mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-24 14:12:40 +00:00
Merge branch 'master' into fixContentNegotiationTestFail-#3904
This commit is contained in:
10
babel.config.json
Normal file
10
babel.config.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"presets": [
|
||||
"@babel/preset-env",
|
||||
"@babel/preset-react"
|
||||
],
|
||||
"plugins": [
|
||||
"@babel/plugin-transform-runtime",
|
||||
"babel-plugin-transform-import-meta"
|
||||
]
|
||||
}
|
||||
@@ -5,7 +5,7 @@ const { useState, useRef, useCallback, useMemo } = React;
|
||||
const _ = require('lodash');
|
||||
|
||||
const MarkdownLegacy = require('naturalcrit/markdownLegacy.js');
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
import Markdown from 'naturalcrit/markdown.js';
|
||||
const ErrorBar = require('./errorBar/errorBar.jsx');
|
||||
const ToolBar = require('./toolBar/toolBar.jsx');
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require('./notificationPopup.less');
|
||||
import React, { useEffect, useState } from 'react';
|
||||
const request = require('../../utils/request-middleware.js');
|
||||
import request from '../../utils/request-middleware.js';
|
||||
|
||||
import Dialog from '../../../components/dialog.jsx';
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
const Markdown = require('../../../shared/naturalcrit/markdown.js');
|
||||
import Markdown from '../../../shared/naturalcrit/markdown.js';
|
||||
|
||||
const CodeEditor = require('naturalcrit/codeEditor/codeEditor.jsx');
|
||||
const SnippetBar = require('./snippetbar/snippetbar.jsx');
|
||||
|
||||
@@ -3,7 +3,7 @@ require('./metadataEditor.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const request = require('../../utils/request-middleware.js');
|
||||
import request from '../../utils/request-middleware.js';
|
||||
const Nav = require('naturalcrit/nav/nav.jsx');
|
||||
const Combobox = require('client/components/combobox.jsx');
|
||||
const TagInput = require('../tagInput/tagInput.jsx');
|
||||
|
||||
@@ -2,7 +2,7 @@ require('./brewItem.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const moment = require('moment');
|
||||
const request = require('../../../../utils/request-middleware.js');
|
||||
import request from '../../../../utils/request-middleware.js';
|
||||
|
||||
const googleDriveIcon = require('../../../../googleDrive.svg');
|
||||
const homebreweryIcon = require('../../../../thumbnail.png');
|
||||
|
||||
@@ -4,7 +4,7 @@ const React = require('react');
|
||||
const _ = require('lodash');
|
||||
const createClass = require('create-react-class');
|
||||
|
||||
const request = require('../../utils/request-middleware.js');
|
||||
import request from '../../utils/request-middleware.js';
|
||||
const { Meta } = require('vitreum/headtags');
|
||||
|
||||
const Nav = require('naturalcrit/nav/nav.jsx');
|
||||
@@ -23,7 +23,7 @@ const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
|
||||
|
||||
const LockNotification = require('./lockNotification/lockNotification.jsx');
|
||||
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
import Markdown from 'naturalcrit/markdown.js';
|
||||
|
||||
const { DEFAULT_BREW_LOAD } = require('../../../../server/brewDefaults.js');
|
||||
const { printCurrentBrew, fetchThemeBundle } = require('../../../../shared/helpers.js');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
require('./errorPage.less');
|
||||
const React = require('react');
|
||||
const UIPage = require('../basePages/uiPage/uiPage.jsx');
|
||||
const Markdown = require('../../../../shared/naturalcrit/markdown.js');
|
||||
import Markdown from '../../../../shared/naturalcrit/markdown.js';
|
||||
const ErrorIndex = require('./errors/errorIndex.js');
|
||||
|
||||
const ErrorPage = ({ brew })=>{
|
||||
|
||||
@@ -2,7 +2,7 @@ require('./homePage.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const cx = require('classnames');
|
||||
const request = require('../../utils/request-middleware.js');
|
||||
import request from '../../utils/request-middleware.js';
|
||||
const { Meta } = require('vitreum/headtags');
|
||||
|
||||
const Nav = require('naturalcrit/nav/nav.jsx');
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
require('./newPage.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const request = require('../../utils/request-middleware.js');
|
||||
import request from '../../utils/request-middleware.js';
|
||||
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
import Markdown from 'naturalcrit/markdown.js';
|
||||
|
||||
const Nav = require('naturalcrit/nav/nav.jsx');
|
||||
const PrintNavItem = require('../../navbar/print.navitem.jsx');
|
||||
|
||||
@@ -15,7 +15,7 @@ const BrewItem = require('../basePages/listPage/brewItem/brewItem.jsx');
|
||||
const SplitPane = require('../../../../shared/naturalcrit/splitPane/splitPane.jsx');
|
||||
const ErrorIndex = require('../errorPage/errors/errorIndex.js');
|
||||
|
||||
const request = require('../../utils/request-middleware.js');
|
||||
import request from '../../utils/request-middleware.js';
|
||||
|
||||
const VaultPage = (props)=>{
|
||||
const [pageState, setPageState] = useState(parseInt(props.query.page) || 1);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const request = require('superagent');
|
||||
import request from 'superagent';
|
||||
|
||||
const addHeader = (request)=>request.set('Homebrewery-Version', global.version);
|
||||
|
||||
@@ -9,4 +9,4 @@ const requestMiddleware = {
|
||||
delete : (path)=>addHeader(request.delete(path)),
|
||||
};
|
||||
|
||||
module.exports = requestMiddleware;
|
||||
export default requestMiddleware;
|
||||
@@ -8,6 +8,8 @@ const template = async function(name, title='', props = {}){
|
||||
});
|
||||
const ogMetaTags = ogTags.join('\n');
|
||||
|
||||
const ssrModule = await import(`../build/${name}/ssr.cjs`);
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@@ -21,7 +23,7 @@ const template = async function(name, title='', props = {}){
|
||||
<title>${title.length ? `${title} - The Homebrewery`: 'The Homebrewery - NaturalCrit'}</title>
|
||||
</head>
|
||||
<body>
|
||||
<main id="reactRoot">${require(`../build/${name}/ssr.js`)(props)}</main>
|
||||
<main id="reactRoot">${ssrModule.default(props)}</main>
|
||||
<script src=${`/${name}/bundle.js`}></script>
|
||||
<script>start_app(${JSON.stringify(props)})</script>
|
||||
</body>
|
||||
@@ -29,4 +31,4 @@ const template = async function(name, title='', props = {}){
|
||||
`;
|
||||
};
|
||||
|
||||
module.exports = template;
|
||||
export default template;
|
||||
150
package-lock.json
generated
150
package-lock.json
generated
@@ -21,7 +21,7 @@
|
||||
"cookie-parser": "^1.4.7",
|
||||
"create-react-class": "^15.7.0",
|
||||
"dedent-tabs": "^0.10.3",
|
||||
"dompurify": "^3.2.0",
|
||||
"dompurify": "^3.2.1",
|
||||
"expr-eval": "^2.0.2",
|
||||
"express": "^4.21.1",
|
||||
"express-async-handler": "^1.2.0",
|
||||
@@ -39,8 +39,8 @@
|
||||
"marked-smartypants-lite": "^1.0.2",
|
||||
"markedLegacy": "npm:marked@^0.3.19",
|
||||
"moment": "^2.30.1",
|
||||
"mongoose": "^8.8.1",
|
||||
"nanoid": "3.3.4",
|
||||
"mongoose": "^8.8.2",
|
||||
"nanoid": "5.0.8",
|
||||
"nconf": "^0.12.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
@@ -52,7 +52,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@stylistic/stylelint-plugin": "^3.1.1",
|
||||
"eslint": "^9.14.0",
|
||||
"babel-plugin-transform-import-meta": "^2.2.1",
|
||||
"eslint": "^9.15.0",
|
||||
"eslint-plugin-jest": "^28.9.0",
|
||||
"eslint-plugin-react": "^7.37.2",
|
||||
"globals": "^15.12.0",
|
||||
@@ -559,6 +560,7 @@
|
||||
"version": "7.26.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
|
||||
"integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
},
|
||||
@@ -1869,9 +1871,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/config-array": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz",
|
||||
"integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==",
|
||||
"version": "0.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.0.tgz",
|
||||
"integrity": "sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint/object-schema": "^2.1.4",
|
||||
@@ -1883,20 +1885,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/core": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz",
|
||||
"integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==",
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.0.tgz",
|
||||
"integrity": "sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
|
||||
"integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz",
|
||||
"integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
@@ -1920,7 +1921,6 @@
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
|
||||
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
@@ -1929,9 +1929,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "9.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz",
|
||||
"integrity": "sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==",
|
||||
"version": "9.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.15.0.tgz",
|
||||
"integrity": "sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -1947,9 +1947,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/plugin-kit": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz",
|
||||
"integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==",
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz",
|
||||
"integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"levn": "^0.4.1"
|
||||
@@ -3082,6 +3082,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/trusted-types": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
|
||||
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@types/webidl-conversions": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
|
||||
@@ -3283,7 +3289,6 @@
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
}
|
||||
@@ -3337,7 +3342,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
@@ -3881,6 +3885,27 @@
|
||||
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-import-meta": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.2.1.tgz",
|
||||
"integrity": "sha512-AxNh27Pcg8Kt112RGa3Vod2QS2YXKKJ6+nSvRtv7qQTJAdx0MZa4UHZ4lnxHUWA2MNbLuZQv5FVab4P1CoLOWw==",
|
||||
"dev": true,
|
||||
"license": "BSD",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.4.4",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-transform-import-meta/node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"dev": true,
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/babel-preset-current-node-syntax": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
|
||||
@@ -4977,11 +5002,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
@@ -5455,9 +5479,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/dompurify": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.0.tgz",
|
||||
"integrity": "sha512-AMdOzK44oFWqHEi0wpOqix/fUNY707OmoeFDnbi3Q5I8uOpy21ufUA5cDJPr0bosxrflOVD/H2DMSvuGKJGfmQ=="
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.1.tgz",
|
||||
"integrity": "sha512-NBHEsc0/kzRYQd+AY6HR6B/IgsqzBABrqJbpCDQII/OK6h7B7LXzweZTDsqSW2LkTRpoxf18YUP+YjGySk6B3w==",
|
||||
"optionalDependencies": {
|
||||
"@types/trusted-types": "^2.0.7"
|
||||
}
|
||||
},
|
||||
"node_modules/duplexer2": {
|
||||
"version": "0.1.4",
|
||||
@@ -5489,9 +5516,9 @@
|
||||
"integrity": "sha512-M+7ph0VGBQqqpTT2YrabjNKSQ2fEl9PVx6AK3N558gDH9NO8O6XN9SXXFWRo9u9PbEg/bWq+tjXQr+eXmxubCw=="
|
||||
},
|
||||
"node_modules/elliptic": {
|
||||
"version": "6.5.7",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz",
|
||||
"integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==",
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.0.tgz",
|
||||
"integrity": "sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==",
|
||||
"dependencies": {
|
||||
"bn.js": "^4.11.9",
|
||||
"brorand": "^1.1.0",
|
||||
@@ -5761,26 +5788,26 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "9.14.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz",
|
||||
"integrity": "sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==",
|
||||
"version": "9.15.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.15.0.tgz",
|
||||
"integrity": "sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
"@eslint/config-array": "^0.18.0",
|
||||
"@eslint/core": "^0.7.0",
|
||||
"@eslint/eslintrc": "^3.1.0",
|
||||
"@eslint/js": "9.14.0",
|
||||
"@eslint/plugin-kit": "^0.2.0",
|
||||
"@eslint/config-array": "^0.19.0",
|
||||
"@eslint/core": "^0.9.0",
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
"@eslint/js": "9.15.0",
|
||||
"@eslint/plugin-kit": "^0.2.3",
|
||||
"@humanfs/node": "^0.16.6",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@humanwhocodes/retry": "^0.4.0",
|
||||
"@humanwhocodes/retry": "^0.4.1",
|
||||
"@types/estree": "^1.0.6",
|
||||
"@types/json-schema": "^7.0.15",
|
||||
"ajv": "^6.12.4",
|
||||
"chalk": "^4.0.0",
|
||||
"cross-spawn": "^7.0.2",
|
||||
"cross-spawn": "^7.0.5",
|
||||
"debug": "^4.3.2",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"eslint-scope": "^8.2.0",
|
||||
@@ -5799,8 +5826,7 @@
|
||||
"lodash.merge": "^4.6.2",
|
||||
"minimatch": "^3.1.2",
|
||||
"natural-compare": "^1.4.0",
|
||||
"optionator": "^0.9.3",
|
||||
"text-table": "^0.2.0"
|
||||
"optionator": "^0.9.3"
|
||||
},
|
||||
"bin": {
|
||||
"eslint": "bin/eslint.js"
|
||||
@@ -10064,8 +10090,7 @@
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json-stable-stringify": {
|
||||
"version": "0.0.1",
|
||||
@@ -10866,9 +10891,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mongoose": {
|
||||
"version": "8.8.1",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.1.tgz",
|
||||
"integrity": "sha512-l7DgeY1szT98+EKU8GYnga5WnyatAu+kOQ2VlVX1Mxif6A0Umt0YkSiksCiyGxzx8SPhGe9a53ND1GD4yVDrPA==",
|
||||
"version": "8.8.2",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.2.tgz",
|
||||
"integrity": "sha512-jCTSqDANfRzk909v4YoZQi7jlGRB2MTvgG+spVBc/BA4tOs1oWJr//V6yYujqNq9UybpOtsSfBqxI0dSOEFJHQ==",
|
||||
"dependencies": {
|
||||
"bson": "^6.7.0",
|
||||
"kareem": "2.6.3",
|
||||
@@ -11022,15 +11047,20 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
|
||||
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
|
||||
"license": "MIT",
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.8.tgz",
|
||||
"integrity": "sha512-TcJPw+9RV9dibz1hHUzlLVy8N4X9TnwirAjrU08Juo6BNKggzVfP2ZJ/3ZUSq15Xl5i85i+Z89XBO90pB2PghQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
"nanoid": "bin/nanoid.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
"node": "^18 || >=20"
|
||||
}
|
||||
},
|
||||
"node_modules/nanomatch": {
|
||||
@@ -14061,13 +14091,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
@@ -14679,7 +14702,6 @@
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
|
||||
22
package.json
22
package.json
@@ -2,6 +2,7 @@
|
||||
"name": "homebrewery",
|
||||
"description": "Create authentic looking D&D homebrews using only markdown",
|
||||
"version": "3.16.0",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"npm": "^10.2.x",
|
||||
"node": "^20.18.x"
|
||||
@@ -57,6 +58,9 @@
|
||||
"shared",
|
||||
"server"
|
||||
],
|
||||
"transformIgnorePatterns": [
|
||||
"node_modules/(?!nanoid/).*"
|
||||
],
|
||||
"coveragePathIgnorePatterns": [
|
||||
"build/*"
|
||||
],
|
||||
@@ -78,15 +82,6 @@
|
||||
"jest-expect-message"
|
||||
]
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
"@babel/preset-env",
|
||||
"@babel/preset-react"
|
||||
],
|
||||
"plugins": [
|
||||
"@babel/plugin-transform-runtime"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.26.0",
|
||||
"@babel/plugin-transform-runtime": "^7.25.9",
|
||||
@@ -99,7 +94,7 @@
|
||||
"cookie-parser": "^1.4.7",
|
||||
"create-react-class": "^15.7.0",
|
||||
"dedent-tabs": "^0.10.3",
|
||||
"dompurify": "^3.2.0",
|
||||
"dompurify": "^3.2.1",
|
||||
"expr-eval": "^2.0.2",
|
||||
"express": "^4.21.1",
|
||||
"express-async-handler": "^1.2.0",
|
||||
@@ -117,8 +112,8 @@
|
||||
"marked-smartypants-lite": "^1.0.2",
|
||||
"markedLegacy": "npm:marked@^0.3.19",
|
||||
"moment": "^2.30.1",
|
||||
"mongoose": "^8.8.1",
|
||||
"nanoid": "3.3.4",
|
||||
"mongoose": "^8.8.2",
|
||||
"nanoid": "5.0.8",
|
||||
"nconf": "^0.12.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
@@ -130,7 +125,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@stylistic/stylelint-plugin": "^3.1.1",
|
||||
"eslint": "^9.14.0",
|
||||
"babel-plugin-transform-import-meta": "^2.2.1",
|
||||
"eslint": "^9.15.0",
|
||||
"eslint-plugin-jest": "^28.9.0",
|
||||
"eslint-plugin-react": "^7.37.2",
|
||||
"globals": "^15.12.0",
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
const fs = require('fs-extra');
|
||||
const Proj = require('./project.json');
|
||||
|
||||
const { pack } = require('vitreum');
|
||||
import fs from 'fs-extra';
|
||||
import Proj from './project.json' with { type: 'json' };
|
||||
import vitreum from 'vitreum';
|
||||
const { pack } = vitreum;
|
||||
|
||||
import lessTransform from 'vitreum/transforms/less.js';
|
||||
import assetTransform from 'vitreum/transforms/asset.js';
|
||||
|
||||
const isDev = !!process.argv.find((arg)=>arg=='--dev');
|
||||
|
||||
const lessTransform = require('vitreum/transforms/less.js');
|
||||
const assetTransform = require('vitreum/transforms/asset.js');
|
||||
//const Meta = require('vitreum/headtags');
|
||||
|
||||
const transforms = {
|
||||
'.less' : lessTransform,
|
||||
'*' : assetTransform('./build')
|
||||
@@ -17,7 +18,7 @@ const build = async ({ bundle, render, ssr })=>{
|
||||
const css = await lessTransform.generate({ paths: './shared' });
|
||||
await fs.outputFile('./build/admin/bundle.css', css);
|
||||
await fs.outputFile('./build/admin/bundle.js', bundle);
|
||||
await fs.outputFile('./build/admin/ssr.js', ssr);
|
||||
await fs.outputFile('./build/admin/ssr.cjs', ssr);
|
||||
};
|
||||
|
||||
fs.emptyDirSync('./build/admin');
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
const fs = require('fs-extra');
|
||||
const zlib = require('zlib');
|
||||
const Proj = require('./project.json');
|
||||
import fs from 'fs-extra';
|
||||
import zlib from 'zlib';
|
||||
import Proj from './project.json' with { type: 'json' };
|
||||
import vitreum from 'vitreum';
|
||||
const { pack, watchFile, livereload } = vitreum;
|
||||
|
||||
const { pack, watchFile, livereload } = require('vitreum');
|
||||
const isDev = !!process.argv.find((arg)=>arg=='--dev');
|
||||
import lessTransform from 'vitreum/transforms/less.js';
|
||||
import assetTransform from 'vitreum/transforms/asset.js';
|
||||
import babel from '@babel/core';
|
||||
import less from 'less';
|
||||
|
||||
const lessTransform = require('vitreum/transforms/less.js');
|
||||
const assetTransform = require('vitreum/transforms/asset.js');
|
||||
const babel = require('@babel/core');
|
||||
const less = require('less');
|
||||
const isDev = !!process.argv.find((arg) => arg === '--dev');
|
||||
|
||||
const babelify = async (code)=>(await babel.transformAsync(code, { presets: [['@babel/preset-env', { 'exclude': ['proposal-dynamic-import'] }], '@babel/preset-react'], plugins: ['@babel/plugin-transform-runtime'] })).code;
|
||||
|
||||
@@ -24,7 +25,7 @@ const build = async ({ bundle, render, ssr })=>{
|
||||
//css = `@layer bundle {\n${css}\n}`;
|
||||
await fs.outputFile('./build/homebrew/bundle.css', css);
|
||||
await fs.outputFile('./build/homebrew/bundle.js', bundle);
|
||||
await fs.outputFile('./build/homebrew/ssr.js', ssr);
|
||||
await fs.outputFile('./build/homebrew/ssr.cjs', ssr);
|
||||
|
||||
await fs.copy('./client/homebrew/favicon.ico', './build/assets/favicon.ico');
|
||||
|
||||
@@ -51,7 +52,7 @@ fs.emptyDirSync('./build');
|
||||
const themes = { Legacy: {}, V3: {} };
|
||||
|
||||
let themeFiles = fs.readdirSync('./themes/Legacy');
|
||||
for (dir of themeFiles) {
|
||||
for (let dir of themeFiles) {
|
||||
const themeData = JSON.parse(fs.readFileSync(`./themes/Legacy/${dir}/settings.json`).toString());
|
||||
themeData.path = dir;
|
||||
themes.Legacy[dir] = (themeData);
|
||||
@@ -68,7 +69,7 @@ fs.emptyDirSync('./build');
|
||||
}
|
||||
|
||||
themeFiles = fs.readdirSync('./themes/V3');
|
||||
for (dir of themeFiles) {
|
||||
for (let dir of themeFiles) {
|
||||
const themeData = JSON.parse(fs.readFileSync(`./themes/V3/${dir}/settings.json`).toString());
|
||||
themeData.path = dir;
|
||||
themes.V3[dir] = (themeData);
|
||||
@@ -104,14 +105,14 @@ fs.emptyDirSync('./build');
|
||||
const editorThemesBuildDir = './build/homebrew/cm-themes';
|
||||
await fs.copy('./node_modules/codemirror/theme', editorThemesBuildDir);
|
||||
await fs.copy('./themes/codeMirror/customThemes', editorThemesBuildDir);
|
||||
editorThemeFiles = fs.readdirSync(editorThemesBuildDir);
|
||||
const editorThemeFiles = fs.readdirSync(editorThemesBuildDir);
|
||||
|
||||
const editorThemeFile = './themes/codeMirror/editorThemes.json';
|
||||
if(fs.existsSync(editorThemeFile)) fs.rmSync(editorThemeFile);
|
||||
const stream = fs.createWriteStream(editorThemeFile, { flags: 'a' });
|
||||
stream.write('[\n"default"');
|
||||
|
||||
for (themeFile of editorThemeFiles) {
|
||||
for (let themeFile of editorThemeFiles) {
|
||||
stream.write(`,\n"${themeFile.slice(0, -4)}"`);
|
||||
}
|
||||
stream.write('\n]\n');
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
const DB = require('./server/db.js');
|
||||
const server = require('./server/app.js');
|
||||
const config = require('./server/config.js');
|
||||
import DB from './server/db.js';
|
||||
import server from './server/app.js';
|
||||
import config from './server/config.js';
|
||||
|
||||
DB.connect(config).then(()=>{
|
||||
// Ensure that we have successfully connected to the database
|
||||
// before launching server
|
||||
const PORT = process.env.PORT || config.get('web_port') || 8000;
|
||||
server.app.listen(PORT, ()=>{
|
||||
server.listen(PORT, ()=>{
|
||||
const reset = '\x1b[0m'; // Reset to default style
|
||||
const bright = '\x1b[1m'; // Bright (bold) style
|
||||
const cyan = '\x1b[36m'; // Cyan color
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
const HomebrewModel = require('./homebrew.model.js').model;
|
||||
const NotificationModel = require('./notifications.model.js').model;
|
||||
const router = require('express').Router();
|
||||
const Moment = require('moment');
|
||||
const templateFn = require('../client/template.js');
|
||||
const zlib = require('zlib');
|
||||
import {model as HomebrewModel } from './homebrew.model.js';
|
||||
import {model as NotificationModel } from './notifications.model.js';
|
||||
import express from 'express';
|
||||
import Moment from 'moment';
|
||||
import zlib from 'zlib';
|
||||
import templateFn from '../client/template.js';
|
||||
|
||||
const HomebrewAPI = require('./homebrew.api.js');
|
||||
const asyncHandler = require('express-async-handler');
|
||||
const { splitTextStyleAndMetadata } = require('../shared/helpers.js');
|
||||
import HomebrewAPI from './homebrew.api.js';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { splitTextStyleAndMetadata } from '../shared/helpers.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin';
|
||||
process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3';
|
||||
@@ -190,4 +192,4 @@ router.get('/admin', mw.adminOnly, (req, res)=>{
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
export default router;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
const supertest = require('supertest');
|
||||
import supertest from 'supertest';
|
||||
import HBApp from './app.js';
|
||||
import {model as NotificationModel } from './notifications.model.js';
|
||||
|
||||
const app = supertest.agent(require('app.js').app)
|
||||
.set('X-Forwarded-Proto', 'https');
|
||||
|
||||
const NotificationModel = require('./notifications.model.js').model;
|
||||
// Mimic https responses to avoid being redirected all the time
|
||||
const app = supertest.agent(HBApp).set('X-Forwarded-Proto', 'https');
|
||||
|
||||
describe('Tests for admin api', ()=>{
|
||||
afterEach(()=>{
|
||||
|
||||
@@ -1,25 +1,41 @@
|
||||
/*eslint max-lines: ["warn", {"max": 500, "skipBlankLines": true, "skipComments": true}]*/
|
||||
// Set working directory to project root
|
||||
import { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import packageJSON from './../package.json' with { type: "json" };
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
process.chdir(`${__dirname}/..`);
|
||||
const version = packageJSON.version;
|
||||
|
||||
import _ from 'lodash';
|
||||
import jwt from 'jwt-simple';
|
||||
import express from 'express';
|
||||
import yaml from 'js-yaml';
|
||||
import config from './config.js';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
const _ = require('lodash');
|
||||
const jwt = require('jwt-simple');
|
||||
const express = require('express');
|
||||
const yaml = require('js-yaml');
|
||||
const app = express();
|
||||
const config = require('./config.js');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
const { homebrewApi, getBrew, getUsersBrewThemes, getCSS } = require('./homebrew.api.js');
|
||||
const GoogleActions = require('./googleActions.js');
|
||||
const serveCompressedStaticAssets = require('./static-assets.mv.js');
|
||||
const sanitizeFilename = require('sanitize-filename');
|
||||
const asyncHandler = require('express-async-handler');
|
||||
const templateFn = require('./../client/template.js');
|
||||
import api from './homebrew.api.js';
|
||||
const { homebrewApi, getBrew, getUsersBrewThemes, getCSS } = api;
|
||||
import adminApi from './admin.api.js';
|
||||
import vaultApi from './vault.api.js';
|
||||
import GoogleActions from './googleActions.js';
|
||||
import serveCompressedStaticAssets from './static-assets.mv.js';
|
||||
import sanitizeFilename from 'sanitize-filename';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import templateFn from '../client/template.js';
|
||||
import {model as HomebrewModel } from './homebrew.model.js';
|
||||
|
||||
const { DEFAULT_BREW } = require('./brewDefaults.js');
|
||||
import { DEFAULT_BREW } from './brewDefaults.js';
|
||||
import { splitTextStyleAndMetadata } from '../shared/helpers.js';
|
||||
|
||||
const { splitTextStyleAndMetadata } = require('../shared/helpers.js');
|
||||
//==== Middleware Imports ====//
|
||||
import contentNegotiation from './middleware/content-negotiation.js';
|
||||
import bodyParser from 'body-parser';
|
||||
import cookieParser from 'cookie-parser';
|
||||
import forceSSL from './forcessl.mw.js';
|
||||
|
||||
|
||||
const sanitizeBrew = (brew, accessType)=>{
|
||||
@@ -34,10 +50,10 @@ const sanitizeBrew = (brew, accessType)=>{
|
||||
app.set('trust proxy', 1 /* number of proxies between user and server */)
|
||||
|
||||
app.use('/', serveCompressedStaticAssets(`build`));
|
||||
app.use(require('./middleware/content-negotiation.js'));
|
||||
app.use(require('body-parser').json({ limit: '25mb' }));
|
||||
app.use(require('cookie-parser')());
|
||||
app.use(require('./forcessl.mw.js'));
|
||||
app.use(contentNegotiation);
|
||||
app.use(bodyParser.json({ limit: '25mb' }));
|
||||
app.use(cookieParser());
|
||||
app.use(forceSSL);
|
||||
|
||||
//Account Middleware
|
||||
app.use((req, res, next)=>{
|
||||
@@ -57,15 +73,14 @@ app.use((req, res, next)=>{
|
||||
});
|
||||
|
||||
app.use(homebrewApi);
|
||||
app.use(require('./admin.api.js'));
|
||||
app.use(require('./vault.api.js'));
|
||||
app.use(adminApi);
|
||||
app.use(vaultApi);
|
||||
|
||||
const HomebrewModel = require('./homebrew.model.js').model;
|
||||
const welcomeText = require('fs').readFileSync('client/homebrew/pages/homePage/welcome_msg.md', 'utf8');
|
||||
const welcomeTextLegacy = require('fs').readFileSync('client/homebrew/pages/homePage/welcome_msg_legacy.md', 'utf8');
|
||||
const migrateText = require('fs').readFileSync('client/homebrew/pages/homePage/migrate.md', 'utf8');
|
||||
const changelogText = require('fs').readFileSync('changelog.md', 'utf8');
|
||||
const faqText = require('fs').readFileSync('faq.md', 'utf8');
|
||||
const welcomeText = fs.readFileSync('client/homebrew/pages/homePage/welcome_msg.md', 'utf8');
|
||||
const welcomeTextLegacy = fs.readFileSync('client/homebrew/pages/homePage/welcome_msg_legacy.md', 'utf8');
|
||||
const migrateText = fs.readFileSync('client/homebrew/pages/homePage/migrate.md', 'utf8');
|
||||
const changelogText = fs.readFileSync('changelog.md', 'utf8');
|
||||
const faqText = fs.readFileSync('faq.md', 'utf8');
|
||||
|
||||
String.prototype.replaceAll = function(s, r){return this.split(s).join(r);};
|
||||
|
||||
@@ -479,7 +494,7 @@ const renderPage = async (req, res)=>{
|
||||
deployment : config.get('heroku_app_name') ?? ''
|
||||
};
|
||||
const props = {
|
||||
version : require('./../package.json').version,
|
||||
version : version,
|
||||
url : req.customUrl || req.originalUrl,
|
||||
brew : req.brew,
|
||||
brews : req.brews,
|
||||
@@ -556,6 +571,4 @@ app.use((req, res)=>{
|
||||
});
|
||||
//^=====--------------------------------------=====^//
|
||||
|
||||
module.exports = {
|
||||
app : app
|
||||
};
|
||||
export default app;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const _ = require('lodash');
|
||||
import _ from 'lodash';
|
||||
|
||||
// Default properties for newly-created brews
|
||||
const DEFAULT_BREW = {
|
||||
@@ -32,7 +32,7 @@ const DEFAULT_BREW_LOAD = _.defaults(
|
||||
},
|
||||
DEFAULT_BREW);
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
DEFAULT_BREW,
|
||||
DEFAULT_BREW_LOAD
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
module.exports = require('nconf')
|
||||
.argv()
|
||||
.env({ lowerCase: true })
|
||||
.file('environment', { file: `config/${process.env.NODE_ENV}.json` })
|
||||
.file('defaults', { file: 'config/default.json' });
|
||||
import nconf from 'nconf';
|
||||
|
||||
export default nconf
|
||||
.argv()
|
||||
.env({ lowerCase: true })
|
||||
.file('environment', { file: `config/${process.env.NODE_ENV}.json` })
|
||||
.file('defaults', { file: 'config/default.json' });
|
||||
@@ -5,7 +5,7 @@
|
||||
// reused by both the main application and all tests which require database
|
||||
// connection.
|
||||
|
||||
const Mongoose = require('mongoose');
|
||||
import Mongoose from 'mongoose';
|
||||
|
||||
const getMongoDBURL = (config)=>{
|
||||
return config.get('mongodb_uri') ||
|
||||
@@ -31,7 +31,7 @@ const connect = async (config)=>{
|
||||
.catch((error)=>handleConnectionError(error));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
connect : connect,
|
||||
disconnect : disconnect
|
||||
export default {
|
||||
connect,
|
||||
disconnect
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module.exports = (req, res, next)=>{
|
||||
export default (req, res, next)=>{
|
||||
if(process.env.NODE_ENV === 'local' || process.env.NODE_ENV === 'docker') return next();
|
||||
if(req.header('x-forwarded-proto') !== 'https') {
|
||||
return res.redirect(302, `https://${req.get('Host')}${req.url}`);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/* eslint-disable max-lines */
|
||||
const googleDrive = require('@googleapis/drive');
|
||||
const { nanoid } = require('nanoid');
|
||||
const token = require('./token.js');
|
||||
const config = require('./config.js');
|
||||
import googleDrive from '@googleapis/drive';
|
||||
import { nanoid } from 'nanoid';
|
||||
import token from './token.js';
|
||||
import config from './config.js';
|
||||
|
||||
|
||||
let serviceAuth;
|
||||
if(!config.get('service_account')){
|
||||
@@ -59,7 +60,7 @@ const GoogleActions = {
|
||||
account.googleRefreshToken = tokens.refresh_token;
|
||||
}
|
||||
account.googleAccessToken = tokens.access_token;
|
||||
const JWTToken = token.generateAccessToken(account);
|
||||
const JWTToken = token(account);
|
||||
|
||||
//Save updated token to cookie
|
||||
//res.cookie('nc_session', JWTToken, { maxAge: 1000*60*60*24*365, path: '/', sameSite: 'lax' });
|
||||
@@ -72,7 +73,7 @@ const GoogleActions = {
|
||||
getGoogleFolder : async (auth)=>{
|
||||
const drive = googleDrive.drive({ version: 'v3', auth });
|
||||
|
||||
fileMetadata = {
|
||||
const fileMetadata = {
|
||||
'name' : 'Homebrewery',
|
||||
'mimeType' : 'application/vnd.google-apps.folder'
|
||||
};
|
||||
@@ -344,4 +345,4 @@ const GoogleActions = {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = GoogleActions;
|
||||
export default GoogleActions;
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
/* eslint-disable max-lines */
|
||||
const _ = require('lodash');
|
||||
const HomebrewModel = require('./homebrew.model.js').model;
|
||||
const router = require('express').Router();
|
||||
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 { nanoid } = require('nanoid');
|
||||
const { splitTextStyleAndMetadata } = require('../shared/helpers.js');
|
||||
import _ from 'lodash';
|
||||
import {model as HomebrewModel} from './homebrew.model.js';
|
||||
import express from 'express';
|
||||
import zlib from 'zlib';
|
||||
import GoogleActions from './googleActions.js';
|
||||
import Markdown from '../shared/naturalcrit/markdown.js';
|
||||
import yaml from 'js-yaml';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { splitTextStyleAndMetadata } from '../shared/helpers.js';
|
||||
import checkClientVersion from './middleware/check-client-version.js';
|
||||
|
||||
const { DEFAULT_BREW, DEFAULT_BREW_LOAD } = require('./brewDefaults.js');
|
||||
const router = express.Router();
|
||||
|
||||
const Themes = require('../themes/themes.json');
|
||||
import { DEFAULT_BREW, DEFAULT_BREW_LOAD } from './brewDefaults.js';
|
||||
import Themes from '../themes/themes.json' with { type: 'json' };
|
||||
|
||||
const isStaticTheme = (renderer, themeName)=>{
|
||||
return Themes[renderer]?.[themeName] !== undefined;
|
||||
@@ -473,7 +475,7 @@ const api = {
|
||||
}
|
||||
};
|
||||
|
||||
router.use('/api', require('./middleware/check-client-version.js'));
|
||||
router.use('/api', checkClientVersion);
|
||||
router.post('/api', asyncHandler(api.newBrew));
|
||||
router.put('/api/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew));
|
||||
router.put('/api/update/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew));
|
||||
@@ -481,4 +483,4 @@ router.delete('/api/:id', asyncHandler(api.deleteBrew));
|
||||
router.get('/api/remove/:id', asyncHandler(api.deleteBrew));
|
||||
router.get('/api/theme/:renderer/:id', asyncHandler(api.getThemeBundle));
|
||||
|
||||
module.exports = api;
|
||||
export default api;
|
||||
@@ -36,8 +36,9 @@ describe('Tests for api', ()=>{
|
||||
}
|
||||
});
|
||||
|
||||
google = require('./googleActions.js');
|
||||
model = require('./homebrew.model.js').model;
|
||||
google = require('./googleActions.js').default;
|
||||
model = require('./homebrew.model.js').model;
|
||||
api = require('./homebrew.api').default;
|
||||
|
||||
jest.mock('./googleActions.js');
|
||||
google.authCheck = jest.fn(()=>'client');
|
||||
@@ -54,8 +55,6 @@ describe('Tests for api', ()=>{
|
||||
setHeader : jest.fn(()=>{})
|
||||
};
|
||||
|
||||
api = require('./homebrew.api');
|
||||
|
||||
hbBrew = {
|
||||
text : `brew text`,
|
||||
style : 'hello yes i am css',
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { nanoid } = require('nanoid');
|
||||
const _ = require('lodash');
|
||||
const zlib = require('zlib');
|
||||
import mongoose from 'mongoose';
|
||||
import { nanoid } from 'nanoid';
|
||||
import _ from 'lodash';
|
||||
import zlib from 'zlib';
|
||||
|
||||
|
||||
const HomebrewSchema = mongoose.Schema({
|
||||
shareId : { type: String, default: ()=>{return nanoid(12);}, index: { unique: true } },
|
||||
@@ -44,7 +45,7 @@ HomebrewSchema.statics.get = async function(query, fields=null){
|
||||
const brew = await Homebrew.findOne(query, fields).orFail()
|
||||
.catch((error)=>{throw 'Can not find brew';});
|
||||
if(!_.isNil(brew.textBin)) { // Uncompress zipped text field
|
||||
unzipped = zlib.inflateRawSync(brew.textBin);
|
||||
const unzipped = zlib.inflateRawSync(brew.textBin);
|
||||
brew.text = unzipped.toString();
|
||||
}
|
||||
return brew;
|
||||
@@ -62,7 +63,7 @@ HomebrewSchema.statics.getByUser = async function(username, allowAccess=false, f
|
||||
|
||||
const Homebrew = mongoose.model('Homebrew', HomebrewSchema);
|
||||
|
||||
module.exports = {
|
||||
schema : HomebrewSchema,
|
||||
model : Homebrew,
|
||||
export {
|
||||
HomebrewSchema as schema,
|
||||
Homebrew as model
|
||||
};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
module.exports = (req, res, next)=>{
|
||||
import packageJSON from '../../package.json' with { type: "json" };
|
||||
const version = packageJSON.version;
|
||||
|
||||
export default (req, res, next)=>{
|
||||
const userVersion = req.get('Homebrewery-Version');
|
||||
const version = require('../../package.json').version;
|
||||
|
||||
if(userVersion != version) {
|
||||
return res.status(412).send({
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const config = require('../config.js');
|
||||
import config from '../config.js';
|
||||
const nodeEnv = config.get('node_env');
|
||||
const isLocalEnvironment = config.get('local_environments').includes(nodeEnv);
|
||||
|
||||
module.exports = (req, res, next)=>{
|
||||
export default (req, res, next)=>{
|
||||
const isImageRequest = req.get('Accept')?.split(',')
|
||||
?.filter((h)=>!h.includes('q='))
|
||||
?.every((h)=>/image\/.*/.test(h));
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
const contentNegotiationMiddleware = require('./content-negotiation.js');
|
||||
|
||||
describe('content-negotiation-middleware', ()=>{
|
||||
let request;
|
||||
let response;
|
||||
let next;
|
||||
|
||||
beforeEach(()=>{
|
||||
request = {
|
||||
get : function(key) {
|
||||
return this[key];
|
||||
}
|
||||
};
|
||||
response = {
|
||||
status : jest.fn(()=>response),
|
||||
send : jest.fn(()=>{})
|
||||
};
|
||||
next = jest.fn();
|
||||
});
|
||||
|
||||
it('should return 406 on image request', ()=>{
|
||||
contentNegotiationMiddleware({
|
||||
Accept : 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
|
||||
...request
|
||||
}, response);
|
||||
|
||||
expect(response.status).toHaveBeenLastCalledWith(406);
|
||||
expect(response.send).toHaveBeenCalledWith({
|
||||
message : 'Request for image at this URL is not supported'
|
||||
});
|
||||
});
|
||||
|
||||
it('should call next on non-image request', ()=>{
|
||||
contentNegotiationMiddleware({
|
||||
Accept : 'text,image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
|
||||
...request
|
||||
}, response, next);
|
||||
|
||||
expect(next).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
const mongoose = require('mongoose');
|
||||
const _ = require('lodash');
|
||||
import mongoose from 'mongoose';
|
||||
import _ from 'lodash';
|
||||
|
||||
const NotificationSchema = new mongoose.Schema({
|
||||
dismissKey : { type: String, unique: true, required: true },
|
||||
@@ -56,7 +56,7 @@ NotificationSchema.statics.getAll = async function() {
|
||||
|
||||
const Notification = mongoose.model('Notification', NotificationSchema);
|
||||
|
||||
module.exports = {
|
||||
schema : NotificationSchema,
|
||||
model : Notification,
|
||||
export {
|
||||
NotificationSchema as schema,
|
||||
Notification as model
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const expressStaticGzip = require('express-static-gzip');
|
||||
import expressStaticGzip from 'express-static-gzip';
|
||||
|
||||
// Serve brotli-compressed static files if available
|
||||
const customCacheControlHandler=(response, path)=>{
|
||||
@@ -28,4 +28,4 @@ const init=(pathToAssets)=>{
|
||||
} });
|
||||
};
|
||||
|
||||
module.exports = init;
|
||||
export default init;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
const jwt = require('jwt-simple');
|
||||
|
||||
// Load configuration values
|
||||
const config = require('./config.js');
|
||||
import jwt from 'jwt-simple';
|
||||
import config from './config.js';
|
||||
|
||||
// Generate an Access Token for the given User ID
|
||||
const generateAccessToken = (account)=>{
|
||||
@@ -24,6 +22,4 @@ const generateAccessToken = (account)=>{
|
||||
return token;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
generateAccessToken : generateAccessToken
|
||||
};
|
||||
export default generateAccessToken;
|
||||
@@ -1,6 +1,6 @@
|
||||
const express = require('express');
|
||||
const asyncHandler = require('express-async-handler');
|
||||
const HomebrewModel = require('./homebrew.model.js').model;
|
||||
import express from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import {model as HomebrewModel } from './homebrew.model.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
@@ -106,4 +106,4 @@ const findTotal = async (req, res)=>{
|
||||
router.get('/api/vault/total', asyncHandler(findTotal));
|
||||
router.get('/api/vault', asyncHandler(findBrews));
|
||||
|
||||
module.exports = router;
|
||||
export default router;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const _ = require('lodash');
|
||||
const yaml = require('js-yaml');
|
||||
const request = require('../client/homebrew/utils/request-middleware.js');
|
||||
import _ from 'lodash';
|
||||
import yaml from 'js-yaml';
|
||||
import request from '../client/homebrew/utils/request-middleware.js';
|
||||
|
||||
const splitTextStyleAndMetadata = (brew)=>{
|
||||
brew.text = brew.text.replaceAll('\r\n', '\n');
|
||||
@@ -51,7 +51,7 @@ const fetchThemeBundle = async (obj, renderer, theme)=>{
|
||||
}));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
splitTextStyleAndMetadata,
|
||||
printCurrentBrew,
|
||||
fetchThemeBundle,
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/* eslint-disable max-lines */
|
||||
const _ = require('lodash');
|
||||
const Marked = require('marked');
|
||||
const MarkedExtendedTables = require('marked-extended-tables');
|
||||
const { markedSmartypantsLite: MarkedSmartypantsLite } = require('marked-smartypants-lite');
|
||||
const { gfmHeadingId: MarkedGFMHeadingId, resetHeadings: MarkedGFMResetHeadingIDs } = require('marked-gfm-heading-id');
|
||||
const { markedEmoji: MarkedEmojis } = require('marked-emoji');
|
||||
import _ from 'lodash';
|
||||
import { Parser as MathParser } from 'expr-eval';
|
||||
import { marked as Marked } from 'marked';
|
||||
import MarkedExtendedTables from 'marked-extended-tables';
|
||||
import { markedSmartypantsLite as MarkedSmartypantsLite } from 'marked-smartypants-lite';
|
||||
import { gfmHeadingId as MarkedGFMHeadingId, resetHeadings as MarkedGFMResetHeadingIDs } from 'marked-gfm-heading-id';
|
||||
import { markedEmoji as MarkedEmojis } from 'marked-emoji';
|
||||
|
||||
//Icon fonts included so they can appear in emoji autosuggest dropdown
|
||||
const diceFont = require('../../themes/fonts/iconFonts/diceFont.js');
|
||||
const elderberryInn = require('../../themes/fonts/iconFonts/elderberryInn.js');
|
||||
const fontAwesome = require('../../themes/fonts/iconFonts/fontAwesome.js');
|
||||
const gameIcons = require('../../themes/fonts/iconFonts/gameIcons.js');
|
||||
import diceFont from '../../themes/fonts/iconFonts/diceFont.js';
|
||||
import elderberryInn from '../../themes/fonts/iconFonts/elderberryInn.js';
|
||||
import gameIcons from '../../themes/fonts/iconFonts/gameIcons.js';
|
||||
import fontAwesome from '../../themes/fonts/iconFonts/fontAwesome.js';
|
||||
|
||||
const MathParser = require('expr-eval').Parser;
|
||||
const renderer = new Marked.Renderer();
|
||||
const renderer = new Marked.Renderer();
|
||||
const tokenizer = new Marked.Tokenizer();
|
||||
|
||||
//Limit math features to simple items
|
||||
@@ -854,7 +854,7 @@ const globalVarsList = {};
|
||||
let varsQueue = [];
|
||||
let globalPageNumber = 0;
|
||||
|
||||
module.exports = {
|
||||
const Markdown = {
|
||||
marked : Marked,
|
||||
render : (rawBrewText, pageNumber=0)=>{
|
||||
globalVarsList[pageNumber] = {}; //Reset global links for current page, to ensure values are parsed in order
|
||||
@@ -865,6 +865,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
rawBrewText = rawBrewText.replace(/^\\column$/gm, `\n<div class='columnSplit'></div>\n`);
|
||||
|
||||
const opts = Marked.defaults;
|
||||
|
||||
rawBrewText = opts.hooks.preprocess(rawBrewText);
|
||||
@@ -935,3 +936,6 @@ module.exports = {
|
||||
return errors;
|
||||
},
|
||||
};
|
||||
|
||||
export default Markdown;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable max-lines */
|
||||
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
import Markdown from 'naturalcrit/markdown.js';
|
||||
|
||||
test('Processes the markdown within an HTML block if its just a class wrapper', function() {
|
||||
const source = '<div>*Bold text*</div>';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable max-lines */
|
||||
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
import Markdown from 'naturalcrit/markdown.js';
|
||||
|
||||
describe('Inline Definition Lists', ()=>{
|
||||
test('No Term 1 Definition', function() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
import Markdown from 'naturalcrit/markdown.js';
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
// Marked.js adds line returns after closing tags on some default tokens.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable max-lines */
|
||||
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
import Markdown from 'naturalcrit/markdown.js';
|
||||
|
||||
describe('Hard Breaks', ()=>{
|
||||
test('Single Break', function() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable max-lines */
|
||||
|
||||
const dedent = require('dedent-tabs').default;
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
import Markdown from 'naturalcrit/markdown.js';
|
||||
|
||||
// Marked.js adds line returns after closing tags on some default tokens.
|
||||
// This removes those line returns for comparison sake.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable max-lines */
|
||||
|
||||
const dedent = require('dedent-tabs').default;
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
import Markdown from 'naturalcrit/markdown.js';
|
||||
|
||||
// Marked.js adds line returns after closing tags on some default tokens.
|
||||
// This removes those line returns for comparison sake.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const supertest = require('supertest');
|
||||
import supertest from 'supertest';
|
||||
import HBApp from 'app.js';
|
||||
|
||||
// Mimic https responses to avoid being redirected all the time
|
||||
const app = supertest.agent(require('app.js').app)
|
||||
.set('X-Forwarded-Proto', 'https');
|
||||
const app = supertest.agent(HBApp).set('X-Forwarded-Proto', 'https');
|
||||
|
||||
describe('Tests for static pages', ()=>{
|
||||
it('Home page works', ()=>{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const Markdown = require('../../../../shared/naturalcrit/markdown.js');
|
||||
import Markdown from '../../../../shared/naturalcrit/markdown.js';
|
||||
|
||||
module.exports = {
|
||||
createFooterFunc : function(headerSize=1){
|
||||
|
||||
@@ -93,4 +93,4 @@ const diceFont = {
|
||||
'df_solid_small_dot_d6_6' : 'df solid-small-dot-d6-6'
|
||||
};
|
||||
|
||||
module.exports = diceFont;
|
||||
export default diceFont;
|
||||
@@ -206,4 +206,4 @@ const elderberryInn = {
|
||||
'ei_wish' : 'ei wish'
|
||||
};
|
||||
|
||||
module.exports = elderberryInn;
|
||||
export default elderberryInn;
|
||||
@@ -2051,4 +2051,4 @@ const fontAwesome = {
|
||||
'fab_zhihu' : 'fab fa-zhihu'
|
||||
};
|
||||
|
||||
module.exports = fontAwesome;
|
||||
export default fontAwesome;
|
||||
@@ -506,4 +506,4 @@ const gameIcons = {
|
||||
'gi_acid' : 'gi acid'
|
||||
};
|
||||
|
||||
module.exports = gameIcons;
|
||||
export default gameIcons;
|
||||
Reference in New Issue
Block a user