1
0
mirror of https://github.com/hotomoe/hotomoe synced 2024-11-24 23:26:17 +09:00
This commit is contained in:
syuilo 2018-06-18 09:54:53 +09:00
parent a766faeae9
commit 80e5645a84
150 changed files with 305 additions and 2334 deletions

View File

@ -6,15 +6,14 @@ import * as fs from 'fs';
import * as yaml from 'js-yaml';
export type LangKey = 'de' | 'en' | 'fr' | 'ja' | 'pl';
export type LocaleObjectChildren = LocaleObject | string | undefined;
export type LocaleObject = {[key: string]: LocaleObjectChildren };
export type LocaleObject = { [key: string]: any };
const loadLang = (lang: LangKey) => yaml.safeLoad(
fs.readFileSync(`./locales/${lang}.yml`, 'utf-8')) as LocaleObject;
const native = loadLang('ja');
const langs: {[key in LangKey]: LocaleObject} = {
const langs: { [key: string]: LocaleObject } = {
'de': loadLang('de'),
'en': loadLang('en'),
'fr': loadLang('fr'),

View File

@ -1,4 +1,4 @@
export default acct => {
export default (acct: string) => {
const splitted = acct.split('@', 2);
return { username: splitted[0], host: splitted[1] || null };
};

View File

@ -1,3 +1,5 @@
export default user => {
import { IUser } from "../models/user";
export default (user: IUser) => {
return user.host === null ? user.username : `${user.username}@${user.host}`;
};

View File

@ -2,7 +2,7 @@
* Replace i18n texts
*/
import locale, { isAvailableLanguage, LocaleObject, LocaleObjectChildren } from '../../locales';
import locale, { isAvailableLanguage, LocaleObject } from '../../locales';
export default class Replacer {
private lang: string;
@ -24,7 +24,7 @@ export default class Replacer {
const texts = locale[this.lang];
let text: LocaleObjectChildren = texts;
let text = texts;
if (path) {
if (text.hasOwnProperty(path)) {

View File

@ -1,8 +1,8 @@
import * as mongo from 'mongodb';
import { Query } from 'cafy';
export const isAnId = x => mongo.ObjectID.isValid(x);
export const isNotAnId = x => !isAnId(x);
export const isAnId = (x: any) => mongo.ObjectID.isValid(x);
export const isNotAnId = (x: any) => !isAnId(x);
/**
* ID

View File

@ -1,60 +0,0 @@
import Note from '../models/note';
// 10分
const interval = 1000 * 60 * 10;
async function tick() {
const res = await Note.aggregate([{
$match: {
createdAt: {
$gt: new Date(Date.now() - interval)
},
tags: {
$exists: true,
$ne: []
}
}
}, {
$unwind: '$tags'
}, {
$group: {
_id: '$tags',
count: {
$sum: 1
}
}
}, {
$group: {
_id: null,
tags: {
$push: {
tag: '$_id',
count: '$count'
}
}
}
}, {
$project: {
_id: false,
tags: true
}
}]) as {
tags: Array<{
tag: string;
count: number;
}>
};
const stats = res.tags
.sort((a, b) => a.count - b.count)
.map(tag => [tag.tag, tag.count])
.slice(0, 10);
console.log(stats);
process.send(stats);
}
tick();
setInterval(tick, interval);

View File

@ -1,20 +0,0 @@
import * as childProcess from 'child_process';
import Xev from 'xev';
const ev = new Xev();
export default function() {
const log = [];
const p = childProcess.fork(__dirname + '/hashtags-stats-child.js');
p.on('message', stats => {
ev.emit('hashtagsStats', stats);
log.push(stats);
if (log.length > 30) log.shift();
});
ev.on('requestHashTagsStatsLog', id => {
ev.emit('hashtagsStatsLog:' + id, log);
});
}

View File

@ -4,7 +4,7 @@ import Xev from 'xev';
const ev = new Xev();
export default function() {
const log = [];
const log: any[] = [];
const p = childProcess.fork(__dirname + '/notes-stats-child.js');

View File

@ -11,14 +11,14 @@ const interval = 1000;
* Report server stats regularly
*/
export default function() {
const log = [];
const log: any[] = [];
ev.on('requestServerStatsLog', id => {
ev.emit('serverStatsLog:' + id, log);
});
async function tick() {
osUtils.cpuUsage(cpuUsage => {
osUtils.cpuUsage((cpuUsage: number) => {
const disk = diskusage.checkSync(os.platform() == 'win32' ? 'c:' : '/');
const stats = {
cpu_usage: cpuUsage,

View File

@ -27,7 +27,7 @@ const nativeDbConn = async (): Promise<mongodb.Db> => {
if (mdb) return mdb;
const db = await ((): Promise<mongodb.Db> => new Promise((resolve, reject) => {
(mongodb as any).MongoClient.connect(uri, (e, client) => {
(mongodb as any).MongoClient.connect(uri, (e: Error, client: any) => {
if (e) return reject(e);
resolve(client.db(config.mongodb.db));
});

View File

@ -60,7 +60,7 @@ function main() {
/**
* Init master process
*/
async function masterMain(opt) {
async function masterMain(opt: any) {
let config: Config;
try {
@ -91,7 +91,7 @@ async function masterMain(opt) {
/**
* Init worker process
*/
async function workerMain(opt) {
async function workerMain(opt: any) {
if (!opt['only-processor']) {
// start server
await require('./server').default();

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import AccessToken from './access-token';
import db from '../db/mongodb';
import config from '../config';

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
import { pack as packApp } from './app';

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import { pack as packFolder } from './drive-folder';
import config from '../config';
import monkDb, { nativeDbConn } from '../db/mongodb';

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
import DriveFile from './drive-file';

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
import { pack as packNote } from './note';

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
import { pack as packUser } from './user';

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import { pack as packUser } from './user';
import { pack as packFile } from './drive-file';
import db from '../db/mongodb';

View File

@ -1,6 +1,6 @@
import * as mongo from 'mongodb';
import $ from 'cafy';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
import Reaction from './note-reaction';
import { pack as packUser } from './user';

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import rap from '@prezzemolo/rap';
import db from '../db/mongodb';
import { IUser, pack as packUser } from './user';
@ -37,7 +37,11 @@ export type INote = {
mediaIds: mongo.ObjectID[];
replyId: mongo.ObjectID;
renoteId: mongo.ObjectID;
poll: any; // todo
poll: {
choices: Array<{
id: number;
}>
};
text: string;
tags: string[];
tagsLower: string[];
@ -304,7 +308,7 @@ export const pack = async (
if (vote != null) {
const myChoice = poll.choices
.filter(c => c.id == vote.choice)[0];
.filter((c: any) => c.id == vote.choice)[0];
myChoice.isVoted = true;
}

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
import { IUser, pack as packUser } from './user';
import { pack as packNote } from './note';

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
import { IUser, pack as packUser } from './user';

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
import { IUser, pack as packUser } from './user';

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
const Signin = db.get<ISignin>('signin');

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
const UserList = db.get<IUserList>('userList');

View File

@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
import * as deepcopy from 'deepcopy';
const deepcopy = require('deepcopy');
import sequential = require('promise-sequential');
import rap from '@prezzemolo/rap';
import db from '../db/mongodb';
@ -153,14 +153,6 @@ export function isValidBirthday(birthday: string): boolean {
}
//#endregion
export function init(user): IUser {
user._id = new mongo.ObjectID(user._id);
user.avatarId = new mongo.ObjectID(user.avatarId);
user.bannerId = new mongo.ObjectID(user.bannerId);
user.pinnedNoteId = new mongo.ObjectID(user.pinnedNoteId);
return user;
}
/**
* Userを物理削除します
*/

View File

@ -1,4 +1,4 @@
export default (id, totalItems, orderedItems) => ({
export default (id: string, totalItems: any, orderedItems: any) => ({
id,
type: 'OrderedCollection',
totalItems,

View File

@ -1,4 +1,4 @@
export default object => ({
export default (object: any) => ({
type: 'Reject',
object
});

View File

@ -1,5 +1,5 @@
import { request } from 'https';
import { sign } from 'http-signature';
const { sign } = require('http-signature');
import { URL } from 'url';
import * as debug from 'debug';
@ -8,7 +8,7 @@ import { ILocalUser } from '../../models/user';
const log = debug('misskey:activitypub:deliver');
export default (user: ILocalUser, url: string, object) => new Promise((resolve, reject) => {
export default (user: ILocalUser, url: string, object: any) => new Promise((resolve, reject) => {
log(`--> ${url}`);
const { protocol, hostname, port, pathname, search } = new URL(url);

View File

@ -12,8 +12,8 @@ type IWebFinger = {
subject: string;
};
export default async function resolve(query): Promise<IWebFinger> {
return await new Promise((res, rej) => webFinger.lookup(query, (error, result) => {
export default async function resolve(query: any): Promise<IWebFinger> {
return await new Promise((res, rej) => webFinger.lookup(query, (error: Error, result: any) => {
if (error) {
return rej(error);
}

View File

@ -1,377 +0,0 @@
/**
* -AI-
* Botのバックエンド()
*
*
*
*/
import * as request from 'request-promise-native';
import Reversi, { Color } from '../core';
import conf from '../../config';
import getUserName from '../../renderers/get-user-name';
let game;
let form;
/**
* BotアカウントのユーザーID
*/
const id = conf.reversi_ai.id;
/**
* BotアカウントのAPIキー
*/
const i = conf.reversi_ai.i;
let note;
process.on('message', async msg => {
// 親プロセスからデータをもらう
if (msg.type == '_init_') {
game = msg.game;
form = msg.form;
}
// フォームが更新されたとき
if (msg.type == 'update-form') {
form.find(i => i.id == msg.body.id).value = msg.body.value;
}
// ゲームが始まったとき
if (msg.type == 'started') {
onGameStarted(msg.body);
//#region TLに投稿する
const game = msg.body;
const url = `${conf.url}/reversi/${game.id}`;
const user = game.user1Id == id ? game.user2 : game.user1;
const isSettai = form[0].value === 0;
const text = isSettai
? `?[${getUserName(user)}](${conf.url}/@${user.username})さんの接待を始めました!`
: `対局を?[${getUserName(user)}](${conf.url}/@${user.username})さんと始めました! (強さ${form[0].value})`;
const res = await request.post(`${conf.api_url}/notes/create`, {
json: { i,
text: `${text}\n→[観戦する](${url})`
}
});
note = res.createdNote;
//#endregion
}
// ゲームが終了したとき
if (msg.type == 'ended') {
// ストリームから切断
process.send({
type: 'close'
});
//#region TLに投稿する
const user = game.user1Id == id ? game.user2 : game.user1;
const isSettai = form[0].value === 0;
const text = isSettai
? msg.body.winnerId === null
? `?[${getUserName(user)}](${conf.url}/@${user.username})さんに接待で引き分けました...`
: msg.body.winnerId == id
? `?[${getUserName(user)}](${conf.url}/@${user.username})さんに接待で勝ってしまいました...`
: `?[${getUserName(user)}](${conf.url}/@${user.username})さんに接待で負けてあげました♪`
: msg.body.winnerId === null
? `?[${getUserName(user)}](${conf.url}/@${user.username})さんと引き分けました~`
: msg.body.winnerId == id
? `?[${getUserName(user)}](${conf.url}/@${user.username})さんに勝ちました♪`
: `?[${getUserName(user)}](${conf.url}/@${user.username})さんに負けました...`;
await request.post(`${conf.api_url}/notes/create`, {
json: { i,
renoteId: note.id,
text: text
}
});
//#endregion
process.exit();
}
// 打たれたとき
if (msg.type == 'set') {
onSet(msg.body);
}
});
let o: Reversi;
let botColor: Color;
// 各マスの強さ
let cellWeights;
/**
*
* @param g
*/
function onGameStarted(g) {
game = g;
// リバーシエンジン初期化
o = new Reversi(game.settings.map, {
isLlotheo: game.settings.isLlotheo,
canPutEverywhere: game.settings.canPutEverywhere,
loopedBoard: game.settings.loopedBoard
});
// 各マスの価値を計算しておく
cellWeights = o.map.map((pix, i) => {
if (pix == 'null') return 0;
const [x, y] = o.transformPosToXy(i);
let count = 0;
const get = (x, y) => {
if (x < 0 || y < 0 || x >= o.mapWidth || y >= o.mapHeight) return 'null';
return o.mapDataGet(o.transformXyToPos(x, y));
};
if (get(x , y - 1) == 'null') count++;
if (get(x + 1, y - 1) == 'null') count++;
if (get(x + 1, y ) == 'null') count++;
if (get(x + 1, y + 1) == 'null') count++;
if (get(x , y + 1) == 'null') count++;
if (get(x - 1, y + 1) == 'null') count++;
if (get(x - 1, y ) == 'null') count++;
if (get(x - 1, y - 1) == 'null') count++;
//return Math.pow(count, 3);
return count >= 4 ? 1 : 0;
});
botColor = game.user1Id == id && game.black == 1 || game.user2Id == id && game.black == 2;
if (botColor) {
think();
}
}
function onSet(x) {
o.put(x.color, x.pos);
if (x.next === botColor) {
think();
}
}
const db = {};
function think() {
console.log('Thinking...');
console.time('think');
const isSettai = form[0].value === 0;
// 接待モードのときは、全力(5手先読みくらい)で負けるようにする
const maxDepth = isSettai ? 5 : form[0].value;
/**
* Botにとってある局面がどれだけ有利か取得する
*/
function staticEval() {
let score = o.canPutSomewhere(botColor).length;
cellWeights.forEach((weight, i) => {
// 係数
const coefficient = 30;
weight = weight * coefficient;
const stone = o.board[i];
if (stone === botColor) {
// TODO: 価値のあるマスに設置されている自分の石に縦か横に接するマスは価値があると判断する
score += weight;
} else if (stone !== null) {
score -= weight;
}
});
// ロセオならスコアを反転
if (game.settings.isLlotheo) score = -score;
// 接待ならスコアを反転
if (isSettai) score = -score;
return score;
}
/**
* αβ
*/
const dive = (pos: number, alpha = -Infinity, beta = Infinity, depth = 0): number => {
// 試し打ち
o.put(o.turn, pos);
const key = o.board.toString();
let cache = db[key];
if (cache) {
if (alpha >= cache.upper) {
o.undo();
return cache.upper;
}
if (beta <= cache.lower) {
o.undo();
return cache.lower;
}
alpha = Math.max(alpha, cache.lower);
beta = Math.min(beta, cache.upper);
} else {
cache = {
upper: Infinity,
lower: -Infinity
};
}
const isBotTurn = o.turn === botColor;
// 勝った
if (o.turn === null) {
const winner = o.winner;
// 勝つことによる基本スコア
const base = 10000;
let score;
if (game.settings.isLlotheo) {
// 勝ちは勝ちでも、より自分の石を少なくした方が美しい勝ちだと判定する
score = o.winner ? base - (o.blackCount * 100) : base - (o.whiteCount * 100);
} else {
// 勝ちは勝ちでも、より相手の石を少なくした方が美しい勝ちだと判定する
score = o.winner ? base + (o.blackCount * 100) : base + (o.whiteCount * 100);
}
// 巻き戻し
o.undo();
// 接待なら自分が負けた方が高スコア
return isSettai
? winner !== botColor ? score : -score
: winner === botColor ? score : -score;
}
if (depth === maxDepth) {
// 静的に評価
const score = staticEval();
// 巻き戻し
o.undo();
return score;
} else {
const cans = o.canPutSomewhere(o.turn);
let value = isBotTurn ? -Infinity : Infinity;
let a = alpha;
let b = beta;
// 次のターンのプレイヤーにとって最も良い手を取得
for (const p of cans) {
if (isBotTurn) {
const score = dive(p, a, beta, depth + 1);
value = Math.max(value, score);
a = Math.max(a, value);
if (value >= beta) break;
} else {
const score = dive(p, alpha, b, depth + 1);
value = Math.min(value, score);
b = Math.min(b, value);
if (value <= alpha) break;
}
}
// 巻き戻し
o.undo();
if (value <= alpha) {
cache.upper = value;
} else if (value >= beta) {
cache.lower = value;
} else {
cache.upper = value;
cache.lower = value;
}
db[key] = cache;
return value;
}
};
/**
* αβ()()
*/
const dive2 = (pos: number, alpha = -Infinity, beta = Infinity, depth = 0): number => {
// 試し打ち
o.put(o.turn, pos);
const isBotTurn = o.turn === botColor;
// 勝った
if (o.turn === null) {
const winner = o.winner;
// 勝つことによる基本スコア
const base = 10000;
let score;
if (game.settings.isLlotheo) {
// 勝ちは勝ちでも、より自分の石を少なくした方が美しい勝ちだと判定する
score = o.winner ? base - (o.blackCount * 100) : base - (o.whiteCount * 100);
} else {
// 勝ちは勝ちでも、より相手の石を少なくした方が美しい勝ちだと判定する
score = o.winner ? base + (o.blackCount * 100) : base + (o.whiteCount * 100);
}
// 巻き戻し
o.undo();
// 接待なら自分が負けた方が高スコア
return isSettai
? winner !== botColor ? score : -score
: winner === botColor ? score : -score;
}
if (depth === maxDepth) {
// 静的に評価
const score = staticEval();
// 巻き戻し
o.undo();
return score;
} else {
const cans = o.canPutSomewhere(o.turn);
// 次のターンのプレイヤーにとって最も良い手を取得
for (const p of cans) {
if (isBotTurn) {
alpha = Math.max(alpha, dive2(p, alpha, beta, depth + 1));
} else {
beta = Math.min(beta, dive2(p, alpha, beta, depth + 1));
}
if (alpha >= beta) break;
}
// 巻き戻し
o.undo();
return isBotTurn ? alpha : beta;
}
};
const cans = o.canPutSomewhere(botColor);
const scores = cans.map(p => dive(p));
const pos = cans[scores.indexOf(Math.max(...scores))];
console.log('Thinked:', pos);
console.timeEnd('think');
process.send({
type: 'put',
pos
});
}

View File

@ -1,233 +0,0 @@
/**
* -AI-
* Botのフロントエンド()
*
*
*
*/
import * as childProcess from 'child_process';
const WebSocket = require('ws');
import * as ReconnectingWebSocket from 'reconnecting-websocket';
import * as request from 'request-promise-native';
import conf from '../../config';
// 設定 ////////////////////////////////////////////////////////
/**
* BotアカウントのAPIキー
*/
const i = conf.reversi_ai.i;
/**
* BotアカウントのユーザーID
*/
const id = conf.reversi_ai.id;
////////////////////////////////////////////////////////////////
/**
*
*/
const homeStream = new ReconnectingWebSocket(`${conf.ws_url}/?i=${i}`, undefined, {
constructor: WebSocket
});
homeStream.on('open', () => {
console.log('home stream opened');
});
homeStream.on('close', () => {
console.log('home stream closed');
});
homeStream.on('message', message => {
const msg = JSON.parse(message.toString());
// タイムライン上でなんか言われたまたは返信されたとき
if (msg.type == 'mention' || msg.type == 'reply') {
const note = msg.body;
if (note.userId == id) return;
// リアクションする
request.post(`${conf.api_url}/notes/reactions/create`, {
json: { i,
noteId: note.id,
reaction: 'love'
}
});
if (note.text) {
if (note.text.indexOf('リバーシ') > -1) {
request.post(`${conf.api_url}/notes/create`, {
json: { i,
replyId: note.id,
text: '良いですよ~'
}
});
invite(note.userId);
}
}
}
// メッセージでなんか言われたとき
if (msg.type == 'messaging_message') {
const message = msg.body;
if (message.text) {
if (message.text.indexOf('リバーシ') > -1) {
request.post(`${conf.api_url}/messaging/messages/create`, {
json: { i,
userId: message.userId,
text: '良いですよ~'
}
});
invite(message.userId);
}
}
}
});
// ユーザーを対局に誘う
function invite(userId) {
request.post(`${conf.api_url}/reversi/match`, {
json: { i,
userId: userId
}
});
}
/**
*
*/
const reversiStream = new ReconnectingWebSocket(`${conf.ws_url}/reversi?i=${i}`, undefined, {
constructor: WebSocket
});
reversiStream.on('open', () => {
console.log('reversi stream opened');
});
reversiStream.on('close', () => {
console.log('reversi stream closed');
});
reversiStream.on('message', message => {
const msg = JSON.parse(message.toString());
// 招待されたとき
if (msg.type == 'invited') {
onInviteMe(msg.body.parent);
}
// マッチしたとき
if (msg.type == 'matched') {
gameStart(msg.body);
}
});
/**
*
* @param game
*/
function gameStart(game) {
// ゲームストリームに接続
const gw = new ReconnectingWebSocket(`${conf.ws_url}/reversi-game?i=${i}&game=${game.id}`, undefined, {
constructor: WebSocket
});
gw.on('open', () => {
console.log('reversi game stream opened');
// フォーム
const form = [{
id: 'strength',
type: 'radio',
label: '強さ',
value: 2,
items: [{
label: '接待',
value: 0
}, {
label: '弱',
value: 1
}, {
label: '中',
value: 2
}, {
label: '強',
value: 3
}, {
label: '最強',
value: 5
}]
}];
//#region バックエンドプロセス開始
const ai = childProcess.fork(__dirname + '/back.js');
// バックエンドプロセスに情報を渡す
ai.send({
type: '_init_',
game,
form
});
ai.on('message', msg => {
if (msg.type == 'put') {
gw.send(JSON.stringify({
type: 'set',
pos: msg.pos
}));
} else if (msg.type == 'close') {
gw.close();
}
});
// ゲームストリームから情報が流れてきたらそのままバックエンドプロセスに伝える
gw.on('message', message => {
const msg = JSON.parse(message.toString());
ai.send(msg);
});
//#endregion
// フォーム初期化
setTimeout(() => {
gw.send(JSON.stringify({
type: 'init-form',
body: form
}));
}, 1000);
// どんな設定内容の対局でも受け入れる
setTimeout(() => {
gw.send(JSON.stringify({
type: 'accept'
}));
}, 2000);
});
gw.on('close', () => {
console.log('reversi game stream closed');
});
}
/**
*
* @param inviter
*/
async function onInviteMe(inviter) {
console.log(`Someone invited me: @${inviter.username}`);
// 承認
const game = await request.post(`${conf.api_url}/reversi/match`, {
json: {
i,
userId: inviter.id
}
});
gameStart(game);
}

View File

@ -1 +0,0 @@
require('./front');

View File

@ -203,7 +203,7 @@ export default class Reversi {
*
*/
public canPutSomewhere(color: Color): number[] {
const result = [];
const result: number[] = [];
this.board.forEach((x, i) => {
if (this.canPut(color, i)) result.push(i);
@ -239,7 +239,7 @@ export default class Reversi {
const enemyColor = !color;
// ひっくり返せる石(の位置)リスト
let stones = [];
let stones: number[] = [];
const initPos = pos;

View File

@ -1,439 +0,0 @@
import * as EventEmitter from 'events';
import * as bcrypt from 'bcryptjs';
import User, { IUser, init as initUser, ILocalUser } from '../../../models/user';
import getNoteSummary from '../../../renderers/get-note-summary';
import getUserName from '../../../renderers/get-user-name';
import getUserSummary from '../../../renderers/get-user-summary';
import parseAcct from '../../../acct/parse';
import getNotificationSummary from '../../../renderers/get-notification-summary';
const hmm = [
'',
'ふぅ~む...',
'ちょっと何言ってるかわからないです',
'「ヘルプ」と言うと利用可能な操作が確認できますよ'
];
/**
* Botの頭脳
*/
export default class BotCore extends EventEmitter {
public user: IUser = null;
private context: Context = null;
constructor(user?: IUser) {
super();
this.user = user;
}
public clearContext() {
this.setContext(null);
}
public setContext(context: Context) {
this.context = context;
this.emit('updated');
if (context) {
context.on('updated', () => {
this.emit('updated');
});
}
}
public export() {
return {
user: this.user,
context: this.context ? this.context.export() : null
};
}
protected _import(data) {
this.user = data.user ? initUser(data.user) : null;
this.setContext(data.context ? Context.import(this, data.context) : null);
}
public static import(data) {
const bot = new BotCore();
bot._import(data);
return bot;
}
public async q(query: string): Promise<string> {
if (this.context != null) {
return await this.context.q(query);
}
if (/^@[a-zA-Z0-9_]+$/.test(query)) {
return await this.showUserCommand(query);
}
switch (query) {
case 'ping':
return 'PONG';
case 'help':
case 'ヘルプ':
return '利用可能なコマンド一覧です:\n' +
'help: これです\n' +
'me: アカウント情報を見ます\n' +
'login, signin: サインインします\n' +
'logout, signout: サインアウトします\n' +
'note: 投稿します\n' +
'tl: タイムラインを見ます\n' +
'no: 通知を見ます\n' +
'@<ユーザー名>: ユーザーを表示します\n' +
'\n' +
'タイムラインや通知を見た後、「次」というとさらに遡ることができます。';
case 'me':
return this.user ? `${getUserName(this.user)}としてサインインしています。\n\n${getUserSummary(this.user)}` : 'サインインしていません';
case 'login':
case 'signin':
case 'ログイン':
case 'サインイン':
if (this.user != null) return '既にサインインしていますよ!';
this.setContext(new SigninContext(this));
return await this.context.greet();
case 'logout':
case 'signout':
case 'ログアウト':
case 'サインアウト':
if (this.user == null) return '今はサインインしてないですよ!';
this.signout();
return 'ご利用ありがとうございました <3';
case 'note':
case '投稿':
if (this.user == null) return 'まずサインインしてください。';
this.setContext(new NoteContext(this));
return await this.context.greet();
case 'tl':
case 'タイムライン':
if (this.user == null) return 'まずサインインしてください。';
this.setContext(new TlContext(this));
return await this.context.greet();
case 'no':
case 'notifications':
case '通知':
if (this.user == null) return 'まずサインインしてください。';
this.setContext(new NotificationsContext(this));
return await this.context.greet();
case 'guessing-game':
case '数当てゲーム':
this.setContext(new GuessingGameContext(this));
return await this.context.greet();
default:
return hmm[Math.floor(Math.random() * hmm.length)];
}
}
public signin(user: IUser) {
this.user = user;
this.emit('signin', user);
this.emit('updated');
}
public signout() {
const user = this.user;
this.user = null;
this.emit('signout', user);
this.emit('updated');
}
public async refreshUser() {
this.user = await User.findOne({
_id: this.user._id
}, {
fields: {
data: false
}
});
this.emit('updated');
}
public async showUserCommand(q: string): Promise<string> {
try {
const user = await require('../endpoints/users/show')(parseAcct(q.substr(1)), this.user);
const text = getUserSummary(user);
return text;
} catch (e) {
return `問題が発生したようです...: ${e}`;
}
}
}
abstract class Context extends EventEmitter {
protected bot: BotCore;
public abstract async greet(): Promise<string>;
public abstract async q(query: string): Promise<string>;
public abstract export(): any;
constructor(bot: BotCore) {
super();
this.bot = bot;
}
public static import(bot: BotCore, data: any) {
if (data.type == 'guessing-game') return GuessingGameContext.import(bot, data.content);
if (data.type == 'note') return NoteContext.import(bot, data.content);
if (data.type == 'tl') return TlContext.import(bot, data.content);
if (data.type == 'notifications') return NotificationsContext.import(bot, data.content);
if (data.type == 'signin') return SigninContext.import(bot, data.content);
return null;
}
}
class SigninContext extends Context {
private temporaryUser: ILocalUser = null;
public async greet(): Promise<string> {
return 'まずユーザー名を教えてください:';
}
public async q(query: string): Promise<string> {
if (this.temporaryUser == null) {
// Fetch user
const user = await User.findOne({
usernameLower: query.toLowerCase(),
host: null
}, {
fields: {
data: false
}
}) as ILocalUser;
if (user === null) {
return `${query}というユーザーは存在しませんでした... もう一度教えてください:`;
} else {
this.temporaryUser = user;
this.emit('updated');
return `パスワードを教えてください:`;
}
} else {
// Compare password
const same = await bcrypt.compare(query, this.temporaryUser.password);
if (same) {
this.bot.signin(this.temporaryUser);
this.bot.clearContext();
return `${getUserName(this.temporaryUser)}さん、おかえりなさい!`;
} else {
return `パスワードが違います... もう一度教えてください:`;
}
}
}
public export() {
return {
type: 'signin',
content: {
temporaryUser: this.temporaryUser
}
};
}
public static import(bot: BotCore, data: any) {
const context = new SigninContext(bot);
context.temporaryUser = data.temporaryUser;
return context;
}
}
class NoteContext extends Context {
public async greet(): Promise<string> {
return '内容:';
}
public async q(query: string): Promise<string> {
await require('../endpoints/notes/create')({
text: query
}, this.bot.user);
this.bot.clearContext();
return '投稿しましたよ!';
}
public export() {
return {
type: 'note'
};
}
public static import(bot: BotCore, data: any) {
const context = new NoteContext(bot);
return context;
}
}
class TlContext extends Context {
private next: string = null;
public async greet(): Promise<string> {
return await this.getTl();
}
public async q(query: string): Promise<string> {
if (query == '次') {
return await this.getTl();
} else {
this.bot.clearContext();
return await this.bot.q(query);
}
}
private async getTl() {
const tl = await require('../endpoints/notes/timeline')({
limit: 5,
untilId: this.next ? this.next : undefined
}, this.bot.user);
if (tl.length > 0) {
this.next = tl[tl.length - 1].id;
this.emit('updated');
const text = tl
.map(note => `${getUserName(note.user)}\n「${getNoteSummary(note)}`)
.join('\n-----\n');
return text;
} else {
return 'タイムラインに表示するものがありません...';
}
}
public export() {
return {
type: 'tl',
content: {
next: this.next,
}
};
}
public static import(bot: BotCore, data: any) {
const context = new TlContext(bot);
context.next = data.next;
return context;
}
}
class NotificationsContext extends Context {
private next: string = null;
public async greet(): Promise<string> {
return await this.getNotifications();
}
public async q(query: string): Promise<string> {
if (query == '次') {
return await this.getNotifications();
} else {
this.bot.clearContext();
return await this.bot.q(query);
}
}
private async getNotifications() {
const notifications = await require('../endpoints/i/notifications')({
limit: 5,
untilId: this.next ? this.next : undefined
}, this.bot.user);
if (notifications.length > 0) {
this.next = notifications[notifications.length - 1].id;
this.emit('updated');
const text = notifications
.map(notification => getNotificationSummary(notification))
.join('\n-----\n');
return text;
} else {
return '通知はありません';
}
}
public export() {
return {
type: 'notifications',
content: {
next: this.next,
}
};
}
public static import(bot: BotCore, data: any) {
const context = new NotificationsContext(bot);
context.next = data.next;
return context;
}
}
class GuessingGameContext extends Context {
private secret: number;
private history: number[] = [];
public async greet(): Promise<string> {
this.secret = Math.floor(Math.random() * 100);
this.emit('updated');
return '0~100の秘密の数を当ててみてください:';
}
public async q(query: string): Promise<string> {
if (query == 'やめる') {
this.bot.clearContext();
return 'やめました。';
}
const guess = parseInt(query, 10);
if (isNaN(guess)) {
return '整数で推測してください。「やめる」と言うとゲームをやめます。';
}
const firsttime = this.history.indexOf(guess) === -1;
this.history.push(guess);
this.emit('updated');
if (this.secret < guess) {
return firsttime ? `${guess}よりも小さいですね` : `もう一度言いますが${guess}より小さいですよ`;
} else if (this.secret > guess) {
return firsttime ? `${guess}よりも大きいですね` : `もう一度言いますが${guess}より大きいですよ`;
} else {
this.bot.clearContext();
return `正解です🎉 (${this.history.length}回目で当てました)`;
}
}
public export() {
return {
type: 'guessing-game',
content: {
secret: this.secret,
history: this.history
}
};
}
public static import(bot: BotCore, data: any) {
const context = new GuessingGameContext(bot);
context.secret = data.secret;
context.history = data.history;
return context;
}
}

View File

@ -1,238 +0,0 @@
import * as EventEmitter from 'events';
import * as Router from 'koa-router';
import * as request from 'request';
import * as crypto from 'crypto';
import User from '../../../../models/user';
import config from '../../../../config';
import BotCore from '../core';
import _redis from '../../../../db/redis';
import prominence = require('prominence');
import getAcct from '../../../../acct/render';
import parseAcct from '../../../../acct/parse';
import getNoteSummary from '../../../../renderers/get-note-summary';
import getUserName from '../../../../renderers/get-user-name';
const redis = prominence(_redis);
// SEE: https://developers.line.me/media/messaging-api/messages/sticker_list.pdf
const stickers = [
'297',
'298',
'299',
'300',
'301',
'302',
'303',
'304',
'305',
'306',
'307'
];
class LineBot extends BotCore {
private replyToken: string;
private reply(messages: any[]) {
request.post({
url: 'https://api.line.me/v2/bot/message/reply',
headers: {
'Authorization': `Bearer ${config.line_bot.channel_access_token}`
},
json: {
replyToken: this.replyToken,
messages: messages
}
}, (err, res, body) => {
if (err) {
console.error(err);
return;
}
});
}
public async react(ev: any): Promise<void> {
this.replyToken = ev.replyToken;
switch (ev.type) {
// メッセージ
case 'message':
switch (ev.message.type) {
// テキスト
case 'text':
const res = await this.q(ev.message.text);
if (res == null) return;
// 返信
this.reply([{
type: 'text',
text: res
}]);
break;
// スタンプ
case 'sticker':
// スタンプで返信
this.reply([{
type: 'sticker',
packageId: '4',
stickerId: stickers[Math.floor(Math.random() * stickers.length)]
}]);
break;
}
break;
// noteback
case 'noteback':
const data = ev.noteback.data;
const cmd = data.split('|')[0];
const arg = data.split('|')[1];
switch (cmd) {
case 'showtl':
this.showUserTimelineNoteback(arg);
break;
}
break;
}
}
public static import(data) {
const bot = new LineBot();
bot._import(data);
return bot;
}
public async showUserCommand(q: string) {
const user = await require('../../endpoints/users/show')(parseAcct(q.substr(1)), this.user);
const acct = getAcct(user);
const actions = [];
actions.push({
type: 'noteback',
label: 'タイムラインを見る',
data: `showtl|${user.id}`
});
if (user.twitter) {
actions.push({
type: 'uri',
label: 'Twitterアカウントを見る',
uri: `https://twitter.com/${user.twitter.screenName}`
});
}
actions.push({
type: 'uri',
label: 'Webで見る',
uri: `${config.url}/@${acct}`
});
this.reply([{
type: 'template',
altText: await super.showUserCommand(q),
template: {
type: 'buttons',
thumbnailImageUrl: `${user.avatarUrl}?thumbnail&size=1024`,
title: `${getUserName(user)} (@${acct})`,
text: user.description || '(no description)',
actions: actions
}
}]);
return null;
}
public async showUserTimelineNoteback(userId: string) {
const tl = await require('../../endpoints/users/notes')({
userId: userId,
limit: 5
}, this.user);
const text = `${getUserName(tl[0].user)}さんのタイムラインはこちらです:\n\n` + tl
.map(note => getNoteSummary(note))
.join('\n-----\n');
this.reply([{
type: 'text',
text: text
}]);
}
}
const handler = new EventEmitter();
handler.on('event', async (ev) => {
const sourceId = ev.source.userId;
const sessionId = `line-bot-sessions:${sourceId}`;
const session = await redis.get(sessionId);
let bot: LineBot;
if (session == null) {
const user = await User.findOne({
host: null,
'line': {
userId: sourceId
}
});
bot = new LineBot(user);
bot.on('signin', user => {
User.update(user._id, {
$set: {
'line': {
userId: sourceId
}
}
});
});
bot.on('signout', user => {
User.update(user._id, {
$set: {
'line': {
userId: null
}
}
});
});
redis.set(sessionId, JSON.stringify(bot.export()));
} else {
bot = LineBot.import(JSON.parse(session));
}
bot.on('updated', () => {
redis.set(sessionId, JSON.stringify(bot.export()));
});
if (session != null) bot.refreshUser();
bot.react(ev);
});
// Init router
const router = new Router();
if (config.line_bot) {
router.post('/hooks/line', ctx => {
const sig1 = ctx.headers['x-line-signature'];
const hash = crypto.createHmac('SHA256', config.line_bot.channel_secret)
.update(ctx.request.rawBody);
const sig2 = hash.digest('base64');
// シグネチャ比較
if (sig1 === sig2) {
ctx.request.body.events.forEach(ev => {
handler.emit('event', ev);
});
} else {
ctx.status = 400;
}
});
}
module.exports = router;

View File

@ -1,5 +1,5 @@
import { toUnicode } from 'punycode';
export default host => {
export default (host: string) => {
return toUnicode(host).toLowerCase();
};

View File

@ -1,13 +1,10 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import Note from '../../../../models/note';
/**
* Aggregate notes
*/
module.exports = params => new Promise(async (res, rej) => {
module.exports = (params: any) => new Promise(async (res, rej) => {
// Get 'limit' parameter
const [limit = 365, limitErr] = $.num.optional().range(1, 365).get(params.limit);
if (limitErr) return rej('invalid limit param');

View File

@ -1,13 +1,10 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import User from '../../../../models/user';
/**
* Aggregate users
*/
module.exports = params => new Promise(async (res, rej) => {
module.exports = (params: any) => new Promise(async (res, rej) => {
// Get 'limit' parameter
const [limit = 365, limitErr] = $.num.optional().range(1, 365).get(params.limit);
if (limitErr) return rej('invalid limit param');

View File

@ -1,6 +1,3 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import User from '../../../../../models/user';
import Note from '../../../../../models/note';
@ -10,7 +7,7 @@ import Note from '../../../../../models/note';
/**
* Aggregate activity of a user
*/
module.exports = (params) => new Promise(async (res, rej) => {
module.exports = (params: any) => new Promise(async (res, rej) => {
// Get 'limit' parameter
const [limit = 365, limitErr] = $.num.optional().range(1, 365).get(params.limit);
if (limitErr) return rej('invalid limit param');
@ -73,13 +70,13 @@ module.exports = (params) => new Promise(async (res, rej) => {
} }
]);
datas.forEach(data => {
datas.forEach((data: any) => {
data.date = data._id;
delete data._id;
data.notes = (data.data.filter(x => x.type == 'note')[0] || { count: 0 }).count;
data.renotes = (data.data.filter(x => x.type == 'renote')[0] || { count: 0 }).count;
data.replies = (data.data.filter(x => x.type == 'reply')[0] || { count: 0 }).count;
data.notes = (data.data.filter((x: any) => x.type == 'note')[0] || { count: 0 }).count;
data.renotes = (data.data.filter((x: any) => x.type == 'renote')[0] || { count: 0 }).count;
data.replies = (data.data.filter((x: any) => x.type == 'reply')[0] || { count: 0 }).count;
delete data.data;
});
@ -89,7 +86,7 @@ module.exports = (params) => new Promise(async (res, rej) => {
for (let i = 0; i < limit; i++) {
const day = new Date(new Date().setDate(new Date().getDate() - i));
const data = datas.filter(d =>
const data = datas.filter((d: any) =>
d.date.year == day.getFullYear() && d.date.month == day.getMonth() + 1 && d.date.day == day.getDate()
)[0];

View File

@ -8,7 +8,7 @@ import FollowedLog from '../../../../../models/followed-log';
/**
* Aggregate followers of a user
*/
module.exports = (params) => new Promise(async (res, rej) => {
module.exports = (params: any) => new Promise(async (res, rej) => {
// Get 'userId' parameter
const [userId, userIdErr] = $.type(ID).get(params.userId);
if (userIdErr) return rej('invalid userId param');

View File

@ -8,7 +8,7 @@ import FollowingLog from '../../../../../models/following-log';
/**
* Aggregate following of a user
*/
module.exports = (params) => new Promise(async (res, rej) => {
module.exports = (params: any) => new Promise(async (res, rej) => {
// Get 'userId' parameter
const [userId, userIdErr] = $.type(ID).get(params.userId);
if (userIdErr) return rej('invalid userId param');

View File

@ -1,6 +1,3 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import User from '../../../../../models/user';
import Note from '../../../../../models/note';
@ -8,7 +5,7 @@ import Note from '../../../../../models/note';
/**
* Aggregate note of a user
*/
module.exports = (params) => new Promise(async (res, rej) => {
module.exports = (params: any) => new Promise(async (res, rej) => {
// Get 'userId' parameter
const [userId, userIdErr] = $.type(ID).get(params.userId);
if (userIdErr) return rej('invalid userId param');
@ -67,13 +64,13 @@ module.exports = (params) => new Promise(async (res, rej) => {
} }
]);
datas.forEach(data => {
datas.forEach((data: any) => {
data.date = data._id;
delete data._id;
data.notes = (data.data.filter(x => x.type == 'note')[0] || { count: 0 }).count;
data.renotes = (data.data.filter(x => x.type == 'renote')[0] || { count: 0 }).count;
data.replies = (data.data.filter(x => x.type == 'reply')[0] || { count: 0 }).count;
data.notes = (data.data.filter((x: any) => x.type == 'note')[0] || { count: 0 }).count;
data.renotes = (data.data.filter((x: any) => x.type == 'renote')[0] || { count: 0 }).count;
data.replies = (data.data.filter((x: any) => x.type == 'reply')[0] || { count: 0 }).count;
delete data.data;
});
@ -83,7 +80,7 @@ module.exports = (params) => new Promise(async (res, rej) => {
for (let i = 0; i < 30; i++) {
const day = new Date(new Date().setDate(new Date().getDate() - i));
const data = datas.filter(d =>
const data = datas.filter((d: any) =>
d.date.year == day.getFullYear() && d.date.month == day.getMonth() + 1 && d.date.day == day.getDate()
)[0];

View File

@ -1,17 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import User from '../../../../../models/user';
import Reaction from '../../../../../models/note-reaction';
/**
* Aggregate reaction of a user
*
* @param {any} params
* @return {Promise<any>}
*/
module.exports = (params) => new Promise(async (res, rej) => {
module.exports = (params: any) => new Promise(async (res, rej) => {
// Get 'userId' parameter
const [userId, userIdErr] = $.type(ID).get(params.userId);
if (userIdErr) return rej('invalid userId param');
@ -48,7 +42,7 @@ module.exports = (params) => new Promise(async (res, rej) => {
}}
]);
datas.forEach(data => {
datas.forEach((data: any) => {
data.date = data._id;
delete data._id;
});
@ -58,7 +52,7 @@ module.exports = (params) => new Promise(async (res, rej) => {
for (let i = 0; i < 30; i++) {
const day = new Date(new Date().setDate(new Date().getDate() - i));
const data = datas.filter(d =>
const data = datas.filter((d: any) =>
d.date.year == day.getFullYear() && d.date.month == day.getMonth() + 1 && d.date.day == day.getDate()
)[0];

View File

@ -1,9 +1,7 @@
/**
* Module dependencies
*/
import rndstr from 'rndstr';
import $ from 'cafy';
import App, { isValidNameId, pack } from '../../../../models/app';
import { ILocalUser } from '../../../../models/user';
/**
* @swagger
@ -60,12 +58,8 @@ import App, { isValidNameId, pack } from '../../../../models/app';
/**
* Create an app
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = async (params, user) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'nameId' parameter
const [nameId, nameIdErr] = $.str.pipe(isValidNameId).get(params.nameId);
if (nameIdErr) return rej('invalid nameId param');

View File

@ -40,7 +40,7 @@ import { isValidNameId } from '../../../../../models/app';
* @param {any} params
* @return {Promise<any>}
*/
module.exports = async (params) => new Promise(async (res, rej) => {
module.exports = async (params: any) => new Promise(async (res, rej) => {
// Get 'nameId' parameter
const [nameId, nameIdErr] = $.str.pipe(isValidNameId).get(params.nameId);
if (nameIdErr) return rej('invalid nameId param');

View File

@ -1,8 +1,6 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import App, { pack } from '../../../../models/app';
import App, { pack, IApp } from '../../../../models/app';
import { ILocalUser } from '../../../../models/user';
/**
* @swagger
@ -37,7 +35,7 @@ import App, { pack } from '../../../../models/app';
/**
* Show an app
*/
module.exports = (params, user, app) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
const isSecure = user != null && app == null;
// Get 'appId' parameter

View File

@ -1,12 +1,10 @@
/**
* Module dependencies
*/
import rndstr from 'rndstr';
const crypto = require('crypto');
import $ from 'cafy';
import App from '../../../../models/app';
import AuthSess from '../../../../models/auth-session';
import AccessToken from '../../../../models/access-token';
import { ILocalUser } from '../../../../models/user';
/**
* @swagger
@ -33,12 +31,8 @@ import AccessToken from '../../../../models/access-token';
/**
* Accept
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'token' parameter
const [token, tokenErr] = $.str.get(params.token);
if (tokenErr) return rej('invalid token param');

View File

@ -44,7 +44,7 @@ import config from '../../../../../config';
* @param {any} params
* @return {Promise<any>}
*/
module.exports = (params) => new Promise(async (res, rej) => {
module.exports = (params: any) => new Promise(async (res, rej) => {
// Get 'appSecret' parameter
const [appSecret, appSecretErr] = $.str.get(params.appSecret);
if (appSecretErr) return rej('invalid appSecret param');

View File

@ -1,8 +1,6 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import AuthSess, { pack } from '../../../../../models/auth-session';
import { ILocalUser } from '../../../../../models/user';
/**
* @swagger
@ -46,12 +44,8 @@ import AuthSess, { pack } from '../../../../../models/auth-session';
/**
* Show a session
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'token' parameter
const [token, tokenErr] = $.str.get(params.token);
if (tokenErr) return rej('invalid token param');

View File

@ -49,7 +49,7 @@ import { pack } from '../../../../../models/user';
* @param {any} params
* @return {Promise<any>}
*/
module.exports = (params) => new Promise(async (res, rej) => {
module.exports = (params: any) => new Promise(async (res, rej) => {
// Get 'appSecret' parameter
const [appSecret, appSecretErr] = $.str.get(params.appSecret);
if (appSecretErr) return rej('invalid appSecret param');

View File

@ -1,9 +1,10 @@
import DriveFile from '../../../models/drive-file';
import { ILocalUser } from '../../../models/user';
/**
* Get drive information
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Calculate drive usage
const usage = await DriveFile
.aggregate([{

View File

@ -1,13 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import DriveFile, { pack } from '../../../../models/drive-file';
import { ILocalUser } from '../../../../models/user';
/**
* Get drive files
*/
module.exports = async (params, user, app) => {
module.exports = async (params: any, user: ILocalUser) => {
// Get 'limit' parameter
const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit);
if (limitErr) throw 'invalid limit param';

View File

@ -1,15 +1,13 @@
/**
* Module dependencies
*/
import * as fs from 'fs';
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import { validateFileName, pack } from '../../../../../models/drive-file';
import create from '../../../../../services/drive/add-file';
import { ILocalUser } from '../../../../../models/user';
/**
* Create a file
*/
module.exports = async (file, params, user): Promise<any> => {
module.exports = async (file: any, params: any, user: ILocalUser): Promise<any> => {
if (file == null) {
throw 'file is required';
}

View File

@ -2,11 +2,12 @@ import $ from 'cafy'; import ID from '../../../../../cafy-id';
import DriveFile from '../../../../../models/drive-file';
import del from '../../../../../services/drive/delete-file';
import { publishDriveStream } from '../../../../../publishers/stream';
import { ILocalUser } from '../../../../../models/user';
/**
* Delete a file
*/
module.exports = async (params, user) => {
module.exports = async (params: any, user: ILocalUser) => {
// Get 'fileId' parameter
const [fileId, fileIdErr] = $.type(ID).get(params.fileId);
if (fileIdErr) throw 'invalid fileId param';

View File

@ -1,13 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import DriveFile, { pack } from '../../../../../models/drive-file';
import { ILocalUser } from '../../../../../models/user';
/**
* Find a file(s)
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'name' parameter
const [name, nameErr] = $.str.get(params.name);
if (nameErr) return rej('invalid name param');

View File

@ -1,13 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import DriveFile, { pack } from '../../../../../models/drive-file';
import { ILocalUser } from '../../../../../models/user';
/**
* Show a file
*/
module.exports = async (params, user) => {
module.exports = async (params: any, user: ILocalUser) => {
// Get 'fileId' parameter
const [fileId, fileIdErr] = $.type(ID).get(params.fileId);
if (fileIdErr) throw 'invalid fileId param';

View File

@ -1,15 +1,13 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import DriveFolder from '../../../../../models/drive-folder';
import DriveFile, { validateFileName, pack } from '../../../../../models/drive-file';
import { publishDriveStream } from '../../../../../publishers/stream';
import { ILocalUser } from '../../../../../models/user';
/**
* Update a file
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'fileId' parameter
const [fileId, fileIdErr] = $.type(ID).get(params.fileId);
if (fileIdErr) return rej('invalid fileId param');

View File

@ -7,7 +7,7 @@ import DriveFolder, { pack } from '../../../../models/drive-folder';
/**
* Get drive folders
*/
module.exports = (params, user, app) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
// Get 'limit' parameter
const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit);
if (limitErr) return rej('invalid limit param');

View File

@ -1,14 +1,12 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import DriveFolder, { isValidFolderName, pack } from '../../../../../models/drive-folder';
import { publishDriveStream } from '../../../../../publishers/stream';
import { ILocalUser } from '../../../../../models/user';
/**
* Create drive folder
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'name' parameter
const [name = '無題のフォルダー', nameErr] = $.str.optional().pipe(isValidFolderName).get(params.name);
if (nameErr) return rej('invalid name param');

View File

@ -1,13 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import DriveFolder, { pack } from '../../../../../models/drive-folder';
import { ILocalUser } from '../../../../../models/user';
/**
* Find a folder(s)
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'name' parameter
const [name, nameErr] = $.str.get(params.name);
if (nameErr) return rej('invalid name param');

View File

@ -1,13 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import DriveFolder, { pack } from '../../../../../models/drive-folder';
import { ILocalUser } from '../../../../../models/user';
/**
* Show a folder
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'folderId' parameter
const [folderId, folderIdErr] = $.type(ID).get(params.folderId);
if (folderIdErr) return rej('invalid folderId param');

View File

@ -1,14 +1,12 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import DriveFolder, { isValidFolderName, pack } from '../../../../../models/drive-folder';
import { publishDriveStream } from '../../../../../publishers/stream';
import { ILocalUser } from '../../../../../models/user';
/**
* Update a folder
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'folderId' parameter
const [folderId, folderIdErr] = $.type(ID).get(params.folderId);
if (folderIdErr) return rej('invalid folderId param');
@ -48,7 +46,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
}
// Check if the circular reference will occur
async function checkCircle(folderId) {
async function checkCircle(folderId: any): Promise<boolean> {
// Fetch folder
const folder2 = await DriveFolder.findOne({
_id: folderId

View File

@ -1,13 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import DriveFile, { pack } from '../../../../models/drive-file';
import { ILocalUser } from '../../../../models/user';
/**
* Get drive stream
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'limit' parameter
const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit);
if (limitErr) return rej('invalid limit param');

View File

@ -1,15 +1,12 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import User, { pack } from '../../../../models/user';
import User, { pack, ILocalUser } from '../../../../models/user';
import Following from '../../../../models/following';
import create from '../../../../services/following/create';
/**
* Follow a user
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
const follower = user;
// Get 'userId' parameter

View File

@ -1,15 +1,12 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import User, { pack } from '../../../../models/user';
import User, { pack, ILocalUser } from '../../../../models/user';
import Following from '../../../../models/following';
import deleteFollowing from '../../../../services/following/delete';
/**
* Unfollow a user
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
const follower = user;
// Get 'userId' parameter

View File

@ -1,11 +1,11 @@
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import acceptFollowRequest from '../../../../../services/following/requests/accept';
import User from '../../../../../models/user';
import User, { ILocalUser } from '../../../../../models/user';
/**
* Accept a follow request
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'userId' parameter
const [followerId, followerIdErr] = $.type(ID).get(params.userId);
if (followerIdErr) return rej('invalid userId param');

View File

@ -1,11 +1,11 @@
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import cancelFollowRequest from '../../../../../services/following/requests/cancel';
import User, { pack } from '../../../../../models/user';
import User, { pack, ILocalUser } from '../../../../../models/user';
/**
* Cancel a follow request
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'userId' parameter
const [followeeId, followeeIdErr] = $.type(ID).get(params.userId);
if (followeeIdErr) return rej('invalid userId param');

View File

@ -1,10 +1,11 @@
//import $ from 'cafy'; import ID from '../../../../../cafy-id';
import FollowRequest, { pack } from '../../../../../models/follow-request';
import { ILocalUser } from '../../../../../models/user';
/**
* Get all pending received follow requests
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
const reqs = await FollowRequest.find({
followeeId: user._id
});

View File

@ -1,11 +1,11 @@
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import rejectFollowRequest from '../../../../../services/following/requests/reject';
import User from '../../../../../models/user';
import User, { ILocalUser } from '../../../../../models/user';
/**
* Reject a follow request
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'userId' parameter
const [followerId, followerIdErr] = $.type(ID).get(params.userId);
if (followerIdErr) return rej('invalid userId param');

View File

@ -1,10 +1,11 @@
import $ from 'cafy'; import ID from '../../../../cafy-id';
import Following from '../../../../models/following';
import { ILocalUser } from '../../../../models/user';
/**
* Stalk a user
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
const follower = user;
// Get 'userId' parameter

View File

@ -1,10 +1,11 @@
import $ from 'cafy'; import ID from '../../../../cafy-id';
import Following from '../../../../models/following';
import { ILocalUser } from '../../../../models/user';
/**
* Unstalk a user
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
const follower = user;
// Get 'userId' parameter

View File

@ -45,7 +45,10 @@ module.exports = () => new Promise(async (res, rej) => {
return res([]);
}
const tags = [];
const tags: Array<{
name: string;
count: number;
}> = [];
// カウント
data.map(x => x._id).forEach(x => {

View File

@ -1,12 +1,10 @@
/**
* Module dependencies
*/
import User, { pack } from '../../../models/user';
import User, { pack, ILocalUser } from '../../../models/user';
import { IApp } from '../../../models/app';
/**
* Show myself
*/
module.exports = (params, user, app) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
const isSecure = user != null && app == null;
// Serialize

View File

@ -1,11 +1,8 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import * as speakeasy from 'speakeasy';
import User from '../../../../../models/user';
import User, { ILocalUser } from '../../../../../models/user';
module.exports = async (params, user) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'token' parameter
const [token, tokenErr] = $.str.get(params.token);
if (tokenErr) return rej('invalid token param');

View File

@ -1,14 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import * as bcrypt from 'bcryptjs';
import * as speakeasy from 'speakeasy';
import * as QRCode from 'qrcode';
import User from '../../../../../models/user';
import User, { ILocalUser } from '../../../../../models/user';
import config from '../../../../../config';
module.exports = async (params, user) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'password' parameter
const [password, passwordErr] = $.str.get(params.password);
if (passwordErr) return rej('invalid password param');

View File

@ -1,11 +1,8 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import * as bcrypt from 'bcryptjs';
import User from '../../../../../models/user';
import User, { ILocalUser } from '../../../../../models/user';
module.exports = async (params, user) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'password' parameter
const [password, passwordErr] = $.str.get(params.password);
if (passwordErr) return rej('invalid password param');

View File

@ -1,14 +1,12 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import AccessToken from '../../../../models/access-token';
import { pack } from '../../../../models/app';
import { ILocalUser } from '../../../../models/user';
/**
* Get authorized apps of my account
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'limit' parameter
const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit);
if (limitErr) return rej('invalid limit param');

View File

@ -1,14 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import * as bcrypt from 'bcryptjs';
import User from '../../../../models/user';
import User, { ILocalUser } from '../../../../models/user';
/**
* Change password
*/
module.exports = async (params, user) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'currentPasword' parameter
const [currentPassword, currentPasswordErr] = $.str.get(params.currentPasword);
if (currentPasswordErr) return rej('invalid currentPasword param');

View File

@ -1,13 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import Favorite, { pack } from '../../../../models/favorite';
import { ILocalUser } from '../../../../models/user';
/**
* Get favorited notes
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'limit' parameter
const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit);
if (limitErr) return rej('invalid limit param');

View File

@ -1,17 +1,15 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import Notification from '../../../../models/notification';
import Mute from '../../../../models/mute';
import { pack } from '../../../../models/notification';
import { getFriendIds } from '../../common/get-friends';
import read from '../../common/read-notification';
import { ILocalUser } from '../../../../models/user';
/**
* Get notifications
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'following' parameter
const [following = false, followingError] =
$.bool.optional().get(params.following);

View File

@ -1,15 +1,12 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import User from '../../../../models/user';
import User, { ILocalUser } from '../../../../models/user';
import Note from '../../../../models/note';
import { pack } from '../../../../models/user';
/**
* Pin note
*/
module.exports = async (params, user) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
const [noteId, noteIdErr] = $.type(ID).get(params.noteId);
if (noteIdErr) return rej('invalid noteId param');

View File

@ -1,16 +1,13 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import * as bcrypt from 'bcryptjs';
import User from '../../../../models/user';
import User, { ILocalUser } from '../../../../models/user';
import event from '../../../../publishers/stream';
import generateUserToken from '../../common/generate-native-user-token';
/**
* Regenerate native token
*/
module.exports = async (params, user) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'password' parameter
const [password, passwordErr] = $.str.get(params.password);
if (passwordErr) return rej('invalid password param');

View File

@ -1,13 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import Signin, { pack } from '../../../../models/signin';
import { ILocalUser } from '../../../../models/user';
/**
* Get signin history of my account
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'limit' parameter
const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit);
if (limitErr) return rej('invalid limit param');

View File

@ -1,16 +1,14 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import User, { isValidName, isValidDescription, isValidLocation, isValidBirthday, pack } from '../../../../models/user';
import User, { isValidName, isValidDescription, isValidLocation, isValidBirthday, pack, ILocalUser } from '../../../../models/user';
import event from '../../../../publishers/stream';
import DriveFile from '../../../../models/drive-file';
import acceptAllFollowRequests from '../../../../services/following/requests/accept-all';
import { IApp } from '../../../../models/app';
/**
* Update myself
*/
module.exports = async (params, user, app) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
const isSecure = user != null && app == null;
const updates = {} as any;

View File

@ -1,14 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import User from '../../../../models/user';
import User, { ILocalUser } from '../../../../models/user';
import event from '../../../../publishers/stream';
/**
* Update myself
*/
module.exports = async (params, user) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'name' parameter
const [name, nameErr] = $.str.get(params.name);
if (nameErr) return rej('invalid name param');
@ -17,7 +14,7 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
const [value, valueErr] = $.any.nullable().get(params.value);
if (valueErr) return rej('invalid value param');
const x = {};
const x: any = {};
x[`clientSettings.${name}`] = value;
await User.update(user._id, {

View File

@ -1,8 +1,8 @@
import $ from 'cafy';
import User from '../../../../models/user';
import User, { ILocalUser } from '../../../../models/user';
import event from '../../../../publishers/stream';
module.exports = async (params, user) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'home' parameter
const [home, homeErr] = $.arr(
$.obj.strict()

View File

@ -1,8 +1,8 @@
import $ from 'cafy';
import User from '../../../../models/user';
import User, { ILocalUser } from '../../../../models/user';
import event from '../../../../publishers/stream';
module.exports = async (params, user) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'home' parameter
const [home, homeErr] = $.arr(
$.obj.strict()

View File

@ -1,8 +1,8 @@
import $ from 'cafy';
import User from '../../../../models/user';
import User, { ILocalUser } from '../../../../models/user';
import event from '../../../../publishers/stream';
module.exports = async (params, user) => new Promise(async (res, rej) => {
module.exports = async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'id' parameter
const [id, idErr] = $.str.get(params.id);
if (idErr) return rej('invalid id param');
@ -18,7 +18,7 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
//#region Desktop home
if (widget == null && user.clientSettings.home) {
const desktopHome = user.clientSettings.home;
widget = desktopHome.find(w => w.id == id);
widget = desktopHome.find((w: any) => w.id == id);
if (widget) {
widget.data = data;
@ -34,7 +34,7 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
//#region Mobile home
if (widget == null && user.clientSettings.mobileHome) {
const mobileHome = user.clientSettings.mobileHome;
widget = mobileHome.find(w => w.id == id);
widget = mobileHome.find((w: any) => w.id == id);
if (widget) {
widget.data = data;
@ -50,8 +50,8 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
//#region Deck
if (widget == null && user.clientSettings.deck && user.clientSettings.deck.columns) {
const deck = user.clientSettings.deck;
deck.columns.filter(c => c.type == 'widgets').forEach(c => {
c.widgets.forEach(w => {
deck.columns.filter((c: any) => c.type == 'widgets').forEach((c: any) => {
c.widgets.forEach((w: any) => {
if (w.id == id) widget = w;
});
});

View File

@ -1,15 +1,13 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import History from '../../../../models/messaging-history';
import Mute from '../../../../models/mute';
import { pack } from '../../../../models/messaging-message';
import { ILocalUser } from '../../../../models/user';
/**
* Show messaging history
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'limit' parameter
const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit);
if (limitErr) return rej('invalid limit param');

View File

@ -1,13 +1,13 @@
import $ from 'cafy'; import ID from '../../../../cafy-id';
import Message from '../../../../models/messaging-message';
import User from '../../../../models/user';
import User, { ILocalUser } from '../../../../models/user';
import { pack } from '../../../../models/messaging-message';
import read from '../../common/read-messaging-message';
/**
* Get messages
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'userId' parameter
const [recipientId, recipientIdErr] = $.type(ID).get(params.userId);
if (recipientIdErr) return rej('invalid userId param');

View File

@ -1,11 +1,8 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../../cafy-id';
import Message from '../../../../../models/messaging-message';
import { isValidText } from '../../../../../models/messaging-message';
import History from '../../../../../models/messaging-history';
import User from '../../../../../models/user';
import User, { ILocalUser } from '../../../../../models/user';
import Mute from '../../../../../models/mute';
import DriveFile from '../../../../../models/drive-file';
import { pack } from '../../../../../models/messaging-message';
@ -17,7 +14,7 @@ import config from '../../../../../config';
/**
* Create a message
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'userId' parameter
const [recipientId, recipientIdErr] = $.type(ID).get(params.userId);
if (recipientIdErr) return rej('invalid userId param');

View File

@ -38,7 +38,7 @@ const client = require('../../../../built/client/meta.json');
/**
* Show core info
*/
module.exports = (params) => new Promise(async (res, rej) => {
module.exports = (params: any) => new Promise(async (res, rej) => {
const meta: any = (await Meta.findOne()) || {};
res({

View File

@ -1,14 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import User from '../../../../models/user';
import User, { ILocalUser } from '../../../../models/user';
import Mute from '../../../../models/mute';
/**
* Mute a user
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
const muter = user;
// Get 'userId' parameter

View File

@ -1,14 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import User from '../../../../models/user';
import User, { ILocalUser } from '../../../../models/user';
import Mute from '../../../../models/mute';
/**
* Unmute a user
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
const muter = user;
// Get 'userId' parameter

View File

@ -1,15 +1,12 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import Mute from '../../../../models/mute';
import { pack } from '../../../../models/user';
import { pack, ILocalUser } from '../../../../models/user';
import { getFriendIds } from '../../common/get-friends';
/**
* Get muted users of a user
*/
module.exports = (params, me) => new Promise(async (res, rej) => {
module.exports = (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
// Get 'iknow' parameter
const [iknow = false, iknowErr] = $.bool.optional().get(params.iknow);
if (iknowErr) return rej('invalid iknow param');

View File

@ -1,13 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import App, { pack } from '../../../../models/app';
import { ILocalUser } from '../../../../models/user';
/**
* Get my apps
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'limit' parameter
const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit);
if (limitErr) return rej('invalid limit param');

View File

@ -7,7 +7,7 @@ import Note, { pack } from '../../../models/note';
/**
* Get all notes
*/
module.exports = (params) => new Promise(async (res, rej) => {
module.exports = (params: any) => new Promise(async (res, rej) => {
// Get 'local' parameter
const [local, localErr] = $.bool.optional().get(params.local);
if (localErr) return rej('invalid local param');

View File

@ -1,13 +1,11 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note, { pack } from '../../../../models/note';
import Note, { pack, INote } from '../../../../models/note';
import { ILocalUser } from '../../../../models/user';
/**
* Show conversation of a note
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
const [noteId, noteIdErr] = $.type(ID).get(params.noteId);
if (noteIdErr) return rej('invalid noteId param');
@ -29,10 +27,10 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
return rej('note not found');
}
const conversation = [];
const conversation: INote[] = [];
let i = 0;
async function get(id) {
async function get(id: any) {
i++;
const p = await Note.findOne({ _id: id });

View File

@ -1,9 +1,6 @@
/**
* Module dependencies
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note, { INote, isValidText, isValidCw, pack } from '../../../../models/note';
import User, { ILocalUser } from '../../../../models/user';
import User, { ILocalUser, IUser } from '../../../../models/user';
import DriveFile from '../../../../models/drive-file';
import create from '../../../../services/note/create';
import { IApp } from '../../../../models/app';
@ -11,7 +8,7 @@ import { IApp } from '../../../../models/app';
/**
* Create a note
*/
module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
module.exports = (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
// Get 'visibility' parameter
const [visibility = 'public', visibilityErr] = $.str.optional().or(['public', 'home', 'followers', 'specified', 'private']).get(params.visibility);
if (visibilityErr) return rej('invalid visibility');
@ -20,7 +17,7 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
const [visibleUserIds, visibleUserIdsErr] = $.arr($.type(ID)).optional().unique().min(1).get(params.visibleUserIds);
if (visibleUserIdsErr) return rej('invalid visibleUserIds');
let visibleUsers = [];
let visibleUsers: IUser[] = [];
if (visibleUserIds !== undefined) {
visibleUsers = await Promise.all(visibleUserIds.map(id => User.findOne({
_id: id
@ -132,7 +129,7 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
if (pollErr) return rej('invalid poll');
if (poll) {
(poll as any).choices = (poll as any).choices.map((choice, i) => ({
(poll as any).choices = (poll as any).choices.map((choice: string, i: number) => ({
id: i, // IDを付与
text: choice.trim(),
votes: 0

Some files were not shown because too many files have changed in this diff Show More