diff --git a/.circleci/config.yml b/.circleci/config.yml index 3bf986cca..13d339892 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,17 +2,23 @@ # # Check https://circleci.com/docs/2.0/language-javascript/ for more details # -version: 2 +version: 2.1 + +orbs: + node: circleci/node@3.0.0 + jobs: build: docker: - - image: circleci/node:16.10.0 - - image: circleci/mongo:4.4 + - image: cimg/node:16.11.0 + - image: mongo:4.4 - working_directory: ~/repo + working_directory: ~/homebrewery + executor: node/default steps: - - checkout + - checkout: + path: ~/homebrewery # Download and cache dependencies - restore_cache: @@ -21,12 +27,48 @@ jobs: # fallback to using the latest cache if no exact match is found - v1-dependencies- - - run: npm install + - node/install-npm + - node/install-packages: + app-dir: ~/homebrewery + cache-path: node_modules + override-ci-command: npm i - save_cache: paths: - node_modules key: v1-dependencies-{{ checksum "package.json" }} + - persist_to_workspace: + root: . + paths: + - . + + test: + docker: + - image: cimg/node:16.11.0 + + working_directory: ~/homebrewery + parallelism: 4 + + steps: + - attach_workspace: + at: . + # run tests! - - run: npm run circleci + - run: + name: Test - Basic + command: npm run test:basic + - run: + name: Test - Mustache Spans + command: npm run test:mustache-span + - run: + name: Test - Routes + command: npm run test:route + +workflows: + build_and_test: + jobs: + - build + - test: + requires: + - build \ No newline at end of file diff --git a/README.md b/README.md index 9a5faeaf4..35f0150d1 100644 --- a/README.md +++ b/README.md @@ -9,37 +9,37 @@ using [Markdown][markdown-url]. It is distributed under the terms of the [MIT Li [markdown-url]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet ## Quick Start -The easiest way to get started using the Homebrewery is to use it +The easiest way to get started using The Homebrewery is to use it [on our website][homebrewery-url]. The code is open source, so feel free to -clone it, tinker with it. If you want to make changes to the code, you can run +clone it and tinker with it. If you want to make changes to the code, you can run your own local version for testing by following the installation instructions below. [homebrewery-url]: https://homebrewery.naturalcrit.com ### Installation -First, install three programs that the Homebrewery requires to run and retrieve +First, install three programs that The Homebrewery requires to run and retrieve updates: 1. install [node](https://nodejs.org/en/) 1. install [mongodb](https://www.mongodb.com/try/download/community) (Community version) - For easiest installation, follow these steps: - 1. In the installer, uncheck the option to run as a service - 1. You can install MongoDB Compass if you want a GUI to view your database documents - 1. Go to the C drive and create a folder called "data" - 1. Inside the "data" folder, create a new folder called "db" - 1. Open a command prompt or other terminal and navigate to your mongodb install folder (c:program files\mongo\server\4.4\bin) - 1. In the command prompt, run "mongod", which will start up your local database server - 1. While MongoD is running, open a second command prompt and navigate to the mongodb install folder - 1. In the second command prompt, run "mongo", which allows you to edit the database - 1. Type `use homebrewery` to create the homebrewery database. You should see `switched to db homebrewery` - 1. Type `db.brews.insert({"title":"test"})` to create a blank document. You should see `WriteResult({ "nInserted" : 1 })` - 1. Search in Windows for "Advanced system settings" and open it - 1. Click "Environment variables", find the "path" variable, and double-click to open it - 1. Click "New" and paste in the path to the mongodb "bin" folder - 1. Click "OK", "OK", "OK" to close all the windows -1. install [git](https://git-scm.com/downloads) (select the option that allows Git to run from the command prompt) + For the easiest installation, follow these steps: + 1. In the installer, uncheck the option to run as a service. + 1. You can install MongoDB Compass if you want a GUI to view your database documents. + 1. Go to the C:\ drive and create a folder called "data". + 1. Inside the "data" folder, create a new folder called "db". + 1. Open a command prompt or other terminal and navigate to your MongoDB install folder (C:\Program Files\Mongo\Server\4.4\bin). + 1. In the command prompt, run "mongod", which will start up your local database server. + 1. While MongoD is running, open a second command prompt and navigate to the MongoDB install folder. + 1. In the second command prompt, run "mongo", which allows you to edit the database. + 1. Type `use homebrewery` to create The Homebrewery database. You should see `switched to db homebrewery`. + 1. Type `db.brews.insert({"title":"test"})` to create a blank document. You should see `WriteResult({ "nInserted" : 1 })`. + 1. Search in Windows for "Advanced system settings" and open it. + 1. Click "Environment variables", find the "path" variable, and double-click to open it. + 1. Click "New" and paste in the path to the MongoDB "bin" folder. + 1. Click "OK" three times to close all the windows. +1. install [git](https://git-scm.com/downloads) (select the option that allows Git to run from the command prompt). Checkout the repo ([documentation][github-clone-repo-docs-url]): ``` @@ -54,7 +54,7 @@ the project to run locally. You can set this temporarily in your shell of choice: * Windows Powershell: `$env:NODE_ENV="local"` * Windows CMD: `set NODE_ENV=local` -* Linux / OSX: `export NODE_ENV=local` +* Linux / macOS: `export NODE_ENV=local` Third, you will need to install the Node dependencies, compile the app, and run it using the two commands: @@ -63,7 +63,7 @@ it using the two commands: 1. `npm start` You should now be able to go to [http://localhost:8000](http://localhost:8000) -in your browser and use the Homebrewery offline. +in your browser and use The Homebrewery offline. ### Running the application via Docker @@ -95,11 +95,11 @@ You can check out the [changelog](./changelog.md). ## License -This project is licensed under the [MIT license](./license). Which means you +This project is licensed under the [MIT license](./license), which means you are free to use The Homebrewery in any way that you want, except for claiming that you made it yourself. -If you wish to sell or in some way gain profit for what's created on this site, +If you wish to sell, or in some way gain profit for, what's created on this site, it's your responsibility to ensure you have the proper licenses/rights for any images or resources used. @@ -108,13 +108,12 @@ images or resources used. You are welcome to contribute to the development and maintenance of the project! There are several ways of doing that: - At the moment, we have a huge backlog of [issues][repo-issues-url] and some - of them are outdated, duplicates or doesn't contain any useful info. In order - to help you can [mark duplicates][github-mark-duplicate-url], try to - reproduce some complex or weird issues, try with finding a workaround for a - reported bug or just mention issue managers team to let them know about - outdated issue via `@naturalcrit/issue-managers`. + of them are outdated, duplicates, or don't contain any useful info. To help, you can [mark duplicates][github-mark-duplicate-url], try to + reproduce some complex or weird issues, try finding a workaround for a + reported bug, or just mention our issue managers team to let them know about + outdated issues via `@naturalcrit/issue-managers`. - Our [subreddit][subreddit-url] is constantly growing and there are number of - bug reports: any help with sorting them out is very welcome. + bug reports. Any help with sorting them out is very welcome. - And of course you can contribute by fixing a bug or implementing a new feature by yourself, we are waiting for your [pull requests][github-pr-docs-url]! diff --git a/changelog.md b/changelog.md index 45f050e01..9fed601f8 100644 --- a/changelog.md +++ b/changelog.md @@ -29,11 +29,43 @@ pre { .page p + pre { margin-top : 0.1cm; } + +.page .openSans { + font-family: 'Open Sans'; + font-size: 0.9em; +} ``` ## changelog For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery). +### Wednesday 27/03/2022 - v3.0.8 +{{taskList +* [x] Style updates to user page. + +* [x] Added a logout button (finally)! You can find it under {{openSans **USERNAME {{fa,fa-user}} → LOGOUT {{fas,fa-power-off}}**}} + + Fixes issues: [#303](https://github.com/naturalcrit/homebrewery/issues/303) + +* [x] Clarified the default text when submitting an issue via Reddit post. + +* [x] Fixed broken Table of Contents links in PDFs. (Thanks lucastucious!) + + Fixes issues: [#1749](https://github.com/naturalcrit/homebrewery/issues/1749) + +* [x] Fixed window resizing causing the edit page divider to get lost off of the edge of the page. + + Fixes issues: [#2053](https://github.com/naturalcrit/homebrewery/issues/2053) + +* [x] Fixed Class Table decorations overlapping main text. + + Fixes issues: [#1985](https://github.com/naturalcrit/homebrewery/issues/1985) + +* [x] Updated {{openSans **STYLE EDITOR {{fa,fa-pencil-alt}} → REMOVE DROP CAP {{fas,fa-remove-format}}**}} snippet to also remove small-caps first line font. + +* [x] Background work in preparation for brew themes. +}} + ### Wednesday 02/02/2022 - v3.0.7 {{taskList * [x] Revert active line highlighting. @@ -50,7 +82,7 @@ For a full record of development, visit our [Github Page](https://github.com/nat Fixes issues: [#1943](https://github.com/naturalcrit/homebrewery/issues/1943) -* [x] Added a Legacy to V3 migration guide under **NEED HELP? {{fa,fa-question-circle}} → MIGRATE {{fas,fa-file-import}}** +* [x] Added a Legacy to V3 migration guide under {{openSans **NEED HELP? {{fa,fa-question-circle}} → MIGRATE {{fas,fa-file-import}}**}} * [x] Background refactoring and unit tests. }} @@ -61,7 +93,7 @@ For a full record of development, visit our [Github Page](https://github.com/nat Fixes issues: [#1736](https://github.com/naturalcrit/homebrewery/issues/1736) -* [x] Code search/replace `CTRL F / CTRL SHIFT F` +* [x] Code search/replace PC: `CTRL F / CTRL SHIFT F` / Mac: `CMD F / OPTION CMD F` Fixes issues: [#1201](https://github.com/naturalcrit/homebrewery/issues/1201) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 4c294a51e..d692fe262 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -78,7 +78,7 @@ const MetadataEditor = createClass({ if(!confirm('Are you REALLY sure? You will lose editor access to this document.')) return; } - request.delete(`/api/${this.props.metadata.editId}`) + request.delete(`/api/${this.props.metadata.googleId ?? ''}${this.props.metadata.editId}`) .send() .end(function(err, res){ window.location.href = '/'; diff --git a/client/homebrew/editor/snippetbar/snippets/snippets.js b/client/homebrew/editor/snippetbar/snippets/snippets.js index 7b008fe1e..10920a564 100644 --- a/client/homebrew/editor/snippetbar/snippets/snippets.js +++ b/client/homebrew/editor/snippetbar/snippets/snippets.js @@ -97,7 +97,11 @@ module.exports = [ gen : dedent`/* Removes Drop Caps */ .page h1+p:first-letter { all: unset; - }\n\n` + }\n\n + /* Removes Small-Caps in first line */ + .page h1+p:first-line { + all: unset; + }` }, { name : 'Tweak Drop Cap', diff --git a/client/homebrew/homebrew.jsx b/client/homebrew/homebrew.jsx index 54dcf2206..732c06486 100644 --- a/client/homebrew/homebrew.jsx +++ b/client/homebrew/homebrew.jsx @@ -32,11 +32,14 @@ const Homebrew = createClass({ } }; }, - componentWillMount : function() { - global.account = this.props.account; + + getInitialState : function(){ global.version = this.props.version; + global.account = this.props.account; global.enable_v3 = this.props.enable_v3; + return {}; }, + render : function (){ return ( @@ -46,7 +49,7 @@ const Homebrew = createClass({ }/> }/> }/> - }/> + }/> }/> }/> }/> diff --git a/client/homebrew/navbar/account.navitem.jsx b/client/homebrew/navbar/account.navitem.jsx index 004685a13..be92cea92 100644 --- a/client/homebrew/navbar/account.navitem.jsx +++ b/client/homebrew/navbar/account.navitem.jsx @@ -20,9 +20,20 @@ const Account = createClass({ handleLogout : function(){ if(confirm('Are you sure you want to log out?')) { - document.cookie = `nc_session=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/;samesite=lax;${window.domain ? `domain=${window.domain}` : ''}`; + // Reset divider position + window.localStorage.removeItem('naturalcrit-pane-split'); + // Clear login cookie + let domain = ''; + if(window.location?.hostname) { + let domainArray = window.location.hostname.split('.'); + if(domainArray.length > 2){ + domainArray = [''].concat(domainArray.slice(-2)); + } + domain = domainArray.join('.'); + } + document.cookie = `nc_session=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/;samesite=lax;${domain ? `domain=${domain}` : ''}`; window.location = '/'; - }; + } }, render : function(){ diff --git a/client/homebrew/navbar/help.navitem.jsx b/client/homebrew/navbar/help.navitem.jsx index b4be18319..f84acabde 100644 --- a/client/homebrew/navbar/help.navitem.jsx +++ b/client/homebrew/navbar/help.navitem.jsx @@ -1,6 +1,7 @@ const React = require('react'); const createClass = require('create-react-class'); const _ = require('lodash'); +const dedent = require('dedent-tabs').default; const Nav = require('naturalcrit/nav/nav.jsx'); @@ -10,7 +11,11 @@ module.exports = function(props){ need help? report issue diff --git a/client/homebrew/navbar/navbar.jsx b/client/homebrew/navbar/navbar.jsx index b3255db45..7929bb5e2 100644 --- a/client/homebrew/navbar/navbar.jsx +++ b/client/homebrew/navbar/navbar.jsx @@ -14,12 +14,10 @@ const Navbar = createClass({ }; }, - componentDidMount : function() { - //const isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); - this.setState({ - //showNonChromeWarning : !isChrome, - ver : window.version - }); + getInitialState : function() { + return { + ver : global.version + }; }, /* diff --git a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx index a89dad11e..8d677c635 100644 --- a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx +++ b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx @@ -31,19 +31,11 @@ const BrewItem = createClass({ if(!confirm('Are you REALLY sure? You will lose editor access to this document.')) return; } - if(this.props.brew.googleId) { - request.get(`/api/removeGoogle/${this.props.brew.googleId}${this.props.brew.editId}`) - .send() - .end(function(err, res){ - location.reload(); - }); - } else { - request.delete(`/api/${this.props.brew.editId}`) - .send() - .end(function(err, res){ - location.reload(); - }); - } + request.delete(`/api/${this.props.brew.googleId ?? ''}${this.props.brew.editId}`) + .send() + .end(function(err, res){ + location.reload(); + }); }, renderDeleteBrewLink : function(){ diff --git a/client/homebrew/pages/basePages/listPage/listPage.jsx b/client/homebrew/pages/basePages/listPage/listPage.jsx index e1f300ab2..934d147be 100644 --- a/client/homebrew/pages/basePages/listPage/listPage.jsx +++ b/client/homebrew/pages/basePages/listPage/listPage.jsx @@ -24,7 +24,8 @@ const ListPage = createClass({ return { sortType : 'alpha', sortDir : 'asc', - filterString : '' + filterString : this.props.query?.filter || '', + query : this.props.query }; }, @@ -74,19 +75,35 @@ const ListPage = createClass({ handleFilterTextChange : function(e){ this.setState({ - filterString : e.target.value + filterString : e.target.value, }); + this.updateUrl(e.target.value); return; }, + updateUrl : function(filterTerm){ + const url = new URL(window.location.href); + const urlParams = new URLSearchParams(url.search); + if(urlParams.get('filter') == filterTerm) + return; + if(!filterTerm) + urlParams.delete('filter'); + else + urlParams.set('filter', filterTerm); + url.search = urlParams; + window.history.replaceState(null, null, url); + }, + renderFilterOption : function(){ return ; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 5e13d5a4d..a77321e6f 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -200,73 +200,18 @@ const EditPage = createClass({ const brew = this.state.brew; brew.pageCount = ((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1; - if(this.state.saveGoogle) { - if(transfer) { - const res = await request - .post('/api/newGoogle/') - .send(brew) - .catch((err)=>{ - console.log(err.status === 401 - ? 'Not signed in!' - : 'Error Transferring to Google!'); - this.setState({ errors: err, saveGoogle: false }); - }); + const params = `${transfer ? `?transfer${this.state.saveGoogle ? 'To' : 'From'}Google=true` : ''}`; + const res = await request + .put(`/api/update/${brew.editId}${params}`) + .send(brew) + .catch((err)=>{ + console.log('Error Updating Local Brew'); + this.setState({ errors: err }); + }); - if(!res) { return; } - - console.log('Deleting Local Copy'); - await request.delete(`/api/${brew.editId}`) - .send() - .catch((err)=>{ - console.log('Error deleting Local Copy'); - }); - - this.savedBrew = res.body; - history.replaceState(null, null, `/edit/${this.savedBrew.googleId}${this.savedBrew.editId}`); //update URL to match doc ID - } else { - const res = await request - .put(`/api/updateGoogle/${brew.editId}`) - .send(brew) - .catch((err)=>{ - console.log(err.status === 401 - ? 'Not signed in!' - : 'Error Saving to Google!'); - this.setState({ errors: err }); - return; - }); - - this.savedBrew = res.body; - } - } else { - if(transfer) { - const res = await request.post('/api') - .send(brew) - .catch((err)=>{ - console.log('Error creating Local Copy'); - this.setState({ errors: err }); - return; - }); - - await request.get(`/api/removeGoogle/${brew.googleId}${brew.editId}`) - .send() - .catch((err)=>{ - console.log('Error Deleting Google Brew'); - }); - - this.savedBrew = res.body; - history.replaceState(null, null, `/edit/${this.savedBrew.editId}`); //update URL to match doc ID - } else { - const res = await request - .put(`/api/update/${brew.editId}`) - .send(brew) - .catch((err)=>{ - console.log('Error Updating Local Brew'); - this.setState({ errors: err }); - return; - }); - - this.savedBrew = res.body; - } + this.savedBrew = res.body; + if(transfer) { + history.replaceState(null, null, `/edit/${this.savedBrew.googleId ?? ''}${this.savedBrew.editId}`); } this.setState((prevState)=>({ @@ -331,26 +276,26 @@ const EditPage = createClass({ console.log(errMsg); } catch (e){} - if(this.state.errors.status == '401'){ - return - Oops! -
- You must be signed in to a Google account - to save this to
Google Drive!
- -
- Sign In -
-
-
- Not Now -
-
-
; - } + // if(this.state.errors.status == '401'){ + // return + // Oops! + //
+ // You must be signed in to a Google account + // to save this to
Google Drive!
+ // + //
+ // Sign In + //
+ //
+ //
+ // Not Now + //
+ //
+ //
; + // } - if(this.state.errors.response.req.url.match(/^\/api\/.*Google.*$/m)){ + if(this.state.errors.response.req.url.match(/^\/api.*Google.*$/m)){ return Oops!
diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index a126d1325..cb8378bdd 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -157,45 +157,24 @@ const NewPage = createClass({ const index = brew.text.indexOf('```\n\n'); brew.style = `${brew.style ? `${brew.style}\n` : ''}${brew.text.slice(7, index - 1)}`; brew.text = brew.text.slice(index + 5); - }; + } brew.pageCount=((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1; - if(this.state.saveGoogle) { - const res = await request - .post('/api/newGoogle/') + const res = await request + .post(`/api${this.state.saveGoogle ? '?transferToGoogle=true' : ''}`) .send(brew) .catch((err)=>{ - console.log(err.status === 401 - ? 'Not signed in!' - : 'Error Creating New Google Brew!'); + console.log(err); this.setState({ isSaving: false, errors: err }); - return; }); + if(!res) return; - brew = res.body; - localStorage.removeItem(BREWKEY); - localStorage.removeItem(STYLEKEY); - localStorage.removeItem(METAKEY); - window.location = `/edit/${brew.googleId}${brew.editId}`; - } else { - request.post('/api') - .send(brew) - .end((err, res)=>{ - if(err){ - this.setState({ - isSaving : false - }); - return; - } - window.onbeforeunload = function(){}; - brew = res.body; - localStorage.removeItem(BREWKEY); - localStorage.removeItem(STYLEKEY); - localStorage.removeItem(METAKEY); - window.location = `/edit/${brew.editId}`; - }); - } + brew = res.body; + localStorage.removeItem(BREWKEY); + localStorage.removeItem(STYLEKEY); + localStorage.removeItem(METAKEY); + window.location = `/edit/${brew.googleId ?? ''}${brew.editId}`; }, renderSaveButton : function(){ @@ -208,26 +187,26 @@ const NewPage = createClass({ console.log(errMsg); } catch (e){} - if(this.state.errors.status == '401'){ - return - Oops! -
- You must be signed in to a Google account - to save this to
Google Drive!
- -
- Sign In -
-
-
- Not Now -
-
-
; - } + // if(this.state.errors.status == '401'){ + // return + // Oops! + //
+ // You must be signed in to a Google account + // to save this to
Google Drive!
+ // + //
+ // Sign In + //
+ //
+ //
+ // Not Now + //
+ //
+ //
; + // } - if(this.state.errors.response.req.url.match(/^\/api\/.*Google.*$/m)){ + if(this.state.errors.response.req.url.match(/^\/api.*Google.*$/m)){ return Oops!
diff --git a/client/homebrew/pages/userPage/userPage.jsx b/client/homebrew/pages/userPage/userPage.jsx index a78ba11af..6c3af7907 100644 --- a/client/homebrew/pages/userPage/userPage.jsx +++ b/client/homebrew/pages/userPage/userPage.jsx @@ -19,6 +19,7 @@ const UserPage = createClass({ return { username : '', brews : [], + query : '' }; }, getInitialState : function() { @@ -62,7 +63,7 @@ const UserPage = createClass({ }, render : function(){ - return ; + return ; } }); diff --git a/package-lock.json b/package-lock.json index 690b92b4c..802ac42c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "homebrewery", - "version": "3.0.7", + "version": "3.0.8", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "3.0.7", + "version": "3.0.8", "hasInstallScript": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.17.5", + "@babel/core": "^7.17.9", "@babel/plugin-transform-runtime": "^7.17.0", "@babel/preset-env": "^7.16.11", "@babel/preset-react": "^7.16.7", - "body-parser": "^1.19.2", + "body-parser": "^1.20.0", "classnames": "^2.3.1", "codemirror": "^5.65.2", "cookie-parser": "^1.4.6", @@ -23,18 +23,18 @@ "express-async-handler": "^1.2.0", "express-static-gzip": "2.1.5", "fs-extra": "10.0.1", - "googleapis": "95.0.0", + "googleapis": "100.0.0", "js-yaml": "^4.1.0", "jwt-simple": "^0.5.6", "less": "^3.13.1", "lodash": "^4.17.21", - "marked": "4.0.12", + "marked": "4.0.14", "marked-extended-tables": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", - "moment": "^2.29.1", - "mongoose": "^6.2.4", - "nanoid": "3.3.1", - "nconf": "^0.11.3", + "moment": "^2.29.2", + "mongoose": "^6.2.10", + "nanoid": "3.3.2", + "nconf": "^0.11.4", "query-string": "7.1.1", "react": "^16.14.0", "react-dom": "^16.14.0", @@ -45,8 +45,8 @@ "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" }, "devDependencies": { - "eslint": "^8.10.0", - "eslint-plugin-react": "^7.29.3", + "eslint": "^8.13.0", + "eslint-plugin-react": "^7.29.4", "jest": "^27.5.1", "supertest": "^6.2.2" }, @@ -77,32 +77,32 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", - "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", + "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.17.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.5.tgz", - "integrity": "sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.9.tgz", + "integrity": "sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw==", "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.17.2", - "@babel/parser": "^7.17.3", + "@babel/generator": "^7.17.9", + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helpers": "^7.17.9", + "@babel/parser": "^7.17.9", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", + "@babel/traverse": "^7.17.9", "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", + "json5": "^2.2.1", "semver": "^6.3.0" }, "engines": { @@ -151,9 +151,9 @@ } }, "node_modules/@babel/generator": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", - "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.9.tgz", + "integrity": "sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ==", "dependencies": { "@babel/types": "^7.17.0", "jsesc": "^2.5.1", @@ -195,11 +195,11 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", + "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", "dependencies": { - "@babel/compat-data": "^7.16.4", + "@babel/compat-data": "^7.17.7", "@babel/helper-validator-option": "^7.16.7", "browserslist": "^4.17.5", "semver": "^6.3.0" @@ -324,24 +324,12 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", + "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", "dependencies": { - "@babel/helper-get-function-arity": "^7.16.7", "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", - "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" @@ -381,18 +369,18 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", + "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", "dependencies": { "@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", "@babel/helper-split-export-declaration": "^7.16.7", "@babel/helper-validator-identifier": "^7.16.7", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" @@ -446,11 +434,11 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", + "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" @@ -509,12 +497,12 @@ } }, "node_modules/@babel/helpers": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", - "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", + "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", "dependencies": { "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", + "@babel/traverse": "^7.17.9", "@babel/types": "^7.17.0" }, "engines": { @@ -564,9 +552,9 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/@babel/parser": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", - "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz", + "integrity": "sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1779,17 +1767,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.9.tgz", + "integrity": "sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw==", "dependencies": { "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", + "@babel/generator": "^7.17.9", "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", + "@babel/helper-function-name": "^7.17.9", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", + "@babel/parser": "^7.17.9", "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" @@ -1841,16 +1829,16 @@ "dev": true }, "node_modules/@eslint/eslintrc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz", - "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", + "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.3.1", "globals": "^13.9.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.0.4", @@ -2781,9 +2769,9 @@ } }, "node_modules/ansi-align/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "engines": { "node": ">=6" } @@ -3322,21 +3310,94 @@ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, "node_modules/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "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": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" + "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/body-parser/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/body-parser/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/body-parser/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/body-parser/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/body-parser/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/body-parser/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/body-parser/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" } @@ -4959,12 +5020,12 @@ } }, "node_modules/eslint": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz", - "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.13.0.tgz", + "integrity": "sha512-D+Xei61eInqauAyTJ6C0q6x9mx7kTUC1KZ0m0LSEexR0V+e94K12LmWX076ZIsldwfQ2RONdaJe0re0TRGQbRQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.2.0", + "@eslint/eslintrc": "^1.2.1", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -5011,9 +5072,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.3.tgz", - "integrity": "sha512-MzW6TuCnDOcta67CkpDyRfRsEVx9FNMDV8wZsDqe1luHPdGTrQIUaUXD27Ja3gHsdOIs/cXzNchWGlqm+qRVRg==", + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz", + "integrity": "sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ==", "dev": true, "dependencies": { "array-includes": "^3.1.4", @@ -5178,15 +5239,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/eslint/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -5551,6 +5603,26 @@ "serve-static": "^1.14.1" } }, + "node_modules/express/node_modules/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", @@ -5559,6 +5631,20 @@ "node": ">= 0.6" } }, + "node_modules/express/node_modules/raw-body": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -6065,9 +6151,9 @@ } }, "node_modules/googleapis": { - "version": "95.0.0", - "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-95.0.0.tgz", - "integrity": "sha512-ZpFZW7FDwcjQa2+xZNS2SC5sK2s46iWKA5QSFVJSK3RELQec4PYHhzKwzbeCzt4urnjYp6udPif95zXTFxbtRA==", + "version": "100.0.0", + "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-100.0.0.tgz", + "integrity": "sha512-RToFQGY54B756IDbjdyjb1vWFmn03bYpXHB2lIf0eq2UBYsIbYOLZ0kqSomfJnpclEukwEmMF7Jn6Wsev871ew==", "dependencies": { "google-auth-library": "^7.0.2", "googleapis-common": "^5.0.2" @@ -6508,9 +6594,9 @@ ] }, "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, "engines": { "node": ">= 4" @@ -8604,12 +8690,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", "bin": { "json5": "lib/cli.js" }, @@ -8698,9 +8781,9 @@ } }, "node_modules/kareem": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.4.tgz", - "integrity": "sha512-Vcrt8lcpVl0s8ePx634BxwRqmFo+5DcOhlmNadehxreMTIQi/9hOL/B3hZQQbK5DgMS7Lem3xABXV7/S3jy+7g==" + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.5.tgz", + "integrity": "sha512-qxCyQtp3ioawkiRNQr/v8xw9KIviMSSNmy+63Wubj7KmMn3g7noRXIZB4vPCAP+ETi2SR8eH6CvmlKZuGpoHOg==" }, "node_modules/keyv": { "version": "3.1.0", @@ -8948,9 +9031,9 @@ } }, "node_modules/marked": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz", - "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==", + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz", + "integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==", "bin": { "marked": "bin/marked.js" }, @@ -9228,9 +9311,9 @@ } }, "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==" }, "node_modules/mixin-deep": { "version": "1.3.2", @@ -9287,9 +9370,9 @@ } }, "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "version": "2.29.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz", + "integrity": "sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==", "engines": { "node": "*" } @@ -9321,12 +9404,12 @@ } }, "node_modules/mongoose": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.4.tgz", - "integrity": "sha512-3hA3IGxBzZdlp1+/I9qn53NjEAd01qvKAH2WUCPahjVO8+uAmR0B4m+1bC3x9a4r0ExY8QYQ2ryG3E/v5Tj+jA==", + "version": "6.2.10", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.10.tgz", + "integrity": "sha512-Yp+6UH5M0AlxAVGdC2/Deq0St+2qW73oKCnhJDr83bOZ12eflTLTT5uQF0p6KzvtFj86XWbq/7ApvO4yW6h1sA==", "dependencies": { "bson": "^4.2.2", - "kareem": "2.3.4", + "kareem": "2.3.5", "mongodb": "4.3.1", "mpath": "0.8.4", "mquery": "4.0.2", @@ -9398,9 +9481,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", + "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -9442,9 +9525,9 @@ "dev": true }, "node_modules/nconf": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.11.3.tgz", - "integrity": "sha512-iYsAuDS9pzjVMGIzJrGE0Vk3Eh8r/suJanRAnWGBd29rVS2XtSgzcAo5l6asV3e4hH2idVONHirg1efoBOslBg==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.11.4.tgz", + "integrity": "sha512-YaDR846q11JnG1vTrhJ0QIlhiGY6+W1bgWtReG9SS3vkTl3AoNwFvUItdhG6/ZjGCfWpUVuRTNEBTDAQ3nWhGw==", "dependencies": { "async": "^1.4.0", "ini": "^2.0.0", @@ -9707,7 +9790,6 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10390,12 +10472,12 @@ } }, "node_modules/raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "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": "1.8.1", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -10403,6 +10485,42 @@ "node": ">= 0.8" } }, + "node_modules/raw-body/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/raw-body/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/raw-body/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/raw-body/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/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -11041,7 +11159,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -13124,29 +13241,29 @@ } }, "@babel/compat-data": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", - "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==" + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", + "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==" }, "@babel/core": { - "version": "7.17.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.5.tgz", - "integrity": "sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.9.tgz", + "integrity": "sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw==", "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.17.2", - "@babel/parser": "^7.17.3", + "@babel/generator": "^7.17.9", + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helpers": "^7.17.9", + "@babel/parser": "^7.17.9", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", + "@babel/traverse": "^7.17.9", "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", + "json5": "^2.2.1", "semver": "^6.3.0" }, "dependencies": { @@ -13179,9 +13296,9 @@ } }, "@babel/generator": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", - "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.9.tgz", + "integrity": "sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ==", "requires": { "@babel/types": "^7.17.0", "jsesc": "^2.5.1", @@ -13213,11 +13330,11 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", + "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", "requires": { - "@babel/compat-data": "^7.16.4", + "@babel/compat-data": "^7.17.7", "@babel/helper-validator-option": "^7.16.7", "browserslist": "^4.17.5", "semver": "^6.3.0" @@ -13305,21 +13422,12 @@ } }, "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", + "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", "requires": { - "@babel/helper-get-function-arity": "^7.16.7", "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", - "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.17.0" } }, "@babel/helper-hoist-variables": { @@ -13347,18 +13455,18 @@ } }, "@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", + "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", "requires": { "@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", "@babel/helper-split-export-declaration": "^7.16.7", "@babel/helper-validator-identifier": "^7.16.7", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" } }, "@babel/helper-optimise-call-expression": { @@ -13397,11 +13505,11 @@ } }, "@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", + "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.17.0" } }, "@babel/helper-skip-transparent-expression-wrappers": { @@ -13442,12 +13550,12 @@ } }, "@babel/helpers": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", - "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", + "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", "requires": { "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", + "@babel/traverse": "^7.17.9", "@babel/types": "^7.17.0" } }, @@ -13487,9 +13595,9 @@ } }, "@babel/parser": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", - "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==" + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz", + "integrity": "sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.16.7", @@ -14284,17 +14392,17 @@ } }, "@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.9.tgz", + "integrity": "sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw==", "requires": { "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", + "@babel/generator": "^7.17.9", "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", + "@babel/helper-function-name": "^7.17.9", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", + "@babel/parser": "^7.17.9", "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" @@ -14336,16 +14444,16 @@ "dev": true }, "@eslint/eslintrc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz", - "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", + "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.3.1", "globals": "^13.9.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.0.4", @@ -15100,9 +15208,9 @@ }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==" }, "emoji-regex": { "version": "7.0.3", @@ -15525,20 +15633,72 @@ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, "body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "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": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "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==" + }, + "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" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "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" + } + }, + "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" + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + } } }, "boxen": { @@ -16868,12 +17028,12 @@ } }, "eslint": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz", - "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.13.0.tgz", + "integrity": "sha512-D+Xei61eInqauAyTJ6C0q6x9mx7kTUC1KZ0m0LSEexR0V+e94K12LmWX076ZIsldwfQ2RONdaJe0re0TRGQbRQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.2.0", + "@eslint/eslintrc": "^1.2.1", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -16950,12 +17110,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -16980,9 +17134,9 @@ } }, "eslint-plugin-react": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.3.tgz", - "integrity": "sha512-MzW6TuCnDOcta67CkpDyRfRsEVx9FNMDV8wZsDqe1luHPdGTrQIUaUXD27Ja3gHsdOIs/cXzNchWGlqm+qRVRg==", + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz", + "integrity": "sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ==", "dev": true, "requires": { "array-includes": "^3.1.4", @@ -17307,11 +17461,39 @@ "vary": "~1.1.2" }, "dependencies": { + "body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + } + }, "cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" }, + "raw-body": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "requires": { + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -17705,9 +17887,9 @@ } }, "googleapis": { - "version": "95.0.0", - "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-95.0.0.tgz", - "integrity": "sha512-ZpFZW7FDwcjQa2+xZNS2SC5sK2s46iWKA5QSFVJSK3RELQec4PYHhzKwzbeCzt4urnjYp6udPif95zXTFxbtRA==", + "version": "100.0.0", + "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-100.0.0.tgz", + "integrity": "sha512-RToFQGY54B756IDbjdyjb1vWFmn03bYpXHB2lIf0eq2UBYsIbYOLZ0kqSomfJnpclEukwEmMF7Jn6Wsev871ew==", "requires": { "google-auth-library": "^7.0.2", "googleapis-common": "^5.0.2" @@ -18043,9 +18225,9 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "ignore-by-default": { @@ -19614,12 +19796,9 @@ "dev": true }, "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" }, "jsonfile": { "version": "6.1.0", @@ -19684,9 +19863,9 @@ "integrity": "sha512-40aUybvhH9t2h71ncA1/1SbtTNCVZHgsTsTgqPUxGWDmUDrXyDf2wMNQKEbdBjbf4AI+fQhbECNTV6lWxQKUzg==" }, "kareem": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.4.tgz", - "integrity": "sha512-Vcrt8lcpVl0s8ePx634BxwRqmFo+5DcOhlmNadehxreMTIQi/9hOL/B3hZQQbK5DgMS7Lem3xABXV7/S3jy+7g==" + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.5.tgz", + "integrity": "sha512-qxCyQtp3ioawkiRNQr/v8xw9KIviMSSNmy+63Wubj7KmMn3g7noRXIZB4vPCAP+ETi2SR8eH6CvmlKZuGpoHOg==" }, "keyv": { "version": "3.1.0", @@ -19879,9 +20058,9 @@ } }, "marked": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz", - "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==" + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz", + "integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==" }, "marked-extended-tables": { "version": "1.0.3", @@ -20097,9 +20276,9 @@ } }, "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==" }, "mixin-deep": { "version": "1.3.2", @@ -20149,9 +20328,9 @@ } }, "moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + "version": "2.29.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz", + "integrity": "sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==" }, "mongodb": { "version": "4.3.1", @@ -20175,12 +20354,12 @@ } }, "mongoose": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.4.tgz", - "integrity": "sha512-3hA3IGxBzZdlp1+/I9qn53NjEAd01qvKAH2WUCPahjVO8+uAmR0B4m+1bC3x9a4r0ExY8QYQ2ryG3E/v5Tj+jA==", + "version": "6.2.10", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.10.tgz", + "integrity": "sha512-Yp+6UH5M0AlxAVGdC2/Deq0St+2qW73oKCnhJDr83bOZ12eflTLTT5uQF0p6KzvtFj86XWbq/7ApvO4yW6h1sA==", "requires": { "bson": "^4.2.2", - "kareem": "2.3.4", + "kareem": "2.3.5", "mongodb": "4.3.1", "mpath": "0.8.4", "mquery": "4.0.2", @@ -20235,9 +20414,9 @@ "optional": true }, "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", + "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==" }, "nanomatch": { "version": "1.2.13", @@ -20270,9 +20449,9 @@ "dev": true }, "nconf": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.11.3.tgz", - "integrity": "sha512-iYsAuDS9pzjVMGIzJrGE0Vk3Eh8r/suJanRAnWGBd29rVS2XtSgzcAo5l6asV3e4hH2idVONHirg1efoBOslBg==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.11.4.tgz", + "integrity": "sha512-YaDR846q11JnG1vTrhJ0QIlhiGY6+W1bgWtReG9SS3vkTl3AoNwFvUItdhG6/ZjGCfWpUVuRTNEBTDAQ3nWhGw==", "requires": { "async": "^1.4.0", "ini": "^2.0.0", @@ -20471,8 +20650,7 @@ "object-inspect": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" }, "object-keys": { "version": "1.1.1", @@ -20998,14 +21176,43 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "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": "1.8.1", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "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" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + } } }, "rc": { @@ -21539,7 +21746,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, "requires": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", diff --git a/package.json b/package.json index b2f2dcddd..504ef46b4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "homebrewery", "description": "Create authentic looking D&D homebrews using only markdown", - "version": "3.0.7", + "version": "3.0.8", "engines": { "node": "16.11.x" }, @@ -20,6 +20,9 @@ "verify": "npm run lint && npm test", "test": "jest", "test:dev": "jest --verbose --watch", + "test:basic": "jest tests/markdown/basic.test.js --verbose", + "test:mustache-span": "jest tests/markdown/mustache-span.test.js --verbose", + "test:route": "jest tests/routes/static-pages.test.js --verbose", "phb": "node scripts/phb.js", "prod": "set NODE_ENV=production && npm run build", "postinstall": "npm run buildall", @@ -31,6 +34,7 @@ "build/*" ], "jest": { + "testTimeout" : 15000, "modulePaths": [ "mode_modules", "shared", @@ -47,11 +51,11 @@ ] }, "dependencies": { - "@babel/core": "^7.17.5", + "@babel/core": "^7.17.9", "@babel/plugin-transform-runtime": "^7.17.0", "@babel/preset-env": "^7.16.11", "@babel/preset-react": "^7.16.7", - "body-parser": "^1.19.2", + "body-parser": "^1.20.0", "classnames": "^2.3.1", "codemirror": "^5.65.2", "cookie-parser": "^1.4.6", @@ -61,18 +65,18 @@ "express-async-handler": "^1.2.0", "express-static-gzip": "2.1.5", "fs-extra": "10.0.1", - "googleapis": "95.0.0", + "googleapis": "100.0.0", "js-yaml": "^4.1.0", "jwt-simple": "^0.5.6", "less": "^3.13.1", "lodash": "^4.17.21", - "marked": "4.0.12", + "marked": "4.0.14", "marked-extended-tables": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", - "moment": "^2.29.1", - "mongoose": "^6.2.4", - "nanoid": "3.3.1", - "nconf": "^0.11.3", + "moment": "^2.29.2", + "mongoose": "^6.2.10", + "nanoid": "3.3.2", + "nconf": "^0.11.4", "query-string": "7.1.1", "react": "^16.14.0", "react-dom": "^16.14.0", @@ -83,8 +87,8 @@ "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" }, "devDependencies": { - "eslint": "^8.10.0", - "eslint-plugin-react": "^7.29.3", + "eslint": "^8.13.0", + "eslint-plugin-react": "^7.29.4", "jest": "^27.5.1", "supertest": "^6.2.2" } diff --git a/server/googleActions.js b/server/googleActions.js index bf48d945d..89691e0d8 100644 --- a/server/googleActions.js +++ b/server/googleActions.js @@ -182,8 +182,8 @@ const GoogleActions = { 'description' : `${brew.description}`, 'parents' : [folderId], 'properties' : { //AppProperties is not accessible - 'shareId' : nanoid(12), - 'editId' : nanoid(12), + 'shareId' : brew.shareId || nanoid(12), + 'editId' : brew.editId || nanoid(12), 'title' : brew.title, 'views' : '0', 'pageCount' : brew.pageCount, diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 747c2360c..4415c948b 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -5,6 +5,7 @@ const zlib = require('zlib'); const GoogleActions = require('./googleActions.js'); const Markdown = require('../shared/naturalcrit/markdown.js'); const yaml = require('js-yaml'); +const asyncHandler = require('express-async-handler'); // const getTopBrews = (cb) => { // HomebrewModel.find().sort({ views: -1 }).limit(5).exec(function(err, brews) { @@ -41,154 +42,195 @@ const excludePropsFromUpdate = (brew)=>{ const propsToExclude = ['views', 'lastViewed']; for (const prop of propsToExclude) { delete brew[prop]; - }; + } return brew; }; -const newBrew = (req, res)=>{ - const brew = req.body; - +const beforeNewSave = (account, brew)=>{ if(!brew.title) { brew.title = getGoodBrewTitle(brew.text); } - brew.authors = (req.account) ? [req.account.username] : []; + brew.authors = (account) ? [account.username] : []; brew.text = mergeBrewText(brew); +}; - delete brew.editId; - delete brew.shareId; - delete brew.googleId; - +const newLocalBrew = async (brew)=>{ const newHomebrew = new HomebrewModel(brew); // Compress brew text to binary before saving newHomebrew.textBin = zlib.deflateRawSync(newHomebrew.text); // Delete the non-binary text field since it's not needed anymore newHomebrew.text = undefined; - newHomebrew.save((err, obj)=>{ - if(err) { - console.error(err, err.toString(), err.stack); - return res.status(500).send(`Error while creating new brew, ${err.toString()}`); - } - - obj = obj.toObject(); - obj.gDrive = false; - return res.status(200).send(obj); - }); -}; - -const updateBrew = (req, res)=>{ - HomebrewModel.get({ editId: req.params.id }) - .then((brew)=>{ - const updateBrew = excludePropsFromUpdate(req.body); - brew = _.merge(brew, updateBrew); - brew.text = mergeBrewText(brew); - - // Compress brew text to binary before saving - brew.textBin = zlib.deflateRawSync(brew.text); - // Delete the non-binary text field since it's not needed anymore - brew.text = undefined; - brew.updatedAt = new Date(); - - if(req.account) { - brew.authors = _.uniq(_.concat(brew.authors, req.account.username)); - } - - brew.markModified('authors'); - brew.markModified('systems'); - - brew.save((err, obj)=>{ - if(err) throw err; - return res.status(200).send(obj); - }); - }) + let saved = await newHomebrew.save() .catch((err)=>{ - console.error(err); - return res.status(500).send('Error while saving'); + console.error(err, err.toString(), err.stack); + throw `Error while creating new brew, ${err.toString()}`; }); + + saved = saved.toObject(); + saved.gDrive = false; + return saved; }; -const deleteBrew = (req, res)=>{ - HomebrewModel.find({ editId: req.params.id }, (err, objs)=>{ - if(!objs.length || err) { - return res.status(404).send('Can not find homebrew with that id'); - } +const newGoogleBrew = async (account, brew, res)=>{ + const oAuth2Client = GoogleActions.authCheck(account, res); - const brew = objs[0]; - - if(req.account) { - // Remove current user as author - brew.authors = _.pull(brew.authors, req.account.username); - brew.markModified('authors'); - } - - if(brew.authors.length === 0) { - // Delete brew if there are no authors left - brew.remove((err)=>{ - if(err) return res.status(500).send('Error while removing'); - return res.status(200).send(); - }); - } else { - // Otherwise, save the brew with updated author list - brew.save((err, savedBrew)=>{ - if(err) throw err; - return res.status(200).send(savedBrew); - }); - } - }); + return await GoogleActions.newGoogleBrew(oAuth2Client, brew); }; -const newGoogleBrew = async (req, res, next)=>{ - let oAuth2Client; - - try { oAuth2Client = GoogleActions.authCheck(req.account, res); } catch (err) { return res.status(err.status).send(err.message); } - +const newBrew = async (req, res)=>{ const brew = req.body; - - if(!brew.title) { - brew.title = getGoodBrewTitle(brew.text); - } - - brew.authors = (req.account) ? [req.account.username] : []; - brew.text = mergeBrewText(brew); + const { transferToGoogle } = req.query; delete brew.editId; delete brew.shareId; delete brew.googleId; - req.body = brew; + beforeNewSave(req.account, brew); - try { - const newBrew = await GoogleActions.newGoogleBrew(oAuth2Client, brew); - return res.status(200).send(newBrew); - } catch (err) { - return res.status(err.response.status).send(err); + let saved; + if(transferToGoogle) { + saved = await newGoogleBrew(req.account, brew, res) + .catch((err)=>{ + res.status(err.status || err.response.status).send(err.message || err); + }); + } else { + saved = await newLocalBrew(brew) + .catch((err)=>{ + res.status(500).send(err); + }); + } + if(!saved) return; + return res.status(200).send(saved); +}; + +const updateBrew = async (req, res)=>{ + let brew = excludePropsFromUpdate(req.body); + const { transferToGoogle, transferFromGoogle } = req.query; + + let saved; + if(brew.googleId && transferFromGoogle) { + beforeNewSave(req.account, brew); + + saved = await newLocalBrew(brew) + .catch((err)=>{ + console.error(err); + res.status(500).send(err); + }); + if(!saved) return; + + await deleteGoogleBrew(req.account, `${brew.googleId}${brew.editId}`, res) + .catch((err)=>{ + console.error(err); + res.status(err.status || err.response.status).send(err.message || err); + }); + } else if(!brew.googleId && transferToGoogle) { + saved = await newGoogleBrew(req.account, brew, res) + .catch((err)=>{ + console.error(err); + res.status(err.status || err.response.status).send(err.message || err); + }); + if(!saved) return; + + await deleteLocalBrew(req.account, brew.editId) + .catch((err)=>{ + console.error(err); + res.status(err.status).send(err.message); + }); + } else if(brew.googleId) { + brew.text = mergeBrewText(brew); + + saved = await GoogleActions.updateGoogleBrew(brew) + .catch((err)=>{ + console.error(err); + res.status(err.response?.status || 500).send(err); + }); + } else { + const dbBrew = await HomebrewModel.get({ editId: req.params.id }) + .catch((err)=>{ + console.error(err); + return res.status(500).send('Error while saving'); + }); + + brew = _.merge(dbBrew, brew); + brew.text = mergeBrewText(brew); + + // Compress brew text to binary before saving + brew.textBin = zlib.deflateRawSync(brew.text); + // Delete the non-binary text field since it's not needed anymore + brew.text = undefined; + brew.updatedAt = new Date(); + + if(req.account) { + brew.authors = _.uniq(_.concat(brew.authors, req.account.username)); + } + + brew.markModified('authors'); + brew.markModified('systems'); + + saved = await brew.save(); + } + if(!saved) return; + + if(!res.headersSent) return res.status(200).send(saved); +}; + +const deleteBrew = async (req, res)=>{ + if(req.params.id.length > 12) { + const deleted = await deleteGoogleBrew(req.account, req.params.id, res) + .catch((err)=>{ + res.status(500).send(err); + }); + if(deleted) return res.status(200).send(); + } else { + const deleted = await deleteLocalBrew(req.account, req.params.id) + .catch((err)=>{ + res.status(err.status).send(err.message); + }); + if(deleted) return res.status(200).send(deleted); + return res.status(200).send(); } }; -const updateGoogleBrew = async (req, res, next)=>{ - const brew = excludePropsFromUpdate(req.body); - brew.text = mergeBrewText(brew); +const deleteLocalBrew = async (account, id)=>{ + const brew = await HomebrewModel.findOne({ editId: id }); + if(!brew) { + throw { status: 404, message: 'Can not find homebrew with that id' }; + } - try { - const updatedBrew = await GoogleActions.updateGoogleBrew(brew); - return res.status(200).send(updatedBrew); - } catch (err) { - return res.status(err.response?.status || 500).send(err); + if(account) { + // Remove current user as author + brew.authors = _.pull(brew.authors, account.username); + brew.markModified('authors'); + } + + if(brew.authors.length === 0) { + // Delete brew if there are no authors left + await brew.remove() + .catch((err)=>{ + console.error(err); + throw { status: 500, message: 'Error while removing' }; + }); + } else { + // Otherwise, save the brew with updated author list + return await brew.save() + .catch((err)=>{ + throw { status: 500, message: err }; + }); } }; -router.post('/api', newBrew); -router.post('/api/newGoogle/', newGoogleBrew); -router.put('/api/:id', updateBrew); -router.put('/api/update/:id', updateBrew); -router.put('/api/updateGoogle/:id', updateGoogleBrew); -router.delete('/api/:id', deleteBrew); -router.get('/api/remove/:id', deleteBrew); -router.get('/api/removeGoogle/:id', async (req, res)=>{ - const auth = await GoogleActions.authCheck(req.account, res); - await GoogleActions.deleteGoogleBrew(auth, req.params.id); - return res.status(200).send(); -}); +const deleteGoogleBrew = async (account, id, res)=>{ + const auth = await GoogleActions.authCheck(account, res); + await GoogleActions.deleteGoogleBrew(auth, id); + return true; +}; + +router.post('/api', asyncHandler(newBrew)); +router.put('/api/:id', asyncHandler(updateBrew)); +router.put('/api/update/:id', asyncHandler(updateBrew)); +router.delete('/api/:id', asyncHandler(deleteBrew)); +router.get('/api/remove/:id', asyncHandler(deleteBrew)); module.exports = router; diff --git a/shared/naturalcrit/splitPane/splitPane.jsx b/shared/naturalcrit/splitPane/splitPane.jsx index 1b4cee5ae..4d138e30b 100644 --- a/shared/naturalcrit/splitPane/splitPane.jsx +++ b/shared/naturalcrit/splitPane/splitPane.jsx @@ -10,43 +10,69 @@ const SplitPane = createClass({ return { storageKey : 'naturalcrit-pane-split', onDragFinish : function(){} //fires when dragging - }; }, + getInitialState : function() { return { - size : null, - isDragging : false + currentDividerPos : null, + windowWidth : 0, + isDragging : false }; }, + componentDidMount : function() { - const paneSize = window.localStorage.getItem(this.props.storageKey); - if(paneSize){ + const dividerPos = window.localStorage.getItem(this.props.storageKey); + if(dividerPos){ this.setState({ - size : paneSize + currentDividerPos : this.limitPosition(dividerPos, 0.1*(window.innerWidth-13), 0.9*(window.innerWidth-13)), + userSetDividerPos : dividerPos, + windowWidth : window.innerWidth }); } + window.addEventListener('resize', this.handleWindowResize); + }, + + componentWillUnmount : function() { + window.removeEventListener('resize', this.handleWindowResize); + }, + + handleWindowResize : function() { + // Allow divider to increase in size to last user-set position + // Limit current position to between 10% and 90% of visible space + const newLoc = this.limitPosition(this.state.userSetDividerPos, 0.1*(window.innerWidth-13), 0.9*(window.innerWidth-13)); + + this.setState({ + currentDividerPos : newLoc, + windowWidth : window.innerWidth + }); + }, + + limitPosition : function(x, min = 1, max = window.innerWidth - 13) { + const result = Math.round(Math.min(max, Math.max(min, x))); + return result; }, handleUp : function(){ if(this.state.isDragging){ - this.props.onDragFinish(this.state.size); - window.localStorage.setItem(this.props.storageKey, this.state.size); + this.props.onDragFinish(this.state.currentDividerPos); + window.localStorage.setItem(this.props.storageKey, this.state.currentDividerPos); } this.setState({ isDragging: false }); }, + handleDown : function(){ this.setState({ isDragging: true }); //this.unFocus() }, + handleMove : function(e){ if(!this.state.isDragging) return; - const minWidth = 1; - const maxWidth = window.innerWidth - 13; - const newSize = Math.min(maxWidth, Math.max(minWidth, e.pageX)); + const newSize = this.limitPosition(e.pageX); this.setState({ - size : newSize + currentDividerPos : newSize, + userSetDividerPos : newSize }); }, /* @@ -70,7 +96,7 @@ const SplitPane = createClass({ render : function(){ return
- {this.props.children[0]} + {this.props.children[0]} {this.renderDivider()} {this.props.children[1]}
; diff --git a/themes/5ePhb.style.less b/themes/5ePhb.style.less index 63af5e972..0ca89693b 100644 --- a/themes/5ePhb.style.less +++ b/themes/5ePhb.style.less @@ -621,6 +621,8 @@ body { } &.decoration { transform-style : preserve-3d; + z-index: -1; + position:relative; } &.decoration::before { content :''; @@ -656,7 +658,7 @@ body { margin-bottom : 0.3cm; } a{ - display : table; + display : inline; color : inherit; text-decoration : none; &:hover{