diff --git a/.gitignore_recorder b/.gitignore_recorder index 7d1a7b68fe94a670b1ee7e52632e231478e013f0..2447eff3a26057275ced9afce3380441674df89a 100644 --- a/.gitignore_recorder +++ b/.gitignore_recorder @@ -123,9 +123,6 @@ typings/ # Yarn Integrity file .yarn-integrity -# dotenv environment variables file -.env -.env.test # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dc83a81d2b421de89432d5d80756b977f740ce29..a435124f01153c6f99a642a9ea784e84e2431b33 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,24 +1,96 @@ +variables: + EXTENSION_PATH: "./deadlock-plugins/deadlock-extension" + REGISTRY: "registry.takima.io" + stages: - build + - publish -before_script: - - apk update - - apk add nodejs npm - - apk add yarn - - apk add curl - - export TAG=${CI_COMMIT_TAG:-latest} build: stage: build services: - docker:18.09.6-dind - parallel: - matrix: - - VERSION: [code, kube] + variables: + VERSION: "desktop" + + before_script: + - apk update + - apk add nodejs npm + - export TAG=${CI_COMMIT_TAG:-latest} + - ./setup.sh script: - - ./build.sh $TAG $VERSION $CI_REGISTRY_IMAGE - - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.e-biz.fr + - ./build.sh $TAG desktop $CI_REGISTRY_IMAGE + - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $REGISTRY - docker push $CI_REGISTRY_IMAGE/$VERSION:$TAG only: - master - - tags + +desktop_extension:package:pre-release: + stage: build + cache: + paths: + - $EXTENSION_PATH + policy: push + before_script: + - apk update + - apk add nodejs npm + - rm -f $EXTENSION_PATH/*.vsix + - npm install --prefix $EXTENSION_PATH + script: + - ./build-desktop.sh staging + only: + - master + + +desktop_extension:publish:pre-release: + stage: publish + cache: + paths: + - $EXTENSION_PATH + policy: pull + + before_script: + - apk update + - apk add nodejs npm + - npm install --prefix $EXTENSION_PATH + script: + - cd $EXTENSION_PATH + - npm run vsce-publish -- --pre-release -p $VSCODE_EXTENSION_MARKET_PLACE_ACCESS_TOKEN + only: + - master + + +desktop_extension:package:release: + stage: build + cache: + paths: + - $EXTENSION_PATH + + policy: push + before_script: + - apk update + - apk add nodejs npm + - rm -f $EXTENSION_PATH/*.vsix + - npm install --prefix $EXTENSION_PATH + script: + - ./build-desktop.sh prod + rules: + - if: $CI_COMMIT_BRANCH == "master" && $CI_COMMIT_TAG =~ /^(?:\d+\.){2}(?:\d+)$/ + +desktop_extension:publish:release: + stage: publish + cache: + paths: + - $EXTENSION_PATH + policy: pull + + before_script: + - apk update + - apk add nodejs npm + - npm install --prefix $EXTENSION_PATH + script: + - cd $EXTENSION_PATH + - npm run vsce-publish -- -p $VSCODE_EXTENSION_MARKET_PLACE_ACCESS_TOKEN + rules: + - if: $CI_COMMIT_BRANCH == "master" && $CI_COMMIT_TAG =~ /^(?:\d+\.){2}(?:\d+)$/ diff --git a/Dockerfile.code b/Dockerfile.code deleted file mode 100644 index 02e18de9e81209f3c2a0a9a9cba8cc3a247a9849..0000000000000000000000000000000000000000 --- a/Dockerfile.code +++ /dev/null @@ -1,28 +0,0 @@ -FROM registry.e-biz.fr/deadlock-public/theia:1.22.1-java - -USER root - -RUN apt update -RUN apt upgrade -y -RUN apt install rsync -y -RUN apt install vim -y - -COPY plugins /home/plugins -COPY default/.theia/ /home/theia/.theia/ -RUN chown theia /home/theia/.theia -R -RUN chown theia /home/plugins -R - -COPY server.js /home/theia/src-gen/backend/server.js - -COPY recorder-out/ deadlock/ -COPY .gitignore_recorder deadlock/.gitignore - -COPY setup_trace.py . -RUN chmod 700 setup_trace.py -RUN chown theia setup_trace.py - -COPY start.sh . -RUN chmod 504 deadlock/ -R -RUN chmod 500 start.sh - -ENTRYPOINT ["bash", "start.sh"] diff --git a/Dockerfile.desktop b/Dockerfile.desktop new file mode 100644 index 0000000000000000000000000000000000000000..84850d36d4c483804b112c25e892e7fb40514c66 --- /dev/null +++ b/Dockerfile.desktop @@ -0,0 +1,36 @@ +FROM docker:20.10.16-dind-alpine3.15 + +RUN apk update +RUN apk add --update nodejs npm +RUN apk --no-cache add vim && apk --no-cache add nano \ + && apk --no-cache add rsync && apk --no-cache add sudo \ + && apk --no-cache add bash && apk --no-cache add openssh \ + && apk --no-cache add git && apk add --update --no-cache python3 && ln -sf python3 /usr/bin/python + +## User account +RUN addgroup -S sudo && adduser --disabled-password --gecos '' deadlock && \ + adduser deadlock sudo && \ + addgroup -S docker && adduser deadlock docker && \ + echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers + +RUN chown root:docker /usr/local/bin/docker + + +COPY setup_trace.py setup_trace.py +RUN chmod 700 setup_trace.py +RUN chown deadlock setup_trace.py + +COPY recorder-out deadlock/ +COPY .gitignore_recorder deadlock/.gitignore + + + +COPY start.desktop.sh . +RUN chmod 504 deadlock/ -R +RUN chmod 500 start.desktop.sh + +RUN mkdir /project && mkdir /tmp/.ssh && mkdir /home/deadlock/mission + +RUN chown deadlock:deadlock /home/deadlock + +ENTRYPOINT ["bash", "start.desktop.sh"] \ No newline at end of file diff --git a/Dockerfile.kube b/Dockerfile.kube deleted file mode 100644 index 7287ba049b47c0fea230a24b9f832056ab5281f1..0000000000000000000000000000000000000000 --- a/Dockerfile.kube +++ /dev/null @@ -1,7 +0,0 @@ -FROM registry.e-biz.fr/deadlock-public/deadlock-theia:1.4 - -RUN apt-get install -y apt-transport-https -RUN curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - -RUN echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list -RUN apt-get update -RUN apt-get install -y kubectl \ No newline at end of file diff --git a/README.md b/README.md index 428481eb4b0d30b949cf41d17331633ffbd087fc..e4ab58074010a8436bc320689ebf9dfd0727d99a 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,52 @@ -Deadlock Theia projet basé sur notre propre image de Theia https://git.e-biz.fr/deadlock-public/theia. -Plusieurs éléments ajoutés à l'image de base : +Deadlock Desktop est un projet dont l'objectif est de permettre à un étudiant de réaliser des exercices deadlock +sur son IDE Vscode directement. Pour cela, le répertoire héberge 3 éléments : -1. Deadlock plugins (deadlock-plugins/) -2. Outil d'enregistrment, qui permet d'enregistrer le code quand un utilisateur exécute du code (deadlock(plugins/recorder)) -3. Gestion du CORS (\*.deadlock.io) dans `server.js` +- **Une extension Vscode** : L'extension est installée sur l'IDE Vscode de l'étudiant et est responsable de l'ouverture + de l'exercice dans un [devcontainer](https://code.visualstudio.com/docs/remote/containers). -Deux images de `deadlock-theia` sont build ici, _code_ et _kube_. +- **Le recorder** : Une application `node` qui va effectuer des sauvegardes du code source de l'étudiant à chaque fois + que celui-ci va modifier un fichier ou saisir certaines commandes dans son terminal. + +- **Une image Docker** : L'image contient des programmes basiques et le recorder qui est lancé au démarrage + du conteneur. + +# Requirements: + +1. NodeJS > ^14.X +2. Vscode ou Vscodium +3. Docker ## Setup Afin d'installer les éléments requis pour le développement, vous pouvez lancer le script `./setup.sh`. -## Construire les plugins : +## L'image Docker desktop -`./build-plugins.sh` +Il s'agit d'une image qui sera utilisé par tous les créateurs d'exercices comme base. +Le créateur d'exercice peut ensuite ajouter l'exercice et les dépendances qu'il souhaite pour créer l'image de son exercice. -Tous les plugins qui se trouvent dans `deadlock-public` vont être construit en `.vsix` puis placés -dans `plugins/` (ex: deadlock-plugins/deadlock-extension). -Il est aussi possible d'ajouter directement des plugins `.vsix` en ajoutant le fichier dans `plugins/` +L'image est décrite dans le fichier `Dockerfile.desktop`. ## Recorder : Le recorder permet de sauvegarder régulièrement le code de l'utilisateur. -Pour se faire il écoute les commandes exécutées par l'utilisateur et si une contient `java|npm|yarn` -alors un snapshot du code est réalisé. +Pour se faire, il écoute les commandes exécutées par l'utilisateur. Si l'une d'entre elles contient `java`, `npm` ou `yarn` +alors un snapshot du code est réalisé. Il va également faire un snapshot du code lorsque l'étudiant modifiera les fichiers de l'exercice. ### Build `./build-recorder.sh` -## Construire l'image Deadlock Theia avec le recorder et les plugins +## Construire les plugins Vscode : -`./build.sh $TAG (code|kube)` +`./build-plugins.sh` -# Requirements: +Tous les plugins qui se trouvent dans `deadlock-public` vont être construit en `.vsix` puis placés +dans `plugins/` (ex: deadlock-plugins/deadlock-extension). +Il est aussi possible d'ajouter directement des plugins `.vsix` en ajoutant le fichier dans `plugins/` -1. NodeJS > ^14.X -2. Vscode ou Vscodium -3. Docker +Plus d'informations sur l'extension `deadlock-coding` dans ce [README](deadlock-plugins/deadlock-extension/dev/README.md). + +## Construire l'image Deadlock Desktop avec le recorder -Ce projet contient le minimum pour construire une image Docker Theia avec Blueprint (https://theia-ide.org/docs/composing_applications/) +`./build.sh $TAG desktop` diff --git a/build-desktop.sh b/build-desktop.sh new file mode 100755 index 0000000000000000000000000000000000000000..d7b91cafc058e4ed609036d9e3ce40c0acd16345 --- /dev/null +++ b/build-desktop.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -e + +cd ./deadlock-plugins/deadlock-extension/ + +./install.sh +./build.sh $@ diff --git a/build-recorder.sh b/build-recorder.sh index cd2cf4cebc367b36e3acc645f4a57ae263f0e401..2ae07c7d14d3e357c4015d7a82f22f49ad4deb1a 100755 --- a/build-recorder.sh +++ b/build-recorder.sh @@ -6,13 +6,10 @@ OUTPUT_DIR='recorder-out' cd ./deadlock-plugins/deadlock-extension/ -npm install npm run build-recorder -npm run build-preStop cd - mkdir -p $OUTPUT_DIR cp -r ./deadlock-plugins/deadlock-extension/out/recorder.js $OUTPUT_DIR -cp -r ./deadlock-plugins/deadlock-extension/out/preStop.js $OUTPUT_DIR diff --git a/build.sh b/build.sh index 6d9e150bfdee0cc6aec9f8c2571cb891d3b5f3c3..960fcd0cb79449d16bd6620e5656abe1a148322a 100755 --- a/build.sh +++ b/build.sh @@ -10,10 +10,6 @@ DOCKERFILE="Dockerfile.$VERSION" echo "Building Dockerfile.$VERSION" -echo '=====================================================' -echo '================= BUILDING PLUGINS ==================' -echo '=====================================================' -./build-plugins.sh echo '=====================================================' echo '================= BUILDING RECORDER =================' echo '=====================================================' diff --git a/deadlock-plugins/deadlock-extension/.eslintrc.js b/deadlock-plugins/deadlock-extension/.eslintrc.js index 2cac4952287f4b6d28a6b22b9a39044d31270618..0de9a9a3633c15296403ab5ab76a2ff7852ea031 100644 --- a/deadlock-plugins/deadlock-extension/.eslintrc.js +++ b/deadlock-plugins/deadlock-extension/.eslintrc.js @@ -7,10 +7,11 @@ module.exports = { extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], rules: { semi: [2, 'always'], - quotes: [2, 'single' | 'backtick', 'avoid-escape'], - '@typescript-eslint/no-unused-vars': 0, + '@typescript-eslint/no-unused-vars': 'error', '@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/explicit-module-boundary-types': 0, '@typescript-eslint/no-non-null-assertion': 0, + '@typescript-eslint/no-var-requires': 0, + '@typescript-eslint/no-this-alias': 0, }, }; diff --git a/deadlock-plugins/deadlock-extension/.vscode/extensions.json b/deadlock-plugins/deadlock-extension/.vscode/extensions.json index 326dae3cd5b9cae9464cbdc6390d11927043f728..57dbdae42d37d5323806c24cefef6387b5770610 100644 --- a/deadlock-plugins/deadlock-extension/.vscode/extensions.json +++ b/deadlock-plugins/deadlock-extension/.vscode/extensions.json @@ -1,7 +1,5 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. - // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp - - // List of extensions which should be recommended for users of this workspace. - "recommendations": ["dbaeumer.vscode-eslint"] + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": ["dbaeumer.vscode-eslint", "amodio.tsl-problem-matcher"] } diff --git a/deadlock-plugins/deadlock-extension/.vscode/launch.json b/deadlock-plugins/deadlock-extension/.vscode/launch.json index 4c4a9c78b100a81bc070816bab70bbcf326ee2c1..cbc9e78604f69f668a120818cce55200eaaaf889 100644 --- a/deadlock-plugins/deadlock-extension/.vscode/launch.json +++ b/deadlock-plugins/deadlock-extension/.vscode/launch.json @@ -9,10 +9,20 @@ "name": "Run Extension", "type": "extensionHost", "request": "launch", - "runtimeExecutable": "${execPath}", - "args": ["--extensionDevelopmentPath=${workspaceRoot}"], - "outFiles": ["${workspaceFolder}/out/**/*.js"], - "preLaunchTask": "npm: watch" + "args": ["--extensionDevelopmentPath=${workspaceFolder}"], + "outFiles": ["${workspaceFolder}/dist/**/*.js"], + "preLaunchTask": "${defaultBuildTask}" + }, + { + "name": "Extension Tests", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" + ], + "outFiles": ["${workspaceFolder}/out/**/*.js", "${workspaceFolder}/dist/**/*.js"], + "preLaunchTask": "tasks: watch-tests" } ] } diff --git a/deadlock-plugins/deadlock-extension/.vscode/settings.json b/deadlock-plugins/deadlock-extension/.vscode/settings.json index 194c9b6b6c9840561b2552671bdaa26be65366ba..64ee929665322e5cdd94fb5b7d2ae18f79a27d45 100644 --- a/deadlock-plugins/deadlock-extension/.vscode/settings.json +++ b/deadlock-plugins/deadlock-extension/.vscode/settings.json @@ -1,3 +1,13 @@ +// Place your settings in this file to overwrite default and user settings. { - "editor.insertSpaces": false + "files.exclude": { + "out": false, // set this to true to hide the "out" folder with the compiled JS files + "dist": false // set this to true to hide the "dist" folder with the compiled JS files + }, + "search.exclude": { + "out": true, // set this to false to include "out" folder in search results + "dist": true // set this to false to include "dist" folder in search results + }, + // Turn off tsc task auto detection since we have the necessary tasks as npm scripts + "typescript.tsc.autoDetect": "off" } diff --git a/deadlock-plugins/deadlock-extension/.vscode/tasks.json b/deadlock-plugins/deadlock-extension/.vscode/tasks.json index 078ff7e01ef583efd188933e6f5af582ec9d81bc..bb452adff76d8709fcb5cec4e14bf672f4e2fcb5 100644 --- a/deadlock-plugins/deadlock-extension/.vscode/tasks.json +++ b/deadlock-plugins/deadlock-extension/.vscode/tasks.json @@ -6,15 +6,32 @@ { "type": "npm", "script": "watch", - "problemMatcher": "$tsc-watch", + "problemMatcher": ["$ts-webpack-watch", "$tslint-webpack-watch"], "isBackground": true, "presentation": { - "reveal": "never" + "reveal": "never", + "group": "watchers" }, "group": { "kind": "build", "isDefault": true } + }, + { + "type": "npm", + "script": "watch-tests", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "presentation": { + "reveal": "never", + "group": "watchers" + }, + "group": "build" + }, + { + "label": "tasks: watch-tests", + "dependsOn": ["npm: watch", "npm: watch-tests"], + "problemMatcher": [] } ] } diff --git a/deadlock-plugins/deadlock-extension/.vscodeignore b/deadlock-plugins/deadlock-extension/.vscodeignore index d626c52f3c583b1db5e9a70958ac2f34ac37a757..62bf20897c27705b453c85d440e97fb4f0d9bc2a 100644 --- a/deadlock-plugins/deadlock-extension/.vscodeignore +++ b/deadlock-plugins/deadlock-extension/.vscodeignore @@ -3,4 +3,5 @@ out/ !out/main.js src/ dev/ -tsconfig.json \ No newline at end of file +tsconfig.json +node_modules \ No newline at end of file diff --git a/deadlock-plugins/deadlock-extension/CHANGELOG.md b/deadlock-plugins/deadlock-extension/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..847017bb2c4193e0c83b3b4f075223c0eea50d9c --- /dev/null +++ b/deadlock-plugins/deadlock-extension/CHANGELOG.md @@ -0,0 +1,20 @@ +### Changelog + +All notable changes to this project will be documented in this file. Dates are displayed in UTC. + +Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). + +#### [0.1.7](https://gitlab.takima.io/deadlock-public/deadlock-desktop/compare/0.1.6...0.1.7) + +#### 0.1.6 + +> 23 May 2022 + +- feat: publish_extension_on_marketplace_with_ci [`#5`](https://gitlab.takima.io/deadlock-public/deadlock-desktop/merge_requests/5) +- fix(view): open `Help` panel by default + fix split screen on views opening after several restarts [`#2`](https://gitlab.takima.io/deadlock-public/deadlock-desktop/merge_requests/2) +- Feat theia professor [`#4`](https://gitlab.takima.io/deadlock-public/deadlock-desktop/merge_requests/4) +- Pull on start [`#3`](https://gitlab.takima.io/deadlock-public/deadlock-desktop/merge_requests/3) +- feat: git pull on startup, refactor user-challenge config [`#2`](https://gitlab.takima.io/deadlock-public/deadlock-desktop/merge_requests/2) +- feat: use new theia build [`43dee03`](https://gitlab.takima.io/deadlock-public/deadlock-desktop/commit/43dee036539001951de56197cf96bc36a46945b7) +- chores: clean theia resources [`8a8ab05`](https://gitlab.takima.io/deadlock-public/deadlock-desktop/commit/8a8ab05c2a6b723d587dc455fcbe2ae03d608de9) +- refactor: apply some recommendation [`cc647f5`](https://gitlab.takima.io/deadlock-public/deadlock-desktop/commit/cc647f51cfa9325db11c0450cf8f37ba681c83ca) diff --git a/deadlock-plugins/deadlock-extension/README.md b/deadlock-plugins/deadlock-extension/README.md index c24101e2f3ea48b3dbe46de58278e86a648bc763..f5847f3f171a675bbcd426c96f244369f98ca1c9 100644 --- a/deadlock-plugins/deadlock-extension/README.md +++ b/deadlock-plugins/deadlock-extension/README.md @@ -1,15 +1,3 @@ -# Deadlock Coding +## Deadlock Coding extension -Vscode extension to show a panel with : - -- adresses availables for the current challenge pulled from `/home/config/user-challenge.json` -- challenge instruction pulled from the `README.md` - -## Quick start - -- Run `setup-dev-env.sh` to mock challenge configuration -- Run `install.sh` -- Run `build.sh` -- Press `F5` (or use `Run and Debug` tab). - -If something goes wrong, you may need to kill watch Task terminal between restarts. +This extension was created to allow you to do some of the [Deadlock](https://www.deadlock.io) platform exercises directly on your Visual Studio Code IDE diff --git a/deadlock-plugins/deadlock-extension/build.sh b/deadlock-plugins/deadlock-extension/build.sh index 77a6867456b2d485d48814efe422a3c5856ea6e5..5cb1d85ec85fda4fc0c2522dba7b6a15fb99faf6 100755 --- a/deadlock-plugins/deadlock-extension/build.sh +++ b/deadlock-plugins/deadlock-extension/build.sh @@ -2,5 +2,16 @@ set -e +CONFIG_FILE=$1 + +if ! [ -z "$CONFIG_FILE" ] + then + echo $CONFIG_FILE + mv -f src/config.$CONFIG_FILE.ts src/config.ts + # Remove all other configs + rm src/config.*.ts +fi + + npm run build-extension -npm run vsce +npm run vsce-package diff --git a/deadlock-plugins/deadlock-extension/dev/README.md b/deadlock-plugins/deadlock-extension/dev/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b2fb4782cd70d06ce2ca9fe91c679f9dc6ab2e7c --- /dev/null +++ b/deadlock-plugins/deadlock-extension/dev/README.md @@ -0,0 +1,80 @@ +# Deadlock Coding + +Extension VSCode permettant de : + +- récupérer la mission en cours à partir du `/home/config/user-challenge.json` +- afficher les consignes de la mission depuis un `README.md`. + +## Quick start + +- Ouvrir le dossier `deadlock-extension` dans Vscode +- Lancer le script `setup-dev-env.sh` pour simuler la configuration d'une mission +- Lancer le script `install.sh` +- Dans l'éditeur, appuyer sur `F5` (ou utiliser l'onglet `Run and Debug`). + +## Gitlab CI pour publier l'extension + +Le pipeline a besoin d'un token provenant de la marketplace pour y publier l'extension. + +- La méthode pour obtenir le token est décrite [ici](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#get-a-personal-access-token) +- Le token doit être inséré en tant que valeur de la variable `VSCODE_EXTENSION_MARKET_PLACE_ACCESS_TOKEN` + +**Le token a une durée de vie maximale de 1 an** + +## Gestion de la production et de la pré-production + +Pour le moment, la marketplace de Vscode ne supporte pas totalement le `semver`([spécialement les suffixes](https://github.com/microsoft/vsmarketplace/issues/50#issuecomment-990764201)). Il n'est pas possible de créer une version `0.0.1-alpha` de l'extension par example. + +### Construire une version pré-release + +1. Monter la version de l'extension avec `npm version`. Vous pouvez voir comment utiliser la commande [ici](https://docs.npmjs.com/cli/v8/commands/npm-version). + +2. Lorsque le travail est poussé sur la branche `master`, une version de l'extension est poussé en `pre-release` sur la marketplace. + +### Constuire une version release + +1. Monter la version de l'extension avec `npm version`. Vous pouvez voir comment utiliser la commande [ici](https://docs.npmjs.com/cli/v8/commands/npm-version). + +2. Pousser le code source et le tag : + +```shell +git tag [X.Y.Z] +git push origin [taBranch] --tags +``` + +### Publier l'extention à la main + +Les commandes nécessaires sont prédéfinies dans le package.json : + +```shell +npm run vsce-package +npm run vsce-publish -- [--pre-release] -p [token] +``` + +La méthode pour obtenir le token est décrite [ici](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#get-a-personal-access-token) + +## Le cas d'usage à essayer + +Le cas d'usage à essayer pour valider une US Deadlock Desktop correspond à un scénario utilisateur. Ce scénario doit être mis à jour à chaque mise à jour. + +Configuration de base : + +- OS: Ubuntu 20.04.4 LTS +- Navigateur: Mozilla Firefox (v99.0+), Google Chrome (v101.0+) +- Docker version 20.10.14, build a224086 +- Visual Studio Code (v1.66.2+) + +Steps: + +1. Aller sur https://www.dev.deadlock.io/. La page d'authentification doit apparaitre. +2. Se connecter via Google. Être redirigé vers la page d'accueil. +3. Sélectionner et lancer une mission du type `desktop`. Les instructions de la mission doivent apparaître sur la page. +4. Tous les liens sur la page de la mission doivent fonctionner : installation de dépendances, la page de l'extension sur la marketplace, et le lien xdg-open permettant d'ouvrir Vscode. +5. Lorsque VS Code est ouvert, une fenêtre doit apparaitre et suggérer l'installation de l'extension. Accepter l'installation. L'installation doit fonctionner et une notification de bienvenue doit apparaître. +6. Désinstaller l'extension, relancer l'IDE, et chercher `deadlock` dans la barre de recherche de la `marketplace`. L'extension doit apparaitre dans les 3 premiers résultats. Reinstaller l'extension. +7. Re-cliquer sur le lien de l'exercice dans le navigateur. La fenêtre demandant de choisir un dossier pour les exercices doit s'ouvrir. +8. Sélectionner un dossier ne nécessitant pas de droits d'accès. Une page doit s'ouvrir dans le navigateur par défault pour permettre à l'utilisateur de s'authentifier. +9. S'authentifier avec Google et retourner dans VSCode. Une notification de connexion doit s'afficher. +10. Ouvrir la page de l'extension, elle doit indiquer que les étapes précédentes (choix du dossier et authentification) ont été validées. +11. Une fois authentifié, VSCode doit se réouvrir automatiquement dans le `devcontainer`. L'arborescence de fichiers doit être montée dans le dossier des exercices. +12. Ouvrir le terminal de VSCode. L'utilisateur en cours doit être `deadlock` et les bibliothèques et exécutables nécessaires à la mission doivent être présents (ex: docker, java, node, ...). diff --git a/deadlock-plugins/deadlock-extension/dev/config/user-challenge.json b/deadlock-plugins/deadlock-extension/dev/ressources/config/user-challenge.json similarity index 100% rename from deadlock-plugins/deadlock-extension/dev/config/user-challenge.json rename to deadlock-plugins/deadlock-extension/dev/ressources/config/user-challenge.json diff --git a/deadlock-plugins/deadlock-extension/dev/docs/briefing.md b/deadlock-plugins/deadlock-extension/dev/ressources/docs/briefing.md similarity index 100% rename from deadlock-plugins/deadlock-extension/dev/docs/briefing.md rename to deadlock-plugins/deadlock-extension/dev/ressources/docs/briefing.md diff --git a/deadlock-plugins/deadlock-extension/dev/docs/toast.jpg b/deadlock-plugins/deadlock-extension/dev/ressources/docs/toast.jpg similarity index 100% rename from deadlock-plugins/deadlock-extension/dev/docs/toast.jpg rename to deadlock-plugins/deadlock-extension/dev/ressources/docs/toast.jpg diff --git a/deadlock-plugins/deadlock-extension/media/logo.png b/deadlock-plugins/deadlock-extension/media/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a53213f88159e56e029222335fa7876c9c2ee9bd Binary files /dev/null and b/deadlock-plugins/deadlock-extension/media/logo.png differ diff --git a/deadlock-plugins/deadlock-extension/package-lock.json b/deadlock-plugins/deadlock-extension/package-lock.json index b295b7667c31cb60e1d9f701b2cefc4ce3da03cb..d74a34235031d3f9b12d8b19849b57b567b77420 100644 --- a/deadlock-plugins/deadlock-extension/package-lock.json +++ b/deadlock-plugins/deadlock-extension/package-lock.json @@ -1,43 +1,52 @@ { "name": "deadlock-coding", - "version": "0.0.2", + "version": "0.1.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "deadlock-coding", - "version": "0.0.2", + "version": "0.1.7", "dependencies": { "@vscode/webview-ui-toolkit": "^1.0.0", "async": "^3.2.2", + "axios": "^0.27.2", "crypto-js": "^4.1.1", "date-fns": "^2.27.0", "inversify": "^6.0.1", + "is-docker": "^3.0.0", "marked": "^4.0.6", "node-fetch": "^3.2.3", "reflect-metadata": "^0.1.13", - "simple-git": "^2.48.0" + "simple-git": "^3.7.0" }, "devDependencies": { "@types/crypto-js": "^4.1.1", + "@types/glob": "^7.2.0", "@types/marked": "^4.0.1", - "@types/node": "^12.20.47", + "@types/mocha": "^9.1.0", + "@types/node": "14.x", "@types/node-fetch": "^2.6.1", - "@types/vscode": "^1.51.0", + "@types/vscode": "^1.66.0", "@typescript-eslint/eslint-plugin": "^3.10.1", "@typescript-eslint/parser": "^3.10.1", + "@vscode/test-electron": "^2.1.3", + "auto-changelog": "^2.4.0", "esbuild": "^0.14.2", "eslint": "^7.32.0", + "glob": "^7.2.0", + "mocha": "^9.2.2", "prettier": "2.6.2", "terser-webpack-plugin": "^5.2.5", + "ts-loader": "^9.2.8", "ts-node": "^9.1.1", "typescript": "^3.9.10", - "vsce": "^2.5.1", - "webpack": "^5.65.0", - "webpack-cli": "^4.9.1" + "vsce": "^2.7.0", + "webpack": "^5.70.0", + "webpack-cli": "^4.9.2" }, "engines": { - "vscode": "^1.63.0" + "vscode": "^1.66.0" } }, "node_modules/@babel/code-frame": { @@ -193,6 +202,15 @@ "exenv-es6": "^1.1.1" } }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/@types/crypto-js": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz", @@ -200,9 +218,9 @@ "dev": true }, "node_modules/@types/eslint": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", - "integrity": "sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", + "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", "dev": true, "dependencies": { "@types/estree": "*", @@ -210,9 +228,9 @@ } }, "node_modules/@types/eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", "dev": true, "dependencies": { "@types/eslint": "*", @@ -226,11 +244,21 @@ "dev": true }, "node_modules/@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", "dev": true }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -243,10 +271,22 @@ "integrity": "sha512-ZigEmCWdNUU7IjZEuQ/iaimYdDHWHfTe3kg8ORfKjyGYd9RWumPoOJRQXB0bO+XLkNwzCthW3wUIQtANaEZ1ag==", "dev": true }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true + }, "node_modules/@types/node": { - "version": "12.20.47", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", - "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", + "version": "14.18.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz", + "integrity": "sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==", "dev": true }, "node_modules/@types/node-fetch": { @@ -260,9 +300,9 @@ } }, "node_modules/@types/vscode": { - "version": "1.62.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.62.0.tgz", - "integrity": "sha512-iGlQJ1w5e3qPUryroO6v4lxg3ql1ztdTCwQW3xEwFawdyPLoeUSv48SYfMwc7kQA7h6ThUqflZIjgKAykeF9oA==", + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.67.0.tgz", + "integrity": "sha512-GH8BDf8cw9AC9080uneJfulhSa7KHSMI2s/CyKePXoGNos9J486w2V4YKoeNUqIEkW4hKoEAWp6/cXTwyGj47g==", "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { @@ -403,6 +443,27 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/@vscode/test-electron": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.1.3.tgz", + "integrity": "sha512-ps/yJ/9ToUZtR1dHfWi1mDXtep1VoyyrmGKC3UnIbScToRQvbUjyy1VMqnMEW3EpMmC3g7+pyThIPtPyCLHyow==", + "dev": true, + "dependencies": { + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "rimraf": "^3.0.2", + "unzipper": "^0.10.11" + }, + "engines": { + "node": ">=8.9.3" + } + }, "node_modules/@vscode/webview-ui-toolkit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@vscode/webview-ui-toolkit/-/webview-ui-toolkit-1.0.0.tgz", @@ -563,9 +624,9 @@ } }, "node_modules/@webpack-cli/configtest": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz", - "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.1.tgz", + "integrity": "sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==", "dev": true, "peerDependencies": { "webpack": "4.x.x || 5.x.x", @@ -573,9 +634,9 @@ } }, "node_modules/@webpack-cli/info": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz", - "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.1.tgz", + "integrity": "sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA==", "dev": true, "dependencies": { "envinfo": "^7.7.3" @@ -585,9 +646,9 @@ } }, "node_modules/@webpack-cli/serve": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz", - "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.1.tgz", + "integrity": "sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==", "dev": true, "peerDependencies": { "webpack-cli": "4.x.x" @@ -640,6 +701,18 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -695,6 +768,19 @@ "node": ">=4" } }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -743,8 +829,77 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/auto-changelog": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/auto-changelog/-/auto-changelog-2.4.0.tgz", + "integrity": "sha512-vh17hko1c0ItsEcw6m7qPRf3m45u+XK5QyCrrBFViElZ8jnKrPC1roSznrd1fIB/0vR/zawdECCRJtTuqIXaJw==", + "dev": true, + "dependencies": { + "commander": "^7.2.0", + "handlebars": "^4.7.7", + "node-fetch": "^2.6.1", + "parse-github-url": "^1.0.2", + "semver": "^7.3.5" + }, + "bin": { + "auto-changelog": "src/index.js" + }, + "engines": { + "node": ">=8.3" + } + }, + "node_modules/auto-changelog/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/auto-changelog/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } }, "node_modules/azure-devops-node-api": { "version": "11.1.0", @@ -782,6 +937,37 @@ } ] }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "dev": true, + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -807,6 +993,12 @@ "node": ">= 6" } }, + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", + "dev": true + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -823,6 +1015,24 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "node_modules/browserslist": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.18.1.tgz", @@ -885,6 +1095,24 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "dev": true, + "engines": { + "node": ">=0.2.0" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -907,6 +1135,18 @@ "node": ">=6" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001285", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001285.tgz", @@ -917,6 +1157,18 @@ "url": "https://opencollective.com/browserslist" } }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "dev": true, + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1030,6 +1282,33 @@ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "dev": true }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", @@ -1045,6 +1324,17 @@ "node": ">=6.0" } }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -1093,7 +1383,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1214,6 +1503,18 @@ } } }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/decompress-response": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", @@ -1245,7 +1546,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -1344,6 +1644,15 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.11", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.11.tgz", @@ -1366,9 +1675,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz", + "integrity": "sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -1795,6 +2104,18 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -1808,6 +2129,15 @@ "node": ">=8" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -1827,6 +2157,25 @@ "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", + "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -1864,6 +2213,47 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -1939,6 +2329,15 @@ "node": ">=0.10.0" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", @@ -2025,11 +2424,41 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -2069,6 +2498,15 @@ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, "node_modules/hosted-git-info": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", @@ -2100,6 +2538,33 @@ "entities": "^2.0.0" } }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -2215,6 +2680,18 @@ "resolved": "https://registry.npmjs.org/inversify/-/inversify-6.0.1.tgz", "integrity": "sha512-B3ex30927698TJENHR++8FfEaJGqoWOgI6ZY5Ht/nLUsFCwHn6akbwtnUAPCgUepAnTpe2qHxhDNjoKLyz6rgQ==" }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-core-module": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", @@ -2227,6 +2704,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2257,6 +2748,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -2281,6 +2790,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2358,10 +2879,10 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "node_modules/json-schema-traverse": { @@ -2419,14 +2940,20 @@ } }, "node_modules/linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", "dev": true, "dependencies": { "uc.micro": "^1.0.1" } }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", + "dev": true + }, "node_modules/loader-runner": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", @@ -2466,6 +2993,22 @@ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -2497,14 +3040,14 @@ "dev": true }, "node_modules/markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" }, @@ -2512,16 +3055,25 @@ "markdown-it": "bin/markdown-it.js" } }, - "node_modules/markdown-it/node_modules/entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/marked": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.6.tgz", - "integrity": "sha512-+H0bTf8DM8zLuFBUm/2VklxaCrwlBFgoJzHJcMZCnZ9cPgsllHwKpL6TPLdDeA38yPluMuVKOL1hO5w6HmG5Mg==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz", + "integrity": "sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==", "bin": { "marked": "bin/marked.js" }, @@ -2541,6 +3093,19 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -2557,7 +3122,6 @@ "version": "1.51.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -2566,7 +3130,6 @@ "version": "2.1.34", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, "dependencies": { "mime-db": "1.51.0" }, @@ -2608,17 +3171,202 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "dev": true }, + "node_modules/mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2630,6 +3378,18 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "node_modules/nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", @@ -2713,6 +3473,15 @@ "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", "dev": true }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -2858,11 +3627,23 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "dependencies": { - "callsites": "^3.0.0" + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==", + "dev": true, + "bin": { + "parse-github-url": "cli.js" }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, "node_modules/parse-semver": { @@ -2943,6 +3724,18 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -3133,6 +3926,18 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/rechoir": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", @@ -3162,6 +3967,15 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -3303,6 +4117,12 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -3377,9 +4197,9 @@ ] }, "node_modules/simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", "dev": true, "dependencies": { "decompress-response": "^4.2.0", @@ -3388,13 +4208,13 @@ } }, "node_modules/simple-git": { - "version": "2.48.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.48.0.tgz", - "integrity": "sha512-z4qtrRuaAFJS4PUd0g+xy7aN4y+RvEt/QTJpR184lhJguBA1S/LsVlvE/CM95RsYMOFJG3NGGDjqFCzKU19S/A==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.7.1.tgz", + "integrity": "sha512-+Osjtsumbtew2y9to0pOYjNzSIr4NkKGBg7Po5SUtjQhaJf2QBmiTX/9E9cv9rmc7oUiSGFIB9e7ys5ibnT9+A==", "dependencies": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.2" + "debug": "^4.3.3" }, "funding": { "type": "github", @@ -3730,6 +4550,52 @@ "node": ">=8.17.0" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ts-loader": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.3.0.tgz", + "integrity": "sha512-2kLLAdAD+FCKijvGKi9sS0OzoqxLCF3CxHpok7rVgCZ5UldRzH0TkbwG9XECKjBzHsAewntC5oDaI/FwKzEUog==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, "node_modules/ts-node": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", @@ -3851,12 +4717,43 @@ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", "dev": true }, + "node_modules/uglify-js": { + "version": "3.15.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.4.tgz", + "integrity": "sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/underscore": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", "dev": true }, + "node_modules/unzipper": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3885,9 +4782,9 @@ "dev": true }, "node_modules/vsce": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.5.1.tgz", - "integrity": "sha512-vJ+xY93Wv3NhgeriMyIC2oMA+niifOI9XGIqEToIq/rFRoQnXlmO4PSyis/OxBl9hw8OKKC/VcI9CijfFufEkw==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.7.0.tgz", + "integrity": "sha512-CKU34wrQlbKDeJCRBkd1a8iwF9EvNxcYMg9hAUH6AxFGR6Wo2IKWwt3cJIcusHxx6XdjDHWlfAS/fJN30uvVnA==", "dev": true, "dependencies": { "azure-devops-node-api": "^11.0.1", @@ -3898,7 +4795,7 @@ "hosted-git-info": "^4.0.2", "keytar": "^7.7.0", "leven": "^3.1.0", - "markdown-it": "^10.0.0", + "markdown-it": "^12.3.2", "mime": "^1.3.4", "minimatch": "^3.0.3", "parse-semver": "^1.1.1", @@ -3980,14 +4877,20 @@ "node": ">= 8" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, "node_modules/webpack": { - "version": "5.65.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.65.0.tgz", - "integrity": "sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw==", + "version": "5.72.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.72.1.tgz", + "integrity": "sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung==", "dev": true, "dependencies": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/wasm-edit": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", @@ -3995,13 +4898,13 @@ "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.3", + "enhanced-resolve": "^5.9.3", "es-module-lexer": "^0.9.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", @@ -4009,7 +4912,7 @@ "tapable": "^2.1.1", "terser-webpack-plugin": "^5.1.3", "watchpack": "^2.3.1", - "webpack-sources": "^3.2.2" + "webpack-sources": "^3.2.3" }, "bin": { "webpack": "bin/webpack.js" @@ -4028,15 +4931,15 @@ } }, "node_modules/webpack-cli": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.1.tgz", - "integrity": "sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.2.tgz", + "integrity": "sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==", "dev": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.1.0", - "@webpack-cli/info": "^1.4.0", - "@webpack-cli/serve": "^1.6.0", + "@webpack-cli/configtest": "^1.1.1", + "@webpack-cli/info": "^1.4.1", + "@webpack-cli/serve": "^1.6.1", "colorette": "^2.0.14", "commander": "^7.0.0", "execa": "^5.0.0", @@ -4093,14 +4996,24 @@ } }, "node_modules/webpack-sources": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.2.tgz", - "integrity": "sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, "engines": { "node": ">=10.13.0" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4140,6 +5053,68 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4168,12 +5143,63 @@ "node": ">=4.0" } }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", @@ -4201,6 +5227,18 @@ "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -4335,6 +5373,12 @@ "exenv-es6": "^1.1.1" } }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, "@types/crypto-js": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz", @@ -4342,9 +5386,9 @@ "dev": true }, "@types/eslint": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", - "integrity": "sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", + "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", "dev": true, "requires": { "@types/estree": "*", @@ -4352,9 +5396,9 @@ } }, "@types/eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", "dev": true, "requires": { "@types/eslint": "*", @@ -4368,11 +5412,21 @@ "dev": true }, "@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", "dev": true }, + "@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -4385,10 +5439,22 @@ "integrity": "sha512-ZigEmCWdNUU7IjZEuQ/iaimYdDHWHfTe3kg8ORfKjyGYd9RWumPoOJRQXB0bO+XLkNwzCthW3wUIQtANaEZ1ag==", "dev": true }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true + }, "@types/node": { - "version": "12.20.47", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", - "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", + "version": "14.18.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz", + "integrity": "sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==", "dev": true }, "@types/node-fetch": { @@ -4402,9 +5468,9 @@ } }, "@types/vscode": { - "version": "1.62.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.62.0.tgz", - "integrity": "sha512-iGlQJ1w5e3qPUryroO6v4lxg3ql1ztdTCwQW3xEwFawdyPLoeUSv48SYfMwc7kQA7h6ThUqflZIjgKAykeF9oA==", + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.67.0.tgz", + "integrity": "sha512-GH8BDf8cw9AC9080uneJfulhSa7KHSMI2s/CyKePXoGNos9J486w2V4YKoeNUqIEkW4hKoEAWp6/cXTwyGj47g==", "dev": true }, "@typescript-eslint/eslint-plugin": { @@ -4478,6 +5544,24 @@ "eslint-visitor-keys": "^1.1.0" } }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "@vscode/test-electron": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.1.3.tgz", + "integrity": "sha512-ps/yJ/9ToUZtR1dHfWi1mDXtep1VoyyrmGKC3UnIbScToRQvbUjyy1VMqnMEW3EpMmC3g7+pyThIPtPyCLHyow==", + "dev": true, + "requires": { + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "rimraf": "^3.0.2", + "unzipper": "^0.10.11" + } + }, "@vscode/webview-ui-toolkit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@vscode/webview-ui-toolkit/-/webview-ui-toolkit-1.0.0.tgz", @@ -4635,25 +5719,25 @@ } }, "@webpack-cli/configtest": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz", - "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.1.tgz", + "integrity": "sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==", "dev": true, "requires": {} }, "@webpack-cli/info": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz", - "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.1.tgz", + "integrity": "sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA==", "dev": true, "requires": { "envinfo": "^7.7.3" } }, "@webpack-cli/serve": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz", - "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.1.tgz", + "integrity": "sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==", "dev": true, "requires": {} }, @@ -4689,6 +5773,15 @@ "dev": true, "requires": {} }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -4729,6 +5822,16 @@ "color-convert": "^1.9.0" } }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -4774,8 +5877,58 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "auto-changelog": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/auto-changelog/-/auto-changelog-2.4.0.tgz", + "integrity": "sha512-vh17hko1c0ItsEcw6m7qPRf3m45u+XK5QyCrrBFViElZ8jnKrPC1roSznrd1fIB/0vR/zawdECCRJtTuqIXaJw==", + "dev": true, + "requires": { + "commander": "^7.2.0", + "handlebars": "^4.7.7", + "node-fetch": "^2.6.1", + "parse-github-url": "^1.0.2", + "semver": "^7.3.5" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + } + } + }, + "axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "requires": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } }, "azure-devops-node-api": { "version": "11.1.0", @@ -4799,6 +5952,28 @@ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, + "big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "dev": true + }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "dev": true, + "requires": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -4823,6 +5998,12 @@ } } }, + "bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", + "dev": true + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -4839,6 +6020,21 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "browserslist": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.18.1.tgz", @@ -4874,6 +6070,18 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "dev": true + }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "dev": true + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -4890,12 +6098,27 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, "caniuse-lite": { "version": "1.0.30001285", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001285.tgz", "integrity": "sha512-KAOkuUtcQ901MtmvxfKD+ODHH9YVDYnBt+TGYSz2KIfnq22CiArbUxXPN9067gNbgMlnNYRSwho8OPXZPALB9Q==", "dev": true }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "dev": true, + "requires": { + "traverse": ">=0.3.0 <0.4" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -4983,6 +6206,22 @@ "domutils": "^2.7.0" } }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", @@ -4995,6 +6234,17 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -5037,7 +6287,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -5125,6 +6374,12 @@ "ms": "2.1.2" } }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, "decompress-response": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", @@ -5149,8 +6404,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegates": { "version": "1.0.0", @@ -5216,6 +6470,15 @@ "domhandler": "^4.2.0" } }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, "electron-to-chromium": { "version": "1.4.11", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.11.tgz", @@ -5238,9 +6501,9 @@ } }, "enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz", + "integrity": "sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -5555,6 +6818,15 @@ "flat-cache": "^3.0.4" } }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -5565,6 +6837,12 @@ "path-exists": "^4.0.0" } }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -5581,6 +6859,11 @@ "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", "dev": true }, + "follow-redirects": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", + "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==" + }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -5612,6 +6895,36 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -5677,6 +6990,12 @@ } } }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, "get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", @@ -5739,11 +7058,30 @@ } }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -5771,6 +7109,12 @@ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, "hosted-git-info": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", @@ -5792,6 +7136,27 @@ "entities": "^2.0.0" } }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -5869,6 +7234,15 @@ "resolved": "https://registry.npmjs.org/inversify/-/inversify-6.0.1.tgz", "integrity": "sha512-B3ex30927698TJENHR++8FfEaJGqoWOgI6ZY5Ht/nLUsFCwHn6akbwtnUAPCgUepAnTpe2qHxhDNjoKLyz6rgQ==" }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-core-module": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", @@ -5878,6 +7252,11 @@ "has": "^1.0.3" } }, + "is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==" + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -5899,6 +7278,18 @@ "is-extglob": "^2.1.1" } }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -5914,6 +7305,12 @@ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -5975,10 +7372,10 @@ "esprima": "^4.0.0" } }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "json-schema-traverse": { @@ -6026,14 +7423,20 @@ } }, "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", "dev": true, "requires": { "uc.micro": "^1.0.1" } }, + "listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", + "dev": true + }, "loader-runner": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", @@ -6067,6 +7470,16 @@ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -6092,30 +7505,36 @@ "dev": true }, "markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", "dev": true, "requires": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" }, "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", "dev": true } } }, "marked": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.6.tgz", - "integrity": "sha512-+H0bTf8DM8zLuFBUm/2VklxaCrwlBFgoJzHJcMZCnZ9cPgsllHwKpL6TPLdDeA38yPluMuVKOL1hO5w6HmG5Mg==" + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz", + "integrity": "sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==" }, "mdurl": { "version": "1.0.1", @@ -6129,6 +7548,16 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -6138,14 +7567,12 @@ "mime-db": { "version": "1.51.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" }, "mime-types": { "version": "2.1.34", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, "requires": { "mime-db": "1.51.0" } @@ -6172,17 +7599,148 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "dev": true }, + "mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -6194,6 +7752,12 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true + }, "napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", @@ -6256,6 +7820,12 @@ "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", "dev": true }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -6369,6 +7939,12 @@ "callsites": "^3.0.0" } }, + "parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==", + "dev": true + }, "parse-semver": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", @@ -6437,6 +8013,12 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -6586,6 +8168,15 @@ } } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "rechoir": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", @@ -6606,6 +8197,12 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -6701,6 +8298,12 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -6749,9 +8352,9 @@ "dev": true }, "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", "dev": true, "requires": { "decompress-response": "^4.2.0", @@ -6760,13 +8363,13 @@ } }, "simple-git": { - "version": "2.48.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.48.0.tgz", - "integrity": "sha512-z4qtrRuaAFJS4PUd0g+xy7aN4y+RvEt/QTJpR184lhJguBA1S/LsVlvE/CM95RsYMOFJG3NGGDjqFCzKU19S/A==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.7.1.tgz", + "integrity": "sha512-+Osjtsumbtew2y9to0pOYjNzSIr4NkKGBg7Po5SUtjQhaJf2QBmiTX/9E9cv9rmc7oUiSGFIB9e7ys5ibnT9+A==", "requires": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.2" + "debug": "^4.3.3" } }, "slice-ansi": { @@ -7015,6 +8618,39 @@ "rimraf": "^3.0.0" } }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "dev": true + }, + "ts-loader": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.3.0.tgz", + "integrity": "sha512-2kLLAdAD+FCKijvGKi9sS0OzoqxLCF3CxHpok7rVgCZ5UldRzH0TkbwG9XECKjBzHsAewntC5oDaI/FwKzEUog==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + } + }, "ts-node": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", @@ -7096,12 +8732,37 @@ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", "dev": true }, + "uglify-js": { + "version": "3.15.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.4.tgz", + "integrity": "sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA==", + "dev": true, + "optional": true + }, "underscore": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", "dev": true }, + "unzipper": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "dev": true, + "requires": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -7130,9 +8791,9 @@ "dev": true }, "vsce": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.5.1.tgz", - "integrity": "sha512-vJ+xY93Wv3NhgeriMyIC2oMA+niifOI9XGIqEToIq/rFRoQnXlmO4PSyis/OxBl9hw8OKKC/VcI9CijfFufEkw==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.7.0.tgz", + "integrity": "sha512-CKU34wrQlbKDeJCRBkd1a8iwF9EvNxcYMg9hAUH6AxFGR6Wo2IKWwt3cJIcusHxx6XdjDHWlfAS/fJN30uvVnA==", "dev": true, "requires": { "azure-devops-node-api": "^11.0.1", @@ -7143,7 +8804,7 @@ "hosted-git-info": "^4.0.2", "keytar": "^7.7.0", "leven": "^3.1.0", - "markdown-it": "^10.0.0", + "markdown-it": "^12.3.2", "mime": "^1.3.4", "minimatch": "^3.0.3", "parse-semver": "^1.1.1", @@ -7203,14 +8864,20 @@ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==" }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, "webpack": { - "version": "5.65.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.65.0.tgz", - "integrity": "sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw==", + "version": "5.72.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.72.1.tgz", + "integrity": "sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung==", "dev": true, "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/wasm-edit": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", @@ -7218,13 +8885,13 @@ "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.3", + "enhanced-resolve": "^5.9.3", "es-module-lexer": "^0.9.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", @@ -7232,19 +8899,19 @@ "tapable": "^2.1.1", "terser-webpack-plugin": "^5.1.3", "watchpack": "^2.3.1", - "webpack-sources": "^3.2.2" + "webpack-sources": "^3.2.3" } }, "webpack-cli": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.1.tgz", - "integrity": "sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.2.tgz", + "integrity": "sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==", "dev": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.1.0", - "@webpack-cli/info": "^1.4.0", - "@webpack-cli/serve": "^1.6.0", + "@webpack-cli/configtest": "^1.1.1", + "@webpack-cli/info": "^1.4.1", + "@webpack-cli/serve": "^1.6.1", "colorette": "^2.0.14", "commander": "^7.0.0", "execa": "^5.0.0", @@ -7274,11 +8941,21 @@ } }, "webpack-sources": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.2.tgz", - "integrity": "sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -7309,6 +8986,55 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -7331,12 +9057,51 @@ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", "dev": true }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, "yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", @@ -7361,6 +9126,12 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/deadlock-plugins/deadlock-extension/package.json b/deadlock-plugins/deadlock-extension/package.json index 69aa8ecd31ee4a426c3aee800ade330a3baf4327..cfd3d4b0397ecd22584c5d33ef5604f3bc6630c0 100644 --- a/deadlock-plugins/deadlock-extension/package.json +++ b/deadlock-plugins/deadlock-extension/package.json @@ -1,10 +1,11 @@ { "name": "deadlock-coding", "description": "Deadlock Coding", - "version": "0.0.2", + "version": "0.1.9", "publisher": "Deadlock", + "icon": "media/logo.png", "engines": { - "vscode": "^1.66.0" + "vscode": ">=1.66.0" }, "categories": [ "Other" @@ -16,11 +17,7 @@ "onWebviewPanel:deadlockHelp", "onStartupFinished" ], - "repository": { - "type": "git", - "url": "https://github.com/microsoft/vscode-extension-samples.git" - }, - "main": "./out/main.js", + "main": "./dist/extension.js", "contributes": { "commands": [ { @@ -64,7 +61,7 @@ { "id": "help", "name": "Help", - "visibility": "collapsed" + "visibility": "visible" } ] }, @@ -85,43 +82,61 @@ } }, "scripts": { - "vsce": "vsce package", + "vsce-package": "vsce package --allow-missing-repository", + "vsce-publish": "vsce publish --allow-missing-repository", + "vscode:prepackage": "npm run build-extension", + "compile": "webpack", "esbuild-base": "esbuild --bundle --format=cjs --platform=node", - "build-extension": "npm run esbuild-base -- --external:vscode ./src/extension.ts --outfile=out/main.js --minify", "build-recorder": "npm run esbuild-base -- ./src/recorder/index.ts --outfile=out/recorder.js --minify", - "build-preStop": "npm run esbuild-base -- ./src/recorder/preStop.ts --outfile=out/preStop.js --minify", "esbuild": "npm run esbuild-base -- --sourcemap", - "esbuild-watch": "npm run esbuild-base -- --sourcemap --watch", - "lint": "eslint . --ext .ts,.tsx", - "watch": "tsc -w -p ./" + "watch": "webpack --watch", + "build-extension": "webpack --mode production --devtool hidden-source-map", + "compile-tests": "tsc -p . --outDir out", + "watch-tests": "tsc -p . -w --outDir out", + "pretest": "npm run compile-tests && npm run compile && npm run lint", + "lint": "eslint src --ext ts", + "test": "node ./out/test/runTest.js", + "postversion": "git add package*.json && auto-changelog -p && git add CHANGELOG.md && git commit -m \"build: $npm_package_version\"" }, "dependencies": { "@vscode/webview-ui-toolkit": "^1.0.0", "async": "^3.2.2", + "axios": "^0.27.2", "crypto-js": "^4.1.1", "date-fns": "^2.27.0", "inversify": "^6.0.1", + "is-docker": "^3.0.0", "marked": "^4.0.6", "node-fetch": "^3.2.3", "reflect-metadata": "^0.1.13", - "simple-git": "^2.48.0" + "simple-git": "^3.7.0" }, "devDependencies": { + "@types/glob": "^7.2.0", + "@types/mocha": "^9.1.0", "@types/crypto-js": "^4.1.1", "@types/marked": "^4.0.1", - "@types/node": "^12.20.47", + "@types/node": "14.x", "@types/node-fetch": "^2.6.1", - "@types/vscode": "^1.51.0", - "@typescript-eslint/eslint-plugin": "^3.10.1", - "@typescript-eslint/parser": "^3.10.1", + "@types/vscode": "^1.66.0", + "auto-changelog": "^2.4.0", "esbuild": "^0.14.2", - "eslint": "^7.32.0", "prettier": "2.6.2", "terser-webpack-plugin": "^5.2.5", "ts-node": "^9.1.1", + "vsce": "^2.7.0", "typescript": "^3.9.10", - "vsce": "^2.5.1", - "webpack": "^5.65.0", - "webpack-cli": "^4.9.1" - } + "ts-loader": "^9.2.8", + "webpack": "^5.70.0", + "webpack-cli": "^4.9.2", + "@typescript-eslint/eslint-plugin": "^3.10.1", + "@typescript-eslint/parser": "^3.10.1", + "eslint": "^7.32.0", + "glob": "^7.2.0", + "mocha": "^9.2.2", + "@vscode/test-electron": "^2.1.3" + }, + "extensionPack": [ + "ms-vscode-remote.remote-containers" + ] } diff --git a/deadlock-plugins/deadlock-extension/resources/dark/help.svg b/deadlock-plugins/deadlock-extension/resources/dark/help.svg index 87a05d2aee68aec706cc1c02179671239f210d43..7d115def191648731c120ebc40a7c742792ffeb5 100644 --- a/deadlock-plugins/deadlock-extension/resources/dark/help.svg +++ b/deadlock-plugins/deadlock-extension/resources/dark/help.svg @@ -1 +1,3 @@ -<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 48 48" height="48px" id="Layer_3" version="1.1" viewBox="0 0 48 48" width="48px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><path d="M26.456,8.366c1.152,0,2.209-0.407,3.161-1.22c0.943-0.812,1.523-1.799,1.731-2.951 c0.195-1.16-0.048-2.138-0.764-2.951c-0.714-0.821-1.648-1.228-2.803-1.228c-1.159,0-2.214,0.407-3.158,1.228 c-0.955,0.813-1.535,1.792-1.732,2.951c-0.143,1.151,0.133,2.139,0.812,2.951C24.384,7.959,25.305,8.366,26.456,8.366z" fill="#241F20"/><path d="M36.68,37.971c0-0.352-0.462-0.712-1.361-1.088c-0.105,0.152-0.211,0.282-0.316,0.435 c-0.627,0.798-2.965,3.613-6.008,5.3c-0.02,0.008-0.036,0.016-0.048,0.027c-0.265,0.141-0.536,0.246-0.808,0.371 c-0.803,0.286-1.552,0.36-1.793,0.38c-0.683-0.09-1.053-0.567-1.053-1.471c0-0.747,0.219-2.222,0.663-4.439l0.51-2.237 l2.083-10.001c0.339-1.705,0.521-2.649,0.562-2.835l0.454-2.339c0.268-1.449,0.404-2.406,0.404-2.873 c0-0.894-0.224-1.572-0.579-2.124c-0.031-0.08-0.074-0.161-0.133-0.245c-0.054-0.064-0.107-0.121-0.164-0.18 c-0.062-0.066-0.095-0.129-0.179-0.198c-0.888-0.726-1.715-0.933-2.287-0.979l0.01-0.016c0,0-3.759-0.286-9.326,3.383 c-0.081,0.054-0.13,0.09-0.204,0.141c-1.507,0.954-2.712,1.913-3.547,2.681c-0.642,0.547-1.135,1.058-1.5,1.533 c0,0.002-0.018,0.021-0.018,0.021l0.004-0.002c-0.476,0.624-0.726,1.193-0.726,1.695c0,0.397,0.32,0.794,0.958,1.189 c0,0,2.392-3.086,6.41-5.096c0.304-0.131,1.076-0.45,1.755-0.627c0.316-0.073,0.915-0.129,1.298,0.187 c0.274,0.284,0.456,0.683,0.456,1.301c0,0.563-0.085,1.243-0.256,2.061l-0.407,1.926l-0.507,2.407l-1.984,9.517 c-1.015,4.916-1.523,7.857-1.523,8.815c0,2.261,1.237,3.392,3.71,3.392c1.12,0,2.274-0.203,3.455-0.566 c0.008,0,0.012,0.004,0.02,0.007c0.081-0.027,0.155-0.059,0.232-0.085c0.196-0.063,0.394-0.138,0.59-0.213 c5.578-2.076,9.248-6.257,10.359-7.657c0.098-0.118,0.18-0.23,0.262-0.337c0.062-0.086,0.102-0.145,0.102-0.145h-0.004 C36.527,38.573,36.68,38.229,36.68,37.971z" fill="#241F20"/></g></svg> \ No newline at end of file +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'> +<svg enable-background="new 0 0 48 48" height="48px" id="Layer_3" version="1.1" viewBox="0 0 48 48" width="48px" + xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g><path d="M26.456,8.366c1.152,0,2.209-0.407,3.161-1.22c0.943-0.812,1.523-1.799,1.731-2.951 c0.195-1.16-0.048-2.138-0.764-2.951c-0.714-0.821-1.648-1.228-2.803-1.228c-1.159,0-2.214,0.407-3.158,1.228 c-0.955,0.813-1.535,1.792-1.732,2.951c-0.143,1.151,0.133,2.139,0.812,2.951C24.384,7.959,25.305,8.366,26.456,8.366z" fill="#241F20"/><path d="M36.68,37.971c0-0.352-0.462-0.712-1.361-1.088c-0.105,0.152-0.211,0.282-0.316,0.435 c-0.627,0.798-2.965,3.613-6.008,5.3c-0.02,0.008-0.036,0.016-0.048,0.027c-0.265,0.141-0.536,0.246-0.808,0.371 c-0.803,0.286-1.552,0.36-1.793,0.38c-0.683-0.09-1.053-0.567-1.053-1.471c0-0.747,0.219-2.222,0.663-4.439l0.51-2.237 l2.083-10.001c0.339-1.705,0.521-2.649,0.562-2.835l0.454-2.339c0.268-1.449,0.404-2.406,0.404-2.873 c0-0.894-0.224-1.572-0.579-2.124c-0.031-0.08-0.074-0.161-0.133-0.245c-0.054-0.064-0.107-0.121-0.164-0.18 c-0.062-0.066-0.095-0.129-0.179-0.198c-0.888-0.726-1.715-0.933-2.287-0.979l0.01-0.016c0,0-3.759-0.286-9.326,3.383 c-0.081,0.054-0.13,0.09-0.204,0.141c-1.507,0.954-2.712,1.913-3.547,2.681c-0.642,0.547-1.135,1.058-1.5,1.533 c0,0.002-0.018,0.021-0.018,0.021l0.004-0.002c-0.476,0.624-0.726,1.193-0.726,1.695c0,0.397,0.32,0.794,0.958,1.189 c0,0,2.392-3.086,6.41-5.096c0.304-0.131,1.076-0.45,1.755-0.627c0.316-0.073,0.915-0.129,1.298,0.187 c0.274,0.284,0.456,0.683,0.456,1.301c0,0.563-0.085,1.243-0.256,2.061l-0.407,1.926l-0.507,2.407l-1.984,9.517 c-1.015,4.916-1.523,7.857-1.523,8.815c0,2.261,1.237,3.392,3.71,3.392c1.12,0,2.274-0.203,3.455-0.566 c0.008,0,0.012,0.004,0.02,0.007c0.081-0.027,0.155-0.059,0.232-0.085c0.196-0.063,0.394-0.138,0.59-0.213 c5.578-2.076,9.248-6.257,10.359-7.657c0.098-0.118,0.18-0.23,0.262-0.337c0.062-0.086,0.102-0.145,0.102-0.145h-0.004 C36.527,38.573,36.68,38.229,36.68,37.971z" fill="#241F20"/></g></svg> \ No newline at end of file diff --git a/deadlock-plugins/deadlock-extension/resources/js/gettingStartedView.js b/deadlock-plugins/deadlock-extension/resources/js/gettingStartedView.js index 363a55f54e7adbcc2c6d4ca27ec46a730a2e4b81..547953b63bc964364cd695380fdad8a1982613d7 100644 --- a/deadlock-plugins/deadlock-extension/resources/js/gettingStartedView.js +++ b/deadlock-plugins/deadlock-extension/resources/js/gettingStartedView.js @@ -1,4 +1,3 @@ -// This file is used by gettingStarted via a <script> tag const vscode = acquireVsCodeApi(); function launchChooseMissionWorkdirAction() { diff --git a/deadlock-plugins/deadlock-extension/resources/light/help.svg b/deadlock-plugins/deadlock-extension/resources/light/help.svg index 87a05d2aee68aec706cc1c02179671239f210d43..7d115def191648731c120ebc40a7c742792ffeb5 100644 --- a/deadlock-plugins/deadlock-extension/resources/light/help.svg +++ b/deadlock-plugins/deadlock-extension/resources/light/help.svg @@ -1 +1,3 @@ -<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 48 48" height="48px" id="Layer_3" version="1.1" viewBox="0 0 48 48" width="48px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><path d="M26.456,8.366c1.152,0,2.209-0.407,3.161-1.22c0.943-0.812,1.523-1.799,1.731-2.951 c0.195-1.16-0.048-2.138-0.764-2.951c-0.714-0.821-1.648-1.228-2.803-1.228c-1.159,0-2.214,0.407-3.158,1.228 c-0.955,0.813-1.535,1.792-1.732,2.951c-0.143,1.151,0.133,2.139,0.812,2.951C24.384,7.959,25.305,8.366,26.456,8.366z" fill="#241F20"/><path d="M36.68,37.971c0-0.352-0.462-0.712-1.361-1.088c-0.105,0.152-0.211,0.282-0.316,0.435 c-0.627,0.798-2.965,3.613-6.008,5.3c-0.02,0.008-0.036,0.016-0.048,0.027c-0.265,0.141-0.536,0.246-0.808,0.371 c-0.803,0.286-1.552,0.36-1.793,0.38c-0.683-0.09-1.053-0.567-1.053-1.471c0-0.747,0.219-2.222,0.663-4.439l0.51-2.237 l2.083-10.001c0.339-1.705,0.521-2.649,0.562-2.835l0.454-2.339c0.268-1.449,0.404-2.406,0.404-2.873 c0-0.894-0.224-1.572-0.579-2.124c-0.031-0.08-0.074-0.161-0.133-0.245c-0.054-0.064-0.107-0.121-0.164-0.18 c-0.062-0.066-0.095-0.129-0.179-0.198c-0.888-0.726-1.715-0.933-2.287-0.979l0.01-0.016c0,0-3.759-0.286-9.326,3.383 c-0.081,0.054-0.13,0.09-0.204,0.141c-1.507,0.954-2.712,1.913-3.547,2.681c-0.642,0.547-1.135,1.058-1.5,1.533 c0,0.002-0.018,0.021-0.018,0.021l0.004-0.002c-0.476,0.624-0.726,1.193-0.726,1.695c0,0.397,0.32,0.794,0.958,1.189 c0,0,2.392-3.086,6.41-5.096c0.304-0.131,1.076-0.45,1.755-0.627c0.316-0.073,0.915-0.129,1.298,0.187 c0.274,0.284,0.456,0.683,0.456,1.301c0,0.563-0.085,1.243-0.256,2.061l-0.407,1.926l-0.507,2.407l-1.984,9.517 c-1.015,4.916-1.523,7.857-1.523,8.815c0,2.261,1.237,3.392,3.71,3.392c1.12,0,2.274-0.203,3.455-0.566 c0.008,0,0.012,0.004,0.02,0.007c0.081-0.027,0.155-0.059,0.232-0.085c0.196-0.063,0.394-0.138,0.59-0.213 c5.578-2.076,9.248-6.257,10.359-7.657c0.098-0.118,0.18-0.23,0.262-0.337c0.062-0.086,0.102-0.145,0.102-0.145h-0.004 C36.527,38.573,36.68,38.229,36.68,37.971z" fill="#241F20"/></g></svg> \ No newline at end of file +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'> +<svg enable-background="new 0 0 48 48" height="48px" id="Layer_3" version="1.1" viewBox="0 0 48 48" width="48px" + xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g><path d="M26.456,8.366c1.152,0,2.209-0.407,3.161-1.22c0.943-0.812,1.523-1.799,1.731-2.951 c0.195-1.16-0.048-2.138-0.764-2.951c-0.714-0.821-1.648-1.228-2.803-1.228c-1.159,0-2.214,0.407-3.158,1.228 c-0.955,0.813-1.535,1.792-1.732,2.951c-0.143,1.151,0.133,2.139,0.812,2.951C24.384,7.959,25.305,8.366,26.456,8.366z" fill="#241F20"/><path d="M36.68,37.971c0-0.352-0.462-0.712-1.361-1.088c-0.105,0.152-0.211,0.282-0.316,0.435 c-0.627,0.798-2.965,3.613-6.008,5.3c-0.02,0.008-0.036,0.016-0.048,0.027c-0.265,0.141-0.536,0.246-0.808,0.371 c-0.803,0.286-1.552,0.36-1.793,0.38c-0.683-0.09-1.053-0.567-1.053-1.471c0-0.747,0.219-2.222,0.663-4.439l0.51-2.237 l2.083-10.001c0.339-1.705,0.521-2.649,0.562-2.835l0.454-2.339c0.268-1.449,0.404-2.406,0.404-2.873 c0-0.894-0.224-1.572-0.579-2.124c-0.031-0.08-0.074-0.161-0.133-0.245c-0.054-0.064-0.107-0.121-0.164-0.18 c-0.062-0.066-0.095-0.129-0.179-0.198c-0.888-0.726-1.715-0.933-2.287-0.979l0.01-0.016c0,0-3.759-0.286-9.326,3.383 c-0.081,0.054-0.13,0.09-0.204,0.141c-1.507,0.954-2.712,1.913-3.547,2.681c-0.642,0.547-1.135,1.058-1.5,1.533 c0,0.002-0.018,0.021-0.018,0.021l0.004-0.002c-0.476,0.624-0.726,1.193-0.726,1.695c0,0.397,0.32,0.794,0.958,1.189 c0,0,2.392-3.086,6.41-5.096c0.304-0.131,1.076-0.45,1.755-0.627c0.316-0.073,0.915-0.129,1.298,0.187 c0.274,0.284,0.456,0.683,0.456,1.301c0,0.563-0.085,1.243-0.256,2.061l-0.407,1.926l-0.507,2.407l-1.984,9.517 c-1.015,4.916-1.523,7.857-1.523,8.815c0,2.261,1.237,3.392,3.71,3.392c1.12,0,2.274-0.203,3.455-0.566 c0.008,0,0.012,0.004,0.02,0.007c0.081-0.027,0.155-0.059,0.232-0.085c0.196-0.063,0.394-0.138,0.59-0.213 c5.578-2.076,9.248-6.257,10.359-7.657c0.098-0.118,0.18-0.23,0.262-0.337c0.062-0.086,0.102-0.145,0.102-0.145h-0.004 C36.527,38.573,36.68,38.229,36.68,37.971z" fill="#241F20"/></g></svg> \ No newline at end of file diff --git a/deadlock-plugins/deadlock-extension/resources/styles/gettingStartedView.css b/deadlock-plugins/deadlock-extension/resources/styles/gettingStartedView.css index 5ae4f6fcf2fff5cd84531b5ab0e3f00fa46cf26f..afd0301f87f3b840c5beade48a0660955d2c0e82 100644 --- a/deadlock-plugins/deadlock-extension/resources/styles/gettingStartedView.css +++ b/deadlock-plugins/deadlock-extension/resources/styles/gettingStartedView.css @@ -1,5 +1,3 @@ -/* This file is used by gettingStarted via a <style> tag */ - .deadlock-getting-started-card-container { display: flex; justify-content: center; diff --git a/deadlock-plugins/deadlock-extension/setup-dev-env.sh b/deadlock-plugins/deadlock-extension/setup-dev-env.sh index fcd5d04ba4016f9026efbb77389456e196f77ee2..8689677d598142b5a7fac45c33b54ac3c242c415 100755 --- a/deadlock-plugins/deadlock-extension/setup-dev-env.sh +++ b/deadlock-plugins/deadlock-extension/setup-dev-env.sh @@ -6,4 +6,4 @@ mkdir -p /home/$USER/deadlock-extension/project mkdir -p /home/$USER/deadlock-extension/project-theia -cp -R ./dev/* /home/$USER/deadlock-extension +cp -R ./dev/ressources/* /home/$USER/deadlock-extension diff --git a/deadlock-plugins/deadlock-extension/src/config.prod.ts b/deadlock-plugins/deadlock-extension/src/config.prod.ts index 46ee6889446bcf153f9619125c3ab2bd4d753d65..cf6b1eca8dd4876a5ebd91f6bde4341be0003bc1 100644 --- a/deadlock-plugins/deadlock-extension/src/config.prod.ts +++ b/deadlock-plugins/deadlock-extension/src/config.prod.ts @@ -2,4 +2,11 @@ export const KEYCLOAK_DEVICE_AUTH_URL = 'https://auth.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/auth/device'; export const KEYCLOAK_TOKEN_CREATE_URL = 'https://auth.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/token'; export const KEYCLOAK_USER_INFO_URL = 'https://auth.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/userinfo'; +export const REGISTRY_MISSION_URL = 'registry.takima.io/deadlock/deadlock-challenges'; export const REJECT_UNAUTHORIZED = true; +export const ENABLE_AUTOMATIC_SAVE = true; +export const ENABLE_RECORDER_HTTP_SERVER = false; +export const RECORDER_HTTP_SERVER_PORT = 8751; +export const RECORDER_HTTP_SERVER_URL = `http://localhost:${RECORDER_HTTP_SERVER_PORT}`; +export const API_URL = 'https://api.deadlock.io/'; +export const API_QUERY_REFERER = 'https://takima.deadlock.io'; diff --git a/deadlock-plugins/deadlock-extension/src/config.staging.ts b/deadlock-plugins/deadlock-extension/src/config.staging.ts index e8ddb5e90e01601adc2b4f79ee07d241551c535b..912c56c27d281d634df899e61b57166d2fc2a50a 100644 --- a/deadlock-plugins/deadlock-extension/src/config.staging.ts +++ b/deadlock-plugins/deadlock-extension/src/config.staging.ts @@ -4,4 +4,11 @@ export const KEYCLOAK_TOKEN_CREATE_URL = 'https://auth.staging.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/token'; export const KEYCLOAK_USER_INFO_URL = 'https://auth.staging.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/userinfo'; +export const REGISTRY_MISSION_URL = 'registry.takima.io/deadlock/deadlock-challenges'; export const REJECT_UNAUTHORIZED = true; +export const ENABLE_AUTOMATIC_SAVE = true; +export const ENABLE_RECORDER_HTTP_SERVER = false; +export const RECORDER_HTTP_SERVER_PORT = 8751; +export const RECORDER_HTTP_SERVER_URL = `http://localhost:${RECORDER_HTTP_SERVER_PORT}`; +export const API_URL = 'https://api.staging.deadlock.io/'; +export const API_QUERY_REFERER = 'https://takima.staging.deadlock.io'; diff --git a/deadlock-plugins/deadlock-extension/src/config.ts b/deadlock-plugins/deadlock-extension/src/config.ts index a53b3ab5bba69c5e9d7ed0ef82f7662a8227933f..fcbe08addba35d99f5fd64632720c89235514ed1 100644 --- a/deadlock-plugins/deadlock-extension/src/config.ts +++ b/deadlock-plugins/deadlock-extension/src/config.ts @@ -5,3 +5,9 @@ export const KEYCLOAK_TOKEN_CREATE_URL = export const KEYCLOAK_USER_INFO_URL = 'https://auth.dev.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/userinfo'; export const REJECT_UNAUTHORIZED = false; +export const ENABLE_AUTOMATIC_SAVE = true; +export const ENABLE_RECORDER_HTTP_SERVER = false; +export const RECORDER_HTTP_SERVER_PORT = 8751; +export const RECORDER_HTTP_SERVER_URL = `http://localhost:${RECORDER_HTTP_SERVER_PORT}`; +export const API_URL = 'https://api.dev.deadlock.io/'; +export const API_QUERY_REFERER = 'https://takima.dev.deadlock.io'; diff --git a/deadlock-plugins/deadlock-extension/src/core/api.service.ts b/deadlock-plugins/deadlock-extension/src/core/api.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..b41170e7c48a64d0db59446afbc8ecdf47cc216f --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/core/api.service.ts @@ -0,0 +1,122 @@ +import axios, { AxiosInstance } from 'axios'; +import { API_QUERY_REFERER, API_URL } from '../config'; +import { GiteaPublicProperties } from '../model/giteaPublicProperties.model'; +import { SshKeyPair } from '../model/sshKeyPair.model'; +import { User } from '../model/user.model'; +import Controller from './controller'; +import ExtensionStore from './extensionStore'; +import KeycloakOAuth2DeviceFlowConnection from './keycloakOAuth2DeviceFlowConnection'; + +export default class ApiService { + private axiosInstance: AxiosInstance; + constructor( + private keycloackConnection: KeycloakOAuth2DeviceFlowConnection, + private extensionStore: ExtensionStore, + private controller: Controller, + ) { + this.axiosInstance = axios.create({ + baseURL: API_URL, + headers: { + 'Content-Type': 'application/json', + referer: API_QUERY_REFERER, + }, + }); + + this.initApiInterceptor(); + } + + initApiInterceptor() { + this.initRequestInterceptor(); + this.initResponseInterceptor(); + } + + private initRequestInterceptor() { + this.axiosInstance.interceptors.request.use( + async (config) => { + const accessToken = await this.extensionStore.getAccessToken(); + if (accessToken && config.headers) { + config.headers['authorization'] = `BEARER ${accessToken}`; + } + return config; + }, + (error) => { + return Promise.reject(error); + }, + ); + } + + private initResponseInterceptor() { + this.axiosInstance.interceptors.response.use( + (res) => { + return res; + }, + async (err) => { + return await this.handleResponseError(err); + }, + ); + } + + private async handleResponseError(err) { + const originalConfig = err.config; + if (err.response) { + // Access Token was expired + if (err.response.status === 401) { + if (!originalConfig._retry) { + originalConfig._retry = true; + return await this.onRetry(originalConfig); + } else if (originalConfig._retry) { + // IF REFRESH TOKEN NOT WORK, REQUEST NEW CONNECTION IN USER BROWSER + return await this.onInvalidRefreshToken(originalConfig); + } + } + if (err.response.status === 403 && err.response.data) { + return Promise.reject(err.response.data); + } + } + return Promise.reject(err); + } + + private async onRetry(originalConfig) { + try { + const storedRefreshToken = await this.extensionStore.getRefreshToken(); + const { accessToken, refreshToken } = await this.keycloackConnection.getToken({ + refreshToken: storedRefreshToken, + openLink: Controller.openBrowserWithUrl, + }); + + await this.extensionStore.setAccessToken(accessToken); + await this.extensionStore.setRefreshToken(refreshToken); + + this.axiosInstance.defaults.headers.common['authorization'] = `BEARER ${accessToken}`; + return this.axiosInstance(originalConfig); + } catch (_error) { + if (_error.response && _error.response.data) { + return Promise.reject(_error.response.data); + } + return await this.onInvalidRefreshToken(originalConfig); + } + } + + private async onInvalidRefreshToken(originalConfig) { + try { + await this.controller.authenticate(); + return this.axiosInstance(originalConfig); + } catch (_error) { + return Promise.reject(_error); + } + } + + getGiteaPublicProperties(): Promise<GiteaPublicProperties> { + return this.axiosInstance.get<GiteaPublicProperties>(`gitea`).then((res) => res.data); + } + + getUserSshKey(): Promise<SshKeyPair> { + return this.axiosInstance.put<SshKeyPair>(`users/gitea/keypair`).then((res) => res.data); + } + + getUser(): Promise<User> { + return this.axiosInstance.get<User>(`auth`).then((res) => { + return res.data; + }); + } +} diff --git a/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts b/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts index 9dcdc452f031924a31a33349fd1ce8566ffedee0..bcaea34d75703232e460fd717821db4245b80f54 100644 --- a/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts +++ b/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts @@ -1,12 +1,8 @@ import { commands } from 'vscode'; import { Command } from '../theia/command'; import Controller from './controller'; -import ExtensionStore from './extensionStore'; - export class CommandHandler { - private extensionStore: ExtensionStore; constructor(private controller: Controller) { - this.extensionStore = ExtensionStore.getInstance(); this.initCommandHandler(); } diff --git a/deadlock-plugins/deadlock-extension/src/core/config.ts b/deadlock-plugins/deadlock-extension/src/core/config.ts index 629d89ddb3183a72bfab6d8bb97bd6e15fc91049..c0849c9d760a422e78274cb749c924528cc57e31 100644 --- a/deadlock-plugins/deadlock-extension/src/core/config.ts +++ b/deadlock-plugins/deadlock-extension/src/core/config.ts @@ -1,19 +1,23 @@ import * as os from 'os'; import * as path from 'path'; +import isDocker from 'is-docker'; const homeDir = os.homedir(); // if we are on container, means the directory will depend differently -const onContainer = homeDir.includes('theia') || homeDir.includes('root'); +const onContainer = isDocker(); const deadlockExtensionPath = path.join(homeDir, 'deadlock-extension'); +const deadlockConfigPath = path.join(homeDir, '.deadlock'); +export const userSshKeyFolderPath = path.join(deadlockConfigPath, '.ssh'); + export const PROJECT_SRC_PATH = onContainer ? '/project' : path.join(homeDir, 'deadlock-extension', '/project'); -export const PROJECT_THEIA_PATH = onContainer - ? path.join('/home/project') +export const PROJECT_DEADLOCK_DESKTOP_PATH = onContainer + ? path.join('/home/deadlock/mission') : path.join(deadlockExtensionPath, 'project-theia'); -export const DOCS_PATH = path.join(path.join(onContainer ? '/home/theia' : deadlockExtensionPath), 'docs'); +export const DOCS_PATH = path.join(path.join(onContainer ? '/home/deadlock' : deadlockExtensionPath), 'docs'); export const CONFIG_PATH = onContainer ? '/home/config/' : path.join(deadlockExtensionPath, 'config'); @@ -21,8 +25,8 @@ export const USER_CHALLENGE_PATH = path.join(CONFIG_PATH, 'user-challenge.json') export const BRIEFING_FILE_NAME = 'briefing.md'; -export const ENV_FILE_PATH = path.join(PROJECT_THEIA_PATH, '/.env'); +export const ENV_FILE_PATH = path.join(PROJECT_DEADLOCK_DESKTOP_PATH, '/.env'); export const BASHRC_PATH = path.join(homeDir, '/.bashrc'); -export const SERVICES_PATHS_PATH = path.join(PROJECT_THEIA_PATH, '/paths.json'); +export const SERVICES_PATHS_PATH = path.join(PROJECT_DEADLOCK_DESKTOP_PATH, '/paths.json'); diff --git a/deadlock-plugins/deadlock-extension/src/core/controller.ts b/deadlock-plugins/deadlock-extension/src/core/controller.ts index 7d7d3bb15fec7d1d56978bac11aa52d28b86716f..00d6a14d1ecc6a766f4dd6d4990317cb2d780b98 100644 --- a/deadlock-plugins/deadlock-extension/src/core/controller.ts +++ b/deadlock-plugins/deadlock-extension/src/core/controller.ts @@ -1,11 +1,17 @@ import * as vscode from 'vscode'; import { KEYCLOAK_DEVICE_AUTH_URL, KEYCLOAK_TOKEN_CREATE_URL, KEYCLOAK_USER_INFO_URL } from '../config'; -import { OPEN_QUICK_SETUP_COMMAND } from '../theia/command'; +import { log } from '../recorder/utils'; import BriefingView from '../view/briefingView'; import QuickSetupView from '../view/quickSetupView'; import { CHOOSE_MISSION_WORKDIR_COMMAND, CommandHandler, OPEN_URL_IN_BROWSER_COMMAND } from './commandHandler'; import ExtensionStore from './extensionStore'; import KeycloakOAuth2DeviceFlowConnection from './keycloakOAuth2DeviceFlowConnection'; +import ApiService from './api.service'; +import { createSshKeyFiles, isSshKeyPairExist } from './sshKeyManager'; +import { GiteaPublicProperties } from '../model/giteaPublicProperties.model'; +import { User } from '../model/user.model'; +import { Mission } from './mission/mission'; +import { MissionDevContainer } from './mission/missionDevContainer'; export default class Controller { public connection: KeycloakOAuth2DeviceFlowConnection; @@ -13,6 +19,7 @@ export default class Controller { private briefingView: BriefingView; private quickSetupView: QuickSetupView; private extensionStore: ExtensionStore; + private apiService: ApiService; constructor(private context: vscode.ExtensionContext) { this.extensionStore = ExtensionStore.getInstance(context); @@ -25,18 +32,30 @@ export default class Controller { KEYCLOAK_USER_INFO_URL, ); + this.apiService = new ApiService(this.connection, this.extensionStore, this); + this.init(); } + private async init() { const that = this; vscode.window.registerUriHandler({ handleUri(uri: vscode.Uri) { - const queryParams: URLSearchParams = new URLSearchParams(uri.query); - const action: string | null = queryParams.get('action'); + const queryParams = new URLSearchParams(uri.query); + const action = queryParams.get('action'); + // TODO: Should we follow eslint no-case-declarations ? + const missionId = queryParams.get('missionId'); + const missionVersion = queryParams.get('missionVersion'); + log('Opening link', uri); switch (action) { - case 'open-challenge': - that.launchMission(queryParams.get('missionId')); + case 'open-mission': + if (!missionId || !missionVersion) { + vscode.window.showErrorMessage('Identifiant ou version de la mission incorrect'); + } else { + that.launchMission(missionId, missionVersion); + } + break; default: @@ -45,9 +64,9 @@ export default class Controller { }, }); - const exensionStorage = ExtensionStore.getInstance(); - this.quickSetupView.isAlreadyConnected = !!(await exensionStorage.getAccessToken()); + this.quickSetupView.isAlreadyConnected = (await this.extensionStore.getAccessToken()) !== undefined; } + async chooseMissionWorkdir() { const actualMissionWorkDir = this.extensionStore.getMissionWorkdir(); @@ -67,43 +86,57 @@ export default class Controller { this.extensionStore.setMissionWorkdir(folderUri[0].path); } } + public async clear() { - const exensionStorage = ExtensionStore.getInstance(); - await exensionStorage.clear(); + await this.extensionStore.clear(); this.quickSetupView.isAlreadyConnected = false; } + public async createSshKeyPairIfNotExist() { + if (isSshKeyPairExist()) return; + const { publicKey, privateKey } = await this.apiService.getUserSshKey(); + await createSshKeyFiles(publicKey, privateKey); + } + public async authenticate() { - // WARN generate a new device code every time student clicks on log in button. Should I keep it ?\ - // The answer might be 'yes' because when the student is already authenticated, the log in button should be disabled. await this.connection.registerDevice(); const tokens = await this.connection.getToken({ openLink: Controller.openBrowserWithUrl }); await this.extensionStore.setAccessToken(tokens.accessToken); await this.extensionStore.setRefreshToken(tokens.refreshToken); + await this.createSshKeyPairIfNotExist(); this.quickSetupView.isAlreadyConnected = true; } + public static openBrowserWithUrl(url: string) { vscode.commands.executeCommand(OPEN_URL_IN_BROWSER_COMMAND.cmd, vscode.Uri.parse(url)); } - public async launchMission(missionId: string | null) { - if (missionId) { - vscode.window.showInformationMessage(`vous lancez la mission ${missionId}`); - const hadMissionWorkdir = this.extensionStore.getMissionWorkdir() !== undefined; - if (!hadMissionWorkdir) { - await vscode.commands.executeCommand(CHOOSE_MISSION_WORKDIR_COMMAND.cmd); - } - - const hadBeenConnected = (await this.extensionStore.getAccessToken()) !== undefined; + public async launchMission(missionId: string, missionVersion: string) { + vscode.window.showInformationMessage(`vous lancez la mission ${missionId}`); + const hadMissionWorkdir = this.extensionStore.getMissionWorkdir() !== undefined; + if (!hadMissionWorkdir) { + await vscode.commands.executeCommand(CHOOSE_MISSION_WORKDIR_COMMAND.cmd); + } - if (!hadBeenConnected) { - this.authenticate(); - vscode.window.showInformationMessage('Nouvelle connexion validée'); - } else { - vscode.window.showInformationMessage('Déjà connecté: session récupérée'); - } + const hadBeenConnected = (await this.extensionStore.getAccessToken()) !== undefined; - vscode.commands.executeCommand(OPEN_QUICK_SETUP_COMMAND.cmd); + if (!hadBeenConnected) { + await this.authenticate(); + vscode.window.showInformationMessage('Connexion validée'); } + + const mission = new Mission(missionId, missionVersion); + + const missionsWorkdir = this.extensionStore.getMissionWorkdir() ?? ''; + const user: User = await this.apiService.getUser(); + const giteaPublicProperties: GiteaPublicProperties = await this.apiService.getGiteaPublicProperties(); + + const missionDevcontainer = new MissionDevContainer(missionsWorkdir, user, mission, giteaPublicProperties); + + vscode.window.showInformationMessage( + 'opening inside folder ' + this.extensionStore.getMissionWorkdir()! + '/' + missionId, + ); + + await missionDevcontainer.open(); } } diff --git a/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts b/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts index 5d4497c98e99a9929c8e88368d2c8a445bb602cc..1bb67b4261b4e4b69d76ff489b538d8dc0c11c1d 100644 --- a/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts +++ b/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts @@ -16,7 +16,7 @@ export default class ExtensionStore { public async clear() { if (this.globalStorage.keys()) { - for (let key of this.globalStorage.keys()) { + for (const key of this.globalStorage.keys()) { this.globalStorage.update(key, undefined); } } @@ -42,35 +42,35 @@ export default class ExtensionStore { window.showInformationMessage(`Nouveau dossier de stockage des missions: ${path}`); } - public async getAccessToken() { + public getAccessToken(): Thenable<string | undefined> { return this.readSecret(StoreKey.AccessTokenKey); } - public async getRefreshToken() { + public getRefreshToken(): Thenable<string | undefined> { return this.readSecret(StoreKey.RefreshTokenKey); } - public async setAccessToken(accessToken: string) { + public setAccessToken(accessToken: string): Thenable<void> { if (!accessToken) { log('Attempt to store undefined access token'); - return; + return Promise.resolve(); } return this.storeSecret(StoreKey.AccessTokenKey, accessToken); } - public async setRefreshToken(refreshToken: string) { + public setRefreshToken(refreshToken: string): Thenable<void> { if (!refreshToken) { log('Attempt to store undefined refresh token'); - return; + return Promise.resolve(); } return this.storeSecret(StoreKey.RefreshTokenKey, refreshToken); } - private async storeSecret(key: StoreKey, value: string) { - this.secretStorage.store(key, value); + private storeSecret(key: StoreKey, value: string): Thenable<void> { + return this.secretStorage.store(key, value); } - private async readSecret(key: StoreKey) { + private readSecret(key: StoreKey): Thenable<string | undefined> { return this.secretStorage.get(key); } } diff --git a/deadlock-plugins/deadlock-extension/src/core/gitMission.ts b/deadlock-plugins/deadlock-extension/src/core/gitMission.ts index 9e739afc67856fa5f0f13e735acde4d5e2f4554a..3bed6fd3f7d48a2dfcfa785cbf38a84cc76af3d0 100644 --- a/deadlock-plugins/deadlock-extension/src/core/gitMission.ts +++ b/deadlock-plugins/deadlock-extension/src/core/gitMission.ts @@ -1,5 +1,5 @@ import simpleGit, { SimpleGit, SimpleGitOptions } from 'simple-git'; -import { error } from '../recorder/utils'; +import { error, log } from '../recorder/utils'; import { PROJECT_SRC_PATH } from './config'; import UserConfig from './userConfig'; @@ -7,7 +7,12 @@ const util = require('util'); const exec = util.promisify(require('child_process').exec); const DEFAULT_REMOTE = 'origin'; -const DEFAULT_BRANCH = 'master'; + +export enum Branch { + MASTER = 'master', + DEFAULT = MASTER, + LIVE = 'live', +} export default class GitMission { private git: SimpleGit; @@ -27,10 +32,10 @@ export default class GitMission { `eval "$(ssh-agent -s)" && ssh-keyscan -p ${this.userConfig.getGiteaSshPort()} -H ${this.userConfig.getGiteaHost()} >> ~/.ssh/known_hosts`, ); - console.log(stdout); + log(stdout); if (err) { - console.error(stderr); + error(stderr); throw new Error(err); } } @@ -41,12 +46,13 @@ export default class GitMission { async init() { try { - console.log('Setup ssh agent'); + log('Setup ssh agent'); await this.setupSshAgent(); - console.log('Init Git mission..'); + log('Init Git mission..'); const remote = await this.readRemote(); + if (remote === DEFAULT_REMOTE) { return Promise.resolve(this); } @@ -54,6 +60,7 @@ export default class GitMission { const remotePath = this.getRemotePath(); await this.git.init(); + await this.git.addRemote(DEFAULT_REMOTE, remotePath); await this.git.addConfig('user.email', this.userConfig.getCurrentUserDetails().email, false, 'system'); await this.git.addConfig( @@ -87,20 +94,47 @@ export default class GitMission { return this.git.fetch(DEFAULT_REMOTE); } - pull() { - return this.git.pull(DEFAULT_REMOTE, DEFAULT_BRANCH, { '--rebase': 'true' }); + pull(branch?: string) { + return this.git.pull(DEFAULT_REMOTE, branch ?? Branch.DEFAULT, { '--rebase': 'true' }); } addAll() { return this.git.add('.'); } - commit(message) { - return this.git.commit(message); + commit(message: string, options?: string[]) { + return this.git.commit(message, options ?? []); } push() { - return this.git.push(DEFAULT_REMOTE, DEFAULT_BRANCH); + return this.git.push(DEFAULT_REMOTE); + } + + createLocalBranch(branch: string) { + return this.git.checkout(['-b', branch]); + } + + createRemoteBranch(branch: string) { + return this.git.push(['-u', DEFAULT_REMOTE, branch]); + } + + setUpstream(branch: string) { + return this.git.branch(['-u', DEFAULT_REMOTE, branch]); + } + + createBranch(branch: string) { + const createBranchLocally = this.createLocalBranch(branch); + const createRemoteBranch = this.createRemoteBranch(branch); + + return Promise.all([createBranchLocally, createRemoteBranch]); + } + + checkout(branch: string) { + return this.git.checkout(branch); + } + + merge(options?: string[]) { + return this.git.merge(options ?? []); } async isRemoteRepoExist() { diff --git a/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.test.ts b/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.test.ts index 006d71388862f23244deef583bda1675242eb2e8..5797fbef288f9211edf3cf56472b0e474e8b790c 100644 --- a/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.test.ts +++ b/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.test.ts @@ -27,14 +27,14 @@ export default class KeycloakOAuth2DeviceFlowConnectionTest { log(`click here: ${link}`); }; - let tokens = await this.connection.getToken({ openLink: openLinkPlaceholder }); + const tokens = await this.connection.getToken({ openLink: openLinkPlaceholder }); log('tokens', tokens); if (!tokens?.refreshToken) { log("refresh token doesn't exist"); return; } - let refreshedTokens = await this.connection.getToken({ + const refreshedTokens = await this.connection.getToken({ refreshToken: tokens.refreshToken, openLink: openLinkPlaceholder, }); diff --git a/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.ts b/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.ts index e0fbb38bf3c481e4ddafe1262b2d0b40c281981e..010a224eec573ac4d6f38d3d23430d616ed961c6 100644 --- a/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.ts +++ b/deadlock-plugins/deadlock-extension/src/core/keycloakOAuth2DeviceFlowConnection.ts @@ -65,9 +65,9 @@ export default class KeycloakOAuth2DeviceFlowConnection { } } - public async getToken(args: { refreshToken?: string; openLink: (link: string) => void }) { + public async getToken(args: { refreshToken?: string; openLink?: (link: string) => void }) { const { refreshToken, openLink } = args; - if (!!refreshToken) { + if (refreshToken !== undefined) { await this.createUserAuthentication({ url: this.tokenUrl, body: (() => { @@ -85,6 +85,7 @@ export default class KeycloakOAuth2DeviceFlowConnection { await this.registerDevice(); } try { + if (!openLink) throw new Error('You neeed to provide a way to open a link for oauth device flow protocol'); openLink(this.deviceAuthorizationRequestResponse.verification_uri_complete!); await this.createUserAuthentication({ url: this.tokenUrl, @@ -153,6 +154,7 @@ export default class KeycloakOAuth2DeviceFlowConnection { agent: new https.Agent({ rejectUnauthorized: REJECT_UNAUTHORIZED }), }); userAuthenticationRequestResponseCode = userAuthenticationRequestResponse.status; + log(` Status ${userAuthenticationRequestResponseCode}`); switch (userAuthenticationRequestResponseCode) { case HttpStatusCode.BAD_REQUEST: { await this.onUserAuthenticationBadRequest(userAuthenticationRequestResponse); diff --git a/deadlock-plugins/deadlock-extension/src/core/metadataProvider.ts b/deadlock-plugins/deadlock-extension/src/core/metadataProvider.ts deleted file mode 100644 index a598545b60abeb4628fb4f5e15949b5dcd391b18..0000000000000000000000000000000000000000 --- a/deadlock-plugins/deadlock-extension/src/core/metadataProvider.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { exec, ExecException } from 'child_process'; -import * as fs from 'fs'; -import { userConfig } from '../extension'; -import { error as err, log } from '../recorder/utils'; -import { BASHRC_PATH, ENV_FILE_PATH } from './config'; - -export default class MetadataProvider { - public static loadPathsToJson(filePath: string) { - const portToPath = userConfig.getPaths(); - const serviceNameToPath = this.getServicePathFromPortPath(portToPath); - const jsonValue = Object.fromEntries(serviceNameToPath); - const fileContent = JSON.stringify(jsonValue, null, 4) + '\n'; - fs.writeFileSync(filePath, fileContent, { flag: 'w+' }); - } - - public static loadPathsToEnvVariables(): void { - const portToPath = userConfig.getPaths(); - const serviceNameToPath = this.getServicePathFromPortPath(portToPath); - let fileContent = ''; - for (const [serviceName, servicePath] of serviceNameToPath.entries()) { - fileContent += `${serviceName}=${servicePath} \n`; - } - fs.writeFileSync(ENV_FILE_PATH, fileContent, { flag: 'w+' }); - const bashrcAppendContent = ` -export $(cat ${ENV_FILE_PATH} | xargs -L 1) -`; - fs.writeFileSync(BASHRC_PATH, bashrcAppendContent, { flag: 'a+' }); - exec(`. ${BASHRC_PATH}`, execCallback); - } - - /** - * two formats to handle: (key="front", value="3001") | (key="8080": value="HXW3fnKwUULrfKS1-cdb")\ - * expected result: (key="front", value="localhost:3001") | (key="cdb", value="HXW3fnKwUULrfKS1-cdb") - * - */ - private static getServicePathFromPortPath(portToPath: Map<number, string>): Map<string, string> { - const serviceToPath = new Map<string, string>(); - for (const [port, path] of Object.entries(portToPath)) { - let key = ''; - let value = ''; - if (isNumeric(port)) { - key = path.split('-').slice(-1); - value = `${path}.${userConfig.getHost()}`; - } else { - key = port; - value = `localhost:${path}`; - } - serviceToPath.set(key, value); - } - return serviceToPath; - } -} - -function isNumeric(val: string) { - return /^\d+$/.test(val); -} - -function execCallback(error: ExecException | null, stdout: string, stderr: string) { - if (error) { - err(`error: ${error.message}`); - return; - } - if (stderr) { - err(`stderr: ${stderr}`); - return; - } - log(stdout); -} diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/devContainer.ts b/deadlock-plugins/deadlock-extension/src/core/mission/devContainer.ts new file mode 100644 index 0000000000000000000000000000000000000000..29db6bb3c01d7e6616e6f9141c55e5bdbf7c8948 --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/core/mission/devContainer.ts @@ -0,0 +1,44 @@ +export interface DockerfileSpecific { + image?: string; + dockerFile?: string; + context?: string; + 'build.args'?: string[]; + 'build.target'?: string; + 'build.cacheFrom'?: string; + containerEnv?: string; + containerUser?: string; + mounts?: string[]; + workspaceMount?: string; + workspaceFolder?: string; + runArgs?: string[]; +} + +export interface Base { + name?: string; + forwardPorts?: string[]; + portsAttributes?: string[]; + otherPortsAttributes?: string[]; + remoteEnv?: string; + remoteUser?: string; + updateRemoteUserUID?: string; + userEnvProbe?: string; + overrideCommand?: boolean; + features?: string[]; + shutdownAction?: string; +} + +export interface VSCodespecific { + extensions?: string[]; + settings?: Record<string, unknown>; + devPort?: string; +} + +export interface LifecycleScripts { + initializeCommand?: string; + onCreateCommand?: string; + updateContentCommand?: string; + postCreateCommand?: string; + postStartCommand?: string; + postAttachCommand?: string; + waitFor?: string; +} diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/mission.ts b/deadlock-plugins/deadlock-extension/src/core/mission/mission.ts new file mode 100644 index 0000000000000000000000000000000000000000..ba27109c96a09ddd2633e3ff21045b3b8f192da9 --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/core/mission/mission.ts @@ -0,0 +1,9 @@ +export class Mission { + readonly id: string; + readonly version: string; + + constructor(id: string, version: string) { + this.id = id; + this.version = version; + } +} diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts b/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts new file mode 100644 index 0000000000000000000000000000000000000000..a8dc306c1de9a674287cc0974451379e8275a12e --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts @@ -0,0 +1,113 @@ +import { userSshKeyFolderPath } from '../config'; +import { Base, DockerfileSpecific, LifecycleScripts, VSCodespecific } from './devContainer'; +import { existsSync } from 'fs'; +import { mkdir, writeFile } from 'fs/promises'; +import { Mission } from './mission'; +import { User, UserChallengeJson } from '../../model/user.model'; +import { GiteaPublicProperties } from '../../model/giteaPublicProperties.model'; +import { commands, Uri } from 'vscode'; +import assert = require('assert'); + +const DOCKER_IMAGE_URL = 'registry.takima.io/deadlock/deadlock-challenges'; + +export class MissionDevContainer { + private isInit = false; + + private readonly dirs = { + missionWorkdir: `${this.missionsWorkdir}/${this.mission.id}`, + config: `${this.missionsWorkdir}/${this.mission.id}/.config`, + devcontainer: `${this.missionsWorkdir}/${this.mission.id}/.devcontainer`, + mounted: `${this.missionsWorkdir}/${this.mission.id}/mounted`, + }; + + constructor( + private readonly missionsWorkdir: string, + private readonly user: User, + private readonly mission: Mission, + private readonly giteaProperties: GiteaPublicProperties, + ) {} + + async open() { + if (!this.isInit) { + await this.init(); + } + assert(existsSync(this.dirs.missionWorkdir)); + await commands.executeCommand('remote-containers.openFolder', Uri.file(this.dirs.missionWorkdir)); + } + + private async init() { + if (this.isInit) { + throw new Error(`${MissionDevContainer.constructor.name} Already initialized`); + } + this.isInit = true; + await this.createDirectories(...Object.values(this.dirs)); + await this.createDevContainerFile(); + await this.createUserChallengeJsonFile(); + } + + private createUserChallengeJsonFile() { + return writeFile( + `${this.dirs.config}/user-challenge.json`, + (() => { + const userChallengeJson: UserChallengeJson = { + giteaHost: this.giteaProperties.sshHost, + giteaSshPort: this.giteaProperties.sshPort, + username: this.user.id.split('-').join(''), + email: `${this.user.id.split('-').join('')}@deadlock.io`, + missionId: this.mission.id, + remoteGitUsername: this.user.id.split('-').join(''), + currentUserDetails: this.user.details, + remoteUserDetails: this.user.details, + }; + return JSON.stringify(userChallengeJson, null, 2); + })(), + ); + } + + private createDevContainerFile(options?: Partial<DockerfileSpecific & Base & VSCodespecific & LifecycleScripts>) { + const remoteUserHomeDir = '/home/deadlock'; + const remoteMissionDir = `${remoteUserHomeDir}/mission/`; + const remoteGiteaWorkDir = `/workdir`; + const hostMissionDevcontainerFileDir = `${this.dirs.devcontainer}/devcontainer.json`; + + const image = `${DOCKER_IMAGE_URL}/${this.mission.id}:${this.mission.version}`; + + return writeFile( + hostMissionDevcontainerFileDir, + (() => { + const devcontainer: Partial<DockerfileSpecific & Base & VSCodespecific & LifecycleScripts> = { + name: `deadlock-${this.mission.id}`, + image, + extensions: ['Deadlock.deadlock-coding'], + remoteUser: 'deadlock', + mounts: [ + `source=${userSshKeyFolderPath},target=/tmp/.ssh,type=bind,consistency=cached,readonly`, + `source=${this.dirs.config},target=/home/config/,type=bind,consistency=cached,readonly`, + 'source=/etc/hosts,target=/etc/hosts,type=bind,consistency=cached,readonly', + ], + userEnvProbe: 'interactiveShell', + settings: { + 'terminal.integrated.defaultProfile.linux': 'bash', + 'terminal.integrated.profiles.linux': { + bash: { + path: '/bin/bash', + }, + }, + }, + overrideCommand: false, + shutdownAction: 'stopContainer', + workspaceMount: `source=${this.dirs.mounted},target=${remoteMissionDir},type=bind`, + workspaceFolder: `${remoteMissionDir}`, + onCreateCommand: `cp -R ${remoteGiteaWorkDir}/* ${remoteMissionDir}`, + runArgs: ['--privileged'], + ...options, + }; + return JSON.stringify(devcontainer, null, 2); + })(), + ); + } + + private createDirectories(...directoryPaths: string[]) { + return Promise.all(directoryPaths.map((directoryPath) => mkdir(directoryPath, { recursive: true }))); + } +} diff --git a/deadlock-plugins/deadlock-extension/src/core/sshKeyManager.ts b/deadlock-plugins/deadlock-extension/src/core/sshKeyManager.ts new file mode 100644 index 0000000000000000000000000000000000000000..94d37e732cb725b21a9faf2c0213c25584e769ba --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/core/sshKeyManager.ts @@ -0,0 +1,31 @@ +import * as fs from 'fs'; +import { userSshKeyFolderPath } from './config'; + +export function isSshKeyPairExist(): boolean { + return isPrivateKeyExist() && isPublicKeyExist(); +} + +function isPublicKeyExist(): boolean { + return fs.existsSync(`${userSshKeyFolderPath}/id_rsa.pub`); +} + +function isPrivateKeyExist(): boolean { + return fs.existsSync(`${userSshKeyFolderPath}/id_rsa`); +} + +export async function createSshKeyFiles(publicKey: string, privateKey: string) { + await createSshKeyFolderIfNotExist(userSshKeyFolderPath); + await fs.promises.writeFile(`${userSshKeyFolderPath}/id_rsa.pub`, publicKey); + + await fs.promises.writeFile(`${userSshKeyFolderPath}/id_rsa`, privateKey, { mode: 0o600 }); +} + +async function createSshKeyFolderIfNotExist(sshKeyFolderPath) { + if (!isSshKeyFolderExist(sshKeyFolderPath)) { + await fs.promises.mkdir(sshKeyFolderPath, { recursive: true }); + } +} + +export function isSshKeyFolderExist(sshKeyFolderPath: string) { + return fs.existsSync(sshKeyFolderPath); +} diff --git a/deadlock-plugins/deadlock-extension/src/core/userConfig.ts b/deadlock-plugins/deadlock-extension/src/core/userConfig.ts index 46295519cf5a44668fabe677467787ecbfd7276e..d881fb9638bfcc8043cac525f37bcaa935062b6b 100644 --- a/deadlock-plugins/deadlock-extension/src/core/userConfig.ts +++ b/deadlock-plugins/deadlock-extension/src/core/userConfig.ts @@ -14,16 +14,9 @@ * "missionId":"code_persist_cdb_crud" * } */ - +import { UserDetails } from '../model/user.model'; import { error } from '../recorder/utils'; -export interface UserDetails { - firstName: string; - lastName: string; - avatarUrl: string; - email: string; -} - export default abstract class UserConfig { private userConfigJson: any | undefined; diff --git a/deadlock-plugins/deadlock-extension/src/customTypings/HttpStatusCode.ts b/deadlock-plugins/deadlock-extension/src/customTypings/HttpStatusCode.ts index e5bb61ccb9a971188808ff21d9693ae63679e851..8c7d46c65ef2f0eafad1b8f58c13de46a500ee8b 100644 --- a/deadlock-plugins/deadlock-extension/src/customTypings/HttpStatusCode.ts +++ b/deadlock-plugins/deadlock-extension/src/customTypings/HttpStatusCode.ts @@ -158,7 +158,7 @@ export enum HttpStatusCode { /** * Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet - * been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the + * been provided. The response must include a WWW-Authenticate header field containing a mission applicable to the * requested resource. See Basic access authentication and Digest access authentication. 401 semantically means * "unauthenticated",i.e. the user does not have the necessary credentials. */ diff --git a/deadlock-plugins/deadlock-extension/src/extension.ts b/deadlock-plugins/deadlock-extension/src/extension.ts index 506ad15ae186c4a443ddda1651c5a02ff2cb1bce..b025f980911c8ad90d924c388f4821609a9a8469 100644 --- a/deadlock-plugins/deadlock-extension/src/extension.ts +++ b/deadlock-plugins/deadlock-extension/src/extension.ts @@ -1,7 +1,5 @@ import * as vscode from 'vscode'; -import { SERVICES_PATHS_PATH } from './core/config'; import Controller from './core/controller'; -import MetadataProvider from './core/metadataProvider'; import { error } from './recorder/utils'; import { DepNodeProvider } from './theia/deadlockPanel'; import UserConfigTheia from './theia/userConfigTheia'; @@ -11,7 +9,7 @@ export const userConfig = new UserConfigTheia(); export async function activate(context: vscode.ExtensionContext) { vscode.window.showInformationMessage('Bienvenue sur Deadlock!'); - const controller = new Controller(context); + new Controller(context); const workspaceFolders = vscode.workspace.workspaceFolders?.toString() ?? ''; if (!workspaceFolders) vscode.window.showInformationMessage('Pas de répertoires ouverts'); @@ -23,7 +21,4 @@ export async function activate(context: vscode.ExtensionContext) { } catch (e) { error('Cannot init userConfig'); } - - MetadataProvider.loadPathsToEnvVariables(); - MetadataProvider.loadPathsToJson(`${SERVICES_PATHS_PATH}`); } diff --git a/deadlock-plugins/deadlock-extension/src/model/giteaPublicProperties.model.ts b/deadlock-plugins/deadlock-extension/src/model/giteaPublicProperties.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..5c10aba3fd8e3a24e20ae78b992e23e06a43b29b --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/model/giteaPublicProperties.model.ts @@ -0,0 +1,6 @@ +export interface GiteaPublicProperties { + apiHost: string; + sshHost: string; + port: number; + sshPort: number; +} diff --git a/deadlock-plugins/deadlock-extension/src/model/sshKeyPair.model.ts b/deadlock-plugins/deadlock-extension/src/model/sshKeyPair.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..4e1868d587295b566eca654b3aa06a168e971345 --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/model/sshKeyPair.model.ts @@ -0,0 +1,4 @@ +export interface SshKeyPair { + privateKey: string; + publicKey: string; +} diff --git a/deadlock-plugins/deadlock-extension/src/model/user.model.ts b/deadlock-plugins/deadlock-extension/src/model/user.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..7744bdc8f081d3c950926eb76932c3dc6078225b --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/model/user.model.ts @@ -0,0 +1,37 @@ +import { GiteaPublicProperties } from './giteaPublicProperties.model'; + +export interface User { + id: string; + details: UserDetails; +} + +export interface UserDetails { + firstName: string; + lastName: string; + organization: string; + email: string; + login: string; + roles: string[]; + avatarUrl: string; +} + +export interface UserChallengeJson { + giteaHost: string; + giteaSshPort: number; + username: string; + email: string; + missionId: string; + remoteGitUsername: string; + currentUserDetails: UserDetails; + remoteUserDetails: UserDetails; +} + +export interface UserChallengeJson2 { + gitea: Pick<GiteaPublicProperties, 'sshPort' | 'sshHost'>; + username: string; + email: string; + missionId: string; + remoteGitUsername: string; + currentUserDetails: UserDetails; + remoteUserDetails: UserDetails; +} diff --git a/deadlock-plugins/deadlock-extension/src/recorder/command-recorder.ts b/deadlock-plugins/deadlock-extension/src/recorder/command-recorder.ts index 17865f4da95b95c0572a67cbb59456bb0fb82657..1a68a0b8ea208688101e267ae24b329a31885af6 100644 --- a/deadlock-plugins/deadlock-extension/src/recorder/command-recorder.ts +++ b/deadlock-plugins/deadlock-extension/src/recorder/command-recorder.ts @@ -1,7 +1,7 @@ import GitMission from '../core/gitMission'; -import { error, commitAndPushCode, CommitFrom, log } from './utils'; -const async = require('async'); -const fs = require('fs'); +import { CommitFrom, error, updateRemote } from './utils'; +import * as async from 'async'; +import * as fs from 'fs'; class Command { public still: boolean; @@ -33,7 +33,7 @@ export default class CommandRecorder { if (!this.commandsInProgress.has(pid)) { this.commandsInProgress.set(pid, new Command(pid, command)); try { - this.queue.push(async () => await commitAndPushCode(this.gitMission, CommitFrom.Run)); + this.queue.push(async () => await updateRemote(this.gitMission, CommitFrom.Run)); } catch (e) { console.error('Cannot send user code to git'); console.error(e); @@ -47,7 +47,7 @@ export default class CommandRecorder { let lastLineIndexWatched = 0; setInterval(() => { try { - const trace = fs.readFileSync('/home/theia/.bash_history', 'utf8'); + const trace = fs.readFileSync('/home/deadlock/.bash_history', 'utf8'); const lines = trace.split(/\r?\n/); this.commandsInProgress.forEach((command) => (command.still = false)); diff --git a/deadlock-plugins/deadlock-extension/src/recorder/index.ts b/deadlock-plugins/deadlock-extension/src/recorder/index.ts index 51f4a3a41cd3a2804c1ac81a2e2b5f5c15efbb72..0927ecf4f9af934c3d3ce1b92339570c9d0abaef 100644 --- a/deadlock-plugins/deadlock-extension/src/recorder/index.ts +++ b/deadlock-plugins/deadlock-extension/src/recorder/index.ts @@ -1,19 +1,24 @@ +import { Branch } from '../core/gitMission'; +import { ENABLE_AUTOMATIC_SAVE } from '../config'; import CommandRecorder from './command-recorder'; import GitMission from '../core/gitMission'; import UserConfigNode from './userConfigNode'; -import { PROJECT_SRC_PATH, PROJECT_THEIA_PATH } from '../core/config'; -import { copyProjectSources, clearFilesExceptGit, log, error, renameTempToUserGitFiles } from './utils'; +import { PROJECT_DEADLOCK_DESKTOP_PATH, PROJECT_SRC_PATH } from '../core/config'; +import { clearFilesExceptGit, copyProjectSources, error, log, renameTempToUserGitFiles } from './utils'; import UserConfig from '../core/userConfig'; +import HttpServer from './services/http-server'; +import { ENABLE_RECORDER_HTTP_SERVER } from '../config'; +import AutomaticSave from './services/automatic-save'; export default class Recorder { async setupProject(userConfig: UserConfig, gitMission?: GitMission) { log('Setup user project..'); if (!userConfig.isProfessor()) { - await copyProjectSources(PROJECT_SRC_PATH, PROJECT_THEIA_PATH, ['.git/']); + await copyProjectSources(PROJECT_SRC_PATH, PROJECT_DEADLOCK_DESKTOP_PATH, ['.git/']); if (gitMission) { - renameTempToUserGitFiles(PROJECT_THEIA_PATH, gitMission.author); + renameTempToUserGitFiles(PROJECT_DEADLOCK_DESKTOP_PATH, gitMission.author); log('Starting CommandRecorder..'); new CommandRecorder(gitMission).run(); @@ -21,13 +26,14 @@ export default class Recorder { error('Cannot start command recorder, gitMission not found'); } } else { - await copyProjectSources(PROJECT_SRC_PATH, PROJECT_THEIA_PATH); + await copyProjectSources(PROJECT_SRC_PATH, PROJECT_DEADLOCK_DESKTOP_PATH); } } async setupFromRemoteRepo(gitMission: GitMission) { log('Check if remote repo exist'); const isRemoteRepoExist = await gitMission.isRemoteRepoExist(); + if (isRemoteRepoExist) { // rm all except git directory pull remote code and setup log('Cleaning files to pull repo'); @@ -35,7 +41,14 @@ export default class Recorder { await clearFilesExceptGit(PROJECT_SRC_PATH); log('Pulling user repo'); - await gitMission.pull(); + + await gitMission.fetch(); + await gitMission.checkout(Branch.MASTER); + await gitMission.checkout(Branch.LIVE); + } else { + await gitMission.commit('initial commit', ['--allow-empty']); + await gitMission.createRemoteBranch(Branch.DEFAULT); + await gitMission.createBranch(Branch.LIVE); } } @@ -49,6 +62,7 @@ export default class Recorder { await userConfig.init(); log('Init GitMission'); gitMission = await new GitMission(userConfig).init(); + await this.setupFromRemoteRepo(gitMission); } catch (e) { error('Cannot setup user repo.'); @@ -60,6 +74,20 @@ export default class Recorder { error('Error while setup project sources'); error(e); } + + try { + if (ENABLE_AUTOMATIC_SAVE) new AutomaticSave(PROJECT_DEADLOCK_DESKTOP_PATH, gitMission); + } catch (e) { + error('Error while setup automatic save'); + error(e); + } + + try { + if (ENABLE_RECORDER_HTTP_SERVER) new HttpServer(gitMission); + } catch (e) { + error('Error while setup recorder http server'); + error(e); + } } } diff --git a/deadlock-plugins/deadlock-extension/src/recorder/package-lock.json b/deadlock-plugins/deadlock-extension/src/recorder/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..851d67cb716f929309c6cc858c7b8b1f5dc3c274 --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/recorder/package-lock.json @@ -0,0 +1,1456 @@ +{ + "name": "deadlock-recorder", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "deadlock-recorder", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.3", + "express": "^4.18.0" + }, + "devDependencies": { + "@types/express": "^4.17.13" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "17.0.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.29.tgz", + "integrity": "sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", + "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + } + }, + "dependencies": { + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "@types/node": { + "version": "17.0.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.29.tgz", + "integrity": "sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA==", + "dev": true + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "body-parser": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", + "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + } + } +} diff --git a/deadlock-plugins/deadlock-extension/src/recorder/package.json b/deadlock-plugins/deadlock-extension/src/recorder/package.json index 3e8d60d9f770b499340fd375b4a7f628120e272e..bb63dc16d2dd366d4d5ac941c1b8c0a1c20df485 100644 --- a/deadlock-plugins/deadlock-extension/src/recorder/package.json +++ b/deadlock-plugins/deadlock-extension/src/recorder/package.json @@ -9,6 +9,10 @@ "author": "", "license": "MIT", "dependencies": { - "deadlock-coding": "^0.0.1" + "chokidar": "^3.5.3", + "express": "^4.18.0" + }, + "devDependencies": { + "@types/express": "^4.17.13" } } diff --git a/deadlock-plugins/deadlock-extension/src/recorder/preStop.ts b/deadlock-plugins/deadlock-extension/src/recorder/preStop.ts deleted file mode 100644 index e3154055e67b1b1a0d13521cc58a7c7891aac31e..0000000000000000000000000000000000000000 --- a/deadlock-plugins/deadlock-extension/src/recorder/preStop.ts +++ /dev/null @@ -1,49 +0,0 @@ -import UserConfigNode from './userConfigNode'; -import GitMission from '../core/gitMission'; -import { PROJECT_SRC_PATH, PROJECT_THEIA_PATH } from '../core/config'; - -import { log, error, commitAndPushCode, CommitFrom } from './utils'; -const util = require('util'); -const exec = util.promisify(require('child_process').exec); - -async function containsDiff() { - try { - // https://man7.org/linux/man-pages/man1/diff.1.html - // Exit status is 0 if inputs are the same, 1 if different, 2 if trouble. - await exec(`diff -qr ${PROJECT_SRC_PATH} ${PROJECT_THEIA_PATH}`); - // When status code is 0 exec does not fail - } catch (result) { - // when status code is > 0 - if (result.code === 1) { - const stdout = result.stdout; - if (stdout.indexOf('Files ') !== -1 || stdout.indexOf('Only in /home/project/') !== -1) { - // if user created new file or added a directory - return true; - } - } else { - // print error - error(result.stderr); - } - } - return false; -} - -(async () => { - try { - log('Container will die'); - - const userConfig = new UserConfigNode(); - await userConfig.init(); - - if (!userConfig.isProfessor()) { - log('Save user code..'); - const gitMission = await new GitMission(userConfig).init(); - if (await containsDiff()) { - await commitAndPushCode(gitMission, CommitFrom.Auto); - } - } - } catch (e) { - error('Cannot push user code at the end..'); - error(e); - } -})(); diff --git a/deadlock-plugins/deadlock-extension/src/recorder/services/automatic-save.ts b/deadlock-plugins/deadlock-extension/src/recorder/services/automatic-save.ts new file mode 100644 index 0000000000000000000000000000000000000000..154cc0ae4e829df391d8c210acd99d8f7bf75927 --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/recorder/services/automatic-save.ts @@ -0,0 +1,17 @@ +import { CommitFrom, getIgnorePatternFromIgnoreFile } from '../utils'; +import FileWatcher from './file-watcher'; +import { updateRemote } from '../utils'; +import GitMission from '../../core/gitMission'; + +export default class AutomaticSave { + constructor(private folderToWatch: string, private gitMission: GitMission) { + this.setupAutomaticSave(); + } + + async setupAutomaticSave() { + const ignoreFilePatterns = await getIgnorePatternFromIgnoreFile('/deadlock/.gitignore'); + new FileWatcher(this.folderToWatch, ['**/*'], ignoreFilePatterns, () => { + updateRemote(this.gitMission, CommitFrom.Auto); + }); + } +} diff --git a/deadlock-plugins/deadlock-extension/src/recorder/services/file-watcher.ts b/deadlock-plugins/deadlock-extension/src/recorder/services/file-watcher.ts new file mode 100644 index 0000000000000000000000000000000000000000..133048b84824e25cb69b094e29764a4f24a71ff5 --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/recorder/services/file-watcher.ts @@ -0,0 +1,21 @@ +import * as chokidar from 'chokidar'; + +export default class FileWatcher { + constructor( + private folderToWatch: string, + private watchFilePatterns: string[], + private ignoreFilePatterns: string[], + private onFilesChangeAction: () => void, + ) { + this.setupWatcher(); + } + + setupWatcher() { + const watcher = chokidar.watch(this.watchFilePatterns, { + cwd: this.folderToWatch, + ignored: this.ignoreFilePatterns, + ignoreInitial: true, + }); + watcher.on('change', this.onFilesChangeAction); + } +} diff --git a/deadlock-plugins/deadlock-extension/src/recorder/services/http-server.ts b/deadlock-plugins/deadlock-extension/src/recorder/services/http-server.ts new file mode 100644 index 0000000000000000000000000000000000000000..53cdd2a6e3159c1ead4289360489d631c47cb372 --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/recorder/services/http-server.ts @@ -0,0 +1,38 @@ +import GitMission from '../../core/gitMission'; +import { Express } from 'express'; +import { CommitFrom, log, updateRemote } from '../utils'; +import { RECORDER_HTTP_SERVER_PORT } from '../../config'; + +const express = require('express'); +export default class HttpServer { + app: Express; + + constructor(private gitMission: GitMission) { + this.app = express(); + + this.setupSaveCodeEndpoints(); + + this.listen(); + } + + setupSaveCodeEndpoints() { + this.app.post('/save', async (req, res) => { + try { + await updateRemote(this.gitMission, CommitFrom.HttpServer); + res.status(200).json({ + message: 'Commit & push done.', + }); + } catch (error) { + res.status(400).json({ + error, + }); + } + }); + } + + listen() { + this.app.listen(RECORDER_HTTP_SERVER_PORT, () => { + log(`Http server listen on port ${RECORDER_HTTP_SERVER_PORT}`); + }); + } +} diff --git a/deadlock-plugins/deadlock-extension/src/recorder/utils.ts b/deadlock-plugins/deadlock-extension/src/recorder/utils.ts index cc271f3f93a3efba58d1b43ba020581c0f1f417e..1aa9fbb58d299f4e3bc0b2da0fa3b4e23ee5ce03 100644 --- a/deadlock-plugins/deadlock-extension/src/recorder/utils.ts +++ b/deadlock-plugins/deadlock-extension/src/recorder/utils.ts @@ -1,8 +1,9 @@ +import { Branch } from './../core/gitMission'; import GitMission from '../core/gitMission'; -import { PROJECT_SRC_PATH, PROJECT_THEIA_PATH } from '../core/config'; +import { PROJECT_DEADLOCK_DESKTOP_PATH, PROJECT_SRC_PATH } from '../core/config'; import { format } from 'date-fns'; import { execSync } from 'child_process'; -import { existsSync, renameSync, copyFileSync, PathLike } from 'fs'; +import { copyFileSync, existsSync, PathLike, renameSync } from 'fs'; const util = require('util'); const unlink = util.promisify(require('fs').unlink); @@ -11,7 +12,7 @@ const fs = require('fs'); const readdirSync = require('fs').readdirSync; const Path = require('path'); -const PREFIX = '[DEADLOCK-RECORDER]'; +const PREFIX = '[55-RECORDER]'; export const log = (message: any, ...args: any[]) => { if (args) { @@ -29,9 +30,15 @@ export const error = (message: any, ...args: any[]) => { } }; -export async function copyProjectSources(srcPath: string, theiaPath: string, excludes: Array<string> = []) { +export async function copyProjectSources( + srcPath: string, + userMissionWorkdirPath: string, + excludes: Array<string> = [], +) { const excludeCmd = excludes.map((current) => `--exclude ${current}`).join(' '); - return exec(`rsync -a ${srcPath}/ ${theiaPath} ${excludeCmd} && chown -R theia:theia /home/project`); + return exec( + `rsync -a ${srcPath}/ ${userMissionWorkdirPath} ${excludeCmd} && chown -R deadlock:deadlock /home/deadlock`, + ); } export async function pathContainsFiles(path: string) { @@ -104,22 +111,29 @@ function copyGitUserFiles(srcPath: string, destPath: string, userId: string) { export enum CommitFrom { Run = 'Run', Auto = 'Auto', + HttpServer = 'HttpServer', } -export async function commitAndPushCode(gitMission: GitMission, from: CommitFrom) { +export async function updateRemote(gitMission: GitMission, from: CommitFrom) { + if (from === CommitFrom.Auto) commitAndPushCode(gitMission); + if (from === CommitFrom.Run) mergeMaster(gitMission); +} + +async function commitAndPushCode(gitMission: GitMission) { try { - log('Commit & push'); + log('Doing Commit & push'); await clearFilesExceptGit(PROJECT_SRC_PATH); - copyGitUserFiles(PROJECT_THEIA_PATH, PROJECT_SRC_PATH, gitMission.author); + copyGitUserFiles(PROJECT_DEADLOCK_DESKTOP_PATH, PROJECT_SRC_PATH, gitMission.author); execSync( - `rsync -r --exclude .git --exclude npm --exclude target ${PROJECT_THEIA_PATH}/* ${PROJECT_SRC_PATH} && cp ${Path.join( + `rsync -r --exclude .git --exclude npm --exclude target ${PROJECT_DEADLOCK_DESKTOP_PATH}/* ${PROJECT_SRC_PATH} && cp ${Path.join( __dirname, '.gitignore', )} ${PROJECT_SRC_PATH} && chown -R root:root /project`, ); const currentDate = format(new Date(), "HH'H'mm'_'dd/LL/y"); + await gitMission.checkout(Branch.LIVE); await gitMission.addAll(); await gitMission.commit(currentDate); await gitMission.push(); @@ -127,5 +141,37 @@ export async function commitAndPushCode(gitMission: GitMission, from: CommitFrom } catch (e) { error(`[${e.status}] cannot commitAndPush code: ${e.stderr}`); error(e.message); + throw new Error(e); + } +} + +async function mergeMaster(gitMission: GitMission) { + try { + log('Merging live to master'); + + const currentDate = format(new Date(), "HH'H'mm'_'dd/LL/y"); + + await gitMission.checkout(Branch.DEFAULT); + await gitMission.merge(['--squash', '-X', 'theirs', Branch.LIVE]); + await gitMission.commit(currentDate); + await gitMission.push(); + log('Merge to master done'); + await gitMission.checkout(Branch.LIVE); + } catch (e) { + error(`[${e.status}] cannot commitAndPush code: ${e.stderr}`); + error(e.message); + throw new Error(e); } } + +export function getIgnorePatternFromIgnoreFile(ignoreFile: string): Promise<string[]> { + return fs.promises + .readFile(ignoreFile, { encoding: 'utf-8' }) + .then((fileContent: string) => { + return fileContent.split(/\s*\r?\n\s*/); + }) + .then((lines: string[]) => { + return lines.filter((line) => line.trimLeft().startsWith('#') || !!line.trim()).map((line) => `**/${line}`); + }) + .then((filesPatterns: string[]) => [...filesPatterns, '.git']); +} diff --git a/deadlock-plugins/deadlock-extension/src/test/runTest.ts b/deadlock-plugins/deadlock-extension/src/test/runTest.ts new file mode 100644 index 0000000000000000000000000000000000000000..014c3a28f7a6484adca8785f3d63a2f01ed0970f --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/test/runTest.ts @@ -0,0 +1,23 @@ +import * as path from 'path'; + +import { runTests } from '@vscode/test-electron'; + +async function main() { + try { + // The folder containing the Extension Manifest package.json + // Passed to `--extensionDevelopmentPath` + const extensionDevelopmentPath = path.resolve(__dirname, '../../'); + + // The path to test runner + // Passed to --extensionTestsPath + const extensionTestsPath = path.resolve(__dirname, './suite/index'); + + // Download VS Code, unzip it and run the integration test + await runTests({ extensionDevelopmentPath, extensionTestsPath }); + } catch (err) { + console.error('Failed to run tests'); + process.exit(1); + } +} + +main(); diff --git a/deadlock-plugins/deadlock-extension/src/test/suite/extension.test.ts b/deadlock-plugins/deadlock-extension/src/test/suite/extension.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..17e2eab2ae2a57eddb862d016f3a3c45c3f3041e --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/test/suite/extension.test.ts @@ -0,0 +1,15 @@ +import * as assert from 'assert'; + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +import * as vscode from 'vscode'; +// import * as myExtension from '../../extension'; + +suite('Extension Test Suite', () => { + vscode.window.showInformationMessage('Start all tests.'); + + test('Sample test', () => { + assert.strictEqual(-1, [1, 2, 3].indexOf(5)); + assert.strictEqual(-1, [1, 2, 3].indexOf(0)); + }); +}); diff --git a/deadlock-plugins/deadlock-extension/src/test/suite/index.ts b/deadlock-plugins/deadlock-extension/src/test/suite/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..8ced9b15d08a6341edb6be162920c0bbe94cb00a --- /dev/null +++ b/deadlock-plugins/deadlock-extension/src/test/suite/index.ts @@ -0,0 +1,38 @@ +import * as path from 'path'; +import * as Mocha from 'mocha'; +import * as glob from 'glob'; + +export function run(): Promise<void> { + // Create the mocha test + const mocha = new Mocha({ + ui: 'tdd', + color: true, + }); + + const testsRoot = path.resolve(__dirname, '..'); + + return new Promise((c, e) => { + glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { + if (err) { + return e(err); + } + + // Add files to the test suite + files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f))); + + try { + // Run the mocha test + mocha.run((failures) => { + if (failures > 0) { + e(new Error(`${failures} tests failed.`)); + } else { + c(); + } + }); + } catch (err) { + console.error(err); + e(err); + } + }); + }); +} diff --git a/deadlock-plugins/deadlock-extension/src/theia/command.ts b/deadlock-plugins/deadlock-extension/src/theia/command.ts index 53638bd941e7cc69623287b76f5670be8e78cb2c..d8fd787c7e2289c7ee84215df89509b5ba0f19f4 100644 --- a/deadlock-plugins/deadlock-extension/src/theia/command.ts +++ b/deadlock-plugins/deadlock-extension/src/theia/command.ts @@ -1,4 +1,5 @@ import { Command as VscodeComand } from 'vscode'; + export class Command { constructor(private _title: string, private command: string) {} diff --git a/deadlock-plugins/deadlock-extension/src/theia/deadlockPanel.ts b/deadlock-plugins/deadlock-extension/src/theia/deadlockPanel.ts index bf68f8424c822157b6e3d543d1afc09ec5702dcb..80ba03a989b88d6dea66723c732b19644c0514b8 100644 --- a/deadlock-plugins/deadlock-extension/src/theia/deadlockPanel.ts +++ b/deadlock-plugins/deadlock-extension/src/theia/deadlockPanel.ts @@ -9,7 +9,7 @@ export class DepNodeProvider implements vscode.TreeDataProvider<Action> { private _onDidChangeTreeData: vscode.EventEmitter<Action | undefined | void> = new vscode.EventEmitter< Action | undefined | void >(); - // @ts-ignore + readonly onDidChangeTreeData: vscode.Event<Action | undefined | void> = this._onDidChangeTreeData.event; constructor(private workspaceRoot: string) {} diff --git a/deadlock-plugins/deadlock-extension/src/view/briefingView.ts b/deadlock-plugins/deadlock-extension/src/view/briefingView.ts index c041518b04192392f591fdc2b69c12ccc983fc11..d7c9141e5e929d5536805faa56f26630044e6f67 100644 --- a/deadlock-plugins/deadlock-extension/src/view/briefingView.ts +++ b/deadlock-plugins/deadlock-extension/src/view/briefingView.ts @@ -1,4 +1,5 @@ import * as fs from 'fs'; +import isDocker from 'is-docker'; import { marked } from 'marked'; import * as path from 'path'; import { setInterval } from 'timers'; @@ -12,9 +13,9 @@ export const BRIEFING_ID = 'brefingView'; export default class BriefingView extends WebviewBase { private briefingContent: string | undefined; - private errorLoadingBriefing: boolean = false; + private errorLoadingBriefing = false; - private loadingBriefing: boolean = false; + private loadingBriefing = false; constructor() { super(BRIEFING_ID, 'Briefing', OPEN_BRIEFING_COMMAND); @@ -28,6 +29,7 @@ export default class BriefingView extends WebviewBase { } setupImages(text: string) { + //eslint-disable-next-line const imageRegex = /\!\[(.*?)\]\(\b(image:)(.*?\))?/g; return text.replace(imageRegex, (match, title, imagePrefix, img) => { @@ -52,6 +54,7 @@ export default class BriefingView extends WebviewBase { console.error(e); this.briefingContent = 'Error while parsing your briefing.'; } + if (isDocker()) this.show(); }, (error) => { console.error('Cannot load briefing', error); @@ -89,7 +92,7 @@ export default class BriefingView extends WebviewBase { output += '<br/>'; if (userConfig.getUsername()) { - output += this.renderUserChallengeConfig(); + output += this.renderUserMissionConfig(); } else { output += 'Loading help..'; } @@ -97,7 +100,7 @@ export default class BriefingView extends WebviewBase { return output; } - private renderUserChallengeConfig() { + private renderUserMissionConfig() { let adresses = ''; let pathsLength = 0; @@ -116,7 +119,7 @@ export default class BriefingView extends WebviewBase { if (pathsLength > 0) { return `<h3>Configuration</h3> - You have the following adresses availables for your challenge : <ul>${adresses}</ul> + You have the following adresses availables for your mission : <ul>${adresses}</ul> </br> You also have access to these paths from: <ul> diff --git a/deadlock-plugins/deadlock-extension/src/view/quickSetupView.ts b/deadlock-plugins/deadlock-extension/src/view/quickSetupView.ts index daeb16529db561a4389c29535b84496c16cac449..26a90fbb943c452938ea79a3208ad63a381b7c5e 100644 --- a/deadlock-plugins/deadlock-extension/src/view/quickSetupView.ts +++ b/deadlock-plugins/deadlock-extension/src/view/quickSetupView.ts @@ -28,42 +28,42 @@ export default class QuickSetupView extends WebviewBase { render(): string { return ` - <head> - ${this.renderHeaderHtml()} - </head> - <body> - ${this.renderHtmlBody()} - </body> - `; + <head> + ${this.renderHeaderHtml()} + </head> + <body> + ${this.renderHtmlBody()} + </body> + `; } renderHtmlBody() { const hadMissionWorkdir = this.extensionStore.getMissionWorkdir() !== undefined; return ` - <h1>Quick Setup</h1> - <div class="deadlock-getting-started-card-container"> + <h1>Quick Setup</h1> + <div class="deadlock-getting-started-card-container"> - ${this.renderCardHtml( - 'Connexion à Deadlock', - "Tu as besoin d'être connecté à Deadlock pour continuer.", - { name: 'Se connecter', onClickFunctionName: 'openAuthenticationPageAction' }, - this._isAlreadyConnected, - this._isAlreadyConnected, - )} - ${this.renderCardHtml( - 'Dossier contenant tes exercices', - 'Choisis le dossier qui contiendra tous les exercices Deadlock.', - { - name: 'Choisir un dossier', - onClickFunctionName: 'launchChooseMissionWorkdirAction', - }, - hadMissionWorkdir, - )} - </div> - - - `; + ${this.renderCardHtml( + 'Connexion à Deadlock', + "Tu as besoin d'être connecté à Deadlock pour continuer.", + { name: 'Se connecter', onClickFunctionName: 'openAuthenticationPageAction' }, + this._isAlreadyConnected, + this._isAlreadyConnected, + )} + ${this.renderCardHtml( + 'Dossier contenant tes exercices', + 'Choisis le dossier qui contiendra tous les exercices Deadlock.', + { + name: 'Choisir un dossier', + onClickFunctionName: 'launchChooseMissionWorkdirAction', + }, + hadMissionWorkdir, + )} + </div> + + + `; } renderCardHtml( @@ -75,22 +75,22 @@ export default class QuickSetupView extends WebviewBase { callbackArgs?: string, ) { return ` - <div class="deadlock-getting-started-card"> - <vscode-checkbox ${isChecked ? 'checked' : ''} readonly> </vscode-checkbox> - <div class="card-body"> - <div class="card-title"> - ${title} - </div> - <div class="card-description"> - ${description} + <div class="deadlock-getting-started-card"> + <vscode-checkbox ${isChecked ? 'checked' : ''} readonly> </vscode-checkbox> + <div class="card-body"> + <div class="card-title"> + ${title} + </div> + <div class="card-description"> + ${description} + </div> + <vscode-button ${isDisabled ? 'disabled' : ''} onclick="${ + button.onClickFunctionName + }(${callbackArgs})">${button.name}</vscode-button> + </div> </div> - <vscode-button ${isDisabled ? 'disabled' : ''} onclick="${button.onClickFunctionName}(${callbackArgs})">${ - button.name - }</vscode-button> - </div> - </div> - - `; + + `; } renderHeaderHtml() { @@ -111,11 +111,11 @@ export default class QuickSetupView extends WebviewBase { const customScript = this.getExternalRessourcePath(this.extensionUri, ['resources', 'js', 'gettingStartedView.js']); return ` - <meta charset="UTF-8"> - <script type="module" src="${toolkitUri}"></script> - <script type="text/javascript" src="${customScript}"></script> - <link href="${customStyle}" rel="stylesheet" /> - `; + <meta charset="UTF-8"> + <script type="module" src="${toolkitUri}"></script> + <script type="text/javascript" src="${customScript}"></script> + <link href="${customStyle}" rel="stylesheet" /> + `; } onMessageReceive(message: any): void { diff --git a/deadlock-plugins/deadlock-extension/src/view/webviewBase.ts b/deadlock-plugins/deadlock-extension/src/view/webviewBase.ts index 1639cb5634d43b3209661865ad8e2bb0a3dac4ee..df113cdf39c27f3fd6408f2668706fe7f1b4869d 100644 --- a/deadlock-plugins/deadlock-extension/src/view/webviewBase.ts +++ b/deadlock-plugins/deadlock-extension/src/view/webviewBase.ts @@ -90,17 +90,12 @@ export abstract class WebviewBase implements Disposable { async show(column: ViewColumn = ViewColumn.Beside): Promise<void> { if (this.panel == null) { - this.panel = window.createWebviewPanel( - this.id, - this.title, - { viewColumn: column, preserveFocus: false }, - { - retainContextWhenHidden: true, - enableFindWidget: true, - enableCommandUris: true, - enableScripts: true, - }, - ); + this.panel = window.createWebviewPanel(this.id, this.title, ViewColumn.Active, { + retainContextWhenHidden: true, + enableFindWidget: true, + enableCommandUris: true, + enableScripts: true, + }); this.disposablePanel = Disposable.from( this.panel, diff --git a/deadlock-plugins/deadlock-extension/tsconfig.json b/deadlock-plugins/deadlock-extension/tsconfig.json index adaa4e495b1fd3b88482adf9b1a89fb97262fbdf..87cef61e7b041014aed5ba72204c3e7fb60e3ffb 100644 --- a/deadlock-plugins/deadlock-extension/tsconfig.json +++ b/deadlock-plugins/deadlock-extension/tsconfig.json @@ -3,16 +3,22 @@ "module": "commonjs", "target": "es2019", "lib": ["ES2019"], - "outDir": "out", - "sourceMap": false, - "strict": true, + "sourceMap": true, "rootDir": "src", + "outDir": "dist", + "strict": true, "noImplicitAny": false, "allowJs": true, "types": ["reflect-metadata"], "moduleResolution": "node", "experimentalDecorators": true, "emitDecoratorMetadata": true + + /* enable all strict type-checking options */ + /* Additional Checks */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ }, - "exclude": ["node_modules", ".vscode-test", "front", "out", "media", "resources"] + "exclude": ["node_modules", ".vscode-test", "dist", "out", "media", "resources", "webpack.config.js"] } diff --git a/deadlock-plugins/deadlock-extension/webpack.config.js b/deadlock-plugins/deadlock-extension/webpack.config.js new file mode 100644 index 0000000000000000000000000000000000000000..04a4c3e1b77664d083660cd2425e1484e1292d12 --- /dev/null +++ b/deadlock-plugins/deadlock-extension/webpack.config.js @@ -0,0 +1,48 @@ +//@ts-check + +'use strict'; + +const path = require('path'); + +//@ts-check +/** @typedef {import('webpack').Configuration} WebpackConfig **/ + +/** @type WebpackConfig */ +const extensionConfig = { + target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/ + mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') + + entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ + output: { + // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ + path: path.resolve(__dirname, 'dist'), + filename: 'extension.js', + libraryTarget: 'commonjs2', + }, + externals: { + vscode: 'commonjs vscode', // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ + // modules added here also need to be added in the .vscodeignore file + }, + resolve: { + // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader + extensions: ['.ts', '.js'], + }, + module: { + rules: [ + { + test: /\.ts$/, + exclude: /node_modules/, + use: [ + { + loader: 'ts-loader', + }, + ], + }, + ], + }, + devtool: 'nosources-source-map', + infrastructureLogging: { + level: 'log', // enables logging required for problem matchers + }, +}; +module.exports = [extensionConfig]; diff --git a/plugins/.gitkeep b/plugins/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/plugins/gitlens-10.2.3.vsix b/plugins/gitlens-10.2.3.vsix deleted file mode 100644 index 248629ac5c2accb40160dfc108b9026f43869ed2..0000000000000000000000000000000000000000 Binary files a/plugins/gitlens-10.2.3.vsix and /dev/null differ diff --git a/setup.sh b/setup.sh index 2ebb8e0d4157f9d08fc87605c996fc2daf1e1085..3cfcf6de32b76061ba02167715bf2fa1bee97443 100755 --- a/setup.sh +++ b/setup.sh @@ -1,2 +1,3 @@ npm install -npm install --prefix ./deadlock-plugins/deadlock-extension \ No newline at end of file +npm install --prefix ./deadlock-plugins/deadlock-extension +npm install --prefix ./deadlock-plugins/deadlock-extension/src/recorder \ No newline at end of file diff --git a/setup_trace.py b/setup_trace.py index 313589500a92f3dd57d6be106950d9382fe7a730..80f70c3c9d60d86bda52a33a14a72ccac9379fae 100644 --- a/setup_trace.py +++ b/setup_trace.py @@ -1,7 +1,7 @@ -open('/home/theia/.bash_history', 'a').close() +open('/home/deadlock/.bash_history', 'a').close() -bashrc = open('/home/theia/.bashrc', 'a') +bashrc = open('/home/deadlock/.bashrc', 'a') bashrc.write('\n') bashrc.write('HISTCONTROL=""') bashrc.write('\n') diff --git a/start.sh b/start.desktop.sh old mode 100755 new mode 100644 similarity index 63% rename from start.sh rename to start.desktop.sh index c45a90336ab9b77e6160e4c17e4341791922076f..21d2886351fbea5236b8ceeece5a5c2069311d5a --- a/start.sh +++ b/start.desktop.sh @@ -3,6 +3,9 @@ ON_START_UP_FILE="/deadlock/startup.sh" TAG="[DEADLOCK]" +# Start docker in docker +dockerd-entrypoint.sh $@ & + # setup ssh key for root user # must be installed by the API first within /tmp/.ssh mkdir ~/.ssh @@ -20,13 +23,15 @@ else echo fi + +su deadlock -c "sudo python /setup_trace.py" + + # start command recorder -node deadlock/recorder.js & +node deadlock/recorder.js + + + -deluser theia sudo -su theia --command "python setup_trace.py" -rm setup_trace.py -# starting theia as THEIA -su theia --command "node /home/theia/src-gen/backend/main.js /home/project --hostname=0.0.0.0 --plugins=local-dir:/home/plugins"