Compare commits

67 Commits

Author SHA1 Message Date
51f418353d Merge branch 'monorepo-ts' of ssh://git.radner.ru:3036/anatolykopyl/warframe-center into monorepo-ts
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-07 02:29:41 +03:00
57ebf51a0a ci workflow 2022-07-07 02:29:37 +03:00
9bfd3bdc01 ci workflow
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is failing
2022-07-07 02:23:41 +03:00
862cbd3af1 Migrate to yarn berry and fix all workspace errors 2022-07-07 01:12:21 +03:00
78fd1b5adf Migrate to yarn 2022-07-07 00:51:28 +03:00
1af1048670 Fix crash
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-06 19:43:44 +03:00
148a3693b9 Merge branch 'monorepo' of ssh://git.radner.ru:3036/anatolykopyl/warframe-center into monorepo
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-05 14:50:16 +03:00
efb1cba216 Remove metrika id from env 2022-07-05 14:50:12 +03:00
755cb06276 Remove metrika id from env
Some checks failed
continuous-integration/drone/push Build was killed
2022-07-05 14:49:12 +03:00
a40390a30e Add ym id to drone secrets
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-05 14:10:50 +03:00
9d5d49c9f2 Fix undefined scan results
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-05 13:31:08 +03:00
fe1cf2f171 Merge branch 'monorepo' of ssh://git.radner.ru:3036/anatolykopyl/warframe-center into monorepo
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build was killed
2022-07-05 12:03:29 +03:00
d3cb737972 Fix ya metrika hopefully 2022-07-05 12:03:08 +03:00
7a0480fa69 Fix ya metrika hopefully
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-05 11:58:01 +03:00
a77fefc251 Switch ya metrika packages
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-05 09:50:16 +03:00
ad10f35e19 Disable ya metrika
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-05 02:34:43 +03:00
0df5022493 Yandex metrica work
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-05 02:19:27 +03:00
ccf1aaba9b Fix empty orders in getSortedOrders
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-04 12:38:56 +03:00
5433c7a1d2 Fixed linting error
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-04 02:40:48 +03:00
0863a73625 Added a help modal
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-04 02:23:09 +03:00
ba28925d3c Modified drone.yml
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-03 17:41:56 +03:00
b96feef044 Modified drone.yml
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-03 17:34:52 +03:00
9387994d6d Fixed no db on build error
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-03 17:27:35 +03:00
e13d6a7f4a Translate table headers
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-03 17:14:56 +03:00
b956bb525d Drone build update
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-03 16:59:19 +03:00
3c888dc7f1 Added i18n
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-03 16:31:31 +03:00
f7b78f6d0f Return empty orders on error
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-02 18:58:00 +03:00
04a3ea5a23 Handle api errors
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-02 17:50:25 +03:00
0b808328f4 Path to pm2
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-30 03:30:38 +03:00
55ecb3b12b Edited pipeline
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-30 03:22:45 +03:00
d366262636 Edited pipeline
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-30 03:21:54 +03:00
714ef9c87f Edited pipeline
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-30 03:20:43 +03:00
41116e6ef1 POSIX exec
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-30 03:11:14 +03:00
b56f1b0b62 Full path
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-30 03:06:34 +03:00
5aab4a955b Source interactive shell files
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-30 03:05:20 +03:00
3f60cba322 Edited pipeline
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-30 02:58:00 +03:00
f8e36fc519 Join lines 2022-03-30 02:54:40 +03:00
9937a407de Edited pipeline 2022-03-30 02:49:14 +03:00
92395f9db1 Replace ssh key with pass 2022-03-30 02:47:37 +03:00
f649cc2c14 Edited pipeline 2022-03-30 02:40:26 +03:00
3f3e851590 Source profioe
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-22 17:05:05 +03:00
dc54effc83 ssh client
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-22 17:02:23 +03:00
6951ce5db7 Remove dependency
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-22 17:00:45 +03:00
10516d84e6 Big step 2022-03-22 16:59:42 +03:00
307dfc2433 alpine-ssh 2022-03-22 16:53:53 +03:00
42c66ac8da All docker 2022-03-22 16:53:08 +03:00
7d70bec13b Костыль путь до npm
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-22 16:49:37 +03:00
fcff4f50c1 Twst pwd
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-22 16:42:29 +03:00
72a395e813 Specified port
Some checks failed
continuous-integration/drone/push Build encountered an error
continuous-integration/drone Build is failing
2022-03-22 16:21:58 +03:00
3877a37e7e Removed useless scp
Some checks failed
continuous-integration/drone/push Build encountered an error
2022-03-22 16:14:57 +03:00
cbffc25a78 Updated drone config
Some checks failed
continuous-integration/drone/push Build encountered an error
2022-03-22 16:12:58 +03:00
131a0b23f5 Disclamer
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-19 20:01:58 +03:00
4f54d08666 Got rid of scss files, fixet time format
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-19 15:41:32 +03:00
76bf04f8de Fix redirect and restart frontend on push
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-19 03:38:25 +03:00
12a482324c pm2 file and redirect fix
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-19 03:11:52 +03:00
e733ca9cc3 Renamed pm2 process
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-19 02:59:51 +03:00
66212c9a7d Sequential pipeline
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-19 01:49:17 +03:00
34c1e577f4 Absolute path
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-19 01:45:44 +03:00
3d3d145072 Install deps in pipeline
Some checks failed
continuous-integration/drone/push Build encountered an error
continuous-integration/drone Build is failing
2022-03-19 01:41:44 +03:00
7e31449bd2 added mongo url
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-18 23:23:33 +03:00
9d663510bc Install in workspace
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-18 22:46:35 +03:00
2c4cd8ca5d Docker deploy yml
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-18 22:24:25 +03:00
2198e134d6 Explicit logo size
Some checks failed
continuous-integration/drone/push Build is failing
2022-03-14 23:57:27 +03:00
2df13c117a ci preparations
Some checks failed
continuous-integration/drone Build is failing
2022-03-14 22:46:08 +03:00
789fb6f38d Fixed mongo hanging script 2022-03-14 03:38:29 +03:00
946a9afeac Expanded mongo model 2022-03-14 01:41:52 +03:00
beb5ff052f Material UI 2022-03-14 00:29:29 +03:00
82 changed files with 8308 additions and 22695 deletions

View File

@@ -1,9 +1,65 @@
kind: pipeline
type: ssh
name: default
name: install dependencies
server:
host: 192.168.1.54
user: pi
password:
from_secret: password
host: warframe.center
user: webmaster
ssh_key:
from_secret: ssh_private_key
clone:
disable: true
steps:
- name: fetch remote
commands:
- cd /home/webmaster/warframe-center && git fetch --all && git reset --hard origin/monorepo-ts
- name: install dependencies
commands:
- export PATH=$PATH:/home/webmaster/.nvm/versions/node/v16.14.2/bin
- cd /home/webmaster/warframe-center && yarn install --immutable
trigger:
branch:
- monorepo-ts
---
kind: pipeline
type: docker
name: build
clone:
disable: true
steps:
- name: bulid frontend
image: node:16
environment:
SSH_PRIVATE_KEY:
from_secret: SSH_PRIVATE_KEY
MONGODB_URI:
from_secret: MONGODB_URI
commands:
- git clone -b monorepo-ts https://git.radner.ru/anatolykopyl/warframe-center.git
- cd warframe-center
- yarn install --immutable
- yarn workspace frontend run build
- mkdir ~/.ssh
- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
- chmod 400 ~/.ssh/id_rsa
- scp -o StrictHostKeyChecking=no -r ./frontend/.next webmaster@warframe.center:~/warframe-center/frontend
- |
ssh -o StrictHostKeyChecking=no webmaster@warframe.center '
[ -s ~/.nvm/nvm.sh ] && source ~/.nvm/nvm.sh &&
nvm use default &&
pm2 restart warframe-center-app-3000
'
depends_on:
- install dependencies
trigger:
branch:
- monorepo-ts

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
node_modules
.yarn
.DS_Store
.vscode
.env

3
.yarnrc.yml Normal file
View File

@@ -0,0 +1,3 @@
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-3.2.1.cjs

View File

@@ -1 +0,0 @@
MONGODB_URI=

View File

@@ -1,3 +0,0 @@
{
"extends": ["standard", "standard-jsx", "standard-react", "next/core-web-vitals"]
}

View File

@@ -1,76 +0,0 @@
## Example app using MongoDB
[MongoDB](https://www.mongodb.com/) is a general purpose, document-based, distributed database built for modern application developers and for the cloud era. This example will show you how to connect to and use MongoDB as your backend for your Next.js app.
If you want to learn more about MongoDB, visit the following pages:
- [MongoDB Atlas](https://mongodb.com/atlas)
- [MongoDB Documentation](https://docs.mongodb.com/)
## Deploy your own
Once you have access to the environment variables you'll need, deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-mongodb&project-name=with-mongodb&repository-name=with-mongodb&env=MONGODB_URI&envDescription=Required%20to%20connect%20the%20app%20with%20MongoDB)
## How to use
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
```bash
npx create-next-app --example with-mongodb with-mongodb-app
# or
yarn create next-app --example with-mongodb with-mongodb-app
```
## Configuration
### Set up a MongoDB database
Set up a MongoDB database either locally or with [MongoDB Atlas for free](https://mongodb.com/atlas).
### Set up environment variables
Copy the `env.local.example` file in this directory to `.env.local` (which will be ignored by Git):
```bash
cp .env.local.example .env.local
```
Set each variable on `.env.local`:
- `MONGODB_URI` - Your MongoDB connection string. If you are using [MongoDB Atlas](https://mongodb.com/atlas) you can find this by clicking the "Connect" button for your cluster.
### Run Next.js in development mode
```bash
npm install
npm run dev
# or
yarn install
yarn dev
```
Your app should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions).
You will either see a message stating "You are connected to MongoDB" or "You are NOT connected to MongoDB". Ensure that you have provided the correct `MONGODB_URI` environment variable.
When you are successfully connected, you can refer to the [MongoDB Node.js Driver docs](https://mongodb.github.io/node-mongodb-native/3.4/tutorials/collections/) for further instructions on how to query your database.
## Deploy on Vercel
You can deploy this app to the cloud with [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
#### Deploy Your Local Project
To deploy your local project to Vercel, push it to GitHub/GitLab/Bitbucket and [import to Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example).
**Important**: When you import your project on Vercel, make sure to click on **Environment Variables** and set them to match your `.env.local` file.
#### Deploy from Our Template
Alternatively, you can deploy using our template by clicking on the Deploy button below.
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-mongodb&project-name=with-mongodb&repository-name=with-mongodb&env=MONGODB_URI,MONGODB_DB&envDescription=Required%20to%20connect%20the%20app%20with%20MongoDB)

View File

@@ -1,16 +0,0 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
redirects: [
{
source: '/',
destination: '/home',
permanent: true
}
]
// webpack: (config, { webpack }) => {
// return config
// },
}
module.exports = nextConfig

5363
app/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +0,0 @@
import 'reset-css'
import '../styles/global.scss'
import Layout from '../components/layout'
function MyApp ({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
export default MyApp

View File

@@ -1,24 +0,0 @@
import { Component } from 'react'
import Image from 'next/image'
import styles from './Hero.module.scss'
import logo from './assets/warframe_logo.png'
export default class Hero extends Component {
render () {
return (
<div className={styles.hero}>
<div className={styles.logo}>
<Image
src={logo}
alt='logo'
layout='responsive'
/>
</div>
<div className={styles.text}>
<h1>Market Gaps</h1>
<p>Find a profitable difference between the price of the set and the price of the sum of it's parts.</p>
</div>
</div>
)
}
}

View File

@@ -1,17 +0,0 @@
.hero {
width: 100%;
padding: 128px 0;
position: relative;
background: white;
text-align: center;
overflow: hidden;
.text, .logo {
width: 400px;
margin: auto;
}
.text {
}
}

View File

@@ -1,18 +0,0 @@
import { Component } from 'react'
export default class ItemRow extends Component {
constructor ({ scanResult }) {
super()
this.scanResult = scanResult
}
render () {
return (
<tr>
<td>{this.scanResult.name}</td>
<td>{this.scanResult.partsPrice}</td>
<td>{this.scanResult.setPrice}</td>
</tr>
)
}
}

View File

@@ -1,25 +0,0 @@
import React from 'react'
import ItemRow from './ItemRow'
export default class Table extends React.Component {
constructor ({ scanResults }) {
super()
this.scanResults = scanResults
}
render () {
return (
<table>
<thead />
<tbody>
{this.scanResults.map((scanResult) =>
<ItemRow
key={scanResult._id}
scanResult={scanResult}
/>
)}
</tbody>
</table>
)
}
}

View File

@@ -1,41 +0,0 @@
import { Component } from 'react'
import dbConnect from '../../lib/dbConnect'
import { models } from 'shared-stuff'
import Hero from './Hero'
import Table from './Table'
export default class Home extends Component {
constructor ({ scanResults }) {
super()
this.scanResults = scanResults
}
render () {
return (
<>
<Hero />
<Table
scanResults={this.scanResults}
/>
</>
)
}
}
export async function getServerSideProps () {
try {
await dbConnect()
const scanResults = await models.ScanResult.find({})
return {
props: {
scanResults: JSON.parse(JSON.stringify(scanResults))
}
}
} catch (e) {
console.error(e)
return {
props: {}
}
}
}

View File

@@ -1 +0,0 @@
$clr-text: #1f1f1f;

View File

@@ -1,22 +0,0 @@
$text-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue,
sans-serif;
$font-h0: normal normal bold 56px/64px $text-font;
$font-h1: normal normal bold 48px/56px $text-font;
$font-h2: normal normal bold 40px/48px $text-font;
$font-h3: normal normal bold 36px/44px $text-font;
$font-h4: normal normal bold 32px/40px $text-font;
$font-h5: normal normal bold 28px/36px $text-font;
$font-h6: normal normal bold 24px/32px $text-font;
$font-h7: normal normal bold 20px/26px $text-font;
$font-h8: normal normal bold 18px/24px $text-font;
$font-h9: normal normal bold 16px/20px $text-font;
$font-r8: normal normal normal 24px/30px $text-font;
$font-r7: normal normal normal 22px/28px $text-font;
$font-r6: normal normal normal 20px/26px $text-font;
$font-r5: normal normal normal 18px/24px $text-font;
$font-r4: normal normal normal 16px/22px $text-font;
$font-r3: normal normal normal 14px/18px $text-font;
$font-r2: normal normal normal 12px/16px $text-font;

View File

@@ -1,2 +0,0 @@
@import './fonts';
@import './colors';

View File

@@ -0,0 +1 @@
MONGODB_URI=

15
frontend/.eslintrc.json Normal file
View File

@@ -0,0 +1,15 @@
{
"extends": ["standard", "standard-jsx", "standard-react", "next/core-web-vitals"],
"rules": {
"import/order": [
"error",
{
"newlines-between": "always",
"alphabetize": {
"order": "asc",
"caseInsensitive": true
}
}
]
}
}

View File

@@ -0,0 +1,33 @@
import { Box, Typography, Link } from '@mui/material'
import { Component } from 'react'
export default class Footer extends Component {
render () {
return (
<Box
sx={{
p: 12
}}
>
All data is collected from the&nbsp;
<Link
href='https://warframe.market/api_docs'
target='_blank'
rel='noreferrer'
>
Warframe Market API
</Link>
<Typography variant='h6'>DISCLAIMER</Typography>
<Box
sx={{
fontSize: 12,
lineHeight: 'normal'
}}
>
Digital Extremes Ltd, Warframe and the logo Warframe are registered trademarks. All rights are reserved worldwide. This site has no official link with Digital Extremes Ltd or Warframe. All artwork, screenshots, characters or other recognizable features of the intellectual property relating to these trademarks are likewise the intellectual property of Digital Extremes Ltd.
</Box>
</Box>
)
}
}

View File

@@ -0,0 +1,37 @@
import Router from 'next/router'
import React, { useCallback, useEffect } from 'react'
import ym, { YMInitializer } from 'react-yandex-metrika'
const WithYandexMetrika = (props) => {
const { children } = props
const enabled = process.env.NODE_ENV !== 'development'
const hit = useCallback((url) => {
if (enabled) {
ym('hit', url)
} else {
console.log('%c[YandexMetrika](HIT)', 'color: orange', url)
}
}, [enabled])
useEffect(() => {
hit(window.location.pathname + window.location.search)
Router.events.on('routeChangeComplete', hit)
}, [hit])
return (
<>
{enabled && (
<YMInitializer
accounts={[87671663]}
options={{ webvisor: true, defer: true }}
version='2'
/>
)}
{children}
</>
)
}
export default WithYandexMetrika

View File

@@ -1,5 +1,7 @@
import Head from 'next/head'
import Footer from './Footer'
export default function Layout ({ children }) {
return (
<>
@@ -8,6 +10,7 @@ export default function Layout ({ children }) {
<link rel='icon' href='/favicon.ico' />
</Head>
<main>{children}</main>
<Footer />
</>
)
}

View File

@@ -0,0 +1,7 @@
module.exports = {
apps: [{
name: 'warframe-center-app-3000',
script: 'npm run start',
watch: false
}]
}

View File

@@ -0,0 +1,6 @@
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'ru']
}
}

31
frontend/next.config.js Normal file
View File

@@ -0,0 +1,31 @@
const withPlugins = require('next-compose-plugins')
const { i18n } = require('./next-i18next.config')
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
i18n
// webpack: (config, { webpack }) => {
// return config
// },
}
const redirects = {
async redirects () {
return [
{
source: '/',
destination: '/home',
permanent: true
}
]
}
}
module.exports = withPlugins(
[
[redirects]
],
nextConfig
)

View File

@@ -1,4 +1,6 @@
{
"name": "frontend",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
@@ -6,12 +8,24 @@
"start": "next start"
},
"dependencies": {
"@emotion/react": "^11.8.2",
"@emotion/styled": "^11.8.1",
"@mui/icons-material": "^5.5.0",
"@mui/material": "^5.5.0",
"@mui/x-data-grid": "^5.6.1",
"moment": "^2.29.4",
"mongoose": "^6.4.3",
"next": "latest",
"next-compose-plugins": "^2.2.1",
"next-i18next": "^11.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-moment": "^1.1.1",
"react-yandex-metrika": "^2.6.0",
"reset-css": "^5.0.1",
"sass": "^1.49.9",
"shared-stuff": "file:../shared-stuff"
"shared-stuff": "1.0.0",
"sharp": "^0.30.3"
},
"devDependencies": {
"babel-eslint": "^10.1.0",

29
frontend/pages/_app.js Normal file
View File

@@ -0,0 +1,29 @@
import { CssBaseline } from '@mui/material'
import { createTheme, ThemeProvider } from '@mui/material/styles'
import { appWithTranslation } from 'next-i18next'
import 'reset-css'
import '../styles/global.scss'
import Layout from '../components/layout'
import WithYandexMetrika from '../components/WithYandexMetrika'
function App ({ Component, pageProps }) {
const theme = createTheme({
palette: {
mode: 'light'
}
})
return (
<WithYandexMetrika>
<ThemeProvider theme={theme}>
<CssBaseline />
<Layout>
<Component {...pageProps} />
</Layout>
</ThemeProvider>
</WithYandexMetrika>
)
}
export default appWithTranslation(App)

View File

@@ -0,0 +1,32 @@
import { Dialog, DialogTitle, Box, Typography } from '@mui/material'
import { useTranslation } from 'next-i18next'
export default function HelpModal ({ open, onClose }) {
const { t } = useTranslation('home')
return (
<Dialog
open={open}
onClose={onClose}
>
<DialogTitle>
{t('help_header')}
</DialogTitle>
<Box
sx={{
p: 3
}}
>
<Typography gutterBottom>
{t('help_body_1')}
</Typography>
<Typography gutterBottom>
{t('help_body_2')}
</Typography>
<Typography gutterBottom>
{t('help_body_3')}
</Typography>
</Box>
</Dialog>
)
}

View File

@@ -0,0 +1,73 @@
import { Box, Chip } from '@mui/material'
import { useTranslation } from 'next-i18next'
import Image from 'next/image'
import { useState } from 'react'
import logo from './assets/warframe_logo.png'
import HelpModal from './HelpModal'
const Hero = () => {
const { t } = useTranslation('home')
const [modalOpen, setModalOpen] = useState(false)
const openModal = () => {
setModalOpen(true)
}
const closeModal = () => {
setModalOpen(false)
}
return (
<>
<Box
sx={{
py: 12,
textAlign: 'center'
}}
>
<Chip
label={t('help_header')}
variant='outlined'
onClick={openModal}
sx={{
position: 'absolute',
top: '10px',
right: '10px'
}}
/>
<Box
sx={{
width: 400,
m: 'auto'
}}
>
<Image
src={logo}
alt='logo'
layout='responsive'
width={500}
height={300}
/>
</Box>
<Box
sx={{
width: 400,
m: 'auto'
}}
>
<h1>Market Gaps</h1>
<p>{t('description')}</p>
</Box>
</Box>
<HelpModal
open={modalOpen}
onClose={closeModal}
/>
</>
)
}
export default Hero

View File

@@ -0,0 +1,98 @@
import { Link, Typography, Box } from '@mui/material'
import { DataGrid } from '@mui/x-data-grid'
import { Component } from 'react'
import { withTranslation } from 'react-i18next'
import Moment from 'react-moment'
class Table extends Component {
constructor ({ scanResults, t }) {
super()
this.scanResults = scanResults
? scanResults.map(row => ({
...row,
id: row._id
}))
: []
this.columns = [
{
field: 'name',
headerName: t('name'),
flex: 2,
renderCell: (cellValues) => {
return (
<Box
component='span'
sx={{
display: 'block'
}}
>
<Link
target='_blank'
href={cellValues.row.url}
rel='noreferrer'
>
{cellValues.row.fullName}
</Link>
<Typography variant='caption' display='block'>
<Moment
format='DD.MM HH:mm'
>
{cellValues.row.updatedAt}
</Moment>
</Typography>
</Box>
)
}
},
{
field: 'partsPrice',
headerName: t('parts_price'),
flex: 1
},
{
field: 'setPrice',
headerName: t('set_price'),
flex: 1
},
{
field: 'difference',
headerName: t('difference'),
flex: 1
}
]
}
static getInitialProps () {
return {
props: { scanResults: [] }
}
}
render () {
return (
<Box
sx={{
height: '90vh',
width: '100%'
}}
>
<DataGrid
rows={this.scanResults}
columns={this.columns}
autoPageSize
initialState={{
sorting: {
sortModel: [{ field: 'difference', sort: 'desc' }]
}
}}
sx={{
borderLeft: 'none',
borderRight: 'none'
}}
/>
</Box>
)
}
}
export default withTranslation('home')(Table)

View File

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 234 KiB

After

Width:  |  Height:  |  Size: 234 KiB

View File

@@ -0,0 +1,30 @@
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
import { models } from 'shared-stuff'
import dbConnect from '../../lib/dbConnect'
import Hero from './Hero'
import Table from './Table'
export default function Home ({ scanResults }) {
return (
<>
<Hero />
<Table
scanResults={scanResults}
/>
</>
)
}
export async function getServerSideProps ({ locale }) {
await dbConnect()
const scanResults = await models.ScanResult.find({})
return {
props: {
scanResults: JSON.parse(JSON.stringify(scanResults)),
...(await serverSideTranslations(locale, ['common', 'home']))
}
}
}

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

View File

@@ -0,0 +1,11 @@
{
"description": "Find a profitable difference between the price of the set and the price of the sum of it's parts.",
"help_header": "How to use this site",
"help_body_1": "The main page of the site has a table, that contains info about prime items, that is updated in real time. The column \"Name\" has a link to the item on warframe.market and the time of the last update.",
"help_body_2": "Knowing the difference between the price of the set and the price of the sum of it's parts lets you save platinum buying or even make a profit by purchasing the parts and selling them as a set.",
"help_body_3": "Have fun!",
"name": "Name",
"parts_price": "Parts Price",
"set_price": "Set Price",
"difference": "Difference"
}

View File

View File

@@ -0,0 +1,11 @@
{
"description": "Находи выгодную разницу между ценой набора и ценой его частей по отдельности.",
"help_header": "Как использовать этот сайт?",
"help_body_1": "На главной странице сайта находится таблица, которая содержит информацию о прайм предметах, обновляемую в реальном времени. Колонка \"Наименование\" содержит ссылку на страницу предмета на warframe.market и время последнего обновления информации.",
"help_body_2": "Зная разницу между ценой частей и ценой комплекта можно, например сэкономить на покупке или даже заработать, если купить части по отдельности, а продать как сет.",
"help_body_3": "Приятного использования!",
"name": "Наименование",
"parts_price": "Цена частей",
"set_price": "Цена набора",
"difference": "Разница"
}

View File

@@ -0,0 +1,22 @@
$text-font: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue,
sans-serif;
$font-h0: normal normal 300 56px/64px $text-font;
$font-h1: normal normal 300 48px/56px $text-font;
$font-h2: normal normal 300 40px/48px $text-font;
$font-h3: normal normal 300 36px/44px $text-font;
$font-h4: normal normal 300 32px/40px $text-font;
$font-h5: normal normal 300 28px/36px $text-font;
$font-h6: normal normal 300 24px/32px $text-font;
$font-h7: normal normal 300 20px/26px $text-font;
$font-h8: normal normal 300 18px/24px $text-font;
$font-h9: normal normal 300 16px/20px $text-font;
$font-r8: normal normal 300 24px/30px $text-font;
$font-r7: normal normal 300 22px/28px $text-font;
$font-r6: normal normal 300 20px/26px $text-font;
$font-r5: normal normal 300 18px/24px $text-font;
$font-r4: normal normal 300 16px/22px $text-font;
$font-r3: normal normal 300 14px/18px $text-font;
$font-r2: normal normal 300 12px/16px $text-font;

View File

@@ -0,0 +1 @@
@import './fonts';

View File

@@ -5,7 +5,6 @@ body {
padding: 0;
margin: 0;
font: $font-r4;
color: $clr-text;
}
* {

View File

@@ -1,3 +0,0 @@
{
"extends": "standard"
}

15
gather/.eslintrc.js Normal file
View File

@@ -0,0 +1,15 @@
export default {
parser: '@typescript-eslint/parser',
extends: 'standard-with-typescript',
parserOptions: {
project: './tsconfig.json'
},
rules: {
'@typescript-eslint/no-floating-promises': [
'error',
{
ignoreIIFE: true
}
]
}
}

1
gather/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
dist

View File

@@ -1,6 +1,6 @@
module.exports = {
apps: [{
name: 'warframe-market-bot',
name: 'warframe-center-gather',
script: './src/index.js',
watch: true,
ignore_watch: ['node_modules', 'public'],

6816
gather/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +1,22 @@
{
"name": "warframe-market-bot",
"name": "gather",
"private": true,
"version": "1.0.0",
"description": "The background job that collects data and stores it in a DB",
"main": "index.js",
"scripts": {
"start": "node src/index.js"
"start": "node ./dist/src/index.js",
"build": "../node_modules/typescript/bin/tsc"
},
"author": "Anatoly Kopyl",
"license": "ISC",
"dependencies": {
"axios": "^0.26.0",
"dotenv": "^16.0.0",
"limiter": "^2.1.0",
"shared-stuff": "file:../shared-stuff"
"mongoose": "^6.4.3",
"shared-stuff": "1.0.0",
"typescript": "^4.7.4"
},
"devDependencies": {
"eslint-config-standard": "^16.0.3",
"eslint-config-standard-with-typescript": "^22.0.0",
"pm2": "^5.2.0"
}
}

View File

@@ -1,31 +0,0 @@
const axios = require('axios')
const { RateLimiter } = require('limiter')
class Api {
constructor () {
this.baseUrl = 'https://api.warframe.market/v1/'
this.delay = process.env.API_DELAY ?? 3000
this.limiter = new RateLimiter({ tokensPerInterval: 1, interval: Number(this.delay) })
}
async _get (url) {
await this.limiter.removeTokens(1)
return axios.get(url)
}
async getOrders (url) {
const response = await this._get(this.baseUrl + 'items/' + url + '/orders')
return response.data.payload.orders.filter(function (order) {
return order.order_type === 'sell' && order.user.status !== 'offline'
})
}
async getSortedOrders (url) {
const orders = await this.getOrders(url)
return orders.sort(function (a, b) {
return a.platinum - b.platinum
})
}
}
module.exports = new Api()

59
gather/src/api.ts Normal file
View File

@@ -0,0 +1,59 @@
import axios from 'axios'
import type { AxiosError } from 'axios'
import { RateLimiter } from 'limiter'
type user = {
status: 'online' | 'offline'
}
type order = {
order_type: 'buy' | 'sell',
platinum: number,
user: user
}
class Api {
baseUrl: string
delay: number
limiter: RateLimiter
constructor () {
this.baseUrl = 'https://api.warframe.market/v1/'
this.delay = Number(process.env.API_DELAY) ?? 3000
this.limiter = new RateLimiter({ tokensPerInterval: 1, interval: Number(this.delay) })
}
async _get (url: string) {
await this.limiter.removeTokens(1)
return axios.get(url).catch((error: AxiosError) => {
console.error(error)
return {
data: {
payload: {
orders: []
}
}
}
})
}
async getOrders (url: string): Promise<order[]> {
const response = await this._get(this.baseUrl + 'items/' + url + '/orders')
return response.data.payload.orders.filter(function (order: order) {
return order.order_type === 'sell' && order.user.status !== 'offline'
})
}
async getSortedOrders (url: string): Promise<order[]> {
const orders = await this.getOrders(url)
if (orders.length === 0) {
return []
}
return orders.sort(function (a: order, b: order) {
return a.platinum - b.platinum
})
}
}
export default new Api()

View File

@@ -1,31 +0,0 @@
require('dotenv').config()
const mongoose = require('mongoose')
const items = require('./items')
const { models } = require('shared-stuff')
async function initDB () {
await mongoose.connect(process.env.MONGODB_URI)
}
(async () => {
await initDB()
for (const item of items) {
console.log(`Looking at ${item.name}`)
let partsPrice = 0
for (const part of item.parts) {
partsPrice += await part.getPrice()
}
const setPrice = await item.set.getPrice()
if (partsPrice < setPrice) {
models.ScanResult.findOneAndUpdate(
{ name: item.name },
{ partsPrice, setPrice },
{ upsert: true },
() => {}
)
}
}
})()

40
gather/src/index.ts Normal file
View File

@@ -0,0 +1,40 @@
import mongoose from 'mongoose'
import items from './items'
import { models } from 'shared-stuff'
import 'dotenv/config'
async function initDB (): Promise<void> {
await mongoose.connect(String(process.env.MONGODB_URI))
}
(async () => {
await initDB()
for (const item of items) {
process.stdout.write(`Looking at ${item.name}: `)
let partsPrice = 0
for (const part of item.parts) {
process.stdout.write(`${part.part} `)
partsPrice += await part.getPrice()
}
const setPrice = await item.set.getPrice()
await models.ScanResult.findOneAndUpdate(
{ name: item.name },
{
fullName: item.fullName,
url: item.set.url,
timestamp: new Date(),
partsPrice,
setPrice,
difference: setPrice - partsPrice
},
{ upsert: true }
)
console.log('✅')
}
await mongoose.disconnect()
})()

View File

@@ -1,7 +1,7 @@
const Item = require('./Item')
import Item from './Item'
module.exports = class Archwings extends Item {
constructor (name) {
export default class Archwings extends Item {
constructor (name: string) {
super(name)
this.addPart('harness')

View File

@@ -1,7 +1,7 @@
const Item = require('./Item')
import Item from './Item'
module.exports = class Companion extends Item {
constructor (name) {
export default class Companion extends Item {
constructor (name: string) {
super(name)
this.addPart('carapace')

View File

@@ -1,15 +0,0 @@
const Part = require('./Part')
module.exports = class Item {
constructor (name) {
this.name = name
this.set = new Part(name, 'set')
this.parts = []
this.addPart('blueprint')
}
addPart (part, amount) {
this.parts.push(new Part(this.name, part, amount))
}
}

25
gather/src/items/Item.ts Normal file
View File

@@ -0,0 +1,25 @@
import Part from './Part'
function capitalize (string: string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}
export default class Item {
name: string
fullName: string
set: Part
parts: Part[]
constructor (name: string) {
this.name = name
this.fullName = capitalize(name) + ' Prime'
this.set = new Part(name, 'set')
this.parts = []
this.addPart('blueprint')
}
addPart (part: string, amount: number = 1) {
this.parts.push(new Part(this.name, part, amount))
}
}

View File

@@ -1,14 +0,0 @@
const Api = require('../api')
module.exports = class Part {
constructor (set, part, amount) {
this.part = part
this.url = `${set}_prime_${part}`
this.amount = amount ?? 1
}
async getPrice () {
const orders = await Api.getSortedOrders(this.url)
return Number(orders[0].platinum) * this.amount
}
}

24
gather/src/items/Part.ts Normal file
View File

@@ -0,0 +1,24 @@
import Api from '../api'
export default class Part {
part: string
urlPath: string
url: string
amount: number
constructor (set: string, part: string, amount: number = 1) {
this.part = part
this.urlPath = `${set}_prime_${part}`
this.url = `https://warframe.market/items/${set}_prime_${part}`
this.amount = amount ?? 1
}
async getPrice (): Promise<number> {
const orders = await Api.getSortedOrders(this.urlPath)
if (orders.length === 0) {
return 0
}
return Number(orders[0].platinum) * this.amount
}
}

View File

@@ -1,7 +1,7 @@
const Item = require('./Item')
import Item from './Item'
module.exports = class Primary extends Item {
constructor (name) {
export default class Primary extends Item {
constructor (name: string) {
super(name)
this.addPart('barrel')

View File

@@ -1,7 +1,7 @@
const Item = require('./Item')
import Item from './Item'
module.exports = class Secondary extends Item {
constructor (name) {
export default class Secondary extends Item {
constructor (name: string) {
super(name)
this.addPart('barrel', 2)

View File

@@ -1,7 +1,7 @@
const Item = require('./Item')
import Item from './Item'
module.exports = class Warframe extends Item {
constructor (name) {
export default class Warframe extends Item {
constructor (name: string) {
super(name)
this.addPart('systems')

View File

@@ -1,11 +1,12 @@
const items = require('./items.json')
const Warframe = require('./Warframe')
import items from './items.json'
import Warframe from './Warframe'
// const Primary = require('./Primary')
// const Secondary = require('./Secondary')
const Companion = require('./Companion')
const Archwings = require('./Archwings')
import Companion from './Companion'
import Archwings from './Archwings'
import type Item from './Item'
const result = []
const result: Item[] = []
items.warframes.forEach((name) => {
result.push(new Warframe(name))
@@ -23,4 +24,4 @@ items.archwings.forEach((name) => {
result.push(new Archwings(name))
})
module.exports = result
export default result

20
gather/tsconfig.json Normal file
View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"allowJs": true,
"checkJs": false,
"outDir": "dist",
"rootDir": ".",
"strict": true,
"forceConsistentCasingInFileNames": true,
"strictNullChecks": true,
"resolveJsonModule": true,
"esModuleInterop": true,
},
"exclude": ["node_modules", "dist"],
"include": [
"./src",
"./*",
]
}

1651
gather/yarn-error.log Normal file

File diff suppressed because it is too large Load Diff

9597
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
{
"name": "warframe-center",
"private": true,
"version": "1.0.0",
"description": "Список Прайм предметов: https://warframe.fandom.com/wiki/Prime",
"repository": {
@@ -7,5 +8,10 @@
"url": "ssh://git@git.radner.ru:3036/anatolykopyl/warframe-center.git"
},
"author": "Anatoly Kopyl",
"workspaces": ["./app", "./gather", "./shared-stuff"]
"workspaces": [
"./frontend",
"./gather",
"./shared-stuff"
],
"packageManager": "yarn@3.2.1"
}

1
shared-stuff/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
dist

View File

@@ -1,9 +0,0 @@
const ScanResult = require('./models/ScanResult')
const models = {
ScanResult
}
module.exports = {
models
}

7
shared-stuff/index.ts Normal file
View File

@@ -0,0 +1,7 @@
import ScanResult from './models/ScanResult'
const models = {
ScanResult
}
export { models }

View File

@@ -1,9 +0,0 @@
const mongoose = require('mongoose')
const scanResultSchema = new mongoose.Schema({
name: String,
partsPrice: Number,
setPrice: Number
})
module.exports = mongoose.models.ScanResult || mongoose.model('ScanResult', scanResultSchema)

View File

@@ -0,0 +1,15 @@
import mongoose from 'mongoose'
const scanResultSchema = new mongoose.Schema({
name: String,
fullName: String,
url: String,
partsPrice: Number,
setPrice: Number,
difference: Number
},
{
timestamps: true
})
export default mongoose.models.ScanResult || mongoose.model('ScanResult', scanResultSchema)

View File

@@ -1,509 +0,0 @@
{
"name": "shared-stuff",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "1.0.0",
"dependencies": {
"mongoose": "^6.2.6"
}
},
"node_modules/@types/node": {
"version": "17.0.21",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
"integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ=="
},
"node_modules/@types/webidl-conversions": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
"integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
},
"node_modules/@types/whatwg-url": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz",
"integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==",
"dependencies": {
"@types/node": "*",
"@types/webidl-conversions": "*"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/bson": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/bson/-/bson-4.6.1.tgz",
"integrity": "sha512-I1LQ7Hz5zgwR4QquilLNZwbhPw0Apx7i7X9kGMBTsqPdml/03Q9NBtD9nt/19ahjlphktQImrnderxqpzeVDjw==",
"dependencies": {
"buffer": "^5.6.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"node_modules/debug": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
"integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/debug/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/denque": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
"integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==",
"engines": {
"node": ">=0.10"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
},
"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=="
},
"node_modules/memory-pager": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
"optional": true
},
"node_modules/mongodb": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.3.1.tgz",
"integrity": "sha512-sNa8APSIk+r4x31ZwctKjuPSaeKuvUeNb/fu/3B6dRM02HpEgig7hTHM8A/PJQTlxuC/KFWlDlQjhsk/S43tBg==",
"dependencies": {
"bson": "^4.6.1",
"denque": "^2.0.1",
"mongodb-connection-string-url": "^2.4.1",
"socks": "^2.6.1"
},
"engines": {
"node": ">=12.9.0"
},
"optionalDependencies": {
"saslprep": "^1.0.3"
}
},
"node_modules/mongodb-connection-string-url": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz",
"integrity": "sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==",
"dependencies": {
"@types/whatwg-url": "^8.2.1",
"whatwg-url": "^11.0.0"
}
},
"node_modules/mongoose": {
"version": "6.2.6",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.6.tgz",
"integrity": "sha512-OkPM1y7Ed9+Pa2/18mxegcD0OOe/aCXTQvOEyEn/MzVdaRsVSc+zE6myOS4LkWWi30c2tl4fpdJJvgC/MgXiww==",
"dependencies": {
"bson": "^4.2.2",
"kareem": "2.3.4",
"mongodb": "4.3.1",
"mpath": "0.8.4",
"mquery": "4.0.2",
"ms": "2.1.3",
"sift": "16.0.0"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mongoose"
}
},
"node_modules/mpath": {
"version": "0.8.4",
"resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz",
"integrity": "sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g==",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/mquery": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.2.tgz",
"integrity": "sha512-oAVF0Nil1mT3rxty6Zln4YiD6x6QsUWYz927jZzjMxOK2aqmhEz5JQ7xmrKK7xRFA2dwV+YaOpKU/S+vfNqKxA==",
"dependencies": {
"debug": "4.x"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"engines": {
"node": ">=6"
}
},
"node_modules/saslprep": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
"optional": true,
"dependencies": {
"sparse-bitfield": "^3.0.3"
},
"engines": {
"node": ">=6"
}
},
"node_modules/sift": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/sift/-/sift-16.0.0.tgz",
"integrity": "sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ=="
},
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/socks": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
"integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
"dependencies": {
"ip": "^1.1.5",
"smart-buffer": "^4.2.0"
},
"engines": {
"node": ">= 10.13.0",
"npm": ">= 3.0.0"
}
},
"node_modules/sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
"optional": true,
"dependencies": {
"memory-pager": "^1.0.2"
}
},
"node_modules/tr46": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
"dependencies": {
"punycode": "^2.1.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
"engines": {
"node": ">=12"
}
},
"node_modules/whatwg-url": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
"integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
"dependencies": {
"tr46": "^3.0.0",
"webidl-conversions": "^7.0.0"
},
"engines": {
"node": ">=12"
}
}
},
"dependencies": {
"@types/node": {
"version": "17.0.21",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
"integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ=="
},
"@types/webidl-conversions": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
"integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
},
"@types/whatwg-url": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz",
"integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==",
"requires": {
"@types/node": "*",
"@types/webidl-conversions": "*"
}
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"bson": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/bson/-/bson-4.6.1.tgz",
"integrity": "sha512-I1LQ7Hz5zgwR4QquilLNZwbhPw0Apx7i7X9kGMBTsqPdml/03Q9NBtD9nt/19ahjlphktQImrnderxqpzeVDjw==",
"requires": {
"buffer": "^5.6.0"
}
},
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"debug": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
"integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
"requires": {
"ms": "2.1.2"
},
"dependencies": {
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"denque": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
"integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ=="
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
},
"kareem": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.4.tgz",
"integrity": "sha512-Vcrt8lcpVl0s8ePx634BxwRqmFo+5DcOhlmNadehxreMTIQi/9hOL/B3hZQQbK5DgMS7Lem3xABXV7/S3jy+7g=="
},
"memory-pager": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
"optional": true
},
"mongodb": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.3.1.tgz",
"integrity": "sha512-sNa8APSIk+r4x31ZwctKjuPSaeKuvUeNb/fu/3B6dRM02HpEgig7hTHM8A/PJQTlxuC/KFWlDlQjhsk/S43tBg==",
"requires": {
"bson": "^4.6.1",
"denque": "^2.0.1",
"mongodb-connection-string-url": "^2.4.1",
"saslprep": "^1.0.3",
"socks": "^2.6.1"
}
},
"mongodb-connection-string-url": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz",
"integrity": "sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==",
"requires": {
"@types/whatwg-url": "^8.2.1",
"whatwg-url": "^11.0.0"
}
},
"mongoose": {
"version": "6.2.6",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.6.tgz",
"integrity": "sha512-OkPM1y7Ed9+Pa2/18mxegcD0OOe/aCXTQvOEyEn/MzVdaRsVSc+zE6myOS4LkWWi30c2tl4fpdJJvgC/MgXiww==",
"requires": {
"bson": "^4.2.2",
"kareem": "2.3.4",
"mongodb": "4.3.1",
"mpath": "0.8.4",
"mquery": "4.0.2",
"ms": "2.1.3",
"sift": "16.0.0"
}
},
"mpath": {
"version": "0.8.4",
"resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz",
"integrity": "sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g=="
},
"mquery": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.2.tgz",
"integrity": "sha512-oAVF0Nil1mT3rxty6Zln4YiD6x6QsUWYz927jZzjMxOK2aqmhEz5JQ7xmrKK7xRFA2dwV+YaOpKU/S+vfNqKxA==",
"requires": {
"debug": "4.x"
}
},
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"saslprep": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
"optional": true,
"requires": {
"sparse-bitfield": "^3.0.3"
}
},
"sift": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/sift/-/sift-16.0.0.tgz",
"integrity": "sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ=="
},
"smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="
},
"socks": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
"integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
"requires": {
"ip": "^1.1.5",
"smart-buffer": "^4.2.0"
}
},
"sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
"optional": true,
"requires": {
"memory-pager": "^1.0.2"
}
},
"tr46": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
"requires": {
"punycode": "^2.1.1"
}
},
"webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
},
"whatwg-url": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
"integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
"requires": {
"tr46": "^3.0.0",
"webidl-conversions": "^7.0.0"
}
}
}
}

View File

@@ -1,9 +1,14 @@
{
"name": "shared-stuff",
"private": true,
"version": "1.0.0",
"description": "The stuff that is shared between the background job and the Next app",
"main": "index.js",
"main": "./dist/index.js",
"scripts": {
"build": "./node_modules/typescript/bin/tsc"
},
"dependencies": {
"mongoose": "^6.2.6"
"mongoose": "^6.4.3",
"typescript": "^4.7.4"
}
}

View File

@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"checkJs": false,
"outDir": "dist",
"rootDir": ".",
"strict": true,
"forceConsistentCasingInFileNames": true,
"strictNullChecks": true,
"resolveJsonModule": true,
"esModuleInterop": true,
},
"exclude": ["node_modules", "dist"],
"include": [
"./*",
]
}

5867
yarn.lock Normal file

File diff suppressed because it is too large Load Diff