Merge branch 'develop' into sw-notification-action

This commit is contained in:
syuilo 2021-03-24 14:44:06 +09:00 committed by GitHub
commit b562e86e4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
166 changed files with 337 additions and 290 deletions

View file

@ -7,6 +7,11 @@ assignees: ''
--- ---
<!--
Thanks for reporting!
First, in order to avoid duplicate Issues, please search to see if the problem you found has already been reported.
-->
## 💡 Summary ## 💡 Summary
<!-- Tell us what the bug is --> <!-- Tell us what the bug is -->

View file

@ -1 +1 @@
see [releases](https://github.com/syuilo/misskey/releases) see [releases](https://github.com/misskey-dev/misskey/releases)

View file

@ -8,7 +8,7 @@
- 温度感高めで見てほしいものは責付いてください。 - 温度感高めで見てほしいものは責付いてください。
## Issues ## Issues
Feature suggestions and bug reports are filed in https://github.com/syuilo/misskey/issues . Feature suggestions and bug reports are filed in https://github.com/misskey-dev/misskey/issues .
* Please search existing issues to avoid duplication. If your issue is already filed, please add your reaction or comment to the existing one. * Please search existing issues to avoid duplication. If your issue is already filed, please add your reaction or comment to the existing one.
* If you have multiple independent issues, please submit them separately. * If you have multiple independent issues, please submit them separately.

View file

@ -4,8 +4,8 @@
<div align="center"> <div align="center">
[![CircleCI](https://img.shields.io/circleci/project/github/syuilo/misskey.svg?style=for-the-badge&logo=circleci)](https://circleci.com/gh/syuilo/misskey) [![CircleCI](https://img.shields.io/circleci/project/github/misskey-dev/misskey.svg?style=for-the-badge&logo=circleci)](https://circleci.com/gh/misskey-dev/misskey)
[![Dependencies](https://img.shields.io/david/syuilo/misskey.svg?style=for-the-badge&logo=npm)](https://david-dm.org/syuilo/misskey) [![Dependencies](https://img.shields.io/david/misskey-dev/misskey.svg?style=for-the-badge&logo=npm)](https://david-dm.org/misskey-dev/misskey)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge&logo=github)](http://makeapullrequest.com) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge&logo=github)](http://makeapullrequest.com)
[![Awesome Humane Tech](https://raw.githubusercontent.com/humanetech-community/awesome-humane-tech/main/humane-tech-badge.svg?sanitize=true)](https://github.com/humanetech-community/awesome-humane-tech) [![Awesome Humane Tech](https://raw.githubusercontent.com/humanetech-community/awesome-humane-tech/main/humane-tech-badge.svg?sanitize=true)](https://github.com/humanetech-community/awesome-humane-tech)
@ -22,11 +22,16 @@ Why don't you take a short break from the hustle and bustle of the city, and div
--- ---
Do you have a question? Or are you experiencing trouble?
Visit [our forum](https://forum.misskey.io/)!
---
![](https://ja.mstdn.wiki/images/e/ed/Deck.jpg) ![](https://ja.mstdn.wiki/images/e/ed/Deck.jpg)
:sparkles: Features :sparkles: Features
---------------------------------------------------------------- ----------------------------------------------------------------
<a href="https://xn--931a.moe/"><img src="https://github.com/syuilo/misskey/blob/develop/assets/ai-orig.png?raw=true" align="right" height="320px"/></a> <a href="https://xn--931a.moe/"><img src="https://github.com/misskey-dev/misskey/blob/develop/assets/ai-orig.png?raw=true" align="right" height="320px"/></a>
<h3>Posting</h3> <h3>Posting</h3>
<p> <p>

View file

@ -12,13 +12,13 @@ This guide describes how to install and setup Misskey with Docker.
---------------------------------------------------------------- ----------------------------------------------------------------
1. Clone Misskey repository's master branch. 1. Clone Misskey repository's master branch.
`git clone -b master git://github.com/syuilo/misskey.git` `git clone -b master git://github.com/misskey-dev/misskey.git`
2. Move to misskey directory. 2. Move to misskey directory.
`cd misskey` `cd misskey`
3. Checkout to the [latest release](https://github.com/syuilo/misskey/releases/latest) tag. 3. Checkout to the [latest release](https://github.com/misskey-dev/misskey/releases/latest) tag.
`git checkout master` `git checkout master`

View file

@ -13,13 +13,13 @@ Ce guide explique comment installer et configurer Misskey avec Docker.
---------------------------------------------------------------- ----------------------------------------------------------------
1. Clone le dépôt de Misskey sur la branche master. 1. Clone le dépôt de Misskey sur la branche master.
`git clone -b master git://github.com/syuilo/misskey.git` `git clone -b master git://github.com/misskey-dev/misskey.git`
2. Naviguez dans le dossier du dépôt. 2. Naviguez dans le dossier du dépôt.
`cd misskey` `cd misskey`
3. Checkout sur le tag de la [dernière version](https://github.com/syuilo/misskey/releases/latest). 3. Checkout sur le tag de la [dernière version](https://github.com/misskey-dev/misskey/releases/latest).
`git checkout master` `git checkout master`

View file

@ -12,13 +12,13 @@ Dockerを使ったMisskey構築方法
---------------------------------------------------------------- ----------------------------------------------------------------
1. masterブランチからMisskeyレポジトリをクローン 1. masterブランチからMisskeyレポジトリをクローン
`git clone -b master git://github.com/syuilo/misskey.git` `git clone -b master git://github.com/misskey-dev/misskey.git`
2. misskeyディレクトリに移動 2. misskeyディレクトリに移動
`cd misskey` `cd misskey`
3. [最新のリリース](https://github.com/syuilo/misskey/releases/latest)を確認 3. [最新のリリース](https://github.com/misskey-dev/misskey/releases/latest)を確認
`git checkout master` `git checkout master`

View file

@ -12,13 +12,13 @@ Docker 部署指南
---------------------------------------------------------------- ----------------------------------------------------------------
1. 克隆 Misskey 项目的 master 分支。 1. 克隆 Misskey 项目的 master 分支。
`git clone -b master git://github.com/syuilo/misskey.git` `git clone -b master git://github.com/misskey-dev/misskey.git`
2. 进入 misskey 文件夹。 2. 进入 misskey 文件夹。
`cd misskey` `cd misskey`
3. 检查 [最新发布版](https://github.com/syuilo/misskey/releases/latest) 标签。 3. 检查 [最新发布版](https://github.com/misskey-dev/misskey/releases/latest) 标签。
`git checkout master` `git checkout master`

View file

@ -40,13 +40,13 @@ Please install and setup these softwares:
2. Clone the misskey repo from master branch. 2. Clone the misskey repo from master branch.
`git clone -b master git://github.com/syuilo/misskey.git` `git clone -b master git://github.com/misskey-dev/misskey.git`
3. Navigate to misskey directory 3. Navigate to misskey directory
`cd misskey` `cd misskey`
4. Checkout to the [latest release](https://github.com/syuilo/misskey/releases/latest) 4. Checkout to the [latest release](https://github.com/misskey-dev/misskey/releases/latest)
`git checkout master` `git checkout master`

View file

@ -41,13 +41,13 @@ Installez les paquets suivants :
2. Clonez la branche master du dépôt misskey. 2. Clonez la branche master du dépôt misskey.
`git clone -b master git://github.com/syuilo/misskey.git` `git clone -b master git://github.com/misskey-dev/misskey.git`
3. Accédez au dossier misskey. 3. Accédez au dossier misskey.
`cd misskey` `cd misskey`
4. Checkout sur le tag de la [version la plus récente](https://github.com/syuilo/misskey/releases/latest) 4. Checkout sur le tag de la [version la plus récente](https://github.com/misskey-dev/misskey/releases/latest)
`git checkout master` `git checkout master`

View file

@ -42,13 +42,13 @@ adduser --disabled-password --disabled-login misskey
2. masterブランチからMisskeyレポジトリをクローン 2. masterブランチからMisskeyレポジトリをクローン
`git clone -b master git://github.com/syuilo/misskey.git` `git clone -b master git://github.com/misskey-dev/misskey.git`
3. misskeyディレクトリに移動 3. misskeyディレクトリに移動
`cd misskey` `cd misskey`
4. [最新のリリース](https://github.com/syuilo/misskey/releases/latest)を確認 4. [最新のリリース](https://github.com/misskey-dev/misskey/releases/latest)を確認
`git checkout master` `git checkout master`

View file

@ -40,13 +40,13 @@ adduser --disabled-password --disabled-login misskey
2. 克隆 Misskey 项目的 master 分支。 2. 克隆 Misskey 项目的 master 分支。
`git clone -b master git://github.com/syuilo/misskey.git` `git clone -b master git://github.com/misskey-dev/misskey.git`
3. 进入 misskey 文件夹。 3. 进入 misskey 文件夹。
`cd misskey` `cd misskey`
4. 检查 [最新发布版](https://github.com/syuilo/misskey/releases/latest) 标签。 4. 检查 [最新发布版](https://github.com/misskey-dev/misskey/releases/latest) 标签。
`git checkout master` `git checkout master`

View file

@ -1,6 +1,6 @@
# **DO NOT edit locale files** except `ja-JP.yml`. # **DO NOT edit locale files** except `ja-JP.yml`.
When you add text to the ja-JP file (of syuilo/misskey), it will automatically be applied to other language files. When you add text to the ja-JP file (of misskey-dev/misskey), it will automatically be applied to other language files.
Translations added in ja-JP file should contain the original Japanese strings. Translations added in ja-JP file should contain the original Japanese strings.
Please see [Contribution guide](../CONTRIBUTING.md) for more information. Please see [Contribution guide](../CONTRIBUTING.md) for more information.

View file

@ -4,8 +4,8 @@ export class AddSomeUrls1557761316509 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> { public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "meta" ADD "ToSUrl" character varying(512)`); await queryRunner.query(`ALTER TABLE "meta" ADD "ToSUrl" character varying(512)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "repositoryUrl" character varying(512) NOT NULL DEFAULT 'https://github.com/syuilo/misskey'`); await queryRunner.query(`ALTER TABLE "meta" ADD "repositoryUrl" character varying(512) NOT NULL DEFAULT 'https://github.com/misskey-dev/misskey'`);
await queryRunner.query(`ALTER TABLE "meta" ADD "feedbackUrl" character varying(512) DEFAULT 'https://github.com/syuilo/misskey/issues/new'`); await queryRunner.query(`ALTER TABLE "meta" ADD "feedbackUrl" character varying(512) DEFAULT 'https://github.com/misskey-dev/misskey/issues/new'`);
} }
public async down(queryRunner: QueryRunner): Promise<any> { public async down(queryRunner: QueryRunner): Promise<any> {

View file

@ -1,11 +1,11 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <syuilotan@yahoo.co.jp>", "author": "syuilo <syuilotan@yahoo.co.jp>",
"version": "12.75.0", "version": "12.75.1",
"codename": "indigo", "codename": "indigo",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/syuilo/misskey.git" "url": "https://github.com/misskey-dev/misskey.git"
}, },
"main": "./index.js", "main": "./index.js",
"private": true, "private": true,
@ -242,7 +242,6 @@
"typeorm": "0.2.31", "typeorm": "0.2.31",
"typescript": "4.2.3", "typescript": "4.2.3",
"ulid": "2.3.0", "ulid": "2.3.0",
"url-loader": "4.1.1",
"uuid": "8.3.2", "uuid": "8.3.2",
"v-debounce": "0.1.2", "v-debounce": "0.1.2",
"vanilla-tilt": "1.7.0", "vanilla-tilt": "1.7.0",

View file

@ -14,7 +14,7 @@
{{ $ts._aboutMisskey.about }} {{ $ts._aboutMisskey.about }}
</section> </section>
<FormGroup> <FormGroup>
<FormLink to="https://github.com/syuilo/misskey" external> <FormLink to="https://github.com/misskey-dev/misskey" external>
<template #icon><Fa :icon="faCode"/></template> <template #icon><Fa :icon="faCode"/></template>
{{ $ts._aboutMisskey.source }} {{ $ts._aboutMisskey.source }}
<template #suffix>GitHub</template> <template #suffix>GitHub</template>
@ -40,7 +40,7 @@
<FormLink to="https://github.com/rinsuki" external>@rinsuki</FormLink> <FormLink to="https://github.com/rinsuki" external>@rinsuki</FormLink>
<FormLink to="https://github.com/Xeltica" external>@Xeltica</FormLink> <FormLink to="https://github.com/Xeltica" external>@Xeltica</FormLink>
<FormLink to="https://github.com/u1-liquid" external>@u1-liquid</FormLink> <FormLink to="https://github.com/u1-liquid" external>@u1-liquid</FormLink>
<template #caption><MkLink url="https://github.com/syuilo/misskey/graphs/contributors">{{ $ts._aboutMisskey.allContributors }}</MkLink></template> <template #caption><MkLink url="https://github.com/misskey-dev/misskey/graphs/contributors">{{ $ts._aboutMisskey.allContributors }}</MkLink></template>
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<template #label><Mfm text="[jelly ❤]"/> {{ $ts._aboutMisskey.patrons }}</template> <template #label><Mfm text="[jelly ❤]"/> {{ $ts._aboutMisskey.patrons }}</template>

View file

@ -3,7 +3,7 @@
<div class="title">{{ title }}</div> <div class="title">{{ title }}</div>
<div class="body" v-html="body"></div> <div class="body" v-html="body"></div>
<div class="footer"> <div class="footer">
<MkLink :url="`https://github.com/syuilo/misskey/blob/master/src/docs/${lang}/${doc}.md`" class="at">{{ $ts.docSource }}</MkLink> <MkLink :url="`https://github.com/misskey-dev/misskey/blob/master/src/docs/${lang}/${doc}.md`" class="at">{{ $ts.docSource }}</MkLink>
</div> </div>
</div> </div>
</template> </template>

View file

@ -79,7 +79,7 @@ export default defineComponent({
localStorage.setItem('v', meta.version); localStorage.setItem('v', meta.version);
}); });
fetch('https://api.github.com/repos/syuilo/misskey/releases', { fetch('https://api.github.com/repos/misskey-dev/misskey/releases', {
method: 'GET', method: 'GET',
}) })
.then(res => res.json()) .then(res => res.json())

View file

@ -32,7 +32,7 @@
</main> </main>
<div class="powered-by"> <div class="powered-by">
<b><MkA to="/">{{ host }}</MkA></b> <b><MkA to="/">{{ host }}</MkA></b>
<small>Powered by <a href="https://github.com/syuilo/misskey" target="_blank">Misskey</a></small> <small>Powered by <a href="https://github.com/misskey-dev/misskey" target="_blank">Misskey</a></small>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,6 +1,6 @@
<template> <template>
<div class="mk-app"> <div class="mk-app">
<a v-if="root" href="https://github.com/syuilo/misskey" target="_blank" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:var(--panel); color:var(--fg); position: fixed; z-index: 10; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a> <a v-if="root" href="https://github.com/misskey-dev/misskey" target="_blank" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:var(--panel); color:var(--fg); position: fixed; z-index: 10; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>
<div class="side" v-if="!narrow && !root"> <div class="side" v-if="!narrow && !root">
<XKanban class="kanban" full/> <XKanban class="kanban" full/>
@ -20,7 +20,7 @@
</main> </main>
<div class="powered-by" v-if="!root"> <div class="powered-by" v-if="!root">
<b><MkA to="/">{{ host }}</MkA></b> <b><MkA to="/">{{ host }}</MkA></b>
<small>Powered by <a href="https://github.com/syuilo/misskey" target="_blank">Misskey</a></small> <small>Powered by <a href="https://github.com/misskey-dev/misskey" target="_blank">Misskey</a></small>
</div> </div>
</div> </div>
</div> </div>

View file

@ -28,7 +28,7 @@
</div> </div>
<div class="powered-by" v-if="poweredBy"> <div class="powered-by" v-if="poweredBy">
<b><MkA to="/">{{ host }}</MkA></b> <b><MkA to="/">{{ host }}</MkA></b>
<small>Powered by <a href="https://github.com/syuilo/misskey" target="_blank">Misskey</a></small> <small>Powered by <a href="https://github.com/misskey-dev/misskey" target="_blank">Misskey</a></small>
</div> </div>
</template> </template>
</div> </div>

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@ Themencodes werden im Format eines JSON5-Objekts gespeichert. Themen werden wie
* `props` ... Definitionen der Themenoptionen.Diese werden im folgenden erläutert. * `props` ... Definitionen der Themenoptionen.Diese werden im folgenden erläutert.
### Definition von Themenoptionen ### Definition von Themenoptionen
Die Optionen des Themas werden in `props` definiert. Die Schlüssel werden zu CSS-Variablen, die Werte geben den Inhalt an. Zusätzlich werden die `props` des gewählten Basisthemas von diesem Thema geerbt. Ist die `base` dieses Themas auf `light` gesetzt, so werden sie aus [_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5) kopiert, ist sie auf `dark` gesetzt, so werden sie aus [_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5) kopiert. Beispielsweise wird, falls sich in den `props` dieses Themas keine Definition für den Schlüssel `panel` befindet, so wird der Wert von `panel` aus dem Basisthema verwendet. Die Optionen des Themas werden in `props` definiert. Die Schlüssel werden zu CSS-Variablen, die Werte geben den Inhalt an. Zusätzlich werden die `props` des gewählten Basisthemas von diesem Thema geerbt. Ist die `base` dieses Themas auf `light` gesetzt, so werden sie aus [_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5) kopiert, ist sie auf `dark` gesetzt, so werden sie aus [_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5) kopiert. Beispielsweise wird, falls sich in den `props` dieses Themas keine Definition für den Schlüssel `panel` befindet, so wird der Wert von `panel` aus dem Basisthema verwendet.
#### Syntax für Wertangaben #### Syntax für Wertangaben
* Hexadezimalfarben * Hexadezimalfarben

View file

@ -43,7 +43,7 @@ Theme codes are saved as a JSON5 object of theme options. Themes are composed of
* `props` ... The style definitions of the theme.These will be explained in the following. * `props` ... The style definitions of the theme.These will be explained in the following.
### Theme style definitions ### Theme style definitions
Define the style of the theme within `props`. The keys will become CSS variables, and the value specifies the content. In addition, the default `props` options are inherited from the base theme. If this theme's `base` is `light`, they will be copied from [_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5), if it is `dark` they will be copied from [_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5). In other words, if there is for example no `panel` key contained in `props`, then the value of `panel` from the base theme will be used. Define the style of the theme within `props`. The keys will become CSS variables, and the value specifies the content. In addition, the default `props` options are inherited from the base theme. If this theme's `base` is `light`, they will be copied from [_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5), if it is `dark` they will be copied from [_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5). In other words, if there is for example no `panel` key contained in `props`, then the value of `panel` from the base theme will be used.
#### Syntax for values #### Syntax for values
* Hex colors * Hex colors

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@ Le code des thèmes est écrit sous forme d'objets JSON5. Les thèmes comprennen
* `props` ... Définir un style de thème.Voir les explications ci-après. * `props` ... Définir un style de thème.Voir les explications ci-après.
### Définir un style de thème ### Définir un style de thème
C'est dans `props` que vous définirez le style de thème. Les propriétés deviendront des variables CSS et les valeurs associées spécifieront le contenu de ces variables. Par ailleurs, les objets présents par défaut dans `props` sont hérités du thème de base. Ainsi, si le thème de `base` est clair `light` ce sera l'objet [_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5) ; et s'il est sombre `dark` ce sera l'objet [_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5). Cela signifie, par exemple, que s'il n'y pas de propriété `panel` définie dans les `props` du thème, alors ce sera la valeur `panel` du thème de base qui sera prise en compte. C'est dans `props` que vous définirez le style de thème. Les propriétés deviendront des variables CSS et les valeurs associées spécifieront le contenu de ces variables. Par ailleurs, les objets présents par défaut dans `props` sont hérités du thème de base. Ainsi, si le thème de `base` est clair `light` ce sera l'objet [_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5) ; et s'il est sombre `dark` ce sera l'objet [_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5). Cela signifie, par exemple, que s'il n'y pas de propriété `panel` définie dans les `props` du thème, alors ce sera la valeur `panel` du thème de base qui sera prise en compte.
#### Syntaxe des valeurs #### Syntaxe des valeurs
* Codes de couleur Hex * Codes de couleur Hex

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@ Il codice dei temi è scritto a forma di oggetti JSON5. I temi contengono gli og
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### Impostare uno stile di tema ### Impostare uno stile di tema
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### Sintassi dei valori #### Sintassi dei valori
* 16進数で表された色 * 16進数で表された色

View file

@ -47,7 +47,7 @@
`props`下にはテーマのスタイルを定義します。 `props`下にはテーマのスタイルを定義します。
キーがCSSの変数名になり、バリューで中身を指定します。 キーがCSSの変数名になり、バリューで中身を指定します。
なお、この`props`オブジェクトはベーステーマから継承されます。 なお、この`props`オブジェクトはベーステーマから継承されます。
ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。
つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@ Kod motywów jest zapisywany jako obiekt JSON5 z opcjami motywu. Motywy składaj
* `props` ... Definicje stylów motywu.これから説明します。 * `props` ... Definicje stylów motywu.これから説明します。
### Definicje stylów motywu. ### Definicje stylów motywu.
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### Składnia wartości #### Składnia wartości
* Kolory Hex * Kolory Hex

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 16進数で表された色 * 16進数で表された色

View file

@ -43,7 +43,7 @@
* `props` ... 关于主题样式的定义,下面是详细介绍。 * `props` ... 关于主题样式的定义,下面是详细介绍。
### 主题样式定义 ### 主题样式定义
`props` 下,你可以定义主题的样式。 键是 CSS 变量名,值是指定的内容。 请注意,`props` 对象是从基础主题集继承的。 如果这个主题的 `base``light`,则基础主题为 [_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5);如果 `dark`,则基础主题为 [_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)。 换句话说,即使这个主题中的 `props` 中没有定义关键的 `panel`,也会继承在基础主题中所拥有 `panel` `props` 下,你可以定义主题的样式。 键是 CSS 变量名,值是指定的内容。 请注意,`props` 对象是从基础主题集继承的。 如果这个主题的 `base``light`,则基础主题为 [_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5);如果 `dark`,则基础主题为 [_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)。 换句话说,即使这个主题中的 `props` 中没有定义关键的 `panel`,也会继承在基础主题中所拥有 `panel`
#### 可以在值中使用的语法 #### 可以在值中使用的语法
* 以十六进制表示的颜色 * 以十六进制表示的颜色

View file

@ -45,7 +45,7 @@
* `props` ... テーマのスタイル定義。これから説明します。 * `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義 ### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 `props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文 #### バリューで使える構文
* 以十六進位色碼標示 * 以十六進位色碼標示

View file

@ -7,8 +7,8 @@
], ],
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"license": "MIT", "license": "MIT",
"repository": "https://github.com/syuilo/misskey.git", "repository": "https://github.com/misskey-dev/misskey.git",
"bugs": "https://github.com/syuilo/misskey/issues", "bugs": "https://github.com/misskey-dev/misskey/issues",
"main": "./built/core.js", "main": "./built/core.js",
"types": "./built/core.d.ts", "types": "./built/core.d.ts",
"scripts": { "scripts": {

View file

@ -1,3 +1,4 @@
import { URL } from 'url';
import config from '@/config'; import config from '@/config';
import { toASCII } from 'punycode'; import { toASCII } from 'punycode';

View file

@ -1,6 +1,7 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as stream from 'stream'; import * as stream from 'stream';
import * as util from 'util'; import * as util from 'util';
import { URL } from 'url';
import fetch from 'node-fetch'; import fetch from 'node-fetch';
import { getAgentByUrl } from './fetch'; import { getAgentByUrl } from './fetch';
import { AbortController } from 'abort-controller'; import { AbortController } from 'abort-controller';

View file

@ -321,14 +321,14 @@ export class Meta {
@Column('varchar', { @Column('varchar', {
length: 512, length: 512,
default: 'https://github.com/syuilo/misskey', default: 'https://github.com/misskey-dev/misskey',
nullable: false nullable: false
}) })
public repositoryUrl: string; public repositoryUrl: string;
@Column('varchar', { @Column('varchar', {
length: 512, length: 512,
default: 'https://github.com/syuilo/misskey/issues/new', default: 'https://github.com/misskey-dev/misskey/issues/new',
nullable: true nullable: true
}) })
public feedbackUrl: string | null; public feedbackUrl: string | null;

View file

@ -9,7 +9,7 @@ export type PackedApp = SchemaType<typeof packedAppSchema>;
export class AppRepository extends Repository<App> { export class AppRepository extends Repository<App> {
public async pack( public async pack(
src: App['id'] | App, src: App['id'] | App,
me?: any, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean, detail?: boolean,
includeSecret?: boolean, includeSecret?: boolean,

View file

@ -2,12 +2,13 @@ import { EntityRepository, Repository } from 'typeorm';
import { Apps } from '..'; import { Apps } from '..';
import { AuthSession } from '../entities/auth-session'; import { AuthSession } from '../entities/auth-session';
import { awaitAll } from '../../prelude/await-all'; import { awaitAll } from '../../prelude/await-all';
import { User } from '../entities/user';
@EntityRepository(AuthSession) @EntityRepository(AuthSession)
export class AuthSessionRepository extends Repository<AuthSession> { export class AuthSessionRepository extends Repository<AuthSession> {
public async pack( public async pack(
src: AuthSession['id'] | AuthSession, src: AuthSession['id'] | AuthSession,
me?: any me?: { id: User['id'] } | null | undefined
) { ) {
const session = typeof src === 'object' ? src : await this.findOneOrFail(src); const session = typeof src === 'object' ? src : await this.findOneOrFail(src);

View file

@ -3,6 +3,7 @@ import { Users } from '..';
import { Blocking } from '../entities/blocking'; import { Blocking } from '../entities/blocking';
import { awaitAll } from '../../prelude/await-all'; import { awaitAll } from '../../prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { User } from '../entities/user';
export type PackedBlocking = SchemaType<typeof packedBlockingSchema>; export type PackedBlocking = SchemaType<typeof packedBlockingSchema>;
@ -10,7 +11,7 @@ export type PackedBlocking = SchemaType<typeof packedBlockingSchema>;
export class BlockingRepository extends Repository<Blocking> { export class BlockingRepository extends Repository<Blocking> {
public async pack( public async pack(
src: Blocking['id'] | Blocking, src: Blocking['id'] | Blocking,
me?: any me?: { id: User['id'] } | null | undefined
): Promise<PackedBlocking> { ): Promise<PackedBlocking> {
const blocking = typeof src === 'object' ? src : await this.findOneOrFail(src); const blocking = typeof src === 'object' ? src : await this.findOneOrFail(src);
@ -26,7 +27,7 @@ export class BlockingRepository extends Repository<Blocking> {
public packMany( public packMany(
blockings: any[], blockings: any[],
me: any me: { id: User['id'] }
) { ) {
return Promise.all(blockings.map(x => this.pack(x, me))); return Promise.all(blockings.map(x => this.pack(x, me)));
} }

View file

@ -10,19 +10,19 @@ export type PackedChannel = SchemaType<typeof packedChannelSchema>;
export class ChannelRepository extends Repository<Channel> { export class ChannelRepository extends Repository<Channel> {
public async pack( public async pack(
src: Channel['id'] | Channel, src: Channel['id'] | Channel,
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
): Promise<PackedChannel> { ): Promise<PackedChannel> {
const channel = typeof src === 'object' ? src : await this.findOneOrFail(src); const channel = typeof src === 'object' ? src : await this.findOneOrFail(src);
const meId = me ? typeof me === 'string' ? me : me.id : null; const meId = me ? me.id : null;
const banner = channel.bannerId ? await DriveFiles.findOne(channel.bannerId) : null; const banner = channel.bannerId ? await DriveFiles.findOne(channel.bannerId) : null;
const hasUnreadNote = me ? (await NoteUnreads.findOne({ noteChannelId: channel.id, userId: meId })) != null : undefined; const hasUnreadNote = meId ? (await NoteUnreads.findOne({ noteChannelId: channel.id, userId: meId })) != null : undefined;
const following = await ChannelFollowings.findOne({ const following = meId ? await ChannelFollowings.findOne({
followerId: meId, followerId: meId,
followeeId: channel.id, followeeId: channel.id,
}); }) : null;
return { return {
id: channel.id, id: channel.id,

View file

@ -53,7 +53,7 @@ export class DriveFileRepository extends Repository<DriveFile> {
return thumbnail ? (file.thumbnailUrl || (isImage ? (file.webpublicUrl || file.url) : null)) : (file.webpublicUrl || file.url); return thumbnail ? (file.thumbnailUrl || (isImage ? (file.webpublicUrl || file.url) : null)) : (file.webpublicUrl || file.url);
} }
public async calcDriveUsageOf(user: User['id'] | User): Promise<number> { public async calcDriveUsageOf(user: User['id'] | { id: User['id'] }): Promise<number> {
const id = typeof user === 'object' ? user.id : user; const id = typeof user === 'object' ? user.id : user;
const { sum } = await this const { sum } = await this

View file

@ -1,12 +1,13 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { FollowRequest } from '../entities/follow-request'; import { FollowRequest } from '../entities/follow-request';
import { Users } from '..'; import { Users } from '..';
import { User } from '../entities/user';
@EntityRepository(FollowRequest) @EntityRepository(FollowRequest)
export class FollowRequestRepository extends Repository<FollowRequest> { export class FollowRequestRepository extends Repository<FollowRequest> {
public async pack( public async pack(
src: FollowRequest['id'] | FollowRequest, src: FollowRequest['id'] | FollowRequest,
me?: any me?: { id: User['id'] } | null | undefined
) { ) {
const request = typeof src === 'object' ? src : await this.findOneOrFail(src); const request = typeof src === 'object' ? src : await this.findOneOrFail(src);

View file

@ -3,6 +3,7 @@ import { Users } from '..';
import { Following } from '../entities/following'; import { Following } from '../entities/following';
import { awaitAll } from '../../prelude/await-all'; import { awaitAll } from '../../prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { User } from '../entities/user';
type LocalFollowerFollowing = Following & { type LocalFollowerFollowing = Following & {
followerHost: null; followerHost: null;
@ -50,7 +51,7 @@ export class FollowingRepository extends Repository<Following> {
public async pack( public async pack(
src: Following['id'] | Following, src: Following['id'] | Following,
me?: any, me?: { id: User['id'] } | null | undefined,
opts?: { opts?: {
populateFollowee?: boolean; populateFollowee?: boolean;
populateFollower?: boolean; populateFollower?: boolean;
@ -76,7 +77,7 @@ export class FollowingRepository extends Repository<Following> {
public packMany( public packMany(
followings: any[], followings: any[],
me?: any, me?: { id: User['id'] } | null | undefined,
opts?: { opts?: {
populateFollowee?: boolean; populateFollowee?: boolean;
populateFollower?: boolean; populateFollower?: boolean;

View file

@ -1,3 +1,4 @@
import { User } from '@/models/entities/user';
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { Users } from '../../..'; import { Users } from '../../..';
import { ReversiGame } from '../../../entities/games/reversi/game'; import { ReversiGame } from '../../../entities/games/reversi/game';
@ -6,7 +7,7 @@ import { ReversiGame } from '../../../entities/games/reversi/game';
export class ReversiGameRepository extends Repository<ReversiGame> { export class ReversiGameRepository extends Repository<ReversiGame> {
public async pack( public async pack(
src: ReversiGame['id'] | ReversiGame, src: ReversiGame['id'] | ReversiGame,
me?: any, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean detail?: boolean
} }
@ -16,7 +17,6 @@ export class ReversiGameRepository extends Repository<ReversiGame> {
}, options); }, options);
const game = typeof src === 'object' ? src : await this.findOneOrFail(src); const game = typeof src === 'object' ? src : await this.findOneOrFail(src);
const meId = me ? typeof me === 'string' ? me : me.id : null;
return { return {
id: game.id, id: game.id,
@ -30,10 +30,10 @@ export class ReversiGameRepository extends Repository<ReversiGame> {
user2Accepted: game.user2Accepted, user2Accepted: game.user2Accepted,
user1Id: game.user1Id, user1Id: game.user1Id,
user2Id: game.user2Id, user2Id: game.user2Id,
user1: await Users.pack(game.user1Id, meId), user1: await Users.pack(game.user1Id, me),
user2: await Users.pack(game.user2Id, meId), user2: await Users.pack(game.user2Id, me),
winnerId: game.winnerId, winnerId: game.winnerId,
winner: game.winnerId ? await Users.pack(game.winnerId, meId) : null, winner: game.winnerId ? await Users.pack(game.winnerId, me) : null,
surrendered: game.surrendered, surrendered: game.surrendered,
black: game.black, black: game.black,
bw: game.bw, bw: game.bw,

View file

@ -2,12 +2,13 @@ import { EntityRepository, Repository } from 'typeorm';
import { ReversiMatching } from '../../../entities/games/reversi/matching'; import { ReversiMatching } from '../../../entities/games/reversi/matching';
import { Users } from '../../..'; import { Users } from '../../..';
import { awaitAll } from '../../../../prelude/await-all'; import { awaitAll } from '../../../../prelude/await-all';
import { User } from '@/models/entities/user';
@EntityRepository(ReversiMatching) @EntityRepository(ReversiMatching)
export class ReversiMatchingRepository extends Repository<ReversiMatching> { export class ReversiMatchingRepository extends Repository<ReversiMatching> {
public async pack( public async pack(
src: ReversiMatching['id'] | ReversiMatching, src: ReversiMatching['id'] | ReversiMatching,
me: any me: { id: User['id'] }
) { ) {
const matching = typeof src === 'object' ? src : await this.findOneOrFail(src); const matching = typeof src === 'object' ? src : await this.findOneOrFail(src);

View file

@ -2,6 +2,7 @@ import { EntityRepository, Repository } from 'typeorm';
import { MessagingMessage } from '../entities/messaging-message'; import { MessagingMessage } from '../entities/messaging-message';
import { Users, DriveFiles, UserGroups } from '..'; import { Users, DriveFiles, UserGroups } from '..';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { User } from '../entities/user';
export type PackedMessagingMessage = SchemaType<typeof packedMessagingMessageSchema>; export type PackedMessagingMessage = SchemaType<typeof packedMessagingMessageSchema>;
@ -13,7 +14,7 @@ export class MessagingMessageRepository extends Repository<MessagingMessage> {
public async pack( public async pack(
src: MessagingMessage['id'] | MessagingMessage, src: MessagingMessage['id'] | MessagingMessage,
me?: any, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
populateRecipient?: boolean, populateRecipient?: boolean,
populateGroup?: boolean, populateGroup?: boolean,

View file

@ -3,6 +3,7 @@ import { Users } from '..';
import { Muting } from '../entities/muting'; import { Muting } from '../entities/muting';
import { awaitAll } from '../../prelude/await-all'; import { awaitAll } from '../../prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { User } from '../entities/user';
export type PackedMuting = SchemaType<typeof packedMutingSchema>; export type PackedMuting = SchemaType<typeof packedMutingSchema>;
@ -10,7 +11,7 @@ export type PackedMuting = SchemaType<typeof packedMutingSchema>;
export class MutingRepository extends Repository<Muting> { export class MutingRepository extends Repository<Muting> {
public async pack( public async pack(
src: Muting['id'] | Muting, src: Muting['id'] | Muting,
me?: any me?: { id: User['id'] } | null | undefined
): Promise<PackedMuting> { ): Promise<PackedMuting> {
const muting = typeof src === 'object' ? src : await this.findOneOrFail(src); const muting = typeof src === 'object' ? src : await this.findOneOrFail(src);
@ -26,7 +27,7 @@ export class MutingRepository extends Repository<Muting> {
public packMany( public packMany(
mutings: any[], mutings: any[],
me: any me: { id: User['id'] }
) { ) {
return Promise.all(mutings.map(x => this.pack(x, me))); return Promise.all(mutings.map(x => this.pack(x, me)));
} }

View file

@ -1,12 +1,13 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { NoteFavorite } from '../entities/note-favorite'; import { NoteFavorite } from '../entities/note-favorite';
import { Notes } from '..'; import { Notes } from '..';
import { User } from '../entities/user';
@EntityRepository(NoteFavorite) @EntityRepository(NoteFavorite)
export class NoteFavoriteRepository extends Repository<NoteFavorite> { export class NoteFavoriteRepository extends Repository<NoteFavorite> {
public async pack( public async pack(
src: NoteFavorite['id'] | NoteFavorite, src: NoteFavorite['id'] | NoteFavorite,
me?: any me?: { id: User['id'] } | null | undefined
) { ) {
const favorite = typeof src === 'object' ? src : await this.findOneOrFail(src); const favorite = typeof src === 'object' ? src : await this.findOneOrFail(src);
@ -20,7 +21,7 @@ export class NoteFavoriteRepository extends Repository<NoteFavorite> {
public packMany( public packMany(
favorites: any[], favorites: any[],
me: any me: { id: User['id'] }
) { ) {
return Promise.all(favorites.map(x => this.pack(x, me))); return Promise.all(favorites.map(x => this.pack(x, me)));
} }

View file

@ -3,6 +3,7 @@ import { NoteReaction } from '../entities/note-reaction';
import { Users } from '..'; import { Users } from '..';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { convertLegacyReaction } from '@/misc/reaction-lib'; import { convertLegacyReaction } from '@/misc/reaction-lib';
import { User } from '../entities/user';
export type PackedNoteReaction = SchemaType<typeof packedNoteReactionSchema>; export type PackedNoteReaction = SchemaType<typeof packedNoteReactionSchema>;
@ -10,7 +11,7 @@ export type PackedNoteReaction = SchemaType<typeof packedNoteReactionSchema>;
export class NoteReactionRepository extends Repository<NoteReaction> { export class NoteReactionRepository extends Repository<NoteReaction> {
public async pack( public async pack(
src: NoteReaction['id'] | NoteReaction, src: NoteReaction['id'] | NoteReaction,
me?: any me?: { id: User['id'] } | null | undefined
): Promise<PackedNoteReaction> { ): Promise<PackedNoteReaction> {
const reaction = typeof src === 'object' ? src : await this.findOneOrFail(src); const reaction = typeof src === 'object' ? src : await this.findOneOrFail(src);

View file

@ -79,7 +79,7 @@ export class NoteRepository extends Repository<Note> {
public async pack( public async pack(
src: Note['id'] | Note, src: Note['id'] | Note,
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean; detail?: boolean;
skipHide?: boolean; skipHide?: boolean;
@ -93,7 +93,7 @@ export class NoteRepository extends Repository<Note> {
skipHide: false skipHide: false
}, options); }, options);
const meId = me ? typeof me === 'string' ? me : me.id : null; const meId = me ? me.id : null;
const note = typeof src === 'object' ? src : await this.findOneOrFail(src); const note = typeof src === 'object' ? src : await this.findOneOrFail(src);
const host = note.userHost; const host = note.userHost;
@ -174,7 +174,7 @@ export class NoteRepository extends Repository<Note> {
id: note.id, id: note.id,
createdAt: note.createdAt.toISOString(), createdAt: note.createdAt.toISOString(),
userId: note.userId, userId: note.userId,
user: Users.pack(note.user || note.userId, meId, { user: Users.pack(note.user || note.userId, me, {
detail: false, detail: false,
}), }),
text: text, text: text,
@ -204,12 +204,12 @@ export class NoteRepository extends Repository<Note> {
_prId_: (note as any)._prId_ || undefined, _prId_: (note as any)._prId_ || undefined,
...(opts.detail ? { ...(opts.detail ? {
reply: note.replyId ? this.pack(note.reply || note.replyId, meId, { reply: note.replyId ? this.pack(note.reply || note.replyId, me, {
detail: false, detail: false,
_hint_: options?._hint_ _hint_: options?._hint_
}) : undefined, }) : undefined,
renote: note.renoteId ? this.pack(note.renote || note.renoteId, meId, { renote: note.renoteId ? this.pack(note.renote || note.renoteId, me, {
detail: true, detail: true,
_hint_: options?._hint_ _hint_: options?._hint_
}) : undefined, }) : undefined,
@ -236,7 +236,7 @@ export class NoteRepository extends Repository<Note> {
public async packMany( public async packMany(
notes: Note[], notes: Note[],
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean; detail?: boolean;
skipHide?: boolean; skipHide?: boolean;
@ -244,7 +244,7 @@ export class NoteRepository extends Repository<Note> {
) { ) {
if (notes.length === 0) return []; if (notes.length === 0) return [];
const meId = me ? typeof me === 'string' ? me : me.id : null; const meId = me ? me.id : null;
const myReactionsMap = new Map<Note['id'], NoteReaction | null>(); const myReactionsMap = new Map<Note['id'], NoteReaction | null>();
if (meId) { if (meId) {
const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!); const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!);

View file

@ -31,38 +31,38 @@ export class NotificationRepository extends Repository<Notification> {
userId: notification.notifierId, userId: notification.notifierId,
user: notification.notifierId ? Users.pack(notification.notifier || notification.notifierId) : null, user: notification.notifierId ? Users.pack(notification.notifier || notification.notifierId) : null,
...(notification.type === 'mention' ? { ...(notification.type === 'mention' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),
} : {}), } : {}),
...(notification.type === 'reply' ? { ...(notification.type === 'reply' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),
} : {}), } : {}),
...(notification.type === 'renote' ? { ...(notification.type === 'renote' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),
} : {}), } : {}),
...(notification.type === 'quote' ? { ...(notification.type === 'quote' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),
} : {}), } : {}),
...(notification.type === 'reaction' ? { ...(notification.type === 'reaction' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),
reaction: notification.reaction reaction: notification.reaction
} : {}), } : {}),
...(notification.type === 'pollVote' ? { ...(notification.type === 'pollVote' ? {
note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, { note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, {
detail: true, detail: true,
_hint_: options._hintForEachNotes_ _hint_: options._hintForEachNotes_
}), }),

View file

@ -1,12 +1,13 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { PageLike } from '../entities/page-like'; import { PageLike } from '../entities/page-like';
import { Pages } from '..'; import { Pages } from '..';
import { User } from '../entities/user';
@EntityRepository(PageLike) @EntityRepository(PageLike)
export class PageLikeRepository extends Repository<PageLike> { export class PageLikeRepository extends Repository<PageLike> {
public async pack( public async pack(
src: PageLike['id'] | PageLike, src: PageLike['id'] | PageLike,
me?: any me?: { id: User['id'] } | null | undefined
) { ) {
const like = typeof src === 'object' ? src : await this.findOneOrFail(src); const like = typeof src === 'object' ? src : await this.findOneOrFail(src);
@ -18,7 +19,7 @@ export class PageLikeRepository extends Repository<PageLike> {
public packMany( public packMany(
likes: any[], likes: any[],
me: any me: { id: User['id'] }
) { ) {
return Promise.all(likes.map(x => this.pack(x, me))); return Promise.all(likes.map(x => this.pack(x, me)));
} }

View file

@ -12,9 +12,9 @@ export type PackedPage = SchemaType<typeof packedPageSchema>;
export class PageRepository extends Repository<Page> { export class PageRepository extends Repository<Page> {
public async pack( public async pack(
src: Page['id'] | Page, src: Page['id'] | Page,
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
): Promise<PackedPage> { ): Promise<PackedPage> {
const meId = me ? typeof me === 'string' ? me : me.id : null; const meId = me ? me.id : null;
const page = typeof src === 'object' ? src : await this.findOneOrFail(src); const page = typeof src === 'object' ? src : await this.findOneOrFail(src);
const attachedFiles: Promise<DriveFile | undefined>[] = []; const attachedFiles: Promise<DriveFile | undefined>[] = [];
@ -84,7 +84,7 @@ export class PageRepository extends Repository<Page> {
public packMany( public packMany(
pages: Page[], pages: Page[],
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
) { ) {
return Promise.all(pages.map(x => this.pack(x, me))); return Promise.all(pages.map(x => this.pack(x, me)));
} }

View file

@ -147,7 +147,7 @@ export class UserRepository extends Repository<User> {
public async pack( public async pack(
src: User['id'] | User, src: User['id'] | User,
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean, detail?: boolean,
includeSecrets?: boolean, includeSecrets?: boolean,
@ -159,7 +159,7 @@ export class UserRepository extends Repository<User> {
}, options); }, options);
const user = typeof src === 'object' ? src : await this.findOneOrFail(src); const user = typeof src === 'object' ? src : await this.findOneOrFail(src);
const meId = me ? typeof me === 'string' ? me : me.id : null; const meId = me ? me.id : null;
const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null; const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null;
const pins = opts.detail ? await UserNotePinings.createQueryBuilder('pin') const pins = opts.detail ? await UserNotePinings.createQueryBuilder('pin')
@ -213,11 +213,11 @@ export class UserRepository extends Repository<User> {
followingCount: user.followingCount, followingCount: user.followingCount,
notesCount: user.notesCount, notesCount: user.notesCount,
pinnedNoteIds: pins.map(pin => pin.noteId), pinnedNoteIds: pins.map(pin => pin.noteId),
pinnedNotes: Notes.packMany(pins.map(pin => pin.note!), meId, { pinnedNotes: Notes.packMany(pins.map(pin => pin.note!), me, {
detail: true detail: true
}), }),
pinnedPageId: profile!.pinnedPageId, pinnedPageId: profile!.pinnedPageId,
pinnedPage: profile!.pinnedPageId ? Pages.pack(profile!.pinnedPageId, meId) : null, pinnedPage: profile!.pinnedPageId ? Pages.pack(profile!.pinnedPageId, me) : null,
twoFactorEnabled: profile!.twoFactorEnabled, twoFactorEnabled: profile!.twoFactorEnabled,
usePasswordLessLogin: profile!.usePasswordLessLogin, usePasswordLessLogin: profile!.usePasswordLessLogin,
securityKeys: profile!.twoFactorEnabled securityKeys: profile!.twoFactorEnabled
@ -286,7 +286,7 @@ export class UserRepository extends Repository<User> {
public packMany( public packMany(
users: (User['id'] | User)[], users: (User['id'] | User)[],
me?: User['id'] | User | null | undefined, me?: { id: User['id'] } | null | undefined,
options?: { options?: {
detail?: boolean, detail?: boolean,
includeSecrets?: boolean, includeSecrets?: boolean,
@ -295,11 +295,15 @@ export class UserRepository extends Repository<User> {
return Promise.all(users.map(u => this.pack(u, me, options))); return Promise.all(users.map(u => this.pack(u, me, options)));
} }
public isLocalUser(user: User): user is ILocalUser { public isLocalUser(user: User): user is ILocalUser;
public isLocalUser<T extends { host: User['host'] }>(user: T): user is T & { host: null; };
public isLocalUser(user: User | { host: User['host'] }): boolean {
return user.host == null; return user.host == null;
} }
public isRemoteUser(user: User): user is IRemoteUser { public isRemoteUser(user: User): user is IRemoteUser;
public isRemoteUser<T extends { host: User['host'] }>(user: T): user is T & { host: string; };
public isRemoteUser(user: User | { host: User['host'] }): boolean {
return !this.isLocalUser(user); return !this.isLocalUser(user);
} }

View file

@ -1,7 +1,7 @@
import * as httpSignature from 'http-signature'; import * as httpSignature from 'http-signature';
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../models/entities/user'; import { User } from '../models/entities/user';
import { program } from '../argv'; import { program } from '../argv';
import processDeliver from './processors/deliver'; import processDeliver from './processors/deliver';
@ -65,7 +65,7 @@ objectStorageQueue
.on('error', (job: any, err: Error) => objectStorageLogger.error(`error ${err}`, { job, e: renderError(err) })) .on('error', (job: any, err: Error) => objectStorageLogger.error(`error ${err}`, { job, e: renderError(err) }))
.on('stalled', (job) => objectStorageLogger.warn(`stalled id=${job.id}`)); .on('stalled', (job) => objectStorageLogger.warn(`stalled id=${job.id}`));
export function deliver(user: ILocalUser, content: any, to: any) { export function deliver(user: { id: User['id']; host: null; }, content: any, to: any) {
if (content == null) return null; if (content == null) return null;
const data = { const data = {
@ -102,7 +102,7 @@ export function inbox(activity: any, signature: httpSignature.IParsedSignature)
}); });
} }
export function createDeleteDriveFilesJob(user: ILocalUser) { export function createDeleteDriveFilesJob(user: { id: User['id'] }) {
return dbQueue.add('deleteDriveFiles', { return dbQueue.add('deleteDriveFiles', {
user: user user: user
}, { }, {
@ -111,7 +111,7 @@ export function createDeleteDriveFilesJob(user: ILocalUser) {
}); });
} }
export function createExportNotesJob(user: ILocalUser) { export function createExportNotesJob(user: { id: User['id'] }) {
return dbQueue.add('exportNotes', { return dbQueue.add('exportNotes', {
user: user user: user
}, { }, {
@ -120,7 +120,7 @@ export function createExportNotesJob(user: ILocalUser) {
}); });
} }
export function createExportFollowingJob(user: ILocalUser) { export function createExportFollowingJob(user: { id: User['id'] }) {
return dbQueue.add('exportFollowing', { return dbQueue.add('exportFollowing', {
user: user user: user
}, { }, {
@ -129,7 +129,7 @@ export function createExportFollowingJob(user: ILocalUser) {
}); });
} }
export function createExportMuteJob(user: ILocalUser) { export function createExportMuteJob(user: { id: User['id'] }) {
return dbQueue.add('exportMute', { return dbQueue.add('exportMute', {
user: user user: user
}, { }, {
@ -138,7 +138,7 @@ export function createExportMuteJob(user: ILocalUser) {
}); });
} }
export function createExportBlockingJob(user: ILocalUser) { export function createExportBlockingJob(user: { id: User['id'] }) {
return dbQueue.add('exportBlocking', { return dbQueue.add('exportBlocking', {
user: user user: user
}, { }, {
@ -147,7 +147,7 @@ export function createExportBlockingJob(user: ILocalUser) {
}); });
} }
export function createExportUserListsJob(user: ILocalUser) { export function createExportUserListsJob(user: { id: User['id'] }) {
return dbQueue.add('exportUserLists', { return dbQueue.add('exportUserLists', {
user: user user: user
}, { }, {
@ -156,7 +156,7 @@ export function createExportUserListsJob(user: ILocalUser) {
}); });
} }
export function createImportFollowingJob(user: ILocalUser, fileId: DriveFile['id']) { export function createImportFollowingJob(user: { id: User['id'] }, fileId: DriveFile['id']) {
return dbQueue.add('importFollowing', { return dbQueue.add('importFollowing', {
user: user, user: user,
fileId: fileId fileId: fileId
@ -166,7 +166,7 @@ export function createImportFollowingJob(user: ILocalUser, fileId: DriveFile['id
}); });
} }
export function createImportUserListsJob(user: ILocalUser, fileId: DriveFile['id']) { export function createImportUserListsJob(user: { id: User['id'] }, fileId: DriveFile['id']) {
return dbQueue.add('importUserLists', { return dbQueue.add('importUserLists', {
user: user, user: user,
fileId: fileId fileId: fileId

View file

@ -1,3 +1,4 @@
import { URL } from 'url';
import * as Bull from 'bull'; import * as Bull from 'bull';
import request from '../../remote/activitypub/request'; import request from '../../remote/activitypub/request';
import { registerOrFetchInstanceDoc } from '../../services/register-or-fetch-instance-doc'; import { registerOrFetchInstanceDoc } from '../../services/register-or-fetch-instance-doc';

View file

@ -1,3 +1,4 @@
import { URL } from 'url';
import * as Bull from 'bull'; import * as Bull from 'bull';
import * as httpSignature from 'http-signature'; import * as httpSignature from 'http-signature';
import perform from '../../remote/activitypub/perform'; import perform from '../../remote/activitypub/perform';

View file

@ -1,5 +1,5 @@
import { Users, Followings } from '../../models'; import { Users, Followings } from '../../models';
import { ILocalUser, IRemoteUser } from '../../models/entities/user'; import { ILocalUser, IRemoteUser, User } from '../../models/entities/user';
import { deliver } from '../../queue'; import { deliver } from '../../queue';
//#region types //#region types
@ -24,7 +24,7 @@ const isDirect = (recipe: any): recipe is IDirectRecipe =>
//#endregion //#endregion
export default class DeliverManager { export default class DeliverManager {
private actor: ILocalUser; private actor: { id: User['id']; host: null; };
private activity: any; private activity: any;
private recipes: IRecipe[] = []; private recipes: IRecipe[] = [];
@ -33,7 +33,7 @@ export default class DeliverManager {
* @param actor Actor * @param actor Actor
* @param activity Activity to deliver * @param activity Activity to deliver
*/ */
constructor(actor: ILocalUser, activity: any) { constructor(actor: { id: User['id']; host: null; }, activity: any) {
this.actor = actor; this.actor = actor;
this.activity = activity; this.activity = activity;
} }

View file

@ -1,3 +1,4 @@
import { URL } from 'url';
import * as promiseLimit from 'promise-limit'; import * as promiseLimit from 'promise-limit';
import config from '@/config'; import config from '@/config';

View file

@ -1,7 +1,7 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '@/models/entities/user';
export default (object: any, user: ILocalUser) => ({ export default (object: any, user: { id: User['id']; host: null }) => ({
type: 'Accept', type: 'Accept',
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
object object

View file

@ -1,7 +1,7 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '../../../models/entities/user';
export default (object: any, user: ILocalUser) => ({ export default (object: any, user: { id: User['id']; host: null }) => ({
type: 'Delete', type: 'Delete',
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
object object

View file

@ -2,7 +2,7 @@ import config from '@/config';
import { User } from '../../../models/entities/user'; import { User } from '../../../models/entities/user';
import { Users } from '../../../models'; import { Users } from '../../../models';
export default (follower: User, followee: User, requestId?: string) => { export default (follower: { id: User['id']; host: User['host']; uri: User['host'] }, followee: { id: User['id']; host: User['host']; uri: User['host'] }, requestId?: string) => {
const follow = { const follow = {
type: 'Follow', type: 'Follow',
actor: Users.isLocalUser(follower) ? `${config.url}/users/${follower.id}` : follower.uri, actor: Users.isLocalUser(follower) ? `${config.url}/users/${follower.id}` : follower.uri,

View file

@ -2,8 +2,8 @@ import config from '@/config';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { IActivity } from '../type'; import { IActivity } from '../type';
import { LdSignature } from '../misc/ld-signature'; import { LdSignature } from '../misc/ld-signature';
import { ILocalUser } from '../../../models/entities/user';
import { getUserKeypair } from '@/misc/keypair-store'; import { getUserKeypair } from '@/misc/keypair-store';
import { User } from '@/models/entities/user';
export const renderActivity = (x: any): IActivity | null => { export const renderActivity = (x: any): IActivity | null => {
if (x == null) return null; if (x == null) return null;
@ -20,7 +20,7 @@ export const renderActivity = (x: any): IActivity | null => {
}, x); }, x);
}; };
export const attachLdSignature = async (activity: any, user: ILocalUser): Promise<IActivity | null> => { export const attachLdSignature = async (activity: any, user: { id: User['id']; host: null; }): Promise<IActivity | null> => {
if (activity == null) return null; if (activity == null) return null;
const keypair = await getUserKeypair(user.id); const keypair = await getUserKeypair(user.id);

View file

@ -1,3 +1,4 @@
import { URL } from 'url';
import renderImage from './image'; import renderImage from './image';
import renderKey from './key'; import renderKey from './key';
import config from '@/config'; import config from '@/config';

View file

@ -1,9 +1,9 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '@/models/entities/user';
import { Note } from '../../../models/entities/note'; import { Note } from '../../../models/entities/note';
import { Poll } from '../../../models/entities/poll'; import { Poll } from '../../../models/entities/poll';
export default async function renderQuestion(user: ILocalUser, note: Note, poll: Poll) { export default async function renderQuestion(user: { id: User['id'] }, note: Note, poll: Poll) {
const question = { const question = {
type: 'Question', type: 'Question',
id: `${config.url}/questions/${note.id}`, id: `${config.url}/questions/${note.id}`,

View file

@ -1,8 +1,8 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '@/models/entities/user';
import { MessagingMessage } from '../../../models/entities/messaging-message'; import { MessagingMessage } from '../../../models/entities/messaging-message';
export const renderReadActivity = (user: ILocalUser, message: MessagingMessage) => ({ export const renderReadActivity = (user: { id: User['id'] }, message: MessagingMessage) => ({
type: 'Read', type: 'Read',
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
object: message.uri object: message.uri

View file

@ -1,7 +1,7 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '@/models/entities/user';
export default (object: any, user: ILocalUser) => ({ export default (object: any, user: { id: User['id'] }) => ({
type: 'Reject', type: 'Reject',
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
object object

View file

@ -1,7 +1,7 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '@/models/entities/user';
export default (user: ILocalUser, target: any, object: any) => ({ export default (user: { id: User['id'] }, target: any, object: any) => ({
type: 'Remove', type: 'Remove',
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
target, target,

View file

@ -1,7 +1,7 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser, User } from '../../../models/entities/user'; import { ILocalUser, User } from '../../../models/entities/user';
export default (object: any, user: ILocalUser | User) => ({ export default (object: any, user: { id: User['id'] }) => ({
type: 'Undo', type: 'Undo',
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
object object

View file

@ -1,7 +1,7 @@
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../../models/entities/user'; import { User } from '@/models/entities/user';
export default (object: any, user: ILocalUser) => { export default (object: any, user: { id: User['id'] }) => {
const activity = { const activity = {
id: `${config.url}/users/${user.id}#updates/${new Date().getTime()}`, id: `${config.url}/users/${user.id}#updates/${new Date().getTime()}`,
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,

View file

@ -1,10 +1,10 @@
import config from '@/config'; import config from '@/config';
import { Note } from '../../../models/entities/note'; import { Note } from '../../../models/entities/note';
import { IRemoteUser, ILocalUser } from '../../../models/entities/user'; import { IRemoteUser, User } from '../../../models/entities/user';
import { PollVote } from '../../../models/entities/poll-vote'; import { PollVote } from '../../../models/entities/poll-vote';
import { Poll } from '../../../models/entities/poll'; import { Poll } from '../../../models/entities/poll';
export default async function renderVote(user: ILocalUser, vote: PollVote, note: Note, poll: Poll, pollOwner: IRemoteUser): Promise<any> { export default async function renderVote(user: { id: User['id'] }, vote: PollVote, note: Note, poll: Poll, pollOwner: IRemoteUser): Promise<any> {
return { return {
id: `${config.url}/users/${user.id}#votes/${vote.id}/activity`, id: `${config.url}/users/${user.id}#votes/${vote.id}/activity`,
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,

View file

@ -4,14 +4,14 @@ import { sign } from 'http-signature';
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import config from '@/config'; import config from '@/config';
import { ILocalUser } from '../../models/entities/user'; import { User } from '@/models/entities/user';
import { getAgentByUrl } from '@/misc/fetch'; import { getAgentByUrl } from '@/misc/fetch';
import { URL } from 'url'; import { URL } from 'url';
import got from 'got'; import got from 'got';
import * as Got from 'got'; import * as Got from 'got';
import { getUserKeypair } from '@/misc/keypair-store'; import { getUserKeypair } from '@/misc/keypair-store';
export default async (user: ILocalUser, url: string, object: any) => { export default async (user: { id: User['id'] }, url: string, object: any) => {
const timeout = 10 * 1000; const timeout = 10 * 1000;
const { protocol, hostname, port, pathname, search } = new URL(url); const { protocol, hostname, port, pathname, search } = new URL(url);
@ -24,7 +24,7 @@ export default async (user: ILocalUser, url: string, object: any) => {
const keypair = await getUserKeypair(user.id); const keypair = await getUserKeypair(user.id);
await new Promise((resolve, reject) => { await new Promise<void>((resolve, reject) => {
const req = https.request({ const req = https.request({
agent: getAgentByUrl(new URL(`https://example.net`)), agent: getAgentByUrl(new URL(`https://example.net`)),
protocol, protocol,
@ -69,7 +69,7 @@ export default async (user: ILocalUser, url: string, object: any) => {
* @param user http-signature user * @param user http-signature user
* @param url URL to fetch * @param url URL to fetch
*/ */
export async function signedGet(url: string, user: ILocalUser) { export async function signedGet(url: string, user: { id: User['id'] }) {
const timeout = 10 * 1000; const timeout = 10 * 1000;
const keypair = await getUserKeypair(user.id); const keypair = await getUserKeypair(user.id);

View file

@ -1,3 +1,4 @@
import { URL } from 'url';
import webFinger from './webfinger'; import webFinger from './webfinger';
import config from '@/config'; import config from '@/config';
import { createPerson, updatePerson } from './activitypub/models/person'; import { createPerson, updatePerson } from './activitypub/models/person';

View file

@ -1,3 +1,4 @@
import { URL } from 'url';
import { getJson } from '@/misc/fetch'; import { getJson } from '@/misc/fetch';
import { query as urlQuery } from '../prelude/url'; import { query as urlQuery } from '../prelude/url';

View file

@ -2,7 +2,7 @@ import { User } from '../../../models/entities/user';
import { Blockings } from '../../../models'; import { Blockings } from '../../../models';
import { SelectQueryBuilder } from 'typeorm'; import { SelectQueryBuilder } from 'typeorm';
export function generateBlockQueryForUsers(q: SelectQueryBuilder<any>, me: User) { export function generateBlockQueryForUsers(q: SelectQueryBuilder<any>, me: { id: User['id'] }) {
const blockingQuery = Blockings.createQueryBuilder('blocking') const blockingQuery = Blockings.createQueryBuilder('blocking')
.select('blocking.blockeeId') .select('blocking.blockeeId')
.where('blocking.blockerId = :blockerId', { blockerId: me.id }); .where('blocking.blockerId = :blockerId', { blockerId: me.id });

View file

@ -2,7 +2,7 @@ import { User } from '../../../models/entities/user';
import { ChannelFollowings } from '../../../models'; import { ChannelFollowings } from '../../../models';
import { Brackets, SelectQueryBuilder } from 'typeorm'; import { Brackets, SelectQueryBuilder } from 'typeorm';
export function generateChannelQuery(q: SelectQueryBuilder<any>, me?: User | null) { export function generateChannelQuery(q: SelectQueryBuilder<any>, me?: { id: User['id'] } | null) {
if (me == null) { if (me == null) {
q.andWhere('note.channelId IS NULL'); q.andWhere('note.channelId IS NULL');
} else { } else {

View file

@ -2,7 +2,7 @@ import { User } from '../../../models/entities/user';
import { MutedNotes } from '../../../models'; import { MutedNotes } from '../../../models';
import { SelectQueryBuilder } from 'typeorm'; import { SelectQueryBuilder } from 'typeorm';
export function generateMutedNoteQuery(q: SelectQueryBuilder<any>, me: User) { export function generateMutedNoteQuery(q: SelectQueryBuilder<any>, me: { id: User['id'] }) {
const mutedQuery = MutedNotes.createQueryBuilder('muted') const mutedQuery = MutedNotes.createQueryBuilder('muted')
.select('muted.noteId') .select('muted.noteId')
.where('muted.userId = :userId', { userId: me.id }); .where('muted.userId = :userId', { userId: me.id });

View file

@ -2,7 +2,7 @@ import { User } from '../../../models/entities/user';
import { Mutings } from '../../../models'; import { Mutings } from '../../../models';
import { SelectQueryBuilder, Brackets } from 'typeorm'; import { SelectQueryBuilder, Brackets } from 'typeorm';
export function generateMutedUserQuery(q: SelectQueryBuilder<any>, me: User, exclude?: User) { export function generateMutedUserQuery(q: SelectQueryBuilder<any>, me: { id: User['id'] }, exclude?: User) {
const mutingQuery = Mutings.createQueryBuilder('muting') const mutingQuery = Mutings.createQueryBuilder('muting')
.select('muting.muteeId') .select('muting.muteeId')
.where('muting.muterId = :muterId', { muterId: me.id }); .where('muting.muterId = :muterId', { muterId: me.id });
@ -28,7 +28,7 @@ export function generateMutedUserQuery(q: SelectQueryBuilder<any>, me: User, exc
q.setParameters(mutingQuery.getParameters()); q.setParameters(mutingQuery.getParameters());
} }
export function generateMutedUserQueryForUsers(q: SelectQueryBuilder<any>, me: User) { export function generateMutedUserQueryForUsers(q: SelectQueryBuilder<any>, me: { id: User['id'] }) {
const mutingQuery = Mutings.createQueryBuilder('muting') const mutingQuery = Mutings.createQueryBuilder('muting')
.select('muting.muteeId') .select('muting.muteeId')
.where('muting.muterId = :muterId', { muterId: me.id }); .where('muting.muterId = :muterId', { muterId: me.id });

View file

@ -1,7 +1,7 @@
import { User } from '../../../models/entities/user'; import { User } from '../../../models/entities/user';
import { Brackets, SelectQueryBuilder } from 'typeorm'; import { Brackets, SelectQueryBuilder } from 'typeorm';
export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: User | null) { export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: { id: User['id'] } | null) {
if (me == null) { if (me == null) {
q.andWhere(new Brackets(qb => { qb q.andWhere(new Brackets(qb => { qb
.where(`note.replyId IS NULL`) // 返信ではない .where(`note.replyId IS NULL`) // 返信ではない

View file

@ -2,7 +2,7 @@ import { User } from '../../../models/entities/user';
import { Followings } from '../../../models'; import { Followings } from '../../../models';
import { Brackets, SelectQueryBuilder } from 'typeorm'; import { Brackets, SelectQueryBuilder } from 'typeorm';
export function generateVisibilityQuery(q: SelectQueryBuilder<any>, me?: User | null) { export function generateVisibilityQuery(q: SelectQueryBuilder<any>, me?: { id: User['id'] } | null) {
if (me == null) { if (me == null) {
q.andWhere(new Brackets(qb => { qb q.andWhere(new Brackets(qb => { qb
.where(`note.visibility = 'public'`) .where(`note.visibility = 'public'`)

View file

@ -2,7 +2,7 @@ import { publishMainStream, publishGroupMessagingStream } from '../../../service
import { publishMessagingStream } from '../../../services/stream'; import { publishMessagingStream } from '../../../services/stream';
import { publishMessagingIndexStream } from '../../../services/stream'; import { publishMessagingIndexStream } from '../../../services/stream';
import { pushNotification } from '../../../services/push-notification'; import { pushNotification } from '../../../services/push-notification';
import { User, ILocalUser, IRemoteUser } from '../../../models/entities/user'; import { User, IRemoteUser } from '../../../models/entities/user';
import { MessagingMessage } from '../../../models/entities/messaging-message'; import { MessagingMessage } from '../../../models/entities/messaging-message';
import { MessagingMessages, UserGroupJoinings, Users } from '../../../models'; import { MessagingMessages, UserGroupJoinings, Users } from '../../../models';
import { In } from 'typeorm'; import { In } from 'typeorm';
@ -136,7 +136,7 @@ export async function readGroupMessagingMessage(
} }
} }
export async function deliverReadActivity(user: ILocalUser, recipient: IRemoteUser, messages: MessagingMessage | MessagingMessage[]) { export async function deliverReadActivity(user: { id: User['id']; host: null; }, recipient: IRemoteUser, messages: MessagingMessage | MessagingMessage[]) {
messages = toArray(messages).filter(x => x.uri); messages = toArray(messages).filter(x => x.uri);
const contents = messages.map(x => renderReadActivity(user, x)); const contents = messages.map(x => renderReadActivity(user, x));

View file

@ -5,6 +5,18 @@ import { ApiError } from './error';
import { SchemaType } from '@/misc/schema'; import { SchemaType } from '@/misc/schema';
import { AccessToken } from '../../models/entities/access-token'; import { AccessToken } from '../../models/entities/access-token';
type SimpleUserInfo = {
id: ILocalUser['id'];
host: ILocalUser['host'];
username: ILocalUser['username'];
uri: ILocalUser['uri'];
inbox: ILocalUser['inbox'];
sharedInbox: ILocalUser['sharedInbox'];
isAdmin: ILocalUser['isAdmin'];
isModerator: ILocalUser['isModerator'];
isSilenced: ILocalUser['isSilenced'];
};
// TODO: defaultが設定されている場合はその型も考慮する // TODO: defaultが設定されている場合はその型も考慮する
type Params<T extends IEndpointMeta> = { type Params<T extends IEndpointMeta> = {
[P in keyof T['params']]: NonNullable<T['params']>[P]['transform'] extends Function [P in keyof T['params']]: NonNullable<T['params']>[P]['transform'] extends Function
@ -15,13 +27,12 @@ type Params<T extends IEndpointMeta> = {
export type Response = Record<string, any> | void; export type Response = Record<string, any> | void;
type executor<T extends IEndpointMeta> = type executor<T extends IEndpointMeta> =
(params: Params<T>, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken | null, file?: any, cleanup?: Function) => (params: Params<T>, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any, cleanup?: Function) =>
Promise<T['res'] extends undefined ? Response : SchemaType<NonNullable<T['res']>>>; Promise<T['res'] extends undefined ? Response : SchemaType<NonNullable<T['res']>>>;
// TODO: API関数に user まるごと渡すのではなくユーザーIDなどの最小限のプロパティだけ渡すようにしたい(キャッシュとか考えないでよくなるため)
export default function <T extends IEndpointMeta>(meta: T, cb: executor<T>) export default function <T extends IEndpointMeta>(meta: T, cb: executor<T>)
: (params: any, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken | null, file?: any) => Promise<any> { : (params: any, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any) => Promise<any> {
return (params: any, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken | null, file?: any) => { return (params: any, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any) => {
function cleanup() { function cleanup() {
fs.unlink(file.path, () => {}); fs.unlink(file.path, () => {});
} }

View file

@ -34,7 +34,8 @@ export const meta = {
} }
}; };
export default define(meta, async (ps, me) => { export default define(meta, async (ps, _me) => {
const me = _me ? await Users.findOneOrFail(_me.id) : null;
const noUsers = (await Users.count({ const noUsers = (await Users.count({
host: null, host: null,
})) === 0; })) === 0;

View file

@ -96,9 +96,9 @@ export default define(meta, async (ps) => {
emojis = await q.getMany(); emojis = await q.getMany();
emojis = emojis.filter(emoji => emojis = emojis.filter(emoji =>
emoji.name.includes(ps.query) || emoji.name.includes(ps.query!) ||
emoji.aliases.some(a => a.includes(ps.query)) || emoji.aliases.some(a => a.includes(ps.query!)) ||
emoji.category?.includes(ps.query)); emoji.category?.includes(ps.query!));
emojis.splice(ps.limit! + 1); emojis.splice(ps.limit! + 1);
} else { } else {

View file

@ -1,5 +1,6 @@
import { deliverQueue } from '@/queue/queues';
import { URL } from 'url';
import define from '../../../define'; import define from '../../../define';
import { deliverQueue } from '../../../../../queue';
export const meta = { export const meta = {
desc: { desc: {

View file

@ -1,3 +1,4 @@
import { URL } from 'url';
import define from '../../../define'; import define from '../../../define';
import { inboxQueue } from '../../../../../queue'; import { inboxQueue } from '../../../../../queue';

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