diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c21fc9512..1f13f4fa2 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -78,6 +78,7 @@ jobs: matrix: workspace: - backend + - sw - misskey-js steps: - uses: actions/checkout@v4.1.1 @@ -92,7 +93,7 @@ jobs: - run: corepack enable - run: pnpm i --frozen-lockfile - run: pnpm --filter misskey-js run build - if: ${{ matrix.workspace == 'backend' }} + if: ${{ matrix.workspace == 'backend' || matrix.workspace == 'sw' }} - run: pnpm --filter misskey-reversi run build if: ${{ matrix.workspace == 'backend' }} - run: pnpm --filter ${{ matrix.workspace }} run typecheck diff --git a/packages/sw/build.js b/packages/sw/build.js index 9522d061e..a9c2e428c 100644 --- a/packages/sw/build.js +++ b/packages/sw/build.js @@ -8,10 +8,10 @@ import { fileURLToPath } from 'node:url'; import * as esbuild from 'esbuild'; import locales from '../../locales/index.js'; -import meta from '../../package.json' with { type: "json" }; +import meta from '../../package.json' with { type: 'json' }; const watch = process.argv[2]?.includes('watch'); -const __dirname = fileURLToPath(new URL('.', import.meta.url)) +const __dirname = fileURLToPath(new URL('.', import.meta.url)); console.log('Starting SW building...'); diff --git a/packages/sw/src/scripts/create-notification.ts b/packages/sw/src/scripts/create-notification.ts index 02d9b0776..3c3765795 100644 --- a/packages/sw/src/scripts/create-notification.ts +++ b/packages/sw/src/scripts/create-notification.ts @@ -59,7 +59,7 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif const userDetail = await cli.request('users/show', { userId: data.body.userId }, account.token); return [i18n.ts._notification.youWereFollowed, { body: getUserName(data.body.user), - icon: data.body.user.avatarUrl, + icon: data.body.user.avatarUrl ?? undefined, badge: iconUrl('user-plus'), data, actions: userDetail.isFollowing ? [] : [ @@ -74,7 +74,7 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif case 'mention': return [i18n.tsx._notification.youGotMention({ name: getUserName(data.body.user) }), { body: data.body.note.text ?? '', - icon: data.body.user.avatarUrl, + icon: data.body.user.avatarUrl ?? undefined, badge: iconUrl('at'), data, actions: [ @@ -88,7 +88,7 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif case 'reply': return [i18n.tsx._notification.youGotReply({ name: getUserName(data.body.user) }), { body: data.body.note.text ?? '', - icon: data.body.user.avatarUrl, + icon: data.body.user.avatarUrl ?? undefined, badge: iconUrl('arrow-back-up'), data, actions: [ @@ -102,7 +102,7 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif case 'renote': return [i18n.tsx._notification.youRenoted({ name: getUserName(data.body.user) }), { body: data.body.note.text ?? '', - icon: data.body.user.avatarUrl, + icon: data.body.user.avatarUrl ?? undefined, badge: iconUrl('repeat'), data, actions: [ @@ -116,7 +116,7 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif case 'quote': return [i18n.tsx._notification.youGotQuote({ name: getUserName(data.body.user) }), { body: data.body.note.text ?? '', - icon: data.body.user.avatarUrl, + icon: data.body.user.avatarUrl ?? undefined, badge: iconUrl('quote'), data, actions: [ @@ -136,7 +136,7 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif case 'note': return [i18n.ts._notification.newNote + ': ' + getUserName(data.body.user), { body: data.body.note.text ?? '', - icon: data.body.user.avatarUrl, + icon: data.body.user.avatarUrl ?? undefined, data, }]; @@ -163,7 +163,7 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif const tag = `reaction:${data.body.note.id}`; return [`${reaction} ${getUserName(data.body.user)}`, { body: data.body.note.text ?? '', - icon: data.body.user.avatarUrl, + icon: data.body.user.avatarUrl ?? undefined, tag, badge, data, @@ -179,7 +179,7 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif case 'receiveFollowRequest': return [i18n.ts._notification.youReceivedFollowRequest, { body: getUserName(data.body.user), - icon: data.body.user.avatarUrl, + icon: data.body.user.avatarUrl ?? undefined, badge: iconUrl('user-plus'), data, actions: [ @@ -197,7 +197,7 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif case 'followRequestAccepted': return [i18n.ts._notification.yourFollowRequestAccepted, { body: getUserName(data.body.user), - icon: data.body.user.avatarUrl, + icon: data.body.user.avatarUrl ?? undefined, badge: iconUrl('circle-check'), data, }]; @@ -237,7 +237,7 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif case 'unreadAntennaNote': return [i18n.tsx._notification.unreadAntennaNote({ name: data.body.antenna.name }), { body: `${getUserName(data.body.note.user)}: ${data.body.note.text ?? ''}`, - icon: data.body.note.user.avatarUrl, + icon: data.body.note.user.avatarUrl ?? undefined, badge: iconUrl('antenna'), tag: `antenna:${data.body.antenna.id}`, data, diff --git a/packages/sw/src/scripts/get-account-from-id.ts b/packages/sw/src/scripts/get-account-from-id.ts index 19bfe052e..157dbd005 100644 --- a/packages/sw/src/scripts/get-account-from-id.ts +++ b/packages/sw/src/scripts/get-account-from-id.ts @@ -4,9 +4,10 @@ */ import { get } from 'idb-keyval'; +import * as Misskey from 'misskey-js'; -export async function getAccountFromId(id: string): Promise<{ token: string; id: string } | void> { - const accounts = await get<{ token: string; id: string }[]>('accounts'); +export async function getAccountFromId(id: string): Promise | undefined> { + const accounts = await get[]>('accounts'); if (!accounts) { console.log('Accounts are not recorded'); return; diff --git a/packages/sw/src/scripts/operations.ts b/packages/sw/src/scripts/operations.ts index 24eea0623..8862c6faa 100644 --- a/packages/sw/src/scripts/operations.ts +++ b/packages/sw/src/scripts/operations.ts @@ -14,15 +14,22 @@ import { getUrlWithLoginId } from '@/scripts/login-id.js'; export const cli = new Misskey.api.APIClient({ origin, fetch: (...args): Promise => fetch(...args) }); -export async function api(endpoint: E, userId?: string, options?: O): Promise>> { - let account: { token: string; id: string } | void = undefined; +export async function api< + E extends keyof Misskey.Endpoints, + P extends Misskey.Endpoints[E]['req'] +>(endpoint: E, userId?: string, params?: P): Promise | undefined> { + let account: Pick | undefined; if (userId) { account = await getAccountFromId(userId); if (!account) return; } - return cli.request(endpoint, options, account?.token); + return (cli.request as ( + endpoint: E, + params: P, + credential?: string | null, + ) => Promise>)(endpoint, params, account?.token); } // mark-all-as-read送出を1秒間隔に制限する @@ -33,7 +40,7 @@ export function sendMarkAllAsRead(userId: string): Promise { setTimeout(() => { readBlockingStatus.set(userId, false); - api('notifications/mark-all-as-read', userId).then(resolve, resolve); + (api('notifications/mark-all-as-read', userId) as Promise).then(resolve, resolve); }, 1000); }); } diff --git a/packages/sw/src/sw.ts b/packages/sw/src/sw.ts index 7a0010992..2d39d23ec 100644 --- a/packages/sw/src/sw.ts +++ b/packages/sw/src/sw.ts @@ -160,8 +160,8 @@ globalThis.addEventListener('notificationclick', (ev: ServiceWorkerGlobalScopeEv case 'markAllAsRead': await globalThis.registration.getNotifications() .then(notifications => notifications.forEach(n => n.tag !== 'read_notification' && n.close())); - await get('accounts').then(accounts => { - return Promise.all(accounts.map(async account => { + await get[]>('accounts').then(accounts => { + return Promise.all((accounts ?? []).map(async account => { await swos.sendMarkAllAsRead(account.id); })); }); diff --git a/packages/sw/tsconfig.json b/packages/sw/tsconfig.json index 50d4aae19..f3f354301 100644 --- a/packages/sw/tsconfig.json +++ b/packages/sw/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "allowJs": true, "noEmitOnError": false, + "noImplicitAny": false, "noImplicitReturns": true, "noUnusedParameters": false, "noUnusedLocals": true,