3.9 KiB
Contribution guide
✌️ Thanks for your contributions ✌️
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.
Localization (l10n)
Please use Crowdin for localization.
Internationalization (i18n)
Misskey uses vue-i18n.
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
.
Test
- Test codes are located in
/test
.
Continuous integration
Misskey uses CircleCI for automated test.
Configuration files are located in /.circleci
.
Glossary
AP
Stands for ActivityPub.
MFM
Stands for Misskey Flavored Markdown.
Mk
Stands for Misskey.
SW
Stands for ServiceWorker.
Nyaize
Convert な(na) to にゃ(nya)
Denyaize
Revert Nyaize
Code style
Use semicolon
To avoid ASI Hazard
Don't use export default
Bad:
export default function(foo: string): string {
Good:
export function something(foo: string): string {
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
mfm ... MFM
test ... Test code
Notes
placeholder
SQLをクエリビルダで組み立てる際、使用するプレースホルダは重複してはならない 例えば
query.andWhere(new Brackets(qb => {
for (const type of ps.fileType) {
qb.orWhere(`:type = ANY(note.attachedFileTypes)`, { type: type });
}
}));
と書くと、ループ中でtype
というプレースホルダが複数回使われてしまいおかしくなる
だから次のようにする必要がある
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文を出し分けなければならない
例えば
query.where('file.folderId = :folderId', { folderId: ps.folderId });
という処理で、ps.folderId
がnull
だと結果的にfile.folderId = null
のようなクエリが発行されてしまい、これは正しいSQLではないので期待した結果が得られない
だから次のようにする必要がある
if (ps.folderId) {
query.where('file.folderId = :folderId', { folderId: ps.folderId });
} else {
query.where('file.folderId IS NULL');
}
[]
in SQL
SQLを発行する際、IN
のパラメータが[]
(空の配列)になる可能性のある場合はSQL文を出し分けなければならない
例えば
const users = await Users.find({
id: In(userIds)
});
という処理で、userIds
が[]
だと結果的にuser.id IN ()
のようなクエリが発行されてしまい、これは正しいSQLではないので期待した結果が得られない
だから次のようにする必要がある
const users = userIds.length > 0 ? await Users.find({
id: In(userIds)
}) : [];
undefined
にご用心
MongoDBの時とは違い、findOneでレコードを取得する時に対象レコードが存在しない場合 undefined
が返ってくるので注意。
MongoDBはnull
で返してきてたので、その感覚でif (x === null)
とか書くとバグる。代わりにif (x == null)
と書いてください