Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/design/contract-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,6 @@ issue が閉じたら該当行を消す。消し忘れは次のスナップシ
「降格対象なのに違反が出ない」状態になるだけで安全側だが、`contract-drift` の issue 本文に
known-gaps の件数を出すので気づける。

初期エントリ: `meta` / `i` / `emojis` / `stats`(notedeck#1250。14 件の配布物が NoteDeck 上で
該当呼び出しに到達すると止まる)。
初期エントリだった `meta` / `i` / `emojis` / `stats`(notedeck#1250)は notedeck 側の欠落ではなく、
同期スクリプトが引用符つきのキーしか読んでいなかったための誤検知だった(biome は識別子として
書けるキーの引用符を外す)。同期スクリプトは引用符なしのキーも読み、読めない行があれば失敗する。
7 changes: 1 addition & 6 deletions scripts/contract/known-gaps.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
{
"$comment": "notedeck 側の既知の欠落。ここに挙げた違反は verify-contract が warning に降格する。issue が閉じたら該当行を消すこと (消し忘れは contract-drift が拾う)。",
"endpoints": {
"meta": { "issue": "https://github.com/notedeck-dev/notedeck/issues/1250", "note": "misskeyEndpoints.generated.ts に無い (本家は公開 endpoint)。14 件の配布物が NoteDeck で止まる" },
"i": { "issue": "https://github.com/notedeck-dev/notedeck/issues/1250", "note": "同上。本家は read:account" },
"emojis": { "issue": "https://github.com/notedeck-dev/notedeck/issues/1250", "note": "同上。本家は公開 endpoint" },
"stats": { "issue": "https://github.com/notedeck-dev/notedeck/issues/1250", "note": "同上。本家は公開 endpoint" }
}
"endpoints": {}
}
16 changes: 15 additions & 1 deletion scripts/contract/notedeck-contract.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"generatedAt": "2026-10-12T10:42:54.123Z",
"generatedAt": "2026-10-13T11:45:02.243Z",
"source": {
"repo": "notedeck-dev/notedeck",
"ref": "25a2567f07744eeea648468412614b61f7831205",
Expand Down Expand Up @@ -1788,6 +1788,7 @@
"admin/update-meta": "deny:admin",
"admin/update-proxy-account": "deny:admin",
"admin/update-user-note": "deny:admin",
"announcements": "allow",
"announcements/show": "allow",
"antennas/create": "account.write",
"antennas/delete": "account.write",
Expand Down Expand Up @@ -1873,6 +1874,7 @@
"clips/show": "account.read",
"clips/unfavorite": "clips.write",
"clips/update": "account.write",
"drive": "drive.read",
"drive/files": "drive.read",
"drive/files/attached-chat-messages": "drive.read",
"drive/files/attached-notes": "drive.read",
Expand All @@ -1893,6 +1895,10 @@
"drive/folders/update": "drive.write",
"drive/stream": "drive.read",
"email-address/available": "allow",
"emoji": "allow",
"emojis": "allow",
"endpoint": "allow",
"endpoints": "allow",
"export-custom-emojis": "deny:credential-required-without-kind",
"federation/followers": "allow",
"federation/following": "allow",
Expand Down Expand Up @@ -1940,6 +1946,7 @@
"hashtags/show": "allow",
"hashtags/trend": "allow",
"hashtags/users": "allow",
"i": "account.read",
"i/2fa/done": "deny:credential-required-without-kind",
"i/2fa/key-done": "deny:credential-required-without-kind",
"i/2fa/password-less": "deny:credential-required-without-kind",
Expand Down Expand Up @@ -2000,11 +2007,13 @@
"invite/delete": "deny:no-mapped-key(write:invite-codes)",
"invite/limit": "account.read",
"invite/list": "account.read",
"meta": "allow",
"miauth/gen-token": "deny:credential-required-without-kind",
"mute/create": "account.write",
"mute/delete": "account.write",
"mute/list": "account.read",
"my/apps": "account.read",
"notes": "allow",
"notes/children": "allow",
"notes/clips": "allow",
"notes/conversation": "allow",
Expand Down Expand Up @@ -2052,6 +2061,7 @@
"pages/show": "allow",
"pages/unlike": "deny:no-mapped-key(write:page-likes)",
"pages/update": "deny:no-mapped-key(write:pages)",
"ping": "allow",
"pinned-users": "allow",
"promo/read": "account.write",
"renote-mute/create": "account.write",
Expand All @@ -2060,6 +2070,7 @@
"request-reset-password": "allow",
"reset-db": "allow",
"reset-password": "allow",
"retention": "allow",
"reversi/cancel-match": "account.write",
"reversi/games": "allow",
"reversi/invitations": "account.read",
Expand All @@ -2072,11 +2083,14 @@
"roles/show": "allow",
"roles/users": "allow",
"server-info": "allow",
"stats": "allow",
"sw/register": "deny:credential-required-without-kind",
"sw/show-registration": "deny:credential-required-without-kind",
"sw/unregister": "allow",
"sw/update-registration": "deny:credential-required-without-kind",
"test": "allow",
"username/available": "allow",
"users": "allow",
"users/achievements": "allow",
"users/clips": "allow",
"users/featured-notes": "allow",
Expand Down
10 changes: 8 additions & 2 deletions scripts/sync-notedeck-contract.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,14 @@ function parseEndpoints(text) {
if (start < 0) throw new Error('misskeyEndpoints.generated.ts に MISSKEY_ENDPOINT_RULES が無い')
const body = text.slice(text.indexOf('{', start), text.indexOf('\n}', start))
const endpoints = {}
for (const m of body.matchAll(/^\s*'([^']+)':\s*'([^']+)',?\s*$/gm)) {
endpoints[m[1]] = m[2]
// biome は識別子として書けるキー (meta / i / emojis …) の引用符を外す (notedeck#1250)
const entry = /^\s*(?:'([^']+)'|([A-Za-z_$][\w$]*)):\s*'([^']+)',?\s*$/
for (const line of body.split('\n').slice(1)) {
if (!line.trim()) continue
const m = line.match(entry)
// 読めない行を黙って落とすと「表に無い」と誤判定するので止める
if (!m) throw new Error(`MISSKEY_ENDPOINT_RULES の行を読めない: ${line.trim()}`)
endpoints[m[1] ?? m[2]] = m[3]
}
return sortObject(endpoints)
}
Expand Down
Loading