Merge pull request #490 from developomp/master
Prettier format and link simplification
This commit is contained in:
commit
00fd55ed77
20
.github/workflows/docker-publish-api.yml
vendored
20
.github/workflows/docker-publish-api.yml
vendored
@ -3,34 +3,29 @@ name: docker-publish-api
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'api/**'
|
||||
- "api/**"
|
||||
|
||||
jobs:
|
||||
docker-api:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Cache Docker layers
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/.buildx-cache/api
|
||||
key: ${{ runner.os }}-buildx-api-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-api-
|
||||
-
|
||||
name: Login to DockerHub
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: ./api
|
||||
@ -38,8 +33,7 @@ jobs:
|
||||
tags: ${{ secrets.DOCKERHUB_TAGS_API }}
|
||||
cache-from: type=local,src=/tmp/.buildx-cache/api
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new/api
|
||||
-
|
||||
# Hackfix to cleanup cache; replace after buildx 0.6 and BuildKit 0.9 are GA
|
||||
- # Hackfix to cleanup cache; replace after buildx 0.6 and BuildKit 0.9 are GA
|
||||
# https://github.com/docker/build-push-action/pull/406#issuecomment-879184394
|
||||
name: Move cache fix
|
||||
run: |
|
||||
|
20
.github/workflows/docker-publish-cdn.yml
vendored
20
.github/workflows/docker-publish-cdn.yml
vendored
@ -3,34 +3,29 @@ name: docker-publish-cdn
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'cdn/**'
|
||||
- "cdn/**"
|
||||
|
||||
jobs:
|
||||
docker-cdn:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Cache Docker layers
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/.buildx-cache/cdn
|
||||
key: ${{ runner.os }}-buildx-cdn-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-cdn-
|
||||
-
|
||||
name: Login to DockerHub
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: ./cdn
|
||||
@ -38,8 +33,7 @@ jobs:
|
||||
tags: ${{ secrets.DOCKERHUB_TAGS_CDN }}
|
||||
cache-from: type=local,src=/tmp/.buildx-cache/cdn
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new/cdn
|
||||
-
|
||||
# Hackfix to cleanup cache; replace after buildx 0.6 and BuildKit 0.9 are GA
|
||||
- # Hackfix to cleanup cache; replace after buildx 0.6 and BuildKit 0.9 are GA
|
||||
# https://github.com/docker/build-push-action/pull/406#issuecomment-879184394
|
||||
name: Move cache fix
|
||||
run: |
|
||||
|
20
.github/workflows/docker-publish-gateway.yml
vendored
20
.github/workflows/docker-publish-gateway.yml
vendored
@ -3,34 +3,29 @@ name: docker-publish-gw
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'gateway/**'
|
||||
- "gateway/**"
|
||||
|
||||
jobs:
|
||||
docker-gw:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Cache Docker layers
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/.buildx-cache/gw
|
||||
key: ${{ runner.os }}-buildx-gw-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-gw-
|
||||
-
|
||||
name: Login to DockerHub
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: ./gateway
|
||||
@ -38,8 +33,7 @@ jobs:
|
||||
tags: ${{ secrets.DOCKERHUB_TAGS_GW }}
|
||||
cache-from: type=local,src=/tmp/.buildx-cache/gw
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new/gw
|
||||
-
|
||||
# Hackfix to cleanup cache; replace after buildx 0.6 and BuildKit 0.9 are GA
|
||||
- # Hackfix to cleanup cache; replace after buildx 0.6 and BuildKit 0.9 are GA
|
||||
# https://github.com/docker/build-push-action/pull/406#issuecomment-879184394
|
||||
name: Move cache fix
|
||||
run: |
|
||||
|
4
.prettierrc
Normal file
4
.prettierrc
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"tabWidth": 4,
|
||||
"useTabs": true
|
||||
}
|
14
README.md
14
README.md
@ -18,13 +18,13 @@
|
||||
|
||||
This repository contains:
|
||||
|
||||
- [Fosscord HTTP API Server](https://github.com/fosscord/fosscord-server/tree/master/api)
|
||||
- [WebSocket Gateway Server](https://github.com/fosscord/fosscord-server/tree/master/gateway)
|
||||
- [HTTP CDN Server](https://github.com/fosscord/fosscord-server/tree/master/cdn)
|
||||
- [Utility and Database Models](https://github.com/fosscord/fosscord-server/tree/master/util)
|
||||
- [RTC Server](https://github.com/fosscord/fosscord-server/tree/master/rtc)
|
||||
- [WebRTC Server](https://github.com/fosscord/fosscord-server/tree/master/webrtc)
|
||||
- [Admin Dashboard](https://github.com/fosscord/fosscord-server/tree/master/dashboard)
|
||||
- [Fosscord HTTP API Server](/api)
|
||||
- [WebSocket Gateway Server](/gateway)
|
||||
- [HTTP CDN Server](/cdn)
|
||||
- [Utility and Database Models](/util)
|
||||
- [RTC Server](/rtc)
|
||||
- [WebRTC Server](/webrtc)
|
||||
- [Admin Dashboard](/dashboard)
|
||||
|
||||
## [Resources](https://docs.fosscord.com/resources/)
|
||||
|
||||
|
8
api/.vscode/api-snippets.code-snippets
vendored
8
api/.vscode/api-snippets.code-snippets
vendored
@ -19,11 +19,7 @@
|
||||
"Route": {
|
||||
"scope": "typescript",
|
||||
"prefix": "route",
|
||||
"body": [
|
||||
"router.get(\"$1\", route({}), (req: Request, res: Response) => {",
|
||||
"\t$2",
|
||||
"});"
|
||||
],
|
||||
"body": ["router.get(\"$1\", route({}), (req: Request, res: Response) => {", "\t$2", "});"],
|
||||
"description": "An API endpoint"
|
||||
},
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -10,10 +10,7 @@ router.post("/", route({ permission: "MANAGE_MESSAGES" }), (req: Request, res: R
|
||||
type: 0,
|
||||
content: "",
|
||||
channel_id: "",
|
||||
author: {id: "",
|
||||
username: "",
|
||||
avatar: "",
|
||||
discriminator: "", public_flags: 64},
|
||||
author: { id: "", username: "", avatar: "", discriminator: "", public_flags: 64 },
|
||||
attachments: [],
|
||||
embeds: [],
|
||||
mentions: [],
|
||||
@ -23,8 +20,9 @@ router.post("/", route({ permission: "MANAGE_MESSAGES" }), (req: Request, res: R
|
||||
tts: false,
|
||||
timestamp: "",
|
||||
edited_timestamp: null,
|
||||
flags: 1, components: []}).status(200);
|
||||
flags: 1,
|
||||
components: []
|
||||
}).status(200);
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
|
@ -1,6 +1,16 @@
|
||||
import { Request, Response, Router } from "express";
|
||||
import { Channel, ChannelRecipientAddEvent, ChannelType, DiscordApiErrors, DmChannelDTO, emitEvent, PublicUserProjection, Recipient, User } from "@fosscord/util";
|
||||
import { route } from "@fosscord/api"
|
||||
import {
|
||||
Channel,
|
||||
ChannelRecipientAddEvent,
|
||||
ChannelType,
|
||||
DiscordApiErrors,
|
||||
DmChannelDTO,
|
||||
emitEvent,
|
||||
PublicUserProjection,
|
||||
Recipient,
|
||||
User
|
||||
} from "@fosscord/util";
|
||||
import { route } from "@fosscord/api";
|
||||
|
||||
const router: Router = Router();
|
||||
|
||||
@ -9,20 +19,17 @@ router.put("/:user_id", route({}), async (req: Request, res: Response) => {
|
||||
const channel = await Channel.findOneOrFail({ where: { id: channel_id }, relations: ["recipients"] });
|
||||
|
||||
if (channel.type !== ChannelType.GROUP_DM) {
|
||||
const recipients = [
|
||||
...channel.recipients!.map(r => r.user_id),
|
||||
user_id
|
||||
].unique()
|
||||
const recipients = [...channel.recipients!.map((r) => r.user_id), user_id].unique();
|
||||
|
||||
const new_channel = await Channel.createDMChannel(recipients, req.user_id)
|
||||
const new_channel = await Channel.createDMChannel(recipients, req.user_id);
|
||||
return res.status(201).json(new_channel);
|
||||
} else {
|
||||
if (channel.recipients!.map(r => r.user_id).includes(user_id)) {
|
||||
throw DiscordApiErrors.INVALID_RECIPIENT //TODO is this the right error?
|
||||
if (channel.recipients!.map((r) => r.user_id).includes(user_id)) {
|
||||
throw DiscordApiErrors.INVALID_RECIPIENT; //TODO is this the right error?
|
||||
}
|
||||
|
||||
channel.recipients!.push(new Recipient({ channel_id: channel_id, user_id: user_id }));
|
||||
await channel.save()
|
||||
await channel.save();
|
||||
|
||||
await emitEvent({
|
||||
event: "CHANNEL_CREATE",
|
||||
@ -31,10 +38,12 @@ router.put("/:user_id", route({}), async (req: Request, res: Response) => {
|
||||
});
|
||||
|
||||
await emitEvent({
|
||||
event: "CHANNEL_RECIPIENT_ADD", data: {
|
||||
event: "CHANNEL_RECIPIENT_ADD",
|
||||
data: {
|
||||
channel_id: channel_id,
|
||||
user: await User.findOneOrFail({ where: { id: user_id }, select: PublicUserProjection })
|
||||
}, channel_id: channel_id
|
||||
},
|
||||
channel_id: channel_id
|
||||
} as ChannelRecipientAddEvent);
|
||||
return res.sendStatus(204);
|
||||
}
|
||||
@ -44,13 +53,13 @@ router.delete("/:user_id", route({}), async (req: Request, res: Response) => {
|
||||
const { channel_id, user_id } = req.params;
|
||||
const channel = await Channel.findOneOrFail({ where: { id: channel_id }, relations: ["recipients"] });
|
||||
if (!(channel.type === ChannelType.GROUP_DM && (channel.owner_id === req.user_id || user_id === req.user_id)))
|
||||
throw DiscordApiErrors.MISSING_PERMISSIONS
|
||||
throw DiscordApiErrors.MISSING_PERMISSIONS;
|
||||
|
||||
if (!channel.recipients!.map(r => r.user_id).includes(user_id)) {
|
||||
throw DiscordApiErrors.INVALID_RECIPIENT //TODO is this the right error?
|
||||
if (!channel.recipients!.map((r) => r.user_id).includes(user_id)) {
|
||||
throw DiscordApiErrors.INVALID_RECIPIENT; //TODO is this the right error?
|
||||
}
|
||||
|
||||
await Channel.removeRecipientFromChannel(channel, user_id)
|
||||
await Channel.removeRecipientFromChannel(channel, user_id);
|
||||
|
||||
return res.sendStatus(204);
|
||||
});
|
||||
|
@ -3,7 +3,6 @@ import { Guild, Config } from "@fosscord/util";
|
||||
import { Router, Request, Response } from "express";
|
||||
import { route } from "@fosscord/api";
|
||||
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get("/", route({}), async (req: Request, res: Response) => {
|
||||
@ -12,7 +11,9 @@ router.get("/", route({}), async (req: Request, res: Response) => {
|
||||
// ! this only works using SQL querys
|
||||
// TODO: implement this with default typeorm query
|
||||
// const guilds = await Guild.find({ where: { features: "DISCOVERABLE" } }); //, take: Math.abs(Number(limit)) });
|
||||
const guilds = showAllGuilds ? await Guild.find({take: Math.abs(Number(limit || 20))}) : await Guild.find({ where: `"features" LIKE '%COMMUNITY%'`, take: Math.abs(Number(limit || 20)) });
|
||||
const guilds = showAllGuilds
|
||||
? await Guild.find({ take: Math.abs(Number(limit || 20)) })
|
||||
: await Guild.find({ where: `"features" LIKE '%COMMUNITY%'`, take: Math.abs(Number(limit || 20)) });
|
||||
res.send({ guilds: guilds });
|
||||
});
|
||||
|
||||
|
@ -12,7 +12,7 @@ export interface GatewayBotResponse {
|
||||
remaining: number;
|
||||
reset_after: number;
|
||||
max_concurrency: number;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const options: RouteOptions = {
|
||||
|
@ -18,7 +18,8 @@ router.get("/", route({}), async (req: Request, res: Response) => {
|
||||
currency: "eur",
|
||||
price: 4199,
|
||||
price_tier: null
|
||||
}]).status(200);
|
||||
}
|
||||
]).status(200);
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
@ -4,10 +4,127 @@ import { route } from "@fosscord/api";
|
||||
const router: Router = Router();
|
||||
|
||||
const skus = new Map([
|
||||
["521842865731534868", [{"id": "511651856145973248", "name": "Premium Monthly (Legacy)", "interval": 1, "interval_count": 1, "tax_inclusive": true, "sku_id": "521842865731534868", "currency": "usd", "price": 0, "price_tier": null}, {"id": "511651860671627264", "name": "Premium Yearly (Legacy)", "interval": 2, "interval_count": 1, "tax_inclusive": true, "sku_id": "521842865731534868", "currency": "usd", "price": 0, "price_tier": null}]],
|
||||
["521846918637420545", [{"id": "511651871736201216", "name": "Premium Classic Monthly", "interval": 1, "interval_count": 1, "tax_inclusive": true, "sku_id": "521846918637420545", "currency": "usd", "price": 0, "price_tier": null}, {"id": "511651876987469824", "name": "Premium Classic Yearly", "interval": 2, "interval_count": 1, "tax_inclusive": true, "sku_id": "521846918637420545", "currency": "usd", "price": 0, "price_tier": null}]],
|
||||
["521847234246082599", [{"id": "642251038925127690", "name": "Premium Quarterly", "interval": 1, "interval_count": 3, "tax_inclusive": true, "sku_id": "521847234246082599", "currency": "usd", "price": 0, "price_tier": null}, {"id": "511651880837840896", "name": "Premium Monthly", "interval": 1, "interval_count": 1, "tax_inclusive": true, "sku_id": "521847234246082599", "currency": "usd", "price": 0, "price_tier": null}, {"id": "511651885459963904", "name": "Premium Yearly", "interval": 2, "interval_count": 1, "tax_inclusive": true, "sku_id": "521847234246082599", "currency": "usd", "price": 0, "price_tier": null}]],
|
||||
["590663762298667008", [{"id": "590665532894740483", "name": "Server Boost Monthly", "interval": 1, "interval_count": 1, "tax_inclusive": true, "sku_id": "590663762298667008", "discount_price": 0, "currency": "usd", "price": 0, "price_tier": null}, {"id": "590665538238152709", "name": "Server Boost Yearly", "interval": 2, "interval_count": 1, "tax_inclusive": true, "sku_id": "590663762298667008", "discount_price": 0, "currency": "usd", "price": 0, "price_tier": null}]],
|
||||
[
|
||||
"521842865731534868",
|
||||
[
|
||||
{
|
||||
id: "511651856145973248",
|
||||
name: "Premium Monthly (Legacy)",
|
||||
interval: 1,
|
||||
interval_count: 1,
|
||||
tax_inclusive: true,
|
||||
sku_id: "521842865731534868",
|
||||
currency: "usd",
|
||||
price: 0,
|
||||
price_tier: null
|
||||
},
|
||||
{
|
||||
id: "511651860671627264",
|
||||
name: "Premium Yearly (Legacy)",
|
||||
interval: 2,
|
||||
interval_count: 1,
|
||||
tax_inclusive: true,
|
||||
sku_id: "521842865731534868",
|
||||
currency: "usd",
|
||||
price: 0,
|
||||
price_tier: null
|
||||
}
|
||||
]
|
||||
],
|
||||
[
|
||||
"521846918637420545",
|
||||
[
|
||||
{
|
||||
id: "511651871736201216",
|
||||
name: "Premium Classic Monthly",
|
||||
interval: 1,
|
||||
interval_count: 1,
|
||||
tax_inclusive: true,
|
||||
sku_id: "521846918637420545",
|
||||
currency: "usd",
|
||||
price: 0,
|
||||
price_tier: null
|
||||
},
|
||||
{
|
||||
id: "511651876987469824",
|
||||
name: "Premium Classic Yearly",
|
||||
interval: 2,
|
||||
interval_count: 1,
|
||||
tax_inclusive: true,
|
||||
sku_id: "521846918637420545",
|
||||
currency: "usd",
|
||||
price: 0,
|
||||
price_tier: null
|
||||
}
|
||||
]
|
||||
],
|
||||
[
|
||||
"521847234246082599",
|
||||
[
|
||||
{
|
||||
id: "642251038925127690",
|
||||
name: "Premium Quarterly",
|
||||
interval: 1,
|
||||
interval_count: 3,
|
||||
tax_inclusive: true,
|
||||
sku_id: "521847234246082599",
|
||||
currency: "usd",
|
||||
price: 0,
|
||||
price_tier: null
|
||||
},
|
||||
{
|
||||
id: "511651880837840896",
|
||||
name: "Premium Monthly",
|
||||
interval: 1,
|
||||
interval_count: 1,
|
||||
tax_inclusive: true,
|
||||
sku_id: "521847234246082599",
|
||||
currency: "usd",
|
||||
price: 0,
|
||||
price_tier: null
|
||||
},
|
||||
{
|
||||
id: "511651885459963904",
|
||||
name: "Premium Yearly",
|
||||
interval: 2,
|
||||
interval_count: 1,
|
||||
tax_inclusive: true,
|
||||
sku_id: "521847234246082599",
|
||||
currency: "usd",
|
||||
price: 0,
|
||||
price_tier: null
|
||||
}
|
||||
]
|
||||
],
|
||||
[
|
||||
"590663762298667008",
|
||||
[
|
||||
{
|
||||
id: "590665532894740483",
|
||||
name: "Server Boost Monthly",
|
||||
interval: 1,
|
||||
interval_count: 1,
|
||||
tax_inclusive: true,
|
||||
sku_id: "590663762298667008",
|
||||
discount_price: 0,
|
||||
currency: "usd",
|
||||
price: 0,
|
||||
price_tier: null
|
||||
},
|
||||
{
|
||||
id: "590665538238152709",
|
||||
name: "Server Boost Yearly",
|
||||
interval: 2,
|
||||
interval_count: 1,
|
||||
tax_inclusive: true,
|
||||
sku_id: "590663762298667008",
|
||||
discount_price: 0,
|
||||
currency: "usd",
|
||||
price: 0,
|
||||
price_tier: null
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
router.get("/", route({}), async (req: Request, res: Response) => {
|
||||
|
@ -5,7 +5,7 @@ const router = Router();
|
||||
|
||||
router.get("/", route({}), (req: Request, res: Response) => {
|
||||
// TODO:
|
||||
res.json([]).status(200)
|
||||
res.json([]).status(200);
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
@ -5,7 +5,7 @@ const router = Router();
|
||||
|
||||
router.get("/", route({}), (req: Request, res: Response) => {
|
||||
// TODO:
|
||||
res.json([]).status(200)
|
||||
res.json([]).status(200);
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
@ -5,8 +5,11 @@ import { route } from "@fosscord/api";
|
||||
const router: Router = Router();
|
||||
|
||||
router.get("/", route({}), async (req: Request, res: Response) => {
|
||||
const recipients = await Recipient.find({ where: { user_id: req.user_id, closed: false }, relations: ["channel", "channel.recipients"] });
|
||||
res.json(await Promise.all(recipients.map(r => DmChannelDTO.from(r.channel, [req.user_id]))));
|
||||
const recipients = await Recipient.find({
|
||||
where: { user_id: req.user_id, closed: false },
|
||||
relations: ["channel", "channel.recipients"]
|
||||
});
|
||||
res.json(await Promise.all(recipients.map((r) => DmChannelDTO.from(r.channel, [req.user_id]))));
|
||||
});
|
||||
|
||||
export interface DmChannelCreateSchema {
|
||||
|
@ -11,7 +11,8 @@ router.get("/", route({}), (req: Request, res: Response) => {
|
||||
communication: true,
|
||||
tips: false,
|
||||
updates_and_announcements: false,
|
||||
recommendations_and_events: false },
|
||||
recommendations_and_events: false
|
||||
},
|
||||
initialized: false
|
||||
}).status(200);
|
||||
});
|
||||
|
@ -81,7 +81,6 @@ export function getIpAdress(req: Request): string {
|
||||
return req.headers[Config.get().security.forwadedFor] || req.socket.remoteAddress;
|
||||
}
|
||||
|
||||
|
||||
export function distanceBetweenLocations(loc1: any, loc2: any): number {
|
||||
return distanceBetweenCoords(loc1.latitude, loc1.longitude, loc2.latitude, loc2.longitude);
|
||||
}
|
||||
@ -90,9 +89,7 @@ export function distanceBetweenLocations(loc1: any, loc2: any): number {
|
||||
function distanceBetweenCoords(lat1: number, lon1: number, lat2: number, lon2: number) {
|
||||
const p = 0.017453292519943295; // Math.PI / 180
|
||||
const c = Math.cos;
|
||||
const a = 0.5 - c((lat2 - lat1) * p) / 2 +
|
||||
c(lat1 * p) * c(lat2 * p) *
|
||||
(1 - c((lon2 - lon1) * p)) / 2;
|
||||
const a = 0.5 - c((lat2 - lat1) * p) / 2 + (c(lat1 * p) * c(lat2 * p) * (1 - c((lon2 - lon1) * p))) / 2;
|
||||
|
||||
return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
|
||||
}
|
4
bundle/.prettierrc
Normal file
4
bundle/.prettierrc
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"useTabs": true,
|
||||
"tabWidth": 4
|
||||
}
|
@ -18,15 +18,24 @@ if (argv.includes("clean")) {
|
||||
});
|
||||
}
|
||||
|
||||
fse.copySync(path.join(__dirname, "..", "..", "api", "assets"), path.join(__dirname, "..", "dist", "api", "assets"));
|
||||
fse.copySync(
|
||||
path.join(__dirname, "..", "..", "api", "assets"),
|
||||
path.join(__dirname, "..", "dist", "api", "assets")
|
||||
);
|
||||
fse.copySync(
|
||||
path.join(__dirname, "..", "..", "api", "client_test"),
|
||||
path.join(__dirname, "..", "dist", "api", "client_test")
|
||||
);
|
||||
fse.copySync(path.join(__dirname, "..", "..", "api", "locales"), path.join(__dirname, "..", "dist", "api", "locales"));
|
||||
fse.copySync(
|
||||
path.join(__dirname, "..", "..", "api", "locales"),
|
||||
path.join(__dirname, "..", "dist", "api", "locales")
|
||||
);
|
||||
dirs.forEach((a) => {
|
||||
fse.copySync("../" + a + "/src", "dist/" + a + "/src");
|
||||
if (verbose) console.log(`Copied ${"../" + a + "/dist"} -> ${"dist/" + a + "/src"}!`);
|
||||
if (verbose)
|
||||
console.log(
|
||||
`Copied ${"../" + a + "/dist"} -> ${"dist/" + a + "/src"}!`
|
||||
);
|
||||
});
|
||||
|
||||
console.log("Copying src files done");
|
||||
@ -35,7 +44,14 @@ console.log("Compiling src files ...");
|
||||
console.log(
|
||||
execSync(
|
||||
'node "' +
|
||||
path.join(__dirname, "..", "node_modules", "typescript", "lib", "tsc.js") +
|
||||
path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"node_modules",
|
||||
"typescript",
|
||||
"lib",
|
||||
"tsc.js"
|
||||
) +
|
||||
'" -p "' +
|
||||
path.join(__dirname, "..") +
|
||||
'"',
|
||||
|
@ -5,10 +5,19 @@ const parts = ["api", "util", "cdn", "gateway"];
|
||||
const bundle = require("../package.json");
|
||||
|
||||
for (const part of parts) {
|
||||
const { devDependencies, dependencies } = require(path.join("..", "..", part, "package.json"));
|
||||
const { devDependencies, dependencies } = require(path.join(
|
||||
"..",
|
||||
"..",
|
||||
part,
|
||||
"package.json"
|
||||
));
|
||||
bundle.devDependencies = { ...bundle.devDependencies, ...devDependencies };
|
||||
bundle.dependencies = { ...bundle.dependencies, ...dependencies };
|
||||
delete bundle.dependencies["@fosscord/util"];
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.join(__dirname, "..", "package.json"), JSON.stringify(bundle, null, "\t"), { encoding: "utf8" });
|
||||
fs.writeFileSync(
|
||||
path.join(__dirname, "..", "package.json"),
|
||||
JSON.stringify(bundle, null, "\t"),
|
||||
{ encoding: "utf8" }
|
||||
);
|
||||
|
@ -8,7 +8,9 @@
|
||||
"incremental": false /* Enable incremental compilation */,
|
||||
"target": "ES6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
||||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
||||
"lib": ["ES2021"] /* Specify library files to be included in the compilation. */,
|
||||
"lib": [
|
||||
"ES2021"
|
||||
] /* Specify library files to be included in the compilation. */,
|
||||
"allowJs": true /* Allow javascript files to be compiled. */,
|
||||
"checkJs": true /* Report errors in .js files. */,
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
@ -46,7 +48,9 @@
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
"types": ["node"] /* Type declaration files to be included in compilation. */,
|
||||
"types": [
|
||||
"node"
|
||||
] /* Type declaration files to be included in compilation. */,
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
|
@ -1,20 +1,26 @@
|
||||
# Fosscord-CDN
|
||||
|
||||
CDN for Fosscord
|
||||
|
||||
## Run localy:
|
||||
|
||||
```
|
||||
npm i
|
||||
node dist/
|
||||
```
|
||||
|
||||
## Endpoints:
|
||||
|
||||
### POST `/attachments/<filename>`
|
||||
|
||||
```
|
||||
Content-Type: form-data
|
||||
|
||||
attachment: File (binary-data)
|
||||
```
|
||||
|
||||
##### Returns:
|
||||
|
||||
```
|
||||
{
|
||||
"success": boolean, // true
|
||||
@ -23,20 +29,28 @@ attachment: File (binary-data)
|
||||
"filename": string // "lakdoiauej.png"
|
||||
}
|
||||
```
|
||||
|
||||
### GET `/attachments/<id>/<filename>`
|
||||
|
||||
```
|
||||
requests image from database with given <id> and <filename>
|
||||
```
|
||||
|
||||
##### Returns:
|
||||
|
||||
```
|
||||
Content-Type: image/<imageType(png,img,gif)>
|
||||
Image
|
||||
```
|
||||
|
||||
### DELETE `/attachments/<id>/<filename>`
|
||||
|
||||
```
|
||||
deletes database entry
|
||||
```
|
||||
|
||||
##### Returns:
|
||||
|
||||
```
|
||||
Content-Type: application/json
|
||||
|
||||
@ -49,6 +63,7 @@ Content-Type: application/json
|
||||
<hr>
|
||||
|
||||
_(endpoints for crawler):_
|
||||
|
||||
### POST `/external`
|
||||
|
||||
```
|
||||
@ -59,7 +74,9 @@ Content-Type: application/json
|
||||
body:
|
||||
{"url": URL} // "https://discord.com"
|
||||
```
|
||||
|
||||
##### Returns:
|
||||
|
||||
```
|
||||
Content-Type: application/json
|
||||
|
||||
@ -72,17 +89,23 @@ Content-Type: application/json
|
||||
"ogType": string // "website"
|
||||
}
|
||||
```
|
||||
|
||||
### GET `/external/<id>/<filename>`
|
||||
|
||||
- requests cached crawled image
|
||||
|
||||
```
|
||||
url-params:
|
||||
:id // aHR0cHM6Ly9kaXNjb3JkLmNvbQ==
|
||||
:filename // discord.png
|
||||
```
|
||||
|
||||
```
|
||||
/external/aHR0cHM6Ly9kaXNjb3JkLmNvbQ==/discord.png
|
||||
```
|
||||
|
||||
##### Returns:
|
||||
|
||||
```
|
||||
Content-Type: image/<imageType(png,img,gif)>
|
||||
Image
|
||||
|
@ -5,30 +5,30 @@ import { Storage } from "./Storage";
|
||||
const readableToBuffer = (readable: Readable): Promise<Buffer> =>
|
||||
new Promise((resolve, reject) => {
|
||||
const chunks: Buffer[] = [];
|
||||
readable.on('data', chunk => chunks.push(chunk));
|
||||
readable.on('error', reject);
|
||||
readable.on('end', () => resolve(Buffer.concat(chunks)));
|
||||
readable.on("data", (chunk) => chunks.push(chunk));
|
||||
readable.on("error", reject);
|
||||
readable.on("end", () => resolve(Buffer.concat(chunks)));
|
||||
});
|
||||
|
||||
export class S3Storage implements Storage {
|
||||
public constructor(
|
||||
private client: S3,
|
||||
private bucket: string,
|
||||
private basePath?: string,
|
||||
private basePath?: string
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Always return a string, to ensure consistency.
|
||||
*/
|
||||
get bucketBasePath() {
|
||||
return this.basePath ?? '';
|
||||
return this.basePath ?? "";
|
||||
}
|
||||
|
||||
async set(path: string, data: Buffer): Promise<void> {
|
||||
await this.client.putObject({
|
||||
Bucket: this.bucket,
|
||||
Key: `${this.bucketBasePath}${path}`,
|
||||
Body: data
|
||||
Body: data,
|
||||
});
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ export class S3Storage implements Storage {
|
||||
try {
|
||||
const s3Object = await this.client.getObject({
|
||||
Bucket: this.bucket,
|
||||
Key: `${this.bucketBasePath ?? ''}${path}`
|
||||
Key: `${this.bucketBasePath ?? ""}${path}`,
|
||||
});
|
||||
|
||||
if (!s3Object.Body) return null;
|
||||
@ -54,7 +54,7 @@ export class S3Storage implements Storage {
|
||||
async delete(path: string): Promise<void> {
|
||||
await this.client.deleteObject({
|
||||
Bucket: this.bucket,
|
||||
Key: `${this.bucketBasePath}${path}`
|
||||
Key: `${this.bucketBasePath}${path}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { FileStorage } from "./FileStorage";
|
||||
import path from "path";
|
||||
import fse from "fs-extra";
|
||||
import { bgCyan, black } from "nanocolors";
|
||||
import { S3 } from '@aws-sdk/client-s3';
|
||||
import { S3 } from "@aws-sdk/client-s3";
|
||||
import { S3Storage } from "./S3Storage";
|
||||
process.cwd();
|
||||
|
||||
@ -27,17 +27,20 @@ if (process.env.STORAGE_PROVIDER === "file" || !process.env.STORAGE_PROVIDER) {
|
||||
|
||||
storage = new FileStorage();
|
||||
} else if (process.env.STORAGE_PROVIDER === "s3") {
|
||||
const
|
||||
region = process.env.STORAGE_REGION,
|
||||
const region = process.env.STORAGE_REGION,
|
||||
bucket = process.env.STORAGE_BUCKET;
|
||||
|
||||
if (!region) {
|
||||
console.error(`[CDN] You must provide a region when using the S3 storage provider.`);
|
||||
console.error(
|
||||
`[CDN] You must provide a region when using the S3 storage provider.`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!bucket) {
|
||||
console.error(`[CDN] You must provide a bucket when using the S3 storage provider.`);
|
||||
console.error(
|
||||
`[CDN] You must provide a bucket when using the S3 storage provider.`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@ -45,7 +48,9 @@ if (process.env.STORAGE_PROVIDER === "file" || !process.env.STORAGE_PROVIDER) {
|
||||
let location = process.env.STORAGE_LOCATION;
|
||||
|
||||
if (!location) {
|
||||
console.warn(`[CDN] STORAGE_LOCATION unconfigured for S3 provider, defaulting to the bucket root...`);
|
||||
console.warn(
|
||||
`[CDN] STORAGE_LOCATION unconfigured for S3 provider, defaulting to the bucket root...`
|
||||
);
|
||||
location = undefined;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,12 @@ if (!process.env.STORAGE_PROVIDER) process.env.STORAGE_PROVIDER = "file";
|
||||
if (process.env.STORAGE_PROVIDER === "file") {
|
||||
if (process.env.STORAGE_LOCATION) {
|
||||
if (!process.env.STORAGE_LOCATION.startsWith("/")) {
|
||||
process.env.STORAGE_LOCATION = path.join(__dirname, "..", process.env.STORAGE_LOCATION, "/");
|
||||
process.env.STORAGE_LOCATION = path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
process.env.STORAGE_LOCATION,
|
||||
"/"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
process.env.STORAGE_LOCATION = path.join(__dirname, "..", "files", "/");
|
||||
@ -67,7 +72,9 @@ describe("/attachments", () => {
|
||||
.set({ signature: Config.get().security.requestSignature })
|
||||
.attach("file", __dirname + "/antman.jpg");
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.headers["content-type"]).toEqual(expect.stringContaining("json"));
|
||||
expect(response.headers["content-type"]).toEqual(
|
||||
expect.stringContaining("json")
|
||||
);
|
||||
expect(response.body.url).toBeDefined();
|
||||
});
|
||||
});
|
||||
@ -79,7 +86,9 @@ describe("/attachments", () => {
|
||||
.post("/attachments/123456789")
|
||||
.set({ signature: Config.get().security.requestSignature })
|
||||
.attach("file", __dirname + "/antman.jpg");
|
||||
request.get(response.body.url.replace("http://localhost:3003", "")).then((x) => {
|
||||
request
|
||||
.get(response.body.url.replace("http://localhost:3003", ""))
|
||||
.then((x) => {
|
||||
expect(x.statusCode).toBe(200);
|
||||
});
|
||||
});
|
||||
@ -92,7 +101,11 @@ describe("/attachments", () => {
|
||||
.post("/attachments/123456789")
|
||||
.set({ signature: Config.get().security.requestSignature })
|
||||
.attach("file", __dirname + "/antman.jpg");
|
||||
request.delete(response.body.url.replace("http://localhost:3003", "")).then((x) => {
|
||||
request
|
||||
.delete(
|
||||
response.body.url.replace("http://localhost:3003", "")
|
||||
)
|
||||
.then((x) => {
|
||||
expect(x.body.success).toBeDefined();
|
||||
});
|
||||
});
|
||||
@ -123,7 +136,9 @@ describe("/avatars", () => {
|
||||
.set({ signature: Config.get().security.requestSignature })
|
||||
.attach("file", __dirname + "/antman.jpg");
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.headers["content-type"]).toEqual(expect.stringContaining("json"));
|
||||
expect(response.headers["content-type"]).toEqual(
|
||||
expect.stringContaining("json")
|
||||
);
|
||||
expect(response.body.url).toBeDefined();
|
||||
});
|
||||
});
|
||||
@ -135,7 +150,9 @@ describe("/avatars", () => {
|
||||
.post("/avatars/123456789")
|
||||
.set({ signature: Config.get().security.requestSignature })
|
||||
.attach("file", __dirname + "/antman.jpg");
|
||||
request.get(response.body.url.replace("http://localhost:3003", "")).then((x) => {
|
||||
request
|
||||
.get(response.body.url.replace("http://localhost:3003", ""))
|
||||
.then((x) => {
|
||||
expect(x.statusCode).toBe(200);
|
||||
});
|
||||
});
|
||||
@ -148,7 +165,11 @@ describe("/avatars", () => {
|
||||
.post("/avatars/123456789")
|
||||
.set({ signature: Config.get().security.requestSignature })
|
||||
.attach("file", __dirname + "/antman.jpg");
|
||||
request.delete(response.body.url.replace("http://localhost:3003", "")).then((x) => {
|
||||
request
|
||||
.delete(
|
||||
response.body.url.replace("http://localhost:3003", "")
|
||||
)
|
||||
.then((x) => {
|
||||
expect(x.body.success).toBeDefined();
|
||||
});
|
||||
});
|
||||
@ -177,9 +198,13 @@ describe("/external", () => {
|
||||
const response = await request
|
||||
.post("/external")
|
||||
.set({ signature: Config.get().security.requestSignature })
|
||||
.send({ url: "https://i.ytimg.com/vi_webp/TiXzhQr5AUc/mqdefault.webp" });
|
||||
.send({
|
||||
url: "https://i.ytimg.com/vi_webp/TiXzhQr5AUc/mqdefault.webp",
|
||||
});
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.headers["content-type"]).toEqual(expect.stringContaining("json"));
|
||||
expect(response.headers["content-type"]).toEqual(
|
||||
expect.stringContaining("json")
|
||||
);
|
||||
expect(response.body.id).toBeDefined();
|
||||
});
|
||||
});
|
||||
@ -201,7 +226,9 @@ describe("/external", () => {
|
||||
let response = await request
|
||||
.post("/external")
|
||||
.set({ signature: Config.get().security.requestSignature })
|
||||
.send({ url: "https://i.ytimg.com/vi_webp/TiXzhQr5AUc/mqdefault.webp" });
|
||||
.send({
|
||||
url: "https://i.ytimg.com/vi_webp/TiXzhQr5AUc/mqdefault.webp",
|
||||
});
|
||||
request.get(`external/${response.body.id}`).then((x) => {
|
||||
expect(x.statusCode).toBe(200);
|
||||
});
|
||||
|
@ -7,7 +7,10 @@
|
||||
"incremental": true /* Enable incremental compilation */,
|
||||
"target": "ES6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
||||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
||||
"lib": ["ES2015", "dom"] /* Specify library files to be included in the compilation. */,
|
||||
"lib": [
|
||||
"ES2015",
|
||||
"dom"
|
||||
] /* Specify library files to be included in the compilation. */,
|
||||
"allowJs": true /* Allow javascript files to be compiled. */,
|
||||
"checkJs": true /* Report errors in .js files. */,
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
@ -48,7 +51,9 @@
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
"types": ["node"] /* Type declaration files to be included in compilation. */,
|
||||
"types": [
|
||||
"node"
|
||||
] /* Type declaration files to be included in compilation. */,
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
|
@ -7,5 +7,7 @@ export function genVoiceToken() {
|
||||
}
|
||||
|
||||
function genRanHex(size: number) {
|
||||
return [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join("");
|
||||
return [...Array(size)]
|
||||
.map(() => Math.floor(Math.random() * 16).toString(16))
|
||||
.join("");
|
||||
}
|
||||
|
@ -8,7 +8,11 @@
|
||||
"incremental": true /* Enable incremental compilation */,
|
||||
"target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
||||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
||||
"lib": ["ES2015", "ES2020.BigInt", "DOM"] /* Specify library files to be included in the compilation. */,
|
||||
"lib": [
|
||||
"ES2015",
|
||||
"ES2020.BigInt",
|
||||
"DOM"
|
||||
] /* Specify library files to be included in the compilation. */,
|
||||
"allowJs": true /* Allow javascript files to be compiled. */,
|
||||
"checkJs": true /* Report errors in .js files. */,
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
@ -48,7 +52,9 @@
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
"types": ["node"] /* Type declaration files to be included in compilation. */,
|
||||
"types": [
|
||||
"node"
|
||||
] /* Type declaration files to be included in compilation. */,
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
|
@ -12,24 +12,30 @@ export class DmChannelDTO {
|
||||
type: number;
|
||||
|
||||
static async from(channel: Channel, excluded_recipients: string[] = [], origin_channel_id?: string) {
|
||||
const obj = new DmChannelDTO()
|
||||
obj.icon = channel.icon || null
|
||||
obj.id = channel.id
|
||||
obj.last_message_id = channel.last_message_id || null
|
||||
obj.name = channel.name || null
|
||||
obj.origin_channel_id = origin_channel_id || null
|
||||
obj.owner_id = channel.owner_id
|
||||
obj.type = channel.type
|
||||
obj.recipients = (await Promise.all(channel.recipients!.filter(r => !excluded_recipients.includes(r.user_id)).map(async r => {
|
||||
return await User.findOneOrFail({ where: { id: r.user_id }, select: PublicUserProjection })
|
||||
}))).map(u => new MinimalPublicUserDTO(u))
|
||||
return obj
|
||||
const obj = new DmChannelDTO();
|
||||
obj.icon = channel.icon || null;
|
||||
obj.id = channel.id;
|
||||
obj.last_message_id = channel.last_message_id || null;
|
||||
obj.name = channel.name || null;
|
||||
obj.origin_channel_id = origin_channel_id || null;
|
||||
obj.owner_id = channel.owner_id;
|
||||
obj.type = channel.type;
|
||||
obj.recipients = (
|
||||
await Promise.all(
|
||||
channel
|
||||
.recipients!.filter((r) => !excluded_recipients.includes(r.user_id))
|
||||
.map(async (r) => {
|
||||
return await User.findOneOrFail({ where: { id: r.user_id }, select: PublicUserProjection });
|
||||
})
|
||||
)
|
||||
).map((u) => new MinimalPublicUserDTO(u));
|
||||
return obj;
|
||||
}
|
||||
|
||||
excludedRecipients(excluded_recipients: string[]): DmChannelDTO {
|
||||
return {
|
||||
...this,
|
||||
recipients: this.recipients.filter(r => !excluded_recipients.includes(r.id))
|
||||
}
|
||||
recipients: this.recipients.filter((r) => !excluded_recipients.includes(r.id)),
|
||||
};
|
||||
}
|
||||
}
|
@ -8,10 +8,10 @@ export class MinimalPublicUserDTO {
|
||||
username: string;
|
||||
|
||||
constructor(user: User) {
|
||||
this.avatar = user.avatar
|
||||
this.discriminator = user.discriminator
|
||||
this.id = user.id
|
||||
this.public_flags = user.public_flags
|
||||
this.username = user.username
|
||||
this.avatar = user.avatar;
|
||||
this.discriminator = user.discriminator;
|
||||
this.id = user.id;
|
||||
this.public_flags = user.public_flags;
|
||||
this.username = user.username;
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ export class Migration extends BaseClassWithoutId {
|
||||
@PrimaryIdAutoGenerated()
|
||||
id: number;
|
||||
|
||||
@Column({ type: 'bigint' })
|
||||
@Column({ type: "bigint" })
|
||||
timestamp: number;
|
||||
|
||||
@Column()
|
||||
|
@ -9,7 +9,8 @@ export class ApiError extends Error {
|
||||
}
|
||||
|
||||
withDefaultParams(): ApiError {
|
||||
if (this.defaultParams) return new ApiError(applyParamsToString(this.message, this.defaultParams), this.code, this.httpStatus);
|
||||
if (this.defaultParams)
|
||||
return new ApiError(applyParamsToString(this.message, this.defaultParams), this.code, this.httpStatus);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
export function containsAll(arr: any[], target: any[]) {
|
||||
return target.every(v => arr.includes(v));
|
||||
return target.every((v) => arr.includes(v));
|
||||
}
|
@ -8,9 +8,9 @@ export function FieldErrors(fields: Record<string, { code?: string; message: str
|
||||
_errors: [
|
||||
{
|
||||
message,
|
||||
code: code || "BASE_TYPE_INVALID"
|
||||
}
|
||||
]
|
||||
code: code || "BASE_TYPE_INVALID",
|
||||
},
|
||||
],
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ export class Rights extends BitField {
|
||||
INVITE_USERS: BitFlag(29), // can create user-specific invites in the guilds that they have INVITE_USERS
|
||||
SELF_DELETE_DISABLE: BitFlag(30), // can disable/delete own account
|
||||
DEBTABLE: BitFlag(31), // can use pay-to-use features
|
||||
CREDITABLE: BitFlag(32) // can receive money from monetisation related features
|
||||
CREDITABLE: BitFlag(32), // can receive money from monetisation related features
|
||||
};
|
||||
|
||||
any(permission: RightResolvable, checkOperator = true) {
|
||||
|
@ -1,2 +1,3 @@
|
||||
# fosscord-rtc-js
|
||||
|
||||
A javascript fosscord webrtc server for voice and video communication
|
||||
|
@ -23,7 +23,11 @@ export class Server {
|
||||
ssrc: 1,
|
||||
ip: "127.0.0.1",
|
||||
port: 3004,
|
||||
modes: ["xsalsa20_poly1305", "xsalsa20_poly1305_suffix", "xsalsa20_poly1305_lite"],
|
||||
modes: [
|
||||
"xsalsa20_poly1305",
|
||||
"xsalsa20_poly1305_suffix",
|
||||
"xsalsa20_poly1305_lite",
|
||||
],
|
||||
heartbeat_interval: 1,
|
||||
},
|
||||
})
|
||||
|
@ -7,7 +7,9 @@
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "ESNext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
||||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
||||
"lib": ["ES2021"] /* Specify library files to be included in the compilation. */,
|
||||
"lib": [
|
||||
"ES2021"
|
||||
] /* Specify library files to be included in the compilation. */,
|
||||
"allowJs": true /* Allow javascript files to be compiled. */,
|
||||
"checkJs": true /* Report errors in .js files. */,
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
@ -45,7 +47,9 @@
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
"types": ["node"] /* Type declaration files to be included in compilation. */,
|
||||
"types": [
|
||||
"node"
|
||||
] /* Type declaration files to be included in compilation. */,
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user