Skip to content
Snippets Groups Projects
CONTRIBUTING.md 4.12 KiB
Newer Older
Aya Morisawa's avatar
Aya Morisawa committed
# Contribution guide
Aya Morisawa's avatar
Aya Morisawa committed
:v: Thanks for your contributions :v:
Aya Morisawa's avatar
Aya Morisawa committed
## Issues
Feature suggestions and bug reports are filed in https://github.com/syuilo/misskey/issues .
Before creating a new issue, please search existing issues to avoid duplication.
If you find the existing issue, please add your reaction or comment to the issue.
Aya Morisawa's avatar
Aya Morisawa committed
## Localization (l10n)
Aya Morisawa's avatar
Aya Morisawa committed
Please use [Crowdin](https://crowdin.com/project/misskey) for localization.
Aya Morisawa's avatar
Aya Morisawa committed
![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg)
syuilo's avatar
syuilo committed
## Internationalization (i18n)
Misskey uses [vue-i18n](https://github.com/kazupon/vue-i18n).

Aya Morisawa's avatar
Aya Morisawa committed
## Documentation
* Documents for contributors are located in `/docs`.
* Documents for instance admins are located in `/docs`.
* Documents for end users are located in `src/docs`.
Aya Morisawa's avatar
Aya Morisawa committed
## Test
* Test codes are located in `/test`.

## Continuous integration
syuilo's avatar
syuilo committed
Misskey uses CircleCI for automated test.
Configuration files are located in `/.circleci`.
syuilo's avatar
syuilo committed

## Glossary
### AP
syuilo's avatar
syuilo committed
Stands for _**A**ctivity**P**ub_.
syuilo's avatar
syuilo committed

### MFM
syuilo's avatar
syuilo committed
Stands for _**M**isskey **F**lavored **M**arkdown_.
syuilo's avatar
syuilo committed

### Mk
syuilo's avatar
syuilo committed
Stands for _**M**iss**k**ey_.
syuilo's avatar
syuilo committed

### SW
Stands for _**S**ervice**W**orker_.
syuilo's avatar
syuilo committed

### Nyaize
Convert な(na) to にゃ(nya)
syuilo's avatar
syuilo committed

#### Denyaize
syuilo's avatar
syuilo committed

## Code style
syuilo's avatar
syuilo committed
### Use semicolon
To avoid ASI Hazard

syuilo's avatar
syuilo committed
### Don't use `export default`
Bad:
``` ts
export default function(foo: string): string {
```

Good:
``` ts
export function something(foo: string): string {
```
syuilo's avatar
syuilo committed

## Directory structure
```
src ... Source code
	@types ... Type definitions
	prelude ... Independence utils for coding JavaScript without side effects
	misc ... Independence utils for Misskey without side effects
	service ... Common functions with side effects
	queue ... Job queues and Jobs
	server ... Web Server
	client ... Client
syuilo's avatar
syuilo committed
	mfm ... MFM

test ... Test code
syuilo's avatar
syuilo committed

```

## Notes
### placeholder
SQLをクエリビルダで組み立てる際、使用するプレースホルダは重複してはならない
例えば
``` ts
query.andWhere(new Brackets(qb => {
	for (const type of ps.fileType) {
		qb.orWhere(`:type = ANY(note.attachedFileTypes)`, { type: type });
	}
}));
```
と書くと、ループ中で`type`というプレースホルダが複数回使われてしまいおかしくなる
だから次のようにする必要がある
```ts
query.andWhere(new Brackets(qb => {
	for (const type of ps.fileType) {
		const i = ps.fileType.indexOf(type);
		qb.orWhere(`:type${i} = ANY(note.attachedFileTypes)`, { [`type${i}`]: type });
	}
}));
```

### `null` in SQL
SQLを発行する際、パラメータが`null`になる可能性のある場合はSQL文を出し分けなければならない
例えば
``` ts
query.where('file.folderId = :folderId', { folderId: ps.folderId });
```
という処理で、`ps.folderId``null`だと結果的に`file.folderId = null`のようなクエリが発行されてしまい、これは正しいSQLではないので期待した結果が得られない
だから次のようにする必要がある
``` ts
if (ps.folderId) {
	query.where('file.folderId = :folderId', { folderId: ps.folderId });
} else {
	query.where('file.folderId IS NULL');
}
```

### `[]` in SQL
SQLを発行する際、`IN`のパラメータが`[]`(空の配列)になる可能性のある場合はSQL文を出し分けなければならない
例えば
``` ts
const users = await Users.find({
	id: In(userIds)
});
```
という処理で、`userIds``[]`だと結果的に`user.id IN ()`のようなクエリが発行されてしまい、これは正しいSQLではないので期待した結果が得られない
だから次のようにする必要がある
``` ts
const users = userIds.length > 0 ? await Users.find({
	id: In(userIds)
}) : [];
```

syuilo's avatar
syuilo committed
### 配列のインデックス in SQL
SQLでは配列のインデックスは**1始まり**
`[a, b, c]``a`にアクセスしたいなら`[0]`ではなく`[1]`と書く

### `undefined`にご用心
MongoDBの時とは違い、findOneでレコードを取得する時に対象レコードが存在しない場合 **`undefined`** が返ってくるので注意。
MongoDBは`null`で返してきてたので、その感覚で`if (x === null)`とか書くとバグる。代わりに`if (x == null)`と書いてください