Use Node.js imports for types

This commit is contained in:
ADAMJR 2021-12-18 22:34:07 +00:00
parent b8bee6eb04
commit 56b5a4c00c
26 changed files with 535 additions and 505 deletions

46
.dockerignore Normal file
View File

@ -0,0 +1,46 @@
.env
keys/
node_modules/
lib/
logs/
upload/
.DS_STORE
scripts/flow/*/.flowconfig
.flowconfig
*~
*.pyc
.grunt
_SpecRunner.html
__benchmarks__
build/
build2/
remote-repo/
coverage/
.module-cache
fixtures/dom/public/react-dom.js
fixtures/dom/public/react.js
test/the-files-to-test.generated.js
*.log*
chrome-user-data
*.sublime-project
*.sublime-workspace
.idea
*.iml
.vscode
*.swp
*.swo
packages/react-devtools-core/dist
packages/react-devtools-extensions/chrome/build
packages/react-devtools-extensions/chrome/*.crx
packages/react-devtools-extensions/chrome/*.pem
packages/react-devtools-extensions/firefox/build
packages/react-devtools-extensions/firefox/*.xpi
packages/react-devtools-extensions/firefox/*.pem
packages/react-devtools-extensions/shared/build
packages/react-devtools-extensions/.tempUserDataDir
packages/react-devtools-inline/dist
packages/react-devtools-shell/dist
packages/react-devtools-scheduling-profiler/dist

View File

@ -1 +0,0 @@
../.gitignore

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,6 @@
{
"name": "accord-backend",
"name": "@accord/backend",
"version": "0.0.0",
"description": "",
"main": "src/app.ts",
"scripts": {
"start": "npm run start:dev",
"start:dev": "ts-node-dev --transpile-only src/app.ts",
@ -15,7 +13,9 @@
"keywords": [],
"author": "github.com/theadamjr",
"dependencies": {
"@accord/types": "file:./types",
"@accord/backend": "file:../src",
"@accord/ion": "github:accord-dot-app/ion",
"@accord/types": "file:../types",
"body-parser": "^1.19.0",
"chai-things": "^0.2.0",
"colors": "^1.4.0",
@ -50,7 +50,6 @@
"winston": "^3.3.3"
},
"devDependencies": {
"@accord/ion": "github:accord-dot-app/ion",
"@types/chai": "^4.2.14",
"@types/chai-as-promised": "^7.1.3",
"@types/chai-spies": "^1.0.3",

View File

@ -1,3 +1,4 @@
import '@accord/types';
import { connect } from 'mongoose';
import { config } from 'dotenv';
config();
@ -11,7 +12,6 @@ connect(process.env.MONGO_URI, {
useFindAndModify: false,
useCreateIndex: true,
serverSelectionTimeoutMS: 0,
}, (error) => (error)
? log.error(error.message, { uri: process.env.MONGO_URI })
: log.info('Connected to database.', { uri: process.env.MONGO_URI })
)
})
.catch(error => log.error(error.message, { uri: process.env.MONGO_URI }))
.then(con => log.info(`Connected to database on PORT ${con.port}.`, { uri: process.env.MONGO_URI }));

View File

@ -21,7 +21,6 @@ export default class Channels extends DBWrapper<string, ChannelDocument> {
return Channel.create({
_id: generateSnowflake(),
name: 'chat',
// TODO: testme
position: await Channel.countDocuments({ guildId: options.guildId }),
type: 'TEXT',
...options as any,

View File

@ -1,11 +1,3 @@
import Channels from '../data/channels';
import GuildMembers from '../data/guild-members';
import Guilds from '../data/guilds';
import Invites from '../data/invites';
import Messages from '../data/messages';
import Pings from '../data/pings';
import Roles from '../data/roles';
import Users from '../data/users';
import { Email } from '../email/email';
import { EmailFunctions } from '../email/email-functions';
import { Verification } from '../email/verification';
@ -15,33 +7,17 @@ import { WSCooldowns } from '../ws/modules/ws-cooldowns';
import { WSGuard } from '../ws/modules/ws-guard';
import { WSRooms } from '../ws/modules/ws-rooms';
import { WebSocket } from '../ws/websocket';
import Channels from '../data/channels';
import GuildMembers from '../data/guild-members';
import Guilds from '../data/guilds';
import Invites from '../data/invites';
import Messages from '../data/messages';
import Pings from '../data/pings';
import Roles from '../data/roles';
import Users from '../data/users';
import ChannelJoin from '../ws/ws-events/channel-join';
import ChannelLeave from '../ws/ws-events/channel-leave';
export interface Deps {
channels: Channels;
/** @deprecated */
channelJoin: ChannelJoin;
/** @deprecated */
channelLeave: ChannelLeave;
email: Email;
emailFunctions: EmailFunctions;
guilds: Guilds;
guildMembers: GuildMembers;
invites: Invites;
messages: Messages;
/** @deprecated */
pings: Pings;
rest: REST;
roles: Roles;
users: Users;
wsCooldowns: WSCooldowns;
wsGuard: WSGuard;
wsRooms: WSRooms;
webSocket: WebSocket;
verification: Verification;
voiceService: VoiceService;
}
import Deps from '@accord/types/deps';
const deps: Deps = {
channels: new Channels(),

View File

@ -19,7 +19,9 @@ const readFileAsync = promisify(readFile);
function setupMulter(app: Application) {
const uploadDir = resolve('./assets/upload');
execSync(`mkdir -p ${uploadDir}`);
try {
execSync(`mkdir -p ${uploadDir} 2>> /dev/null`);
} catch {}
// uses storage rather than memory - 2 file operations per file upload
const storage = multer.diskStorage({

View File

@ -22,10 +22,11 @@ export default class implements WSEvent<'CHANNEL_DELETE'> {
await channel.deleteOne();
await this.lowerHigherChannels(channel);
/** @deprecated */
ws
.to(channel.guildId)
.emit(this.on, { channelId, guildId: channel.guildId });
return [{
emit: this.on,
to: channel.guildId,
send: { channelId, guildId: channel.guildId },
}];
}
private async lowerHigherChannels(channel: ChannelDocument) {

View File

@ -1,26 +1,28 @@
import { config } from 'dotenv';
import { should, use } from 'chai';
import chaiAsPromised from 'chai-as-promised';
import chaiSpies from 'chai-spies';
import chaiThings from 'chai-things';
import mongoose from 'mongoose';
import { MongoMemoryServer } from 'mongodb-memory-server';
config({ path: 'test/.env' });
use(chaiAsPromised);
use(chaiSpies);
use(chaiThings);
use(should);
(async() => {
const mongod = await MongoMemoryServer.create();
await mongoose.connect(mongod.getUri('accord-test'), {
useUnifiedTopology: true,
useNewUrlParser: true,
useFindAndModify: false,
useCreateIndex: true,
});
})();
import { config } from 'dotenv';
import { should, use } from 'chai';
import chaiAsPromised from 'chai-as-promised';
import chaiSpies from 'chai-spies';
import chaiThings from 'chai-things';
import mongoose from 'mongoose';
import { MongoMemoryServer } from 'mongodb-memory-server';
config({ path: 'test/.env' });
use(chaiAsPromised);
use(chaiSpies);
use(chaiThings);
use(should);
(async() => {
const mongod = await MongoMemoryServer.create();
await mongoose.connect(mongod.getUri('accord-test'), {
useUnifiedTopology: true,
useNewUrlParser: true,
useFindAndModify: false,
useCreateIndex: true,
});
})();
import('../../src/app');
import('./ws/channel-delete.test');

View File

@ -1,17 +1,45 @@
import '@accord/types';
import { Channel } from '../../../src/data/models/channel';
import { Guild } from '../../../src/data/models/guild';
import ChannelDelete from '../../../src/ws/ws-events/channel-delete';
import { given, test } from '@accord/ion';
import { WebSocket } from '../../../src/ws/websocket';
import { User } from '../../../src/data/models/user';
test(channelDelete, () => {
let channel: Entity.Channel;
let guild: Entity.Guild;
let ownerUser: Entity.User;
beforeEach(async () => {
ownerUser = await deps.users.create({
email: 'doesnotmatter@example.com',
username: 'Test User',
password: 'doesnotmatter',
});
guild = await deps.guilds.create('Test Guild', '');
channel = await deps.channels.create({ guildId: guild.id });
});
after(async () => {
await Channel.deleteMany();
await Guild.deleteMany();
await User.deleteMany();
});
given({})
.before(async () => ownerUser = await User.create({}));
given({}).rejectWith('Channel not found');
given({}).rejectWith('Channel not found');
// given({ channelId: generateSnowflake() }).rejectWith('Channel not found');
given({ channelId: channel.id }).resolveWith([{
emit: 'CHANNEL_DELETE',
to: channel.id,
send: { channelId: channel.id },
}]);
});
async function channelDelete(args: WS.To['CHANNEL_DELETE']) {
await import('../../../src/modules/deps');
console.error = () => {};
global['log'] = console;
const event = new ChannelDelete();
return event.invoke(new WebSocket(), {} as any, args);
}
}

View File

@ -1,32 +1,32 @@
version: '3.8'
services:
database:
container_name: accord_database
image: mongo:5-focal
ports: [27018:27017]
volumes: [accord:/data/db]
types:
build: ./types
backend:
container_name: accord_backend
depends_on: [types, database]
build: ./backend
ports: [3000:3000]
env_file: [./backend/.env]
volumes:
- ./backend/src:/app/src
- ./backend/assets:/app/assets
- ./backend/logs:/app/logs
frontend:
container_name: accord_frontend
depends_on: [types, database]
build:
context: ./frontend
args:
REACT_APP_API_URL: ${backend}/v2
ports: [4200:4200]
env_file: [./frontend/env/.env.dev]
volumes:
- ./frontend/src:/app/src
volumes:
version: '3.8'
services:
database:
container_name: accord_database
image: mongo:5-focal
ports: [27018:27017]
volumes: [accord:/data/db]
types:
build: ./types
backend:
container_name: accord_backend
depends_on: [types, database]
build: ./backend
ports: [3000:3000]
env_file: [./backend/.env]
volumes:
- ./backend/src:/app/src
- ./backend/assets:/app/assets
- ./backend/logs:/app/logs
frontend:
container_name: accord_frontend
depends_on: [types, database]
build:
context: ./frontend
args:
REACT_APP_API_URL: ${backend}/v2
ports: [4200:4200]
env_file: [./frontend/env/.env.dev]
volumes:
- ./frontend/src:/app/src
volumes:
accord:

View File

@ -1,10 +0,0 @@
#!/bin/sh
sudo docker pull mongo:4.4-bionic
sudo docker tag mongo:4.4-bionic accord_database
(cd types; sudo docker build -t accord_types:latest .)
(cd backend; sudo docker build -t accord_backend:latest .)
(cd frontend; sudo docker build -t accord_frontend:latest .)
sudo docker volume create accord 2>> /dev/null
sudo docker network create accord 2>> /dev/null

View File

@ -1,4 +0,0 @@
yes | docker container prune
yes | docker image prune
yes | docker network prune
yes | docker volume prune

View File

@ -1,5 +0,0 @@
#!/bin/sh
docker container rm -f $(docker ps -aq) 2> /dev/null
docker image rm -f $(docker image ls -q) 2> /dev/null
docker volume rm -f $(docker volume ls -q) 2> /dev/null
docker network rm $(docker network ls -q) 2> /dev/null

View File

@ -1,8 +0,0 @@
docker container rm -f accord_database
docker container rm -f accord_backend
docker container rm -f accord_frontend
docker image rm -f accord_database
docker image rm -f accord_types
docker image rm -f accord_backend
docker image rm -f accord_frontend

View File

@ -1,27 +0,0 @@
#!/bin/sh
docker container rm -f accord_database
docker container rm -f accord_backend
docker container rm -f accord_frontend
sudo docker run \
--name accord_database \
--hostname accord_database \
-p 27018:27017 \
-v accord:/data/db \
-d accord_database:latest;
sudo docker run \
--name accord_backend \
--hostname accord_backend \
--env-file ./backend/.env \
-p 3000:3000 \
-u root \
-d accord_backend:latest;
sudo docker run \
--name accord_frontend \
--hostname accord_frontend \
--env-file ./frontend/env/.env.dev \
-p 4200:4200 \
-u root \
-d accord_frontend:latest;

View File

@ -1 +0,0 @@
../.gitignore

View File

@ -1,22 +1,22 @@
FROM node:16-alpine3.14
RUN addgroup app && adduser -SG app app
RUN mkdir /app && chown app:app /app
USER app
WORKDIR /app
COPY --chown=app:app package*.json ./
RUN npm i
COPY --chown=app:app . .
RUN unlink /app/types
COPY --chown=app:app --from=accord_types:latest /app /app/types
ENV PORT $PORT
ENV REACT_APP_API_URL $REACT_APP_API_URL
ENV REACT_APP_CDN_URL $REACT_APP_CDN_URL
ENV REACT_APP_REPO $REACT_APP_REPO
ENV REACT_APP_ROOT_API_URL $REACT_APP_ROOT_API_URL
ARG REACT_APP_API_URL $REACT_APP_API_URL
EXPOSE 4200
FROM node:16-alpine3.14
RUN addgroup app && adduser -SG app app
RUN mkdir /app && chown app:app /app
USER app
WORKDIR /app
COPY --chown=app:app package*.json ./
RUN npm i
COPY --chown=app:app . .
RUN unlink /app/types
COPY --chown=app:app --from=accord_types:latest /app /app/types
ENV PORT $PORT
ENV REACT_APP_API_URL $REACT_APP_API_URL
ENV REACT_APP_CDN_URL $REACT_APP_CDN_URL
ENV REACT_APP_REPO $REACT_APP_REPO
ENV REACT_APP_ROOT_API_URL $REACT_APP_ROOT_API_URL
ARG REACT_APP_API_URL $REACT_APP_API_URL
EXPOSE 4200
CMD npm run start:dev

View File

@ -1,5 +1,5 @@
PORT=4200
REACT_APP_API_URL="${backend}/v2"
REACT_APP_CDN_URL="${backend}/assets"
REACT_APP_REPO="https://github.com/accord-dot-app/app"
PORT=4200
REACT_APP_API_URL="${backend}/v2"
REACT_APP_CDN_URL="${backend}/assets"
REACT_APP_REPO="https://github.com/accord-dot-app/app"
REACT_APP_ROOT_API_URL=${backend}

View File

@ -1,28 +1,28 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/app';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
import configureStore from './store/configure-store';
import { SnackbarProvider } from 'notistack';
import './index.css';
console.log(process.env);
ReactDOM.render(
<SnackbarProvider maxSnack={1}>
<Provider store={configureStore()}>
<React.StrictMode>
<App />
</React.StrictMode>
</Provider>
</SnackbarProvider>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/app';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
import configureStore from './store/configure-store';
import { SnackbarProvider } from 'notistack';
import './index.css';
console.log(process.env);
ReactDOM.render(
<SnackbarProvider maxSnack={1}>
<Provider store={configureStore()}>
<React.StrictMode>
<App />
</React.StrictMode>
</Provider>
</SnackbarProvider>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

45
types/deps.ts Normal file
View File

@ -0,0 +1,45 @@
import { Email } from '@accord/backend/src/email/email';
import { EmailFunctions } from '@accord/backend/src/email/email-functions';
import { Verification } from '@accord/backend/src/email/verification';
import { REST } from '@accord/backend/src/rest/server';
import { VoiceService } from '@accord/backend/src/voice/voice-service';
import { WSCooldowns } from '@accord/backend/src/ws/modules/ws-cooldowns';
import { WSGuard } from '@accord/backend/src/ws/modules/ws-guard';
import { WSRooms } from '@accord/backend/src/ws/modules/ws-rooms';
import { WebSocket } from '@accord/backend/src/ws/websocket';
import Channels from '@accord/backend/src/data/channels';
import GuildMembers from '@accord/backend/src/data/guild-members';
import Guilds from '@accord/backend/src/data/guilds';
import Invites from '@accord/backend/src/data/invites';
import Messages from '@accord/backend/src/data/messages';
import Pings from '@accord/backend/src/data/pings';
import Roles from '@accord/backend/src/data/roles';
import Users from '@accord/backend/src/data/users';
import ChannelJoin from '@accord/backend/src/ws/ws-events/channel-join';
import ChannelLeave from '@accord/backend/src/ws/ws-events/channel-leave';
declare interface Deps {
channels: Channels;
/** @deprecated */
channelJoin: ChannelJoin;
/** @deprecated */
channelLeave: ChannelLeave;
email: Email;
emailFunctions: EmailFunctions;
guilds: Guilds;
guildMembers: GuildMembers;
invites: Invites;
messages: Messages;
/** @deprecated */
pings: Pings;
rest: REST;
roles: Roles;
users: Users;
wsCooldowns: WSCooldowns;
wsGuard: WSGuard;
wsRooms: WSRooms;
webSocket: WebSocket;
verification: Verification;
voiceService: VoiceService;
}
export default Deps;

2
types/global.d.ts vendored
View File

@ -1,4 +1,4 @@
export declare global {
const log: import('winston').Logger;
const deps: import('../modules/deps').Deps;
const deps: import('./deps').default;
}

9
types/main.ts Normal file
View File

@ -0,0 +1,9 @@
import './auth';
import './deps';
import './dotenv';
import './entity';
import './global';
import './rest';
import './store';
import './util';
import './ws';

168
types/package-lock.json generated Normal file
View File

@ -0,0 +1,168 @@
{
"name": "@accord/types",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@accord/types",
"dependencies": {
"@accord/backend": "file:../backend"
}
},
"../backend": {
"name": "@accord/backend",
"version": "0.0.0",
"dependencies": {
"@accord/backend": "file:../src",
"@accord/ion": "github:accord-dot-app/ion",
"@accord/types": "file:../types",
"body-parser": "^1.19.0",
"chai-things": "^0.2.0",
"colors": "^1.4.0",
"cors": "^2.8.5",
"crypto-js": "^4.1.1",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-async-errors": "^3.1.1",
"express-rate-limit": "^5.2.6",
"faker": "^5.4.0",
"got": "^11.7.0",
"helmet": "^4.4.1",
"imghash": "^0.0.9",
"jsonwebtoken": "^8.5.1",
"mongodb-memory-server": "^8.0.2",
"mongoose": "^5.10.7",
"mongoose-unique-validator": "^2.0.3",
"multer": "^1.4.3",
"node-fetch": "^2.6.1",
"nodemailer": "^6.5.0",
"nodemailer-pug-engine": "^2.0.0",
"passport": "^0.4.1",
"passport-local": "^1.0.0",
"passport-local-mongoose": "^6.0.1",
"rate-limit-mongo": "^2.3.1",
"re2": "^1.16.0",
"socket.io": "^4.0.0",
"socket.io-client": "^4.0.0",
"striptags": "^3.2.0",
"ts-node": "^9.1.1",
"typescript": "^4.2.3",
"winston": "^3.3.3"
},
"devDependencies": {
"@types/chai": "^4.2.14",
"@types/chai-as-promised": "^7.1.3",
"@types/chai-spies": "^1.0.3",
"@types/chai-things": "^0.0.34",
"@types/colors": "^1.2.1",
"@types/cors": "^2.8.7",
"@types/crypto-js": "^4.0.2",
"@types/deasync": "^0.1.2",
"@types/dotenv": "^8.2.0",
"@types/express": "^4.17.11",
"@types/express-rate-limit": "^5.1.1",
"@types/faker": "^5.1.6",
"@types/jest": "^27.0.1",
"@types/jsonwebtoken": "^8.5.0",
"@types/mocha": "^8.2.3",
"@types/mongoose": "^5.7.36",
"@types/multer": "^1.4.7",
"@types/node": "^14.11.2",
"@types/node-fetch": "^2.5.7",
"@types/nodemailer": "^6.4.1",
"@types/passport": "^1.0.4",
"@types/passport-local": "^1.0.33",
"@types/socket.io": "^2.1.13",
"@types/socket.io-client": "^3.0.0",
"@types/supertest": "^2.0.10",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"chai-spies": "^1.0.0",
"mocha": "^8.2.1",
"nodemon": "^2.0.14",
"supertest": "^6.1.3",
"ts-mocha": "^8.0.0",
"ts-node-dev": "^1.1.8"
}
},
"node_modules/@accord/backend": {
"resolved": "../backend",
"link": true
}
},
"dependencies": {
"@accord/backend": {
"version": "file:../backend",
"requires": {
"@accord/backend": "file:../src",
"@accord/ion": "github:accord-dot-app/ion",
"@accord/types": "file:../types",
"@types/chai": "^4.2.14",
"@types/chai-as-promised": "^7.1.3",
"@types/chai-spies": "^1.0.3",
"@types/chai-things": "^0.0.34",
"@types/colors": "^1.2.1",
"@types/cors": "^2.8.7",
"@types/crypto-js": "^4.0.2",
"@types/deasync": "^0.1.2",
"@types/dotenv": "^8.2.0",
"@types/express": "^4.17.11",
"@types/express-rate-limit": "^5.1.1",
"@types/faker": "^5.1.6",
"@types/jest": "^27.0.1",
"@types/jsonwebtoken": "^8.5.0",
"@types/mocha": "^8.2.3",
"@types/mongoose": "^5.7.36",
"@types/multer": "^1.4.7",
"@types/node": "^14.11.2",
"@types/node-fetch": "^2.5.7",
"@types/nodemailer": "^6.4.1",
"@types/passport": "^1.0.4",
"@types/passport-local": "^1.0.33",
"@types/socket.io": "^2.1.13",
"@types/socket.io-client": "^3.0.0",
"@types/supertest": "^2.0.10",
"body-parser": "^1.19.0",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"chai-spies": "^1.0.0",
"chai-things": "^0.2.0",
"colors": "^1.4.0",
"cors": "^2.8.5",
"crypto-js": "^4.1.1",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-async-errors": "^3.1.1",
"express-rate-limit": "^5.2.6",
"faker": "^5.4.0",
"got": "^11.7.0",
"helmet": "^4.4.1",
"imghash": "^0.0.9",
"jsonwebtoken": "^8.5.1",
"mocha": "^8.2.1",
"mongodb-memory-server": "^8.0.2",
"mongoose": "^5.10.7",
"mongoose-unique-validator": "^2.0.3",
"multer": "^1.4.3",
"node-fetch": "^2.6.1",
"nodemailer": "^6.5.0",
"nodemailer-pug-engine": "^2.0.0",
"nodemon": "^2.0.14",
"passport": "^0.4.1",
"passport-local": "^1.0.0",
"passport-local-mongoose": "^6.0.1",
"rate-limit-mongo": "^2.3.1",
"re2": "^1.16.0",
"socket.io": "^4.0.0",
"socket.io-client": "^4.0.0",
"striptags": "^3.2.0",
"supertest": "^6.1.3",
"ts-mocha": "^8.0.0",
"ts-node": "^9.1.1",
"ts-node-dev": "^1.1.8",
"typescript": "^4.2.3",
"winston": "^3.3.3"
}
}
}
}

7
types/package.json Normal file
View File

@ -0,0 +1,7 @@
{
"name":"@accord/types",
"main":"main.ts",
"dependencies": {
"@accord/backend": "file:../backend"
}
}