0
0
Fork 0

ES Modulesに移行

This commit is contained in:
Xeltica 2023-02-25 17:13:07 +09:00
parent 0c3df4245d
commit 69212dd99a
105 changed files with 3154 additions and 3230 deletions

View file

@ -16,13 +16,7 @@ module.exports = {
'@typescript-eslint' '@typescript-eslint'
], ],
'rules': { 'rules': {
'indent': [ 'indent': ['error', 2, { 'SwitchCase': 1 } ],
'error',
'tab',
{
'SwitchCase': 1,
}
],
'quotes': [ 'quotes': [
'error', 'error',
'single' 'single'
@ -31,6 +25,7 @@ module.exports = {
'error', 'error',
'always' 'always'
], ],
'@typescript-eslint/explicit-module-boundary-types': 'off' '@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
} }
}; };

1
.gitignore vendored
View file

@ -2,3 +2,4 @@ node_modules
built built
yarn-error.log yarn-error.log
config.json config.json
.yarn

View file

@ -1,14 +1,19 @@
<component name="ProjectCodeStyleConfiguration"> <component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173"> <code_scheme name="Project" version="173">
<option name="AUTODETECT_INDENTS" value="false" />
<JSCodeStyleSettings version="0"> <JSCodeStyleSettings version="0">
<option name="FORCE_SEMICOLON_STYLE" value="true" /> <option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="USE_DOUBLE_QUOTES" value="false" /> <option name="USE_DOUBLE_QUOTES" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" /> <option name="FORCE_QUOTE_STYlE" value="true" />
<option name="USE_EXPLICIT_JS_EXTENSION" value="TRUE" />
<option name="IMPORT_USE_NODE_RESOLUTION" value="FALSE" />
</JSCodeStyleSettings> </JSCodeStyleSettings>
<TypeScriptCodeStyleSettings version="0"> <TypeScriptCodeStyleSettings version="0">
<option name="FORCE_SEMICOLON_STYLE" value="true" /> <option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="USE_DOUBLE_QUOTES" value="false" /> <option name="USE_DOUBLE_QUOTES" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" /> <option name="FORCE_QUOTE_STYlE" value="true" />
<option name="USE_EXPLICIT_JS_EXTENSION" value="TRUE" />
<option name="IMPORT_USE_NODE_RESOLUTION" value="GLOBAL" />
</TypeScriptCodeStyleSettings> </TypeScriptCodeStyleSettings>
<codeStyleSettings language="JavaScript"> <codeStyleSettings language="JavaScript">
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
@ -21,7 +26,9 @@
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="ALIGN_MULTILINE_FOR" value="false" /> <option name="ALIGN_MULTILINE_FOR" value="false" />
<indentOptions> <indentOptions>
<option name="USE_TAB_CHARACTER" value="true" /> <option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
</code_scheme> </code_scheme>

6
.idea/jsLibraryMappings.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<includedPredefinedLibrary name="Node.js Core" />
</component>
</project>

View file

@ -1,2 +1,2 @@
yarnPath: .yarn/releases/yarn-1.22.19.cjs yarnPath: .yarn/releases/yarn-1.22.19.cjs
nodeLinker: node-modulesl nodeLinker: node-modules

View file

@ -1,4 +1,4 @@
const { readFileSync, writeFileSync } = require('fs'); import {readFileSync, writeFileSync} from 'fs';
const { version } = JSON.parse(readFileSync('./package.json', { const { version } = JSON.parse(readFileSync('./package.json', {
encoding: 'UTF-8', encoding: 'UTF-8',

View file

@ -1,7 +1,7 @@
import {MigrationInterface, QueryRunner} from 'typeorm'; import {MigrationInterface, QueryRunner} from 'typeorm';
export class Init1596513280623 implements MigrationInterface { export class Init1596513280623 implements MigrationInterface {
name = 'Init1596513280623' name = 'Init1596513280623';
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('CREATE TABLE "user" ("id" SERIAL NOT NULL, "username" character varying NOT NULL, "host" character varying NOT NULL, "token" character varying NOT NULL, "prevNotesCount" integer NOT NULL, "prevFollowingCount" integer NOT NULL, "prevFollowersCount" integer NOT NULL, CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))'); await queryRunner.query('CREATE TABLE "user" ("id" SERIAL NOT NULL, "username" character varying NOT NULL, "host" character varying NOT NULL, "token" character varying NOT NULL, "prevNotesCount" integer NOT NULL, "prevFollowingCount" integer NOT NULL, "prevFollowersCount" integer NOT NULL, CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))');

View file

@ -1,7 +1,7 @@
import {MigrationInterface, QueryRunner} from 'typeorm'; import {MigrationInterface, QueryRunner} from 'typeorm';
export class Init21596514165166 implements MigrationInterface { export class Init21596514165166 implements MigrationInterface {
name = 'Init21596514165166' name = 'Init21596514165166';
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('ALTER TABLE "user" ALTER COLUMN "prevNotesCount" SET DEFAULT 0'); await queryRunner.query('ALTER TABLE "user" ALTER COLUMN "prevNotesCount" SET DEFAULT 0');

View file

@ -1,7 +1,7 @@
import {MigrationInterface, QueryRunner} from 'typeorm'; import {MigrationInterface, QueryRunner} from 'typeorm';
export class mypage1599570288522 implements MigrationInterface { export class mypage1599570288522 implements MigrationInterface {
name = 'mypage1599570288522' name = 'mypage1599570288522';
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('CREATE TABLE "used_token" ("token" character varying NOT NULL, CONSTRAINT "PK_7f2db4c33c33cd6b38e63393fe5" PRIMARY KEY ("token"))'); await queryRunner.query('CREATE TABLE "used_token" ("token" character varying NOT NULL, CONSTRAINT "PK_7f2db4c33c33cd6b38e63393fe5" PRIMARY KEY ("token"))');

View file

@ -1,7 +1,7 @@
import {MigrationInterface, QueryRunner} from 'typeorm'; import {MigrationInterface, QueryRunner} from 'typeorm';
export class mode1599577510614 implements MigrationInterface { export class mode1599577510614 implements MigrationInterface {
name = 'mode1599577510614' name = 'mode1599577510614';
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('CREATE TYPE "user_alertmode_enum" AS ENUM(\'note\', \'notification\', \'nothing\')'); await queryRunner.query('CREATE TYPE "user_alertmode_enum" AS ENUM(\'note\', \'notification\', \'nothing\')');

View file

@ -1,7 +1,7 @@
import {MigrationInterface, QueryRunner} from 'typeorm'; import {MigrationInterface, QueryRunner} from 'typeorm';
export class visibility1609938844427 implements MigrationInterface { export class visibility1609938844427 implements MigrationInterface {
name = 'visibility1609938844427' name = 'visibility1609938844427';
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('CREATE TYPE "user_visibility_enum" AS ENUM(\'public\', \'home\', \'followers\', \'users\')'); await queryRunner.query('CREATE TYPE "user_visibility_enum" AS ENUM(\'public\', \'home\', \'followers\', \'users\')');

View file

@ -1,7 +1,7 @@
import {MigrationInterface, QueryRunner} from 'typeorm'; import {MigrationInterface, QueryRunner} from 'typeorm';
export class template1609941393782 implements MigrationInterface { export class template1609941393782 implements MigrationInterface {
name = 'template1609941393782' name = 'template1609941393782';
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('ALTER TABLE "user" ADD "template" character varying(280)'); await queryRunner.query('ALTER TABLE "user" ADD "template" character varying(280)');

View file

@ -1,7 +1,7 @@
import {MigrationInterface, QueryRunner} from 'typeorm'; import {MigrationInterface, QueryRunner} from 'typeorm';
export class rating1609948116186 implements MigrationInterface { export class rating1609948116186 implements MigrationInterface {
name = 'rating1609948116186' name = 'rating1609948116186';
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('ALTER TABLE "user" ADD "prevRating" real NOT NULL DEFAULT 0'); await queryRunner.query('ALTER TABLE "user" ADD "prevRating" real NOT NULL DEFAULT 0');

View file

@ -1,13 +1,13 @@
import {MigrationInterface, QueryRunner} from "typeorm"; import {MigrationInterface, QueryRunner} from 'typeorm';
export class useRanking1651804009671 implements MigrationInterface { export class useRanking1651804009671 implements MigrationInterface {
name = 'useRanking1651804009671' name = 'useRanking1651804009671';
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "user" ADD "useRanking" boolean NOT NULL DEFAULT false`); await queryRunner.query('ALTER TABLE "user" ADD "useRanking" boolean NOT NULL DEFAULT false');
} }
public async down(queryRunner: QueryRunner): Promise<void> { public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "useRanking"`); await queryRunner.query('ALTER TABLE "user" DROP COLUMN "useRanking"');
} }
} }

View file

@ -5,6 +5,7 @@
"main": "built/app.js", "main": "built/app.js",
"author": "Shrimpia Network", "author": "Shrimpia Network",
"private": true, "private": true,
"type": "module",
"scripts": { "scripts": {
"build": "run-s build:backend build:frontend", "build": "run-s build:backend build:frontend",
"build:frontend": "webpack", "build:frontend": "webpack",
@ -30,13 +31,11 @@
"@koa/multer": "^3.0.2", "@koa/multer": "^3.0.2",
"@reduxjs/toolkit": "^1.6.1", "@reduxjs/toolkit": "^1.6.1",
"axios": "^0.21.2", "axios": "^0.21.2",
"class-transformer": "^0.4.0", "class-transformer": "^0.5.1",
"class-validator": "^0.14.0", "class-validator": "^0.14.0",
"css-loader": "^6.2.0", "css-loader": "^6.2.0",
"dayjs": "^1.10.7", "dayjs": "^1.10.7",
"deepmerge": "^4.2.2", "deepmerge": "^4.2.2",
"delay": "^4.4.0",
"fibers": "^5.0.0",
"i18next": "^20.6.1", "i18next": "^20.6.1",
"i18next-browser-languagedetector": "^6.1.2", "i18next-browser-languagedetector": "^6.1.2",
"insert-text-at-cursor": "^0.3.0", "insert-text-at-cursor": "^0.3.0",
@ -65,7 +64,7 @@
"react-twemoji": "^0.5.0", "react-twemoji": "^0.5.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"rndstr": "^1.0.0", "rndstr": "^1.0.0",
"routing-controllers": "^0.9.0", "routing-controllers": "^0.10.1",
"sass": "^1.38.2", "sass": "^1.38.2",
"sass-loader": "^12.1.0", "sass-loader": "^12.1.0",
"striptags": "^3.2.0", "striptags": "^3.2.0",
@ -75,7 +74,7 @@
"tsc-alias": "^1.3.9", "tsc-alias": "^1.3.9",
"tsconfig-paths-webpack-plugin": "^3.5.1", "tsconfig-paths-webpack-plugin": "^3.5.1",
"typeorm": "0.2.25", "typeorm": "0.2.25",
"typescript": "^4.4.2", "typescript": "^4.9.5",
"uuid": "^8.3.0", "uuid": "^8.3.0",
"webpack": "^5.75.0", "webpack": "^5.75.0",
"webpack-cli": "^4.8.0", "webpack-cli": "^4.8.0",
@ -91,7 +90,7 @@
"@types/koa-views": "^2.0.4", "@types/koa-views": "^2.0.4",
"@types/markdown-it": "^12.2.3", "@types/markdown-it": "^12.2.3",
"@types/ms": "^0.7.31", "@types/ms": "^0.7.31",
"@types/node": "^8.0.29", "@types/node": "^18.14.1",
"@types/node-cron": "^2.0.3", "@types/node-cron": "^2.0.3",
"@types/object.pick": "^1.3.1", "@types/object.pick": "^1.3.1",
"@types/react": "^17.0.19", "@types/react": "^17.0.19",
@ -100,17 +99,14 @@
"@types/react-twemoji": "^0.4.0", "@types/react-twemoji": "^0.4.0",
"@types/styled-components": "^5.1.13", "@types/styled-components": "^5.1.13",
"@types/uuid": "^8.0.0", "@types/uuid": "^8.0.0",
"@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^4.30.0", "@typescript-eslint/parser": "^5.53.0",
"copyfiles": "^2.3.0", "copyfiles": "^2.3.0",
"eslint": "^7.32.0", "eslint": "^8.34.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.4",
"nodemon": "^2.0.4", "nodemon": "^2.0.4",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^2.0.5", "rimraf": "^4.1.2",
"rimraf": "^3.0.2", "ts-node": "10.9.1"
"ts-node": "3.3.0"
}, },
"packageManager": "yarn@1.22.19" "packageManager": "yarn@1.22.19"
} }

View file

@ -2,8 +2,8 @@ import 'reflect-metadata';
import axios from 'axios'; import axios from 'axios';
import { initDb } from './backend/services/db'; import { initDb } from './backend/services/db.js';
import { ua } from './backend/services/misskey'; import { ua } from './backend/services/misskey.js';
axios.defaults.headers['User-Agent'] = ua; axios.defaults.headers['User-Agent'] = ua;
axios.defaults.headers['Content-Type'] = 'application/json'; axios.defaults.headers['Content-Type'] = 'application/json';
@ -11,6 +11,6 @@ axios.defaults.validateStatus = (stat) => stat < 500;
(async () => { (async () => {
await initDb(); await initDb();
(await import('./backend/services/worker')).default(); (await import('./backend/services/worker.js')).default();
(await import('./backend/server')).default(); (await import('./backend/server.js')).default();
})(); })();

View file

@ -4,12 +4,12 @@
*/ */
import { BadRequestError, CurrentUser, Get, JsonController, OnUndefined, Post } from 'routing-controllers'; import { BadRequestError, CurrentUser, Get, JsonController, OnUndefined, Post } from 'routing-controllers';
import { IUser } from '../../common/types/user'; import { IUser } from '../../common/types/user.js';
import { config } from '../../config'; import { config } from '../../config.js';
import { work } from '../services/worker'; import { work } from '../services/worker.js';
import * as Store from '../store'; import * as Store from '../store.js';
@JsonController('/admin') @JsonController('/admin')
export class AdminController { export class AdminController {
@Get() getAdmin() { @Get() getAdmin() {
const { username, host } = config.admin; const { username, host } = config.admin;

View file

@ -4,14 +4,14 @@
*/ */
import { BadRequestError, Body, CurrentUser, Delete, Get, JsonController, NotFoundError, OnUndefined, Param, Post, Put } from 'routing-controllers'; import { BadRequestError, Body, CurrentUser, Delete, Get, JsonController, NotFoundError, OnUndefined, Param, Post, Put } from 'routing-controllers';
import { IUser } from '../../common/types/user'; import { IUser } from '../../common/types/user.js';
import { Announcements } from '../models'; import { Announcements } from '../models/index.js';
import { AnnounceCreate } from './body/announce-create'; import { AnnounceCreate } from './body/announce-create.js';
import { AnnounceUpdate } from './body/announce-update'; import { AnnounceUpdate } from './body/announce-update.js';
import { IdProp } from './body/id-prop'; import { IdProp } from './body/id-prop.js';
@JsonController('/announcements') @JsonController('/announcements')
export class AdminController { export class AnnouncementController {
@Get() get() { @Get() get() {
const query = Announcements.createQueryBuilder('announcement') const query = Announcements.createQueryBuilder('announcement')
.orderBy('"announcement"."createdAt"', 'DESC'); .orderBy('"announcement"."createdAt"', 'DESC');

View file

@ -1,6 +1,6 @@
import { IsIn, IsOptional } from 'class-validator'; import { IsIn, IsOptional } from 'class-validator';
import { AlertMode, alertModes } from '../../../common/types/alert-mode'; import { AlertMode, alertModes } from '../../../common/types/alert-mode.js';
import { visibilities, Visibility } from '../../../common/types/visibility'; import { visibilities, Visibility } from '../../../common/types/visibility.js';
export class UserSetting { export class UserSetting {
@IsIn(alertModes) @IsIn(alertModes)

View file

@ -0,0 +1,13 @@
import {MetaController} from './meta.js';
import {AdminController} from './admin.js';
import {AnnouncementController} from './announcement.js';
import {RankingController} from './ranking.js';
import {SessionController} from './session.js';
export default [
MetaController,
AdminController,
AnnouncementController,
RankingController,
SessionController,
];

View file

@ -3,18 +3,16 @@
* @author Xeltica * @author Xeltica
*/ */
import { readFile } from 'fs';
import { Get, JsonController } from 'routing-controllers'; import { Get, JsonController } from 'routing-controllers';
import { promisify } from 'util'; import { Meta } from '../../common/types/meta.js';
import { Meta } from '../../common/types/meta'; import { currentTokenVersion } from '../const.js';
import { currentTokenVersion } from '../const'; import { meta } from '../../config.js';
@JsonController('/meta') @JsonController('/meta')
export class MetaController { export class MetaController {
@Get() async get(): Promise<Meta> { @Get() async get(): Promise<Meta> {
const {version} = JSON.parse(await promisify(readFile)(__dirname + '/../../meta.json', { encoding: 'utf-8'}));
return { return {
version, version: meta.version,
currentTokenVersion, currentTokenVersion,
}; };
} }

View file

@ -4,9 +4,9 @@
*/ */
import { Get, JsonController, QueryParam } from 'routing-controllers'; import { Get, JsonController, QueryParam } from 'routing-controllers';
import { getRanking } from '../functions/ranking'; import { getRanking } from '../functions/ranking.js';
import { getUserCount } from '../functions/users'; import { getUserCount } from '../functions/users.js';
import { getState } from '../store'; import { getState } from '../store.js';
@JsonController('/ranking') @JsonController('/ranking')
export class RankingController { export class RankingController {

View file

@ -5,11 +5,11 @@
import { Body, CurrentUser, Delete, Get, JsonController, OnUndefined, Post, Put } from 'routing-controllers'; import { Body, CurrentUser, Delete, Get, JsonController, OnUndefined, Post, Put } from 'routing-controllers';
import { DeepPartial } from 'typeorm'; import { DeepPartial } from 'typeorm';
import { getScores } from '../functions/get-scores'; import { getScores } from '../functions/get-scores.js';
import { deleteUser, updateUser } from '../functions/users'; import { deleteUser, updateUser } from '../functions/users.js';
import { User } from '../models/entities/user'; import { User } from '../models/entities/user.js';
import { sendAlert } from '../services/send-alert'; import { sendAlert } from '../services/send-alert.js';
import { UserSetting } from './body/user-setting'; import { UserSetting } from './body/user-setting.js';
@JsonController('/session') @JsonController('/session')
export class SessionController { export class SessionController {

View file

@ -1,5 +1,5 @@
import { Context } from 'koa'; import { Context } from 'koa';
import { ErrorCode } from '../common/types/error-code'; import { ErrorCode } from '../common/types/error-code.js';
export const die = (ctx: Context, error: ErrorCode = 'other', status = 400): Promise<void> => { export const die = (ctx: Context, error: ErrorCode = 'other', status = 400): Promise<void> => {
ctx.status = status; ctx.status = status;

View file

@ -1,8 +1,8 @@
import {MisskeyError} from '../services/misskey'; import {MisskeyError} from '../services/misskey.js';
export const errorToString = (e: Error) => { export const errorToString = (e: Error) => {
if (e instanceof MisskeyError) { if (e instanceof MisskeyError) {
return JSON.stringify(e.error); return JSON.stringify(e.error, null, ' ');
} }
return `${e.name}: ${e.message}\n${e.stack}`; return `${e.name}: ${e.message}\n${e.stack}`;
}; };

View file

@ -1,6 +1,6 @@
import rndstr from 'rndstr'; import rndstr from 'rndstr';
import { UsedToken } from '../models/entities/used-token'; import { UsedToken } from '../models/entities/used-token.js';
import { UsedTokens } from '../models'; import { UsedTokens } from '../models/index.js';
/** /**
* *

View file

@ -1,9 +1,9 @@
import { User } from '../models/entities/user'; import { User } from '../models/entities/user.js';
import { toSignedString } from '../../common/functions/to-signed-string'; import { toSignedString } from '../../common/functions/to-signed-string.js';
import {Count} from '../models/count'; import {Count} from '../models/count.js';
import {api} from '../services/misskey'; import {api} from '../services/misskey.js';
import {Score} from '../../common/types/score'; import {Score} from '../../common/types/score.js';
import {MiUser} from './update-score'; import {MiUser} from './update-score.js';
/** /**
* *

View file

@ -1,5 +1,5 @@
import { Users } from '../models'; import { Users } from '../models/index.js';
import { User } from '../models/entities/user'; import { User } from '../models/entities/user.js';
/** /**
* *

View file

@ -1,8 +1,8 @@
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { User } from '../models/entities/user'; import { User } from '../models/entities/user.js';
import { updateUser } from './users'; import { updateUser } from './users.js';
import { MiUser } from './update-score'; import { MiUser } from './update-score.js';
/** /**
* *

View file

@ -1,6 +1,6 @@
import { User } from '../models/entities/user'; import { User } from '../models/entities/user.js';
import { updateUser } from './users'; import { updateUser } from './users.js';
import {Count} from '../models/count'; import {Count} from '../models/count.js';
/** /**
* Misskeyのユーザーモデル * Misskeyのユーザーモデル

View file

@ -1,10 +1,10 @@
import { User } from '../models/entities/user'; import { User } from '../models/entities/user.js';
import { Users } from '../models'; import { Users } from '../models/index.js';
import { DeepPartial } from 'typeorm'; import { DeepPartial } from 'typeorm';
import { genToken } from './gen-token'; import { genToken } from './gen-token.js';
import { IUser } from '../../common/types/user'; import { IUser } from '../../common/types/user.js';
import { config } from '../../config'; import { config } from '../../config.js';
import { currentTokenVersion } from '../const'; import { currentTokenVersion } from '../const.js';
/** /**
* IUser * IUser

View file

@ -1,5 +1,5 @@
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; import {Entity, PrimaryGeneratedColumn, Column} from 'typeorm';
import { IAnnouncement } from '../../../common/types/announcement'; import {IAnnouncement} from '../../../common/types/announcement.js';
@Entity() @Entity()
export class Announcement implements IAnnouncement { export class Announcement implements IAnnouncement {

View file

@ -1,7 +1,7 @@
import { Entity, Column, PrimaryGeneratedColumn, Index } from 'typeorm'; import { Entity, Column, PrimaryGeneratedColumn, Index } from 'typeorm';
import { AlertMode, alertModes } from '../../../common/types/alert-mode'; import { AlertMode, alertModes } from '../../../common/types/alert-mode.js';
import { visibilities, Visibility } from '../../../common/types/visibility'; import { visibilities, Visibility } from '../../../common/types/visibility.js';
import { IUser } from '../../../common/types/user'; import { IUser } from '../../../common/types/user.js';
@Entity() @Entity()
@Index(['username', 'host'], { unique: true }) @Index(['username', 'host'], { unique: true })

View file

@ -1,7 +1,7 @@
import { User } from './entities/user'; import { User } from './entities/user.js';
import { UsedToken } from './entities/used-token'; import { UsedToken } from './entities/used-token.js';
import { getRepository } from 'typeorm'; import { getRepository } from 'typeorm';
import { Announcement } from './entities/announcement'; import { Announcement } from './entities/announcement.js';
export const Users = getRepository(User); export const Users = getRepository(User);
export const UsedTokens = getRepository(UsedToken); export const UsedTokens = getRepository(UsedToken);

View file

@ -1,7 +1,12 @@
import views from 'koa-views'; import views from 'koa-views';
import { version } from '../meta.json'; import path from 'path';
import url from 'url';
import { meta } from '../config.js';
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
export const render = views(__dirname + '/views', { export const render = views(__dirname + '/views', {
extension: 'pug', extension: 'pug',
options: { version }, options: { version: meta.version },
}); });

View file

@ -8,12 +8,16 @@ import ms from 'ms';
import striptags from 'striptags'; import striptags from 'striptags';
import MarkdownIt from 'markdown-it'; import MarkdownIt from 'markdown-it';
import { config } from '../config'; import { config } from '../config.js';
import { upsertUser, getUser, updateUser } from './functions/users'; import { upsertUser, getUser, updateUser } from './functions/users.js';
import { api } from './services/misskey'; import { api } from './services/misskey.js';
import { die } from './die'; import { die } from './die.js';
import { misskeyAppInfo } from './const'; import { misskeyAppInfo } from './const.js';
import { Announcements } from './models'; import { Announcements } from './models/index.js';
import path from 'path';
import url from 'url';
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
export const router = new Router<DefaultState, Context>(); export const router = new Router<DefaultState, Context>();

View file

@ -1,19 +1,19 @@
import Koa from 'koa'; import Koa from 'koa';
import bodyParser from 'koa-bodyparser'; import bodyParser from 'koa-bodyparser';
import { Action, useKoaServer } from 'routing-controllers'; import {Action, useKoaServer} from 'routing-controllers';
import { config } from '../config'; import {config, meta} from '../config.js';
import { render } from './render'; import {render} from './render.js';
import { router } from './router'; import {router} from './router.js';
import { getUserByToolsToken } from './functions/users'; import {getUserByToolsToken} from './functions/users.js';
import { version } from '../meta.json'; import controllers from './controllers/index.js';
import 'reflect-metadata'; import 'reflect-metadata';
export default (): void => { export default (): void => {
const app = new Koa(); const app = new Koa();
console.log('Misskey Tools v' + version); console.log('Misskey Tools v' + meta.version);
console.log('Initializing DB connection...'); console.log('Initializing DB connection...');
@ -21,7 +21,7 @@ export default (): void => {
app.use(bodyParser()); app.use(bodyParser());
useKoaServer(app, { useKoaServer(app, {
controllers: [__dirname + '/controllers/**/*{.ts,.js}'], controllers,
routePrefix: '/api/v1', routePrefix: '/api/v1',
classTransformer: true, classTransformer: true,
validation: true, validation: true,
@ -30,8 +30,7 @@ export default (): void => {
if (!authorization || !authorization.startsWith('Bearer ')) return null; if (!authorization || !authorization.startsWith('Bearer ')) return null;
const token = authorization.split(' ')[1].trim(); const token = authorization.split(' ')[1].trim();
const user = await getUserByToolsToken(token); return await getUserByToolsToken(token);
return user;
}, },
}); });

View file

@ -1,8 +1,8 @@
import { getConnection, createConnection, Connection } from 'typeorm'; import { getConnection, createConnection, Connection } from 'typeorm';
import { config } from '../../config'; import { config } from '../../config.js';
import { User } from '../models/entities/user'; import { User } from '../models/entities/user.js';
import { UsedToken } from '../models/entities/used-token'; import { UsedToken } from '../models/entities/used-token.js';
import { Announcement } from '../models/entities/announcement'; import { Announcement } from '../models/entities/announcement.js';
export const entities = [ export const entities = [
User, User,

View file

@ -1,6 +1,6 @@
import axios from 'axios'; import axios from 'axios';
import {printLog} from '../store'; import {printLog} from '../store.js';
import {delay} from '../utils/delay'; import {delay} from '../utils/delay.js';
export const ua = `Mozilla/5.0 MisskeyTools +https://github.com/shrimpia/misskey-tools Node/${process.version}`; export const ua = `Mozilla/5.0 MisskeyTools +https://github.com/shrimpia/misskey-tools Node/${process.version}`;
@ -24,7 +24,7 @@ export const api = async <T extends Record<string, unknown> = Record<string, unk
await delay(3000); await delay(3000);
continue; continue;
} }
if (!('error' in data)) { if (!(typeof data === 'object' && 'error' in data)) {
return data; return data;
} }
throw new MisskeyError((data as any).error); throw new MisskeyError((data as any).error);

View file

@ -1,7 +1,7 @@
import { User } from '../models/entities/user'; import { User } from '../models/entities/user.js';
import { api } from './misskey'; import { api } from './misskey.js';
import {format} from '../../common/functions/format'; import {format} from '../../common/functions/format.js';
import {getScores} from '../functions/get-scores'; import {getScores} from '../functions/get-scores.js';
/** /**

View file

@ -1,18 +1,19 @@
import cron from 'node-cron'; import cron from 'node-cron';
import { deleteUser } from '../functions/users'; import { deleteUser } from '../functions/users.js';
import { MiUser, updateScore } from '../functions/update-score'; import { MiUser, updateScore } from '../functions/update-score.js';
import { updateRating } from '../functions/update-rating'; import { updateRating } from '../functions/update-rating.js';
import { Users } from '../models'; import { Users } from '../models/index.js';
import {sendNoteAlert, sendNotificationAlert} from './send-alert'; import {sendNoteAlert, sendNotificationAlert} from './send-alert.js';
import {api, MisskeyError, TimedOutError} from './misskey'; import {api, MisskeyError, TimedOutError} from './misskey.js';
import * as Store from '../store'; import * as Store from '../store.js';
import { User } from '../models/entities/user'; import { User } from '../models/entities/user.js';
import {groupBy} from '../utils/group-by'; import {groupBy} from '../utils/group-by.js';
import {clearLog, printLog} from '../store'; import {clearLog, printLog} from '../store.js';
import {errorToString} from '../functions/error-to-string'; import {errorToString} from '../functions/error-to-string.js';
import {Acct, toAcct} from '../models/acct'; import {Acct, toAcct} from '../models/acct.js';
import {Count} from '../models/count'; import {Count} from '../models/count.js';
import {format} from '../../common/functions/format'; import {format} from '../../common/functions/format.js';
import {delay} from '../utils/delay.js';
const ERROR_CODES_USER_REMOVED = ['NO_SUCH_USER', 'AUTHENTICATION_FAILED', 'YOUR_ACCOUNT_SUSPENDED']; const ERROR_CODES_USER_REMOVED = ['NO_SUCH_USER', 'AUTHENTICATION_FAILED', 'YOUR_ACCOUNT_SUSPENDED'];
@ -43,7 +44,7 @@ export const work = async () => {
printLog('ミス廃アラートワーカーは正常に完了しました。'); printLog('ミス廃アラートワーカーは正常に完了しました。');
} catch (e) { } catch (e) {
printLog('ミス廃アラートワーカーが異常終了しました。', 'error'); printLog('ミス廃アラートワーカーが異常終了しました。', 'error');
printLog(e instanceof Error ? errorToString(e) : e, 'error'); printLog(e instanceof Error ? errorToString(e) : JSON.stringify(e, null, ' '), 'error');
} finally { } finally {
Store.dispatch({ nowCalculating: false }); Store.dispatch({ nowCalculating: false });
} }
@ -115,10 +116,13 @@ const sendAlerts = async (host: string, users: User[]) => {
} }
} }
// 通知 // アラート
for (const {user, count, message} of models.filter(m => m.user.alertMode === 'note')) { for (const {user, count, message} of models.filter(m => m.user.alertMode === 'note' || m.user.alertMode === 'both')) {
await sendNoteAlert(message, user); await sendNoteAlert(message, user);
await updateScore(user, count); await Promise.all([
updateScore(user, count),
delay(1000),
]);
} }
printLog(`${host} ユーザー(${users.length}人) へのアラート送信が完了しました。`); printLog(`${host} ユーザー(${users.length}人) へのアラート送信が完了しました。`);

View file

@ -2,7 +2,7 @@
// getStateを介してステートを取得し、dispatchによって更新する // getStateを介してステートを取得し、dispatchによって更新する
// stateを直接編集できないようになっている // stateを直接編集できないようになっている
import {Log} from '../common/types/log'; import {Log} from '../common/types/log.js';
/** /**
* *
@ -48,4 +48,5 @@ export const printLog = (log: unknown, level: Log['level'] = 'info') => {
...getState().misshaiWorkerLog, ...getState().misshaiWorkerLog,
{ text: String(log), level, timestamp: new Date() }, { text: String(log), level, timestamp: new Date() },
] }); ] });
console[level](log);
}; };

View file

@ -1,10 +1,10 @@
import { config } from '../../config'; import { config } from '../../config.js';
import { Score } from '../types/score'; import { Score } from '../types/score.js';
import { defaultTemplate } from '../../backend/const'; import { defaultTemplate } from '../../backend/const.js';
import { IUser } from '../types/user'; import { IUser } from '../types/user.js';
import { createGacha } from './create-gacha'; import { createGacha } from './create-gacha.js';
import {Count} from '../../backend/models/count'; import {Count} from '../../backend/models/count.js';
import {getDelta} from '../../backend/functions/get-scores'; import {getDelta} from '../../backend/functions/get-scores.js';
/** /**
* *
@ -28,7 +28,7 @@ export const variables: Record<string, Variable> = {
gacha: () => createGacha(), gacha: () => createGacha(),
}; };
const variableRegex = /\{([a-zA-Z0-9_]+?)\}/g; const variableRegex = /\{([a-zA-Z0-9_]+?)}/g;
/** /**
* *

View file

@ -1,5 +1,5 @@
import { AlertMode } from './alert-mode'; import { AlertMode } from './alert-mode.js';
import { Visibility } from './visibility'; import { Visibility } from './visibility.js';
export interface IUser { export interface IUser {
id: number; id: number;

View file

@ -1,3 +1,13 @@
import path from 'path';
import url from 'url';
import fs from 'fs'; import fs from 'fs';
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
export const config = Object.freeze(JSON.parse(fs.readFileSync(__dirname + '/../config.json', 'utf-8'))); export const config = Object.freeze(JSON.parse(fs.readFileSync(__dirname + '/../config.json', 'utf-8')));
export const meta: MetaJson = Object.freeze(JSON.parse(fs.readFileSync(__dirname + '/meta.json', 'utf-8')));
export type MetaJson = {
version: string;
};

View file

@ -1,5 +1,5 @@
import React, {useMemo, useState} from 'react'; import React, {useMemo, useState} from 'react';
import {Log} from '../../common/types/log'; import {Log} from '../../common/types/log.js';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
const LogItem: React.FC<{log: Log}> = ({log}) => { const LogItem: React.FC<{log: Log}> = ({log}) => {
@ -43,7 +43,7 @@ export const LogView: React.FC<{log: Log[]}> = ({log}) => {
<span><i className="fas fa-circle-xmark fa-fw" /> ERROR</span> <span><i className="fas fa-circle-xmark fa-fw" /> ERROR</span>
</label> </label>
<div className="log-view vstack slim"> <div className="log-view vstack slim">
{filteredLog.map(l => <LogItem log={l} key={l.text} />)} {filteredLog.map(l => <LogItem log={l} key={`${l.level} ${l.timestamp.valueOf()} ${l.text}`} />)}
</div> </div>
</> </>
); );

View file

@ -45,7 +45,7 @@ export const NekomimiPage: React.VFC = () => {
await new Promise<void>((res, rej) => { await new Promise<void>((res, rej) => {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open('POST', `https://${data.host}/api/drive/files/create`, true); xhr.open('POST', `https://${data.host}/api/drive/files/create`, true);
xhr.onload = (e) => { xhr.onload = () => {
setPercentage(100); setPercentage(100);
const {id: avatarId} = JSON.parse(xhr.responseText); const {id: avatarId} = JSON.parse(xhr.responseText);
fetch(`https://${data.host}/api/i/update`, { fetch(`https://${data.host}/api/i/update`, {

View file

@ -74,7 +74,7 @@ export const MisshaiPage: React.VFC = () => {
const previousDraft = draft; const previousDraft = draft;
dispatchDraft(obj); dispatchDraft(obj);
return $put('session', obj) return $put('session', obj)
.catch(e => { .catch(() => {
dispatch(showModal({ dispatch(showModal({
type: 'dialog', type: 'dialog',
icon: 'error', icon: 'error',

View file

@ -1,4 +1,5 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { API_ENDPOINT, LOCALSTORAGE_KEY_TOKEN } from '../const'; import { API_ENDPOINT, LOCALSTORAGE_KEY_TOKEN } from '../const';
import { IUser } from '../../common/types/user'; import { IUser } from '../../common/types/user';
import { Score } from '../../common/types/score'; import { Score } from '../../common/types/score';

View file

@ -1,4 +1,4 @@
import { initDb } from '../backend/services/db'; import { initDb } from '../backend/services/db.js';
import 'reflect-metadata'; import 'reflect-metadata';
(async () => { (async () => {

View file

@ -1,7 +1,7 @@
import { Users } from '../backend/models'; import { Users } from '../backend/models/index.js';
import { updateRating } from '../backend/functions/update-rating'; import { updateRating } from '../backend/functions/update-rating.js';
import { api } from '../backend/services/misskey'; import { api } from '../backend/services/misskey.js';
import { MiUser } from '../backend/functions/update-score'; import { MiUser } from '../backend/functions/update-score.js';
export default async () => { export default async () => {
const users = await Users.find(); const users = await Users.find();

View file

@ -1,7 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es5", "target": "es2021",
"module": "commonjs", "module": "esnext",
"moduleResolution": "node",
"outDir": "./built/", "outDir": "./built/",
"rootDir": "./src/", "rootDir": "./src/",
"strict": true, "strict": true,

View file

@ -2,18 +2,7 @@
* webpack configuration * webpack configuration
*/ */
const fs = require('fs');
const webpack = require('webpack'); const webpack = require('webpack');
// class WebpackOnBuildPlugin {
// constructor(readonly callback: (stats: any) => void) {
// }
// public apply(compiler: any) {
// compiler.hooks.done.tap('WebpackOnBuildPlugin', this.callback);
// }
// }
const isProduction = process.env.NODE_ENV === 'production'; const isProduction = process.env.NODE_ENV === 'production';
const meta = require('./package.json'); const meta = require('./package.json');

1026
yarn.lock

File diff suppressed because it is too large Load diff