mirror of
https://github.com/byulmaru/quesdon
synced 2024-11-27 06:18:02 +09:00
서버 코드 ts3 붙이고 문법 내스타일로 정리
This commit is contained in:
parent
1e20b4f186
commit
f68e1678f2
@ -29,7 +29,9 @@
|
||||
"comma-dangle": ["warn", "never"],
|
||||
"brace-style": ["error", "allman", { "allowSingleLine": true }],
|
||||
"eqeqeq": ["error", "always"],
|
||||
"require-atomic-updates": "off",
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
"@typescript-eslint/camelcase": "off"
|
||||
"@typescript-eslint/camelcase": "off",
|
||||
"@typescript-eslint/interface-name-prefix": ["error", { "prefixWithI": "always" }]
|
||||
}
|
||||
}
|
@ -1,24 +1,25 @@
|
||||
// インスタンス別ユーザー数ランキング
|
||||
// RoboMongoで実行
|
||||
// 인스턴스별 사용자 수 랭킹
|
||||
// RoboMongo 사용
|
||||
|
||||
(function(){
|
||||
(function()
|
||||
{
|
||||
let hostNames = db.getCollection('users').find({}, {acctLower: 1}).map(user => user.acctLower.split("@").pop()).filter(hostName => hostName)
|
||||
let count = {}
|
||||
|
||||
var hostNames = db.getCollection('users').find({}, {acctLower: 1}).map(user => user.acctLower.split("@").pop()).filter(hostName => hostName)
|
||||
var count = {}
|
||||
hostNames.forEach(hostName =>
|
||||
{
|
||||
if (count[hostName] == null) count[hostName] = 0
|
||||
count[hostName]++
|
||||
})
|
||||
|
||||
hostNames.forEach(hostName => {
|
||||
if (count[hostName] == null) count[hostName] = 0
|
||||
count[hostName]++
|
||||
})
|
||||
let sortedCount = Object.keys(count).map(hostName => [hostName, count[hostName]]).sort((a, b) => b[1] - a[1])
|
||||
|
||||
var sortedCount = Object.keys(count).map(hostName => [hostName, count[hostName]]).sort((a, b) => b[1] - a[1])
|
||||
count = {}
|
||||
|
||||
count = {}
|
||||
sortedCount.forEach(a =>
|
||||
{
|
||||
count[a[0]] = a[1]
|
||||
})
|
||||
|
||||
sortedCount.forEach(a => {
|
||||
count[a[0]] = a[1]
|
||||
})
|
||||
|
||||
return count
|
||||
|
||||
return count
|
||||
})()
|
||||
|
18
package.json
18
package.json
@ -19,6 +19,7 @@
|
||||
"author": "rinsuki",
|
||||
"license": "AGPL-3.0+",
|
||||
"devDependencies": {
|
||||
"@types/common-tags": "^1.8.0",
|
||||
"@types/dotenv": "^8.2.0",
|
||||
"@types/koa": "^2.0.51",
|
||||
"@types/koa-mount": "^4.0.0",
|
||||
@ -26,15 +27,16 @@
|
||||
"@types/koa-router": "^7.0.42",
|
||||
"@types/koa-session": "^5.10.1",
|
||||
"@types/koa-static": "^4.0.1",
|
||||
"@types/mongoose": "^5.5.28",
|
||||
"@types/node-fetch": "^2.5.2",
|
||||
"@types/koa-static-cache": "^5.1.0",
|
||||
"@types/mongoose": "^5.5.29",
|
||||
"@types/node-fetch": "^2.5.3",
|
||||
"@types/parse-link-header": "^1.0.0",
|
||||
"@types/react": "^16.9.11",
|
||||
"@types/react-dom": "^16.9.3",
|
||||
"@types/react-router-dom": "^5.1.1",
|
||||
"@types/react-router-dom": "^5.1.2",
|
||||
"@types/reactstrap": "^8.0.6",
|
||||
"@typescript-eslint/eslint-plugin": "^2.6.0",
|
||||
"@typescript-eslint/parser": "^2.6.0",
|
||||
"@typescript-eslint/eslint-plugin": "^2.6.1",
|
||||
"@typescript-eslint/parser": "^2.6.1",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
@ -46,6 +48,7 @@
|
||||
"fetch-defaults": "^1.0.0",
|
||||
"file-loader": "^4.2.0",
|
||||
"jquery": "^3.4.1",
|
||||
"megalodon": "^2.0.0",
|
||||
"moment": "^2.24.0",
|
||||
"node-dev": "^4.0.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
@ -57,13 +60,14 @@
|
||||
"reactstrap": "^8.1.1",
|
||||
"style-loader": "^1.0.0",
|
||||
"ts-loader": "^6.2.1",
|
||||
"typescript": "^3.6.4",
|
||||
"typescript": "^3.7.2",
|
||||
"uglifyjs-webpack-plugin": "^2.2.0",
|
||||
"webpack": "^4.41.2",
|
||||
"webpack-cli": "^3.3.10",
|
||||
"webpack-dev-server": "^3.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"common-tags": "^1.8.0",
|
||||
"dotenv": "^8.2.0",
|
||||
"koa": "^2.11.0",
|
||||
"koa-body": "^4.1.1",
|
||||
@ -73,7 +77,7 @@
|
||||
"koa-session": "^5.12.3",
|
||||
"koa-static": "^5.0.0",
|
||||
"koa-static-cache": "^5.1.1",
|
||||
"mongoose": "^5.7.7",
|
||||
"mongoose": "^5.7.8",
|
||||
"mongoose-autopopulate": "^0.9.1",
|
||||
"node-fetch": "^2.6.0",
|
||||
"oauth-1.0a": "github:rinsuki/oauth-1.0a",
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* eslint @typescript-eslint/interface-name-prefix: 0 */
|
||||
|
||||
export interface APIQuestion
|
||||
{
|
||||
_id: string;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as Router from 'koa-router';
|
||||
import Router from 'koa-router';
|
||||
import webRouter from './web';
|
||||
|
||||
const router = new Router();
|
||||
|
@ -1,199 +1,254 @@
|
||||
import * as Koa from 'koa';
|
||||
import * as Router from 'koa-router';
|
||||
import * as mongoose from 'mongoose';
|
||||
import Koa from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import fetch from 'node-fetch';
|
||||
import * as parseLinkHeader from 'parse-link-header';
|
||||
import { Link, Links } from 'parse-link-header';
|
||||
import parseLinkHeader, { Link, Links } from 'parse-link-header';
|
||||
import { Account } from 'megalodon';
|
||||
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';
|
||||
|
||||
const router = new Router();
|
||||
|
||||
router.get('/verify_credentials', async (ctx) =>
|
||||
router.get('/verify_credentials', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
const user = await User.findById(ctx.session!.user);
|
||||
if (!user) return ctx.throw('not found', 404);
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const user = await User.findById(ctx.session.user);
|
||||
if (!user)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
ctx.body = user;
|
||||
});
|
||||
|
||||
router.get('/followers', async (ctx) =>
|
||||
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);
|
||||
const user = await User.findById(ctx.session!.user);
|
||||
if (!user) return ctx.throw('not found', 404);
|
||||
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);
|
||||
|
||||
const user = await User.findById(ctx.session.user);
|
||||
if (!user)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
// twitter
|
||||
if (user.hostName === 'twitter.com')
|
||||
{
|
||||
return {max_id: undefined, accounts: []};
|
||||
}
|
||||
return;
|
||||
// return { 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', {
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + user.accessToken
|
||||
}
|
||||
}).then((r) => r.json());
|
||||
const param = ctx.query.max_id ? '&max_id=' + ctx.query.max_id : '';
|
||||
const followersRes = await fetch(
|
||||
`${instanceUrl}/api/v1/accounts/${myInfo.id}/followers?limit=80${param}`,
|
||||
const myInfo = await fetch(instanceUrl + '/api/v1/accounts/verify_credentials',
|
||||
{
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + user.accessToken
|
||||
}
|
||||
}
|
||||
);
|
||||
let followers: any[] = await followersRes.json();
|
||||
followers = followers
|
||||
.map((follower) => follower.acct as string)
|
||||
headers: { Authorization: 'Bearer ' + user.accessToken }
|
||||
}).then((r) => r.json());
|
||||
const param = ctx.query.max_id ? '&max_id=' + ctx.query.max_id : '';
|
||||
const followersRes = await fetch(`${instanceUrl}/api/v1/accounts/${myInfo.id}/followers?limit=80${param}`,
|
||||
{
|
||||
headers: { Authorization: 'Bearer ' + user.accessToken }
|
||||
});
|
||||
const followersRaw: Account[] = await followersRes.json();
|
||||
const followers = followersRaw
|
||||
.map((follower) => follower.acct)
|
||||
.map((acct) => acct.includes('@') ? acct : (acct + '@' + user.acct.split('@')[1]))
|
||||
.map((acct) => acct.toLowerCase());
|
||||
.map((acct) => acct.toLowerCase()); // create a string[] of followers in 'lowercase@host.name' form
|
||||
|
||||
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 = {
|
||||
accounts: followersObject,
|
||||
max_id
|
||||
};
|
||||
const max_id = ((parseLinkHeader(followersRes.headers.get('Link') ?? '') || {} as Links).next || {} as Link).max_id;
|
||||
ctx.body =
|
||||
{
|
||||
accounts: followersObject,
|
||||
max_id
|
||||
};
|
||||
});
|
||||
|
||||
router.post('/update', async (ctx) =>
|
||||
router.post('/update', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
const user = await User.findById(ctx.session!.user);
|
||||
if (!user) return ctx.throw('not found', 404);
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const user = await User.findById(ctx.session.user);
|
||||
if (!user)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
user.description = ctx.request.body.fields.description;
|
||||
user.questionBoxName = ctx.request.body.fields.questionBoxName;
|
||||
user.allAnon = !!ctx.request.body.fields.allAnon;
|
||||
user.stopNewQuestion = !!ctx.request.body.fields.stopNewQuestion;
|
||||
await user.save();
|
||||
ctx.body = {status: 'ok'};
|
||||
ctx.body = {status: 'ok'};
|
||||
});
|
||||
|
||||
router.get('/id/:id', async (ctx) =>
|
||||
router.get('/id/:id', async (ctx): Promise<never|void> =>
|
||||
{
|
||||
const user = await User.findById(ctx.params.id);
|
||||
if (!user) return ctx.throw('not found', 404);
|
||||
ctx.body = user;
|
||||
if (!user)
|
||||
return ctx.throw('not found', 404);
|
||||
ctx.body = user;
|
||||
});
|
||||
|
||||
router.get('/pushbullet/redirect', async (ctx) =>
|
||||
router.get('/pushbullet/redirect', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
const user = await User.findById(ctx.session!.user);
|
||||
if (!user) return ctx.throw('not found', 404);
|
||||
ctx.redirect('https://www.pushbullet.com/authorize'
|
||||
+ '?client_id=' + PUSHBULLET_CLIENT_ID
|
||||
+ '&redirect_uri=' + encodeURIComponent(BASE_URL + '/api/web/accounts/pushbullet/callback')
|
||||
+ '&response_type=code'
|
||||
+ '&scope=everything'
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const user = await User.findById(ctx.session.user);
|
||||
if (!user)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
ctx.redirect(oneLineTrim`https://www.pushbullet.com/authorize
|
||||
?client_id=${PUSHBULLET_CLIENT_ID}
|
||||
&redirect_uri=${encodeURIComponent(BASE_URL + '/api/web/accounts/pushbullet/callback')}
|
||||
&response_type=code
|
||||
&scope=everything`
|
||||
);
|
||||
});
|
||||
|
||||
router.get('/pushbullet/callback', async (ctx) =>
|
||||
router.get('/pushbullet/callback', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
const user = await User.findById(ctx.session!.user);
|
||||
if (!user) return ctx.throw('not found', 404);
|
||||
const res = await fetch('https://api.pushbullet.com/oauth2/token', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
client_id: PUSHBULLET_CLIENT_ID,
|
||||
client_secret: PUSHBULLET_CLIENT_SECRET,
|
||||
code: ctx.query.code,
|
||||
grant_type: 'authorization_code'
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((r) => r.json());
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const user = await User.findById(ctx.session.user);
|
||||
if (!user)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
const res = await fetch('https://api.pushbullet.com/oauth2/token',
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(
|
||||
{
|
||||
client_id: PUSHBULLET_CLIENT_ID,
|
||||
client_secret: PUSHBULLET_CLIENT_SECRET,
|
||||
code: ctx.query.code,
|
||||
grant_type: 'authorization_code'
|
||||
}),
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}).then((r) => r.json());
|
||||
if (res.error)
|
||||
{
|
||||
return ctx.throw(500, 'pushbullet error: ' + res.error.message);
|
||||
}
|
||||
|
||||
user.pushbulletAccessToken = res.access_token;
|
||||
await user.save();
|
||||
|
||||
ctx.redirect('/my/settings');
|
||||
});
|
||||
|
||||
router.post('/pushbullet/disconnect', async (ctx) =>
|
||||
router.post('/pushbullet/disconnect', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
const user = await User.findById(ctx.session!.user);
|
||||
if (!user) return ctx.throw('not found', 404);
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const user = await User.findById(ctx.session.user);
|
||||
if (!user)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
user.pushbulletAccessToken = null;
|
||||
await user.save();
|
||||
ctx.body = {status: 'ok'};
|
||||
|
||||
ctx.body = {status: 'ok'};
|
||||
});
|
||||
|
||||
router.get('/:acct', async (ctx) =>
|
||||
router.get('/:acct', async (ctx): Promise<never|void> =>
|
||||
{
|
||||
const user = await User.findOne({acctLower: ctx.params.acct.toLowerCase()});
|
||||
if (!user) return ctx.throw('not found', 404);
|
||||
ctx.body = user;
|
||||
if (!user)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
ctx.body = user;
|
||||
});
|
||||
|
||||
router.post('/:acct/question', async (ctx) =>
|
||||
router.post('/:acct/question', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
const questionString = ctx.request.body.fields.question;
|
||||
if (questionString.length < 1) return ctx.throw('please input question', 400);
|
||||
if (questionString.length > QUESTION_TEXT_MAX_LENGTH) return ctx.throw('too long', 400);
|
||||
|
||||
if (questionString.length < 1)
|
||||
return ctx.throw('please input question', 400);
|
||||
if (questionString.length > QUESTION_TEXT_MAX_LENGTH)
|
||||
return ctx.throw('too long', 400);
|
||||
|
||||
const user = await User.findOne({acctLower: ctx.params.acct.toLowerCase()});
|
||||
if (!user) return ctx.throw('not found', 404);
|
||||
if (user.stopNewQuestion) return ctx.throw(400, 'this user has stopped new question submit');
|
||||
if (!user)
|
||||
return ctx.throw('not found', 404);
|
||||
if (user.stopNewQuestion)
|
||||
return ctx.throw(400, 'this user has stopped new question submit');
|
||||
|
||||
const question = new Question();
|
||||
question.question = questionString;
|
||||
question.user = user;
|
||||
if (ctx.request.body.fields.noAnon)
|
||||
{
|
||||
if (user.allAnon) return ctx.throw('all anon', 400);
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
const questionUser = await User.findById(ctx.session!.user);
|
||||
if (!questionUser) return ctx.throw('not found', 404);
|
||||
if (user.allAnon)
|
||||
return ctx.throw('all anon', 400);
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const questionUser = await User.findById(ctx.sessions.user);
|
||||
if (!questionUser)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
question.questionUser = questionUser;
|
||||
}
|
||||
await question.save();
|
||||
|
||||
ctx.body = {status: 'ok'};
|
||||
|
||||
if (user.pushbulletAccessToken)
|
||||
{
|
||||
fetch('https://api.pushbullet.com/v2/pushes', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
type: 'link',
|
||||
body: '새로운 질문이에요!\nQ. ' + question.question,
|
||||
url: BASE_URL + '/my/questions'
|
||||
}),
|
||||
headers: {
|
||||
'Access-Token': user.pushbulletAccessToken,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
fetch('https://api.pushbullet.com/v2/pushes',
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(
|
||||
{
|
||||
type: 'link',
|
||||
body: stripIndents`새로운 질문이에요!
|
||||
Q. ${question.question}`,
|
||||
url: BASE_URL + '/my/questions'
|
||||
}),
|
||||
headers:
|
||||
{
|
||||
'Access-Token': user.pushbulletAccessToken,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
}
|
||||
if (NOTICE_ACCESS_TOKEN)
|
||||
{
|
||||
fetch('https://planet.moe/api/v1/statuses', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
status: '@' + user.acct + ' Quesdon@Planet - 새로운 질문이에요!\nQ. ' + question.question
|
||||
+ '\n' + BASE_URL + '/my/questions',
|
||||
visibility: 'direct'
|
||||
}),
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + NOTICE_ACCESS_TOKEN,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
fetch('https://planet.moe/api/v1/statuses',
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(
|
||||
{
|
||||
status: stripIndents`@${user.acct} Quesdon@Planet - 새로운 질문이에요!
|
||||
Q. ${question.question}
|
||||
${BASE_URL}/my/questions`,
|
||||
visibility: 'direct'
|
||||
}),
|
||||
headers:
|
||||
{
|
||||
'Authorization': 'Bearer ' + NOTICE_ACCESS_TOKEN,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const getAnswers = async (ctx: Koa.Context) =>
|
||||
const getAnswers = async (ctx: Koa.ParameterizedContext): Promise<void> =>
|
||||
{
|
||||
const user = await User.findOne({acctLower: ctx.params.acct.toLowerCase()});
|
||||
if (!user) return ctx.throw('not found', 404);
|
||||
const questions = await Question.find({
|
||||
user,
|
||||
answeredAt: {$ne: null},
|
||||
isDeleted: {$ne: true}
|
||||
}).sort('-answeredAt');
|
||||
if (!user)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
const questions = await Question.find(
|
||||
{
|
||||
user,
|
||||
answeredAt: {$ne: null},
|
||||
isDeleted: {$ne: true}
|
||||
}).sort('-answeredAt');
|
||||
|
||||
ctx.body = questions.map((question) =>
|
||||
{
|
||||
question.user = user;
|
||||
|
@ -1,16 +1,17 @@
|
||||
import * as Router from 'koa-router';
|
||||
import Koa from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import accountsRouter from './accounts';
|
||||
import oauthRouter from './oauth';
|
||||
import questionsRouter from './questions';
|
||||
|
||||
const router = new Router();
|
||||
|
||||
router.use(async (ctx, next) =>
|
||||
router.use(async (ctx: Koa.ParameterizedContext, next): Promise<void> =>
|
||||
{
|
||||
if (ctx.request.method !== 'GET')
|
||||
{
|
||||
if (ctx.session!.csrfToken !== ctx.request.headers['x-csrf-token']) return ctx.throw('invalid csrf token', 403);
|
||||
}
|
||||
if (ctx.session.csrfToken !== ctx.request.headers['x-csrf-token'])
|
||||
return ctx.throw('invalid csrf token', 403);
|
||||
|
||||
await next();
|
||||
});
|
||||
|
||||
@ -18,10 +19,10 @@ router.use('/oauth', oauthRouter.routes());
|
||||
router.use('/accounts', accountsRouter.routes());
|
||||
router.use('/questions', questionsRouter.routes());
|
||||
|
||||
router.get('/logout', async (ctx) =>
|
||||
router.get('/logout', (ctx: Koa.ParameterizedContext) =>
|
||||
{
|
||||
ctx.session!.user = undefined;
|
||||
ctx.body = {status: 'ok'};
|
||||
ctx.session.user = undefined;
|
||||
ctx.body = { status: 'ok' };
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import * as Router from 'koa-router';
|
||||
import Koa from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import fetch from 'node-fetch';
|
||||
import rndstr from 'rndstr';
|
||||
import { URL } from 'url';
|
||||
@ -10,189 +11,213 @@ import twitterClient from '../../utils/twitterClient';
|
||||
|
||||
const router = new Router();
|
||||
|
||||
router.post('/get_url', async (ctx) =>
|
||||
router.post('/get_url', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
const hostName = ctx.request.body.fields.instance
|
||||
.replace(/.*@/, '').toLowerCase();
|
||||
if (hostName.includes('/')) return ctx.reject(400, 'not use slash in hostname');
|
||||
const hostName = ctx.request.body.fields.instance.replace(/.*@/, '').toLowerCase();
|
||||
if (hostName.includes('/'))
|
||||
return ctx.throw(400, 'not use slash in hostname');
|
||||
|
||||
const redirectUri = BASE_URL + '/api/web/oauth/redirect';
|
||||
let url = '';
|
||||
|
||||
if (hostName !== 'twitter.com')
|
||||
{ // Mastodon
|
||||
let app = await MastodonApp.findOne({hostName, appBaseUrl: BASE_URL, redirectUri});
|
||||
{
|
||||
// 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());
|
||||
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.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
|
||||
ctx.session!.loginState = 'twitter';
|
||||
const { TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET } = process.env;
|
||||
if (TWITTER_CONSUMER_KEY == null || TWITTER_CONSUMER_SECRET == null)
|
||||
{
|
||||
ctx.throw(500, 'twitter not supported in this server.');
|
||||
}
|
||||
const requestTokenRes = await requestOAuth(twitterClient, {
|
||||
url: 'https://api.twitter.com/oauth/request_token',
|
||||
method: 'POST',
|
||||
data: {}
|
||||
}).then((r) => r.text()).then((r) => QueryStringUtils.decode(r));
|
||||
const requestToken = {
|
||||
token: requestTokenRes.oauth_token,
|
||||
secret: requestTokenRes.oauth_token_secret
|
||||
};
|
||||
ctx.session!.twitterOAuth = requestToken;
|
||||
url = `https://twitter.com/oauth/authenticate?oauth_token=${requestToken.token}`;
|
||||
else // Twitter
|
||||
{
|
||||
ctx.session.loginState = 'twitter';
|
||||
const { TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET } = process.env;
|
||||
if (TWITTER_CONSUMER_KEY === null || TWITTER_CONSUMER_SECRET === null)
|
||||
ctx.throw(500, 'twitter not supported in this server.');
|
||||
const requestTokenRes = await requestOAuth(twitterClient,
|
||||
{
|
||||
url: 'https://api.twitter.com/oauth/request_token',
|
||||
method: 'POST',
|
||||
data: {}
|
||||
}).then((r) => r.text()).then((r) => QueryStringUtils.decode(r));
|
||||
const requestToken =
|
||||
{
|
||||
token: requestTokenRes.oauth_token,
|
||||
secret: requestTokenRes.oauth_token_secret
|
||||
};
|
||||
ctx.session.twitterOAuth = requestToken;
|
||||
url = `https://twitter.com/oauth/authenticate?oauth_token=${requestToken.token}`;
|
||||
}
|
||||
ctx.body = {
|
||||
url
|
||||
};
|
||||
ctx.body = { url };
|
||||
});
|
||||
|
||||
router.get('/redirect', async (ctx) =>
|
||||
router.get('/redirect', async (ctx: Koa.ParameterizedContext) =>
|
||||
{
|
||||
let profile: {
|
||||
id: string;
|
||||
name: string;
|
||||
screenName: string;
|
||||
avatarUrl: string;
|
||||
accessToken: string;
|
||||
hostName: string;
|
||||
url: string;
|
||||
acct: string;
|
||||
};
|
||||
if (ctx.session!.loginState !== 'twitter')
|
||||
{
|
||||
if (ctx.query.state !== ctx.session!.loginState)
|
||||
let profile:
|
||||
{
|
||||
ctx.redirect('/login?error=invalid_state');
|
||||
return;
|
||||
}
|
||||
const app = await MastodonApp.findById(ctx.session!.loginState.split('_')[1]);
|
||||
if (app == null)
|
||||
{
|
||||
ctx.redirect('/login?error=app_notfound');
|
||||
return;
|
||||
}
|
||||
const res = await fetch('https://' + app.hostName + '/oauth/token', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
grant_type: 'authorization_code',
|
||||
redirect_uri: app.redirectUri,
|
||||
client_id: app.clientId,
|
||||
client_secret: app.clientSecret,
|
||||
code: ctx.query.code,
|
||||
state: ctx.query.state
|
||||
}),
|
||||
headers: {'Content-Type': 'application/json'}
|
||||
}).then((r) => r.json());
|
||||
const myProfile = await fetch('https://' + app.hostName + '/api/v1/accounts/verify_credentials', {
|
||||
headers: {Authorization: 'Bearer ' + res.access_token}
|
||||
}).then((r) => r.json());
|
||||
profile = {
|
||||
id: myProfile.id,
|
||||
name: myProfile.display_name || myProfile.username,
|
||||
screenName: myProfile.username,
|
||||
hostName: app.hostName,
|
||||
avatarUrl: myProfile.avatar_static,
|
||||
accessToken: res.access_token,
|
||||
url: myProfile.url,
|
||||
acct: myProfile.username + '@' + app.hostName
|
||||
id: string;
|
||||
name: string;
|
||||
screenName: string;
|
||||
avatarUrl: string;
|
||||
accessToken: string;
|
||||
hostName: string;
|
||||
url: string;
|
||||
acct: string;
|
||||
};
|
||||
|
||||
if (ctx.session.loginState !== 'twitter')
|
||||
{
|
||||
// Mastodon
|
||||
// TODO: handle misskey
|
||||
if (ctx.query.state !== ctx.session.loginState)
|
||||
return ctx.redirect('/login?error=invalid_state');
|
||||
|
||||
const app = await MastodonApp.findById(ctx.session.loginState.split('_')[1]);
|
||||
if (app === null)
|
||||
return ctx.redirect('/login?error=app_notfound');
|
||||
|
||||
const res = await fetch('https://' + app.hostName + '/oauth/token',
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
grant_type: 'authorization_code',
|
||||
redirect_uri: app.redirectUri,
|
||||
client_id: app.clientId,
|
||||
client_secret: app.clientSecret,
|
||||
code: ctx.query.code,
|
||||
state: ctx.query.state
|
||||
}),
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}).then((r) => r.json());
|
||||
|
||||
const myProfile = await fetch('https://' + app.hostName + '/api/v1/accounts/verify_credentials',
|
||||
{
|
||||
headers: { Authorization: 'Bearer ' + res.access_token }
|
||||
}).then((r) => r.json());
|
||||
|
||||
profile =
|
||||
{
|
||||
id: myProfile.id,
|
||||
name: myProfile.display_name || myProfile.username,
|
||||
screenName: myProfile.username,
|
||||
hostName: app.hostName,
|
||||
avatarUrl: myProfile.avatar_static,
|
||||
accessToken: res.access_token,
|
||||
url: myProfile.url,
|
||||
acct: myProfile.username + '@' + app.hostName
|
||||
};
|
||||
}
|
||||
else
|
||||
{ // twitter
|
||||
const requestToken: {
|
||||
const requestToken:
|
||||
{
|
||||
token: string;
|
||||
secret: string;
|
||||
} | undefined = ctx.session!.twitterOAuth;
|
||||
if (!requestToken) return ctx.redirect('/login?error=no_request_token');
|
||||
if (requestToken.token !== ctx.query.oauth_token) return ctx.redirect('/login?error=invalid_request_token');
|
||||
} | undefined = ctx.session.twitterOAuth;
|
||||
|
||||
if (!requestToken)
|
||||
return ctx.redirect('/login?error=no_request_token');
|
||||
if (requestToken.token !== ctx.query.oauth_token)
|
||||
return ctx.redirect('/login?error=invalid_request_token');
|
||||
|
||||
let accessToken;
|
||||
try
|
||||
{
|
||||
const accessTokenRes = await requestOAuth(twitterClient, {
|
||||
url: 'https://api.twitter.com/oauth/access_token',
|
||||
method: 'POST',
|
||||
data: {oauth_verifier: ctx.query.oauth_verifier}
|
||||
}, {
|
||||
key: requestToken.token,
|
||||
secret: requestToken.secret
|
||||
}).then((r) => r.text()).then((r) => QueryStringUtils.decode(r));
|
||||
accessToken = {
|
||||
key: accessTokenRes.oauth_token,
|
||||
secret: accessTokenRes.oauth_token_secret
|
||||
};
|
||||
const accessTokenRes = await requestOAuth(twitterClient,
|
||||
{
|
||||
url: 'https://api.twitter.com/oauth/access_token',
|
||||
method: 'POST',
|
||||
data: { oauth_verifier: ctx.query.oauth_verifier }
|
||||
},
|
||||
{
|
||||
key: requestToken.token,
|
||||
secret: requestToken.secret
|
||||
}).then((r) => r.text()).then((r) => QueryStringUtils.decode(r));
|
||||
accessToken =
|
||||
{
|
||||
key: accessTokenRes.oauth_token,
|
||||
secret: accessTokenRes.oauth_token_secret
|
||||
};
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
return ctx.redirect('/login?error=failed_access_token_fetch');
|
||||
}
|
||||
let a;
|
||||
|
||||
let resp;
|
||||
try
|
||||
{
|
||||
a = await requestOAuth(twitterClient, {
|
||||
url: 'https://api.twitter.com/1.1/account/verify_credentials.json',
|
||||
method: 'GET',
|
||||
data: {}
|
||||
}, accessToken).then((r) => r.json());
|
||||
resp = await requestOAuth(twitterClient,
|
||||
{
|
||||
url: 'https://api.twitter.com/1.1/account/verify_credentials.json',
|
||||
method: 'GET',
|
||||
data: {}
|
||||
}, accessToken).then((r) => r.json());
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
return ctx.redirect('/login?error=failed_user_profile_fetch');
|
||||
}
|
||||
profile = {
|
||||
id: a.id_str,
|
||||
name: a.name,
|
||||
screenName: a.screen_name,
|
||||
|
||||
profile =
|
||||
{
|
||||
id: resp.id_str,
|
||||
name: resp.name,
|
||||
screenName: resp.screen_name,
|
||||
hostName: 'twitter.com',
|
||||
avatarUrl: a.profile_image_url_https.replace('_normal.', '_400x400.'),
|
||||
avatarUrl: resp.profile_image_url_https.replace('_normal.', '_400x400.'),
|
||||
accessToken: accessToken.key + ':' + accessToken.secret,
|
||||
url: 'https://twitter.com/' + a.screen_name,
|
||||
acct: a.screen_name + ':' + a.id_str + '@twitter.com'
|
||||
url: 'https://twitter.com/' + resp.screen_name,
|
||||
acct: resp.screen_name + ':' + resp.id_str + '@twitter.com'
|
||||
};
|
||||
}
|
||||
if (!profile) return;
|
||||
|
||||
const acct = profile.acct;
|
||||
let user;
|
||||
if (profile.hostName !== 'twitter.com')
|
||||
{ // Mastodon
|
||||
{
|
||||
// Mastodon
|
||||
// TODO: misskey
|
||||
user = await User.findOne({acctLower: acct.toLowerCase()});
|
||||
}
|
||||
else
|
||||
{
|
||||
user = await User.findOne({upstreamId: profile.id, hostName: profile.hostName});
|
||||
}
|
||||
if (user == null)
|
||||
{
|
||||
if (user === null)
|
||||
user = new User();
|
||||
}
|
||||
|
||||
user.acct = acct;
|
||||
user.acctLower = acct.toLowerCase();
|
||||
user.name = profile.name;
|
||||
@ -202,8 +227,10 @@ router.get('/redirect', async (ctx) =>
|
||||
user.url = profile.url;
|
||||
user.upstreamId = profile.id;
|
||||
await user.save();
|
||||
ctx.session!.user = user.id;
|
||||
ctx.redirect('/my');
|
||||
|
||||
ctx.session.user = user.id;
|
||||
|
||||
ctx.redirect('/my');
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
@ -1,6 +1,8 @@
|
||||
import * as Router from 'koa-router';
|
||||
import * as mongoose from 'mongoose';
|
||||
import Koa from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import mongoose from 'mongoose';
|
||||
import fetch from 'node-fetch';
|
||||
import { stripIndents } from 'common-tags';
|
||||
import { BASE_URL } from '../../config';
|
||||
import { IMastodonApp, IUser, Question, QuestionLike, User } from '../../db/index';
|
||||
import { cutText } from '../../utils/cutText';
|
||||
@ -9,176 +11,224 @@ import twitterClient from '../../utils/twitterClient';
|
||||
|
||||
const router = new Router();
|
||||
|
||||
router.get('/', async (ctx) =>
|
||||
router.get('/', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
const questions = await Question.find({
|
||||
user: mongoose.Types.ObjectId(ctx.session!.user),
|
||||
answeredAt: null,
|
||||
isDeleted: {$ne: true}
|
||||
});
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const questions = await Question.find(
|
||||
{
|
||||
user: mongoose.Types.ObjectId(ctx.session.user),
|
||||
answeredAt: null,
|
||||
isDeleted: {$ne: true}
|
||||
});
|
||||
|
||||
ctx.body = JSON.stringify(questions);
|
||||
});
|
||||
|
||||
router.get('/count', async (ctx) =>
|
||||
router.get('/count', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
const count = await Question.find({
|
||||
user: mongoose.Types.ObjectId(ctx.session!.user),
|
||||
answeredAt: null,
|
||||
isDeleted: {$ne: true}
|
||||
}).count();
|
||||
ctx.body = {count};
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const count = await Question.find(
|
||||
{
|
||||
user: mongoose.Types.ObjectId(ctx.session!.user),
|
||||
answeredAt: null,
|
||||
isDeleted: {$ne: true}
|
||||
}).count();
|
||||
|
||||
ctx.body = { count };
|
||||
});
|
||||
|
||||
router.get('/latest', async (ctx) =>
|
||||
{
|
||||
const questions = await Question.find({
|
||||
answeredAt: {$ne: null},
|
||||
isDeleted: {$ne: true}
|
||||
}).limit(20).sort('-answeredAt');
|
||||
const questions = await Question.find(
|
||||
{
|
||||
answeredAt: {$ne: null},
|
||||
isDeleted: {$ne: true}
|
||||
}).limit(20).sort('-answeredAt');
|
||||
|
||||
ctx.body = questions;
|
||||
});
|
||||
|
||||
router.post('/:id/answer', async (ctx) =>
|
||||
router.post('/:id/answer', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const question = await Question.findById(ctx.params.id);
|
||||
if (!question) return ctx.throw('not found', 404);
|
||||
if (question.isDeleted) return ctx.throw('not found', 404);
|
||||
// tslint:disable-next-line:triple-equals
|
||||
if (question.user._id != ctx.session!.user) return ctx.throw('not found', 404);
|
||||
if (question.answeredAt) return ctx.throw('alread answered', 400);
|
||||
question.answer = ctx.request.body.fields.answer;
|
||||
if (question.answer!.length < 1) return ctx.throw('please input answer', 400);
|
||||
if (!question)
|
||||
return ctx.throw('not found', 404);
|
||||
if (question.isDeleted)
|
||||
return ctx.throw('not found', 404);
|
||||
if (question.user._id != ctx.session.user) // eslint-disable-line eqeqeq
|
||||
return ctx.throw('not found', 404);
|
||||
if (question.answeredAt)
|
||||
return ctx.throw('alread answered', 400);
|
||||
|
||||
question.answer = ctx.request.body.fields.answer as string;
|
||||
if (question.answer.length < 1)
|
||||
return ctx.throw('please input answer', 400);
|
||||
|
||||
question.answeredAt = new Date();
|
||||
if (ctx.request.body.fields.isNSFW) question.isNSFW = true;
|
||||
if (ctx.request.body.fields.isNSFW)
|
||||
question.isNSFW = true;
|
||||
await question.save();
|
||||
ctx.body = {status: 'ok'};
|
||||
const user = await User.findById(ctx.session!.user);
|
||||
if (!['public', 'unlisted', 'private'].includes(ctx.request.body.fields.visibility)) return;
|
||||
if (!user) return;
|
||||
|
||||
ctx.body = { status: 'ok' };
|
||||
|
||||
const user = await User.findById(ctx.session.user);
|
||||
if (!['public', 'unlisted', 'private'].includes(ctx.request.body.fields.visibility))
|
||||
return;
|
||||
if (!user)
|
||||
return;
|
||||
|
||||
const isTwitter = user.hostName === 'twitter.com';
|
||||
const answerCharMax = isTwitter ? (110 - question.question.length) : 200;
|
||||
const answerUrl = BASE_URL + '/@' + user.acct + '/questions/' + question.id;
|
||||
const answerUrl = `${BASE_URL}/@${user.acct}/questions/${question.id}`;
|
||||
if (!isTwitter)
|
||||
{ // Mastodon
|
||||
const body = {
|
||||
spoiler_text: 'Q. ' + question.question + ' #quesdon',
|
||||
status: [
|
||||
'A. ',
|
||||
(question.answer!.length > 200
|
||||
? question.answer!.substring(0, 200) + '...'
|
||||
: question.answer),
|
||||
'\n#quesdon ',
|
||||
answerUrl
|
||||
].join(''),
|
||||
visibility: ctx.request.body.fields.visibility
|
||||
};
|
||||
{
|
||||
// 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.fields.visibility
|
||||
};
|
||||
if (question.questionUser)
|
||||
{
|
||||
let questionUserAcct = '@' + question.questionUser.acct;
|
||||
let questionUserAcct = `@${question.questionUser.acct}`;
|
||||
if (question.questionUser.hostName === 'twitter.com')
|
||||
{
|
||||
questionUserAcct = 'https://twitter.com/' + question.questionUser.acct.replace(/:.+/, '');
|
||||
}
|
||||
body.status = '질문자: ' + questionUserAcct + '\n' + body.status;
|
||||
questionUserAcct = `https://twitter.com/${question.questionUser.acct.replace(/:.+/, '')}`;
|
||||
body.status = stripIndents`질문자: ${questionUserAcct}
|
||||
${body.status}`;
|
||||
}
|
||||
if (question.isNSFW)
|
||||
{
|
||||
body.status = 'Q. ' + question.question + '\n' + body.status;
|
||||
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'
|
||||
}
|
||||
});
|
||||
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 strA = cutText(question.answer, 120 - strQ.length);
|
||||
const [key, secret] = user.accessToken.split(':');
|
||||
const body = 'Q. ' + strQ + '\nA. ' + strA + '\n#quesdon ' + answerUrl;
|
||||
requestOAuth(twitterClient, {
|
||||
url: 'https://api.twitter.com/1.1/statuses/update.json',
|
||||
method: 'POST',
|
||||
data: {status: body}
|
||||
}, {
|
||||
key, secret
|
||||
});
|
||||
const body = `Q. ${strQ}
|
||||
A. ${strA}
|
||||
#quesdon ${answerUrl}`;
|
||||
requestOAuth(twitterClient,
|
||||
{
|
||||
url: 'https://api.twitter.com/1.1/statuses/update.json',
|
||||
method: 'POST',
|
||||
data: { status: body }
|
||||
}, { key, secret });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/delete', async (ctx) =>
|
||||
router.post('/:id/delete', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const question = await Question.findById(ctx.params.id);
|
||||
if (!question) return ctx.throw('not found', 404);
|
||||
// tslint:disable-next-line:triple-equals
|
||||
if (question.user._id != ctx.session!.user) return ctx.throw('not found', 404);
|
||||
if (!question)
|
||||
return ctx.throw('not found', 404);
|
||||
if (question.user._id != ctx.session.user) // eslint-disable-line eqeqeq
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
question.isDeleted = true;
|
||||
await question.save();
|
||||
ctx.body = {status: 'ok'};
|
||||
|
||||
ctx.body = { status: 'ok' };
|
||||
});
|
||||
|
||||
router.post('/:id/like', async (ctx) =>
|
||||
router.post('/:id/like', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const question = await Question.findById(ctx.params.id);
|
||||
if (!question) return ctx.throw('not found', 404);
|
||||
if (!question.answeredAt) return ctx.throw('not found', 404);
|
||||
if (await QuestionLike.findOne({question})) return ctx.throw('already liked', 400);
|
||||
if (!question)
|
||||
return ctx.throw('not found', 404);
|
||||
if (!question.answeredAt)
|
||||
return ctx.throw('not found', 404);
|
||||
if (await QuestionLike.findOne({question}))
|
||||
return ctx.throw('already liked', 400);
|
||||
|
||||
const like = new QuestionLike();
|
||||
like.question = question;
|
||||
like.user = mongoose.Types.ObjectId(ctx.session!.user);
|
||||
like.user = mongoose.Types.ObjectId(ctx.session.user);
|
||||
await like.save();
|
||||
question.likesCount = await QuestionLike.find({question}).count();
|
||||
|
||||
await question.save();
|
||||
ctx.body = {status: 'ok'};
|
||||
|
||||
ctx.body = { status: 'ok' };
|
||||
});
|
||||
|
||||
router.post('/:id/unlike', async (ctx) =>
|
||||
router.post('/:id/unlike', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
const question = await Question.findById(ctx.params.id);
|
||||
const user = mongoose.Types.ObjectId(ctx.session!.user);
|
||||
if (!question) return ctx.throw('not found', 404);
|
||||
if (!question.answeredAt) return ctx.throw('not found', 404);
|
||||
const user = mongoose.Types.ObjectId(ctx.session.user);
|
||||
if (!question)
|
||||
return ctx.throw('not found', 404);
|
||||
if (!question.answeredAt)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
const like = await QuestionLike.findOne({question, user});
|
||||
if (!like) return ctx.throw('not liked', 400);
|
||||
if (!like)
|
||||
return ctx.throw('not liked', 400);
|
||||
await like.remove();
|
||||
question.likesCount = await QuestionLike.find({question}).count();
|
||||
|
||||
await question.save();
|
||||
ctx.body = {status: 'ok'};
|
||||
ctx.body = { status: 'ok' };
|
||||
});
|
||||
|
||||
router.get('/:id', async (ctx) =>
|
||||
router.get('/:id', async (ctx): Promise<never|void> =>
|
||||
{
|
||||
const question = await Question.findById(ctx.params.id);
|
||||
if (!question) return ctx.throw('not found', 404);
|
||||
if (!question.answeredAt) return ctx.throw('not found', 404);
|
||||
if (question.isDeleted) return ctx.throw('not found', 404);
|
||||
if (!question)
|
||||
return ctx.throw('not found', 404);
|
||||
if (!question.answeredAt)
|
||||
return ctx.throw('not found', 404);
|
||||
if (question.isDeleted)
|
||||
return ctx.throw('not found', 404);
|
||||
|
||||
ctx.body = question;
|
||||
});
|
||||
|
||||
router.post('/all_delete', async (ctx) =>
|
||||
router.post('/all_delete', async (ctx: Koa.ParameterizedContext): Promise<never|void> =>
|
||||
{
|
||||
if (!ctx.session!.user) return ctx.throw('please login', 403);
|
||||
await Question.update({
|
||||
user: mongoose.Types.ObjectId(ctx.session!.user)
|
||||
}, {
|
||||
$set: {
|
||||
isDeleted: true
|
||||
}
|
||||
}, {
|
||||
multi: true
|
||||
});
|
||||
ctx.body = {status: 'ok'};
|
||||
if (!ctx.session.user)
|
||||
return ctx.throw('please login', 403);
|
||||
|
||||
await Question.update(
|
||||
{ user: mongoose.Types.ObjectId(ctx.session.user) },
|
||||
{
|
||||
$set: { isDeleted: true }
|
||||
},
|
||||
{ multi: true });
|
||||
|
||||
ctx.body = { status: 'ok' };
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
@ -13,7 +13,7 @@ export const MONGODB_URL = process.env.MONGODB_URL || 'mongodb://localhost/quesd
|
||||
|
||||
export const SECRET_KEY = process.env.SECRET_KEY || 'shibuyarin16544';
|
||||
|
||||
export var GIT_COMMIT = execSync('git rev-parse HEAD').toString().trim();
|
||||
export const GIT_COMMIT = execSync('git rev-parse HEAD').toString().trim();
|
||||
|
||||
export const PUSHBULLET_CLIENT_ID = process.env.PUSHBULLET_CLIENT_ID;
|
||||
export const PUSHBULLET_CLIENT_SECRET = process.env.PUSHBULLET_CLIENT_SECRET;
|
||||
|
@ -1,16 +1,16 @@
|
||||
import * as mongoose from 'mongoose';
|
||||
|
||||
const schema = new mongoose.Schema({
|
||||
hostName: {type: String, required: true},
|
||||
clientId: {type: String, required: true},
|
||||
clientSecret: {type: String, required: true},
|
||||
appBaseUrl: {type: String, required: true},
|
||||
redirectUri: {type: String, required: true}
|
||||
}, {
|
||||
timestamps: true
|
||||
});
|
||||
const schema = new mongoose.Schema(
|
||||
{
|
||||
hostName: {type: String, required: true},
|
||||
clientId: {type: String, required: true},
|
||||
clientSecret: {type: String, required: true},
|
||||
appBaseUrl: {type: String, required: true},
|
||||
redirectUri: {type: String, required: true}
|
||||
}, { timestamps: true });
|
||||
|
||||
export interface IMastodonApp extends mongoose.Document {
|
||||
export interface IMastodonApp extends mongoose.Document
|
||||
{
|
||||
hostName: string;
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
@ -18,4 +18,4 @@ export interface IMastodonApp extends mongoose.Document {
|
||||
redirectUri: string;
|
||||
}
|
||||
|
||||
export default mongoose.model('mastodon_apps', schema);
|
||||
export default mongoose.model<IMastodonApp>('mastodon_apps', schema);
|
||||
|
@ -3,7 +3,7 @@ import { MONGODB_URL } from '../config';
|
||||
|
||||
mongoose.connect(MONGODB_URL).catch((e) =>
|
||||
{
|
||||
console.error('MongoDB Error: ' + e.message);
|
||||
console.error('MongoDB Error: ' + e.message); // eslint-disable-line no-console
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
5
src/server/db/mongoose-autopopulate.d.ts
vendored
Normal file
5
src/server/db/mongoose-autopopulate.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
declare module 'mongoose-autopopulate'
|
||||
{
|
||||
import { Schema } from 'mongoose';
|
||||
export default function autopopulate(schema: Schema): void;
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
import * as mongoose from 'mongoose';
|
||||
import { IQuestion, IUser } from './index';
|
||||
|
||||
const schema = new mongoose.Schema({
|
||||
user: {type: mongoose.Schema.Types.ObjectId, required: true, ref: 'users'},
|
||||
question: {type: mongoose.Schema.Types.ObjectId, required: true, ref: 'questions'}
|
||||
}, {
|
||||
timestamps: true
|
||||
});
|
||||
const schema = new mongoose.Schema(
|
||||
{
|
||||
user: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'users' },
|
||||
question: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'questions' }
|
||||
}, { timestamps: true });
|
||||
|
||||
export interface IQuestionLike extends mongoose.Document {
|
||||
export interface IQuestionLike extends mongoose.Document
|
||||
{
|
||||
user: IUser | mongoose.Types.ObjectId;
|
||||
question: IQuestion | mongoose.Types.ObjectId;
|
||||
}
|
||||
|
||||
export default mongoose.model('question_likes', schema);
|
||||
export default mongoose.model<IQuestionLike>('question_likes', schema);
|
||||
|
@ -1,23 +1,22 @@
|
||||
import * as mongoose from 'mongoose';
|
||||
import { IUser } from './index';
|
||||
// tslint:disable-next-line:no-var-requires
|
||||
const autopopulate = require('mongoose-autopopulate'); // @types/がないのでしかたない
|
||||
import autopopulate from 'mongoose-autopopulate';
|
||||
|
||||
const schema = new mongoose.Schema({
|
||||
user: {type: mongoose.Schema.Types.ObjectId, required: true, ref: 'users', autopopulate: true},
|
||||
question: {type: String, required: true},
|
||||
answer: String,
|
||||
answeredAt: Date,
|
||||
isDeleted: {type: Boolean, default: false},
|
||||
likesCount: {type: Number, default: 0},
|
||||
isNSFW: {type: Boolean, default: false},
|
||||
questionUser: {type: mongoose.Schema.Types.ObjectId, ref: 'users', autopopulate: true}
|
||||
}, {
|
||||
timestamps: true
|
||||
});
|
||||
const schema = new mongoose.Schema(
|
||||
{
|
||||
user: {type: mongoose.Schema.Types.ObjectId, required: true, ref: 'users', autopopulate: true},
|
||||
question: {type: String, required: true},
|
||||
answer: String,
|
||||
answeredAt: Date,
|
||||
isDeleted: {type: Boolean, default: false},
|
||||
likesCount: {type: Number, default: 0},
|
||||
isNSFW: {type: Boolean, default: false},
|
||||
questionUser: {type: mongoose.Schema.Types.ObjectId, ref: 'users', autopopulate: true}
|
||||
}, { timestamps: true });
|
||||
schema.plugin(autopopulate);
|
||||
|
||||
export interface IQuestion extends mongoose.Document {
|
||||
export interface IQuestion extends mongoose.Document
|
||||
{
|
||||
user: IUser;
|
||||
question: string;
|
||||
answer: string | null;
|
||||
@ -28,4 +27,4 @@ export interface IQuestion extends mongoose.Document {
|
||||
questionUser: IUser;
|
||||
}
|
||||
|
||||
export default mongoose.model('questions', schema);
|
||||
export default mongoose.model<IQuestion>('questions', schema);
|
||||
|
@ -1,27 +1,26 @@
|
||||
import * as mongoose from 'mongoose';
|
||||
import mongoose from 'mongoose';
|
||||
import setTransformer from '../utils/setTransformer';
|
||||
import { IMastodonApp } from './';
|
||||
|
||||
const schema = new mongoose.Schema({
|
||||
acct: {type: String, required: true},
|
||||
acctLower: {type: String, required: true, unique: true},
|
||||
app: {type: mongoose.Schema.Types.ObjectId, ref: 'mastodon_apps'},
|
||||
name: {type: String, required: true},
|
||||
avatarUrl: {type: String, required: true},
|
||||
accessToken: {type: String, required: true},
|
||||
url: {type: String},
|
||||
description: {type: String, default: ''},
|
||||
questionBoxName: {type: String, default: '질문 상자'},
|
||||
pushbulletAccessToken: {type: String},
|
||||
allAnon: {type: Boolean, default: false},
|
||||
upstreamId: {type: String},
|
||||
hostName: {type: String},
|
||||
stopNewQuestion: {type: Boolean}
|
||||
}, {
|
||||
timestamps: true
|
||||
});
|
||||
const schema = new mongoose.Schema(
|
||||
{
|
||||
acct: { type: String, required: true },
|
||||
acctLower: { type: String, required: true, unique: true },
|
||||
app: { type: mongoose.Schema.Types.ObjectId, ref: 'mastodon_apps' },
|
||||
name: { type: String, required: true },
|
||||
avatarUrl: { type: String, required: true },
|
||||
accessToken: { type: String, required: true },
|
||||
url: { type: String },
|
||||
description: { type: String, default: '' },
|
||||
questionBoxName: { type: String, default: '질문 상자' },
|
||||
pushbulletAccessToken: { type: String },
|
||||
allAnon: { type: Boolean, default: false },
|
||||
upstreamId: { type: String },
|
||||
hostName: { type: String },
|
||||
stopNewQuestion: { type: Boolean }
|
||||
}, { timestamps: true });
|
||||
|
||||
setTransformer(schema, (doc: IUser, ret: any) =>
|
||||
setTransformer(schema, (doc: IUser, ret: any) => // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
{
|
||||
ret.hostName = ret.acctLower.split('@').reverse()[0];
|
||||
delete ret.app;
|
||||
@ -52,4 +51,4 @@ export interface IUser extends mongoose.Document {
|
||||
stopNewQuestion: boolean | null;
|
||||
}
|
||||
|
||||
export default mongoose.model('users', schema);
|
||||
export default mongoose.model<IUser>('users', schema);
|
||||
|
@ -1,10 +1,11 @@
|
||||
import * as Koa from 'koa';
|
||||
import * as koaBody from 'koa-body';
|
||||
import * as mount from 'koa-mount';
|
||||
import * as Pug from 'koa-pug';
|
||||
import * as Router from 'koa-router';
|
||||
import * as session from 'koa-session';
|
||||
import * as path from 'path';
|
||||
import Koa from 'koa';
|
||||
import koaBody from 'koa-body';
|
||||
import mount from 'koa-mount';
|
||||
import Pug from 'koa-pug';
|
||||
import Router from 'koa-router';
|
||||
import session from 'koa-session';
|
||||
import koaStaticCache from 'koa-static-cache';
|
||||
import path from 'path';
|
||||
import rndstr from 'rndstr';
|
||||
import apiRouter from './api';
|
||||
import { GIT_COMMIT, PORT, SECRET_KEY } from './config';
|
||||
@ -14,47 +15,34 @@ const app = new Koa();
|
||||
|
||||
app.keys = [SECRET_KEY];
|
||||
|
||||
new Pug({
|
||||
viewPath: path.join(__dirname, '../../views')
|
||||
}).use(app);
|
||||
app.use(koaBody({
|
||||
multipart: true
|
||||
}));
|
||||
app.use(session({
|
||||
}, app));
|
||||
new Pug( { viewPath: path.join(__dirname, '../../views') } ).use(app);
|
||||
app.use(koaBody( { multipart: true } ));
|
||||
app.use(session({}, app));
|
||||
|
||||
// tslint:disable-next-line:no-var-requires
|
||||
app.use(mount('/assets', require('koa-static-cache')(__dirname + '/../client')));
|
||||
app.use(mount('/assets', koaStaticCache(__dirname + '/../client')));
|
||||
|
||||
const router = new Router();
|
||||
|
||||
router.use('/api', apiRouter.routes());
|
||||
|
||||
router.get('/*', async (ctx) =>
|
||||
router.get('/*', async (ctx: Koa.ParameterizedContext) =>
|
||||
{
|
||||
let user;
|
||||
if (ctx.session!.user)
|
||||
if (ctx.session.user)
|
||||
{
|
||||
user = await User.findById(ctx.session!.user);
|
||||
user = JSON.stringify(user).replace(/[\u0080-\uFFFF]/g, (chr) =>
|
||||
{
|
||||
return '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).substr(-4);
|
||||
});
|
||||
user = await User.findById(ctx.session.user);
|
||||
user = JSON.stringify(user).replace(/[\u0080-\uFFFF]/g, (chr) => '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).substr(-4) );
|
||||
user = new Buffer(user, 'binary').toString('base64');
|
||||
}
|
||||
if (!ctx.session!.csrfToken)
|
||||
{
|
||||
ctx.session!.csrfToken = rndstr();
|
||||
}
|
||||
ctx.render('index.pug', {
|
||||
GIT_COMMIT,
|
||||
user,
|
||||
csrfToken: ctx.session!.csrfToken
|
||||
});
|
||||
if (!ctx.session.csrfToken)
|
||||
ctx.session.csrfToken = rndstr();
|
||||
ctx.render('index.pug',
|
||||
{
|
||||
GIT_COMMIT,
|
||||
user,
|
||||
csrfToken: ctx.session.csrfToken
|
||||
});
|
||||
});
|
||||
|
||||
app.use(router.routes());
|
||||
app.listen(PORT, () =>
|
||||
{
|
||||
console.log('listen for http://localhost:' + PORT);
|
||||
});
|
||||
app.listen(PORT, () => console.log('listen for http://localhost:' + PORT) ); // eslint-disable-line no-console
|
||||
|
@ -1,11 +1,7 @@
|
||||
export function cutText(s: string, l: number)
|
||||
export function cutText(s: string, l: number): string
|
||||
{
|
||||
if (s.length <= l)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
else
|
||||
{
|
||||
return s.slice(0, l - 1) + '…';
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,14 @@ import * as OAuth from 'oauth-1.0a';
|
||||
|
||||
export default new class QueryStringUtils
|
||||
{
|
||||
decode(query: string)
|
||||
decode(query: string): { [key: string]: string }
|
||||
{
|
||||
const res: {[key: string]: string} = {};
|
||||
query.split('&').map((q) =>
|
||||
{
|
||||
const splitedQuery = q.split('=');
|
||||
if (splitedQuery.length < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const name = splitedQuery[0];
|
||||
const value = splitedQuery.slice(1).join('=');
|
||||
res[name] = decodeURIComponent(value);
|
||||
@ -19,11 +17,10 @@ export default new class QueryStringUtils
|
||||
return res;
|
||||
}
|
||||
|
||||
encode(params: {[key: string]: any})
|
||||
encode(params: {[key: string]: any}): string // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
{
|
||||
return Object.keys(params).map((key) =>
|
||||
{
|
||||
return encodeURIComponent(key) + '=' + OAuth.prototype.percentEncode(params[key]);
|
||||
}).join('&');
|
||||
return Object.keys(params).map(
|
||||
(key) => encodeURIComponent(key) + '=' + OAuth.prototype.percentEncode(params[key])
|
||||
).join('&');
|
||||
}
|
||||
}();
|
||||
|
@ -2,23 +2,27 @@ import fetch, { Response } from 'node-fetch';
|
||||
import * as OAuth from 'oauth-1.0a';
|
||||
import QueryStringUtils from './queryString';
|
||||
|
||||
export function requestOAuth(oauth: OAuth, options: OAuth.RequestOptions, token?: OAuth.Token)
|
||||
export function requestOAuth(oauth: OAuth, options: OAuth.RequestOptions, token?: OAuth.Token): Promise<Response>
|
||||
{
|
||||
const opt = {
|
||||
const opt =
|
||||
{
|
||||
url: options.url,
|
||||
method: options.method,
|
||||
body: QueryStringUtils.encode(options.data),
|
||||
headers: {
|
||||
...oauth.toHeader(oauth.authorize(options, token)),
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
headers:
|
||||
{
|
||||
...oauth.toHeader(oauth.authorize(options, token)),
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
};
|
||||
|
||||
if (options.method === 'GET')
|
||||
{
|
||||
opt.url += '?' + opt.body;
|
||||
delete opt.body;
|
||||
delete opt.headers['Content-Type'];
|
||||
}
|
||||
|
||||
return fetch(opt.url, opt).then((r) =>
|
||||
{
|
||||
if (!r.ok)
|
||||
|
@ -1,14 +1,16 @@
|
||||
/* eslint @typescript-eslint/no-explicit-any: 0 */
|
||||
/* eslint @typescript-eslint/explicit-function-return-type: 0 */
|
||||
/* eslint eqeqeq: 0 */
|
||||
|
||||
import * as mongoose from 'mongoose';
|
||||
export default (schema: mongoose.Schema, transformer: (doc: any, ret: any) => any) =>
|
||||
{
|
||||
if ((schema as any).options.toObject == null)
|
||||
{
|
||||
(schema as any).options.toObject = {};
|
||||
}
|
||||
|
||||
if ((schema as any).options.toJSON == null)
|
||||
{
|
||||
(schema as any).options.toJSON = {};
|
||||
}
|
||||
|
||||
(schema as any).options.toObject.transform = transformer;
|
||||
(schema as any).options.toJSON.transform = transformer;
|
||||
};
|
||||
|
@ -1,17 +1,21 @@
|
||||
import * as crypto from 'crypto';
|
||||
import * as OAuth from 'oauth-1.0a';
|
||||
import OAuth from 'oauth-1.0a';
|
||||
|
||||
const twitterClient = new OAuth({
|
||||
consumer: {
|
||||
key: process.env.TWITTER_CONSUMER_KEY!,
|
||||
secret: process.env.TWITTER_CONSUMER_SECRET!
|
||||
},
|
||||
signature_method: 'HMAC-SHA1',
|
||||
hash_function(baseString, key)
|
||||
const twitterClient = new OAuth(
|
||||
{
|
||||
return crypto.createHmac('sha1', key).update(baseString).digest('base64');
|
||||
},
|
||||
realm: ''
|
||||
});
|
||||
consumer:
|
||||
{
|
||||
key: process.env.TWITTER_CONSUMER_KEY ?? '',
|
||||
secret: process.env.TWITTER_CONSUMER_SECRET ?? ''
|
||||
},
|
||||
signature_method: 'HMAC-SHA1',
|
||||
|
||||
hash_function(baseString, key): string
|
||||
{
|
||||
return crypto.createHmac('sha1', key).update(baseString).digest('base64');
|
||||
},
|
||||
|
||||
realm: ''
|
||||
});
|
||||
|
||||
export default twitterClient;
|
||||
|
@ -1,24 +1,24 @@
|
||||
doctype html
|
||||
html
|
||||
head
|
||||
meta(name="viewport",content="width=device-width")
|
||||
if user
|
||||
script window.USER=JSON.parse(atob("!{user}"))
|
||||
else
|
||||
script window.USER=undefined
|
||||
script window.CSRF_TOKEN="#{csrfToken}"
|
||||
script window.GIT_VERSION="#{GIT_COMMIT}"
|
||||
script(src="https://cdn.polyfill.io/v2/polyfill.js?features=fetch")
|
||||
script(src="/assets/bundle.js?version="+GIT_COMMIT)
|
||||
body
|
||||
#root
|
||||
p ...어? 혹시 페이지가 나오지 않나요??
|
||||
p 불편을 끼쳐 드려 죄송해요. 새로고침을 해 보시고, 만약 그래도 이 화면만 계속 뜬다면 아래 동작 환경을 충족하는지 확인 후 Mastodon @planet@planet.moe 에 문의해 주세요.
|
||||
h2 동작 환경
|
||||
ul
|
||||
li iOS
|
||||
del 9.3.5
|
||||
| 10 이상 (추천: iOS 11.2.2 이상)
|
||||
li Chrome 63 이상
|
||||
li Firefox 57 이상
|
||||
p Edge, Internet Explorer는 지원 대상이 아니라서 오류가 발생할 수 있어요. Firefox나 Google Chrome을 추천드려요.
|
||||
head
|
||||
meta(name="viewport",content="width=device-width")
|
||||
if user
|
||||
script window.USER=JSON.parse(atob("!{user}"))
|
||||
else
|
||||
script window.USER=undefined
|
||||
script window.CSRF_TOKEN="#{csrfToken}"
|
||||
script window.GIT_VERSION="#{GIT_COMMIT}"
|
||||
script(src="https://cdn.polyfill.io/v2/polyfill.js?features=fetch")
|
||||
script(src="/assets/bundle.js?version="+GIT_COMMIT)
|
||||
body
|
||||
#root
|
||||
p ...어? 혹시 페이지가 나오지 않나요??
|
||||
p 불편을 끼쳐 드려 죄송해요. 새로고침을 해 보시고, 만약 그래도 이 화면만 계속 뜬다면 아래 동작 환경을 충족하는지 확인 후 Mastodon @planet@planet.moe 에 문의해 주세요.
|
||||
h2 동작 환경
|
||||
ul
|
||||
li iOS
|
||||
del 9.3.5
|
||||
| 10 이상 (추천: iOS 11.2.2 이상)
|
||||
li Chrome 63 이상
|
||||
li Firefox 57 이상
|
||||
p Edge, Internet Explorer는 지원 대상이 아니라서 오류가 발생할 수 있어요. Firefox나 Google Chrome을 추천드려요.
|
7587
yarn-error.log
Normal file
7587
yarn-error.log
Normal file
File diff suppressed because it is too large
Load Diff
562
yarn.lock
562
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.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.3.tgz#935122c74c73d2240cafd32ddb5fc2a6cd35cf1f"
|
||||
integrity sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==
|
||||
version "7.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.1.tgz#b223497bbfbcbbb38116673904debc71470ca528"
|
||||
integrity sha512-SQ0sS7KUJDvgCI2cpZG0nJygO6002oTbhgSuw4WcocsnbxLwL5Q8I3fqbJdyBAc3uFrWZiR2JomseuxSuci3SQ==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
@ -59,6 +59,16 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/caseless@*":
|
||||
version "0.12.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8"
|
||||
integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==
|
||||
|
||||
"@types/common-tags@^1.8.0":
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/common-tags/-/common-tags-1.8.0.tgz#79d55e748d730b997be5b7fce4b74488d8b26a6b"
|
||||
integrity sha512-htRqZr5qn8EzMelhX/Xmx142z218lLyGaeZ3YR8jlze4TATRU9huKKvuBmAJEW4LCC4pnY1N6JAm6p85fMHjhg==
|
||||
|
||||
"@types/connect@*":
|
||||
version "3.4.32"
|
||||
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28"
|
||||
@ -94,17 +104,17 @@
|
||||
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
|
||||
|
||||
"@types/express-serve-static-core@*":
|
||||
version "4.16.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.10.tgz#3c1313c6e6b75594561b473a286f016a9abf2132"
|
||||
integrity sha512-gM6evDj0OvTILTRKilh9T5dTaGpv1oYiFcJAfgSejuMJgGJUsD9hKEU2lB4aiTNy4WwChxRnjfYFuBQsULzsJw==
|
||||
version "4.16.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.11.tgz#46e8cb091de19d51731a05c2581e515855979dad"
|
||||
integrity sha512-K8d2M5t3tBQimkyaYTXxtHYyoJPUEhy2/omVRnTAKw5FEdT+Ft6lTaTOpoJdHeG+mIwQXXtqiTcYZ6IR8LTzjQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
"@types/range-parser" "*"
|
||||
|
||||
"@types/express@*":
|
||||
version "4.17.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.1.tgz#4cf7849ae3b47125a567dfee18bfca4254b88c5c"
|
||||
integrity sha512-VfH/XCP0QbQk5B5puLqTLEeFgR8lfCJHZJKkInZ9mkYd+u8byX0kztXEQxEk4wZXJs8HI+7km2ALXjn4YKcX9w==
|
||||
version "4.17.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.2.tgz#a0fb7a23d8855bac31bc01d5a58cadd9b2173e6c"
|
||||
integrity sha512-5mHFNyavtLoJmnusB8OKJ5bshSzw+qkMIBAobLrIM48HJvunFva9mOa6aBwh64lBFyNwBbs0xiEFuj4eU/NjCA==
|
||||
dependencies:
|
||||
"@types/body-parser" "*"
|
||||
"@types/express-serve-static-core" "*"
|
||||
@ -190,6 +200,13 @@
|
||||
"@types/cookies" "*"
|
||||
"@types/koa" "*"
|
||||
|
||||
"@types/koa-static-cache@^5.1.0":
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/koa-static-cache/-/koa-static-cache-5.1.0.tgz#37c33f877ecd92c13065ed402184632ab18da326"
|
||||
integrity sha512-9n89fpWYyhfdpjDmHYJikeah6r2F3LC8F+dm+nuCrKd+7R4CiCnlYbNR1AfB3H/1b7Ndz+uucrAycwi9u7QtRA==
|
||||
dependencies:
|
||||
"@types/koa" "*"
|
||||
|
||||
"@types/koa-static@^4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/koa-static/-/koa-static-4.0.1.tgz#b740d80a549b0a0a7a3b38918daecde88a7a50ec"
|
||||
@ -221,32 +238,39 @@
|
||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||
|
||||
"@types/mongodb@*":
|
||||
version "3.3.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-3.3.7.tgz#f11fbad6ea48135634bce7e70080031cb35c5c84"
|
||||
integrity sha512-X/yDgFAgn3ypXN/CcckHe3nzxaliGtvrJ52kW2k9MAHDfYpc83wvvqHECfmx88pfrrquxFgRWqCTXprqABPfbw==
|
||||
version "3.3.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-3.3.8.tgz#a6023ff343a90478c0e22b2b5d35e56964c3ba60"
|
||||
integrity sha512-hsLcKRBFVeam4FyJOU6bwklvsNHzmUBI5SIxQ2meZu+RZgTDzrv+W19YAHgDIuiTn6UqHrVolweLMk0RpKEbxg==
|
||||
dependencies:
|
||||
"@types/bson" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/mongoose@^5.5.28":
|
||||
version "5.5.28"
|
||||
resolved "https://registry.yarnpkg.com/@types/mongoose/-/mongoose-5.5.28.tgz#8f52367c7d05ada15086a50c6f087f13c8949906"
|
||||
integrity sha512-1VPsBwiJeYDe4E9h8XIL+c3w3q+RzNQwd2R7tnQ8XO7UDOoLOIK4oIRNTUjQY7PFBWAZpzjOggvNDwUkPIDSDQ==
|
||||
"@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==
|
||||
dependencies:
|
||||
"@types/mongodb" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node-fetch@^2.5.2":
|
||||
version "2.5.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.2.tgz#76906dea5b3d6901e50e63e15249c9bcd6e9676e"
|
||||
integrity sha512-djYYKmdNRSBtL1x4CiE9UJb9yZhwtI1VC+UxZD0psNznrUj80ywsxKlEGAE+QL1qvLjPbfb24VosjkYM6W4RSQ==
|
||||
"@types/node-fetch@^2.5.3":
|
||||
version "2.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.3.tgz#b84127facd93642b1fb6439bc630ba0612e3ec50"
|
||||
integrity sha512-X3TNlzZ7SuSwZsMkb5fV7GrPbVKvHc2iwHmslb8bIxRKWg2iqkfm3F/Wd79RhDpOXR7wCtKAwc5Y2JE6n/ibyw==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*":
|
||||
version "12.12.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.3.tgz#ebfe83507ac506bc3486314a8aa395be66af8d23"
|
||||
integrity sha512-opgSsy+cEF9N8MgaVPnWVtdJ3o4mV2aMHvDq7thkQUFt0EuOHJon4rQpJfhjmNHB+ikl0Cd6WhWIErOyQ+f7tw==
|
||||
version "12.12.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.6.tgz#a47240c10d86a9a57bb0c633f0b2e0aea9ce9253"
|
||||
integrity sha512-FjsYUPzEJdGXjwKqSpE0/9QEh6kzhTAeObA54rn6j3rR4C/mzpI9L0KNfoeASSPMMdxIsoJuCLDWcM/rVjIsSA==
|
||||
|
||||
"@types/oauth@^0.9.0":
|
||||
version "0.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/oauth/-/oauth-0.9.1.tgz#e17221e7f7936b0459ae7d006255dff61adca305"
|
||||
integrity sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/parse-link-header@^1.0.0":
|
||||
version "1.0.0"
|
||||
@ -270,10 +294,10 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-router-dom@^5.1.1":
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.1.1.tgz#77a2dae8ba6ff1df51d27517f7646127a51a1a3e"
|
||||
integrity sha512-yXqWGaehta/cdmjvEQfCbHFX6l1c7QHuE5n2OfhcJ33ufbt55xhAKqQ0BmT24YM3s7OKwrrUUgY3FaSzO7be3Q==
|
||||
"@types/react-router-dom@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.1.2.tgz#853f229f1f297513c0be84f7c914a08b778cfdf5"
|
||||
integrity sha512-kRx8hoBflE4Dp7uus+j/0uMHR5uGTAvQtc4A3vOTWKS+epe0leCuxEx7HNT7XGUd1lH53/moWM51MV2YUyhzAg==
|
||||
dependencies:
|
||||
"@types/history" "*"
|
||||
"@types/react" "*"
|
||||
@ -303,6 +327,16 @@
|
||||
"@types/react" "*"
|
||||
popper.js "^1.14.1"
|
||||
|
||||
"@types/request@^2.47.0":
|
||||
version "2.48.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.3.tgz#970b8ed2317568c390361d29c555a95e74bd6135"
|
||||
integrity sha512-3Wo2jNYwqgXcIz/rrq18AdOZUQB8cQ34CXZo+LUwPJNpvRAL86+Kc2wwI8mqpz9Cr1V+enIox5v+WZhy/p3h8w==
|
||||
dependencies:
|
||||
"@types/caseless" "*"
|
||||
"@types/node" "*"
|
||||
"@types/tough-cookie" "*"
|
||||
form-data "^2.5.0"
|
||||
|
||||
"@types/serve-static@*":
|
||||
version "1.13.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.3.tgz#eb7e1c41c4468272557e897e9171ded5e2ded9d1"
|
||||
@ -311,46 +345,59 @@
|
||||
"@types/express-serve-static-core" "*"
|
||||
"@types/mime" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^2.6.0":
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.6.0.tgz#e82ed43fc4527b21bfe35c20a2d6e4ed49fc7957"
|
||||
integrity sha512-iCcXREU4RciLmLniwKLRPCOFVXrkF7z27XuHq5DrykpREv/mz6ztKAyLg2fdkM0hQC7659p5ZF5uStH7uzAJ/w==
|
||||
"@types/tough-cookie@*":
|
||||
version "2.3.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.5.tgz#9da44ed75571999b65c37b60c9b2b88db54c585d"
|
||||
integrity sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==
|
||||
|
||||
"@types/ws@^6.0.1":
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.3.tgz#b772375ba59d79066561c8d87500144d674ba6b3"
|
||||
integrity sha512-yBTM0P05Tx9iXGq00BbJPo37ox68R5vaGTXivs6RGh/BQ6QP5zqZDGWdAO6JbRE/iR1l80xeGAwCQS2nMV9S/w==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "2.6.0"
|
||||
"@types/node" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.6.1.tgz#e34972a24f8aba0861f9ccf7130acd74fd11e079"
|
||||
integrity sha512-Z0rddsGqioKbvqfohg7BwkFC3PuNLsB+GE9QkFza7tiDzuHoy0y823Y+oGNDzxNZrYyLjqkZtCTl4vCqOmEN4g==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "2.6.1"
|
||||
eslint-utils "^1.4.2"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
regexpp "^2.0.1"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
"@typescript-eslint/experimental-utils@2.6.0":
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.6.0.tgz#ed70bef72822bff54031ff0615fc888b9e2b6e8a"
|
||||
integrity sha512-34BAFpNOwHXeqT+AvdalLxOvcPYnCxA5JGmBAFL64RGMdP0u65rXjii7l/nwpgk5aLEE1LaqF+SsCU0/Cb64xA==
|
||||
"@typescript-eslint/experimental-utils@2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.6.1.tgz#eddaca17a399ebf93a8628923233b4f93793acfd"
|
||||
integrity sha512-EVrrUhl5yBt7fC7c62lWmriq4MIc49zpN3JmrKqfiFXPXCM5ErfEcZYfKOhZXkW6MBjFcJ5kGZqu1b+lyyExUw==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.3"
|
||||
"@typescript-eslint/typescript-estree" "2.6.0"
|
||||
"@typescript-eslint/typescript-estree" "2.6.1"
|
||||
eslint-scope "^5.0.0"
|
||||
|
||||
"@typescript-eslint/parser@^2.6.0":
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.6.0.tgz#5106295c6a7056287b4719e24aae8d6293d5af49"
|
||||
integrity sha512-AvLejMmkcjRTJ2KD72v565W4slSrrzUIzkReu1JN34b8JnsEsxx7S9Xx/qXEuMQas0mkdUfETr0j3zOhq2DIqQ==
|
||||
"@typescript-eslint/parser@^2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.6.1.tgz#3c00116baa0d696bc334ca18ac5286b34793993c"
|
||||
integrity sha512-PDPkUkZ4c7yA+FWqigjwf3ngPUgoLaGjMlFh6TRtbjhqxFBnkElDfckSjm98q9cMr4xRzZ15VrS/xKm6QHYf0w==
|
||||
dependencies:
|
||||
"@types/eslint-visitor-keys" "^1.0.0"
|
||||
"@typescript-eslint/experimental-utils" "2.6.0"
|
||||
"@typescript-eslint/typescript-estree" "2.6.0"
|
||||
"@typescript-eslint/experimental-utils" "2.6.1"
|
||||
"@typescript-eslint/typescript-estree" "2.6.1"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@2.6.0":
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.6.0.tgz#d3e9d8e001492e2b9124c4d4bd4e7f03c0fd7254"
|
||||
integrity sha512-A3lSBVIdj2Gp0lFEL6in2eSPqJ33uAc3Ko+Y4brhjkxzjbzLnwBH22CwsW2sCo+iwogfIyvb56/AJri15H0u5Q==
|
||||
"@typescript-eslint/typescript-estree@2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.6.1.tgz#fb363dd4ca23384745c5ea4b7f4c867432b00d31"
|
||||
integrity sha512-+sTnssW6bcbDZKE8Ce7VV6LdzkQz2Bxk7jzk1J8H1rovoTxnm6iXvYIyncvNsaB/kBCOM63j/LNJfm27bNdUoA==
|
||||
dependencies:
|
||||
debug "^4.1.1"
|
||||
glob "^7.1.4"
|
||||
is-glob "^4.0.1"
|
||||
lodash.unescape "4.0.1"
|
||||
semver "^6.3.0"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
"@webassemblyjs/ast@1.8.5":
|
||||
version "1.8.5"
|
||||
@ -553,6 +600,20 @@ acorn@^7.1.0:
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c"
|
||||
integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==
|
||||
|
||||
agent-base@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
|
||||
integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
|
||||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
agent-base@~4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
|
||||
integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==
|
||||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
ajv-errors@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
|
||||
@ -563,7 +624,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1:
|
||||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da"
|
||||
integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==
|
||||
|
||||
ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2:
|
||||
ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5:
|
||||
version "6.10.2"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52"
|
||||
integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==
|
||||
@ -740,6 +801,18 @@ asn1.js@^4.0.0:
|
||||
inherits "^2.0.1"
|
||||
minimalistic-assert "^1.0.0"
|
||||
|
||||
asn1@~0.2.3:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
|
||||
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
|
||||
dependencies:
|
||||
safer-buffer "~2.1.0"
|
||||
|
||||
assert-plus@1.0.0, assert-plus@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
||||
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
|
||||
|
||||
assert@^1.1.1:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
|
||||
@ -763,7 +836,7 @@ async-each@^1.0.0, async-each@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
|
||||
integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
|
||||
|
||||
async-limiter@~1.0.0:
|
||||
async-limiter@^1.0.0, async-limiter@~1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
|
||||
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
|
||||
@ -775,11 +848,34 @@ async@^2.6.2:
|
||||
dependencies:
|
||||
lodash "^4.17.14"
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||
|
||||
atob@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||
|
||||
aws-sign2@~0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
|
||||
|
||||
aws4@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
|
||||
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
|
||||
|
||||
axios@^0.18.1:
|
||||
version "0.18.1"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3"
|
||||
integrity sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==
|
||||
dependencies:
|
||||
follow-redirects "1.5.10"
|
||||
is-buffer "^2.0.2"
|
||||
|
||||
babel-code-frame@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
|
||||
@ -1329,6 +1425,13 @@ batch@0.6.1:
|
||||
resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
|
||||
integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=
|
||||
|
||||
bcrypt-pbkdf@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
|
||||
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
|
||||
dependencies:
|
||||
tweetnacl "^0.14.3"
|
||||
|
||||
big.js@^5.2.2:
|
||||
version "5.2.2"
|
||||
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
|
||||
@ -1629,9 +1732,14 @@ camelcase@^5.0.0, camelcase@^5.3.1:
|
||||
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
|
||||
|
||||
caniuse-lite@^1.0.30000844:
|
||||
version "1.0.30001006"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001006.tgz#5b6e8288792cfa275f007b2819a00ccad7112655"
|
||||
integrity sha512-MXnUVX27aGs/QINz+QG1sWSLDr3P1A3Hq5EUWoIt0T7K24DuvMxZEnh3Y5aHlJW6Bz2aApJdSewdYLd8zQnUuw==
|
||||
version "1.0.30001008"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001008.tgz#b8841b1df78a9f5ed9702537ef592f1f8772c0d9"
|
||||
integrity sha512-b8DJyb+VVXZGRgJUa30cbk8gKHZ3LOZTBLaUEEVr2P4xpmFigOCc62CO4uzquW641Ouq1Rm9N+rWLWdSYDaDIw==
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||
|
||||
center-align@^0.1.1:
|
||||
version "0.1.3"
|
||||
@ -1829,11 +1937,23 @@ color-name@1.1.3:
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||
|
||||
combined-stream@^1.0.6, combined-stream@~1.0.6:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@^2.20.0, commander@~2.20.3:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
common-tags@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
|
||||
integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==
|
||||
|
||||
commondir@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||
@ -1922,9 +2042,9 @@ content-type@^1.0.4, content-type@~1.0.4:
|
||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
||||
|
||||
convert-source-map@^1.5.1:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20"
|
||||
integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
|
||||
integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==
|
||||
dependencies:
|
||||
safe-buffer "~5.1.1"
|
||||
|
||||
@ -1968,7 +2088,7 @@ core-js@^2.4.0, core-js@^2.5.0:
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.10.tgz#8a5b8391f8cc7013da703411ce5b585706300d7f"
|
||||
integrity sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==
|
||||
|
||||
core-util-is@^1.0.2, core-util-is@~1.0.0:
|
||||
core-util-is@1.0.2, core-util-is@^1.0.2, core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
@ -2104,6 +2224,13 @@ cyclist@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
|
||||
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
||||
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
dateformat@~1.0.4-1.2.3:
|
||||
version "1.0.12"
|
||||
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9"
|
||||
@ -2124,7 +2251,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@3.1.0, debug@~3.1.0:
|
||||
debug@3.1.0, debug@=3.1.0, debug@~3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
@ -2232,6 +2359,11 @@ del@^4.1.1:
|
||||
pify "^4.0.1"
|
||||
rimraf "^2.6.3"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
||||
|
||||
delegates@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
||||
@ -2362,15 +2494,23 @@ dynamic-dedupe@^0.3.0:
|
||||
dependencies:
|
||||
xtend "^4.0.0"
|
||||
|
||||
ecc-jsbn@~0.1.1:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
|
||||
integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
|
||||
dependencies:
|
||||
jsbn "~0.1.0"
|
||||
safer-buffer "^2.1.0"
|
||||
|
||||
ee-first@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
|
||||
|
||||
electron-to-chromium@^1.3.47:
|
||||
version "1.3.296"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.296.tgz#a1d4322d742317945285d3ba88966561b67f3ac8"
|
||||
integrity sha512-s5hv+TSJSVRsxH190De66YHb50pBGTweT9XGWYu/LMR20KX6TsjFzObo36CjVAzM+PUeeKSBRtm/mISlCzeojQ==
|
||||
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==
|
||||
|
||||
elliptic@^6.0.0:
|
||||
version "6.5.1"
|
||||
@ -2474,6 +2614,18 @@ es-to-primitive@^1.2.0:
|
||||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
es6-promise@^4.0.3:
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
|
||||
|
||||
es6-promisify@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
|
||||
integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
|
||||
dependencies:
|
||||
es6-promise "^4.0.3"
|
||||
|
||||
escape-html@^1.0.3, escape-html@~1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||
@ -2721,6 +2873,11 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
|
||||
assign-symbols "^1.0.0"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
||||
external-editor@^3.0.3:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
|
||||
@ -2751,6 +2908,16 @@ extglob@^2.0.4:
|
||||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
extsprintf@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
||||
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
|
||||
|
||||
extsprintf@^1.2.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
|
||||
|
||||
fast-deep-equal@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
|
||||
@ -2928,6 +3095,13 @@ flush-write-stream@^1.0.0:
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
follow-redirects@1.5.10:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
||||
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
|
||||
dependencies:
|
||||
debug "=3.1.0"
|
||||
|
||||
follow-redirects@^1.0.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.9.0.tgz#8d5bcdc65b7108fe1508649c79c12d732dcedb4f"
|
||||
@ -2947,6 +3121,29 @@ for-own@^0.1.4:
|
||||
dependencies:
|
||||
for-in "^1.0.1"
|
||||
|
||||
forever-agent@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
||||
|
||||
form-data@^2.5.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
|
||||
integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
form-data@~2.3.2:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
|
||||
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
formidable@^1.1.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.1.tgz#70fb7ca0290ee6ff961090415f4b3df3d2082659"
|
||||
@ -3072,6 +3269,13 @@ get-value@^2.0.3, get-value@^2.0.6:
|
||||
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
|
||||
integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
|
||||
|
||||
getpass@^0.1.1:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
||||
integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
glob-base@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
|
||||
@ -3198,6 +3402,19 @@ handle-thing@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754"
|
||||
integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==
|
||||
|
||||
har-schema@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
||||
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
|
||||
|
||||
har-validator@~5.1.0:
|
||||
version "5.1.3"
|
||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
|
||||
integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
|
||||
dependencies:
|
||||
ajv "^6.5.5"
|
||||
har-schema "^2.0.0"
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
||||
@ -3406,11 +3623,28 @@ http-proxy@^1.17.0:
|
||||
follow-redirects "^1.0.0"
|
||||
requires-port "^1.0.0"
|
||||
|
||||
http-signature@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
||||
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
https-browserify@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
||||
|
||||
https-proxy-agent@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz#b8c286433e87602311b01c8ea34413d856a4af81"
|
||||
integrity sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==
|
||||
dependencies:
|
||||
agent-base "^4.3.0"
|
||||
debug "^3.1.0"
|
||||
|
||||
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
@ -3623,6 +3857,11 @@ is-buffer@^1.1.5:
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
||||
|
||||
is-buffer@^2.0.2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
|
||||
integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==
|
||||
|
||||
is-callable@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
|
||||
@ -3855,6 +4094,11 @@ is-type-of@^1.0.0:
|
||||
is-class-hotfix "~0.0.6"
|
||||
isstream "~0.1.2"
|
||||
|
||||
is-typedarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
||||
|
||||
is-utf8@^0.2.0:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
|
||||
@ -3930,6 +4174,11 @@ js-yaml@^3.13.1:
|
||||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
jsbn@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
|
||||
|
||||
jsesc@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
|
||||
@ -3950,11 +4199,21 @@ json-schema-traverse@^0.4.1:
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||
|
||||
json-schema@0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
|
||||
json-stable-stringify-without-jsonify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
|
||||
|
||||
json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
|
||||
json3@^3.3.2:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
|
||||
@ -3979,6 +4238,16 @@ jsonfile@^4.0.0:
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsprim@^1.2.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
||||
integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
|
||||
dependencies:
|
||||
assert-plus "1.0.0"
|
||||
extsprintf "1.3.0"
|
||||
json-schema "0.2.3"
|
||||
verror "1.10.0"
|
||||
|
||||
jstransformer@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3"
|
||||
@ -4345,6 +4614,23 @@ media-typer@0.3.0:
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
||||
|
||||
megalodon@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/megalodon/-/megalodon-2.0.0.tgz#7dd484787fa07d2ff836f944e2666ace016d6178"
|
||||
integrity sha512-UDreCcc6ULNr/6+6ev1QVozjmxyWgBo5ESC1xcYsiXIPVOJFqLRfGC+MuMMVsPD+fOyWiyo5lhfnomJVQgH2sQ==
|
||||
dependencies:
|
||||
"@types/oauth" "^0.9.0"
|
||||
"@types/request" "^2.47.0"
|
||||
"@types/ws" "^6.0.1"
|
||||
axios "^0.18.1"
|
||||
https-proxy-agent "^3.0.0"
|
||||
moment "^2.24.0"
|
||||
oauth "^0.9.15"
|
||||
request "^2.87.0"
|
||||
socks-proxy-agent h3poteto/node-socks-proxy-agent#master
|
||||
typescript "^3.4.5"
|
||||
ws "^7.0.1"
|
||||
|
||||
mem@^4.0.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178"
|
||||
@ -4470,7 +4756,7 @@ mime-db@1.40.0:
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac"
|
||||
integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==
|
||||
|
||||
mime-types@^2.1.18, mime-types@^2.1.8, mime-types@~2.1.17, mime-types@~2.1.24:
|
||||
mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.8, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
|
||||
version "2.1.24"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
|
||||
integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
|
||||
@ -4600,10 +4886,10 @@ mongoose-legacy-pluralize@1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz#3ba9f91fa507b5186d399fb40854bff18fb563e4"
|
||||
integrity sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==
|
||||
|
||||
mongoose@^5.7.7:
|
||||
version "5.7.7"
|
||||
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-5.7.7.tgz#038b47d10434ea6cc9ec9b45d88bfcf9ab401a1a"
|
||||
integrity sha512-FU59waB4LKBa9KOnqBUcCcMIVRc09TFo1F8nMxrzSiIWATaJpjxxSSH5FBVUDxQfNdJLfg9uFHxaTxhhwjsZOQ==
|
||||
mongoose@^5.7.8:
|
||||
version "5.7.8"
|
||||
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-5.7.8.tgz#ae86bff72687e8950dd95690a5eb3365ad9d57a0"
|
||||
integrity sha512-GsFXYo7z3ebnIDdnqlDJYQXQFqEGS+yxfdY9G0B7fxpvUJchDpwLGuGJdVd1QbGxu2l0DscCYBO0ntl3G6OACA==
|
||||
dependencies:
|
||||
bson "~1.1.1"
|
||||
kareem "2.3.1"
|
||||
@ -4900,6 +5186,16 @@ number-is-nan@^1.0.0:
|
||||
version "2.2.3"
|
||||
resolved "https://codeload.github.com/rinsuki/oauth-1.0a/tar.gz/b6a8b9cfd4f9621c03a57379f4f04ce79e2f4248"
|
||||
|
||||
oauth-sign@~0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
||||
|
||||
oauth@^0.9.15:
|
||||
version "0.9.15"
|
||||
resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"
|
||||
integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE=
|
||||
|
||||
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
@ -5271,6 +5567,11 @@ pbkdf2@^3.0.3:
|
||||
safe-buffer "^5.0.1"
|
||||
sha.js "^2.4.8"
|
||||
|
||||
performance-now@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
picomatch@^2.0.5:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.0.tgz#0fd042f568d08b1ad9ff2d3ec0f0bfb3cb80e177"
|
||||
@ -5454,6 +5755,11 @@ prr@~1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
|
||||
integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
|
||||
|
||||
psl@^1.1.24:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2"
|
||||
integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==
|
||||
|
||||
public-encrypt@^4.0.0:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
|
||||
@ -5601,7 +5907,7 @@ punycode@1.3.2:
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
|
||||
integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
|
||||
|
||||
punycode@^1.2.4:
|
||||
punycode@^1.2.4, punycode@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
|
||||
@ -5621,6 +5927,11 @@ qs@^6.4.0:
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.0.tgz#d1297e2a049c53119cb49cca366adbbacc80b409"
|
||||
integrity sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA==
|
||||
|
||||
qs@~6.5.2:
|
||||
version "6.5.2"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
||||
|
||||
querystring-es3@^0.2.0:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
|
||||
@ -5956,6 +6267,32 @@ repeating@^2.0.0:
|
||||
dependencies:
|
||||
is-finite "^1.0.0"
|
||||
|
||||
request@^2.87.0:
|
||||
version "2.88.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
|
||||
integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
|
||||
dependencies:
|
||||
aws-sign2 "~0.7.0"
|
||||
aws4 "^1.8.0"
|
||||
caseless "~0.12.0"
|
||||
combined-stream "~1.0.6"
|
||||
extend "~3.0.2"
|
||||
forever-agent "~0.6.1"
|
||||
form-data "~2.3.2"
|
||||
har-validator "~5.1.0"
|
||||
http-signature "~1.2.0"
|
||||
is-typedarray "~1.0.0"
|
||||
isstream "~0.1.2"
|
||||
json-stringify-safe "~5.0.1"
|
||||
mime-types "~2.1.19"
|
||||
oauth-sign "~0.9.0"
|
||||
performance-now "^2.1.0"
|
||||
qs "~6.5.2"
|
||||
safe-buffer "^5.1.2"
|
||||
tough-cookie "~2.4.3"
|
||||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
require-directory@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
@ -6132,7 +6469,7 @@ safe-regex@^1.1.0:
|
||||
dependencies:
|
||||
ret "~0.1.10"
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3":
|
||||
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
@ -6337,6 +6674,11 @@ 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==
|
||||
|
||||
snapdragon-node@^2.0.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
|
||||
@ -6387,6 +6729,21 @@ sockjs@0.3.19:
|
||||
faye-websocket "^0.10.0"
|
||||
uuid "^3.0.1"
|
||||
|
||||
socks-proxy-agent@h3poteto/node-socks-proxy-agent#master:
|
||||
version "4.0.2"
|
||||
resolved "https://codeload.github.com/h3poteto/node-socks-proxy-agent/tar.gz/5be42d4a3f98c5a156d713ea88a54b825f26d1f3"
|
||||
dependencies:
|
||||
agent-base "~4.2.1"
|
||||
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==
|
||||
dependencies:
|
||||
ip "^1.1.5"
|
||||
smart-buffer "4.0.2"
|
||||
|
||||
source-list-map@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
|
||||
@ -6501,6 +6858,21 @@ sprintf-js@~1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
|
||||
|
||||
sshpk@^1.7.0:
|
||||
version "1.16.1"
|
||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
|
||||
integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
|
||||
dependencies:
|
||||
asn1 "~0.2.3"
|
||||
assert-plus "^1.0.0"
|
||||
bcrypt-pbkdf "^1.0.0"
|
||||
dashdash "^1.12.0"
|
||||
ecc-jsbn "~0.1.1"
|
||||
getpass "^0.1.1"
|
||||
jsbn "~0.1.0"
|
||||
safer-buffer "^2.0.2"
|
||||
tweetnacl "~0.14.0"
|
||||
|
||||
ssri@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8"
|
||||
@ -6881,6 +7253,14 @@ token-stream@0.0.1:
|
||||
resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a"
|
||||
integrity sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=
|
||||
|
||||
tough-cookie@~2.4.3:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
|
||||
integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
|
||||
dependencies:
|
||||
psl "^1.1.24"
|
||||
punycode "^1.4.1"
|
||||
|
||||
trim-newlines@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
|
||||
@ -6924,6 +7304,18 @@ tty-browserify@0.0.0:
|
||||
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
|
||||
integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
|
||||
|
||||
tunnel-agent@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
|
||||
integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||
version "0.14.5"
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||
|
||||
type-check@~0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
|
||||
@ -6954,10 +7346,10 @@ typedarray@^0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||
|
||||
typescript@^3.6.4:
|
||||
version "3.6.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d"
|
||||
integrity sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==
|
||||
typescript@^3.4.5, typescript@^3.7.2:
|
||||
version "3.7.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.2.tgz#27e489b95fa5909445e9fef5ee48d81697ad18fb"
|
||||
integrity sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==
|
||||
|
||||
uglify-js@^2.6.1:
|
||||
version "2.8.29"
|
||||
@ -6970,9 +7362,9 @@ uglify-js@^2.6.1:
|
||||
uglify-to-browserify "~1.0.0"
|
||||
|
||||
uglify-js@^3.6.0:
|
||||
version "3.6.5"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.5.tgz#b0ee796d2ae7e25672e04f65629b997cd4b30bd6"
|
||||
integrity sha512-7L3W+Npia1OCr5Blp4/Vw83tK1mu5gnoIURtT1fUVfQ3Kf8WStWV6NJz0fdoBJZls0KlweruRTLVe6XLafmy5g==
|
||||
version "3.6.7"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.7.tgz#15f49211df6b8a01ee91322bbe46fa33223175dc"
|
||||
integrity sha512-4sXQDzmdnoXiO+xvmTzQsfIiwrjUCSA95rSP4SEd8tDb51W2TiDOlL76Hl+Kw0Ie42PSItCW8/t6pBNCF2R48A==
|
||||
dependencies:
|
||||
commander "~2.20.3"
|
||||
source-map "~0.6.1"
|
||||
@ -7144,10 +7536,19 @@ vary@^1.1.2, vary@~1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
|
||||
|
||||
verror@1.10.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
|
||||
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
core-util-is "1.0.2"
|
||||
extsprintf "^1.2.0"
|
||||
|
||||
vm-browserify@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019"
|
||||
integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
||||
|
||||
void-elements@^2.0.1:
|
||||
version "2.0.1"
|
||||
@ -7388,6 +7789,13 @@ ws@^6.2.1:
|
||||
dependencies:
|
||||
async-limiter "~1.0.0"
|
||||
|
||||
ws@^7.0.1:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.0.tgz#422eda8c02a4b5dba7744ba66eebbd84bcef0ec7"
|
||||
integrity sha512-+SqNqFbwTm/0DC18KYzIsMTnEWpLwJsiasW/O17la4iDRRIO9uaHbvKiAS3AHgTiuuWerK/brj4O6MYZkei9xg==
|
||||
dependencies:
|
||||
async-limiter "^1.0.0"
|
||||
|
||||
xtend@^4.0.0, xtend@~4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
|
Loading…
Reference in New Issue
Block a user