mirror of
https://github.com/byulmaru/quesdon
synced 2024-11-27 06:18:02 +09:00
Merge branch 'misskey-support' into 'master'
Misskey support Closes #2 See merge request chocological00/quesdon!3
This commit is contained in:
commit
05fa99dea8
@ -1,25 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": false,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
@ -3,10 +3,13 @@ import Router from 'koa-router';
|
||||
import fetch from 'node-fetch';
|
||||
import parseLinkHeader, { Link, Links } from 'parse-link-header';
|
||||
import { Account } from 'megalodon';
|
||||
import { User as MisskeyUser } from '../../utils/misskey_entities/user';
|
||||
import { Following } from '../../utils/misskey_entities/following';
|
||||
import { oneLineTrim, stripIndents } from 'common-tags';
|
||||
import { QUESTION_TEXT_MAX_LENGTH } from '../../../common/const';
|
||||
import { BASE_URL, NOTICE_ACCESS_TOKEN, PUSHBULLET_CLIENT_ID, PUSHBULLET_CLIENT_SECRET } from '../../config';
|
||||
import { Question, User } from '../../db/index';
|
||||
import detectInstance from '../../utils/detectInstance';
|
||||
|
||||
const router = new Router();
|
||||
|
||||
@ -24,8 +27,6 @@ router.get('/verify_credentials', async (ctx: Koa.ParameterizedContext): Promise
|
||||
|
||||
router.get('/followers', async (ctx: Koa.ParameterizedContext): Promise<never|void|{}> =>
|
||||
{
|
||||
if (null === /^\d+$/.exec(ctx.query.max_id || '0'))
|
||||
return ctx.throw('max_id is num only', 400);
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
@ -37,10 +38,46 @@ router.get('/followers', async (ctx: Koa.ParameterizedContext): Promise<never|vo
|
||||
if (user.hostName === 'twitter.com')
|
||||
return ctx.body = { max_id: undefined, accounts: [] };
|
||||
|
||||
// TODO: add logic for misskey
|
||||
// mastodon
|
||||
const instanceUrl = 'https://' + user.acct.split('@')[1];
|
||||
const myInfo = await fetch(instanceUrl + '/api/v1/accounts/verify_credentials',
|
||||
const instanceType = await detectInstance(instanceUrl);
|
||||
|
||||
if (instanceType === 'misskey')
|
||||
{
|
||||
// misskey
|
||||
const fetchOptions =
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
};
|
||||
|
||||
const myInfo: MisskeyUser = await fetch(`${instanceUrl}/api/i`,
|
||||
Object.assign({}, fetchOptions,
|
||||
{
|
||||
body: JSON.stringify( { i: user.accessToken })
|
||||
})).then(r => r.json());
|
||||
const body: { i: string; userId: string; limit: number; untilId?: string } =
|
||||
{
|
||||
i: user.accessToken,
|
||||
userId: myInfo.id,
|
||||
limit: 80
|
||||
};
|
||||
if (ctx.query.max_id)
|
||||
body.untilId = ctx.query.max_id;
|
||||
const followersRaw: Following[] = await fetch(`${instanceUrl}/api/users/followers`,
|
||||
Object.assign({}, fetchOptions, { body: body })).then(r => r.json());
|
||||
const followers = followersRaw
|
||||
.map(follower => `${follower.follower?.username}@${follower.follower?.host ?? user.acct.split('@')[1]}`.toLowerCase());
|
||||
const followersObject = await User.find({acctLower: {$in: followers}});
|
||||
const max_id = followersRaw[followersRaw.length - 1]?.id ?? '';
|
||||
return ctx.body =
|
||||
{
|
||||
accounts: followersObject,
|
||||
max_id
|
||||
};
|
||||
}
|
||||
|
||||
// mastodon
|
||||
const myInfo = await fetch(`${instanceUrl}/api/v1/accounts/verify_credentials`,
|
||||
{
|
||||
headers: { Authorization: 'Bearer ' + user.accessToken }
|
||||
}).then((r) => r.json());
|
||||
@ -57,7 +94,7 @@ router.get('/followers', async (ctx: Koa.ParameterizedContext): Promise<never|vo
|
||||
|
||||
const followersObject = await User.find({acctLower: {$in: followers}});
|
||||
const max_id = ((parseLinkHeader(followersRes.headers.get('Link') ?? '') || {} as Links).next || {} as Link).max_id;
|
||||
ctx.body =
|
||||
return ctx.body =
|
||||
{
|
||||
accounts: followersObject,
|
||||
max_id
|
||||
@ -185,7 +222,7 @@ router.post('/:acct/question', async (ctx: Koa.ParameterizedContext): Promise<ne
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const questionUser = await User.findById(ctx.sessions.user);
|
||||
const questionUser = await User.findById(ctx.session.user);
|
||||
if (!questionUser)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
|
@ -2,12 +2,16 @@ import Koa from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import fetch from 'node-fetch';
|
||||
import rndstr from 'rndstr';
|
||||
import crypto from 'crypto';
|
||||
import { URL } from 'url';
|
||||
import { BASE_URL } from '../../config';
|
||||
import { MastodonApp, User } from '../../db/index';
|
||||
import QueryStringUtils from '../../utils/queryString';
|
||||
import { requestOAuth } from '../../utils/requestOAuth';
|
||||
import twitterClient from '../../utils/twitterClient';
|
||||
import detectInstance from '../../utils/detectInstance';
|
||||
import { App } from '../../utils/misskey_entities/app';
|
||||
import { User as MisskeyUser } from '../../utils/misskey_entities/user';
|
||||
|
||||
const router = new Router();
|
||||
|
||||
@ -20,47 +24,7 @@ router.post('/get_url', async (ctx: Koa.ParameterizedContext): Promise<never|voi
|
||||
const redirectUri = BASE_URL + '/api/web/oauth/redirect';
|
||||
let url = '';
|
||||
|
||||
if (hostName !== 'twitter.com')
|
||||
{
|
||||
// Mastodon
|
||||
// TODO: misskey support
|
||||
let app = await MastodonApp.findOne( { hostName, appBaseUrl: BASE_URL, redirectUri } );
|
||||
if (!app)
|
||||
{
|
||||
const res = await fetch('https://' + hostName + '/api/v1/apps',
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(
|
||||
{
|
||||
client_name: 'Quesdon',
|
||||
redirect_uris: redirectUri,
|
||||
scopes: 'read write',
|
||||
website: BASE_URL
|
||||
}),
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}).then((r) => r.json());
|
||||
|
||||
app = new MastodonApp();
|
||||
app.clientId = res.client_id;
|
||||
app.clientSecret = res.client_secret;
|
||||
app.hostName = hostName;
|
||||
app.appBaseUrl = BASE_URL;
|
||||
app.redirectUri = redirectUri;
|
||||
|
||||
await app.save();
|
||||
}
|
||||
ctx.session.loginState = `${rndstr()}_${app.id}`;
|
||||
const params: {[key: string]: string} =
|
||||
{
|
||||
client_id: app.clientId,
|
||||
scope: 'read+write',
|
||||
redirect_uri: redirectUri,
|
||||
response_type: 'code',
|
||||
state: ctx.session.loginState
|
||||
};
|
||||
url = `https://${app.hostName}/oauth/authorize?${Object.entries(params).map((v) => v.join('=')).join('&')}`;
|
||||
}
|
||||
else // Twitter
|
||||
if (hostName === 'twitter.com')
|
||||
{
|
||||
ctx.session.loginState = 'twitter';
|
||||
const { TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET } = process.env;
|
||||
@ -80,6 +44,85 @@ router.post('/get_url', async (ctx: Koa.ParameterizedContext): Promise<never|voi
|
||||
ctx.session.twitterOAuth = requestToken;
|
||||
url = `https://twitter.com/oauth/authenticate?oauth_token=${requestToken.token}`;
|
||||
}
|
||||
else
|
||||
{
|
||||
const instanceType = await detectInstance(`https://${hostName}`);
|
||||
if (instanceType === 'misskey')
|
||||
{
|
||||
let app = await MastodonApp.findOne( { hostName, appBaseUrl: BASE_URL, redirectUri } );
|
||||
if (!app) // if it's the first time user from this instance is using quesdon
|
||||
{
|
||||
const res: App = await fetch(`https://${hostName}/api/app/create`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(
|
||||
{
|
||||
name: 'Quesdon',
|
||||
description: BASE_URL,
|
||||
permission: ['read:following', 'write:notes'],
|
||||
callbackUrl: redirectUri
|
||||
}),
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}).then(r => r.json());
|
||||
|
||||
app = new MastodonApp();
|
||||
app.clientId = res.id,
|
||||
app.clientSecret = res.secret as string;
|
||||
app.hostName = hostName;
|
||||
app.appBaseUrl = BASE_URL;
|
||||
app.redirectUri = redirectUri;
|
||||
|
||||
await app.save();
|
||||
}
|
||||
ctx.session.loginState = `misskey_${app.id}`;
|
||||
const res = await fetch(`https://${hostName}/api/auth/session/generate`, // get authentication url from misskey instance
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify( { appSecret: app.clientSecret } )
|
||||
}).then(r => r.json());
|
||||
url = res.url;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mastodon
|
||||
let app = await MastodonApp.findOne( { hostName, appBaseUrl: BASE_URL, redirectUri } );
|
||||
if (!app)
|
||||
{
|
||||
const res = await fetch('https://' + hostName + '/api/v1/apps',
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(
|
||||
{
|
||||
client_name: 'Quesdon',
|
||||
redirect_uris: redirectUri,
|
||||
scopes: 'read write',
|
||||
website: BASE_URL
|
||||
}),
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}).then((r) => r.json());
|
||||
|
||||
app = new MastodonApp();
|
||||
app.clientId = res.client_id;
|
||||
app.clientSecret = res.client_secret;
|
||||
app.hostName = hostName;
|
||||
app.appBaseUrl = BASE_URL;
|
||||
app.redirectUri = redirectUri;
|
||||
|
||||
await app.save();
|
||||
}
|
||||
ctx.session.loginState = `${rndstr()}_${app.id}`;
|
||||
const params: {[key: string]: string} =
|
||||
{
|
||||
client_id: app.clientId,
|
||||
scope: 'read+write',
|
||||
redirect_uri: redirectUri,
|
||||
response_type: 'code',
|
||||
state: ctx.session.loginState
|
||||
};
|
||||
url = `https://${app.hostName}/oauth/authorize?${Object.entries(params).map((v) => v.join('=')).join('&')}`;
|
||||
}
|
||||
}
|
||||
ctx.body = { url };
|
||||
});
|
||||
|
||||
@ -96,11 +139,40 @@ router.get('/redirect', async (ctx: Koa.ParameterizedContext) =>
|
||||
url: string;
|
||||
acct: string;
|
||||
};
|
||||
|
||||
if (ctx.session.loginState !== 'twitter')
|
||||
|
||||
if ((ctx.session.loginState as string).startsWith('misskey'))
|
||||
{
|
||||
// misskey
|
||||
const app = await MastodonApp.findById(ctx.session.loginState.split('_')[1]);
|
||||
if (app === null)
|
||||
return ctx.redirect('/login?error=app_notfound');
|
||||
|
||||
const res: { accessToken: string; user: MisskeyUser } = await fetch(`https://${app.hostName}/api/auth/session/userkey`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(
|
||||
{
|
||||
appSecret: app.clientSecret,
|
||||
token: ctx.query.token
|
||||
})
|
||||
}).then(r => r.json());
|
||||
|
||||
profile =
|
||||
{
|
||||
id: res.user.id,
|
||||
name: res.user.name ?? res.user.username,
|
||||
screenName: res.user.username,
|
||||
hostName: app.hostName,
|
||||
avatarUrl: res.user.avatarUrl as string,
|
||||
accessToken: crypto.createHash('sha256').update(res.accessToken + app.clientSecret).digest('hex'),
|
||||
url: `https://${res.user.host}/@${res.user.username}`,
|
||||
acct: `${res.user.username}@${app.hostName}`
|
||||
};
|
||||
}
|
||||
else if (ctx.session.loginState !== 'twitter')
|
||||
{
|
||||
// Mastodon
|
||||
// TODO: handle misskey
|
||||
if (ctx.query.state !== ctx.session.loginState)
|
||||
return ctx.redirect('/login?error=invalid_state');
|
||||
|
||||
@ -207,14 +279,12 @@ router.get('/redirect', async (ctx: Koa.ParameterizedContext) =>
|
||||
|
||||
const acct = profile.acct;
|
||||
let user;
|
||||
if (profile.hostName !== 'twitter.com')
|
||||
{
|
||||
// Mastodon
|
||||
// TODO: misskey
|
||||
|
||||
if (profile.hostName !== 'twitter.com') // Mastodon and misskey
|
||||
user = await User.findOne({acctLower: acct.toLowerCase()});
|
||||
}
|
||||
else
|
||||
user = await User.findOne({upstreamId: profile.id, hostName: profile.hostName});
|
||||
|
||||
if (user === null)
|
||||
user = new User();
|
||||
|
||||
|
@ -8,6 +8,7 @@ import { IMastodonApp, IUser, Question, QuestionLike, User } from '../../db/inde
|
||||
import { cutText } from '../../utils/cutText';
|
||||
import { requestOAuth } from '../../utils/requestOAuth';
|
||||
import twitterClient from '../../utils/twitterClient';
|
||||
import detectInstance from '../../utils/detectInstance';
|
||||
|
||||
const router = new Router();
|
||||
|
||||
@ -52,7 +53,7 @@ router.get('/latest', async (ctx) =>
|
||||
ctx.body = questions;
|
||||
});
|
||||
|
||||
router.post('/:id/answer', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
router.post('/:id/answer', async (ctx: Koa.ParameterizedContext): Promise<void|never> =>
|
||||
{
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
@ -87,57 +88,99 @@ router.post('/:id/answer', async (ctx: Koa.ParameterizedContext): Promise<never|
|
||||
const isTwitter = user.hostName === 'twitter.com';
|
||||
const answerCharMax = isTwitter ? (110 - question.question.length) : 200;
|
||||
const answerUrl = `${BASE_URL}/@${user.acct}/questions/${question.id}`;
|
||||
if (!isTwitter)
|
||||
|
||||
if (isTwitter)
|
||||
{
|
||||
// Mastodon
|
||||
// TODO: misskey
|
||||
const body =
|
||||
{
|
||||
spoiler_text: `Q. ${question.question} #quesdon`,
|
||||
status: `A. ${question.answer.length > 200 ? `${question.answer.substring(0, 200)}...` : question.answer}
|
||||
#quesdon ${answerUrl}`,
|
||||
visibility: ctx.request.body.visibility
|
||||
};
|
||||
if (question.questionUser)
|
||||
{
|
||||
let questionUserAcct = `@${question.questionUser.acct}`;
|
||||
if (question.questionUser.hostName === 'twitter.com')
|
||||
questionUserAcct = `https://twitter.com/${question.questionUser.acct.replace(/:.+/, '')}`;
|
||||
body.status = stripIndents`질문자: ${questionUserAcct}
|
||||
${body.status}`;
|
||||
}
|
||||
if (question.isNSFW)
|
||||
{
|
||||
body.status = `Q. ${question.question}
|
||||
${body.status}`;
|
||||
body.spoiler_text = '⚠ 이 질문은 답변자가 NSFW하다고 했어요. #quesdon';
|
||||
}
|
||||
fetch('https://' + user.acct.split('@')[1] + '/api/v1/statuses',
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
headers:
|
||||
{
|
||||
'Authorization': 'Bearer ' + user.accessToken,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
const strQ = cutText(question.question, 60);
|
||||
const strA = cutText(question.answer, 120 - strQ.length);
|
||||
const [key, secret] = user.accessToken.split(':');
|
||||
const body = `Q. ${strQ}
|
||||
A. ${strA}
|
||||
#quesdon ${answerUrl}`;
|
||||
requestOAuth(twitterClient,
|
||||
await requestOAuth(twitterClient,
|
||||
{
|
||||
url: 'https://api.twitter.com/1.1/statuses/update.json',
|
||||
method: 'POST',
|
||||
data: { status: body }
|
||||
}, { key, secret });
|
||||
return;
|
||||
}
|
||||
|
||||
// misskey
|
||||
const instanceUrl = 'https://' + user.acct.split('@')[1];
|
||||
const instanceType = await detectInstance(instanceUrl);
|
||||
|
||||
const status =
|
||||
{
|
||||
title: `Q. ${question.question} #quesdon`,
|
||||
text: stripIndents`
|
||||
A. ${question.answer.length > answerCharMax ? `${question.answer.substring(0, answerCharMax)}...` : question.answer}
|
||||
#quesdon ${answerUrl}`
|
||||
};
|
||||
if (question.questionUser)
|
||||
{
|
||||
let questionUserAcct = `@${question.questionUser.acct}`;
|
||||
if (question.questionUser.hostName === 'twitter.com')
|
||||
questionUserAcct = `https://twitter.com/${question.questionUser.acct.replace(/:.+/, '')}`;
|
||||
status.text = stripIndents`
|
||||
질문자: ${questionUserAcct}
|
||||
${status.text}`;
|
||||
}
|
||||
if (question.isNSFW)
|
||||
{
|
||||
status.text = stripIndents`
|
||||
Q. ${question.question}
|
||||
${status.text}`;
|
||||
status.title = '⚠ 이 질문은 답변자가 NSFW하다고 했어요. #quesdon';
|
||||
}
|
||||
|
||||
if (instanceType === 'misskey')
|
||||
{
|
||||
let visibility;
|
||||
switch(ctx.request.body.visibility)
|
||||
{
|
||||
case 'public': visibility = 'public'; break;
|
||||
case 'unlisted': visibility = 'home'; break;
|
||||
case 'private': visibility = 'followers'; break;
|
||||
default: visibility = 'home'; break;
|
||||
}
|
||||
|
||||
const body =
|
||||
{
|
||||
i: user.accessToken,
|
||||
visibility: visibility,
|
||||
cw: status.title,
|
||||
text: status.text
|
||||
};
|
||||
|
||||
await fetch(`${instanceUrl}/api/notes/create`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Mastodon
|
||||
const body =
|
||||
{
|
||||
spoiler_text: status.title,
|
||||
status: status.text,
|
||||
visibility: ctx.request.body.visibility
|
||||
};
|
||||
|
||||
await fetch(instanceUrl + '/api/v1/statuses',
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
headers:
|
||||
{
|
||||
'Authorization': 'Bearer ' + user.accessToken,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
return;
|
||||
});
|
||||
|
||||
router.post('/:id/delete', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
|
@ -14,7 +14,7 @@ import { User } from './db/index';
|
||||
const app = new Koa();
|
||||
|
||||
app.keys = [SECRET_KEY];
|
||||
const pug = new Pug( { viewPath: path.resolve(__dirname, '../../views'), app: app } );
|
||||
new Pug( { viewPath: path.resolve(__dirname, '../../views'), app: app } );
|
||||
app.use(koaBody( { multipart: true } ));
|
||||
app.use(session({}, app));
|
||||
|
||||
|
36
src/server/utils/detectInstance.ts
Normal file
36
src/server/utils/detectInstance.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
type nodeinfoMeta =
|
||||
{
|
||||
links: nodeinfoVersionList[];
|
||||
};
|
||||
|
||||
type nodeinfoVersionList =
|
||||
{
|
||||
rel: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
type nodeinfo =
|
||||
{
|
||||
version: string;
|
||||
software: { name: string; version: string };
|
||||
// irrelevent properties skipped
|
||||
}
|
||||
|
||||
export default async function detectInstance(url: string): Promise<string|undefined>
|
||||
{
|
||||
const parsedURL = new URL(url);
|
||||
if(parsedURL.hostname === 'twitter.com')
|
||||
return 'twitter';
|
||||
|
||||
// fediverse
|
||||
const nodeinfoMeta: nodeinfoMeta = await fetch(`${parsedURL.origin}/.well-known/nodeinfo`).then(r => r.json());
|
||||
const nodeinfoLink = nodeinfoMeta.links.find(elem => elem.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.0');
|
||||
|
||||
// TODO: add support for 1.0 as a fallback? All latest versions of major AP softwares seem to support 2.0 tho
|
||||
if(!nodeinfoLink)
|
||||
return undefined;
|
||||
const nodeinfo: nodeinfo = await fetch(`${nodeinfoLink.href}`).then(r => r.json());
|
||||
return nodeinfo.software.name;
|
||||
}
|
8
src/server/utils/misskey_entities/app.ts
Normal file
8
src/server/utils/misskey_entities/app.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export type App =
|
||||
{
|
||||
id: string;
|
||||
name: string;
|
||||
callbackUrl: string | null;
|
||||
permission?: Array<string>;
|
||||
secret?: string;
|
||||
}
|
9
src/server/utils/misskey_entities/blocking.ts
Normal file
9
src/server/utils/misskey_entities/blocking.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { User } from './user';
|
||||
|
||||
export type Blocking =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
blockeeId: string;
|
||||
blockee: User;
|
||||
}
|
12
src/server/utils/misskey_entities/drivefile.ts
Normal file
12
src/server/utils/misskey_entities/drivefile.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export type DriveFile =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
name: string;
|
||||
type: string;
|
||||
md5: string;
|
||||
size: number;
|
||||
url: string | null;
|
||||
folderId: string | null;
|
||||
isSensitive: boolean;
|
||||
}
|
10
src/server/utils/misskey_entities/drivefolder.ts
Normal file
10
src/server/utils/misskey_entities/drivefolder.ts
Normal file
@ -0,0 +1,10 @@
|
||||
export type DriveFolder =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
name: string;
|
||||
foldersCount?: number;
|
||||
filesCount?: number;
|
||||
parentId: string | null;
|
||||
parent?: DriveFolder | null;
|
||||
}
|
9
src/server/utils/misskey_entities/error.ts
Normal file
9
src/server/utils/misskey_entities/error.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export type Error =
|
||||
{
|
||||
error:
|
||||
{
|
||||
code: string;
|
||||
message: string;
|
||||
id: string;
|
||||
};
|
||||
}
|
11
src/server/utils/misskey_entities/following.ts
Normal file
11
src/server/utils/misskey_entities/following.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { User } from './user';
|
||||
|
||||
export type Following =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
followeeId: string;
|
||||
followee?: User;
|
||||
followerId: string;
|
||||
follower?: User;
|
||||
}
|
10
src/server/utils/misskey_entities/hashtag.ts
Normal file
10
src/server/utils/misskey_entities/hashtag.ts
Normal file
@ -0,0 +1,10 @@
|
||||
export type Hashtag =
|
||||
{
|
||||
tag: string;
|
||||
mentionedUsersCount: number;
|
||||
mentionedLocalUsersCount: number;
|
||||
mentionedRemoteUsersCount: number;
|
||||
attachedUsersCount: number;
|
||||
attahedLocalUsersCount: number;
|
||||
attachedRemoteUsersCount: number;
|
||||
}
|
20
src/server/utils/misskey_entities/messagingmessage.ts
Normal file
20
src/server/utils/misskey_entities/messagingmessage.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { User } from './user';
|
||||
import { UserGroup } from './usergroup';
|
||||
import { DriveFile } from './drivefile';
|
||||
|
||||
export type MessagingMessage =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
userId: string;
|
||||
user?: User;
|
||||
text: string | null;
|
||||
fileId?: string | null;
|
||||
file?: DriveFile | null;
|
||||
recipientId: string | null;
|
||||
recipient?: User | null;
|
||||
groupId: string | null;
|
||||
group?: UserGroup | null;
|
||||
isRead?: boolean;
|
||||
reads?: Array<string>;
|
||||
}
|
9
src/server/utils/misskey_entities/muting.ts
Normal file
9
src/server/utils/misskey_entities/muting.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { User } from './user';
|
||||
|
||||
export type Muting =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
muteeId: string;
|
||||
mutee: User;
|
||||
}
|
26
src/server/utils/misskey_entities/note.ts
Normal file
26
src/server/utils/misskey_entities/note.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { User } from './user';
|
||||
import { DriveFile } from './drivefile';
|
||||
|
||||
export type Note =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
text: string | null;
|
||||
cw?: string | null;
|
||||
userId: string;
|
||||
user: User;
|
||||
replyId?: string | null;
|
||||
renoteId?: string | null;
|
||||
reply?: Note | null;
|
||||
renote?: Note | null;
|
||||
viaMobile?: boolean;
|
||||
isHidden?: boolean;
|
||||
visibility: string;
|
||||
mentions?: Array<string>;
|
||||
visibleUserIds?: Array<string>;
|
||||
fileIds?: Array<string>;
|
||||
files?: Array<DriveFile>;
|
||||
tags?: Array<string>;
|
||||
poll?: object | null; // FIXME: poll
|
||||
geo?: object | null; // FIXME: geo
|
||||
}
|
7
src/server/utils/misskey_entities/notefavorite.ts
Normal file
7
src/server/utils/misskey_entities/notefavorite.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export type NoteFavorite =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
note: string;
|
||||
noteId: string;
|
||||
}
|
9
src/server/utils/misskey_entities/notereaction.ts
Normal file
9
src/server/utils/misskey_entities/notereaction.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { User } from './user';
|
||||
|
||||
export type NoteReaction =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
user: User;
|
||||
type: string;
|
||||
}
|
22
src/server/utils/misskey_entities/notification.ts
Normal file
22
src/server/utils/misskey_entities/notification.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { User } from './user';
|
||||
|
||||
enum NotificationType // TODO: bring this out
|
||||
{
|
||||
follow = 'follow',
|
||||
receiveFollowRequest = 'receiveFollowRequest',
|
||||
mention = 'mention',
|
||||
reply = 'reply',
|
||||
renote = 'renote',
|
||||
quote = 'quote',
|
||||
reaction = 'reaction',
|
||||
pollVote = 'pollVote'
|
||||
}
|
||||
|
||||
export type Notification =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
type: NotificationType;
|
||||
userId?: string | null;
|
||||
user?: User | null;
|
||||
}
|
15
src/server/utils/misskey_entities/page.ts
Normal file
15
src/server/utils/misskey_entities/page.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { User } from './user';
|
||||
|
||||
export type Page =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
title: string;
|
||||
name: string;
|
||||
summary: string | null;
|
||||
content: Array<void>;
|
||||
variables: Array<void>;
|
||||
userId: string;
|
||||
user: User;
|
||||
}
|
32
src/server/utils/misskey_entities/user.ts
Normal file
32
src/server/utils/misskey_entities/user.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { Note } from './note';
|
||||
|
||||
export type User =
|
||||
{
|
||||
id: string;
|
||||
username: string;
|
||||
name: string | null;
|
||||
url?: string | null;
|
||||
avatarUrl: string | null;
|
||||
avatarColor: any | null; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
bannerUrl?: string | null;
|
||||
bannerColor?: any | null; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
emojis: any | null; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
host: string | null;
|
||||
description?: string | null;
|
||||
birthday?: string | null;
|
||||
createdAt?: string;
|
||||
updatedAt?: string | null;
|
||||
location?: string | null;
|
||||
followersCount?: number;
|
||||
followingCount?: number;
|
||||
notesCount?: number;
|
||||
isBot?: boolean;
|
||||
pinnedNoteIds?: Array<string>;
|
||||
pinnedNotes?: Array<Note>;
|
||||
isCat?: boolean;
|
||||
isAdmin?: boolean;
|
||||
isModerator?: boolean;
|
||||
isLocked?: boolean;
|
||||
hasUnreadSpecifiedNotes?: boolean;
|
||||
hasUnreadMentions?: boolean;
|
||||
}
|
8
src/server/utils/misskey_entities/usergroup.ts
Normal file
8
src/server/utils/misskey_entities/usergroup.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export type UserGroup =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
name: string;
|
||||
ownerId: string;
|
||||
userIds?: Array<string>;
|
||||
}
|
7
src/server/utils/misskey_entities/userlist.ts
Normal file
7
src/server/utils/misskey_entities/userlist.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export type UserList =
|
||||
{
|
||||
id: string;
|
||||
createdAt: string;
|
||||
name: string;
|
||||
userIds?: Array<string>;
|
||||
}
|
162
yarn.lock
162
yarn.lock
@ -19,9 +19,9 @@
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.4.0":
|
||||
version "7.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.1.tgz#b223497bbfbcbbb38116673904debc71470ca528"
|
||||
integrity sha512-SQ0sS7KUJDvgCI2cpZG0nJygO6002oTbhgSuw4WcocsnbxLwL5Q8I3fqbJdyBAc3uFrWZiR2JomseuxSuci3SQ==
|
||||
version "7.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a"
|
||||
integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
@ -158,9 +158,9 @@
|
||||
integrity sha1-/1QEYtL7TQqIRBzq8n0oewHD2Hg=
|
||||
|
||||
"@types/koa-compose@*":
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/koa-compose/-/koa-compose-3.2.4.tgz#76a461634a59c3e13449831708bb9b355fb1548e"
|
||||
integrity sha512-ioou0rxkuWL+yBQYsHUQAzRTfVxAg8Y2VfMftU+Y3RA03/MzuFL0x/M2sXXj3PkfnENbHsjeHR1aMdezLYpTeA==
|
||||
version "3.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/koa-compose/-/koa-compose-3.2.5.tgz#85eb2e80ac50be95f37ccf8c407c09bbe3468e9d"
|
||||
integrity sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==
|
||||
dependencies:
|
||||
"@types/koa" "*"
|
||||
|
||||
@ -216,9 +216,9 @@
|
||||
"@types/koa-send" "*"
|
||||
|
||||
"@types/koa@*", "@types/koa@^2.0.51":
|
||||
version "2.0.51"
|
||||
resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.0.51.tgz#b08a57dc49e34aaf6b5cc004b5fef4b16ebe32e1"
|
||||
integrity sha512-L5e/l6Z+SR9Jk6HM0wNYdkvWhSUBOvi+7Q5Uwn7kE/VmBXX7NIxARMigARWAyXAtXiv5Ry1P2HmebolFdvuIVg==
|
||||
version "2.0.52"
|
||||
resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.0.52.tgz#7dd11de4189ab339ad66c4ccad153716b14e525f"
|
||||
integrity sha512-cp/GTOhOYwomlSKqEoG0kaVEVJEzP4ojYmfa7EKaGkmkkRwJ4B/1VBLbQZ49Z+WJNvzXejQB/9GIKqMo9XLgFQ==
|
||||
dependencies:
|
||||
"@types/accepts" "*"
|
||||
"@types/cookies" "*"
|
||||
@ -238,17 +238,17 @@
|
||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||
|
||||
"@types/mongodb@*":
|
||||
version "3.3.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-3.3.8.tgz#a6023ff343a90478c0e22b2b5d35e56964c3ba60"
|
||||
integrity sha512-hsLcKRBFVeam4FyJOU6bwklvsNHzmUBI5SIxQ2meZu+RZgTDzrv+W19YAHgDIuiTn6UqHrVolweLMk0RpKEbxg==
|
||||
version "3.3.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-3.3.10.tgz#ef8255cc78b32ecd8afd901796e458f4379d9bc2"
|
||||
integrity sha512-0irlIjqs0UVcs+1ih7qdA9Rs4gkN9hBX7PI6IBWYu/kcMQ52L+oLW19gKT8wBJD2uMBkgT4mVKDmEo6ygObnHA==
|
||||
dependencies:
|
||||
"@types/bson" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/mongoose@^5.5.29":
|
||||
version "5.5.29"
|
||||
resolved "https://registry.yarnpkg.com/@types/mongoose/-/mongoose-5.5.29.tgz#611cb2eaed58d8d12d3f6338d8811290a4407f0f"
|
||||
integrity sha512-bIlJfCIg/pPhORc35hGs14gmDjPLIPffcs20UgMZFB8bw0WPIAkDRTZJlBLpuZ0UgHTOOxcSt56exkUv7f/1Yw==
|
||||
version "5.5.30"
|
||||
resolved "https://registry.yarnpkg.com/@types/mongoose/-/mongoose-5.5.30.tgz#8b6b06e4142771204ae1abec5773157b8a94ec53"
|
||||
integrity sha512-LQ7Q/MoRLhtYn1zGefsTrobeg4hieXe6MGYM2plbZHhqf4Ud1zRuEwjDQIjCgDIyMPnACiyCvPMTyzHaoSp0SA==
|
||||
dependencies:
|
||||
"@types/mongodb" "*"
|
||||
"@types/node" "*"
|
||||
@ -261,9 +261,9 @@
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*":
|
||||
version "12.12.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.6.tgz#a47240c10d86a9a57bb0c633f0b2e0aea9ce9253"
|
||||
integrity sha512-FjsYUPzEJdGXjwKqSpE0/9QEh6kzhTAeObA54rn6j3rR4C/mzpI9L0KNfoeASSPMMdxIsoJuCLDWcM/rVjIsSA==
|
||||
version "12.12.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
|
||||
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
|
||||
|
||||
"@types/oauth@^0.9.0":
|
||||
version "0.9.1"
|
||||
@ -293,9 +293,9 @@
|
||||
integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
|
||||
|
||||
"@types/react-dom@^16.9.3":
|
||||
version "16.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.3.tgz#4006ff0e13958af91313869077c04cb20d9b9d04"
|
||||
integrity sha512-FUuZKXPr9qlzUT9lhuzrZgLjH63TvNn28Ch3MvKG4B+F52zQtO8DtE0Opbncy3xaucNZM2WIPfuNTgkbKx5Brg==
|
||||
version "16.9.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.4.tgz#0b58df09a60961dcb77f62d4f1832427513420df"
|
||||
integrity sha512-fya9xteU/n90tda0s+FtN5Ym4tbgxpq/hb/Af24dvs6uYnYn+fspaxw5USlw0R8apDNwxsqumdRoCoKitckQqw==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
@ -1613,9 +1613,9 @@ browserslist@^3.2.6:
|
||||
electron-to-chromium "^1.3.47"
|
||||
|
||||
bson@^1.1.1, bson@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.1.tgz#4330f5e99104c4e751e7351859e2d408279f2f13"
|
||||
integrity sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg==
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.3.tgz#aa82cb91f9a453aaa060d6209d0675114a8154d3"
|
||||
integrity sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg==
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.1.1"
|
||||
@ -1633,9 +1633,9 @@ buffer-xor@^1.0.3:
|
||||
integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
|
||||
|
||||
buffer@^4.3.0:
|
||||
version "4.9.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
|
||||
integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=
|
||||
version "4.9.2"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8"
|
||||
integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==
|
||||
dependencies:
|
||||
base64-js "^1.0.2"
|
||||
ieee754 "^1.1.4"
|
||||
@ -2513,9 +2513,9 @@ ee-first@1.1.1:
|
||||
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
|
||||
|
||||
electron-to-chromium@^1.3.47:
|
||||
version "1.3.304"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.304.tgz#49b47d961f8143116174c2f70fbfee3aabf43015"
|
||||
integrity sha512-a5mqa13jCdBc+Crgk3Gyr7vpXCiFWfFq23YDCEmrPYeiDOQKZDVE6EX/Q4Xdv97n3XkcjiSBDOY0IS19yP2yeA==
|
||||
version "1.3.306"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.306.tgz#e8265301d053d5f74e36cb876486830261fbe946"
|
||||
integrity sha512-frDqXvrIROoYvikSKTIKbHbzO6M3/qC6kCIt/1FOa9kALe++c4VAJnwjSFvf1tYLEUsP2n9XZ4XSCyqc3l7A/A==
|
||||
|
||||
elliptic@^6.0.0:
|
||||
version "6.5.1"
|
||||
@ -2611,9 +2611,9 @@ es-abstract@^1.4.3:
|
||||
string.prototype.trimright "^2.1.0"
|
||||
|
||||
es-to-primitive@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377"
|
||||
integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
|
||||
integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
|
||||
dependencies:
|
||||
is-callable "^1.1.4"
|
||||
is-date-object "^1.0.1"
|
||||
@ -2933,7 +2933,7 @@ fast-json-stable-stringify@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
|
||||
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
|
||||
|
||||
fast-levenshtein@~2.0.4:
|
||||
fast-levenshtein@~2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||
@ -3319,9 +3319,9 @@ glob2base@^0.0.12:
|
||||
find-index "^0.1.1"
|
||||
|
||||
glob@^7.0.3, glob@^7.0.5, glob@^7.1.3, glob@^7.1.4:
|
||||
version "7.1.5"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0"
|
||||
integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
@ -3806,7 +3806,7 @@ ip-regex@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
|
||||
integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
|
||||
|
||||
ip@^1.1.0, ip@^1.1.5:
|
||||
ip@1.1.5, ip@^1.1.0, ip@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
|
||||
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
|
||||
@ -4532,9 +4532,9 @@ lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4:
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
|
||||
loglevel@^1.6.4:
|
||||
version "1.6.4"
|
||||
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.4.tgz#f408f4f006db8354d0577dcf6d33485b3cb90d56"
|
||||
integrity sha512-p0b6mOGKcGa+7nnmKbpzR6qloPbrgLcnio++E+14Vo/XffOGwZtRpUhr8dTH/x2oCMmEoIU0Zwm3ZauhvYD17g==
|
||||
version "1.6.6"
|
||||
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.6.tgz#0ee6300cc058db6b3551fa1c4bf73b83bb771312"
|
||||
integrity sha512-Sgr5lbboAUBo3eXCSPL4/KoVz3ROKquOjcctxmHIt+vol2DrqTQe3SwkKKuYhEiWB5kYa13YyopJ69deJ1irzQ==
|
||||
|
||||
longest@^1.0.1:
|
||||
version "1.0.1"
|
||||
@ -4892,9 +4892,9 @@ mongoose-legacy-pluralize@1.0.2:
|
||||
integrity sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==
|
||||
|
||||
mongoose@^5.7.8:
|
||||
version "5.7.8"
|
||||
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-5.7.8.tgz#ae86bff72687e8950dd95690a5eb3365ad9d57a0"
|
||||
integrity sha512-GsFXYo7z3ebnIDdnqlDJYQXQFqEGS+yxfdY9G0B7fxpvUJchDpwLGuGJdVd1QbGxu2l0DscCYBO0ntl3G6OACA==
|
||||
version "5.7.9"
|
||||
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-5.7.9.tgz#c7b7684e079749a26cdcc59b7027aae5d2b8f0f8"
|
||||
integrity sha512-wXYY4+IEvplbEEeOxLVOHBGosBDNn/DYgwKzBFgsamCTvRQZHbdw88m9xUH8Srza+jdKND73/4XbQLynPseRAQ==
|
||||
dependencies:
|
||||
bson "~1.1.1"
|
||||
kareem "2.3.1"
|
||||
@ -5301,16 +5301,16 @@ opn@^5.5.0:
|
||||
is-wsl "^1.1.0"
|
||||
|
||||
optionator@^0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
|
||||
integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=
|
||||
version "0.8.3"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
|
||||
integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==
|
||||
dependencies:
|
||||
deep-is "~0.1.3"
|
||||
fast-levenshtein "~2.0.4"
|
||||
fast-levenshtein "~2.0.6"
|
||||
levn "~0.3.0"
|
||||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
wordwrap "~1.0.0"
|
||||
word-wrap "~1.2.3"
|
||||
|
||||
original@^1.0.0:
|
||||
version "1.0.2"
|
||||
@ -5532,9 +5532,9 @@ path-to-regexp@0.1.7:
|
||||
integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
|
||||
|
||||
path-to-regexp@^1.1.1, path-to-regexp@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d"
|
||||
integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a"
|
||||
integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
|
||||
dependencies:
|
||||
isarray "0.0.1"
|
||||
|
||||
@ -5578,9 +5578,9 @@ performance-now@^2.1.0:
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
picomatch@^2.0.5:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.0.tgz#0fd042f568d08b1ad9ff2d3ec0f0bfb3cb80e177"
|
||||
integrity sha512-uhnEDzAbrcJ8R3g2fANnSuXZMBtkpSjxTTgn2LeSiQlfmq72enQJWdQllXW24MBLYnA1SBD2vfvx2o0Zw3Ielw==
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.1.tgz#ecdfbea7704adb5fe6fb47f9866c4c0e15e905c5"
|
||||
integrity sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==
|
||||
|
||||
pidtree@^0.3.0:
|
||||
version "0.3.0"
|
||||
@ -5928,9 +5928,9 @@ qs@6.7.0:
|
||||
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
|
||||
|
||||
qs@^6.4.0:
|
||||
version "6.9.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.0.tgz#d1297e2a049c53119cb49cca366adbbacc80b409"
|
||||
integrity sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA==
|
||||
version "6.9.1"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.1.tgz#20082c65cb78223635ab1a9eaca8875a29bf8ec9"
|
||||
integrity sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==
|
||||
|
||||
qs@~6.5.2:
|
||||
version "6.5.2"
|
||||
@ -6037,9 +6037,9 @@ react-lifecycles-compat@^3.0.4:
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
||||
react-popper@^1.3.3:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.4.tgz#f0cd3b0d30378e1f663b0d79bcc8614221652ced"
|
||||
integrity sha512-9AcQB29V+WrBKk6X7p0eojd1f25/oJajVdMZkywIoAV6Ag7hzE1Mhyeup2Q1QnvFRtGQFQvtqfhlEoDAPfKAVA==
|
||||
version "1.3.6"
|
||||
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.6.tgz#32122f83af8fda01bdd4f86625ddacaf64fdd06d"
|
||||
integrity sha512-kLTfa9z8n+0jJvRVal9+vIuirg41rObg4Bbrvv/ZfsGPQDN9reyVVSxqnHF1ZNgXgV7x11PeUfd5ItF8DZnqhg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
create-react-context "^0.3.0"
|
||||
@ -6679,10 +6679,10 @@ sliced@1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/sliced/-/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41"
|
||||
integrity sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=
|
||||
|
||||
smart-buffer@4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.2.tgz#5207858c3815cc69110703c6b94e46c15634395d"
|
||||
integrity sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==
|
||||
smart-buffer@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba"
|
||||
integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==
|
||||
|
||||
snapdragon-node@^2.0.1:
|
||||
version "2.1.1"
|
||||
@ -6742,12 +6742,12 @@ socks-proxy-agent@h3poteto/node-socks-proxy-agent#master:
|
||||
socks "~2.3.2"
|
||||
|
||||
socks@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.2.tgz#ade388e9e6d87fdb11649c15746c578922a5883e"
|
||||
integrity sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ==
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3"
|
||||
integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==
|
||||
dependencies:
|
||||
ip "^1.1.5"
|
||||
smart-buffer "4.0.2"
|
||||
ip "1.1.5"
|
||||
smart-buffer "^4.1.0"
|
||||
|
||||
source-list-map@^2.0.0:
|
||||
version "2.0.1"
|
||||
@ -7137,9 +7137,9 @@ terser-webpack-plugin@^1.4.1:
|
||||
worker-farm "^1.7.0"
|
||||
|
||||
terser@^4.1.2:
|
||||
version "4.3.9"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.9.tgz#e4be37f80553d02645668727777687dad26bbca8"
|
||||
integrity sha512-NFGMpHjlzmyOtPL+fDw3G7+6Ueh/sz4mkaUYa4lJCxOPTNzd0Uj0aZJOmsDYoSQyfuVoWDMSWTPU3huyOm2zdA==
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-4.4.0.tgz#22c46b4817cf4c9565434bfe6ad47336af259ac3"
|
||||
integrity sha512-oDG16n2WKm27JO8h4y/w3iqBGAOSCtq7k8dRmrn4Wf9NouL0b2WpMHGChFGZq4nFAQy1FsNJrVQHfurXOSTmOA==
|
||||
dependencies:
|
||||
commander "^2.20.0"
|
||||
source-map "~0.6.1"
|
||||
@ -7367,9 +7367,9 @@ uglify-js@^2.6.1:
|
||||
uglify-to-browserify "~1.0.0"
|
||||
|
||||
uglify-js@^3.6.0:
|
||||
version "3.6.7"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.7.tgz#15f49211df6b8a01ee91322bbe46fa33223175dc"
|
||||
integrity sha512-4sXQDzmdnoXiO+xvmTzQsfIiwrjUCSA95rSP4SEd8tDb51W2TiDOlL76Hl+Kw0Ie42PSItCW8/t6pBNCF2R48A==
|
||||
version "3.6.8"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.8.tgz#5edcbcf9d49cbb0403dc49f856fe81530d65145e"
|
||||
integrity sha512-XhHJ3S3ZyMwP8kY1Gkugqx3CJh2C3O0y8NPiSxtm1tyD/pktLAkFZsFGpuNfTZddKDQ/bbDBLAd2YyA1pbi8HQ==
|
||||
dependencies:
|
||||
commander "~2.20.3"
|
||||
source-map "~0.6.1"
|
||||
@ -7741,16 +7741,16 @@ with@^5.0.0:
|
||||
acorn "^3.1.0"
|
||||
acorn-globals "^3.0.0"
|
||||
|
||||
word-wrap@~1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
||||
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
|
||||
|
||||
wordwrap@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
|
||||
integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=
|
||||
|
||||
wordwrap@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||
integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
|
||||
|
||||
worker-farm@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"
|
||||
|
Loading…
Reference in New Issue
Block a user