Compare commits

..

103 Commits

Author SHA1 Message Date
d4e9082941 Merge branch 'develop' 2022-04-02 17:05:00 +09:00
a2242261db Merge remote-tracking branch 'misskey-dev/master' into develop 2022-04-02 17:04:46 +09:00
9cf6561a95 Merge branch 'develop' 2022-04-02 16:07:03 +09:00
a989e904cc Merge branch '2022-wtf' into develop 2022-04-02 16:06:26 +09:00
7774465274 Merge branch 'develop' 2022-04-02 15:58:45 +09:00
b2299e1344 Merge remote-tracking branch 'misskey-dev/master' into develop 2022-04-02 15:57:56 +09:00
af0dfb2362 wtf??? 2022-04-01 03:39:17 +09:00
ad74fbc48f wtf????aaaa 2022-04-01 03:29:45 +09:00
d0775da7d2 wtf????aaa 2022-04-01 03:23:01 +09:00
633994ecb6 wtf????aa 2022-04-01 02:46:07 +09:00
54923b7ac9 wtf????aa 2022-04-01 02:21:30 +09:00
48e132a2c7 wtf????a 2022-04-01 02:03:24 +09:00
7663170fae wtf????a 2022-04-01 01:59:08 +09:00
cebb66cc36 wtf???? 2022-04-01 00:47:56 +09:00
f6dda604dc fix: update package.json select-file-enc.ts 2022-03-30 16:05:35 +09:00
d10143544d fix: update package.json 2022-03-30 16:04:20 +09:00
40e3c75c13 fix: update select-file-enc.ts 2022-03-30 15:59:08 +09:00
a2150b1269 fix: update l-simkey.json5 2022-03-29 03:08:09 +09:00
19579ed0f1 fix: add l-simkey.json5 2022-03-29 02:54:17 +09:00
78396baf82 fix: update package.json 2022-03-29 02:34:31 +09:00
982896f7be fix: update default store.ts 2022-03-29 02:31:29 +09:00
1c9b842983 fix: max note text length to 8192 2022-03-23 11:36:10 +09:00
0cf950bb35 Update test.yml 2022-03-21 19:38:59 +09:00
ef4f49778e Merge branch 'develop' 2022-03-21 19:29:41 +09:00
721c47a74b fix: reject mp4 2022-03-21 19:28:22 +09:00
11cbbeb795 Merge branch 'develop' 2022-03-13 16:22:27 +09:00
6bc893ca44 Merge pull request #27 from sim1222/sim-dev-comv-mov-1
feat: Add convert video container button
2022-03-13 16:15:56 +09:00
9c34f96cdd feat: Add convert video container button lang 2022-03-13 16:14:57 +09:00
74a80b3405 feat: Add convert video container button 2022-03-13 16:11:08 +09:00
84da9d4cd4 fix: wip 2022-03-13 14:37:55 +09:00
b48f76aad1 fix: update package.json 2022-03-13 14:14:44 +09:00
78b9550eca fix: debug 2022-03-13 14:09:44 +09:00
8fc770d371 Merge branch 'develop' 2022-03-12 19:38:26 +09:00
4aed68ec96 Merge tag '12.108.1-simkey' into develop 2022-03-12 19:38:14 +09:00
90c89c3083 fix: debug 2022-03-12 02:24:23 +09:00
c63d7dc898 fix: wippppppppppppppppppppppaaafaafawfwafwaafw 2022-03-12 02:19:56 +09:00
74e695a320 fix: wipppppppppppppppppppppp 2022-03-12 02:11:15 +09:00
f269ceaee9 fix: wip 2022-03-12 01:30:08 +09:00
57a106a192 fix: wip 2022-03-12 01:23:49 +09:00
5563d6bdeb fix: wip 2022-03-11 22:48:50 +09:00
ab59a5b659 fix: dont export select-file-enc.ts 2022-03-11 22:45:03 +09:00
a81f8b8275 feat: Add video convert button 2022-03-11 22:34:38 +09:00
c99c4b73f4 Create select-file-enc.ts 2022-03-11 22:05:08 +09:00
995d8f2f5d Update post-form.vue 2022-03-11 22:03:36 +09:00
6bb22007d8 Merge branch 'develop' 2022-03-09 23:09:49 +09:00
a4a0d33348 Merge tag '12.108.0-simkey' into develop 2022-03-09 23:09:14 +09:00
7d1f3cd1e8 Merge branch 'develop' of github.com:sim1222/misskey into develop 2022-02-21 19:08:08 +09:00
dc13627a68 add gitignore 2022-02-21 19:08:04 +09:00
b96e886a61 Merge branch 'develop' 2022-02-17 01:19:43 +09:00
7024f6651f Merge remote-tracking branch 'origin/sim-dev-reload-button-2' into develop 2022-02-17 01:19:30 +09:00
4f9aca0aa3 add reload button 2022-02-17 01:18:37 +09:00
88a2606884 Merge branch 'develop' 2022-02-12 17:39:33 +09:00
d6b15add1b Merge remote-tracking branch 'misskey-dev/master' into develop 2022-02-12 17:39:23 +09:00
39307694b5 Merge branch 'develop' 2022-02-11 22:20:20 +09:00
9b7be06eef Merge remote-tracking branch 'misskey-dev/develop' into develop 2022-02-11 22:20:04 +09:00
5afb3a59cd Merge branch 'develop' 2022-02-11 19:25:04 +09:00
73d66fc439 Merge tag '12.106.0-simkey' into develop 2022-02-11 19:24:42 +09:00
12214c473a Merge branch 'develop' 2022-02-09 22:01:03 +09:00
8e173a6d8e Merge tag '12.105.0' into develop 2022-02-09 22:00:47 +09:00
9d0c1a8fea Merge branch 'develop' 2022-02-09 17:17:20 +09:00
aee5193ef6 Merge branch 'master' into develop 2022-02-09 17:16:54 +09:00
2892a31142 Merge remote-tracking branch 'origin/develop' into develop 2022-02-09 17:14:50 +09:00
90bb0cec37 fix: Nya Translation from ja-JP 2022-02-09 17:14:30 +09:00
19775507fc Merge pull request #26 from sim1222/develop
Merge Develop 12.104.0
2022-02-09 16:40:32 +09:00
9d4f621833 fix conflct 2022-02-09 16:39:15 +09:00
2e095b4863 Merge pull request #24 from sim1222/develop
Merge Develop 12.103.1
2022-02-03 10:48:14 +09:00
5d9b9eeaad Merge branch 'master' into develop 2022-02-03 10:48:04 +09:00
98f5cb6cd2 git push origin developMerge branch 'misskey-dev-develop' into develop 2022-02-03 01:43:09 +00:00
b88c4d6d34 fix comf 2022-02-03 01:42:58 +00:00
6238ba965b wip add button 2022-01-30 19:42:54 +09:00
8489c3ca7b Merge pull request #22 from sim1222/v12.102.1
Merge develop V12.102.1
2022-01-29 05:34:12 +09:00
33871f3cb8 Merge branch 'master' into v12.102.1 2022-01-29 05:34:03 +09:00
5eb758fa28 update package.json 2022-01-29 04:17:15 +09:00
56d8f7f257 Merge pull request #19 from sim1222/develop
Merge Develop v12.102.0
2022-01-27 00:53:29 +09:00
74c3e6d483 Merge branch 'misskey-dev-develop' into develop 2022-01-27 00:52:19 +09:00
ead62a538f fix confrict 2022-01-27 00:52:09 +09:00
72058b30c2 Merge branch 'misskey-dev:develop' into develop 2022-01-26 20:09:42 +09:00
22102639a8 Merge pull request #16 from sim1222/develop
Change Color
2022-01-13 03:11:14 +09:00
ee4289076f Change Color 2022-01-13 03:10:42 +09:00
be011d3985 Merge pull request #15 from sim1222/develop
change color
2022-01-09 21:43:44 +09:00
6ef86df368 change color 2022-01-09 21:43:12 +09:00
34e099984f Merge pull request #14 from sim1222/develop
Fix ja-NY Language
2022-01-04 19:50:23 +09:00
5a1c6be944 Fix ja-NY Language 2022-01-04 19:33:41 +09:00
25991cfdc1 Merge pull request #11 from sim1222/develop
Merge Develop 12.101.1
2021-12-29 18:15:50 +09:00
b1a526aeea fix conflict 2021-12-29 18:15:03 +09:00
f31ef70ce7 Merge pull request #9 from sim1222/develop
Merge develop 12.101.0
2021-12-29 15:12:02 +09:00
09a751b992 git push origin developMerge branch 'misskey-dev-develop' into develop 2021-12-29 15:08:42 +09:00
a41e4ed4fd fix conflict 2021-12-29 15:08:31 +09:00
b77f7f5041 Merge pull request #7 from sim1222/develop
change repo url
2021-12-28 16:16:19 +09:00
7adcf99865 change repo url 2021-12-28 16:15:51 +09:00
cc2d5480f3 Merge pull request #6 from sim1222/develop
wip
2021-12-28 03:16:18 +09:00
fdd129fb83 wip 2021-12-28 03:15:56 +09:00
8dd3fef0e2 Merge pull request #5 from sim1222/develop
fix wip
2021-12-28 03:04:25 +09:00
f1c66f09e1 fix wip 2021-12-28 03:03:58 +09:00
6f328f2ccf Merge pull request #4 from sim1222/develop
fix typo
2021-12-28 02:55:19 +09:00
70b3d598c6 fix typo 2021-12-28 02:54:53 +09:00
668c403ece Merge pull request #3 from sim1222/develop
fix NYA JP
2021-12-28 02:49:24 +09:00
c873f17080 fix NYA JP 2021-12-28 02:48:55 +09:00
3f6691bd5e Merge pull request #2 from sim1222/develop
vsddgvsgdsgsdsg
2021-12-28 02:27:13 +09:00
260ece9881 Update package.json 2021-12-28 02:26:10 +09:00
9a4c04fe79 Merge pull request #1 from sim1222/sim-dev-ja-nya
Sim dev ja nya
2021-12-28 02:25:13 +09:00
24896d4a36 Merge branch 'misskey-dev:develop' into sim-dev-ja-nya 2021-12-28 02:17:22 +09:00
8aea52e9b4 てぬきにゃ翻訳 2021-12-28 02:05:40 +09:00
183 changed files with 9322 additions and 2130 deletions

View File

@ -1,18 +0,0 @@
name: Docker Image CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build the Docker image
run: docker build . --file Dockerfile --tag my-image-name:$(date +%s)

View File

@ -14,12 +14,12 @@ jobs:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-node@v3
- uses: actions/setup-node@v1
with:
node-version: 16.x
cache: 'yarn'
cache-dependency-path: |
packages/backend/yarn.lock
packages/client/yarn.lock
node-version: 12.x
- uses: actions/cache@v2
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
- run: yarn install
- run: yarn lint

View File

@ -8,48 +8,44 @@ on:
pull_request:
jobs:
mocha:
runs-on: ubuntu-latest
#mocha:
# runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
# strategy:
# matrix:
# node-version: [16.x]
services:
postgres:
image: postgres:13
ports:
- 54312:5432
env:
POSTGRES_DB: test-misskey
POSTGRES_HOST_AUTH_METHOD: trust
redis:
image: redis:6
ports:
- 56312:6379
# services:
# postgres:
# image: postgres:13
# ports:
# - 54312:5432
# env:
# POSTGRES_DB: test-misskey
# POSTGRES_HOST_AUTH_METHOD: trust
# redis:
# image: redis:6
# ports:
# - 56312:6379
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
cache-dependency-path: |
packages/backend/yarn.lock
packages/client/yarn.lock
- name: Install dependencies
run: yarn install
- name: Check yarn.lock
run: git diff --exit-code yarn.lock
- name: Copy Configure
run: cp .github/misskey/test.yml .config
- name: Build
run: yarn build
- name: Test
run: yarn mocha
# steps:
# - uses: actions/checkout@v2
# with:
# submodules: true
# - name: Use Node.js ${{ matrix.node-version }}
# uses: actions/setup-node@v1
# with:
# node-version: ${{ matrix.node-version }}
# - name: Install dependencies
# run: yarn install
# - name: Check yarn.lock
# run: git diff --exit-code yarn.lock
# - name: Copy Configure
# run: cp .github/misskey/test.yml .config
# - name: Build
# run: yarn build
# - name: Test
# run: yarn mocha
e2e:
runs-on: ubuntu-latest
@ -84,13 +80,13 @@ jobs:
#- uses: browser-actions/setup-firefox@latest
# if: ${{ matrix.browser == 'firefox' }}
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
cache-dependency-path: |
packages/backend/yarn.lock
packages/client/yarn.lock
- uses: actions/cache@v2
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
- name: Install dependencies
run: yarn install
- name: Check yarn.lock

2
.gitignore vendored
View File

@ -42,3 +42,5 @@ ormconfig.json
*.blend3
*.blend4
*.blend5
start.sh

View File

@ -10,28 +10,6 @@
You should also include the user name that made the change.
-->
## 12.110.1 (2022/04/23)
### Bugfixes
- Fix GOP rendering @syuilo
- Improve performance of antenna, clip, and list @xianon
## 12.110.0 (2022/04/11)
### Improvements
- Improve webhook @syuilo
- Client: Show loading icon on splash screen @syuilo
### Bugfixes
- API: parameter validation of users/show was wrong
- Federation: リモートインスタンスへのダイレクト投稿が届かない問題を修正 @syuilo
## 12.109.2 (2022/04/03)
### Bugfixes
- API: admin/update-meta was not working @syuilo
- Client: テーマを切り替えたり読み込んだりするとmeta[name="theme-color"]のcontentがundefinedになる問題を修正 @tamaina
## 12.109.1 (2022/04/02)
### Bugfixes

View File

@ -32,3 +32,4 @@ COPY --from=builder /misskey/packages/client/node_modules ./packages/client/node
COPY . ./
CMD ["npm", "run", "migrateandstart"]

173
README.md
View File

@ -1,7 +1,168 @@
## これってなに?
[Misskey](https://github.com/misskey-dev/misskey)ベースのSNS
[![Misskey](https://github.com/misskey-dev/assets/blob/main/banner.png?raw=true)](https://join.misskey.page/)
## 本家との違い
[ここ](https://nullc.at/nca10.net/)にかいてあるよ
## 導入方法
[MisskeyHub](https://misskey-hub.net/docs/install.html)をみてね
<div align="center">
**🌎 A forever evolving, interplanetary microblogging platform. 🚀**
**Misskey** is a distributed microblogging platform with advanced features such as Reactions and a highly customizable UI.
[Learn more](https://misskey-hub.net/)
---
[✨ Find an instance](https://misskey-hub.net/instances.html)
[📦 Create your own instance](https://misskey-hub.net/docs/install.html)
[🛠️ Contribute](./CONTRIBUTING.md)
[🚀 Join the community](https://discord.gg/Wp8gVStHW3)
---
<a href="https://www.patreon.com/syuilo"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="Become a Patron!" width="160" /></a>
</div>
<div>
<a href="https://xn--931a.moe/"><img src="https://github.com/misskey-dev/misskey/blob/develop/assets/ai.png?raw=true" align="right" height="320px"/></a>
## ✨ Features
- **ActivityPub support**\
It is possible to interact with other software.
- **Reactions**\
You can add "reactions" to each post, making it easy for you to express your feelings.
- **Drive**\
An interface to manage uploaded files such as images, videos, sounds, etc.
You can also organize your favorite content into folders, making it easy to share again.
- **Rich Web UI**\
Misskey has a rich WebUI by default.
It is highly customizable by flexibly changing the layout and installing various widgets and themes.
Furthermore, plug-ins can be created using AiScript, a original programming language.
- and more...
</div>
<div style="clear: both;"></div>
## Sponsors
<div align="center">
<a class="rss3" title="RSS3" href="https://rss3.io/" target="_blank"><img src="https://rss3.mypinata.cloud/ipfs/QmUG6H3Z7D5P511shn7sB4CPmpjH5uZWu4m5mWX7U3Gqbu" alt="RSS3" height="60"></a>
</div>
## Backers
<!-- PATREON_START -->
<table><tr>
<td><img src="https://c8.patreon.com/2/200/20832595" alt="Roujo " width="100"></td>
<td><img src="https://c8.patreon.com/2/200/27956229" alt="Oliver Maximilian Seidel" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12190916/fb7fa7983c14425f890369535b1506a4/3.png?token-time=2145916800&token-hash=oH_i7gJjNT7Ot6j9JiVwy7ZJIBqACVnzLqlz4YrDAZA%3D" alt="weepjp " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/19045173/cb91c0f345c24d4ebfd05f19906d5e26/1.png?token-time=2145916800&token-hash=o_zKBytJs_AxHwSYw_5R8eD0eSJe3RoTR3kR3Q0syN0%3D" alt="kiritan " width="100"></td>
<td><img src="https://c8.patreon.com/2/200/27648259" alt="みなしま " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/24430516/b1964ac5b9f746d2a12ff53dbc9aa40a/1.jpg?token-time=2145916800&token-hash=bmEiMGYpp3bS7hCCbymjGGsHBZM3AXuBOFO3Kro37PU%3D" alt="Eduardo Quiros" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/user?u=20832595">Roujo </a></td>
<td><a href="https://www.patreon.com/user?u=27956229">Oliver Maximilian Seidel</a></td>
<td><a href="https://www.patreon.com/weepjp">weepjp </a></td>
<td><a href="https://www.patreon.com/user?u=19045173">kiritan </a></td>
<td><a href="https://www.patreon.com/user?u=27648259">みなしま </a></td>
<td><a href="https://www.patreon.com/user?u=24430516">Eduardo Quiros</a></td>
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/14215107/1cbe1912c26143919fa0faca16f12ce1/4.jpg?token-time=2145916800&token-hash=BslMqDjTjz8KYANLvxL87agHTugHa0dMPUzT-hwR6Vk%3D" alt="Nesakko" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/776209" alt="Demogrognard" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/3075183/c2ae575c604e420297f000ccc396e395/1.jpeg?token-time=2145916800&token-hash=O9qmPtpo6wWb0OuvnkEekhk_1WO2MTdytLr7ZgsAr80%3D" alt="Liaizon Wakest" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/557245" alt="mkatze " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/23915207/25428766ecd745478e600b3d7f871eb2/1.png?token-time=2145916800&token-hash=urCLLA4KjJZX92Y1CxcBP4d8bVTHGkiaPnQZp-Tqz68%3D" alt="kabo2468y " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/8249688/4aacf36b6b244ab1bc6653591b6640df/2.png?token-time=2145916800&token-hash=1ZEf2w6L34253cZXS_HlVevLEENWS9QqrnxGUAYblPo%3D" alt="AureoleArk " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5670915/ee175f0bfb6347ffa4ea101a8c097bff/1.jpg?token-time=2145916800&token-hash=mPLM9CA-riFHx-myr3bLZJuH2xBRHA9se5VbHhLIOuA%3D" alt="osapon " width="100"></td>
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/36813045/29876ea679d443bcbba3c3f16edab8c2/2.jpeg?token-time=2145916800&token-hash=YCKWnIhrV9rjUCV9KqtJnEqjy_uGYF3WMXftjUdpi7o%3D" alt="Wataru Manji (manji0)" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/Nesakko">Nesakko</a></td>
<td><a href="https://www.patreon.com/user?u=776209">Demogrognard</a></td>
<td><a href="https://www.patreon.com/wakest">Liaizon Wakest</a></td>
<td><a href="https://www.patreon.com/user?u=557245">mkatze </a></td>
<td><a href="https://www.patreon.com/user?u=23915207">kabo2468y </a></td>
<td><a href="https://www.patreon.com/AureoleArk">AureoleArk </a></td>
<td><a href="https://www.patreon.com/osapon">osapon </a></td>
<td><a href="https://www.patreon.com/user?u=16869916">見当かなみ </a></td>
<td><a href="https://www.patreon.com/user?u=36813045">Wataru Manji (manji0)</a></td>
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18899730/6a22797f68254034a854d69ea2445fc8/1.png?token-time=2145916800&token-hash=b_uj57yxo5VzkSOUS7oXE_762dyOTB_oxzbO6lFNG3k%3D" alt="YuzuRyo61 " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5788159/af42076ab3354bb49803cfba65f94bee/1.jpg?token-time=2145916800&token-hash=iSaxp_Yr2-ZiU2YVi9rcpZZj9mj3UvNSMrZr4CU4qtA%3D" alt="mewl hayabusa" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/28779508/3cd4cb7f017f4ee0864341e3464d42f9/1.png?token-time=2145916800&token-hash=eGQtR15be44kgvh8fw2Jx8Db4Bv15YBp2ldxh0EKRxA%3D" alt="S Y" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/16542964" alt="Takumi Sugita" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/17866454" alt="sikyosyounin " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/3.png?token-time=2145916800&token-hash=KjfQL8nf3AIf6WqzLshBYAyX44piAqOAZiYXgZS_H6A%3D" alt="YUKIMOCHI" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/38837364/9421361c54c645ac8f5fc442a40c32e9/1.png?token-time=2145916800&token-hash=TUZB48Nem3BeUPLBH6s3P6WyKBnQOy0xKaDSTBBUNzA%3D" alt="xianon" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/26340354/08834cf767b3449e93098ef73a434e2f/2.png?token-time=2145916800&token-hash=nyM8DnKRL8hR47HQ619mUzsqVRpkWZjgtgBU9RY15Uc%3D" alt="totokoro " width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/Yuzulia">YuzuRyo61 </a></td>
<td><a href="https://www.patreon.com/hs_sh_net">mewl hayabusa</a></td>
<td><a href="https://www.patreon.com/user?u=28779508">S Y</a></td>
<td><a href="https://www.patreon.com/user?u=16542964">Takumi Sugita</a></td>
<td><a href="https://www.patreon.com/user?u=17866454">sikyosyounin </a></td>
<td><a href="https://www.patreon.com/yukimochi">YUKIMOCHI</a></td>
<td><a href="https://www.patreon.com/user?u=38837364">xianon</a></td>
<td><a href="https://www.patreon.com/user?u=26340354">totokoro </a></td>
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/19356899/496b4681d33b4520bd7688e0fd19c04d/2.jpeg?token-time=2145916800&token-hash=_sTj3dUBOhn9qwiJ7F19Qd-yWWfUqJC_0jG1h0agEqQ%3D" alt="sheeta.s " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5827393/59893c191dda408f9cabd0f20a3a5627/1.jpeg?token-time=2145916800&token-hash=i9N05vOph-eP1LTLb9_npATjYOpntL0ZsHNaZFSsPmE%3D" alt="motcha " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/20494440/540beaf2445f408ea6597bc61e077bb3/1.png?token-time=2145916800&token-hash=UJ0JQge64Bx9XmN_qYA1inMQhrWf4U91fqz7VAKJeSg%3D" alt="axtuki1 " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13737140/1adf7835017d479280d90fe8d30aade2/1.png?token-time=2145916800&token-hash=0pdle8h5pDZrww0BDOjdz6zO-HudeGTh36a3qi1biVU%3D" alt="Satsuki Yanagi" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17880724/311738c8a48f4a6b9443c2445a75adde/1.jpg?token-time=2145916800&token-hash=nVAntpybQrznE0rg05keLrSE6ogPKJXB13rmrJng42c%3D" alt="takimura " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13100201/fc5be4fa90444f09a9c8a06f72385272/1.png?token-time=2145916800&token-hash=i8PjlgfOB2LPEdbtWyx8ZPsBKhGcNZqcw_FQmH71UGU%3D" alt="aqz tamaina" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/9109588/e3cffc48d20a4e43afe04123e696781d/3.png?token-time=2145916800&token-hash=T_VIUA0IFIbleZv4pIjiszZGnQonwn34sLCYFIhakBo%3D" alt="nafuchoco " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/16900731/619ab87cc08448439222631ebb26802f/1.gif?token-time=2145916800&token-hash=o27K7M02s1z-LkDUEO5Oa7cu-GviRXeOXxryi4o_6VU%3D" alt="Atsuko Tominaga" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4389829/9f709180ac714651a70f74a82f3ffdb9/3.png?token-time=2145916800&token-hash=FTm3WVom4dJ9NwWMU4OpCL_8Yc13WiwEbKrDPyTZTPs%3D" alt="natalie" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/26144593/9514b10a5c1b42a3af58621aee213d1d/1.png?token-time=2145916800&token-hash=v1PYRsjzu4c_mndN4Hvi_dlispZJsuGRCQeNS82pUSM%3D" alt="EBISUME" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5923936/2a743cbfbff946c2af3f09026047c0da/2.png?token-time=2145916800&token-hash=h6yphW1qnM0n_NOWaf8qtszMRLXEwIxfk5beu4RxdT0%3D" alt="noellabo " width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/user?u=19356899">sheeta.s </a></td>
<td><a href="https://www.patreon.com/user?u=5827393">motcha </a></td>
<td><a href="https://www.patreon.com/user?u=20494440">axtuki1 </a></td>
<td><a href="https://www.patreon.com/user?u=13737140">Satsuki Yanagi</a></td>
<td><a href="https://www.patreon.com/takimura">takimura </a></td>
<td><a href="https://www.patreon.com/aqz">aqz tamaina</a></td>
<td><a href="https://www.patreon.com/user?u=9109588">nafuchoco </a></td>
<td><a href="https://www.patreon.com/user?u=16900731">Atsuko Tominaga</a></td>
<td><a href="https://www.patreon.com/user?u=4389829">natalie</a></td>
<td><a href="https://www.patreon.com/user?u=26144593">EBISUME</a></td>
<td><a href="https://www.patreon.com/noellabo">noellabo </a></td>
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/2384390/5681180e1efb46a8b28e0e8d4c8b9037/1.jpg?token-time=2145916800&token-hash=SJcMy-Q1BcS940-LFUVOMfR7-5SgrzsEQGhYb3yowFk%3D" alt="CG " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18072312/98e894d960314fa7bc236a72a39488fe/1.jpg?token-time=2145916800&token-hash=7bkMqTwHPRsJPGAq42PYdDXDZBVGLqdgr1ZmBxX8GFQ%3D" alt="Hekovic " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/24641572/b4fd175424814f15b0ca9178d2d2d2e4/1.png?token-time=2145916800&token-hash=e2fyqdbuJbpCckHcwux7rbuW6OPkKdERcus0u2wIEWU%3D" alt="uroco @99" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/14661394" alt="Chandler " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1.png?token-time=2145916800&token-hash=hBayGfOmQH3kRMdNnDe4oCZD_9fsJWSt29xXR3KRMVk%3D" alt="Nokotaro Takeda" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/23932002" alt="nenohi " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/9481273/7fa89168e72943859c3d3c96e424ed31/4.jpeg?token-time=2145916800&token-hash=5w1QV1qXe-NdWbdFmp1H7O_-QBsSiV0haumk3XTHIEg%3D" alt="Efertone " width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12531784/93a45137841849329ba692da92ac7c60/1.jpeg?token-time=2145916800&token-hash=vGe7wXGqmA8Q7m-kDNb6fyGdwk-Dxk4F-ut8ZZu51RM%3D" alt="Takashi Shibuya" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/Corset">CG </a></td>
<td><a href="https://www.patreon.com/hekovic">Hekovic </a></td>
<td><a href="https://www.patreon.com/user?u=24641572">uroco @99</a></td>
<td><a href="https://www.patreon.com/user?u=14661394">Chandler </a></td>
<td><a href="https://www.patreon.com/takenoko">Nokotaro Takeda</a></td>
<td><a href="https://www.patreon.com/user?u=23932002">nenohi </a></td>
<td><a href="https://www.patreon.com/efertone">Efertone </a></td>
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
</tr></table>
**Last updated:** Sun, 26 Jul 2020 07:00:10 UTC
<!-- PATREON_END -->
[backer-url]: #backers
[backer-badge]: https://opencollective.com/misskey/backers/badge.svg
[backers-image]: https://opencollective.com/misskey/backers.svg
[sponsor-url]: #sponsors
[sponsor-badge]: https://opencollective.com/misskey/sponsors/badge.svg
[sponsors-image]: https://opencollective.com/misskey/sponsors.svg
[support-url]: https://opencollective.com/misskey#support
[syuilo-link]: https://syuilo.com
[syuilo-icon]: https://avatars2.githubusercontent.com/u/4439005?v=3&s=70

BIN
assets/about/drive.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
assets/about/post.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 KiB

BIN
assets/about/reaction.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
assets/about/ui.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

BIN
assets/ai-orig.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

BIN
assets/ai.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

BIN
assets/banner.afdesign Normal file

Binary file not shown.

BIN
assets/mi-white.afdesign Normal file

Binary file not shown.

BIN
assets/mi.afdesign Normal file

Binary file not shown.

BIN
assets/ss/explore.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

BIN
assets/ss/user.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
assets/title.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -1,31 +1,52 @@
version: "3"
services:
db:
restart: always
image: postgres:12.2-alpine
ports:
- "5432:5432"
networks:
- internal_network
- external_network
env_file:
- .config/docker.env
volumes:
- ./db:/var/lib/postgresql/data
redis:
restart: always
image: redis:4.0-alpine
ports:
- "6379:6379"
networks:
- internal_network
- external_network
volumes:
- ./redis:/data
networks:
internal_network:
internal: true
external_network:
version: "3"
services:
web:
build: .
restart: always
links:
- db
- redis
# - es
ports:
- "127.0.0.1:3000:3000"
networks:
- internal_network
- external_network
volumes:
- ./files:/misskey/files
- ./.config:/misskey/.config:ro
redis:
restart: always
image: redis:4.0-alpine
networks:
- internal_network
volumes:
- ./redis:/data
db:
restart: always
image: postgres:12.2-alpine
networks:
- internal_network
env_file:
- .config/docker.env
volumes:
- ./db:/var/lib/postgresql/data
# es:
# restart: always
# image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.2
# environment:
# - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
# - "TAKE_FILE_OWNERSHIP=111"
# networks:
# - internal_network
# volumes:
# - ./elasticsearch:/usr/share/elasticsearch/data
networks:
internal_network:
internal: true
external_network:

View File

@ -1,6 +0,0 @@
`packages/backend/src/server/web/views/base.pug` の中の
```
meta(name='theme-color' content='#好きな色')
meta(name='theme-color-orig' content='#好きな色')
```
の好きな色の部分を変更する(Hex値)

View File

@ -1,15 +0,0 @@
## 主な変更点
- なとナがにゃ
- コピーがコビー
- あなたが僕
- パスワードが鍵
- doneがドネ
- ユーザー名が名前
- バナーがバニャーニャ
- ユーザーネームがid
- コントロールパネルがコンソトールパネル
## ぬるきゃごの導入方法
1. `./locales/ja-JP.yml``ja-NCAT.yml` に変更
2. `ja-NCAT.yml``./locales` のなかに入れる
3. `./locales/inde.js``const languages``ja-NCAT` を追加する

View File

@ -908,7 +908,6 @@ _mfm:
rainbow: "قوس قزح"
rainbowDescription: "اجعل المحتوى يظهر بألوان الطيف"
rotate: "تدوير"
rotateDescription: "يُدير المحتوى بزاوية معيّنة."
_instanceTicker:
none: "لا تظهره بتاتًا"
remote: "أظهر للمستخدمين البِعاد"
@ -1237,8 +1236,6 @@ _pages:
font: "الخط"
fontSerif: "Serif"
fontSansSerif: "Sans Serif"
eyeCatchingImageSet: "عيّن صورة مصغّرة"
eyeCatchingImageRemove: "احذف صورة مصغّرة"
chooseBlock: "إضافة كتلة"
selectType: "اختر النوع"
enterVariableName: "أدخل اسم المتغيّر"
@ -1499,7 +1496,6 @@ _notification:
pollVote: "مصوِت شارك في الاستطلاع"
receiveFollowRequest: "طلبات المتابعة المتلقاة"
followRequestAccepted: "طلبات المتابعة المقبولة"
groupInvited: "دعوات الفريق"
app: "إشعارات التطبيقات المرتبطة"
_deck:
alwaysShowMainColumn: "أظهر العمود الرئيسي دائمًا"

View File

@ -832,10 +832,6 @@ size: "আকার"
numberOfColumn: "কলামের সংখ্যা"
searchByGoogle: "গুগল"
indefinitely: "অনির্দিষ্ট"
tenMinutes: "১০ মিনিট"
oneHour: "১ ঘণ্টা"
oneDay: "একদিন"
oneWeek: "এক সপ্তাহ"
_emailUnavailable:
used: "এই ইমেইল ঠিকানাটি ইতোমধ্যে ব্যবহৃত হয়েছে"
format: "এই ইমেল ঠিকানাটি সঠিকভাবে লিখা হয়নি"

View File

@ -94,8 +94,6 @@ unfollow: "Unfollow"
followRequestPending: "Follow request pending"
enterEmoji: "Enter an emoji"
renote: "Renote"
renoteHomeOnly: "Renote to home only"
renoteFollowersOnly: "Renote to followers only"
unrenote: "Take back renote"
renoted: "Renoted."
cantRenote: "This post can't be renoted."

1151
locales/eo-UY.yml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -19,10 +19,12 @@ const languages = [
'da-DK',
'de-DE',
'en-US',
'eo-UY',
'es-ES',
'fr-FR',
'id-ID',
'it-IT',
'ja-NY',
'ja-JP',
'ja-KS',
'kab-KAB',
@ -56,6 +58,7 @@ module.exports = Object.entries(locales)
const [lang] = k.split('-');
switch (k) {
case 'ja-JP': return v;
case 'ja-NY':
case 'ja-KS':
case 'en-US': return merge(locales['ja-JP'], v);
default: return merge(

File diff suppressed because it is too large Load Diff

1793
locales/ja-NY.yml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -481,24 +481,13 @@ showFeaturedNotesInTimeline: "Arată notele recomandate în cronologii"
objectStorage: "Object Storage"
useObjectStorage: "Folosește Object Storage"
objectStorageBaseUrl: "URL de bază"
objectStorageBaseUrlDesc: "URL-ul este folosit pentru referință. Specifică URL-ul CDN-ului sau Proxy-ului tău dacă folosești unul. Pentru S3 folosește 'https://<bucket>.s3.amazonaws.com' și pentru GCS sau servicii echivalente folosește 'https://storage.googleapis.com/<bucket>', etc."
objectStorageBucket: "Bucket"
objectStorageBucketDesc: "Te rog specifică numele bucket-ului furnizorului tău."
objectStoragePrefix: "Prefix"
objectStoragePrefixDesc: "Fișierele vor fi stocate sub directoare cu acest prefix."
objectStorageEndpoint: "Endpoint"
objectStorageEndpointDesc: "Lasă acest câmp gol dacă folosești AWS S3, dacă nu specifică endpoint-ul ca '<host>' sau '<host>:<port>', depinzând de ce serviciu folosești."
objectStorageRegion: "Regiune"
objectStorageRegionDesc: "Specifică o regiune precum 'xx-east-1'. Dacă serviciul tău nu face distincția între regiuni lasă acest câmp gol sau introdu 'us-east-1'."
objectStorageUseSSL: "Folosește SSl"
objectStorageUseSSLDesc: "Oprește această opțiune dacă nu vei folosi HTTPS pentru conexiunile API-ului"
objectStorageUseProxy: "Conectează-te prin Proxy"
objectStorageUseProxyDesc: "Oprește această opțiune dacă vei nu folosi un Proxy pentru conexiunile API-ului"
objectStorageSetPublicRead: "Setează \"public-read\" pentru încărcare"
serverLogs: "Loguri server"
deleteAll: "Șterge tot"
showFixedPostForm: "Arată caseta de postare în vârful cronologie"
newNoteRecived: "Sunt note noi"
sounds: "Sunete"
listen: "Ascultă"
none: "Nimic"
@ -533,42 +522,12 @@ removeAllFollowingDescription: "Asta va dez-urmări toate conturile din {host}.
userSuspended: "Acest utilizator a fost suspendat."
userSilenced: "Acest utilizator a fost setat silențios."
yourAccountSuspendedTitle: "Acest cont a fost suspendat"
yourAccountSuspendedDescription: "Acest cont a fost suspendat din cauza încălcării termenilor de serviciu al serverului sau ceva similar. Contactează administratorul dacă ai dori să afli un motiv mai detaliat. Te rog nu crea un cont nou."
menu: "Meniu"
divider: "Separator"
addItem: "Adaugă element"
relays: "Relee"
addRelay: "Adaugă Releu"
inboxUrl: "URL-ul inbox-ului"
addedRelays: "Relee adăugate"
serviceworkerInfo: "Trebuie să fie activat pentru notificări push."
deletedNote: "Notă ștearsă"
invisibleNote: "Note ascunse"
enableInfiniteScroll: "Încarcă mai mult automat"
visibility: "Vizibilitate"
poll: "Sondaj"
useCw: "Ascunde conținutul"
enablePlayer: "Deschide player-ul video"
disablePlayer: "Închide player-ul video"
expandTweet: "Expandează tweet"
themeEditor: "Editor de teme"
description: "Descriere"
describeFile: "Adaugă titrări"
enterFileDescription: "Introdu titrările"
author: "Autor"
leaveConfirm: "Ai schimbări nesalvate. Vrei să renunți la ele?"
manage: "Gestionare"
plugins: "Pluginuri"
deck: "Deck"
undeck: "Părăsește Deck"
useBlurEffectForModal: "Folosește efect de blur pentru modale"
smtpHost: "Gazdă"
smtpUser: "Nume de utilizator"
smtpPass: "Parolă"
clearCache: "Golește cache-ul"
info: "Despre"
user: "Utilizatori"
administration: "Gestionare"
searchByGoogle: "Caută"
_email:
_follow:
@ -579,11 +538,9 @@ _mfm:
emoji: "Emoji personalizat"
search: "Caută"
_theme:
description: "Descriere"
keys:
mention: "Mențiune"
renote: "Re-notează"
divider: "Separator"
_sfx:
note: "Note"
notification: "Notificări"

View File

@ -81,8 +81,6 @@ somethingHappened: "發生錯誤"
retry: "重試"
pageLoadError: "載入頁面失敗"
pageLoadErrorDescription: "這通常是因為網路錯誤或是瀏覽器快取殘留的原因。請先清除瀏覽器快取,稍後再重試"
serverIsDead: "伺服器沒有回應。請稍等片刻,然後重試。"
youShouldUpgradeClient: "請重新載入以使用新版本的客戶端顯示此頁面"
enterListName: "輸入清單名稱"
privacy: "隱私"
makeFollowManuallyApprove: "手動審核追隨請求"
@ -106,7 +104,6 @@ clickToShow: "按一下以顯示"
sensitive: "敏感內容"
add: "新增"
reaction: "情感"
reactionSetting: "在選擇器中顯示反應"
reactionSettingDescription2: "拖動以重新列序,點擊以刪除,按下 + 添加。"
rememberNoteVisibility: "記住貼文可見性"
attachCancel: "移除附件"
@ -141,7 +138,6 @@ flagAsBot: "此使用者是機器人"
flagAsBotDescription: "如果本帳戶是由程式控制請啟用此選項。啟用後會作為標示幫助其他開發者防止機器人之間產生無限互動的行為並會調整Misskey內部系統將本帳戶識別為機器人"
flagAsCat: "此使用者是貓"
flagAsCatDescription: "如果想將本帳戶標示為一隻貓,請開啟此標示"
flagShowTimelineReplies: "在時間軸上顯示貼文的回覆"
autoAcceptFollowed: "自動追隨中使用者的追隨請求"
addAccount: "添加帳戶"
loginFailed: "登入失敗"
@ -603,9 +599,6 @@ reportAbuse: "檢舉"
reportAbuseOf: "檢舉{name}"
fillAbuseReportDescription: "請填寫檢舉的詳細理由。可以的話請附上針對的URL網址。"
abuseReported: "回報已送出。感謝您的報告。"
reporter: "檢舉者"
reporteeOrigin: "檢舉來源"
reporterOrigin: "檢舉者來源"
send: "發送"
abuseMarkAsResolved: "處理完畢"
openInNewTab: "在新分頁中開啟"
@ -741,7 +734,6 @@ postToGallery: "發佈到相簿"
gallery: "相簿"
recentPosts: "最新貼文"
popularPosts: "熱門的貼文"
shareWithNote: "在貼文中分享"
ads: "廣告"
expiration: "期限"
memo: "備忘錄"
@ -751,35 +743,14 @@ middle: "中"
low: "低"
emailNotConfiguredWarning: "沒有設定電子郵件地址"
ratio: "%"
previewNoteText: "預覽文本"
customCss: "自定義 CSS"
global: "公開"
sent: "發送"
received: "收取"
searchResult: "搜尋結果"
hashtags: "#tag"
troubleshooting: "故障排除"
useBlurEffect: "在 UI 上使用模糊效果"
misskeyUpdated: "Misskey 更新完成!"
translate: "翻譯"
translatedFrom: "從 {x} 翻譯"
accountDeletionInProgress: "正在刪除帳戶"
pubSub: "Pub/Sub 帳戶"
resolved: "已解決"
unresolved: "未解決"
breakFollow: "移除追蹤者"
hide: "隱藏"
leaveGroupConfirm: "確定離開「{name}」?"
auto: "自動"
searchByGoogle: "搜尋"
indefinitely: "無期限"
_ffVisibility:
public: "發佈"
private: "私密"
_signup:
almostThere: "即將完成"
_accountDelete:
inProgress: "正在刪除"
_ad:
back: "返回"
reduceFrequencyOfThisAd: "降低此廣告的頻率 "

View File

@ -1,10 +1,10 @@
{
"name": "misskey",
"version": "12.110.1-nca10.net-v1",
"version": "12.109.1-simkey-v1",
"codename": "indigo",
"repository": {
"type": "git",
"url": "https://github.com/misskey-dev/misskey.git"
"url": "https://github.com/sim1222/misskey.git"
},
"private": true,
"scripts": {
@ -41,7 +41,7 @@
"js-yaml": "4.1.0"
},
"devDependencies": {
"@typescript-eslint/parser": "5.18.0",
"@typescript-eslint/parser": "5.17.0",
"cross-env": "7.0.3",
"cypress": "9.5.3",
"start-server-and-test": "1.14.0",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -5,7 +5,7 @@
"scripts": {
"build": "tsc -p tsconfig.json || echo done. && tsc-alias -p tsconfig.json",
"watch": "node watch.mjs",
"lint": "eslint --quiet \"src/**/*.ts\"",
"lint": "eslint --quiet src/**/*.ts",
"mocha": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
"test": "npm run mocha"
},
@ -55,24 +55,25 @@
"@types/redis": "4.0.11",
"@types/rename": "1.0.4",
"@types/sanitize-html": "2.6.2",
"@types/sharp": "0.30.1",
"@types/sharp": "0.30.0",
"@types/sinonjs__fake-timers": "8.1.2",
"@types/speakeasy": "2.0.7",
"@types/throttle-debounce": "2.1.0",
"@types/tinycolor2": "1.4.3",
"@types/tmp": "0.2.3",
"@types/uuid": "8.3.4",
"@types/web-push": "3.3.2",
"@types/websocket": "1.0.5",
"@types/ws": "8.5.3",
"@typescript-eslint/eslint-plugin": "5.18.0",
"@typescript-eslint/parser": "5.18.0",
"@bull-board/koa": "3.10.3",
"@typescript-eslint/eslint-plugin": "5.17.0",
"@typescript-eslint/parser": "5.17.0",
"@bull-board/koa": "3.10.2",
"abort-controller": "3.0.0",
"ajv": "8.11.0",
"archiver": "5.3.0",
"autobind-decorator": "2.4.0",
"autwh": "0.1.0",
"aws-sdk": "2.1111.0",
"aws-sdk": "2.1105.0",
"bcryptjs": "2.4.3",
"blurhash": "1.1.5",
"broadcast-channel": "4.10.0",
@ -88,8 +89,8 @@
"date-fns": "2.28.0",
"deep-email-validator": "0.1.21",
"escape-regexp": "0.0.1",
"eslint": "8.13.0",
"eslint-plugin-import": "2.26.0",
"eslint": "8.12.0",
"eslint-plugin-import": "2.25.4",
"feed": "4.2.2",
"file-type": "17.1.1",
"fluent-ffmpeg": "2.1.2",
@ -144,7 +145,7 @@
"rndstr": "1.0.0",
"s-age": "1.1.2",
"sanitize-html": "2.7.0",
"semver": "7.3.6",
"semver": "7.3.5",
"sharp": "0.30.3",
"speakeasy": "2.0.0",
"strict-event-emitter-types": "2.0.0",
@ -153,6 +154,7 @@
"summaly": "2.5.0",
"syslog-pro": "1.0.0",
"systeminformation": "5.11.9",
"throttle-debounce": "3.0.1",
"tinycolor2": "1.4.2",
"tmp": "0.2.1",
"ts-loader": "9.2.8",
@ -160,7 +162,7 @@
"tsc-alias": "1.4.1",
"tsconfig-paths": "3.14.1",
"twemoji-parser": "14.0.0",
"typeorm": "0.3.5",
"typeorm": "0.3.4",
"typescript": "4.6.3",
"ulid": "2.3.0",
"unzipper": "0.10.11",
@ -171,7 +173,7 @@
"xev": "2.0.1"
},
"devDependencies": {
"@redocly/openapi-core": "1.0.0-beta.93",
"@redocly/openapi-core": "1.0.0-beta.91",
"@types/fluent-ffmpeg": "2.1.20",
"cross-env": "7.0.3",
"execa": "6.1.0"

View File

@ -1,4 +1,4 @@
export const MAX_NOTE_TEXT_LENGTH = 3000;
export const MAX_NOTE_TEXT_LENGTH = 8192;
export const USER_ONLINE_THRESHOLD = 1000 * 60 * 10; // 10min
export const USER_ACTIVE_THRESHOLD = 1000 * 60 * 60 * 24 * 3; // 3days

View File

@ -209,11 +209,7 @@ export const db = new DataSource({
});
export async function initDb() {
if (db.isInitialized) {
// nop
} else {
await db.connect();
}
await db.connect();
}
export async function resetDb() {

View File

@ -42,8 +42,7 @@ async function getCaptchaResponse(url: string, secret: string, response: string)
headers: {
'User-Agent': config.userAgent,
},
// TODO
//timeout: 10 * 1000,
timeout: 10 * 1000,
agent: getAgentByUrl,
}).catch(e => {
throw `${e.message || e}`;

View File

@ -120,9 +120,9 @@ export const httpsAgent = config.proxy
*/
export function getAgentByUrl(url: URL, bypassProxy = false) {
if (bypassProxy || (config.proxyBypassHosts || []).includes(url.hostname)) {
return url.protocol === 'http:' ? _http : _https;
return url.protocol == 'http:' ? _http : _https;
} else {
return url.protocol === 'http:' ? httpAgent : httpsAgent;
return url.protocol == 'http:' ? httpAgent : httpsAgent;
}
}

View File

@ -23,7 +23,7 @@ export const getNoteSummary = (note: Packed<'Note'>): string => {
}
// ファイルが添付されているとき
if ((note.files || []).length !== 0) {
if ((note.files || []).length != 0) {
summary += ` (📎${note.files!.length})`;
}

View File

@ -1,6 +1,6 @@
import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
import { id } from '../id.js';
import { DriveFile } from './drive-file.js';
import { id } from '../id.js';
@Entity()
@Index(['usernameLower', 'host'], { unique: true })
@ -207,7 +207,7 @@ export class User {
@Column('boolean', {
default: false,
comment: 'Whether to show users replying to other users in the timeline',
comment: 'Whether to show users replying to other users in the timeline'
})
public showTimelineReplies: boolean;

View File

@ -1,6 +1,7 @@
import { EntityRepository, Repository, In, Not } from 'typeorm';
import Ajv from 'ajv';
import { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js';
import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances, DriveFiles } from '../index.js';
import config from '@/config/index.js';
import { Packed } from '@/misc/schema.js';
import { awaitAll, Promiseable } from '@/prelude/await-all.js';
@ -8,9 +9,8 @@ import { populateEmojis } from '@/misc/populate-emojis.js';
import { getAntennas } from '@/misc/antenna-cache.js';
import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js';
import { Cache } from '@/misc/cache.js';
import { db } from '@/db/postgre.js';
import { Instance } from '../entities/instance.js';
import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances, DriveFiles } from '../index.js';
import { db } from '@/db/postgre.js';
const userInstanceCache = new Cache<Instance | null>(1000 * 60 * 60 * 3);
@ -112,7 +112,7 @@ export const UserRepository = db.getRepository(User).extend({
const joinings = await UserGroupJoinings.findBy({ userId: userId });
const groupQs = Promise.all(joinings.map(j => MessagingMessages.createQueryBuilder('message')
.where('message.groupId = :groupId', { groupId: j.userGroupId })
.where(`message.groupId = :groupId`, { groupId: j.userGroupId })
.andWhere('message.userId != :userId', { userId: userId })
.andWhere('NOT (:userId = ANY(message.reads))', { userId: userId })
.andWhere('message.createdAt > :joinedAt', { joinedAt: j.createdAt }) // 自分が加入する前の会話については、未読扱いしない
@ -204,18 +204,8 @@ export const UserRepository = db.getRepository(User).extend({
);
},
async getAvatarUrl(user: User): Promise<string> {
if (user.avatar) {
return DriveFiles.getPublicUrl(user.avatar, true) || this.getIdenticonUrl(user.id);
} else if (user.avatarId) {
const avatar = await DriveFiles.findOneByOrFail({ id: user.avatarId });
return DriveFiles.getPublicUrl(avatar, true) || this.getIdenticonUrl(user.id);
} else {
return this.getIdenticonUrl(user.id);
}
},
getAvatarUrlSync(user: User): string {
getAvatarUrl(user: User): string {
// TODO: avatarIdがあるがavatarがない(JOINされてない)場合のハンドリング
if (user.avatar) {
return DriveFiles.getPublicUrl(user.avatar, true) || this.getIdenticonUrl(user.id);
} else {
@ -233,7 +223,7 @@ export const UserRepository = db.getRepository(User).extend({
options?: {
detail?: D,
includeSecrets?: boolean,
},
}
): Promise<IsMeAndIsUserDetailed<ExpectsMe, D>> {
const opts = Object.assign({
detail: false,
@ -284,7 +274,7 @@ export const UserRepository = db.getRepository(User).extend({
name: user.name,
username: user.username,
host: user.host,
avatarUrl: this.getAvatarUrlSync(user),
avatarUrl: this.getAvatarUrl(user),
avatarBlurhash: user.avatar?.blurhash || null,
avatarColor: null, // 後方互換性のため
isAdmin: user.isAdmin || falsy,
@ -293,7 +283,7 @@ export const UserRepository = db.getRepository(User).extend({
isCat: user.isCat || falsy,
instance: user.host ? userInstanceCache.fetch(user.host,
() => Instances.findOneBy({ host: user.host! }),
v => v != null,
v => v != null
).then(instance => instance ? {
name: instance.name,
softwareName: instance.softwareName,
@ -413,7 +403,7 @@ export const UserRepository = db.getRepository(User).extend({
options?: {
detail?: D,
includeSecrets?: boolean,
},
}
): Promise<IsUserDetailed<D>[]> {
return Promise.all(users.map(u => this.pack(u, me, options)));
},

View File

@ -27,7 +27,6 @@ export const packedEmojiSchema = {
host: {
type: 'string',
optional: false, nullable: true,
description: 'The local host is represented with `null`.',
},
url: {
type: 'string',

View File

@ -21,7 +21,6 @@ export const packedUserLiteSchema = {
type: 'string',
nullable: true, optional: false,
example: 'misskey.example.com',
description: 'The local host is represented with `null`.',
},
avatarUrl: {
type: 'string',

View File

@ -1,5 +1,4 @@
import httpSignature from 'http-signature';
import { v4 as uuid } from 'uuid';
import config from '@/config/index.js';
import { envOption } from '../env.js';
@ -17,7 +16,7 @@ import { getJobInfo } from './get-job-info.js';
import { systemQueue, dbQueue, deliverQueue, inboxQueue, objectStorageQueue, endedPollNotificationQueue, webhookDeliverQueue } from './queues.js';
import { ThinUser } from './types.js';
import { IActivity } from '@/remote/activitypub/type.js';
import { Webhook, webhookEventTypes } from '@/models/entities/webhook.js';
import { Webhook } from '@/models/entities/webhook.js';
function renderError(e: Error): any {
return {
@ -263,16 +262,12 @@ export function createCleanRemoteFilesJob() {
});
}
export function webhookDeliver(webhook: Webhook, type: typeof webhookEventTypes[number], content: unknown) {
export function webhookDeliver(webhook: Webhook, content: unknown) {
const data = {
type,
content,
webhookId: webhook.id,
userId: webhook.userId,
to: webhook.url,
secret: webhook.secret,
createdAt: Date.now(),
eventId: uuid(),
};
return webhookDeliverQueue.add(data, {

View File

@ -8,9 +8,13 @@ import config from '@/config/index.js';
const logger = new Logger('webhook');
let latest: string | null = null;
export default async (job: Bull.Job<WebhookDeliverJobData>) => {
try {
logger.debug(`delivering ${job.data.webhookId}`);
if (latest !== (latest = JSON.stringify(job.data.content, null, 2))) {
logger.debug(`delivering ${latest}`);
}
const res = await getResponse({
url: job.data.to,
@ -21,14 +25,7 @@ export default async (job: Bull.Job<WebhookDeliverJobData>) => {
'X-Misskey-Hook-Id': job.data.webhookId,
'X-Misskey-Hook-Secret': job.data.secret,
},
body: JSON.stringify({
hookId: job.data.webhookId,
userId: job.data.userId,
eventId: job.data.eventId,
createdAt: job.data.createdAt,
type: job.data.type,
body: job.data.content,
}),
body: JSON.stringify(job.data.content),
});
Webhooks.update({ id: job.data.webhookId }, {

View File

@ -48,14 +48,10 @@ export type EndedPollNotificationJobData = {
};
export type WebhookDeliverJobData = {
type: string;
content: unknown;
webhookId: Webhook['id'];
userId: User['id'];
to: string;
secret: string;
createdAt: number;
eventId: string;
};
export type ThinUser = {

View File

@ -95,7 +95,7 @@ function genSigningString(request: Request, includeHeaders: string[]) {
function lcObjectKey(src: Record<string, string>) {
const dst: Record<string, string> = {};
for (const key of Object.keys(src).filter(x => x !== '__proto__' && typeof src[x] === 'string')) dst[key.toLowerCase()] = src[key];
for (const key of Object.keys(src).filter(x => x != '__proto__' && typeof src[x] === 'string')) dst[key.toLowerCase()] = src[key];
return dst;
}

View File

@ -109,15 +109,15 @@ export default class DeliverManager {
}
}
this.recipes.filter((recipe): recipe is IDirectRecipe =>
this.recipes.filter((recipe): recipe is IDirectRecipe => {
// followers recipes have already been processed
isDirect(recipe)
// check that shared inbox has not been added yet
&& !(recipe.to.sharedInbox && inboxes.has(recipe.to.sharedInbox))
// check that they actually have an inbox
&& recipe.to.inbox != null,
)
.forEach(recipe => inboxes.add(recipe.to.inbox!));
&& recipe.to.inbox
})
.forEach(recipe => inboxes.add(recipe.to.inbox));
// deliver
for (const inbox of inboxes) {

View File

@ -18,7 +18,7 @@ export const performReadActivity = async (actor: CacheableRemoteUser, activity:
return `skip: message not found`;
}
if (actor.id !== message.recipientId) {
if (actor.id != message.recipientId) {
return `skip: actor is not a message recipient`;
}

View File

@ -1,6 +1,6 @@
import unfollow from '@/services/following/delete.js';
import cancelRequest from '@/services/following/requests/cancel.js';
import { IAccept } from '../../type.js';
import {IAccept} from '../../type.js';
import { CacheableRemoteUser } from '@/models/entities/user.js';
import { Followings } from '@/models/index.js';
import DbResolver from '../../db-resolver.js';

View File

@ -113,8 +113,7 @@ export class LdSignature {
headers: {
Accept: 'application/ld+json, application/json',
},
// TODO
//timeout: this.loderTimeout,
timeout: this.loderTimeout,
agent: u => u.protocol === 'http:' ? httpAgent : httpsAgent,
}).then(res => {
if (!res.ok) {

View File

@ -69,7 +69,7 @@ export async function updateQuestion(value: any) {
const oldCount = poll.votes[poll.choices.indexOf(choice)];
const newCount = apChoices!.filter(ap => ap.name === choice)[0].replies!.totalItems;
if (oldCount !== newCount) {
if (oldCount != newCount) {
changed = true;
poll.votes[poll.choices.indexOf(choice)] = newCount;
}

View File

@ -15,7 +15,7 @@ type IWebFinger = {
export default async function(query: string): Promise<IWebFinger> {
const url = genUrl(query);
return await getJson(url, 'application/jrd+json, application/json') as IWebFinger;
return await getJson(url, 'application/jrd+json, application/json');
}
function genUrl(query: string) {

View File

@ -121,14 +121,14 @@ export function verifyLogin({
signature: Buffer,
challenge: string
}) {
if (clientData.type !== 'webauthn.get') {
if (clientData.type != 'webauthn.get') {
throw new Error('type is not webauthn.get');
}
if (hash(clientData.challenge).toString('hex') !== challenge) {
if (hash(clientData.challenge).toString('hex') != challenge) {
throw new Error('challenge mismatch');
}
if (clientData.origin !== config.scheme + '://' + config.host) {
if (clientData.origin != config.scheme + '://' + config.host) {
throw new Error('origin mismatch');
}
@ -148,11 +148,11 @@ export const procedures = {
verify({ publicKey }: {publicKey: Map<number, Buffer>}) {
const negTwo = publicKey.get(-2);
if (!negTwo || negTwo.length !== 32) {
if (!negTwo || negTwo.length != 32) {
throw new Error('invalid or no -2 key given');
}
const negThree = publicKey.get(-3);
if (!negThree || negThree.length !== 32) {
if (!negThree || negThree.length != 32) {
throw new Error('invalid or no -3 key given');
}
@ -183,7 +183,7 @@ export const procedures = {
rpIdHash: Buffer,
credentialId: Buffer,
}) {
if (attStmt.alg !== -7) {
if (attStmt.alg != -7) {
throw new Error('alg mismatch');
}
@ -196,11 +196,11 @@ export const procedures = {
const negTwo = publicKey.get(-2);
if (!negTwo || negTwo.length !== 32) {
if (!negTwo || negTwo.length != 32) {
throw new Error('invalid or no -2 key given');
}
const negThree = publicKey.get(-3);
if (!negThree || negThree.length !== 32) {
if (!negThree || negThree.length != 32) {
throw new Error('invalid or no -3 key given');
}
@ -263,7 +263,7 @@ export const procedures = {
.map((key: any) => PEMString(key))
.concat([GSR2]);
if (getCertSubject(certificateChain[0]).CN !== 'attest.android.com') {
if (getCertSubject(certificateChain[0]).CN != 'attest.android.com') {
throw new Error('invalid common name');
}
@ -283,11 +283,11 @@ export const procedures = {
const negTwo = publicKey.get(-2);
if (!negTwo || negTwo.length !== 32) {
if (!negTwo || negTwo.length != 32) {
throw new Error('invalid or no -2 key given');
}
const negThree = publicKey.get(-3);
if (!negThree || negThree.length !== 32) {
if (!negThree || negThree.length != 32) {
throw new Error('invalid or no -3 key given');
}
@ -332,11 +332,11 @@ export const procedures = {
const negTwo = publicKey.get(-2);
if (!negTwo || negTwo.length !== 32) {
if (!negTwo || negTwo.length != 32) {
throw new Error('invalid or no -2 key given');
}
const negThree = publicKey.get(-3);
if (!negThree || negThree.length !== 32) {
if (!negThree || negThree.length != 32) {
throw new Error('invalid or no -3 key given');
}
@ -353,7 +353,7 @@ export const procedures = {
// https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-ecdaa-algorithm-v2.0-id-20180227.html#ecdaa-verify-operation
throw new Error('ECDAA-Verify is not supported');
} else {
if (attStmt.alg !== -7) throw new Error('alg mismatch');
if (attStmt.alg != -7) throw new Error('alg mismatch');
throw new Error('self attestation is not supported');
}
@ -377,7 +377,7 @@ export const procedures = {
credentialId: Buffer
}) {
const x5c: Buffer[] = attStmt.x5c;
if (x5c.length !== 1) {
if (x5c.length != 1) {
throw new Error('x5c length does not match expectation');
}
@ -387,11 +387,11 @@ export const procedures = {
const negTwo: Buffer = publicKey.get(-2);
if (!negTwo || negTwo.length !== 32) {
if (!negTwo || negTwo.length != 32) {
throw new Error('invalid or no -2 key given');
}
const negThree: Buffer = publicKey.get(-3);
if (!negThree || negThree.length !== 32) {
if (!negThree || negThree.length != 32) {
throw new Error('invalid or no -3 key given');
}

View File

@ -9,7 +9,7 @@ import { publishMainStream } from '@/services/stream.js';
export default function(ctx: Koa.Context, user: ILocalUser, redirect = false) {
if (redirect) {
//#region Cookie
ctx.cookies.set('igi', user.token!, {
ctx.cookies.set('igi', user.token, {
path: '/',
// SEE: https://github.com/koajs/koa/issues/974
// When using a SSL proxy it should be configured to add the "X-Forwarded-Proto: https" header

View File

@ -27,12 +27,7 @@ export const paramDef = {
untilId: { type: 'string', format: 'misskey:id' },
type: { type: 'string', nullable: true, pattern: /^[a-zA-Z0-9\/\-*]+$/.toString().slice(1, -1) },
origin: { type: 'string', enum: ['combined', 'local', 'remote'], default: "local" },
hostname: {
type: 'string',
nullable: true,
default: null,
description: 'The local host is represented with `null`.',
},
hostname: { type: 'string', nullable: true, default: null },
},
required: [],
} as const;

View File

@ -40,7 +40,6 @@ export const meta = {
userHost: {
type: 'string',
optional: false, nullable: true,
description: 'The local host is represented with `null`.',
},
md5: {
type: 'string',
@ -152,20 +151,11 @@ export const meta = {
export const paramDef = {
type: 'object',
anyOf: [
{
properties: {
fileId: { type: 'string', format: 'misskey:id' },
},
required: ['fileId'],
},
{
properties: {
url: { type: 'string' },
},
required: ['url'],
},
],
properties: {
fileId: { type: 'string', format: 'misskey:id' },
url: { type: 'string' },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export

View File

@ -40,7 +40,6 @@ export const meta = {
host: {
type: 'string',
optional: false, nullable: true,
description: 'The local host is represented with `null`.',
},
url: {
type: 'string',
@ -55,12 +54,7 @@ export const paramDef = {
type: 'object',
properties: {
query: { type: 'string', nullable: true, default: null },
host: {
type: 'string',
nullable: true,
default: null,
description: 'Use `null` to represent the local host.',
},
host: { type: 'string', nullable: true, default: null },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },

View File

@ -38,9 +38,8 @@ export const meta = {
optional: false, nullable: true,
},
host: {
type: 'null',
optional: false,
description: 'The local host is represented with `null`. The field exists for compatibility with other API endpoints that return files.',
type: 'string',
optional: false, nullable: true,
},
url: {
type: 'string',

View File

@ -17,11 +17,7 @@ export const paramDef = {
ids: { type: 'array', items: {
type: 'string', format: 'misskey:id',
} },
category: {
type: 'string',
nullable: true,
description: 'Use `null` to reset the category.',
},
category: { type: 'string', nullable: true },
},
required: ['ids'],
} as const;

View File

@ -23,11 +23,7 @@ export const paramDef = {
properties: {
id: { type: 'string', format: 'misskey:id' },
name: { type: 'string' },
category: {
type: 'string',
nullable: true,
description: 'Use `null` to reset the category.',
},
category: { type: 'string', nullable: true },
aliases: { type: 'array', items: {
type: 'string',
} },

View File

@ -26,13 +26,8 @@ export const paramDef = {
sort: { type: 'string', enum: ['+follower', '-follower', '+createdAt', '-createdAt', '+updatedAt', '-updatedAt'] },
state: { type: 'string', enum: ['all', 'available', 'admin', 'moderator', 'adminOrModerator', 'silenced', 'suspended'], default: "all" },
origin: { type: 'string', enum: ['combined', 'local', 'remote'], default: "local" },
username: { type: 'string', nullable: true, default: null },
hostname: {
type: 'string',
nullable: true,
default: null,
description: 'The local host is represented with `null`.',
},
username: { type: 'string', default: null },
hostname: { type: 'string', default: null },
},
required: [],
} as const;

View File

@ -397,14 +397,12 @@ export default define(meta, paramDef, async (ps, me) => {
}
await db.transaction(async transactionalEntityManager => {
const metas = await transactionalEntityManager.find(Meta, {
const meta = await transactionalEntityManager.findOne(Meta, {
order: {
id: 'DESC',
},
});
const meta = metas[0];
if (meta) {
await transactionalEntityManager.update(Meta, meta.id, set);
} else {

View File

@ -57,9 +57,13 @@ export default define(meta, paramDef, async (ps, user) => {
throw new ApiError(meta.errors.noSuchAntenna);
}
const antennaQuery = AntennaNotes.createQueryBuilder('joining')
.select('joining.noteId')
.where('joining.antennaId = :antennaId', { antennaId: antenna.id });
const query = makePaginationQuery(Notes.createQueryBuilder('note'),
ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
.innerJoin(AntennaNotes.metadata.targetName, 'antennaNote', 'antennaNote.noteId = note.id')
.andWhere(`note.id IN (${ antennaQuery.getQuery() })`)
.innerJoinAndSelect('note.user', 'user')
.leftJoinAndSelect('user.avatar', 'avatar')
.leftJoinAndSelect('user.banner', 'banner')
@ -71,7 +75,7 @@ export default define(meta, paramDef, async (ps, user) => {
.leftJoinAndSelect('renote.user', 'renoteUser')
.leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar')
.leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner')
.andWhere('antennaNote.antennaId = :antennaId', { antennaId: antenna.id });
.setParameters(antennaQuery.getParameters());
generateVisibilityQuery(query, user);
generateMutedUserQuery(query, user);

View File

@ -20,7 +20,7 @@ export const paramDef = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1, maxLength: 100 },
isPublic: { type: 'boolean', default: false },
isPublic: { type: 'boolean' },
description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 },
},
required: ['name'],

View File

@ -57,8 +57,12 @@ export default define(meta, paramDef, async (ps, user) => {
throw new ApiError(meta.errors.noSuchClip);
}
const clipQuery = ClipNotes.createQueryBuilder('joining')
.select('joining.noteId')
.where('joining.clipId = :clipId', { clipId: clip.id });
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
.innerJoin(ClipNotes.metadata.targetName, 'clipNote', 'clipNote.noteId = note.id')
.andWhere(`note.id IN (${ clipQuery.getQuery() })`)
.innerJoinAndSelect('note.user', 'user')
.leftJoinAndSelect('user.avatar', 'avatar')
.leftJoinAndSelect('user.banner', 'banner')
@ -70,7 +74,7 @@ export default define(meta, paramDef, async (ps, user) => {
.leftJoinAndSelect('renote.user', 'renoteUser')
.leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar')
.leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner')
.andWhere('clipNote.clipId = :clipId', { clipId: clip.id });
.setParameters(clipQuery.getParameters());
if (user) {
generateVisibilityQuery(query, user);

View File

@ -48,6 +48,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
// @ts-ignore
export default define(meta, paramDef, async (ps, user, _, file, cleanup) => {
// Get 'name' parameter
let name = ps.name || file.originalname;

View File

@ -28,25 +28,22 @@ export const meta = {
code: 'ACCESS_DENIED',
id: '25b73c73-68b1-41d0-bad1-381cfdf6579f',
},
fileIdOrUrlRequired: {
message: 'fileId or url required.',
code: 'INVALID_PARAM',
id: '89674805-722c-440c-8d88-5641830dc3e4',
},
},
} as const;
export const paramDef = {
type: 'object',
anyOf: [
{
properties: {
fileId: { type: 'string', format: 'misskey:id' },
},
required: ['fileId'],
},
{
properties: {
url: { type: 'string' },
},
required: ['url'],
},
],
properties: {
fileId: { type: 'string', format: 'misskey:id' },
url: { type: 'string' },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
@ -65,6 +62,8 @@ export default define(meta, paramDef, async (ps, user) => {
thumbnailUrl: ps.url,
}],
});
} else {
throw new ApiError(meta.errors.fileIdOrUrlRequired);
}
if (file == null) {

View File

@ -22,7 +22,7 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
host: { type: 'string', nullable: true, description: 'Omit or use `null` to not filter by host.' },
host: { type: 'string', nullable: true },
blocked: { type: 'boolean', nullable: true },
notResponding: { type: 'boolean', nullable: true },
suspended: { type: 'boolean', nullable: true },

View File

@ -50,10 +50,10 @@ export default define(meta, paramDef, async (ps, user) => {
const clientData = JSON.parse(ps.clientDataJSON);
if (clientData.type !== 'webauthn.create') {
if (clientData.type != 'webauthn.create') {
throw new Error('not a creation attestation');
}
if (clientData.origin !== config.scheme + '://' + config.host) {
if (clientData.origin != config.scheme + '://' + config.host) {
throw new Error('origin mismatch');
}
@ -78,7 +78,7 @@ export default define(meta, paramDef, async (ps, user) => {
const credentialId = authData.slice(55, 55 + credentialIdLength);
const publicKeyData = authData.slice(55 + credentialIdLength);
const publicKey: Map<number, any> = await cborDecodeFirst(publicKeyData);
if (publicKey.get(3) !== -7) {
if (publicKey.get(3) != -7) {
throw new Error('alg mismatch');
}

View File

@ -27,7 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
take: ps.limit,
skip: ps.offset,
order: {
id: ps.sort === 'asc' ? 1 : -1,
id: ps.sort == 'asc' ? 1 : -1,
},
});

View File

@ -47,25 +47,14 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
groupId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
markAsRead: { type: 'boolean', default: true },
},
anyOf: [
{
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
},
{
properties: {
groupId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId'],
},
],
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
@ -137,5 +126,7 @@ export default define(meta, paramDef, async (ps, user) => {
return await Promise.all(messages.map(message => MessagingMessages.pack(message, user, {
populateGroup: false,
})));
} else {
throw new Error();
}
});

View File

@ -67,23 +67,12 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
groupId: { type: 'string', format: 'misskey:id' },
text: { type: 'string', nullable: true, maxLength: 3000 },
fileId: { type: 'string', format: 'misskey:id' },
},
anyOf: [
{
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
},
{
properties: {
groupId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId'],
},
],
required: [],
} as const;
// eslint-disable-next-line import/no-default-export

View File

@ -169,7 +169,6 @@ export const meta = {
host: {
type: 'string',
optional: false, nullable: true,
description: 'The local host is represented with `null`.',
},
url: {
type: 'string',

View File

@ -38,11 +38,7 @@ export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
expiresAt: {
type: 'integer',
nullable: true,
description: 'A Unix Epoch timestamp that must lie in the future. `null` means an indefinite mute.',
},
expiresAt: { type: 'integer', nullable: true },
},
required: ['userId'],
} as const;

View File

@ -19,7 +19,7 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
local: { type: 'boolean', default: false },
local: { type: 'boolean' },
reply: { type: 'boolean' },
renote: { type: 'boolean' },
withFiles: { type: 'boolean' },
@ -52,19 +52,19 @@ export default define(meta, paramDef, async (ps) => {
query.andWhere('note.userHost IS NULL');
}
if (ps.reply !== undefined) {
if (ps.reply != undefined) {
query.andWhere(ps.reply ? 'note.replyId IS NOT NULL' : 'note.replyId IS NULL');
}
if (ps.renote !== undefined) {
if (ps.renote != undefined) {
query.andWhere(ps.renote ? 'note.renoteId IS NOT NULL' : 'note.renoteId IS NULL');
}
if (ps.withFiles !== undefined) {
if (ps.withFiles != undefined) {
query.andWhere(ps.withFiles ? `note.fileIds != '{}'` : `note.fileIds = '{}'`);
}
if (ps.poll !== undefined) {
if (ps.poll != undefined) {
query.andWhere(ps.poll ? 'note.hasPoll = TRUE' : 'note.hasPoll = FALSE');
}

View File

@ -57,7 +57,7 @@ export default define(meta, paramDef, async (ps, user) => {
conversation.push(p);
}
if (conversation.length === ps.limit) {
if (conversation.length == ps.limit) {
return;
}

View File

@ -9,7 +9,6 @@ import { Note } from '@/models/entities/note.js';
import { noteVisibilities } from '../../../../types.js';
import { Channel } from '@/models/entities/channel.js';
import { MAX_NOTE_TEXT_LENGTH } from '@/const.js';
import { In } from 'typeorm';
export const meta = {
tags: ['notes'],
@ -60,6 +59,12 @@ export const meta = {
id: '3ac74a84-8fd5-4bb0-870f-01804f82ce15',
},
contentRequired: {
message: 'Content required. You need to set text, fileIds, renoteId or poll.',
code: 'CONTENT_REQUIRED',
id: '6f57e42b-c348-439b-bc45-993995cc515a',
},
cannotCreateAlreadyExpiredPoll: {
message: 'Poll is already expired.',
code: 'CANNOT_CREATE_ALREADY_EXPIRED_POLL',
@ -87,41 +92,29 @@ export const paramDef = {
visibleUserIds: { type: 'array', uniqueItems: true, items: {
type: 'string', format: 'misskey:id',
} },
text: { type: 'string', maxLength: MAX_NOTE_TEXT_LENGTH, nullable: true },
text: { type: 'string', nullable: true, maxLength: MAX_NOTE_TEXT_LENGTH, default: null },
cw: { type: 'string', nullable: true, maxLength: 100 },
localOnly: { type: 'boolean', default: false },
noExtractMentions: { type: 'boolean', default: false },
noExtractHashtags: { type: 'boolean', default: false },
noExtractEmojis: { type: 'boolean', default: false },
fileIds: {
type: 'array',
uniqueItems: true,
minItems: 1,
maxItems: 16,
items: { type: 'string', format: 'misskey:id' },
},
mediaIds: {
deprecated: true,
description: 'Use `fileIds` instead. If both are specified, this property is discarded.',
type: 'array',
uniqueItems: true,
minItems: 1,
maxItems: 16,
items: { type: 'string', format: 'misskey:id' },
},
fileIds: { type: 'array', uniqueItems: true, minItems: 1, maxItems: 16, items: {
type: 'string', format: 'misskey:id',
} },
mediaIds: { type: 'array', uniqueItems: true, minItems: 1, maxItems: 16, items: {
type: 'string', format: 'misskey:id',
} },
replyId: { type: 'string', format: 'misskey:id', nullable: true },
renoteId: { type: 'string', format: 'misskey:id', nullable: true },
channelId: { type: 'string', format: 'misskey:id', nullable: true },
poll: {
type: 'object',
nullable: true,
type: 'object', nullable: true,
properties: {
choices: {
type: 'array',
uniqueItems: true,
minItems: 2,
maxItems: 10,
items: { type: 'string', minLength: 1, maxLength: 50 },
type: 'array', uniqueItems: true, minItems: 2, maxItems: 10,
items: {
type: 'string', minLength: 1, maxLength: 50,
},
},
multiple: { type: 'boolean', default: false },
expiresAt: { type: 'integer', nullable: true },
@ -130,52 +123,26 @@ export const paramDef = {
required: ['choices'],
},
},
anyOf: [
{
// (re)note with text, files and poll are optional
properties: {
text: { type: 'string', maxLength: MAX_NOTE_TEXT_LENGTH, nullable: false },
},
required: ['text'],
},
{
// (re)note with files, text and poll are optional
required: ['fileIds'],
},
{
// (re)note with files, text and poll are optional
required: ['mediaIds'],
},
{
// (re)note with poll, text and files are optional
properties: {
poll: { type: 'object', nullable: false, },
},
required: ['poll'],
},
{
// pure renote
required: ['renoteId'],
},
],
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
let visibleUsers: User[] = [];
if (ps.visibleUserIds) {
visibleUsers = await Users.findBy({
id: In(ps.visibleUserIds),
});
visibleUsers = (await Promise.all(ps.visibleUserIds.map(id => Users.findOneBy({ id }))))
.filter(x => x != null) as User[];
}
let files: DriveFile[] = [];
const fileIds = ps.fileIds != null ? ps.fileIds : ps.mediaIds != null ? ps.mediaIds : null;
if (fileIds != null) {
files = await DriveFiles.findBy({
userId: user.id,
id: In(fileIds),
});
files = (await Promise.all(fileIds.map(fileId =>
DriveFiles.findOneBy({
id: fileId,
userId: user.id,
})
))).filter(file => file != null) as DriveFile[];
}
let renote: Note | null;
@ -185,7 +152,7 @@ export default define(meta, paramDef, async (ps, user) => {
if (renote == null) {
throw new ApiError(meta.errors.noSuchRenoteTarget);
} else if (renote.renoteId && !renote.text && !renote.fileIds && !renote.poll) {
} else if (renote.renoteId && !renote.text && !renote.fileIds) {
throw new ApiError(meta.errors.cannotReRenote);
}
@ -208,7 +175,10 @@ export default define(meta, paramDef, async (ps, user) => {
if (reply == null) {
throw new ApiError(meta.errors.noSuchReplyTarget);
} else if (reply.renoteId && !reply.text && !reply.fileIds && !renote.poll) {
}
// 返信対象が引用でないRenoteだったらエラー
if (reply.renoteId && !reply.text && !reply.fileIds) {
throw new ApiError(meta.errors.cannotReplyToPureRenote);
}
@ -234,6 +204,11 @@ export default define(meta, paramDef, async (ps, user) => {
}
}
// テキストが無いかつ添付ファイルが無いかつRenoteも無いかつ投票も無かったらエラー
if (!(ps.text || files.length || renote || ps.poll)) {
throw new ApiError(meta.errors.contentRequired);
}
let channel: Channel | undefined;
if (ps.channelId != null) {
channel = await Channels.findOneBy({ id: ps.channelId });

View File

@ -35,11 +35,7 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
withFiles: {
type: 'boolean',
default: false,
description: 'Only show notes that have attached files.',
},
withFiles: { type: 'boolean' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },

View File

@ -48,11 +48,7 @@ export const paramDef = {
includeMyRenotes: { type: 'boolean', default: true },
includeRenotedMyNotes: { type: 'boolean', default: true },
includeLocalRenotes: { type: 'boolean', default: true },
withFiles: {
type: 'boolean',
default: false,
description: 'Only show notes that have attached files.',
},
withFiles: { type: 'boolean' },
},
required: [],
} as const;

View File

@ -37,11 +37,7 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
withFiles: {
type: 'boolean',
default: false,
description: 'Only show notes that have attached files.',
},
withFiles: { type: 'boolean' },
fileType: { type: 'array', items: {
type: 'string',
} },

View File

@ -110,7 +110,7 @@ export default define(meta, paramDef, async (ps, user) => {
if (exist.length) {
if (poll.multiple) {
if (exist.some(x => x.choice === ps.choice)) {
if (exist.some(x => x.choice == ps.choice)) {
throw new ApiError(meta.errors.alreadyVoted);
}
} else {

View File

@ -25,44 +25,21 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
tag: { type: 'string' },
query: { type: 'array', items: {
type: 'array', items: {
type: 'string',
},
} },
reply: { type: 'boolean', nullable: true, default: null },
renote: { type: 'boolean', nullable: true, default: null },
withFiles: {
type: 'boolean',
default: false,
description: 'Only show notes that have attached files.',
},
withFiles: { type: 'boolean' },
poll: { type: 'boolean', nullable: true, default: null },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
},
anyOf: [
{
properties: {
tag: { type: 'string', minLength: 1 },
},
required: ['tag'],
},
{
properties: {
query: {
type: 'array',
description: 'The outer arrays are chained with OR, the inner arrays are chained with AND.',
items: {
type: 'array',
items: {
type: 'string',
minLength: 1,
},
minItems: 1,
},
minItems: 1,
},
},
required: ['query'],
},
],
required: [],
} as const;
// eslint-disable-next-line import/no-default-export

View File

@ -35,11 +35,7 @@ export const paramDef = {
untilId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
offset: { type: 'integer', default: 0 },
host: {
type: 'string',
nullable: true,
description: 'The local host is represented with `null`.',
},
host: { type: 'string', nullable: true },
userId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
channelId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
},

View File

@ -38,11 +38,7 @@ export const paramDef = {
includeMyRenotes: { type: 'boolean', default: true },
includeRenotedMyNotes: { type: 'boolean', default: true },
includeLocalRenotes: { type: 'boolean', default: true },
withFiles: {
type: 'boolean',
default: false,
description: 'Only show notes that have attached files.',
},
withFiles: { type: 'boolean' },
},
required: [],
} as const;

View File

@ -75,8 +75,7 @@ export default define(meta, paramDef, async (ps, user) => {
Accept: 'application/json, */*',
},
body: params,
// TODO
//timeout: 10000,
timeout: 10000,
agent: getAgentByUrl,
});

View File

@ -42,11 +42,7 @@ export const paramDef = {
includeMyRenotes: { type: 'boolean', default: true },
includeRenotedMyNotes: { type: 'boolean', default: true },
includeLocalRenotes: { type: 'boolean', default: true },
withFiles: {
type: 'boolean',
default: false,
description: 'Only show notes that have attached files.',
},
withFiles: { type: 'boolean' },
},
required: ['listId'],
} as const;
@ -63,8 +59,12 @@ export default define(meta, paramDef, async (ps, user) => {
}
//#region Construct query
const listQuery = UserListJoinings.createQueryBuilder('joining')
.select('joining.userId')
.where('joining.userListId = :userListId', { userListId: list.id });
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
.innerJoin(UserListJoinings.metadata.targetName, 'userListJoining', 'userListJoining.userId = note.userId')
.andWhere(`note.userId IN (${ listQuery.getQuery() })`)
.innerJoinAndSelect('note.user', 'user')
.leftJoinAndSelect('user.avatar', 'avatar')
.leftJoinAndSelect('user.banner', 'banner')
@ -76,7 +76,7 @@ export default define(meta, paramDef, async (ps, user) => {
.leftJoinAndSelect('renote.user', 'renoteUser')
.leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar')
.leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner')
.andWhere('userListJoining.userListId = :userListId', { userListId: list.id });
.setParameters(listQuery.getParameters());
generateVisibilityQuery(query, user);

View File

@ -26,21 +26,12 @@ export const meta = {
export const paramDef = {
type: 'object',
anyOf: [
{
properties: {
pageId: { type: 'string', format: 'misskey:id' },
},
required: ['pageId'],
},
{
properties: {
name: { type: 'string' },
username: { type: 'string' },
},
required: ['name', 'username'],
},
],
properties: {
pageId: { type: 'string', format: 'misskey:id' },
name: { type: 'string' },
username: { type: 'string' },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export

View File

@ -38,29 +38,14 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
username: { type: 'string' },
host: { type: 'string', nullable: true },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
},
anyOf: [
{
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
},
{
properties: {
username: { type: 'string' },
host: {
type: 'string',
nullable: true,
description: 'The local host is represented with `null`.',
},
},
required: ['username', 'host'],
},
],
required: [],
} as const;
// eslint-disable-next-line import/no-default-export

View File

@ -38,29 +38,14 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
username: { type: 'string' },
host: { type: 'string', nullable: true },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
},
anyOf: [
{
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
},
{
properties: {
username: { type: 'string' },
host: {
type: 'string',
nullable: true,
description: 'The local host is represented with `null`.',
},
},
required: ['username', 'host'],
},
],
required: [],
} as const;
// eslint-disable-next-line import/no-default-export

View File

@ -28,10 +28,7 @@ export const paramDef = {
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
detail: { type: 'boolean', default: true },
},
anyOf: [
{ required: ['username'] },
{ required: ['host'] },
],
required: [],
} as const;
// TODO: avatar,bannerをJOINしたいけどエラーになる

View File

@ -23,9 +23,9 @@ export const meta = {
items: {
type: 'object',
ref: 'UserDetailed',
},
}
},
],
]
},
errors: {
@ -46,33 +46,15 @@ export const meta = {
export const paramDef = {
type: 'object',
anyOf: [
{
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
},
{
properties: {
userIds: { type: 'array', uniqueItems: true, items: {
type: 'string', format: 'misskey:id',
} },
},
required: ['userIds'],
},
{
properties: {
username: { type: 'string' },
host: {
type: 'string',
nullable: true,
description: 'The local host is represented with `null`.',
},
},
required: ['username'],
},
],
properties: {
userId: { type: 'string', format: 'misskey:id' },
userIds: { type: 'array', uniqueItems: true, items: {
type: 'string', format: 'misskey:id',
} },
username: { type: 'string' },
host: { type: 'string', nullable: true },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export

View File

@ -24,17 +24,17 @@ export default async (ctx: Koa.Context) => {
ctx.body = { error };
}
if (typeof username !== 'string') {
if (typeof username != 'string') {
ctx.status = 400;
return;
}
if (typeof password !== 'string') {
if (typeof password != 'string') {
ctx.status = 400;
return;
}
if (token != null && typeof token !== 'string') {
if (token != null && typeof token != 'string') {
ctx.status = 400;
return;
}

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