summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2024-03-07 16:09:36 +0000
committerdakkar <dakkar@thenautilus.net>2024-03-07 16:09:36 +0000
commitdfff4d20731c9d356c28db6238a9e438618ff2e7 (patch)
tree732119af4c809639356e71cd73f79eb41497d7dc
parentmerge: check prohibited words when creating notes (!461) (diff)
parentfix(frontend): 周年の実績が閏年を考慮するように (#13525) (diff)
downloadsharkey-dfff4d20731c9d356c28db6238a9e438618ff2e7.tar.gz
sharkey-dfff4d20731c9d356c28db6238a9e438618ff2e7.tar.bz2
sharkey-dfff4d20731c9d356c28db6238a9e438618ff2e7.zip
Merge remote-tracking branch 'misskey/develop' into future
-rw-r--r--.old/workflows/lint.yml95
-rw-r--r--CHANGELOG.md12
-rw-r--r--CONTRIBUTING.md92
-rw-r--r--locales/index.d.ts6
-rw-r--r--locales/ja-JP.yml3
-rw-r--r--packages/backend/src/core/FetchInstanceMetadataService.ts28
-rw-r--r--packages/backend/src/core/entities/DriveFileEntityService.ts2
-rw-r--r--packages/backend/src/core/entities/NoteEntityService.ts1
-rw-r--r--packages/backend/src/models/json-schema/note.ts4
-rw-r--r--packages/backend/src/server/web/boot.js4
-rw-r--r--packages/backend/test/e2e/2fa.ts96
-rw-r--r--packages/backend/test/e2e/antennas.ts116
-rw-r--r--packages/backend/test/e2e/api-visibility.ts74
-rw-r--r--packages/backend/test/e2e/api.ts43
-rw-r--r--packages/backend/test/e2e/block.ts19
-rw-r--r--packages/backend/test/e2e/clips.ts298
-rw-r--r--packages/backend/test/e2e/drive.ts36
-rw-r--r--packages/backend/test/e2e/endpoints.ts261
-rw-r--r--packages/backend/test/e2e/exports.ts38
-rw-r--r--packages/backend/test/e2e/fetch-resource.ts18
-rw-r--r--packages/backend/test/e2e/ff-visibility.ts206
-rw-r--r--packages/backend/test/e2e/move.ts186
-rw-r--r--packages/backend/test/e2e/mute.ts87
-rw-r--r--packages/backend/test/e2e/note.ts177
-rw-r--r--packages/backend/test/e2e/renote-mute.ts6
-rw-r--r--packages/backend/test/e2e/streaming.ts6
-rw-r--r--packages/backend/test/e2e/thread-mute.ts18
-rw-r--r--packages/backend/test/e2e/timelines.ts354
-rw-r--r--packages/backend/test/e2e/user-notes.ts8
-rw-r--r--packages/backend/test/e2e/users.ts463
-rw-r--r--packages/backend/test/global.d.ts7
-rw-r--r--packages/backend/test/prelude/get-api-validator.ts4
-rw-r--r--packages/backend/test/tsconfig.json3
-rw-r--r--packages/backend/test/unit/AnnouncementService.ts2
-rw-r--r--packages/backend/test/unit/FetchInstanceMetadataService.ts43
-rw-r--r--packages/backend/test/unit/RelayService.ts3
-rw-r--r--packages/backend/test/unit/RoleService.ts3
-rw-r--r--packages/backend/test/utils.ts61
-rw-r--r--packages/frontend/src/boot/main-boot.ts28
-rw-r--r--packages/frontend/src/components/MkMediaAudio.vue15
-rw-r--r--packages/frontend/src/components/MkMediaImage.vue9
-rw-r--r--packages/frontend/src/components/MkMediaVideo.vue15
-rw-r--r--packages/frontend/src/components/MkNote.vue25
-rw-r--r--packages/frontend/src/components/MkNoteDetailed.vue31
-rw-r--r--packages/frontend/src/components/MkNotification.vue27
-rw-r--r--packages/frontend/src/components/MkTutorialDialog.Note.vue1
-rw-r--r--packages/frontend/src/components/MkTutorialDialog.PostNote.vue1
-rw-r--r--packages/frontend/src/components/MkTutorialDialog.Sensitive.vue1
-rw-r--r--packages/frontend/src/components/global/MkAd.vue21
-rw-r--r--packages/frontend/src/nirax.ts20
-rw-r--r--packages/frontend/src/scripts/use-note-capture.ts2
-rw-r--r--packages/frontend/src/style.scss7
-rw-r--r--packages/frontend/vite.config.local-dev.ts3
-rw-r--r--packages/misskey-js/src/autogen/types.ts1
-rw-r--r--pnpm-lock.yaml1111
55 files changed, 2128 insertions, 2073 deletions
diff --git a/.old/workflows/lint.yml b/.old/workflows/lint.yml
deleted file mode 100644
index 8ad19b45c8..0000000000
--- a/.old/workflows/lint.yml
+++ /dev/null
@@ -1,95 +0,0 @@
-name: Lint
-
-on:
- push:
- branches:
- - stable
- - develop
- paths:
- - packages/**
- pull_request:
- paths:
- - packages/backend/**
- - packages/frontend/**
- - packages/sw/**
- - packages/misskey-js/**
- - packages/shared/.eslintrc.js
-
-jobs:
- pnpm_install:
- runs-on: docker
- steps:
- - uses: actions/checkout@v4.1.1
- with:
- fetch-depth: 0
- submodules: true
- - uses: https://github.com/pnpm/action-setup@v2
- with:
- version: 8
- run_install: false
- - uses: https://code.forgejo.org/actions/setup-node@v4
- with:
- node-version-file: '.node-version'
- cache: 'pnpm'
- - run: corepack enable
- - run: pnpm i --frozen-lockfile
-
- lint:
- needs: [pnpm_install]
- runs-on: docker
- continue-on-error: true
- strategy:
- matrix:
- workspace:
- - backend
- - frontend
- - sw
- - misskey-js
- steps:
- - uses: actions/checkout@v4.1.1
- with:
- fetch-depth: 0
- submodules: true
- - uses: https://github.com/pnpm/action-setup@v2
- with:
- version: 7
- run_install: false
- - uses: https://code.forgejo.org/actions/setup-node@v4
- with:
- node-version-file: '.node-version'
- cache: 'pnpm'
- - run: corepack enable
- - run: pnpm i --frozen-lockfile
- - run: pnpm --filter ${{ matrix.workspace }} run eslint
-
- typecheck:
- needs: [pnpm_install]
- runs-on: docker
- continue-on-error: true
- strategy:
- matrix:
- workspace:
- - backend
- - misskey-js
- steps:
- - uses: actions/checkout@v4.1.1
- with:
- fetch-depth: 0
- submodules: true
- - uses: https://github.com/pnpm/action-setup@v2
- with:
- version: 7
- run_install: false
- - uses: https://code.forgejo.org/actions/setup-node@v4
- with:
- node-version-file: '.node-version'
- cache: 'pnpm'
- - run: corepack enable
- - run: pnpm i --frozen-lockfile
- - run: pnpm --filter misskey-js run build
- if: ${{ matrix.workspace == 'backend' }}
- - run: pnpm --filter misskey-reversi run build:tsc
- if: ${{ matrix.workspace == 'backend' }}
- - run: pnpm --filter misskey-bubble-game run build
- if: ${{ matrix.workspace == 'backend' }}
- - run: pnpm --filter ${{ matrix.workspace }} run typecheck
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bafee277d2..be621e1ebd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,17 +1,19 @@
-<!--
-## 202x.x.x (unreleased)
+## Unreleased
### General
-
### Client
--
+- Enhance: 自分のノートの添付ファイルから直接ファイルの詳細ページに飛べるように
+- Enhance: 広告がMisskeyと同一ドメインの場合はRouterで遷移するように
+- Enhance: リアクション・いいねの総数を表示するように
+- Enhance: リアクション受け入れが「いいねのみ」の場合はリアクション絵文字一覧を表示しないように
+- Fix: 一部のページ内リンクが正しく動作しない問題を修正
+- Fix: 周年の実績が閏年を考慮しない問題を修正
### Server
-
--->
-
## 2024.3.1
### General
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 50f323fab0..95f0383c70 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -307,6 +307,98 @@ export const handlers = [
Don't forget to re-run the `.storybook/generate.js` script after adding, editing, or removing the above files.
+## Nest
+
+### Nest Service Circular dependency / Nestでサービスの循環参照でエラーが起きた場合
+
+#### forwardRef
+まずは簡単に`forwardRef`を試してみる
+
+```typescript
+export class FooService {
+ constructor(
+ @Inject(forwardRef(() => BarService))
+ private barService: BarService
+ ) {
+ }
+}
+```
+
+#### OnModuleInit
+できなければ`OnModuleInit`を使う
+
+```typescript
+import { Injectable, OnModuleInit } from '@nestjs/common';
+import { ModuleRef } from '@nestjs/core';
+import { BarService } from '@/core/BarService';
+
+@Injectable()
+export class FooService implements OnModuleInit {
+ private barService: BarService // constructorから移動してくる
+
+ constructor(
+ private moduleRef: ModuleRef,
+ ) {
+ }
+
+ async onModuleInit() {
+ this.barService = this.moduleRef.get(BarService.name);
+ }
+
+ public async niceMethod() {
+ return await this.barService.incredibleMethod({ hoge: 'fuga' });
+ }
+}
+```
+
+##### Service Unit Test
+テストで`onModuleInit`を呼び出す必要がある
+
+```typescript
+// import ...
+
+describe('test', () => {
+ let app: TestingModule;
+ let fooService: FooService; // for test case
+ let barService: BarService; // for test case
+
+ beforeEach(async () => {
+ app = await Test.createTestingModule({
+ imports: ...,
+ providers: [
+ FooService,
+ { // mockする (mockは必須ではないかもしれない)
+ provide: BarService,
+ useFactory: () => ({
+ incredibleMethod: jest.fn(),
+ }),
+ },
+ { // Provideにする
+ provide: BarService.name,
+ useExisting: BarService,
+ },
+ ],
+ })
+ .useMocker(...
+ .compile();
+
+ fooService = app.get<FooService>(FooService);
+ barService = app.get<BarService>(BarService) as jest.Mocked<BarService>;
+
+ // onModuleInitを実行する
+ await fooService.onModuleInit();
+ });
+
+ test('nice', () => {
+ await fooService.niceMethod();
+
+ expect(barService.incredibleMethod).toHaveBeenCalled();
+ expect(barService.incredibleMethod.mock.lastCall![0])
+ .toEqual({ hoge: 'fuga' });
+ });
+})
+```
+
## Notes
### Misskeyのドメイン固有の概念は`Mi`をprefixする
diff --git a/locales/index.d.ts b/locales/index.d.ts
index e407d2119b..b148161524 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -9167,7 +9167,11 @@ export interface Locale extends ILocale {
*/
"reactedBySomeUsers": ParameterizedString<"n">;
/**
- * {n}人がブーストしました
+ * {n}人がいいねしました
+ */
+ "likedBySomeUsers": ParameterizedString<"n">;
+ /**
+ * {n}人がリノートしました
*/
"renotedBySomeUsers": ParameterizedString<"n">;
/**
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 57f52c64b2..272bd2027e 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -2419,7 +2419,8 @@ _notification:
sendTestNotification: "テスト通知を送信する"
notificationWillBeDisplayedLikeThis: "通知はこのように表示されます"
reactedBySomeUsers: "{n}人がリアクションしました"
- renotedBySomeUsers: "{n}人がブーストしました"
+ likedBySomeUsers: "{n}人がいいねしました"
+ renotedBySomeUsers: "{n}人がリノートしました"
followedBySomeUsers: "{n}人にフォローされました"
flushNotification: "通知の履歴をリセットする"
diff --git a/packages/backend/src/core/FetchInstanceMetadataService.ts b/packages/backend/src/core/FetchInstanceMetadataService.ts
index bc270bd28f..8d173855f3 100644
--- a/packages/backend/src/core/FetchInstanceMetadataService.ts
+++ b/packages/backend/src/core/FetchInstanceMetadataService.ts
@@ -51,21 +51,35 @@ export class FetchInstanceMetadataService {
}
@bindThis
- public async tryLock(host: string): Promise<boolean> {
- const mutex = await this.redisClient.set(`fetchInstanceMetadata:mutex:${host}`, '1', 'GET');
- return mutex !== '1';
+ // public for test
+ public async tryLock(host: string): Promise<string | null> {
+ // TODO: マイグレーションなのであとで消す (2024.3.1)
+ this.redisClient.del(`fetchInstanceMetadata:mutex:${host}`);
+
+ return await this.redisClient.set(
+ `fetchInstanceMetadata:mutex:v2:${host}`, '1',
+ 'EX', 30, // 30秒したら自動でロック解除 https://github.com/misskey-dev/misskey/issues/13506#issuecomment-1975375395
+ 'GET' // 古い値を返す(なかったらnull)
+ );
}
@bindThis
- public unlock(host: string): Promise<'OK'> {
- return this.redisClient.set(`fetchInstanceMetadata:mutex:${host}`, '0');
+ // public for test
+ public unlock(host: string): Promise<number> {
+ return this.redisClient.del(`fetchInstanceMetadata:mutex:v2:${host}`);
}
@bindThis
public async fetchInstanceMetadata(instance: MiInstance, force = false): Promise<void> {
const host = instance.host;
- // Acquire mutex to ensure no parallel runs
- if (!await this.tryLock(host)) return;
+
+ // finallyでunlockされてしまうのでtry内でロックチェックをしない
+ // (returnであってもfinallyは実行される)
+ if (!force && await this.tryLock(host) === '1') {
+ // 1が返ってきていたらロックされているという意味なので、何もしない
+ return;
+ }
+
try {
if (!force) {
const _instance = await this.federatedInstanceService.fetch(host);
diff --git a/packages/backend/src/core/entities/DriveFileEntityService.ts b/packages/backend/src/core/entities/DriveFileEntityService.ts
index 8affe2b3bf..26bf386cbc 100644
--- a/packages/backend/src/core/entities/DriveFileEntityService.ts
+++ b/packages/backend/src/core/entities/DriveFileEntityService.ts
@@ -248,7 +248,7 @@ export class DriveFileEntityService {
folder: opts.detail && file.folderId ? this.driveFolderEntityService.pack(file.folderId, {
detail: true,
}) : null,
- userId: opts.withUser ? file.userId : null,
+ userId: file.userId,
user: (opts.withUser && file.userId) ? this.userEntityService.pack(file.userId) : null,
});
}
diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts
index 86a8670f29..9f59f89d17 100644
--- a/packages/backend/src/core/entities/NoteEntityService.ts
+++ b/packages/backend/src/core/entities/NoteEntityService.ts
@@ -351,6 +351,7 @@ export class NoteEntityService implements OnModuleInit {
visibleUserIds: note.visibility === 'specified' ? note.visibleUserIds : undefined,
renoteCount: note.renoteCount,
repliesCount: note.repliesCount,
+ reactionCount: Object.values(note.reactions).reduce((a, b) => a + b, 0),
reactions: this.reactionService.convertLegacyReactions(note.reactions),
reactionEmojis: this.customEmojiService.populateEmojis(reactionEmojiNames, host),
reactionAndUserPairCache: opts.withReactionAndUserPairCache ? note.reactionAndUserPairCache : undefined,
diff --git a/packages/backend/src/models/json-schema/note.ts b/packages/backend/src/models/json-schema/note.ts
index bb4ccc7ee4..2641161c8b 100644
--- a/packages/backend/src/models/json-schema/note.ts
+++ b/packages/backend/src/models/json-schema/note.ts
@@ -223,6 +223,10 @@ export const packedNoteSchema = {
}],
},
},
+ reactionCount: {
+ type: 'number',
+ optional: false, nullable: false,
+ },
renoteCount: {
type: 'number',
optional: false, nullable: false,
diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js
index 6b9dc0a103..0543cc2b65 100644
--- a/packages/backend/src/server/web/boot.js
+++ b/packages/backend/src/server/web/boot.js
@@ -86,8 +86,8 @@
//#endregion
//#region Script
- function importAppScript() {
- import(`/vite/${CLIENT_ENTRY}`)
+ async function importAppScript() {
+ await import(`/vite/${CLIENT_ENTRY}`)
.catch(async e => {
console.error(e);
renderError('APP_IMPORT', e);
diff --git a/packages/backend/test/e2e/2fa.ts b/packages/backend/test/e2e/2fa.ts
index 87a3c227d6..13c56b88a6 100644
--- a/packages/backend/test/e2e/2fa.ts
+++ b/packages/backend/test/e2e/2fa.ts
@@ -187,7 +187,7 @@ describe('2要素認証', () => {
}, 1000 * 60 * 2);
test('が設定でき、OTPでログインできる。', async () => {
- const registerResponse = await api('/i/2fa/register', {
+ const registerResponse = await api('i/2fa/register', {
password,
}, alice);
assert.strictEqual(registerResponse.status, 200);
@@ -197,18 +197,18 @@ describe('2要素認証', () => {
assert.strictEqual(registerResponse.body.label, username);
assert.strictEqual(registerResponse.body.issuer, config.host);
- const doneResponse = await api('/i/2fa/done', {
+ const doneResponse = await api('i/2fa/done', {
token: otpToken(registerResponse.body.secret),
}, alice);
assert.strictEqual(doneResponse.status, 200);
- const usersShowResponse = await api('/users/show', {
+ const usersShowResponse = await api('users/show', {
username,
}, alice);
assert.strictEqual(usersShowResponse.status, 200);
assert.strictEqual(usersShowResponse.body.twoFactorEnabled, true);
- const signinResponse = await api('/signin', {
+ const signinResponse = await api('signin', {
...signinParam(),
token: otpToken(registerResponse.body.secret),
});
@@ -216,24 +216,24 @@ describe('2要素認証', () => {
assert.notEqual(signinResponse.body.i, undefined);
// 後片付け
- await api('/i/2fa/unregister', {
+ await api('i/2fa/unregister', {
password,
token: otpToken(registerResponse.body.secret),
}, alice);
});
test('が設定でき、セキュリティキーでログインできる。', async () => {
- const registerResponse = await api('/i/2fa/register', {
+ const registerResponse = await api('i/2fa/register', {
password,
}, alice);
assert.strictEqual(registerResponse.status, 200);
- const doneResponse = await api('/i/2fa/done', {
+ const doneResponse = await api('i/2fa/done', {
token: otpToken(registerResponse.body.secret),
}, alice);
assert.strictEqual(doneResponse.status, 200);
- const registerKeyResponse = await api('/i/2fa/register-key', {
+ const registerKeyResponse = await api('i/2fa/register-key', {
password,
token: otpToken(registerResponse.body.secret),
}, alice);
@@ -243,23 +243,23 @@ describe('2要素認証', () => {
const keyName = 'example-key';
const credentialId = crypto.randomBytes(0x41);
- const keyDoneResponse = await api('/i/2fa/key-done', keyDoneParam({
+ const keyDoneResponse = await api('i/2fa/key-done', keyDoneParam({
token: otpToken(registerResponse.body.secret),
keyName,
credentialId,
creationOptions: registerKeyResponse.body,
- }), alice);
+ }) as any, alice);
assert.strictEqual(keyDoneResponse.status, 200);
assert.strictEqual(keyDoneResponse.body.id, credentialId.toString('base64url'));
assert.strictEqual(keyDoneResponse.body.name, keyName);
- const usersShowResponse = await api('/users/show', {
+ const usersShowResponse = await api('users/show', {
username,
});
assert.strictEqual(usersShowResponse.status, 200);
assert.strictEqual(usersShowResponse.body.securityKeys, true);
- const signinResponse = await api('/signin', {
+ const signinResponse = await api('signin', {
...signinParam(),
});
assert.strictEqual(signinResponse.status, 200);
@@ -268,7 +268,7 @@ describe('2要素認証', () => {
assert.notEqual(signinResponse.body.allowCredentials, undefined);
assert.strictEqual(signinResponse.body.allowCredentials[0].id, credentialId.toString('base64url'));
- const signinResponse2 = await api('/signin', signinWithSecurityKeyParam({
+ const signinResponse2 = await api('signin', signinWithSecurityKeyParam({
keyName,
credentialId,
requestOptions: signinResponse.body,
@@ -277,24 +277,24 @@ describe('2要素認証', () => {
assert.notEqual(signinResponse2.body.i, undefined);
// 後片付け
- await api('/i/2fa/unregister', {
+ await api('i/2fa/unregister', {
password,
token: otpToken(registerResponse.body.secret),
}, alice);
});
test('が設定でき、セキュリティキーでパスワードレスログインできる。', async () => {
- const registerResponse = await api('/i/2fa/register', {
+ const registerResponse = await api('i/2fa/register', {
password,
}, alice);
assert.strictEqual(registerResponse.status, 200);
- const doneResponse = await api('/i/2fa/done', {
+ const doneResponse = await api('i/2fa/done', {
token: otpToken(registerResponse.body.secret),
}, alice);
assert.strictEqual(doneResponse.status, 200);
- const registerKeyResponse = await api('/i/2fa/register-key', {
+ const registerKeyResponse = await api('i/2fa/register-key', {
token: otpToken(registerResponse.body.secret),
password,
}, alice);
@@ -302,33 +302,33 @@ describe('2要素認証', () => {
const keyName = 'example-key';
const credentialId = crypto.randomBytes(0x41);
- const keyDoneResponse = await api('/i/2fa/key-done', keyDoneParam({
+ const keyDoneResponse = await api('i/2fa/key-done', keyDoneParam({
token: otpToken(registerResponse.body.secret),
keyName,
credentialId,
creationOptions: registerKeyResponse.body,
- }), alice);
+ }) as any, alice);
assert.strictEqual(keyDoneResponse.status, 200);
- const passwordLessResponse = await api('/i/2fa/password-less', {
+ const passwordLessResponse = await api('i/2fa/password-less', {
value: true,
}, alice);
assert.strictEqual(passwordLessResponse.status, 204);
- const usersShowResponse = await api('/users/show', {
+ const usersShowResponse = await api('users/show', {
username,
});
assert.strictEqual(usersShowResponse.status, 200);
assert.strictEqual(usersShowResponse.body.usePasswordLessLogin, true);
- const signinResponse = await api('/signin', {
+ const signinResponse = await api('signin', {
...signinParam(),
password: '',
});
assert.strictEqual(signinResponse.status, 200);
assert.strictEqual(signinResponse.body.i, undefined);
- const signinResponse2 = await api('/signin', {
+ const signinResponse2 = await api('signin', {
...signinWithSecurityKeyParam({
keyName,
credentialId,
@@ -340,24 +340,24 @@ describe('2要素認証', () => {
assert.notEqual(signinResponse2.body.i, undefined);
// 後片付け
- await api('/i/2fa/unregister', {
+ await api('i/2fa/unregister', {
password,
token: otpToken(registerResponse.body.secret),
}, alice);
});
test('が設定でき、設定したセキュリティキーの名前を変更できる。', async () => {
- const registerResponse = await api('/i/2fa/register', {
+ const registerResponse = await api('i/2fa/register', {
password,
}, alice);
assert.strictEqual(registerResponse.status, 200);
- const doneResponse = await api('/i/2fa/done', {
+ const doneResponse = await api('i/2fa/done', {
token: otpToken(registerResponse.body.secret),
}, alice);
assert.strictEqual(doneResponse.status, 200);
- const registerKeyResponse = await api('/i/2fa/register-key', {
+ const registerKeyResponse = await api('i/2fa/register-key', {
token: otpToken(registerResponse.body.secret),
password,
}, alice);
@@ -365,22 +365,22 @@ describe('2要素認証', () => {
const keyName = 'example-key';
const credentialId = crypto.randomBytes(0x41);
- const keyDoneResponse = await api('/i/2fa/key-done', keyDoneParam({
+ const keyDoneResponse = await api('i/2fa/key-done', keyDoneParam({
token: otpToken(registerResponse.body.secret),
keyName,
credentialId,
creationOptions: registerKeyResponse.body,
- }), alice);
+ }) as any, alice);
assert.strictEqual(keyDoneResponse.status, 200);
const renamedKey = 'other-key';
- const updateKeyResponse = await api('/i/2fa/update-key', {
+ const updateKeyResponse = await api('i/2fa/update-key', {
name: renamedKey,
credentialId: credentialId.toString('base64url'),
}, alice);
assert.strictEqual(updateKeyResponse.status, 200);
- const iResponse = await api('/i', {
+ const iResponse = await api('i', {
}, alice);
assert.strictEqual(iResponse.status, 200);
const securityKeys = iResponse.body.securityKeysList.filter((s: { id: string; }) => s.id === credentialId.toString('base64url'));
@@ -389,24 +389,24 @@ describe('2要素認証', () => {
assert.notEqual(securityKeys[0].lastUsed, undefined);
// 後片付け
- await api('/i/2fa/unregister', {
+ await api('i/2fa/unregister', {
password,
token: otpToken(registerResponse.body.secret),
}, alice);
});
test('が設定でき、設定したセキュリティキーを削除できる。', async () => {
- const registerResponse = await api('/i/2fa/register', {
+ const registerResponse = await api('i/2fa/register', {
password,
}, alice);
assert.strictEqual(registerResponse.status, 200);
- const doneResponse = await api('/i/2fa/done', {
+ const doneResponse = await api('i/2fa/done', {
token: otpToken(registerResponse.body.secret),
}, alice);
assert.strictEqual(doneResponse.status, 200);
- const registerKeyResponse = await api('/i/2fa/register-key', {
+ const registerKeyResponse = await api('i/2fa/register-key', {
token: otpToken(registerResponse.body.secret),
password,
}, alice);
@@ -414,20 +414,20 @@ describe('2要素認証', () => {
const keyName = 'example-key';
const credentialId = crypto.randomBytes(0x41);
- const keyDoneResponse = await api('/i/2fa/key-done', keyDoneParam({
+ const keyDoneResponse = await api('i/2fa/key-done', keyDoneParam({
token: otpToken(registerResponse.body.secret),
keyName,
credentialId,
creationOptions: registerKeyResponse.body,
- }), alice);
+ }) as any, alice);
assert.strictEqual(keyDoneResponse.status, 200);
// テストの実行順によっては複数残ってるので全部消す
- const iResponse = await api('/i', {
+ const iResponse = await api('i', {
}, alice);
assert.strictEqual(iResponse.status, 200);
for (const key of iResponse.body.securityKeysList) {
- const removeKeyResponse = await api('/i/2fa/remove-key', {
+ const removeKeyResponse = await api('i/2fa/remove-key', {
token: otpToken(registerResponse.body.secret),
password,
credentialId: key.id,
@@ -435,13 +435,13 @@ describe('2要素認証', () => {
assert.strictEqual(removeKeyResponse.status, 200);
}
- const usersShowResponse = await api('/users/show', {
+ const usersShowResponse = await api('users/show', {
username,
});
assert.strictEqual(usersShowResponse.status, 200);
assert.strictEqual(usersShowResponse.body.securityKeys, false);
- const signinResponse = await api('/signin', {
+ const signinResponse = await api('signin', {
...signinParam(),
token: otpToken(registerResponse.body.secret),
});
@@ -449,43 +449,43 @@ describe('2要素認証', () => {
assert.notEqual(signinResponse.body.i, undefined);
// 後片付け
- await api('/i/2fa/unregister', {
+ await api('i/2fa/unregister', {
password,
token: otpToken(registerResponse.body.secret),
}, alice);
});
test('が設定でき、設定解除できる。(パスワードのみでログインできる。)', async () => {
- const registerResponse = await api('/i/2fa/register', {
+ const registerResponse = await api('i/2fa/register', {
password,
}, alice);
assert.strictEqual(registerResponse.status, 200);
- const doneResponse = await api('/i/2fa/done', {
+ const doneResponse = await api('i/2fa/done', {
token: otpToken(registerResponse.body.secret),
}, alice);
assert.strictEqual(doneResponse.status, 200);
- const usersShowResponse = await api('/users/show', {
+ const usersShowResponse = await api('users/show', {
username,
});
assert.strictEqual(usersShowResponse.status, 200);
assert.strictEqual(usersShowResponse.body.twoFactorEnabled, true);
- const unregisterResponse = await api('/i/2fa/unregister', {
+ const unregisterResponse = await api('i/2fa/unregister', {
token: otpToken(registerResponse.body.secret),
password,
}, alice);
assert.strictEqual(unregisterResponse.status, 204);
- const signinResponse = await api('/signin', {
+ const signinResponse = await api('signin', {
...signinParam(),
});
assert.strictEqual(signinResponse.status, 200);
assert.notEqual(signinResponse.body.i, undefined);
// 後片付け
- await api('/i/2fa/unregister', {
+ await api('i/2fa/unregister', {
password,
token: otpToken(registerResponse.body.secret),
}, alice);
diff --git a/packages/backend/test/e2e/antennas.ts b/packages/backend/test/e2e/antennas.ts
index 1a9d5bf1f0..7370b1963c 100644
--- a/packages/backend/test/e2e/antennas.ts
+++ b/packages/backend/test/e2e/antennas.ts
@@ -7,7 +7,6 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
-import type { Packed } from '@/misc/json-schema.js';
import {
api,
failedApiCall,
@@ -29,10 +28,7 @@ describe('アンテナ', () => {
// エンティティとしてのアンテナを主眼においたテストを記述する
// (Antennaを返すエンドポイント、Antennaエンティティを書き換えるエンドポイント、Antennaからノートを取得するエンドポイントをテストする)
- // BUG misskey-jsとjson-schemaが一致していない。
- // - srcのenumにgroupが残っている
- // - userGroupIdが残っている, isActiveがない
- type Antenna = misskey.entities.Antenna | Packed<'Antenna'>;
+ type Antenna = misskey.entities.Antenna;
type User = misskey.entities.SignupResponse;
type Note = misskey.entities.Note;
@@ -80,7 +76,7 @@ describe('アンテナ', () => {
aliceList = await userList(alice, {});
bob = await signup({ username: 'bob' });
aliceList = await userList(alice, {});
- bobFile = (await uploadFile(bob)).body;
+ bobFile = (await uploadFile(bob)).body!;
bobList = await userList(bob);
carol = await signup({ username: 'carol' });
await api('users/lists/push', { listId: aliceList.id, userId: bob.id }, alice);
@@ -129,9 +125,9 @@ describe('アンテナ', () => {
beforeEach(async () => {
// テスト間で影響し合わないように毎回全部消す。
for (const user of [alice, bob]) {
- const list = await api('/antennas/list', {}, user);
+ const list = await api('antennas/list', {}, user);
for (const antenna of list.body) {
- await api('/antennas/delete', { antennaId: antenna.id }, user);
+ await api('antennas/delete', { antennaId: antenna.id }, user);
}
}
});
@@ -141,11 +137,11 @@ describe('アンテナ', () => {
test('が作成できること、キーが過不足なく入っていること。', async () => {
const response = await successfulApiCall({
endpoint: 'antennas/create',
- parameters: { ...defaultParam },
+ parameters: defaultParam,
user: alice,
});
assert.match(response.id, /[0-9a-z]{10}/);
- const expected = {
+ const expected: Antenna = {
id: response.id,
caseSensitive: false,
createdAt: new Date(response.createdAt).toISOString(),
@@ -161,7 +157,7 @@ describe('アンテナ', () => {
withFile: false,
withReplies: false,
localOnly: false,
- } as Antenna;
+ };
assert.deepStrictEqual(response, expected);
});
@@ -202,27 +198,27 @@ describe('アンテナ', () => {
});
const antennaParamPattern = [
- { parameters: (): object => ({ name: 'x'.repeat(100) }) },
- { parameters: (): object => ({ name: 'x' }) },
- { parameters: (): object => ({ src: 'home' }) },
- { parameters: (): object => ({ src: 'all' }) },
- { parameters: (): object => ({ src: 'users' }) },
- { parameters: (): object => ({ src: 'list' }) },
- { parameters: (): object => ({ userListId: null }) },
- { parameters: (): object => ({ src: 'list', userListId: aliceList.id }) },
- { parameters: (): object => ({ keywords: [['x']] }) },
- { parameters: (): object => ({ keywords: [['a', 'b', 'c'], ['x'], ['y'], ['z']] }) },
- { parameters: (): object => ({ excludeKeywords: [['a', 'b', 'c'], ['x'], ['y'], ['z']] }) },
- { parameters: (): object => ({ users: [alice.username] }) },
- { parameters: (): object => ({ users: [alice.username, bob.username, carol.username] }) },
- { parameters: (): object => ({ caseSensitive: false }) },
- { parameters: (): object => ({ caseSensitive: true }) },
- { parameters: (): object => ({ withReplies: false }) },
- { parameters: (): object => ({ withReplies: true }) },
- { parameters: (): object => ({ withFile: false }) },
- { parameters: (): object => ({ withFile: true }) },
- { parameters: (): object => ({ notify: false }) },
- { parameters: (): object => ({ notify: true }) },
+ { parameters: () => ({ name: 'x'.repeat(100) }) },
+ { parameters: () => ({ name: 'x' }) },
+ { parameters: () => ({ src: 'home' as const }) },
+ { parameters: () => ({ src: 'all' as const }) },
+ { parameters: () => ({ src: 'users' as const }) },
+ { parameters: () => ({ src: 'list' as const }) },
+ { parameters: () => ({ userListId: null }) },
+ { parameters: () => ({ src: 'list' as const, userListId: aliceList.id }) },
+ { parameters: () => ({ keywords: [['x']] }) },
+ { parameters: () => ({ keywords: [['a', 'b', 'c'], ['x'], ['y'], ['z']] }) },
+ { parameters: () => ({ excludeKeywords: [['a', 'b', 'c'], ['x'], ['y'], ['z']] }) },
+ { parameters: () => ({ users: [alice.username] }) },
+ { parameters: () => ({ users: [alice.username, bob.username, carol.username] }) },
+ { parameters: () => ({ caseSensitive: false }) },
+ { parameters: () => ({ caseSensitive: true }) },
+ { parameters: () => ({ withReplies: false }) },
+ { parameters: () => ({ withReplies: true }) },
+ { parameters: () => ({ withFile: false }) },
+ { parameters: () => ({ withFile: true }) },
+ { parameters: () => ({ notify: false }) },
+ { parameters: () => ({ notify: true }) },
];
test.each(antennaParamPattern)('を作成できること($#)', async ({ parameters }) => {
const response = await successfulApiCall({
@@ -335,7 +331,7 @@ describe('アンテナ', () => {
test.each([
{
label: '全体から',
- parameters: (): object => ({ src: 'all' }),
+ parameters: () => ({ src: 'all' }),
posts: [
{ note: (): Promise<Note> => post(alice, { text: `${keyword}` }), included: true },
{ note: (): Promise<Note> => post(userFollowedByAlice, { text: `${keyword}` }), included: true },
@@ -346,7 +342,7 @@ describe('アンテナ', () => {
{
// BUG e4144a1 以降home指定は壊れている(allと同じ)
label: 'ホーム指定はallと同じ',
- parameters: (): object => ({ src: 'home' }),
+ parameters: () => ({ src: 'home' }),
posts: [
{ note: (): Promise<Note> => post(alice, { text: `${keyword}` }), included: true },
{ note: (): Promise<Note> => post(userFollowedByAlice, { text: `${keyword}` }), included: true },
@@ -357,7 +353,7 @@ describe('アンテナ', () => {
{
// https://github.com/misskey-dev/misskey/issues/9025
label: 'ただし、フォロワー限定投稿とDM投稿を含まない。フォロワーであっても。',
- parameters: (): object => ({}),
+ parameters: () => ({}),
posts: [
{ note: (): Promise<Note> => post(userFollowedByAlice, { text: `${keyword}`, visibility: 'public' }), included: true },
{ note: (): Promise<Note> => post(userFollowedByAlice, { text: `${keyword}`, visibility: 'home' }), included: true },
@@ -367,56 +363,56 @@ describe('アンテナ', () => {
},
{
label: 'ブロックしているユーザーのノートは含む',
- parameters: (): object => ({}),
+ parameters: () => ({}),
posts: [
{ note: (): Promise<Note> => post(userBlockedByAlice, { text: `${keyword}` }), included: true },
],
},
{
label: 'ブロックされているユーザーのノートは含まない',
- parameters: (): object => ({}),
+ parameters: () => ({}),
posts: [
{ note: (): Promise<Note> => post(userBlockingAlice, { text: `${keyword}` }) },
],
},
{
label: 'ミュートしているユーザーのノートは含まない',
- parameters: (): object => ({}),
+ parameters: () => ({}),
posts: [
{ note: (): Promise<Note> => post(userMutedByAlice, { text: `${keyword}` }) },
],
},
{
label: 'ミュートされているユーザーのノートは含む',
- parameters: (): object => ({}),
+ parameters: () => ({}),
posts: [
{ note: (): Promise<Note> => post(userMutingAlice, { text: `${keyword}` }), included: true },
],
},
{
label: '「見つけやすくする」がOFFのユーザーのノートも含まれる',
- parameters: (): object => ({}),
+ parameters: () => ({}),
posts: [
{ note: (): Promise<Note> => post(userNotExplorable, { text: `${keyword}` }), included: true },
],
},
{
label: '鍵付きユーザーのノートも含まれる',
- parameters: (): object => ({}),
+ parameters: () => ({}),
posts: [
{ note: (): Promise<Note> => post(userLocking, { text: `${keyword}` }), included: true },
],
},
{
label: 'サイレンスのノートも含まれる',
- parameters: (): object => ({}),
+ parameters: () => ({}),
posts: [
{ note: (): Promise<Note> => post(userSilenced, { text: `${keyword}` }), included: true },
],
},
{
label: '削除ユーザーのノートも含まれる',
- parameters: (): object => ({}),
+ parameters: () => ({}),
posts: [
{ note: (): Promise<Note> => post(userDeletedBySelf, { text: `${keyword}` }), included: true },
{ note: (): Promise<Note> => post(userDeletedByAdmin, { text: `${keyword}` }), included: true },
@@ -424,7 +420,7 @@ describe('アンテナ', () => {
},
{
label: 'ユーザー指定で',
- parameters: (): object => ({ src: 'users', users: [`@${bob.username}`, `@${carol.username}`] }),
+ parameters: () => ({ src: 'users', users: [`@${bob.username}`, `@${carol.username}`] }),
posts: [
{ note: (): Promise<Note> => post(alice, { text: `test ${keyword}` }) },
{ note: (): Promise<Note> => post(bob, { text: `test ${keyword}` }), included: true },
@@ -433,7 +429,7 @@ describe('アンテナ', () => {
},
{
label: 'リスト指定で',
- parameters: (): object => ({ src: 'list', userListId: aliceList.id }),
+ parameters: () => ({ src: 'list', userListId: aliceList.id }),
posts: [
{ note: (): Promise<Note> => post(alice, { text: `test ${keyword}` }) },
{ note: (): Promise<Note> => post(bob, { text: `test ${keyword}` }), included: true },
@@ -442,14 +438,14 @@ describe('アンテナ', () => {
},
{
label: 'CWにもマッチする',
- parameters: (): object => ({ keywords: [[keyword]] }),
+ parameters: () => ({ keywords: [[keyword]] }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: 'test', cw: `cw ${keyword}` }), included: true },
],
},
{
label: 'キーワード1つ',
- parameters: (): object => ({ keywords: [[keyword]] }),
+ parameters: () => ({ keywords: [[keyword]] }),
posts: [
{ note: (): Promise<Note> => post(alice, { text: 'test' }) },
{ note: (): Promise<Note> => post(bob, { text: `test ${keyword}` }), included: true },
@@ -458,7 +454,7 @@ describe('アンテナ', () => {
},
{
label: 'キーワード3つ(AND)',
- parameters: (): object => ({ keywords: [['A', 'B', 'C']] }),
+ parameters: () => ({ keywords: [['A', 'B', 'C']] }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: 'test A' }) },
{ note: (): Promise<Note> => post(bob, { text: 'test A B' }) },
@@ -469,7 +465,7 @@ describe('アンテナ', () => {
},
{
label: 'キーワード3つ(OR)',
- parameters: (): object => ({ keywords: [['A'], ['B'], ['C']] }),
+ parameters: () => ({ keywords: [['A'], ['B'], ['C']] }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: 'test' }) },
{ note: (): Promise<Note> => post(bob, { text: 'test A' }), included: true },
@@ -482,7 +478,7 @@ describe('アンテナ', () => {
},
{
label: '除外ワード3つ(AND)',
- parameters: (): object => ({ excludeKeywords: [['A', 'B', 'C']] }),
+ parameters: () => ({ excludeKeywords: [['A', 'B', 'C']] }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: `test ${keyword}` }), included: true },
{ note: (): Promise<Note> => post(bob, { text: `test ${keyword} A` }), included: true },
@@ -495,7 +491,7 @@ describe('アンテナ', () => {
},
{
label: '除外ワード3つ(OR)',
- parameters: (): object => ({ excludeKeywords: [['A'], ['B'], ['C']] }),
+ parameters: () => ({ excludeKeywords: [['A'], ['B'], ['C']] }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: `test ${keyword}` }), included: true },
{ note: (): Promise<Note> => post(bob, { text: `test ${keyword} A` }) },
@@ -508,7 +504,7 @@ describe('アンテナ', () => {
},
{
label: 'キーワード1つ(大文字小文字区別する)',
- parameters: (): object => ({ keywords: [['KEYWORD']], caseSensitive: true }),
+ parameters: () => ({ keywords: [['KEYWORD']], caseSensitive: true }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: 'keyword' }) },
{ note: (): Promise<Note> => post(bob, { text: 'kEyWoRd' }) },
@@ -517,7 +513,7 @@ describe('アンテナ', () => {
},
{
label: 'キーワード1つ(大文字小文字区別しない)',
- parameters: (): object => ({ keywords: [['KEYWORD']], caseSensitive: false }),
+ parameters: () => ({ keywords: [['KEYWORD']], caseSensitive: false }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: 'keyword' }), included: true },
{ note: (): Promise<Note> => post(bob, { text: 'kEyWoRd' }), included: true },
@@ -526,7 +522,7 @@ describe('アンテナ', () => {
},
{
label: '除外ワード1つ(大文字小文字区別する)',
- parameters: (): object => ({ excludeKeywords: [['KEYWORD']], caseSensitive: true }),
+ parameters: () => ({ excludeKeywords: [['KEYWORD']], caseSensitive: true }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: `${keyword}` }), included: true },
{ note: (): Promise<Note> => post(bob, { text: `${keyword} keyword` }), included: true },
@@ -536,7 +532,7 @@ describe('アンテナ', () => {
},
{
label: '除外ワード1つ(大文字小文字区別しない)',
- parameters: (): object => ({ excludeKeywords: [['KEYWORD']], caseSensitive: false }),
+ parameters: () => ({ excludeKeywords: [['KEYWORD']], caseSensitive: false }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: `${keyword}` }), included: true },
{ note: (): Promise<Note> => post(bob, { text: `${keyword} keyword` }) },
@@ -546,7 +542,7 @@ describe('アンテナ', () => {
},
{
label: '添付ファイルを問わない',
- parameters: (): object => ({ withFile: false }),
+ parameters: () => ({ withFile: false }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: `${keyword}`, fileIds: [bobFile.id] }), included: true },
{ note: (): Promise<Note> => post(bob, { text: `${keyword}` }), included: true },
@@ -554,7 +550,7 @@ describe('アンテナ', () => {
},
{
label: '添付ファイル付きのみ',
- parameters: (): object => ({ withFile: true }),
+ parameters: () => ({ withFile: true }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: `${keyword}`, fileIds: [bobFile.id] }), included: true },
{ note: (): Promise<Note> => post(bob, { text: `${keyword}` }) },
@@ -562,7 +558,7 @@ describe('アンテナ', () => {
},
{
label: 'リプライ以外',
- parameters: (): object => ({ withReplies: false }),
+ parameters: () => ({ withReplies: false }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: `${keyword}`, replyId: alicePost.id }) },
{ note: (): Promise<Note> => post(bob, { text: `${keyword}` }), included: true },
@@ -570,7 +566,7 @@ describe('アンテナ', () => {
},
{
label: 'リプライも含む',
- parameters: (): object => ({ withReplies: true }),
+ parameters: () => ({ withReplies: true }),
posts: [
{ note: (): Promise<Note> => post(bob, { text: `${keyword}`, replyId: alicePost.id }), included: true },
{ note: (): Promise<Note> => post(bob, { text: `${keyword}` }), included: true },
@@ -633,7 +629,7 @@ describe('アンテナ', () => {
endpoint: 'antennas/notes',
parameters: { antennaId: antenna.id, ...paginationParam },
user: alice,
- }) as any as Note[];
+ });
}, offsetBy, 'desc');
});
diff --git a/packages/backend/test/e2e/api-visibility.ts b/packages/backend/test/e2e/api-visibility.ts
index f92384525c..c61b0c2a86 100644
--- a/packages/backend/test/e2e/api-visibility.ts
+++ b/packages/backend/test/e2e/api-visibility.ts
@@ -6,7 +6,7 @@
process.env.NODE_ENV = 'test';
import * as assert from 'assert';
-import { api, post, signup } from '../utils.js';
+import { UserToken, api, post, signup } from '../utils.js';
import type * as misskey from 'misskey-js';
describe('API visibility', () => {
@@ -24,38 +24,38 @@ describe('API visibility', () => {
let target2: misskey.entities.SignupResponse;
/** public-post */
- let pub: any;
+ let pub: misskey.entities.Note;
/** home-post */
- let home: any;
+ let home: misskey.entities.Note;
/** followers-post */
- let fol: any;
+ let fol: misskey.entities.Note;
/** specified-post */
- let spe: any;
+ let spe: misskey.entities.Note;
/** public-reply to target's post */
- let pubR: any;
+ let pubR: misskey.entities.Note;
/** home-reply to target's post */
- let homeR: any;
+ let homeR: misskey.entities.Note;
/** followers-reply to target's post */
- let folR: any;
+ let folR: misskey.entities.Note;
/** specified-reply to target's post */
- let speR: any;
+ let speR: misskey.entities.Note;
/** public-mention to target */
- let pubM: any;
+ let pubM: misskey.entities.Note;
/** home-mention to target */
- let homeM: any;
+ let homeM: misskey.entities.Note;
/** followers-mention to target */
- let folM: any;
+ let folM: misskey.entities.Note;
/** specified-mention to target */
- let speM: any;
+ let speM: misskey.entities.Note;
/** reply target post */
- let tgt: any;
+ let tgt: misskey.entities.Note;
//#endregion
- const show = async (noteId: any, by: any) => {
- return await api('/notes/show', {
+ const show = async (noteId: misskey.entities.Note['id'], by?: UserToken) => {
+ return await api('notes/show', {
noteId,
}, by);
};
@@ -70,7 +70,7 @@ describe('API visibility', () => {
target2 = await signup({ username: 'target2' });
// follow alice <= follower
- await api('/following/create', { userId: alice.id }, follower);
+ await api('following/create', { userId: alice.id }, follower);
// normal posts
pub = await post(alice, { text: 'x', visibility: 'public' });
@@ -111,7 +111,7 @@ describe('API visibility', () => {
});
test('[show] public-postを未認証が見れる', async () => {
- const res = await show(pub.id, null);
+ const res = await show(pub.id);
assert.strictEqual(res.body.text, 'x');
});
@@ -132,7 +132,7 @@ describe('API visibility', () => {
});
test('[show] home-postを未認証が見れる', async () => {
- const res = await show(home.id, null);
+ const res = await show(home.id);
assert.strictEqual(res.body.text, 'x');
});
@@ -153,7 +153,7 @@ describe('API visibility', () => {
});
test('[show] followers-postを未認証が見れない', async () => {
- const res = await show(fol.id, null);
+ const res = await show(fol.id);
assert.strictEqual(res.body.isHidden, true);
});
@@ -179,7 +179,7 @@ describe('API visibility', () => {
});
test('[show] specified-postを未認証が見れない', async () => {
- const res = await show(spe.id, null);
+ const res = await show(spe.id);
assert.strictEqual(res.body.isHidden, true);
});
//#endregion
@@ -207,7 +207,7 @@ describe('API visibility', () => {
});
test('[show] public-replyを未認証が見れる', async () => {
- const res = await show(pubR.id, null);
+ const res = await show(pubR.id);
assert.strictEqual(res.body.text, 'x');
});
@@ -233,7 +233,7 @@ describe('API visibility', () => {
});
test('[show] home-replyを未認証が見れる', async () => {
- const res = await show(homeR.id, null);
+ const res = await show(homeR.id);
assert.strictEqual(res.body.text, 'x');
});
@@ -259,7 +259,7 @@ describe('API visibility', () => {
});
test('[show] followers-replyを未認証が見れない', async () => {
- const res = await show(folR.id, null);
+ const res = await show(folR.id);
assert.strictEqual(res.body.isHidden, true);
});
@@ -290,7 +290,7 @@ describe('API visibility', () => {
});
test('[show] specified-replyを未認証が見れない', async () => {
- const res = await show(speR.id, null);
+ const res = await show(speR.id);
assert.strictEqual(res.body.isHidden, true);
});
//#endregion
@@ -318,7 +318,7 @@ describe('API visibility', () => {
});
test('[show] public-mentionを未認証が見れる', async () => {
- const res = await show(pubM.id, null);
+ const res = await show(pubM.id);
assert.strictEqual(res.body.text, '@target x');
});
@@ -344,7 +344,7 @@ describe('API visibility', () => {
});
test('[show] home-mentionを未認証が見れる', async () => {
- const res = await show(homeM.id, null);
+ const res = await show(homeM.id);
assert.strictEqual(res.body.text, '@target x');
});
@@ -370,7 +370,7 @@ describe('API visibility', () => {
});
test('[show] followers-mentionを未認証が見れない', async () => {
- const res = await show(folM.id, null);
+ const res = await show(folM.id);
assert.strictEqual(res.body.isHidden, true);
});
@@ -401,28 +401,28 @@ describe('API visibility', () => {
});
test('[show] specified-mentionを未認証が見れない', async () => {
- const res = await show(speM.id, null);
+ const res = await show(speM.id);
assert.strictEqual(res.body.isHidden, true);
});
//#endregion
//#region HTL
test('[HTL] public-post が 自分が見れる', async () => {
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id === pub.id);
assert.strictEqual(notes[0].text, 'x');
});
test('[HTL] public-post が 非フォロワーから見れない', async () => {
- const res = await api('/notes/timeline', { limit: 100 }, other);
+ const res = await api('notes/timeline', { limit: 100 }, other);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id === pub.id);
assert.strictEqual(notes.length, 0);
});
test('[HTL] followers-post が フォロワーから見れる', async () => {
- const res = await api('/notes/timeline', { limit: 100 }, follower);
+ const res = await api('notes/timeline', { limit: 100 }, follower);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id === fol.id);
assert.strictEqual(notes[0].text, 'x');
@@ -431,21 +431,21 @@ describe('API visibility', () => {
//#region RTL
test('[replies] followers-reply が フォロワーから見れる', async () => {
- const res = await api('/notes/replies', { noteId: tgt.id, limit: 100 }, follower);
+ const res = await api('notes/replies', { noteId: tgt.id, limit: 100 }, follower);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id === folR.id);
assert.strictEqual(notes[0].text, 'x');
});
test('[replies] followers-reply が 非フォロワー (リプライ先ではない) から見れない', async () => {
- const res = await api('/notes/replies', { noteId: tgt.id, limit: 100 }, other);
+ const res = await api('notes/replies', { noteId: tgt.id, limit: 100 }, other);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id === folR.id);
assert.strictEqual(notes.length, 0);
});
test('[replies] followers-reply が 非フォロワー (リプライ先である) から見れる', async () => {
- const res = await api('/notes/replies', { noteId: tgt.id, limit: 100 }, target);
+ const res = await api('notes/replies', { noteId: tgt.id, limit: 100 }, target);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id === folR.id);
assert.strictEqual(notes[0].text, 'x');
@@ -454,14 +454,14 @@ describe('API visibility', () => {
//#region MTL
test('[mentions] followers-reply が 非フォロワー (リプライ先である) から見れる', async () => {
- const res = await api('/notes/mentions', { limit: 100 }, target);
+ const res = await api('notes/mentions', { limit: 100 }, target);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id === folR.id);
assert.strictEqual(notes[0].text, 'x');
});
test('[mentions] followers-mention が 非フォロワー (メンション先である) から見れる', async () => {
- const res = await api('/notes/mentions', { limit: 100 }, target);
+ const res = await api('notes/mentions', { limit: 100 }, target);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id === folM.id);
assert.strictEqual(notes[0].text, '@target x');
diff --git a/packages/backend/test/e2e/api.ts b/packages/backend/test/e2e/api.ts
index b6eeec99d7..49c6a0636b 100644
--- a/packages/backend/test/e2e/api.ts
+++ b/packages/backend/test/e2e/api.ts
@@ -23,32 +23,32 @@ import type * as misskey from 'misskey-js';
describe('API', () => {
let alice: misskey.entities.SignupResponse;
let bob: misskey.entities.SignupResponse;
- let carol: misskey.entities.SignupResponse;
beforeAll(async () => {
alice = await signup({ username: 'alice' });
bob = await signup({ username: 'bob' });
- carol = await signup({ username: 'carol' });
}, 1000 * 60 * 2);
describe('General validation', () => {
test('wrong type', async () => {
- const res = await api('/test', {
+ const res = await api('test', {
required: true,
+ // @ts-expect-error string must be string
string: 42,
});
assert.strictEqual(res.status, 400);
});
test('missing require param', async () => {
- const res = await api('/test', {
+ // @ts-expect-error required is required
+ const res = await api('test', {
string: 'a',
});
assert.strictEqual(res.status, 400);
});
test('invalid misskey:id (empty string)', async () => {
- const res = await api('/test', {
+ const res = await api('test', {
required: true,
id: '',
});
@@ -56,7 +56,7 @@ describe('API', () => {
});
test('valid misskey:id', async () => {
- const res = await api('/test', {
+ const res = await api('test', {
required: true,
id: '8wvhjghbxu',
});
@@ -64,7 +64,7 @@ describe('API', () => {
});
test('default value', async () => {
- const res = await api('/test', {
+ const res = await api('test', {
required: true,
string: 'a',
});
@@ -73,7 +73,7 @@ describe('API', () => {
});
test('can set null even if it has default value', async () => {
- const res = await api('/test', {
+ const res = await api('test', {
required: true,
nullableDefault: null,
});
@@ -82,7 +82,7 @@ describe('API', () => {
});
test('cannot set undefined if it has default value', async () => {
- const res = await api('/test', {
+ const res = await api('test', {
required: true,
nullableDefault: undefined,
});
@@ -99,14 +99,14 @@ describe('API', () => {
// aliceは管理者、APIを使える
await successfulApiCall({
- endpoint: '/admin/get-index-stats',
+ endpoint: 'admin/get-index-stats',
parameters: {},
user: alice,
});
// bobは一般ユーザーだからダメ
await failedApiCall({
- endpoint: '/admin/get-index-stats',
+ endpoint: 'admin/get-index-stats',
parameters: {},
user: bob,
}, {
@@ -117,7 +117,7 @@ describe('API', () => {
// publicアクセスももちろんダメ
await failedApiCall({
- endpoint: '/admin/get-index-stats',
+ endpoint: 'admin/get-index-stats',
parameters: {},
user: undefined,
}, {
@@ -128,7 +128,7 @@ describe('API', () => {
// ごまがしもダメ
await failedApiCall({
- endpoint: '/admin/get-index-stats',
+ endpoint: 'admin/get-index-stats',
parameters: {},
user: { token: 'tsukawasete' },
}, {
@@ -138,13 +138,13 @@ describe('API', () => {
});
await successfulApiCall({
- endpoint: '/admin/get-index-stats',
+ endpoint: 'admin/get-index-stats',
parameters: {},
user: { token: application2 },
});
await failedApiCall({
- endpoint: '/admin/get-index-stats',
+ endpoint: 'admin/get-index-stats',
parameters: {},
user: { token: application },
}, {
@@ -154,7 +154,7 @@ describe('API', () => {
});
await failedApiCall({
- endpoint: '/admin/get-index-stats',
+ endpoint: 'admin/get-index-stats',
parameters: {},
user: { token: application3 },
}, {
@@ -164,7 +164,7 @@ describe('API', () => {
});
await failedApiCall({
- endpoint: '/admin/get-index-stats',
+ endpoint: 'admin/get-index-stats',
parameters: {},
user: { token: application4 },
}, {
@@ -177,7 +177,7 @@ describe('API', () => {
describe('Authentication header', () => {
test('一般リクエスト', async () => {
await successfulApiCall({
- endpoint: '/admin/get-index-stats',
+ endpoint: 'admin/get-index-stats',
parameters: {},
user: {
token: alice.token,
@@ -211,7 +211,7 @@ describe('API', () => {
describe('tokenエラー応答でWWW-Authenticate headerを送る', () => {
describe('invalid_token', () => {
test('一般リクエスト', async () => {
- const result = await api('/admin/get-index-stats', {}, {
+ const result = await api('admin/get-index-stats', {}, {
token: 'syuilo',
bearer: true,
});
@@ -246,7 +246,7 @@ describe('API', () => {
describe('tokenがないとrealmだけおくる', () => {
test('一般リクエスト', async () => {
- const result = await api('/admin/get-index-stats', {});
+ const result = await api('admin/get-index-stats', {});
assert.strictEqual(result.status, 401);
assert.strictEqual(result.headers.get('WWW-Authenticate'), 'Bearer realm="Misskey"');
});
@@ -259,7 +259,8 @@ describe('API', () => {
});
test('invalid_request', async () => {
- const result = await api('/notes/create', { text: true }, {
+ // @ts-expect-error text must be string
+ const result = await api('notes/create', { text: true }, {
token: alice.token,
bearer: true,
});
diff --git a/packages/backend/test/e2e/block.ts b/packages/backend/test/e2e/block.ts
index cbd91e6e42..e4f798498f 100644
--- a/packages/backend/test/e2e/block.ts
+++ b/packages/backend/test/e2e/block.ts
@@ -22,7 +22,7 @@ describe('Block', () => {
}, 1000 * 60 * 2);
test('Block作成', async () => {
- const res = await api('/blocking/create', {
+ const res = await api('blocking/create', {
userId: bob.id,
}, alice);
@@ -30,7 +30,7 @@ describe('Block', () => {
});
test('ブロックされているユーザーをフォローできない', async () => {
- const res = await api('/following/create', { userId: alice.id }, bob);
+ const res = await api('following/create', { userId: alice.id }, bob);
assert.strictEqual(res.status, 400);
assert.strictEqual(res.body.error.id, 'c4ab57cc-4e41-45e9-bfd9-584f61e35ce0');
@@ -39,7 +39,7 @@ describe('Block', () => {
test('ブロックされているユーザーにリアクションできない', async () => {
const note = await post(alice, { text: 'hello' });
- const res = await api('/notes/reactions/create', { noteId: note.id, reaction: '👍' }, bob);
+ const res = await api('notes/reactions/create', { noteId: note.id, reaction: '👍' }, bob);
assert.strictEqual(res.status, 400);
assert.strictEqual(res.body.error.id, '20ef5475-9f38-4e4c-bd33-de6d979498ec');
@@ -48,7 +48,7 @@ describe('Block', () => {
test('ブロックされているユーザーに返信できない', async () => {
const note = await post(alice, { text: 'hello' });
- const res = await api('/notes/create', { replyId: note.id, text: 'yo' }, bob);
+ const res = await api('notes/create', { replyId: note.id, text: 'yo' }, bob);
assert.strictEqual(res.status, 400);
assert.strictEqual(res.body.error.id, 'b390d7e1-8a5e-46ed-b625-06271cafd3d3');
@@ -57,7 +57,7 @@ describe('Block', () => {
test('ブロックされているユーザーのノートをRenoteできない', async () => {
const note = await post(alice, { text: 'hello' });
- const res = await api('/notes/create', { renoteId: note.id, text: 'yo' }, bob);
+ const res = await api('notes/create', { renoteId: note.id, text: 'yo' }, bob);
assert.strictEqual(res.status, 400);
assert.strictEqual(res.body.error.id, 'b390d7e1-8a5e-46ed-b625-06271cafd3d3');
@@ -72,12 +72,13 @@ describe('Block', () => {
const bobNote = await post(bob, { text: 'hi' });
const carolNote = await post(carol, { text: 'hi' });
- const res = await api('/notes/local-timeline', {}, bob);
+ const res = await api('notes/local-timeline', {}, bob);
+ const body = res.body as misskey.entities.Note[];
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
- assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), false);
- assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
- assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
+ assert.strictEqual(body.some(note => note.id === aliceNote.id), false);
+ assert.strictEqual(body.some(note => note.id === bobNote.id), true);
+ assert.strictEqual(body.some(note => note.id === carolNote.id), true);
});
});
diff --git a/packages/backend/test/e2e/clips.ts b/packages/backend/test/e2e/clips.ts
index 2cf397e22d..ba6f9d6a65 100644
--- a/packages/backend/test/e2e/clips.ts
+++ b/packages/backend/test/e2e/clips.ts
@@ -6,47 +6,34 @@
process.env.NODE_ENV = 'test';
import * as assert from 'assert';
-import { JTDDataType } from 'ajv/dist/jtd';
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
-import type { Packed } from '@/misc/json-schema.js';
-import { paramDef as CreateParamDef } from '@/server/api/endpoints/clips/create.js';
-import { paramDef as UpdateParamDef } from '@/server/api/endpoints/clips/update.js';
-import { paramDef as DeleteParamDef } from '@/server/api/endpoints/clips/delete.js';
-import { paramDef as ShowParamDef } from '@/server/api/endpoints/clips/show.js';
-import { paramDef as FavoriteParamDef } from '@/server/api/endpoints/clips/favorite.js';
-import { paramDef as UnfavoriteParamDef } from '@/server/api/endpoints/clips/unfavorite.js';
-import { paramDef as AddNoteParamDef } from '@/server/api/endpoints/clips/add-note.js';
-import { paramDef as RemoveNoteParamDef } from '@/server/api/endpoints/clips/remove-note.js';
-import { paramDef as NotesParamDef } from '@/server/api/endpoints/clips/notes.js';
import { api, ApiRequest, failedApiCall, hiddenNote, post, signup, successfulApiCall } from '../utils.js';
+import type * as Misskey from 'misskey-js';
-describe('クリップ', () => {
- type User = Packed<'User'>;
- type Note = Packed<'Note'>;
- type Clip = Packed<'Clip'>;
+type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
- let alice: User;
- let bob: User;
- let aliceNote: Note;
- let aliceHomeNote: Note;
- let aliceFollowersNote: Note;
- let aliceSpecifiedNote: Note;
- let bobNote: Note;
- let bobHomeNote: Note;
- let bobFollowersNote: Note;
- let bobSpecifiedNote: Note;
+describe('クリップ', () => {
+ let alice: Misskey.entities.SignupResponse;
+ let bob: Misskey.entities.SignupResponse;
+ let aliceNote: Misskey.entities.Note;
+ let aliceHomeNote: Misskey.entities.Note;
+ let aliceFollowersNote: Misskey.entities.Note;
+ let aliceSpecifiedNote: Misskey.entities.Note;
+ let bobNote: Misskey.entities.Note;
+ let bobHomeNote: Misskey.entities.Note;
+ let bobFollowersNote: Misskey.entities.Note;
+ let bobSpecifiedNote: Misskey.entities.Note;
const compareBy = <T extends { id: string }, >(selector: (s: T) => string = (s: T): string => s.id) => (a: T, b: T): number => {
return selector(a).localeCompare(selector(b));
};
- type CreateParam = JTDDataType<typeof CreateParamDef>;
- const defaultCreate = (): Partial<CreateParam> => ({
+ const defaultCreate = (): Pick<Misskey.entities.ClipsCreateRequest, 'name'> => ({
name: 'test',
});
- const create = async (parameters: Partial<CreateParam> = {}, request: Partial<ApiRequest> = {}): Promise<Clip> => {
- const clip = await successfulApiCall<Clip>({
- endpoint: '/clips/create',
+ const create = async (parameters: Partial<Misskey.entities.ClipsCreateRequest> = {}, request: Partial<ApiRequest<'clips/create'>> = {}): Promise<Misskey.entities.Clip> => {
+ const clip = await successfulApiCall({
+ endpoint: 'clips/create',
parameters: {
...defaultCreate(),
...parameters,
@@ -64,17 +51,16 @@ describe('クリップ', () => {
return clip;
};
- const createMany = async (parameters: Partial<CreateParam>, count = 10, user = alice): Promise<Clip[]> => {
+ const createMany = async (parameters: Partial<Misskey.entities.ClipsCreateRequest>, count = 10, user = alice): Promise<Misskey.entities.Clip[]> => {
return await Promise.all([...Array(count)].map((_, i) => create({
name: `test${i}`,
...parameters,
}, { user })));
};
- type UpdateParam = JTDDataType<typeof UpdateParamDef>;
- const update = async (parameters: Partial<UpdateParam>, request: Partial<ApiRequest> = {}): Promise<Clip> => {
- const clip = await successfulApiCall<Clip>({
- endpoint: '/clips/update',
+ const update = async (parameters: Optional<Misskey.entities.ClipsUpdateRequest, 'name'>, request: Partial<ApiRequest<'clips/update'>> = {}): Promise<Misskey.entities.Clip> => {
+ const clip = await successfulApiCall({
+ endpoint: 'clips/update',
parameters: {
name: 'updated',
...parameters,
@@ -92,41 +78,39 @@ describe('クリップ', () => {
return clip;
};
- type DeleteParam = JTDDataType<typeof DeleteParamDef>;
- const deleteClip = async (parameters: DeleteParam, request: Partial<ApiRequest> = {}): Promise<void> => {
- return await successfulApiCall<void>({
- endpoint: '/clips/delete',
+ const deleteClip = async (parameters: Misskey.entities.ClipsDeleteRequest, request: Partial<ApiRequest<'clips/delete'>> = {}): Promise<void> => {
+ return await successfulApiCall({
+ endpoint: 'clips/delete',
parameters,
user: alice,
...request,
}, {
status: 204,
- });
+ }) as any as void;
};
- type ShowParam = JTDDataType<typeof ShowParamDef>;
- const show = async (parameters: ShowParam, request: Partial<ApiRequest> = {}): Promise<Clip> => {
- return await successfulApiCall<Clip>({
- endpoint: '/clips/show',
+ const show = async (parameters: Misskey.entities.ClipsShowRequest, request: Partial<ApiRequest<'clips/show'>> = {}): Promise<Misskey.entities.Clip> => {
+ return await successfulApiCall({
+ endpoint: 'clips/show',
parameters,
user: alice,
...request,
});
};
- const list = async (request: Partial<ApiRequest>): Promise<Clip[]> => {
- return successfulApiCall<Clip[]>({
- endpoint: '/clips/list',
+ const list = async (request: Partial<ApiRequest<'clips/list'>>): Promise<Misskey.entities.Clip[]> => {
+ return successfulApiCall({
+ endpoint: 'clips/list',
parameters: {},
user: alice,
...request,
});
};
- const usersClips = async (request: Partial<ApiRequest>): Promise<Clip[]> => {
- return await successfulApiCall<Clip[]>({
- endpoint: '/users/clips',
- parameters: {},
+ const usersClips = async (parameters: Misskey.entities.UsersClipsRequest, request: Partial<ApiRequest<'users/clips'>> = {}): Promise<Misskey.entities.Clip[]> => {
+ return await successfulApiCall({
+ endpoint: 'users/clips',
+ parameters,
user: alice,
...request,
});
@@ -136,23 +120,22 @@ describe('クリップ', () => {
alice = await signup({ username: 'alice' });
bob = await signup({ username: 'bob' });
- // FIXME: misskey-jsのNoteはoutdatedなので直接変換できない
- aliceNote = await post(alice, { text: 'test' }) as any;
- aliceHomeNote = await post(alice, { text: 'home only', visibility: 'home' }) as any;
- aliceFollowersNote = await post(alice, { text: 'followers only', visibility: 'followers' }) as any;
- aliceSpecifiedNote = await post(alice, { text: 'specified only', visibility: 'specified' }) as any;
- bobNote = await post(bob, { text: 'test' }) as any;
- bobHomeNote = await post(bob, { text: 'home only', visibility: 'home' }) as any;
- bobFollowersNote = await post(bob, { text: 'followers only', visibility: 'followers' }) as any;
- bobSpecifiedNote = await post(bob, { text: 'specified only', visibility: 'specified' }) as any;
+ aliceNote = await post(alice, { text: 'test' });
+ aliceHomeNote = await post(alice, { text: 'home only', visibility: 'home' });
+ aliceFollowersNote = await post(alice, { text: 'followers only', visibility: 'followers' });
+ aliceSpecifiedNote = await post(alice, { text: 'specified only', visibility: 'specified' });
+ bobNote = await post(bob, { text: 'test' });
+ bobHomeNote = await post(bob, { text: 'home only', visibility: 'home' });
+ bobFollowersNote = await post(bob, { text: 'followers only', visibility: 'followers' });
+ bobSpecifiedNote = await post(bob, { text: 'specified only', visibility: 'specified' });
}, 1000 * 60 * 2);
afterEach(async () => {
// テスト間で影響し合わないように毎回全部消す。
for (const user of [alice, bob]) {
- const list = await api('/clips/list', { limit: 11 }, user);
+ const list = await api('clips/list', { limit: 11 }, user);
for (const clip of list.body) {
- await api('/clips/delete', { clipId: clip.id }, user);
+ await api('clips/delete', { clipId: clip.id }, user);
}
}
});
@@ -177,7 +160,7 @@ describe('クリップ', () => {
}
await failedApiCall({
- endpoint: '/clips/create',
+ endpoint: 'clips/create',
parameters: defaultCreate(),
user: alice,
}, {
@@ -204,7 +187,8 @@ describe('クリップ', () => {
{ label: 'descriptionが最大長+1', parameters: { description: 'a'.repeat(2049) } },
];
test.each(createClipDenyPattern)('の作成は$labelならできない', async ({ parameters }) => failedApiCall({
- endpoint: '/clips/create',
+ endpoint: 'clips/create',
+ // @ts-expect-error invalid params
parameters: {
...defaultCreate(),
...parameters,
@@ -246,15 +230,15 @@ describe('クリップ', () => {
code: 'NO_SUCH_CLIP',
id: 'b4d92d70-b216-46fa-9a3f-a8c811699257',
} },
- { label: '他人のクリップ', user: (): User => bob, assertion: {
+ { label: '他人のクリップ', user: () => bob, assertion: {
code: 'NO_SUCH_CLIP',
id: 'b4d92d70-b216-46fa-9a3f-a8c811699257',
} },
...createClipDenyPattern as any,
])('の更新は$labelならできない', async ({ parameters, user, assertion }) => failedApiCall({
- endpoint: '/clips/update',
+ endpoint: 'clips/update',
parameters: {
- clipId: (await create({}, { user: (user ?? ((): User => alice))() })).id,
+ clipId: (await create({}, { user: (user ?? (() => alice))() })).id,
name: 'updated',
...parameters,
},
@@ -279,14 +263,15 @@ describe('クリップ', () => {
code: 'NO_SUCH_CLIP',
id: '70ca08ba-6865-4630-b6fb-8494759aa754',
} },
- { label: '他人のクリップ', user: (): User => bob, assertion: {
+ { label: '他人のクリップ', user: () => bob, assertion: {
code: 'NO_SUCH_CLIP',
id: '70ca08ba-6865-4630-b6fb-8494759aa754',
} },
])('の削除は$labelならできない', async ({ parameters, user, assertion }) => failedApiCall({
- endpoint: '/clips/delete',
+ endpoint: 'clips/delete',
parameters: {
- clipId: (await create({}, { user: (user ?? ((): User => alice))() })).id,
+ // @ts-expect-error clipId must not be null
+ clipId: (await create({}, { user: (user ?? (() => alice))() })).id,
...parameters,
},
user: alice,
@@ -306,7 +291,7 @@ describe('クリップ', () => {
test('のID指定取得は他人のPrivateなクリップは取得できない', async () => {
const clip = await create({ isPublic: false }, { user: bob } );
failedApiCall({
- endpoint: '/clips/show',
+ endpoint: 'clips/show',
parameters: { clipId: clip.id },
user: alice,
}, {
@@ -323,7 +308,8 @@ describe('クリップ', () => {
id: 'c3c5fe33-d62c-44d2-9ea5-d997703f5c20',
} },
])('のID指定取得は$labelならできない', async ({ parameters, assetion }) => failedApiCall({
- endpoint: '/clips/show',
+ endpoint: 'clips/show',
+ // @ts-expect-error clipId must not be undefined
parameters: {
...parameters,
},
@@ -356,27 +342,23 @@ describe('クリップ', () => {
test('の一覧が取得できる(空)', async () => {
const res = await usersClips({
- parameters: {
- userId: alice.id,
- },
+ userId: alice.id,
});
assert.deepStrictEqual(res, []);
});
test.each([
{ label: '' },
- { label: '他人アカウントから', user: (): User => bob },
+ { label: '他人アカウントから', user: () => bob },
])('の一覧が$label取得できる', async () => {
const clips = await createMany({ isPublic: true });
const res = await usersClips({
- parameters: {
- userId: alice.id,
- },
+ userId: alice.id,
});
// 返ってくる配列には順序保障がないのでidでソートして厳密比較
assert.deepStrictEqual(
- res.sort(compareBy<Clip>(s => s.id)),
+ res.sort(compareBy<Misskey.entities.Clip>(s => s.id)),
clips.sort(compareBy(s => s.id)));
// 認証状態で見たときだけisFavoritedが入っている
@@ -386,17 +368,16 @@ describe('クリップ', () => {
});
test.each([
- { label: '未認証', user: (): undefined => undefined },
+ { label: '未認証', user: () => undefined },
{ label: '存在しないユーザーのもの', parameters: { userId: 'xxxxxxx' } },
])('の一覧は$labelでも取得できる', async ({ parameters, user }) => {
const clips = await createMany({ isPublic: true });
const res = await usersClips({
- parameters: {
- userId: alice.id,
- limit: clips.length,
- ...parameters,
- },
- user: (user ?? ((): User => alice))(),
+ userId: alice.id,
+ limit: clips.length,
+ ...parameters,
+ }, {
+ user: (user ?? (() => alice))(),
});
// 未認証で見たときはisFavoritedは入らない
@@ -409,10 +390,8 @@ describe('クリップ', () => {
await create({ isPublic: false });
const aliceClip = await create({ isPublic: true });
const res = await usersClips({
- parameters: {
- userId: alice.id,
- limit: 2,
- },
+ userId: alice.id,
+ limit: 2,
});
assert.deepStrictEqual(res, [aliceClip]);
});
@@ -421,17 +400,15 @@ describe('クリップ', () => {
const clips = await createMany({ isPublic: true }, 7);
clips.sort(compareBy(s => s.id));
const res = await usersClips({
- parameters: {
- userId: alice.id,
- sinceId: clips[1].id,
- untilId: clips[5].id,
- limit: 4,
- },
+ userId: alice.id,
+ sinceId: clips[1].id,
+ untilId: clips[5].id,
+ limit: 4,
});
// Promise.allで返ってくる配列には順序保障がないのでidでソートして厳密比較
assert.deepStrictEqual(
- res.sort(compareBy<Clip>(s => s.id)),
+ res.sort(compareBy<Misskey.entities.Clip>(s => s.id)),
[clips[2], clips[3], clips[4]], // sinceIdとuntilId自体は結果に含まれない
clips[1].id + ' ... ' + clips[3].id + ' with ' + clips.map(s => s.id) + ' vs. ' + res.map(s => s.id));
});
@@ -441,8 +418,9 @@ describe('クリップ', () => {
{ label: 'limitゼロ', parameters: { limit: 0 } },
{ label: 'limit最大+1', parameters: { limit: 101 } },
])('の一覧は$labelだと取得できない', async ({ parameters }) => failedApiCall({
- endpoint: '/users/clips',
+ endpoint: 'users/clips',
parameters: {
+ // @ts-expect-error userId must not be undefined
userId: alice.id,
...parameters,
},
@@ -454,15 +432,15 @@ describe('クリップ', () => {
}));
test.each([
- { label: '作成', endpoint: '/clips/create' },
- { label: '更新', endpoint: '/clips/update' },
- { label: '削除', endpoint: '/clips/delete' },
- { label: '取得', endpoint: '/clips/list' },
- { label: 'お気に入り設定', endpoint: '/clips/favorite' },
- { label: 'お気に入り解除', endpoint: '/clips/unfavorite' },
- { label: 'お気に入り取得', endpoint: '/clips/my-favorites' },
- { label: 'ノート追加', endpoint: '/clips/add-note' },
- { label: 'ノート削除', endpoint: '/clips/remove-note' },
+ { label: '作成', endpoint: 'clips/create' as const },
+ { label: '更新', endpoint: 'clips/update' as const },
+ { label: '削除', endpoint: 'clips/delete' as const },
+ { label: '取得', endpoint: 'clips/list' as const },
+ { label: 'お気に入り設定', endpoint: 'clips/favorite' as const },
+ { label: 'お気に入り解除', endpoint: 'clips/unfavorite' as const },
+ { label: 'お気に入り取得', endpoint: 'clips/my-favorites' as const },
+ { label: 'ノート追加', endpoint: 'clips/add-note' as const },
+ { label: 'ノート削除', endpoint: 'clips/remove-note' as const },
])('の$labelは未認証ではできない', async ({ endpoint }) => await failedApiCall({
endpoint: endpoint,
parameters: {},
@@ -474,35 +452,33 @@ describe('クリップ', () => {
}));
describe('のお気に入り', () => {
- let aliceClip: Clip;
+ let aliceClip: Misskey.entities.Clip;
- type FavoriteParam = JTDDataType<typeof FavoriteParamDef>;
- const favorite = async (parameters: FavoriteParam, request: Partial<ApiRequest> = {}): Promise<void> => {
- return successfulApiCall<void>({
- endpoint: '/clips/favorite',
+ const favorite = async (parameters: Misskey.entities.ClipsFavoriteRequest, request: Partial<ApiRequest<'clips/favorite'>> = {}): Promise<void> => {
+ return successfulApiCall({
+ endpoint: 'clips/favorite',
parameters,
user: alice,
...request,
}, {
status: 204,
- });
+ }) as any as void;
};
- type UnfavoriteParam = JTDDataType<typeof UnfavoriteParamDef>;
- const unfavorite = async (parameters: UnfavoriteParam, request: Partial<ApiRequest> = {}): Promise<void> => {
- return successfulApiCall<void>({
- endpoint: '/clips/unfavorite',
+ const unfavorite = async (parameters: Misskey.entities.ClipsUnfavoriteRequest, request: Partial<ApiRequest<'clips/unfavorite'>> = {}): Promise<void> => {
+ return successfulApiCall({
+ endpoint: 'clips/unfavorite',
parameters,
user: alice,
...request,
}, {
status: 204,
- });
+ }) as any as void;
};
- const myFavorites = async (request: Partial<ApiRequest> = {}): Promise<Clip[]> => {
- return successfulApiCall<Clip[]>({
- endpoint: '/clips/my-favorites',
+ const myFavorites = async (request: Partial<ApiRequest<'clips/my-favorites'>> = {}): Promise<Misskey.entities.Clip[]> => {
+ return successfulApiCall({
+ endpoint: 'clips/my-favorites',
parameters: {},
user: alice,
...request,
@@ -568,7 +544,7 @@ describe('クリップ', () => {
test('は同じクリップに対して二回設定できない。', async () => {
await favorite({ clipId: aliceClip.id });
await failedApiCall({
- endpoint: '/clips/favorite',
+ endpoint: 'clips/favorite',
parameters: {
clipId: aliceClip.id,
},
@@ -586,14 +562,15 @@ describe('クリップ', () => {
code: 'NO_SUCH_CLIP',
id: '4c2aaeae-80d8-4250-9606-26cb1fdb77a5',
} },
- { label: '他人のクリップ', user: (): User => bob, assertion: {
+ { label: '他人のクリップ', user: () => bob, assertion: {
code: 'NO_SUCH_CLIP',
id: '4c2aaeae-80d8-4250-9606-26cb1fdb77a5',
} },
])('の設定は$labelならできない', async ({ parameters, user, assertion }) => failedApiCall({
- endpoint: '/clips/favorite',
+ endpoint: 'clips/favorite',
parameters: {
- clipId: (await create({}, { user: (user ?? ((): User => alice))() })).id,
+ // @ts-expect-error clipId must not be null
+ clipId: (await create({}, { user: (user ?? (() => alice))() })).id,
...parameters,
},
user: alice,
@@ -619,7 +596,7 @@ describe('クリップ', () => {
code: 'NO_SUCH_CLIP',
id: '2603966e-b865-426c-94a7-af4a01241dc1',
} },
- { label: '他人のクリップ', user: (): User => bob, assertion: {
+ { label: '他人のクリップ', user: () => bob, assertion: {
code: 'NOT_FAVORITED',
id: '90c3a9e8-b321-4dae-bf57-2bf79bbcc187',
} },
@@ -628,9 +605,10 @@ describe('クリップ', () => {
id: '90c3a9e8-b321-4dae-bf57-2bf79bbcc187',
} },
])('の設定解除は$labelならできない', async ({ parameters, user, assertion }) => failedApiCall({
- endpoint: '/clips/unfavorite',
+ endpoint: 'clips/unfavorite',
parameters: {
- clipId: (await create({}, { user: (user ?? ((): User => alice))() })).id,
+ // @ts-expect-error clipId must not be null
+ clipId: (await create({}, { user: (user ?? (() => alice))() })).id,
...parameters,
},
user: alice,
@@ -655,41 +633,38 @@ describe('クリップ', () => {
});
describe('に紐づくノート', () => {
- let aliceClip: Clip;
+ let aliceClip: Misskey.entities.Clip;
- const sampleNotes = (): Note[] => [
+ const sampleNotes = (): Misskey.entities.Note[] => [
aliceNote, aliceHomeNote, aliceFollowersNote, aliceSpecifiedNote,
bobNote, bobHomeNote, bobFollowersNote, bobSpecifiedNote,
];
- type AddNoteParam = JTDDataType<typeof AddNoteParamDef>;
- const addNote = async (parameters: AddNoteParam, request: Partial<ApiRequest> = {}): Promise<void> => {
- return successfulApiCall<void>({
- endpoint: '/clips/add-note',
+ const addNote = async (parameters: Misskey.entities.ClipsAddNoteRequest, request: Partial<ApiRequest<'clips/add-note'>> = {}): Promise<void> => {
+ return successfulApiCall({
+ endpoint: 'clips/add-note',
parameters,
user: alice,
...request,
}, {
status: 204,
- });
+ }) as any as void;
};
- type RemoveNoteParam = JTDDataType<typeof RemoveNoteParamDef>;
- const removeNote = async (parameters: RemoveNoteParam, request: Partial<ApiRequest> = {}): Promise<void> => {
- return successfulApiCall<void>({
- endpoint: '/clips/remove-note',
+ const removeNote = async (parameters: Misskey.entities.ClipsRemoveNoteRequest, request: Partial<ApiRequest<'clips/remove-note'>> = {}): Promise<void> => {
+ return successfulApiCall({
+ endpoint: 'clips/remove-note',
parameters,
user: alice,
...request,
}, {
status: 204,
- });
+ }) as any as void;
};
- type NotesParam = JTDDataType<typeof NotesParamDef>;
- const notes = async (parameters: Partial<NotesParam>, request: Partial<ApiRequest> = {}): Promise<Note[]> => {
- return successfulApiCall<Note[]>({
- endpoint: '/clips/notes',
+ const notes = async (parameters: Misskey.entities.ClipsNotesRequest, request: Partial<ApiRequest<'clips/notes'>> = {}): Promise<Misskey.entities.Note[]> => {
+ return successfulApiCall({
+ endpoint: 'clips/notes',
parameters,
user: alice,
...request,
@@ -715,7 +690,7 @@ describe('クリップ', () => {
test('として同じノートを二回紐づけることはできない', async () => {
await addNote({ clipId: aliceClip.id, noteId: aliceNote.id });
await failedApiCall({
- endpoint: '/clips/add-note',
+ endpoint: 'clips/add-note',
parameters: {
clipId: aliceClip.id,
noteId: aliceNote.id,
@@ -733,11 +708,11 @@ describe('クリップ', () => {
const noteLimit = DEFAULT_POLICIES.noteEachClipsLimit + 1;
const noteList = await Promise.all([...Array(noteLimit)].map((_, i) => post(alice, {
text: `test ${i}`,
- }) as unknown)) as Note[];
+ }) as unknown)) as Misskey.entities.Note[];
await Promise.all(noteList.map(s => addNote({ clipId: aliceClip.id, noteId: s.id })));
await failedApiCall({
- endpoint: '/clips/add-note',
+ endpoint: 'clips/add-note',
parameters: {
clipId: aliceClip.id,
noteId: aliceNote.id,
@@ -751,7 +726,7 @@ describe('クリップ', () => {
});
test('は他人のクリップへ追加できない。', async () => await failedApiCall({
- endpoint: '/clips/add-note',
+ endpoint: 'clips/add-note',
parameters: {
clipId: aliceClip.id,
noteId: aliceNote.id,
@@ -774,18 +749,20 @@ describe('クリップ', () => {
code: 'NO_SUCH_NOTE',
id: 'fc8c0b49-c7a3-4664-a0a6-b418d386bb8b',
} },
- { label: '他人のクリップ', user: (): object => bob, assetion: {
+ { label: '他人のクリップ', user: () => bob, assetion: {
code: 'NO_SUCH_CLIP',
id: 'd6e76cc0-a1b5-4c7c-a287-73fa9c716dcf',
} },
])('の追加は$labelだとできない', async ({ parameters, user, assetion }) => failedApiCall({
- endpoint: '/clips/add-note',
+ endpoint: 'clips/add-note',
parameters: {
+ // @ts-expect-error clipId must not be undefined
clipId: aliceClip.id,
+ // @ts-expect-error noteId must not be undefined
noteId: aliceNote.id,
...parameters,
},
- user: (user ?? ((): User => alice))(),
+ user: (user ?? (() => alice))(),
}, {
status: 400,
code: 'INVALID_PARAM',
@@ -810,18 +787,20 @@ describe('クリップ', () => {
code: 'NO_SUCH_NOTE',
id: 'aff017de-190e-434b-893e-33a9ff5049d8', // add-noteと異なる
} },
- { label: '他人のクリップ', user: (): object => bob, assetion: {
+ { label: '他人のクリップ', user: () => bob, assetion: {
code: 'NO_SUCH_CLIP',
id: 'b80525c6-97f7-49d7-a42d-ebccd49cfd52', // add-noteと異なる
} },
])('の削除は$labelだとできない', async ({ parameters, user, assetion }) => failedApiCall({
- endpoint: '/clips/remove-note',
+ endpoint: 'clips/remove-note',
parameters: {
+ // @ts-expect-error clipId must not be undefined
clipId: aliceClip.id,
+ // @ts-expect-error noteId must not be undefined
noteId: aliceNote.id,
...parameters,
},
- user: (user ?? ((): User => alice))(),
+ user: (user ?? (() => alice))(),
}, {
status: 400,
code: 'INVALID_PARAM',
@@ -925,21 +904,22 @@ describe('クリップ', () => {
code: 'NO_SUCH_CLIP',
id: '1d7645e6-2b6d-4635-b0fe-fe22b0e72e00',
} },
- { label: '他人のPrivateなクリップから', user: (): object => bob, assertion: {
+ { label: '他人のPrivateなクリップから', user: () => bob, assertion: {
code: 'NO_SUCH_CLIP',
id: '1d7645e6-2b6d-4635-b0fe-fe22b0e72e00',
} },
- { label: '未認証でPrivateなクリップから', user: (): undefined => undefined, assertion: {
+ { label: '未認証でPrivateなクリップから', user: () => undefined, assertion: {
code: 'NO_SUCH_CLIP',
id: '1d7645e6-2b6d-4635-b0fe-fe22b0e72e00',
} },
])('は$labelだと取得できない', async ({ parameters, user, assertion }) => failedApiCall({
- endpoint: '/clips/notes',
+ endpoint: 'clips/notes',
parameters: {
+ // @ts-expect-error clipId must not be undefined
clipId: aliceClip.id,
...parameters,
},
- user: (user ?? ((): User => alice))(),
+ user: (user ?? (() => alice))(),
}, {
status: 400,
code: 'INVALID_PARAM',
diff --git a/packages/backend/test/e2e/drive.ts b/packages/backend/test/e2e/drive.ts
index 22ec66e2af..828c5200ef 100644
--- a/packages/backend/test/e2e/drive.ts
+++ b/packages/backend/test/e2e/drive.ts
@@ -6,22 +6,14 @@
process.env.NODE_ENV = 'test';
import * as assert from 'assert';
-import { MiNote } from '@/models/Note.js';
-import { api, initTestDb, makeStreamCatcher, post, signup, uploadFile } from '../utils.js';
+import { api, makeStreamCatcher, post, signup, uploadFile } from '../utils.js';
import type * as misskey from 'misskey-js';
-import type{ Repository } from 'typeorm'
-import type { Packed } from '@/misc/json-schema.js';
-
describe('Drive', () => {
- let Notes: Repository<MiNote>;
-
let alice: misskey.entities.SignupResponse;
let bob: misskey.entities.SignupResponse;
beforeAll(async () => {
- const connection = await initTestDb(true);
- Notes = connection.getRepository(MiNote);
alice = await signup({ username: 'alice' });
bob = await signup({ username: 'bob' });
}, 1000 * 60 * 2);
@@ -31,13 +23,13 @@ describe('Drive', () => {
const marker = Math.random().toString();
- const url = 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg'
+ const url = 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg';
const catcher = makeStreamCatcher(
alice,
'main',
(msg) => msg.type === 'urlUploadFinished' && msg.body.marker === marker,
- (msg) => msg.body.file as Packed<'DriveFile'>,
+ (msg) => msg.body.file,
10 * 1000);
const res = await api('drive/files/upload-from-url', {
@@ -51,7 +43,7 @@ describe('Drive', () => {
assert.strictEqual(res.status, 204);
assert.strictEqual(file.name, 'Lenna.jpg');
assert.strictEqual(file.type, 'image/jpeg');
- })
+ });
test('ローカルからアップロードできる', async () => {
// APIレスポンスを直接使用するので utils.js uploadFile が通過することで成功とする
@@ -59,27 +51,27 @@ describe('Drive', () => {
const res = await uploadFile(alice, { path: 'Lenna.jpg', name: 'テスト画像' });
assert.strictEqual(res.body?.name, 'テスト画像.jpg');
- assert.strictEqual(res.body?.type, 'image/jpeg');
- })
+ assert.strictEqual(res.body.type, 'image/jpeg');
+ });
test('添付ノート一覧を取得できる', async () => {
- const ids = (await Promise.all([uploadFile(alice), uploadFile(alice), uploadFile(alice)])).map(elm => elm.body!.id)
+ const ids = (await Promise.all([uploadFile(alice), uploadFile(alice), uploadFile(alice)])).map(elm => elm.body!.id);
const note0 = await post(alice, { fileIds: [ids[0]] });
const note1 = await post(alice, { fileIds: [ids[0], ids[1]] });
const attached0 = await api('drive/files/attached-notes', { fileId: ids[0] }, alice);
assert.strictEqual(attached0.body.length, 2);
- assert.strictEqual(attached0.body[0].id, note1.id)
- assert.strictEqual(attached0.body[1].id, note0.id)
+ assert.strictEqual(attached0.body[0].id, note1.id);
+ assert.strictEqual(attached0.body[1].id, note0.id);
const attached1 = await api('drive/files/attached-notes', { fileId: ids[1] }, alice);
assert.strictEqual(attached1.body.length, 1);
- assert.strictEqual(attached1.body[0].id, note1.id)
+ assert.strictEqual(attached1.body[0].id, note1.id);
const attached2 = await api('drive/files/attached-notes', { fileId: ids[2] }, alice);
- assert.strictEqual(attached2.body.length, 0)
- })
+ assert.strictEqual(attached2.body.length, 0);
+ });
test('添付ノート一覧は他の人から見えない', async () => {
const file = await uploadFile(alice);
@@ -89,7 +81,5 @@ describe('Drive', () => {
const res = await api('drive/files/attached-notes', { fileId: file.body!.id }, bob);
assert.strictEqual(res.status, 400);
assert.strictEqual('error' in res.body, true);
-
- })
+ });
});
-
diff --git a/packages/backend/test/e2e/endpoints.ts b/packages/backend/test/e2e/endpoints.ts
index d469597805..bc89dc37f4 100644
--- a/packages/backend/test/e2e/endpoints.ts
+++ b/packages/backend/test/e2e/endpoints.ts
@@ -79,6 +79,7 @@ describe('Endpoints', () => {
test('クエリをインジェクションできない', async () => {
const res = await api('signin', {
username: 'test1',
+ // @ts-expect-error password must be string
password: {
$gt: '',
},
@@ -103,7 +104,7 @@ describe('Endpoints', () => {
const myLocation = '七森中';
const myBirthday = '2000-09-07';
- const res = await api('/i/update', {
+ const res = await api('i/update', {
name: myName,
location: myLocation,
birthday: myBirthday,
@@ -117,7 +118,7 @@ describe('Endpoints', () => {
});
test('名前を空白にできる', async () => {
- const res = await api('/i/update', {
+ const res = await api('i/update', {
name: ' ',
}, alice);
assert.strictEqual(res.status, 200);
@@ -125,11 +126,11 @@ describe('Endpoints', () => {
});
test('誕生日の設定を削除できる', async () => {
- await api('/i/update', {
+ await api('i/update', {
birthday: '2000-09-07',
}, alice);
- const res = await api('/i/update', {
+ const res = await api('i/update', {
birthday: null,
}, alice);
@@ -139,7 +140,7 @@ describe('Endpoints', () => {
});
test('不正な誕生日の形式で怒られる', async () => {
- const res = await api('/i/update', {
+ const res = await api('i/update', {
birthday: '2000/09/07',
}, alice);
assert.strictEqual(res.status, 400);
@@ -148,7 +149,7 @@ describe('Endpoints', () => {
describe('users/show', () => {
test('ユーザーが取得できる', async () => {
- const res = await api('/users/show', {
+ const res = await api('users/show', {
userId: alice.id,
}, alice);
@@ -158,14 +159,14 @@ describe('Endpoints', () => {
});
test('ユーザーが存在しなかったら怒る', async () => {
- const res = await api('/users/show', {
+ const res = await api('users/show', {
userId: '000000000000000000000000',
});
assert.strictEqual(res.status, 404);
});
test('間違ったIDで怒られる', async () => {
- const res = await api('/users/show', {
+ const res = await api('users/show', {
userId: 'kyoppie',
});
assert.strictEqual(res.status, 404);
@@ -178,7 +179,7 @@ describe('Endpoints', () => {
text: 'test',
});
- const res = await api('/notes/show', {
+ const res = await api('notes/show', {
noteId: myPost.id,
}, alice);
@@ -189,14 +190,14 @@ describe('Endpoints', () => {
});
test('投稿が存在しなかったら怒る', async () => {
- const res = await api('/notes/show', {
+ const res = await api('notes/show', {
noteId: '000000000000000000000000',
});
assert.strictEqual(res.status, 400);
});
test('間違ったIDで怒られる', async () => {
- const res = await api('/notes/show', {
+ const res = await api('notes/show', {
noteId: 'kyoppie',
});
assert.strictEqual(res.status, 400);
@@ -207,14 +208,14 @@ describe('Endpoints', () => {
test('リアクションできる', async () => {
const bobPost = await post(bob, { text: 'hi' });
- const res = await api('/notes/reactions/create', {
+ const res = await api('notes/reactions/create', {
noteId: bobPost.id,
reaction: '🚀',
}, alice);
assert.strictEqual(res.status, 204);
- const resNote = await api('/notes/show', {
+ const resNote = await api('notes/show', {
noteId: bobPost.id,
}, alice);
@@ -225,7 +226,7 @@ describe('Endpoints', () => {
test('自分の投稿にもリアクションできる', async () => {
const myPost = await post(alice, { text: 'hi' });
- const res = await api('/notes/reactions/create', {
+ const res = await api('notes/reactions/create', {
noteId: myPost.id,
reaction: '🚀',
}, alice);
@@ -236,19 +237,19 @@ describe('Endpoints', () => {
test('二重にリアクションすると上書きされる', async () => {
const bobPost = await post(bob, { text: 'hi' });
- await api('/notes/reactions/create', {
+ await api('notes/reactions/create', {
noteId: bobPost.id,
reaction: '🥰',
}, alice);
- const res = await api('/notes/reactions/create', {
+ const res = await api('notes/reactions/create', {
noteId: bobPost.id,
reaction: '🚀',
}, alice);
assert.strictEqual(res.status, 204);
- const resNote = await api('/notes/show', {
+ const resNote = await api('notes/show', {
noteId: bobPost.id,
}, alice);
@@ -257,7 +258,7 @@ describe('Endpoints', () => {
});
test('存在しない投稿にはリアクションできない', async () => {
- const res = await api('/notes/reactions/create', {
+ const res = await api('notes/reactions/create', {
noteId: '000000000000000000000000',
reaction: '🚀',
}, alice);
@@ -266,13 +267,14 @@ describe('Endpoints', () => {
});
test('空のパラメータで怒られる', async () => {
- const res = await api('/notes/reactions/create', {}, alice);
+ // @ts-expect-error param must not be empty
+ const res = await api('notes/reactions/create', {}, alice);
assert.strictEqual(res.status, 400);
});
test('間違ったIDで怒られる', async () => {
- const res = await api('/notes/reactions/create', {
+ const res = await api('notes/reactions/create', {
noteId: 'kyoppie',
reaction: '🚀',
}, alice);
@@ -283,7 +285,7 @@ describe('Endpoints', () => {
describe('following/create', () => {
test('フォローできる', async () => {
- const res = await api('/following/create', {
+ const res = await api('following/create', {
userId: alice.id,
}, bob);
@@ -301,7 +303,7 @@ describe('Endpoints', () => {
});
test('既にフォローしている場合は怒る', async () => {
- const res = await api('/following/create', {
+ const res = await api('following/create', {
userId: alice.id,
}, bob);
@@ -309,7 +311,7 @@ describe('Endpoints', () => {
});
test('存在しないユーザーはフォローできない', async () => {
- const res = await api('/following/create', {
+ const res = await api('following/create', {
userId: '000000000000000000000000',
}, alice);
@@ -317,7 +319,7 @@ describe('Endpoints', () => {
});
test('自分自身はフォローできない', async () => {
- const res = await api('/following/create', {
+ const res = await api('following/create', {
userId: alice.id,
}, alice);
@@ -325,13 +327,14 @@ describe('Endpoints', () => {
});
test('空のパラメータで怒られる', async () => {
- const res = await api('/following/create', {}, alice);
+ // @ts-expect-error params must not be empty
+ const res = await api('following/create', {}, alice);
assert.strictEqual(res.status, 400);
});
test('間違ったIDで怒られる', async () => {
- const res = await api('/following/create', {
+ const res = await api('following/create', {
userId: 'foo',
}, alice);
@@ -341,11 +344,11 @@ describe('Endpoints', () => {
describe('following/delete', () => {
test('フォロー解除できる', async () => {
- await api('/following/create', {
+ await api('following/create', {
userId: alice.id,
}, bob);
- const res = await api('/following/delete', {
+ const res = await api('following/delete', {
userId: alice.id,
}, bob);
@@ -363,7 +366,7 @@ describe('Endpoints', () => {
});
test('フォローしていない場合は怒る', async () => {
- const res = await api('/following/delete', {
+ const res = await api('following/delete', {
userId: alice.id,
}, bob);
@@ -371,7 +374,7 @@ describe('Endpoints', () => {
});
test('存在しないユーザーはフォロー解除できない', async () => {
- const res = await api('/following/delete', {
+ const res = await api('following/delete', {
userId: '000000000000000000000000',
}, alice);
@@ -379,7 +382,7 @@ describe('Endpoints', () => {
});
test('自分自身はフォロー解除できない', async () => {
- const res = await api('/following/delete', {
+ const res = await api('following/delete', {
userId: alice.id,
}, alice);
@@ -387,13 +390,14 @@ describe('Endpoints', () => {
});
test('空のパラメータで怒られる', async () => {
- const res = await api('/following/delete', {}, alice);
+ // @ts-expect-error params must not be empty
+ const res = await api('following/delete', {}, alice);
assert.strictEqual(res.status, 400);
});
test('間違ったIDで怒られる', async () => {
- const res = await api('/following/delete', {
+ const res = await api('following/delete', {
userId: 'kyoppie',
}, alice);
@@ -403,20 +407,20 @@ describe('Endpoints', () => {
describe('channels/search', () => {
test('空白検索で一覧を取得できる', async () => {
- await api('/channels/create', {
+ await api('channels/create', {
name: 'aaa',
description: 'bbb',
}, bob);
- await api('/channels/create', {
+ await api('channels/create', {
name: 'ccc1',
description: 'ddd1',
}, bob);
- await api('/channels/create', {
+ await api('channels/create', {
name: 'ccc2',
description: 'ddd2',
}, bob);
- const res = await api('/channels/search', {
+ const res = await api('channels/search', {
query: '',
}, bob);
@@ -425,7 +429,7 @@ describe('Endpoints', () => {
assert.strictEqual(res.body.length, 3);
});
test('名前のみの検索で名前を検索できる', async () => {
- const res = await api('/channels/search', {
+ const res = await api('channels/search', {
query: 'aaa',
type: 'nameOnly',
}, bob);
@@ -436,7 +440,7 @@ describe('Endpoints', () => {
assert.strictEqual(res.body[0].name, 'aaa');
});
test('名前のみの検索で名前を複数検索できる', async () => {
- const res = await api('/channels/search', {
+ const res = await api('channels/search', {
query: 'ccc',
type: 'nameOnly',
}, bob);
@@ -446,7 +450,7 @@ describe('Endpoints', () => {
assert.strictEqual(res.body.length, 2);
});
test('名前のみの検索で説明は検索できない', async () => {
- const res = await api('/channels/search', {
+ const res = await api('channels/search', {
query: 'bbb',
type: 'nameOnly',
}, bob);
@@ -456,7 +460,7 @@ describe('Endpoints', () => {
assert.strictEqual(res.body.length, 0);
});
test('名前と説明の検索で名前を検索できる', async () => {
- const res = await api('/channels/search', {
+ const res = await api('channels/search', {
query: 'ccc1',
}, bob);
@@ -466,7 +470,7 @@ describe('Endpoints', () => {
assert.strictEqual(res.body[0].name, 'ccc1');
});
test('名前と説明での検索で説明を検索できる', async () => {
- const res = await api('/channels/search', {
+ const res = await api('channels/search', {
query: 'ddd1',
}, bob);
@@ -476,7 +480,7 @@ describe('Endpoints', () => {
assert.strictEqual(res.body[0].name, 'ccc1');
});
test('名前と説明の検索で名前を複数検索できる', async () => {
- const res = await api('/channels/search', {
+ const res = await api('channels/search', {
query: 'ccc',
}, bob);
@@ -485,7 +489,7 @@ describe('Endpoints', () => {
assert.strictEqual(res.body.length, 2);
});
test('名前と説明での検索で説明を複数検索できる', async () => {
- const res = await api('/channels/search', {
+ const res = await api('channels/search', {
query: 'ddd',
}, bob);
@@ -506,7 +510,7 @@ describe('Endpoints', () => {
await uploadFile(alice, {
blob: new Blob([new Uint8Array(1024)]),
});
- const res = await api('/drive', {}, alice);
+ const res = await api('drive', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
expect(res.body).toHaveProperty('usage', 1792);
@@ -519,7 +523,7 @@ describe('Endpoints', () => {
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
- assert.strictEqual(res.body.name, 'Lenna.jpg');
+ assert.strictEqual(res.body!.name, 'Lenna.jpg');
});
test('ファイルに名前を付けられる', async () => {
@@ -527,7 +531,7 @@ describe('Endpoints', () => {
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
- assert.strictEqual(res.body.name, 'Belmond.jpg');
+ assert.strictEqual(res.body!.name, 'Belmond.jpg');
});
test('ファイルに名前を付けられるが、拡張子は正しいものになる', async () => {
@@ -535,11 +539,12 @@ describe('Endpoints', () => {
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
- assert.strictEqual(res.body.name, 'Belmond.png.jpg');
+ assert.strictEqual(res.body!.name, 'Belmond.png.jpg');
});
test('ファイル無しで怒られる', async () => {
- const res = await api('/drive/files/create', {}, alice);
+ // @ts-expect-error params must not be empty
+ const res = await api('drive/files/create', {}, alice);
assert.strictEqual(res.status, 400);
});
@@ -549,14 +554,14 @@ describe('Endpoints', () => {
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
- assert.strictEqual(res.body.name, 'image.svg');
- assert.strictEqual(res.body.type, 'image/svg+xml');
+ assert.strictEqual(res.body!.name, 'image.svg');
+ assert.strictEqual(res.body!.type, 'image/svg+xml');
});
for (const type of ['webp', 'avif']) {
const mediaType = `image/${type}`;
- const getWebpublicType = async (user: any, fileId: string): Promise<string> => {
+ const getWebpublicType = async (user: misskey.entities.SignupResponse, fileId: string): Promise<string> => {
// drive/files/create does not expose webpublicType directly, so get it by posting it
const res = await post(user, {
text: mediaType,
@@ -573,10 +578,10 @@ describe('Endpoints', () => {
const res = await uploadFile(alice, { path });
assert.strictEqual(res.status, 200);
- assert.strictEqual(res.body.name, path);
- assert.strictEqual(res.body.type, mediaType);
+ assert.strictEqual(res.body!.name, path);
+ assert.strictEqual(res.body!.type, mediaType);
- const webpublicType = await getWebpublicType(alice, res.body.id);
+ const webpublicType = await getWebpublicType(alice, res.body!.id);
assert.strictEqual(webpublicType, 'image/webp');
});
@@ -584,10 +589,10 @@ describe('Endpoints', () => {
const path = `without-alpha.${type}`;
const res = await uploadFile(alice, { path });
assert.strictEqual(res.status, 200);
- assert.strictEqual(res.body.name, path);
- assert.strictEqual(res.body.type, mediaType);
+ assert.strictEqual(res.body!.name, path);
+ assert.strictEqual(res.body!.type, mediaType);
- const webpublicType = await getWebpublicType(alice, res.body.id);
+ const webpublicType = await getWebpublicType(alice, res.body!.id);
assert.strictEqual(webpublicType, 'image/webp');
});
}
@@ -598,8 +603,8 @@ describe('Endpoints', () => {
const file = (await uploadFile(alice)).body;
const newName = 'いちごパスタ.png';
- const res = await api('/drive/files/update', {
- fileId: file.id,
+ const res = await api('drive/files/update', {
+ fileId: file!.id,
name: newName,
}, alice);
@@ -611,8 +616,8 @@ describe('Endpoints', () => {
test('他人のファイルは更新できない', async () => {
const file = (await uploadFile(alice)).body;
- const res = await api('/drive/files/update', {
- fileId: file.id,
+ const res = await api('drive/files/update', {
+ fileId: file!.id,
name: 'いちごパスタ.png',
}, bob);
@@ -621,12 +626,12 @@ describe('Endpoints', () => {
test('親フォルダを更新できる', async () => {
const file = (await uploadFile(alice)).body;
- const folder = (await api('/drive/folders/create', {
+ const folder = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- const res = await api('/drive/files/update', {
- fileId: file.id,
+ const res = await api('drive/files/update', {
+ fileId: file!.id,
folderId: folder.id,
}, alice);
@@ -638,17 +643,17 @@ describe('Endpoints', () => {
test('親フォルダを無しにできる', async () => {
const file = (await uploadFile(alice)).body;
- const folder = (await api('/drive/folders/create', {
+ const folder = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- await api('/drive/files/update', {
- fileId: file.id,
+ await api('drive/files/update', {
+ fileId: file!.id,
folderId: folder.id,
}, alice);
- const res = await api('/drive/files/update', {
- fileId: file.id,
+ const res = await api('drive/files/update', {
+ fileId: file!.id,
folderId: null,
}, alice);
@@ -659,12 +664,12 @@ describe('Endpoints', () => {
test('他人のフォルダには入れられない', async () => {
const file = (await uploadFile(alice)).body;
- const folder = (await api('/drive/folders/create', {
+ const folder = (await api('drive/folders/create', {
name: 'test',
}, bob)).body;
- const res = await api('/drive/files/update', {
- fileId: file.id,
+ const res = await api('drive/files/update', {
+ fileId: file!.id,
folderId: folder.id,
}, alice);
@@ -674,8 +679,8 @@ describe('Endpoints', () => {
test('存在しないフォルダで怒られる', async () => {
const file = (await uploadFile(alice)).body;
- const res = await api('/drive/files/update', {
- fileId: file.id,
+ const res = await api('drive/files/update', {
+ fileId: file!.id,
folderId: '000000000000000000000000',
}, alice);
@@ -685,8 +690,8 @@ describe('Endpoints', () => {
test('不正なフォルダIDで怒られる', async () => {
const file = (await uploadFile(alice)).body;
- const res = await api('/drive/files/update', {
- fileId: file.id,
+ const res = await api('drive/files/update', {
+ fileId: file!.id,
folderId: 'foo',
}, alice);
@@ -694,7 +699,7 @@ describe('Endpoints', () => {
});
test('ファイルが存在しなかったら怒る', async () => {
- const res = await api('/drive/files/update', {
+ const res = await api('drive/files/update', {
fileId: '000000000000000000000000',
name: 'いちごパスタ.png',
}, alice);
@@ -706,8 +711,8 @@ describe('Endpoints', () => {
const file = (await uploadFile(alice)).body;
const newName = '';
- const res = await api('/drive/files/update', {
- fileId: file.id,
+ const res = await api('drive/files/update', {
+ fileId: file!.id,
name: newName,
}, alice);
@@ -715,7 +720,7 @@ describe('Endpoints', () => {
});
test('間違ったIDで怒られる', async () => {
- const res = await api('/drive/files/update', {
+ const res = await api('drive/files/update', {
fileId: 'kyoppie',
name: 'いちごパスタ.png',
}, alice);
@@ -726,7 +731,7 @@ describe('Endpoints', () => {
describe('drive/folders/create', () => {
test('フォルダを作成できる', async () => {
- const res = await api('/drive/folders/create', {
+ const res = await api('drive/folders/create', {
name: 'test',
}, alice);
@@ -738,11 +743,11 @@ describe('Endpoints', () => {
describe('drive/folders/update', () => {
test('名前を更新できる', async () => {
- const folder = (await api('/drive/folders/create', {
+ const folder = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: folder.id,
name: 'new name',
}, alice);
@@ -753,11 +758,11 @@ describe('Endpoints', () => {
});
test('他人のフォルダを更新できない', async () => {
- const folder = (await api('/drive/folders/create', {
+ const folder = (await api('drive/folders/create', {
name: 'test',
}, bob)).body;
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: folder.id,
name: 'new name',
}, alice);
@@ -766,14 +771,14 @@ describe('Endpoints', () => {
});
test('親フォルダを更新できる', async () => {
- const folder = (await api('/drive/folders/create', {
+ const folder = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- const parentFolder = (await api('/drive/folders/create', {
+ const parentFolder = (await api('drive/folders/create', {
name: 'parent',
}, alice)).body;
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: folder.id,
parentId: parentFolder.id,
}, alice);
@@ -784,18 +789,18 @@ describe('Endpoints', () => {
});
test('親フォルダを無しに更新できる', async () => {
- const folder = (await api('/drive/folders/create', {
+ const folder = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- const parentFolder = (await api('/drive/folders/create', {
+ const parentFolder = (await api('drive/folders/create', {
name: 'parent',
}, alice)).body;
- await api('/drive/folders/update', {
+ await api('drive/folders/update', {
folderId: folder.id,
parentId: parentFolder.id,
}, alice);
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: folder.id,
parentId: null,
}, alice);
@@ -806,14 +811,14 @@ describe('Endpoints', () => {
});
test('他人のフォルダを親フォルダに設定できない', async () => {
- const folder = (await api('/drive/folders/create', {
+ const folder = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- const parentFolder = (await api('/drive/folders/create', {
+ const parentFolder = (await api('drive/folders/create', {
name: 'parent',
}, bob)).body;
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: folder.id,
parentId: parentFolder.id,
}, alice);
@@ -822,18 +827,18 @@ describe('Endpoints', () => {
});
test('フォルダが循環するような構造にできない', async () => {
- const folder = (await api('/drive/folders/create', {
+ const folder = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- const parentFolder = (await api('/drive/folders/create', {
+ const parentFolder = (await api('drive/folders/create', {
name: 'parent',
}, alice)).body;
- await api('/drive/folders/update', {
+ await api('drive/folders/update', {
folderId: parentFolder.id,
parentId: folder.id,
}, alice);
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: folder.id,
parentId: parentFolder.id,
}, alice);
@@ -842,25 +847,25 @@ describe('Endpoints', () => {
});
test('フォルダが循環するような構造にできない(再帰的)', async () => {
- const folderA = (await api('/drive/folders/create', {
+ const folderA = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- const folderB = (await api('/drive/folders/create', {
+ const folderB = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- const folderC = (await api('/drive/folders/create', {
+ const folderC = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- await api('/drive/folders/update', {
+ await api('drive/folders/update', {
folderId: folderB.id,
parentId: folderA.id,
}, alice);
- await api('/drive/folders/update', {
+ await api('drive/folders/update', {
folderId: folderC.id,
parentId: folderB.id,
}, alice);
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: folderA.id,
parentId: folderC.id,
}, alice);
@@ -869,11 +874,11 @@ describe('Endpoints', () => {
});
test('フォルダが循環するような構造にできない(自身)', async () => {
- const folderA = (await api('/drive/folders/create', {
+ const folderA = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: folderA.id,
parentId: folderA.id,
}, alice);
@@ -882,11 +887,11 @@ describe('Endpoints', () => {
});
test('存在しない親フォルダを設定できない', async () => {
- const folder = (await api('/drive/folders/create', {
+ const folder = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: folder.id,
parentId: '000000000000000000000000',
}, alice);
@@ -895,11 +900,11 @@ describe('Endpoints', () => {
});
test('不正な親フォルダIDで怒られる', async () => {
- const folder = (await api('/drive/folders/create', {
+ const folder = (await api('drive/folders/create', {
name: 'test',
}, alice)).body;
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: folder.id,
parentId: 'foo',
}, alice);
@@ -908,7 +913,7 @@ describe('Endpoints', () => {
});
test('存在しないフォルダを更新できない', async () => {
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: '000000000000000000000000',
}, alice);
@@ -916,7 +921,7 @@ describe('Endpoints', () => {
});
test('不正なフォルダIDで怒られる', async () => {
- const res = await api('/drive/folders/update', {
+ const res = await api('drive/folders/update', {
folderId: 'foo',
}, alice);
@@ -937,7 +942,7 @@ describe('Endpoints', () => {
visibleUserIds: [alice.id],
});
- const res = await api('/notes/replies', {
+ const res = await api('notes/replies', {
noteId: alicePost.id,
}, carol);
@@ -949,7 +954,7 @@ describe('Endpoints', () => {
describe('notes/timeline', () => {
test('フォロワー限定投稿が含まれる', async () => {
- await api('/following/create', {
+ await api('following/create', {
userId: carol.id,
}, dave);
@@ -958,7 +963,7 @@ describe('Endpoints', () => {
visibility: 'followers',
});
- const res = await api('/notes/timeline', {}, dave);
+ const res = await api('notes/timeline', {}, dave);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -979,12 +984,12 @@ describe('Endpoints', () => {
test('他者に関するメモを更新できる', async () => {
const memo = '10月まで低浮上とのこと。';
- const res1 = await api('/users/update-memo', {
+ const res1 = await api('users/update-memo', {
memo,
userId: bob.id,
}, alice);
- const res2 = await api('/users/show', {
+ const res2 = await api('users/show', {
userId: bob.id,
}, alice);
assert.strictEqual(res1.status, 204);
@@ -994,12 +999,12 @@ describe('Endpoints', () => {
test('自分に関するメモを更新できる', async () => {
const memo = 'チケットを月末までに買う。';
- const res1 = await api('/users/update-memo', {
+ const res1 = await api('users/update-memo', {
memo,
userId: alice.id,
}, alice);
- const res2 = await api('/users/show', {
+ const res2 = await api('users/show', {
userId: alice.id,
}, alice);
assert.strictEqual(res1.status, 204);
@@ -1009,17 +1014,17 @@ describe('Endpoints', () => {
test('メモを削除できる', async () => {
const memo = '10月まで低浮上とのこと。';
- await api('/users/update-memo', {
+ await api('users/update-memo', {
memo,
userId: bob.id,
}, alice);
- await api('/users/update-memo', {
+ await api('users/update-memo', {
memo: '',
userId: bob.id,
}, alice);
- const res = await api('/users/show', {
+ const res = await api('users/show', {
userId: bob.id,
}, alice);
@@ -1032,21 +1037,21 @@ describe('Endpoints', () => {
const memoCarolToBob = '例の件について今度問いただす。';
await Promise.all([
- api('/users/update-memo', {
+ api('users/update-memo', {
memo: memoAliceToBob,
userId: bob.id,
}, alice),
- api('/users/update-memo', {
+ api('users/update-memo', {
memo: memoCarolToBob,
userId: bob.id,
}, carol),
]);
const [resAlice, resCarol] = await Promise.all([
- api('/users/show', {
+ api('users/show', {
userId: bob.id,
}, alice),
- api('/users/show', {
+ api('users/show', {
userId: bob.id,
}, carol),
]);
diff --git a/packages/backend/test/e2e/exports.ts b/packages/backend/test/e2e/exports.ts
index eb03935a2a..80a5331a6d 100644
--- a/packages/backend/test/e2e/exports.ts
+++ b/packages/backend/test/e2e/exports.ts
@@ -18,7 +18,7 @@ describe('export-clips', () => {
// XXX: Any better way to get the result?
async function pollFirstDriveFile() {
while (true) {
- const files = (await api('/drive/files', {}, alice)).body;
+ const files = (await api('drive/files', {}, alice)).body;
if (!files.length) {
await new Promise(r => setTimeout(r, 100));
continue;
@@ -26,7 +26,7 @@ describe('export-clips', () => {
if (files.length > 1) {
throw new Error('Too many files?');
}
- const file = (await api('/drive/files/show', { fileId: files[0].id }, alice)).body;
+ const file = (await api('drive/files/show', { fileId: files[0].id }, alice)).body;
const res = await fetch(new URL(new URL(file.url).pathname, `http://127.0.0.1:${port}`));
return await res.json();
}
@@ -44,16 +44,16 @@ describe('export-clips', () => {
beforeEach(async () => {
// Clean all clips and files of alice
- const clips = (await api('/clips/list', {}, alice)).body;
+ const clips = (await api('clips/list', {}, alice)).body;
for (const clip of clips) {
- const res = await api('/clips/delete', { clipId: clip.id }, alice);
+ const res = await api('clips/delete', { clipId: clip.id }, alice);
if (res.status !== 204) {
throw new Error('Failed to delete clip');
}
}
- const files = (await api('/drive/files', {}, alice)).body;
+ const files = (await api('drive/files', {}, alice)).body;
for (const file of files) {
- const res = await api('/drive/files/delete', { fileId: file.id }, alice);
+ const res = await api('drive/files/delete', { fileId: file.id }, alice);
if (res.status !== 204) {
throw new Error('Failed to delete file');
}
@@ -61,13 +61,13 @@ describe('export-clips', () => {
});
test('basic export', async () => {
- let res = await api('/clips/create', {
+ let res = await api('clips/create', {
name: 'foo',
description: 'bar',
}, alice);
assert.strictEqual(res.status, 200);
- res = await api('/i/export-clips', {}, alice);
+ res = await api('i/export-clips', {}, alice);
assert.strictEqual(res.status, 204);
const exported = await pollFirstDriveFile();
@@ -77,7 +77,7 @@ describe('export-clips', () => {
});
test('export with notes', async () => {
- let res = await api('/clips/create', {
+ let res = await api('clips/create', {
name: 'foo',
description: 'bar',
}, alice);
@@ -96,14 +96,14 @@ describe('export-clips', () => {
});
for (const note of [note1, note2]) {
- res = await api('/clips/add-note', {
+ res = await api('clips/add-note', {
clipId: clip.id,
noteId: note.id,
}, alice);
assert.strictEqual(res.status, 204);
}
- res = await api('/i/export-clips', {}, alice);
+ res = await api('i/export-clips', {}, alice);
assert.strictEqual(res.status, 204);
const exported = await pollFirstDriveFile();
@@ -116,14 +116,14 @@ describe('export-clips', () => {
});
test('multiple clips', async () => {
- let res = await api('/clips/create', {
+ let res = await api('clips/create', {
name: 'kawaii',
description: 'kawaii',
}, alice);
assert.strictEqual(res.status, 200);
const clip1 = res.body;
- res = await api('/clips/create', {
+ res = await api('clips/create', {
name: 'yuri',
description: 'yuri',
}, alice);
@@ -138,19 +138,19 @@ describe('export-clips', () => {
text: 'baz2',
});
- res = await api('/clips/add-note', {
+ res = await api('clips/add-note', {
clipId: clip1.id,
noteId: note1.id,
}, alice);
assert.strictEqual(res.status, 204);
- res = await api('/clips/add-note', {
+ res = await api('clips/add-note', {
clipId: clip2.id,
noteId: note2.id,
}, alice);
assert.strictEqual(res.status, 204);
- res = await api('/i/export-clips', {}, alice);
+ res = await api('i/export-clips', {}, alice);
assert.strictEqual(res.status, 204);
const exported = await pollFirstDriveFile();
@@ -163,7 +163,7 @@ describe('export-clips', () => {
});
test('Clipping other user\'s note', async () => {
- let res = await api('/clips/create', {
+ let res = await api('clips/create', {
name: 'kawaii',
description: 'kawaii',
}, alice);
@@ -175,13 +175,13 @@ describe('export-clips', () => {
visibility: 'followers',
});
- res = await api('/clips/add-note', {
+ res = await api('clips/add-note', {
clipId: clip.id,
noteId: note.id,
}, alice);
assert.strictEqual(res.status, 204);
- res = await api('/i/export-clips', {}, alice);
+ res = await api('i/export-clips', {}, alice);
assert.strictEqual(res.status, 204);
const exported = await pollFirstDriveFile();
diff --git a/packages/backend/test/e2e/fetch-resource.ts b/packages/backend/test/e2e/fetch-resource.ts
index 74033b7dff..4851ed14be 100644
--- a/packages/backend/test/e2e/fetch-resource.ts
+++ b/packages/backend/test/e2e/fetch-resource.ts
@@ -23,13 +23,13 @@ const JSON_UTF8 = 'application/json; charset=utf-8';
describe('Webリソース', () => {
let alice: misskey.entities.SignupResponse;
- let aliceUploadedFile: any;
- let alicesPost: any;
- let alicePage: any;
- let alicePlay: any;
- let aliceClip: any;
- let aliceGalleryPost: any;
- let aliceChannel: any;
+ let aliceUploadedFile: misskey.entities.DriveFile | null;
+ let alicesPost: misskey.entities.Note;
+ let alicePage: misskey.entities.Page;
+ let alicePlay: misskey.entities.Flash;
+ let aliceClip: misskey.entities.Clip;
+ let aliceGalleryPost: misskey.entities.GalleryPost;
+ let aliceChannel: misskey.entities.Channel;
let bob: misskey.entities.SignupResponse;
@@ -77,7 +77,7 @@ describe('Webリソース', () => {
beforeAll(async () => {
alice = await signup({ username: 'alice' });
- aliceUploadedFile = await uploadFile(alice);
+ aliceUploadedFile = (await uploadFile(alice)).body;
alicesPost = await post(alice, {
text: 'test',
});
@@ -85,7 +85,7 @@ describe('Webリソース', () => {
alicePlay = await play(alice, {});
aliceClip = await clip(alice, {});
aliceGalleryPost = await galleryPost(alice, {
- fileIds: [aliceUploadedFile.body.id],
+ fileIds: [aliceUploadedFile!.id],
});
aliceChannel = await channel(alice, {});
diff --git a/packages/backend/test/e2e/ff-visibility.ts b/packages/backend/test/e2e/ff-visibility.ts
index b59dd8824a..5d0c70a3c2 100644
--- a/packages/backend/test/e2e/ff-visibility.ts
+++ b/packages/backend/test/e2e/ff-visibility.ts
@@ -19,15 +19,15 @@ describe('FF visibility', () => {
}, 1000 * 60 * 2);
test('followingVisibility, followersVisibility がともに public なユーザーのフォロー/フォロワーを誰でも見れる', async () => {
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'public',
followersVisibility: 'public',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
@@ -39,36 +39,36 @@ describe('FF visibility', () => {
test('followingVisibility が public であれば followersVisibility の設定に関わらずユーザーのフォローを誰でも見れる', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'public',
followersVisibility: 'public',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 200);
assert.strictEqual(Array.isArray(followingRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'public',
followersVisibility: 'followers',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 200);
assert.strictEqual(Array.isArray(followingRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'public',
followersVisibility: 'private',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 200);
@@ -78,36 +78,36 @@ describe('FF visibility', () => {
test('followersVisibility が public であれば followingVisibility の設定に関わらずユーザーのフォロワーを誰でも見れる', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'public',
followersVisibility: 'public',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'public',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'public',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 200);
@@ -116,15 +116,15 @@ describe('FF visibility', () => {
});
test('followingVisibility, followersVisibility がともに followers なユーザーのフォロー/フォロワーを自分で見れる', async () => {
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'followers',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, alice);
@@ -136,36 +136,36 @@ describe('FF visibility', () => {
test('followingVisibility が followers なユーザーのフォローを followersVisibility の設定に関わらず自分で見れる', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'public',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, alice);
assert.strictEqual(followingRes.status, 200);
assert.strictEqual(Array.isArray(followingRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'followers',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, alice);
assert.strictEqual(followingRes.status, 200);
assert.strictEqual(Array.isArray(followingRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'private',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, alice);
assert.strictEqual(followingRes.status, 200);
@@ -175,36 +175,36 @@ describe('FF visibility', () => {
test('followersVisibility が followers なユーザーのフォロワーを followingVisibility の設定に関わらず自分で見れる', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'public',
followersVisibility: 'followers',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, alice);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'followers',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, alice);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'followers',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, alice);
assert.strictEqual(followersRes.status, 200);
@@ -213,15 +213,15 @@ describe('FF visibility', () => {
});
test('followingVisibility, followersVisibility がともに followers なユーザーのフォロー/フォロワーを非フォロワーが見れない', async () => {
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'followers',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
@@ -231,34 +231,34 @@ describe('FF visibility', () => {
test('followingVisibility が followers なユーザーのフォローを followersVisibility の設定に関わらず非フォロワーが見れない', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'public',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 400);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'followers',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 400);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'private',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 400);
@@ -267,34 +267,34 @@ describe('FF visibility', () => {
test('followersVisibility が followers なユーザーのフォロワーを followingVisibility の設定に関わらず非フォロワーが見れない', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'public',
followersVisibility: 'followers',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 400);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'followers',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 400);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'followers',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 400);
@@ -302,19 +302,19 @@ describe('FF visibility', () => {
});
test('followingVisibility, followersVisibility がともに followers なユーザーのフォロー/フォロワーをフォロワーが見れる', async () => {
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'followers',
}, alice);
- await api('/following/create', {
+ await api('following/create', {
userId: alice.id,
}, bob);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
@@ -326,45 +326,45 @@ describe('FF visibility', () => {
test('followingVisibility が followers なユーザーのフォローを followersVisibility の設定に関わらずフォロワーが見れる', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'public',
}, alice);
- await api('/following/create', {
+ await api('following/create', {
userId: alice.id,
}, bob);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 200);
assert.strictEqual(Array.isArray(followingRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'followers',
}, alice);
- await api('/following/create', {
+ await api('following/create', {
userId: alice.id,
}, bob);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 200);
assert.strictEqual(Array.isArray(followingRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'private',
}, alice);
- await api('/following/create', {
+ await api('following/create', {
userId: alice.id,
}, bob);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 200);
@@ -374,45 +374,45 @@ describe('FF visibility', () => {
test('followersVisibility が followers なユーザーのフォロワーを followingVisibility の設定に関わらずフォロワーが見れる', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'public',
followersVisibility: 'followers',
}, alice);
- await api('/following/create', {
+ await api('following/create', {
userId: alice.id,
}, bob);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'followers',
}, alice);
- await api('/following/create', {
+ await api('following/create', {
userId: alice.id,
}, bob);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'followers',
}, alice);
- await api('/following/create', {
+ await api('following/create', {
userId: alice.id,
}, bob);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 200);
@@ -421,15 +421,15 @@ describe('FF visibility', () => {
});
test('followingVisibility, followersVisibility がともに private なユーザーのフォロー/フォロワーを自分で見れる', async () => {
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'private',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, alice);
@@ -441,36 +441,36 @@ describe('FF visibility', () => {
test('followingVisibility が private なユーザーのフォローを followersVisibility の設定に関わらず自分で見れる', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'public',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, alice);
assert.strictEqual(followingRes.status, 200);
assert.strictEqual(Array.isArray(followingRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'followers',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, alice);
assert.strictEqual(followingRes.status, 200);
assert.strictEqual(Array.isArray(followingRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'private',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, alice);
assert.strictEqual(followingRes.status, 200);
@@ -480,36 +480,36 @@ describe('FF visibility', () => {
test('followersVisibility が private なユーザーのフォロワーを followingVisibility の設定に関わらず自分で見れる', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'public',
followersVisibility: 'private',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, alice);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'private',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, alice);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'private',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, alice);
assert.strictEqual(followersRes.status, 200);
@@ -518,15 +518,15 @@ describe('FF visibility', () => {
});
test('followingVisibility, followersVisibility がともに private なユーザーのフォロー/フォロワーを他人が見れない', async () => {
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'private',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
@@ -536,34 +536,34 @@ describe('FF visibility', () => {
test('followingVisibility が private なユーザーのフォローを followersVisibility の設定に関わらず他人が見れない', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'public',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 400);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'followers',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 400);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'private',
}, alice);
- const followingRes = await api('/users/following', {
+ const followingRes = await api('users/following', {
userId: alice.id,
}, bob);
assert.strictEqual(followingRes.status, 400);
@@ -572,34 +572,34 @@ describe('FF visibility', () => {
test('followersVisibility が private なユーザーのフォロワーを followingVisibility の設定に関わらず他人が見れない', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'public',
followersVisibility: 'private',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 400);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
followersVisibility: 'private',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 400);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
followersVisibility: 'private',
}, alice);
- const followersRes = await api('/users/followers', {
+ const followersRes = await api('users/followers', {
userId: alice.id,
}, bob);
assert.strictEqual(followersRes.status, 400);
@@ -609,7 +609,7 @@ describe('FF visibility', () => {
describe('AP', () => {
test('followingVisibility が public 以外ならばAPからはフォローを取得できない', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'public',
}, alice);
@@ -617,7 +617,7 @@ describe('FF visibility', () => {
assert.strictEqual(followingRes.status, 200);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'followers',
}, alice);
@@ -625,7 +625,7 @@ describe('FF visibility', () => {
assert.strictEqual(followingRes.status, 403);
}
{
- await api('/i/update', {
+ await api('i/update', {
followingVisibility: 'private',
}, alice);
@@ -636,7 +636,7 @@ describe('FF visibility', () => {
test('followersVisibility が public 以外ならばAPからはフォロワーを取得できない', async () => {
{
- await api('/i/update', {
+ await api('i/update', {
followersVisibility: 'public',
}, alice);
@@ -644,7 +644,7 @@ describe('FF visibility', () => {
assert.strictEqual(followersRes.status, 200);
}
{
- await api('/i/update', {
+ await api('i/update', {
followersVisibility: 'followers',
}, alice);
@@ -652,7 +652,7 @@ describe('FF visibility', () => {
assert.strictEqual(followersRes.status, 403);
}
{
- await api('/i/update', {
+ await api('i/update', {
followersVisibility: 'private',
}, alice);
diff --git a/packages/backend/test/e2e/move.ts b/packages/backend/test/e2e/move.ts
index f6417e39b5..4e5306da97 100644
--- a/packages/backend/test/e2e/move.ts
+++ b/packages/backend/test/e2e/move.ts
@@ -55,7 +55,7 @@ describe('Account Move', () => {
}, 1000 * 10);
test('Able to create an alias', async () => {
- const res = await api('/i/update', {
+ const res = await api('i/update', {
alsoKnownAs: [`@alice@${url.hostname}`],
}, bob);
@@ -67,7 +67,7 @@ describe('Account Move', () => {
});
test('Able to create a local alias without hostname', async () => {
- await api('/i/update', {
+ await api('i/update', {
alsoKnownAs: ['@alice'],
}, bob);
@@ -77,7 +77,7 @@ describe('Account Move', () => {
});
test('Able to create a local alias without @', async () => {
- await api('/i/update', {
+ await api('i/update', {
alsoKnownAs: ['alice'],
}, bob);
@@ -87,7 +87,7 @@ describe('Account Move', () => {
});
test('Able to set remote user (but may fail)', async () => {
- const res = await api('/i/update', {
+ const res = await api('i/update', {
alsoKnownAs: ['@syuilo@example.com'],
}, bob);
@@ -97,7 +97,7 @@ describe('Account Move', () => {
});
test('Unable to add duplicated aliases to alsoKnownAs', async () => {
- const res = await api('/i/update', {
+ const res = await api('i/update', {
alsoKnownAs: [`@alice@${url.hostname}`, `@alice@${url.hostname}`],
}, bob);
@@ -107,7 +107,7 @@ describe('Account Move', () => {
});
test('Unable to add itself', async () => {
- const res = await api('/i/update', {
+ const res = await api('i/update', {
alsoKnownAs: [`@bob@${url.hostname}`],
}, bob);
@@ -117,7 +117,7 @@ describe('Account Move', () => {
});
test('Unable to add a nonexisting local account to alsoKnownAs', async () => {
- const res1 = await api('/i/update', {
+ const res1 = await api('i/update', {
alsoKnownAs: [`@nonexist@${url.hostname}`],
}, bob);
@@ -125,7 +125,7 @@ describe('Account Move', () => {
assert.strictEqual(res1.body.error.code, 'NO_SUCH_USER');
assert.strictEqual(res1.body.error.id, 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5');
- const res2 = await api('/i/update', {
+ const res2 = await api('i/update', {
alsoKnownAs: ['@alice', 'nonexist'],
}, bob);
@@ -135,7 +135,7 @@ describe('Account Move', () => {
});
test('Able to add two existing local account to alsoKnownAs', async () => {
- await api('/i/update', {
+ await api('i/update', {
alsoKnownAs: [`@alice@${url.hostname}`, `@carol@${url.hostname}`],
}, bob);
@@ -146,10 +146,10 @@ describe('Account Move', () => {
});
test('Able to properly overwrite alsoKnownAs', async () => {
- await api('/i/update', {
+ await api('i/update', {
alsoKnownAs: [`@alice@${url.hostname}`],
}, bob);
- await api('/i/update', {
+ await api('i/update', {
alsoKnownAs: [`@carol@${url.hostname}`, `@dave@${url.hostname}`],
}, bob);
@@ -164,27 +164,27 @@ describe('Account Move', () => {
let antennaId = '';
beforeAll(async () => {
- await api('/i/update', {
+ await api('i/update', {
alsoKnownAs: [`@alice@${url.hostname}`],
}, root);
- const listRoot = await api('/users/lists/create', {
+ const listRoot = await api('users/lists/create', {
name: secureRndstr(8),
}, root);
- await api('/users/lists/push', {
+ await api('users/lists/push', {
listId: listRoot.body.id,
userId: alice.id,
}, root);
- await api('/following/create', {
+ await api('following/create', {
userId: root.id,
}, alice);
- await api('/following/create', {
+ await api('following/create', {
userId: eve.id,
}, alice);
- const antenna = await api('/antennas/create', {
+ const antenna = await api('antennas/create', {
name: secureRndstr(8),
src: 'home',
- keywords: [secureRndstr(8)],
+ keywords: [[secureRndstr(8)]],
excludeKeywords: [],
users: [],
caseSensitive: false,
@@ -195,48 +195,48 @@ describe('Account Move', () => {
}, alice);
antennaId = antenna.body.id;
- await api('/i/update', {
+ await api('i/update', {
alsoKnownAs: [`@alice@${url.hostname}`],
}, bob);
- await api('/following/create', {
+ await api('following/create', {
userId: alice.id,
}, carol);
- await api('/mute/create', {
+ await api('mute/create', {
userId: alice.id,
}, dave);
- await api('/blocking/create', {
+ await api('blocking/create', {
userId: alice.id,
}, dave);
- await api('/following/create', {
+ await api('following/create', {
userId: eve.id,
}, dave);
- await api('/following/create', {
+ await api('following/create', {
userId: dave.id,
}, eve);
- const listEve = await api('/users/lists/create', {
+ const listEve = await api('users/lists/create', {
name: secureRndstr(8),
}, eve);
- await api('/users/lists/push', {
+ await api('users/lists/push', {
listId: listEve.body.id,
userId: bob.id,
}, eve);
- await api('/i/update', {
+ await api('i/update', {
isLocked: true,
}, frank);
- await api('/following/create', {
+ await api('following/create', {
userId: frank.id,
}, alice);
- await api('/following/requests/accept', {
+ await api('following/requests/accept', {
userId: alice.id,
}, frank);
}, 1000 * 10);
test('Prohibit the root account from moving', async () => {
- const res = await api('/i/move', {
+ const res = await api('i/move', {
moveToAccount: `@bob@${url.hostname}`,
}, root);
@@ -246,7 +246,7 @@ describe('Account Move', () => {
});
test('Unable to move to a nonexisting local account', async () => {
- const res = await api('/i/move', {
+ const res = await api('i/move', {
moveToAccount: `@nonexist@${url.hostname}`,
}, alice);
@@ -256,7 +256,7 @@ describe('Account Move', () => {
});
test('Unable to move if alsoKnownAs is invalid', async () => {
- const res = await api('/i/move', {
+ const res = await api('i/move', {
moveToAccount: `@carol@${url.hostname}`,
}, alice);
@@ -266,7 +266,7 @@ describe('Account Move', () => {
});
test('Relationships have been properly migrated', async () => {
- const move = await api('/i/move', {
+ const move = await api('i/move', {
moveToAccount: `@bob@${url.hostname}`,
}, alice);
@@ -275,13 +275,13 @@ describe('Account Move', () => {
await sleep(1000 * 3); // wait for jobs to finish
// Unfollow delayed?
- const aliceFollowings = await api('/users/following', {
+ const aliceFollowings = await api('users/following', {
userId: alice.id,
}, alice);
assert.strictEqual(aliceFollowings.status, 200);
assert.strictEqual(aliceFollowings.body.length, 3);
- const carolFollowings = await api('/users/following', {
+ const carolFollowings = await api('users/following', {
userId: carol.id,
}, carol);
assert.strictEqual(carolFollowings.status, 200);
@@ -289,25 +289,25 @@ describe('Account Move', () => {
assert.strictEqual(carolFollowings.body[0].followeeId, bob.id);
assert.strictEqual(carolFollowings.body[1].followeeId, alice.id);
- const blockings = await api('/blocking/list', {}, dave);
+ const blockings = await api('blocking/list', {}, dave);
assert.strictEqual(blockings.status, 200);
assert.strictEqual(blockings.body.length, 2);
assert.strictEqual(blockings.body[0].blockeeId, bob.id);
assert.strictEqual(blockings.body[1].blockeeId, alice.id);
- const mutings = await api('/mute/list', {}, dave);
+ const mutings = await api('mute/list', {}, dave);
assert.strictEqual(mutings.status, 200);
assert.strictEqual(mutings.body.length, 2);
assert.strictEqual(mutings.body[0].muteeId, bob.id);
assert.strictEqual(mutings.body[1].muteeId, alice.id);
- const rootLists = await api('/users/lists/list', {}, root);
+ const rootLists = await api('users/lists/list', {}, root);
assert.strictEqual(rootLists.status, 200);
assert.strictEqual(rootLists.body[0].userIds.length, 2);
assert.ok(rootLists.body[0].userIds.find((id: string) => id === bob.id));
assert.ok(rootLists.body[0].userIds.find((id: string) => id === alice.id));
- const eveLists = await api('/users/lists/list', {}, eve);
+ const eveLists = await api('users/lists/list', {}, eve);
assert.strictEqual(eveLists.status, 200);
assert.strictEqual(eveLists.body[0].userIds.length, 1);
assert.ok(eveLists.body[0].userIds.find((id: string) => id === bob.id));
@@ -315,13 +315,13 @@ describe('Account Move', () => {
test('A locked account automatically accept the follow request if it had already accepted the old account.', async () => {
await successfulApiCall({
- endpoint: '/following/create',
+ endpoint: 'following/create',
parameters: {
userId: frank.id,
},
user: bob,
});
- const followers = await api('/users/followers', {
+ const followers = await api('users/followers', {
userId: frank.id,
}, frank);
@@ -333,7 +333,7 @@ describe('Account Move', () => {
test('Unfollowed after 10 sec (24 hours in production).', async () => {
await sleep(1000 * 8);
- const following = await api('/users/following', {
+ const following = await api('users/following', {
userId: alice.id,
}, alice);
@@ -342,7 +342,7 @@ describe('Account Move', () => {
});
test('Unable to move if the destination account has already moved.', async () => {
- const res = await api('/i/move', {
+ const res = await api('i/move', {
moveToAccount: `@alice@${url.hostname}`,
}, bob);
@@ -352,7 +352,7 @@ describe('Account Move', () => {
});
test('Follow and follower counts are properly adjusted', async () => {
- await api('/following/create', {
+ await api('following/create', {
userId: alice.id,
}, eve);
const newAlice = await Users.findOneByOrFail({ id: alice.id });
@@ -365,7 +365,7 @@ describe('Account Move', () => {
assert.strictEqual(newEve.followingCount, 1);
assert.strictEqual(newEve.followersCount, 1);
- await api('/following/delete', {
+ await api('following/delete', {
userId: alice.id,
}, eve);
newEve = await Users.findOneByOrFail({ id: eve.id });
@@ -374,49 +374,49 @@ describe('Account Move', () => {
});
test.each([
- '/antennas/create',
- '/channels/create',
- '/channels/favorite',
- '/channels/follow',
- '/channels/unfavorite',
- '/channels/unfollow',
- '/clips/add-note',
- '/clips/create',
- '/clips/favorite',
- '/clips/remove-note',
- '/clips/unfavorite',
- '/clips/update',
- '/drive/files/upload-from-url',
- '/flash/create',
- '/flash/like',
- '/flash/unlike',
- '/flash/update',
- '/following/create',
- '/gallery/posts/create',
- '/gallery/posts/like',
- '/gallery/posts/unlike',
- '/gallery/posts/update',
- '/i/claim-achievement',
- '/i/move',
- '/i/import-blocking',
- '/i/import-following',
- '/i/import-muting',
- '/i/import-user-lists',
- '/i/pin',
- '/mute/create',
- '/notes/create',
- '/notes/favorites/create',
- '/notes/polls/vote',
- '/notes/reactions/create',
- '/pages/create',
- '/pages/like',
- '/pages/unlike',
- '/pages/update',
- '/renote-mute/create',
- '/users/lists/create',
- '/users/lists/pull',
- '/users/lists/push',
- ])('Prohibit access after moving: %s', async (endpoint) => {
+ 'antennas/create',
+ 'channels/create',
+ 'channels/favorite',
+ 'channels/follow',
+ 'channels/unfavorite',
+ 'channels/unfollow',
+ 'clips/add-note',
+ 'clips/create',
+ 'clips/favorite',
+ 'clips/remove-note',
+ 'clips/unfavorite',
+ 'clips/update',
+ 'drive/files/upload-from-url',
+ 'flash/create',
+ 'flash/like',
+ 'flash/unlike',
+ 'flash/update',
+ 'following/create',
+ 'gallery/posts/create',
+ 'gallery/posts/like',
+ 'gallery/posts/unlike',
+ 'gallery/posts/update',
+ 'i/claim-achievement',
+ 'i/move',
+ 'i/import-blocking',
+ 'i/import-following',
+ 'i/import-muting',
+ 'i/import-user-lists',
+ 'i/pin',
+ 'mute/create',
+ 'notes/create',
+ 'notes/favorites/create',
+ 'notes/polls/vote',
+ 'notes/reactions/create',
+ 'pages/create',
+ 'pages/like',
+ 'pages/unlike',
+ 'pages/update',
+ 'renote-mute/create',
+ 'users/lists/create',
+ 'users/lists/pull',
+ 'users/lists/push',
+ ] as const)('Prohibit access after moving: %s', async (endpoint) => {
const res = await api(endpoint, {}, alice);
assert.strictEqual(res.status, 403);
assert.strictEqual(res.body.error.code, 'YOUR_ACCOUNT_MOVED');
@@ -424,11 +424,11 @@ describe('Account Move', () => {
});
test('Prohibit access after moving: /antennas/update', async () => {
- const res = await api('/antennas/update', {
+ const res = await api('antennas/update', {
antennaId,
name: secureRndstr(8),
src: 'users',
- keywords: [secureRndstr(8)],
+ keywords: [[secureRndstr(8)]],
excludeKeywords: [],
users: [eve.id],
caseSensitive: false,
@@ -447,12 +447,12 @@ describe('Account Move', () => {
const res = await uploadFile(alice);
assert.strictEqual(res.status, 403);
- assert.strictEqual(res.body.error.code, 'YOUR_ACCOUNT_MOVED');
- assert.strictEqual(res.body.error.id, '56f20ec9-fd06-4fa5-841b-edd6d7d4fa31');
+ assert.strictEqual((res.body! as any as { error: misskey.api.APIError }).error.code, 'YOUR_ACCOUNT_MOVED');
+ assert.strictEqual((res.body! as any as { error: misskey.api.APIError }).error.id, '56f20ec9-fd06-4fa5-841b-edd6d7d4fa31');
});
test('Prohibit updating alsoKnownAs after moving', async () => {
- const res = await api('/i/update', {
+ const res = await api('i/update', {
alsoKnownAs: [`@eve@${url.hostname}`],
}, alice);
diff --git a/packages/backend/test/e2e/mute.ts b/packages/backend/test/e2e/mute.ts
index 1d28e07b7d..0e52c5decc 100644
--- a/packages/backend/test/e2e/mute.ts
+++ b/packages/backend/test/e2e/mute.ts
@@ -19,21 +19,31 @@ describe('Mute', () => {
alice = await signup({ username: 'alice' });
bob = await signup({ username: 'bob' });
carol = await signup({ username: 'carol' });
+
+ // Mute: alice ==> carol
+ await api('mute/create', {
+ userId: carol.id,
+ }, alice);
}, 1000 * 60 * 2);
test('ミュート作成', async () => {
- const res = await api('/mute/create', {
- userId: carol.id,
+ const res = await api('mute/create', {
+ userId: bob.id,
}, alice);
assert.strictEqual(res.status, 204);
+
+ // 単体でも走らせられるように副作用消す
+ await api('mute/delete', {
+ userId: bob.id,
+ }, alice);
});
test('「自分宛ての投稿」にミュートしているユーザーの投稿が含まれない', async () => {
const bobNote = await post(bob, { text: '@alice hi' });
const carolNote = await post(carol, { text: '@alice hi' });
- const res = await api('/notes/mentions', {}, alice);
+ const res = await api('notes/mentions', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -43,11 +53,11 @@ describe('Mute', () => {
test('ミュートしているユーザーからメンションされても、hasUnreadMentions が true にならない', async () => {
// 状態リセット
- await api('/i/read-all-unread-notes', {}, alice);
+ await api('i/read-all-unread-notes', {}, alice);
await post(carol, { text: '@alice hi' });
- const res = await api('/i', {}, alice);
+ const res = await api('i', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.body.hasUnreadMentions, false);
@@ -55,7 +65,7 @@ describe('Mute', () => {
test('ミュートしているユーザーからメンションされても、ストリームに unreadMention イベントが流れてこない', async () => {
// 状態リセット
- await api('/i/read-all-unread-notes', {}, alice);
+ await api('i/read-all-unread-notes', {}, alice);
const fired = await waitFire(alice, 'main', () => post(carol, { text: '@alice hi' }), msg => msg.type === 'unreadMention');
@@ -64,8 +74,8 @@ describe('Mute', () => {
test('ミュートしているユーザーからメンションされても、ストリームに unreadNotification イベントが流れてこない', async () => {
// 状態リセット
- await api('/i/read-all-unread-notes', {}, alice);
- await api('/notifications/mark-all-as-read', {}, alice);
+ await api('i/read-all-unread-notes', {}, alice);
+ await api('notifications/mark-all-as-read', {}, alice);
const fired = await waitFire(alice, 'main', () => post(carol, { text: '@alice hi' }), msg => msg.type === 'unreadNotification');
@@ -78,7 +88,7 @@ describe('Mute', () => {
const bobNote = await post(bob, { text: 'hi' });
const carolNote = await post(carol, { text: 'hi' });
- const res = await api('/notes/local-timeline', {}, alice);
+ const res = await api('notes/local-timeline', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -94,7 +104,7 @@ describe('Mute', () => {
renoteId: carolNote.id,
});
- const res = await api('/notes/local-timeline', {}, alice);
+ const res = await api('notes/local-timeline', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -110,7 +120,7 @@ describe('Mute', () => {
await react(bob, aliceNote, 'like');
await react(carol, aliceNote, 'like');
- const res = await api('/i/notifications', {}, alice);
+ const res = await api('i/notifications', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -123,7 +133,7 @@ describe('Mute', () => {
await post(bob, { text: '@alice hi', replyId: aliceNote.id });
await post(carol, { text: '@alice hi', replyId: aliceNote.id });
- const res = await api('/i/notifications', {}, alice);
+ const res = await api('i/notifications', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -137,7 +147,7 @@ describe('Mute', () => {
await post(bob, { text: '@alice hi' });
await post(carol, { text: '@alice hi' });
- const res = await api('/i/notifications', {}, alice);
+ const res = await api('i/notifications', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -151,7 +161,7 @@ describe('Mute', () => {
await post(bob, { text: 'hi', renoteId: aliceNote.id });
await post(carol, { text: 'hi', renoteId: aliceNote.id });
- const res = await api('/i/notifications', {}, alice);
+ const res = await api('i/notifications', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -165,7 +175,7 @@ describe('Mute', () => {
await post(bob, { renoteId: aliceNote.id });
await post(carol, { renoteId: aliceNote.id });
- const res = await api('/i/notifications', {}, alice);
+ const res = await api('i/notifications', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -175,30 +185,36 @@ describe('Mute', () => {
});
test('通知にミュートしているユーザーからのフォロー通知が含まれない', async () => {
- await api('/i/follow', { userId: alice.id }, bob);
- await api('/i/follow', { userId: alice.id }, carol);
+ await api('following/create', { userId: alice.id }, bob);
+ await api('following/create', { userId: alice.id }, carol);
- const res = await api('/i/notifications', {}, alice);
+ const res = await api('i/notifications', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+
+ await api('following/delete', { userId: alice.id }, bob);
+ await api('following/delete', { userId: alice.id }, carol);
});
test('通知にミュートしているユーザーからのフォローリクエストが含まれない', async () => {
- await api('/i/update/', { isLocked: true }, alice);
- await api('/following/create', { userId: alice.id }, bob);
- await api('/following/create', { userId: alice.id }, carol);
+ await api('i/update', { isLocked: true }, alice);
+ await api('following/create', { userId: alice.id }, bob);
+ await api('following/create', { userId: alice.id }, carol);
- const res = await api('/i/notifications', {}, alice);
+ const res = await api('i/notifications', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+
+ await api('following/delete', { userId: alice.id }, bob);
+ await api('following/delete', { userId: alice.id }, carol);
});
});
@@ -208,7 +224,7 @@ describe('Mute', () => {
await react(bob, aliceNote, 'like');
await react(carol, aliceNote, 'like');
- const res = await api('/i/notifications-grouped', {}, alice);
+ const res = await api('i/notifications-grouped', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -220,7 +236,7 @@ describe('Mute', () => {
await post(bob, { text: '@alice hi', replyId: aliceNote.id });
await post(carol, { text: '@alice hi', replyId: aliceNote.id });
- const res = await api('/i/notifications-grouped', {}, alice);
+ const res = await api('i/notifications-grouped', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -234,7 +250,7 @@ describe('Mute', () => {
await post(bob, { text: '@alice hi' });
await post(carol, { text: '@alice hi' });
- const res = await api('/i/notifications-grouped', {}, alice);
+ const res = await api('i/notifications-grouped', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -248,7 +264,7 @@ describe('Mute', () => {
await post(bob, { text: 'hi', renoteId: aliceNote.id });
await post(carol, { text: 'hi', renoteId: aliceNote.id });
- const res = await api('/i/notifications-grouped', {}, alice);
+ const res = await api('i/notifications-grouped', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -262,7 +278,7 @@ describe('Mute', () => {
await post(bob, { renoteId: aliceNote.id });
await post(carol, { renoteId: aliceNote.id });
- const res = await api('/i/notifications-grouped', {}, alice);
+ const res = await api('i/notifications-grouped', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -272,24 +288,27 @@ describe('Mute', () => {
});
test('通知にミュートしているユーザーからのフォロー通知が含まれない', async () => {
- await api('/i/follow', { userId: alice.id }, bob);
- await api('/i/follow', { userId: alice.id }, carol);
+ await api('following/create', { userId: alice.id }, bob);
+ await api('following/create', { userId: alice.id }, carol);
- const res = await api('/i/notifications-grouped', {}, alice);
+ const res = await api('i/notifications-grouped', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+
+ await api('following/delete', { userId: alice.id }, bob);
+ await api('following/delete', { userId: alice.id }, carol);
});
test('通知にミュートしているユーザーからのフォローリクエストが含まれない', async () => {
- await api('/i/update/', { isLocked: true }, alice);
- await api('/following/create', { userId: alice.id }, bob);
- await api('/following/create', { userId: alice.id }, carol);
+ await api('i/update', { isLocked: true }, alice);
+ await api('following/create', { userId: alice.id }, bob);
+ await api('following/create', { userId: alice.id }, carol);
- const res = await api('/i/notifications-grouped', {}, alice);
+ const res = await api('i/notifications-grouped', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
diff --git a/packages/backend/test/e2e/note.ts b/packages/backend/test/e2e/note.ts
index 2406204f41..11016f58ae 100644
--- a/packages/backend/test/e2e/note.ts
+++ b/packages/backend/test/e2e/note.ts
@@ -31,7 +31,7 @@ describe('Note', () => {
text: 'test',
};
- const res = await api('/notes/create', post, alice);
+ const res = await api('notes/create', post, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
@@ -41,7 +41,7 @@ describe('Note', () => {
test('ファイルを添付できる', async () => {
const file = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg');
- const res = await api('/notes/create', {
+ const res = await api('notes/create', {
fileIds: [file.id],
}, alice);
@@ -53,7 +53,7 @@ describe('Note', () => {
test('他人のファイルで怒られる', async () => {
const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg');
- const res = await api('/notes/create', {
+ const res = await api('notes/create', {
text: 'test',
fileIds: [file.id],
}, alice);
@@ -64,7 +64,7 @@ describe('Note', () => {
}, 1000 * 10);
test('存在しないファイルで怒られる', async () => {
- const res = await api('/notes/create', {
+ const res = await api('notes/create', {
text: 'test',
fileIds: ['000000000000000000000000'],
}, alice);
@@ -75,7 +75,7 @@ describe('Note', () => {
});
test('不正なファイルIDで怒られる', async () => {
- const res = await api('/notes/create', {
+ const res = await api('notes/create', {
fileIds: ['kyoppie'],
}, alice);
assert.strictEqual(res.status, 400);
@@ -93,7 +93,7 @@ describe('Note', () => {
replyId: bobPost.id,
};
- const res = await api('/notes/create', alicePost, alice);
+ const res = await api('notes/create', alicePost, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
@@ -111,7 +111,7 @@ describe('Note', () => {
renoteId: bobPost.id,
};
- const res = await api('/notes/create', alicePost, alice);
+ const res = await api('notes/create', alicePost, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
@@ -129,7 +129,7 @@ describe('Note', () => {
renoteId: bobPost.id,
};
- const res = await api('/notes/create', alicePost, alice);
+ const res = await api('notes/create', alicePost, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
@@ -142,7 +142,7 @@ describe('Note', () => {
const bobPost = await post(bob, {
text: 'test',
});
- const res = await api('/notes/create', {
+ const res = await api('notes/create', {
text: ' ',
renoteId: bobPost.id,
}, alice);
@@ -152,7 +152,7 @@ describe('Note', () => {
});
test('visibility: followersでrenoteできる', async () => {
- const createRes = await api('/notes/create', {
+ const createRes = await api('notes/create', {
text: 'test',
visibility: 'followers',
}, alice);
@@ -160,7 +160,7 @@ describe('Note', () => {
assert.strictEqual(createRes.status, 200);
const renoteId = createRes.body.createdNote.id;
- const renoteRes = await api('/notes/create', {
+ const renoteRes = await api('notes/create', {
visibility: 'followers',
renoteId,
}, alice);
@@ -169,7 +169,7 @@ describe('Note', () => {
assert.strictEqual(renoteRes.body.createdNote.renoteId, renoteId);
assert.strictEqual(renoteRes.body.createdNote.visibility, 'followers');
- const deleteRes = await api('/notes/delete', {
+ const deleteRes = await api('notes/delete', {
noteId: renoteRes.body.createdNote.id,
}, alice);
@@ -177,11 +177,11 @@ describe('Note', () => {
});
test('visibility: followersなノートに対してフォロワーはリプライできる', async () => {
- await api('/following/create', {
+ await api('following/create', {
userId: alice.id,
}, bob);
- const aliceNote = await api('/notes/create', {
+ const aliceNote = await api('notes/create', {
text: 'direct note to bob',
visibility: 'followers',
}, alice);
@@ -189,7 +189,7 @@ describe('Note', () => {
assert.strictEqual(aliceNote.status, 200);
const replyId = aliceNote.body.createdNote.id;
- const bobReply = await api('/notes/create', {
+ const bobReply = await api('notes/create', {
text: 'reply to alice note',
replyId,
}, bob);
@@ -197,20 +197,20 @@ describe('Note', () => {
assert.strictEqual(bobReply.status, 200);
assert.strictEqual(bobReply.body.createdNote.replyId, replyId);
- await api('/following/delete', {
+ await api('following/delete', {
userId: alice.id,
}, bob);
});
test('visibility: followersなノートに対してフォロワーでないユーザーがリプライしようとすると怒られる', async () => {
- const aliceNote = await api('/notes/create', {
+ const aliceNote = await api('notes/create', {
text: 'direct note to bob',
visibility: 'followers',
}, alice);
assert.strictEqual(aliceNote.status, 200);
- const bobReply = await api('/notes/create', {
+ const bobReply = await api('notes/create', {
text: 'reply to alice note',
replyId: aliceNote.body.createdNote.id,
}, bob);
@@ -220,7 +220,7 @@ describe('Note', () => {
});
test('visibility: specifiedなノートに対してvisibility: specifiedで返信できる', async () => {
- const aliceNote = await api('/notes/create', {
+ const aliceNote = await api('notes/create', {
text: 'direct note to bob',
visibility: 'specified',
visibleUserIds: [bob.id],
@@ -228,7 +228,7 @@ describe('Note', () => {
assert.strictEqual(aliceNote.status, 200);
- const bobReply = await api('/notes/create', {
+ const bobReply = await api('notes/create', {
text: 'reply to alice note',
replyId: aliceNote.body.createdNote.id,
visibility: 'specified',
@@ -239,7 +239,7 @@ describe('Note', () => {
});
test('visibility: specifiedなノートに対してvisibility: follwersで返信しようとすると怒られる', async () => {
- const aliceNote = await api('/notes/create', {
+ const aliceNote = await api('notes/create', {
text: 'direct note to bob',
visibility: 'specified',
visibleUserIds: [bob.id],
@@ -247,7 +247,7 @@ describe('Note', () => {
assert.strictEqual(aliceNote.status, 200);
- const bobReply = await api('/notes/create', {
+ const bobReply = await api('notes/create', {
text: 'reply to alice note with visibility: followers',
replyId: aliceNote.body.createdNote.id,
visibility: 'followers',
@@ -261,7 +261,7 @@ describe('Note', () => {
const post = {
text: '!'.repeat(MAX_NOTE_TEXT_LENGTH), // 3000文字
};
- const res = await api('/notes/create', post, alice);
+ const res = await api('notes/create', post, alice);
assert.strictEqual(res.status, 200);
});
@@ -269,7 +269,7 @@ describe('Note', () => {
const post = {
text: '!'.repeat(MAX_NOTE_TEXT_LENGTH + 1), // 3001文字
};
- const res = await api('/notes/create', post, alice);
+ const res = await api('notes/create', post, alice);
assert.strictEqual(res.status, 400);
});
@@ -278,7 +278,7 @@ describe('Note', () => {
text: 'test',
replyId: '000000000000000000000000',
};
- const res = await api('/notes/create', post, alice);
+ const res = await api('notes/create', post, alice);
assert.strictEqual(res.status, 400);
});
@@ -286,7 +286,7 @@ describe('Note', () => {
const post = {
renoteId: '000000000000000000000000',
};
- const res = await api('/notes/create', post, alice);
+ const res = await api('notes/create', post, alice);
assert.strictEqual(res.status, 400);
});
@@ -295,7 +295,7 @@ describe('Note', () => {
text: 'test',
replyId: 'foo',
};
- const res = await api('/notes/create', post, alice);
+ const res = await api('notes/create', post, alice);
assert.strictEqual(res.status, 400);
});
@@ -303,7 +303,7 @@ describe('Note', () => {
const post = {
renoteId: 'foo',
};
- const res = await api('/notes/create', post, alice);
+ const res = await api('notes/create', post, alice);
assert.strictEqual(res.status, 400);
});
@@ -312,7 +312,7 @@ describe('Note', () => {
text: '@ghost yo',
};
- const res = await api('/notes/create', post, alice);
+ const res = await api('notes/create', post, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
@@ -324,7 +324,7 @@ describe('Note', () => {
text: '@bob @bob @bob yo',
};
- const res = await api('/notes/create', post, alice);
+ const res = await api('notes/create', post, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
@@ -337,25 +337,25 @@ describe('Note', () => {
describe('添付ファイル情報', () => {
test('ファイルを添付した場合、投稿成功時にファイル情報入りのレスポンスが帰ってくる', async () => {
const file = await uploadFile(alice);
- const res = await api('/notes/create', {
- fileIds: [file.body.id],
+ const res = await api('notes/create', {
+ fileIds: [file.body!.id],
}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
assert.strictEqual(res.body.createdNote.files.length, 1);
- assert.strictEqual(res.body.createdNote.files[0].id, file.body.id);
+ assert.strictEqual(res.body.createdNote.files[0].id, file.body!.id);
});
test('ファイルを添付した場合、タイムラインでファイル情報入りのレスポンスが帰ってくる', async () => {
const file = await uploadFile(alice);
- const createdNote = await api('/notes/create', {
- fileIds: [file.body.id],
+ const createdNote = await api('notes/create', {
+ fileIds: [file.body!.id],
}, alice);
assert.strictEqual(createdNote.status, 200);
- const res = await api('/notes', {
+ const res = await api('notes', {
withFiles: true,
}, alice);
@@ -364,23 +364,23 @@ describe('Note', () => {
const myNote = res.body.find((note: { id: string; files: { id: string }[] }) => note.id === createdNote.body.createdNote.id);
assert.notEqual(myNote, null);
assert.strictEqual(myNote.files.length, 1);
- assert.strictEqual(myNote.files[0].id, file.body.id);
+ assert.strictEqual(myNote.files[0].id, file.body!.id);
});
test('ファイルが添付されたノートをリノートした場合、タイムラインでファイル情報入りのレスポンスが帰ってくる', async () => {
const file = await uploadFile(alice);
- const createdNote = await api('/notes/create', {
- fileIds: [file.body.id],
+ const createdNote = await api('notes/create', {
+ fileIds: [file.body!.id],
}, alice);
assert.strictEqual(createdNote.status, 200);
- const renoted = await api('/notes/create', {
+ const renoted = await api('notes/create', {
renoteId: createdNote.body.createdNote.id,
}, alice);
assert.strictEqual(renoted.status, 200);
- const res = await api('/notes', {
+ const res = await api('notes', {
renote: true,
}, alice);
@@ -389,24 +389,24 @@ describe('Note', () => {
const myNote = res.body.find((note: { id: string }) => note.id === renoted.body.createdNote.id);
assert.notEqual(myNote, null);
assert.strictEqual(myNote.renote.files.length, 1);
- assert.strictEqual(myNote.renote.files[0].id, file.body.id);
+ assert.strictEqual(myNote.renote.files[0].id, file.body!.id);
});
test('ファイルが添付されたノートに返信した場合、タイムラインでファイル情報入りのレスポンスが帰ってくる', async () => {
const file = await uploadFile(alice);
- const createdNote = await api('/notes/create', {
- fileIds: [file.body.id],
+ const createdNote = await api('notes/create', {
+ fileIds: [file.body!.id],
}, alice);
assert.strictEqual(createdNote.status, 200);
- const reply = await api('/notes/create', {
+ const reply = await api('notes/create', {
replyId: createdNote.body.createdNote.id,
text: 'this is reply',
}, alice);
assert.strictEqual(reply.status, 200);
- const res = await api('/notes', {
+ const res = await api('notes', {
reply: true,
}, alice);
@@ -415,29 +415,29 @@ describe('Note', () => {
const myNote = res.body.find((note: { id: string }) => note.id === reply.body.createdNote.id);
assert.notEqual(myNote, null);
assert.strictEqual(myNote.reply.files.length, 1);
- assert.strictEqual(myNote.reply.files[0].id, file.body.id);
+ assert.strictEqual(myNote.reply.files[0].id, file.body!.id);
});
test('ファイルが添付されたノートへの返信をリノートした場合、タイムラインでファイル情報入りのレスポンスが帰ってくる', async () => {
const file = await uploadFile(alice);
- const createdNote = await api('/notes/create', {
- fileIds: [file.body.id],
+ const createdNote = await api('notes/create', {
+ fileIds: [file.body!.id],
}, alice);
assert.strictEqual(createdNote.status, 200);
- const reply = await api('/notes/create', {
+ const reply = await api('notes/create', {
replyId: createdNote.body.createdNote.id,
text: 'this is reply',
}, alice);
assert.strictEqual(reply.status, 200);
- const renoted = await api('/notes/create', {
+ const renoted = await api('notes/create', {
renoteId: reply.body.createdNote.id,
}, alice);
assert.strictEqual(renoted.status, 200);
- const res = await api('/notes', {
+ const res = await api('notes', {
renote: true,
}, alice);
@@ -446,7 +446,7 @@ describe('Note', () => {
const myNote = res.body.find((note: { id: string }) => note.id === renoted.body.createdNote.id);
assert.notEqual(myNote, null);
assert.strictEqual(myNote.renote.reply.files.length, 1);
- assert.strictEqual(myNote.renote.reply.files[0].id, file.body.id);
+ assert.strictEqual(myNote.renote.reply.files[0].id, file.body!.id);
});
test('NSFWが強制されている場合変更できない', async () => {
@@ -472,7 +472,7 @@ describe('Note', () => {
priority: 0,
value: true,
},
- },
+ } as any,
}, alice);
assert.strictEqual(res.status, 200);
@@ -483,15 +483,15 @@ describe('Note', () => {
}, alice);
assert.strictEqual(assign.status, 204);
- assert.strictEqual(file.body.isSensitive, false);
+ assert.strictEqual(file.body!.isSensitive, false);
const nsfwfile = await uploadFile(alice);
assert.strictEqual(nsfwfile.status, 200);
- assert.strictEqual(nsfwfile.body.isSensitive, true);
+ assert.strictEqual(nsfwfile.body!.isSensitive, true);
const liftnsfw = await api('drive/files/update', {
- fileId: nsfwfile.body.id,
+ fileId: nsfwfile.body!.id,
isSensitive: false,
}, alice);
@@ -499,7 +499,7 @@ describe('Note', () => {
assert.strictEqual(liftnsfw.body.error.code, 'RESTRICTED_BY_ROLE');
const oldaddnsfw = await api('drive/files/update', {
- fileId: file.body.id,
+ fileId: file.body!.id,
isSensitive: true,
}, alice);
@@ -518,7 +518,7 @@ describe('Note', () => {
describe('notes/create', () => {
test('投票を添付できる', async () => {
- const res = await api('/notes/create', {
+ const res = await api('notes/create', {
text: 'test',
poll: {
choices: ['foo', 'bar'],
@@ -531,14 +531,15 @@ describe('Note', () => {
});
test('投票の選択肢が無くて怒られる', async () => {
- const res = await api('/notes/create', {
+ const res = await api('notes/create', {
+ // @ts-expect-error poll must not be empty
poll: {},
}, alice);
assert.strictEqual(res.status, 400);
});
test('投票の選択肢が無くて怒られる (空の配列)', async () => {
- const res = await api('/notes/create', {
+ const res = await api('notes/create', {
poll: {
choices: [],
},
@@ -547,7 +548,7 @@ describe('Note', () => {
});
test('投票の選択肢が1つで怒られる', async () => {
- const res = await api('/notes/create', {
+ const res = await api('notes/create', {
poll: {
choices: ['Strawberry Pasta'],
},
@@ -556,14 +557,14 @@ describe('Note', () => {
});
test('投票できる', async () => {
- const { body } = await api('/notes/create', {
+ const { body } = await api('notes/create', {
text: 'test',
poll: {
choices: ['sakura', 'izumi', 'ako'],
},
}, alice);
- const res = await api('/notes/polls/vote', {
+ const res = await api('notes/polls/vote', {
noteId: body.createdNote.id,
choice: 1,
}, alice);
@@ -572,19 +573,19 @@ describe('Note', () => {
});
test('複数投票できない', async () => {
- const { body } = await api('/notes/create', {
+ const { body } = await api('notes/create', {
text: 'test',
poll: {
choices: ['sakura', 'izumi', 'ako'],
},
}, alice);
- await api('/notes/polls/vote', {
+ await api('notes/polls/vote', {
noteId: body.createdNote.id,
choice: 0,
}, alice);
- const res = await api('/notes/polls/vote', {
+ const res = await api('notes/polls/vote', {
noteId: body.createdNote.id,
choice: 2,
}, alice);
@@ -593,7 +594,7 @@ describe('Note', () => {
});
test('許可されている場合は複数投票できる', async () => {
- const { body } = await api('/notes/create', {
+ const { body } = await api('notes/create', {
text: 'test',
poll: {
choices: ['sakura', 'izumi', 'ako'],
@@ -601,17 +602,17 @@ describe('Note', () => {
},
}, alice);
- await api('/notes/polls/vote', {
+ await api('notes/polls/vote', {
noteId: body.createdNote.id,
choice: 0,
}, alice);
- await api('/notes/polls/vote', {
+ await api('notes/polls/vote', {
noteId: body.createdNote.id,
choice: 1,
}, alice);
- const res = await api('/notes/polls/vote', {
+ const res = await api('notes/polls/vote', {
noteId: body.createdNote.id,
choice: 2,
}, alice);
@@ -620,7 +621,7 @@ describe('Note', () => {
});
test('締め切られている場合は投票できない', async () => {
- const { body } = await api('/notes/create', {
+ const { body } = await api('notes/create', {
text: 'test',
poll: {
choices: ['sakura', 'izumi', 'ako'],
@@ -630,7 +631,7 @@ describe('Note', () => {
await new Promise(x => setTimeout(x, 2));
- const res = await api('/notes/polls/vote', {
+ const res = await api('notes/polls/vote', {
noteId: body.createdNote.id,
choice: 1,
}, alice);
@@ -649,7 +650,7 @@ describe('Note', () => {
await new Promise(x => setTimeout(x, 2));
- const note1 = await api('/notes/create', {
+ const note1 = await api('notes/create', {
text: 'hogetesthuge',
}, alice);
@@ -666,7 +667,7 @@ describe('Note', () => {
assert.strictEqual(sensitive.status, 204);
- const note2 = await api('/notes/create', {
+ const note2 = await api('notes/create', {
text: 'hogetesthuge',
}, alice);
@@ -683,7 +684,7 @@ describe('Note', () => {
assert.strictEqual(sensitive.status, 204);
- const note2 = await api('/notes/create', {
+ const note2 = await api('notes/create', {
text: 'hogeTesthuge',
}, alice);
@@ -702,7 +703,7 @@ describe('Note', () => {
await new Promise(x => setTimeout(x, 2));
- const note1 = await api('/notes/create', {
+ const note1 = await api('notes/create', {
text: 'hogetesthuge',
}, alice);
@@ -719,7 +720,7 @@ describe('Note', () => {
assert.strictEqual(prohibited.status, 204);
- const note2 = await api('/notes/create', {
+ const note2 = await api('notes/create', {
text: 'hogetesthuge',
}, alice);
@@ -736,7 +737,7 @@ describe('Note', () => {
assert.strictEqual(prohibited.status, 204);
- const note2 = await api('/notes/create', {
+ const note2 = await api('notes/create', {
text: 'hogeTesthuge',
}, alice);
@@ -755,7 +756,7 @@ describe('Note', () => {
await new Promise(x => setTimeout(x, 2));
- const note1 = await api('/notes/create', {
+ const note1 = await api('notes/create', {
text: 'hogetesthuge',
}, tom);
@@ -783,7 +784,7 @@ describe('Note', () => {
priority: 1,
value: 0,
},
- },
+ } as any,
}, alice);
assert.strictEqual(res.status, 200);
@@ -799,7 +800,7 @@ describe('Note', () => {
await new Promise(x => setTimeout(x, 2));
- const note = await api('/notes/create', {
+ const note = await api('notes/create', {
text: '@bob potentially annoying text',
}, alice);
@@ -837,7 +838,7 @@ describe('Note', () => {
priority: 1,
value: 0,
},
- },
+ } as any,
}, alice);
assert.strictEqual(res.status, 200);
@@ -853,10 +854,10 @@ describe('Note', () => {
await new Promise(x => setTimeout(x, 2));
- const note = await api('/notes/create', {
+ const note = await api('notes/create', {
text: 'potentially annoying text',
visibility: 'specified',
- visibleUserIds: [ bob.id ],
+ visibleUserIds: [bob.id],
}, alice);
assert.strictEqual(note.status, 400);
@@ -893,7 +894,7 @@ describe('Note', () => {
priority: 1,
value: 1,
},
- },
+ } as any,
}, alice);
assert.strictEqual(res.status, 200);
@@ -909,10 +910,10 @@ describe('Note', () => {
await new Promise(x => setTimeout(x, 2));
- const note = await api('/notes/create', {
+ const note = await api('notes/create', {
text: '@bob potentially annoying text',
visibility: 'specified',
- visibleUserIds: [ bob.id ],
+ visibleUserIds: [bob.id],
}, alice);
assert.strictEqual(note.status, 200);
diff --git a/packages/backend/test/e2e/renote-mute.ts b/packages/backend/test/e2e/renote-mute.ts
index 403de0cb8d..9826068e48 100644
--- a/packages/backend/test/e2e/renote-mute.ts
+++ b/packages/backend/test/e2e/renote-mute.ts
@@ -22,7 +22,7 @@ describe('Renote Mute', () => {
}, 1000 * 60 * 2);
test('ミュート作成', async () => {
- const res = await api('/renote-mute/create', {
+ const res = await api('renote-mute/create', {
userId: carol.id,
}, alice);
@@ -37,7 +37,7 @@ describe('Renote Mute', () => {
// redisに追加されるのを待つ
await sleep(100);
- const res = await api('/notes/local-timeline', {}, alice);
+ const res = await api('notes/local-timeline', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -54,7 +54,7 @@ describe('Renote Mute', () => {
// redisに追加されるのを待つ
await sleep(100);
- const res = await api('/notes/local-timeline', {}, alice);
+ const res = await api('notes/local-timeline', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
diff --git a/packages/backend/test/e2e/streaming.ts b/packages/backend/test/e2e/streaming.ts
index 57ce73ba60..edb930617f 100644
--- a/packages/backend/test/e2e/streaming.ts
+++ b/packages/backend/test/e2e/streaming.ts
@@ -601,7 +601,7 @@ describe('Streaming', () => {
// #10443
test('ミュートしているサーバのノートがリストTLに流れない', async () => {
- await api('/i/update', {
+ await api('i/update', {
mutedInstances: ['example.com'],
}, chitose);
@@ -618,7 +618,7 @@ describe('Streaming', () => {
// #10443
test('ミュートしているサーバのノートに対するリプライがリストTLに流れない', async () => {
- await api('/i/update', {
+ await api('i/update', {
mutedInstances: ['example.com'],
}, chitose);
@@ -635,7 +635,7 @@ describe('Streaming', () => {
// #10443
test('ミュートしているサーバのノートに対するリノートがリストTLに流れない', async () => {
- await api('/i/update', {
+ await api('i/update', {
mutedInstances: ['example.com'],
}, chitose);
diff --git a/packages/backend/test/e2e/thread-mute.ts b/packages/backend/test/e2e/thread-mute.ts
index b4570cdef1..53bb6eb765 100644
--- a/packages/backend/test/e2e/thread-mute.ts
+++ b/packages/backend/test/e2e/thread-mute.ts
@@ -24,12 +24,12 @@ describe('Note thread mute', () => {
const bobNote = await post(bob, { text: '@alice @carol root note' });
const aliceReply = await post(alice, { replyId: bobNote.id, text: '@bob @carol child note' });
- await api('/notes/thread-muting/create', { noteId: bobNote.id }, alice);
+ await api('notes/thread-muting/create', { noteId: bobNote.id }, alice);
const carolReply = await post(carol, { replyId: bobNote.id, text: '@bob @alice child note' });
const carolReplyWithoutMention = await post(carol, { replyId: aliceReply.id, text: 'child note' });
- const res = await api('/notes/mentions', {}, alice);
+ const res = await api('notes/mentions', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
@@ -40,15 +40,15 @@ describe('Note thread mute', () => {
test('ミュートしているスレッドからメンションされても、hasUnreadMentions が true にならない', async () => {
// 状態リセット
- await api('/i/read-all-unread-notes', {}, alice);
+ await api('i/read-all-unread-notes', {}, alice);
const bobNote = await post(bob, { text: '@alice @carol root note' });
- await api('/notes/thread-muting/create', { noteId: bobNote.id }, alice);
+ await api('notes/thread-muting/create', { noteId: bobNote.id }, alice);
const carolReply = await post(carol, { replyId: bobNote.id, text: '@bob @alice child note' });
- const res = await api('/i', {}, alice);
+ const res = await api('i', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.body.hasUnreadMentions, false);
@@ -56,11 +56,11 @@ describe('Note thread mute', () => {
test('ミュートしているスレッドからメンションされても、ストリームに unreadMention イベントが流れてこない', () => new Promise<void>(async done => {
// 状態リセット
- await api('/i/read-all-unread-notes', {}, alice);
+ await api('i/read-all-unread-notes', {}, alice);
const bobNote = await post(bob, { text: '@alice @carol root note' });
- await api('/notes/thread-muting/create', { noteId: bobNote.id }, alice);
+ await api('notes/thread-muting/create', { noteId: bobNote.id }, alice);
let fired = false;
@@ -84,12 +84,12 @@ describe('Note thread mute', () => {
const bobNote = await post(bob, { text: '@alice @carol root note' });
const aliceReply = await post(alice, { replyId: bobNote.id, text: '@bob @carol child note' });
- await api('/notes/thread-muting/create', { noteId: bobNote.id }, alice);
+ await api('notes/thread-muting/create', { noteId: bobNote.id }, alice);
const carolReply = await post(carol, { replyId: bobNote.id, text: '@bob @alice child note' });
const carolReplyWithoutMention = await post(carol, { replyId: aliceReply.id, text: 'child note' });
- const res = await api('/i/notifications', {}, alice);
+ const res = await api('i/notifications', {}, alice);
assert.strictEqual(res.status, 200);
assert.strictEqual(Array.isArray(res.body), true);
diff --git a/packages/backend/test/e2e/timelines.ts b/packages/backend/test/e2e/timelines.ts
index 0e71d707dd..5487292afc 100644
--- a/packages/backend/test/e2e/timelines.ts
+++ b/packages/backend/test/e2e/timelines.ts
@@ -26,7 +26,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.find((note: any) => note.id === aliceNote.id).text, 'hi');
@@ -35,14 +35,14 @@ describe('Timelines', () => {
test.concurrent('フォローしているユーザーのノートが含まれる', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi' });
const carolNote = await post(carol, { text: 'hi' });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -51,14 +51,14 @@ describe('Timelines', () => {
test.concurrent('フォローしているユーザーの visibility: followers なノートが含まれる', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'followers' });
const carolNote = await post(carol, { text: 'hi' });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'hi');
@@ -68,14 +68,14 @@ describe('Timelines', () => {
test.concurrent('withReplies: false でフォローしているユーザーの他人への返信が含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -84,15 +84,15 @@ describe('Timelines', () => {
test.concurrent('withReplies: true でフォローしているユーザーの他人への返信が含まれる', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
- await api('/following/update', { userId: bob.id, withReplies: true }, alice);
+ await api('following/create', { userId: bob.id }, alice);
+ await api('following/update', { userId: bob.id, withReplies: true }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -101,15 +101,15 @@ describe('Timelines', () => {
test.concurrent('withReplies: true でフォローしているユーザーの他人へのDM返信が含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
- await api('/following/update', { userId: bob.id, withReplies: true }, alice);
+ await api('following/create', { userId: bob.id }, alice);
+ await api('following/update', { userId: bob.id, withReplies: true }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id, visibility: 'specified', visibleUserIds: [carolNote.id] });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -118,15 +118,15 @@ describe('Timelines', () => {
test.concurrent('withReplies: true でフォローしているユーザーの他人の visibility: followers な投稿への返信が含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
- await api('/following/update', { userId: bob.id, withReplies: true }, alice);
+ await api('following/create', { userId: bob.id }, alice);
+ await api('following/update', { userId: bob.id, withReplies: true }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi', visibility: 'followers' });
const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -135,17 +135,17 @@ describe('Timelines', () => {
test.concurrent('withReplies: true でフォローしているユーザーの行った別のフォローしているユーザーの visibility: followers な投稿への返信が含まれる', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
- await api('/following/create', { userId: carol.id }, alice);
- await api('/following/create', { userId: carol.id }, bob);
- await api('/following/update', { userId: bob.id, withReplies: true }, alice);
+ await api('following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: carol.id }, alice);
+ await api('following/create', { userId: carol.id }, bob);
+ await api('following/update', { userId: bob.id, withReplies: true }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi', visibility: 'followers' });
const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
@@ -155,16 +155,16 @@ describe('Timelines', () => {
test.concurrent('withReplies: true でフォローしているユーザーの行った別のフォローしているユーザーの投稿への visibility: specified な返信が含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
- await api('/following/create', { userId: carol.id }, alice);
- await api('/following/update', { userId: bob.id, withReplies: true }, alice);
+ await api('following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: carol.id }, alice);
+ await api('following/update', { userId: bob.id, withReplies: true }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id, visibility: 'specified', visibleUserIds: [carolNote.id] });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
@@ -173,14 +173,14 @@ describe('Timelines', () => {
test.concurrent('withReplies: false でフォローしているユーザーのそのユーザー自身への返信が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const bobNote1 = await post(bob, { text: 'hi' });
const bobNote2 = await post(bob, { text: 'hi', replyId: bobNote1.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
@@ -189,14 +189,14 @@ describe('Timelines', () => {
test.concurrent('withReplies: false でフォローしているユーザーからの自分への返信が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const aliceNote = await post(alice, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
@@ -210,7 +210,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
@@ -219,14 +219,14 @@ describe('Timelines', () => {
test.concurrent('フォローしているユーザーの他人の投稿のリノートが含まれる', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { renoteId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -235,14 +235,14 @@ describe('Timelines', () => {
test.concurrent('[withRenotes: false] フォローしているユーザーの他人の投稿のリノートが含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { renoteId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', {
+ const res = await api('notes/timeline', {
withRenotes: false,
}, alice);
@@ -253,14 +253,14 @@ describe('Timelines', () => {
test.concurrent('[withRenotes: false] フォローしているユーザーの他人の投稿の引用が含まれる', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', renoteId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', {
+ const res = await api('notes/timeline', {
withRenotes: false,
}, alice);
@@ -271,13 +271,13 @@ describe('Timelines', () => {
test.concurrent('フォローしているユーザーの他人への visibility: specified なノートが含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'specified', visibleUserIds: [carol.id] });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -285,15 +285,15 @@ describe('Timelines', () => {
test.concurrent('フォローしているユーザーが行ったミュートしているユーザーのリノートが含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
- await api('/mute/create', { userId: carol.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
+ await api('mute/create', { userId: carol.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', renoteId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -302,16 +302,16 @@ describe('Timelines', () => {
test.concurrent('withReplies: true でフォローしているユーザーが行ったミュートしているユーザーの投稿への返信が含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
- await api('/following/update', { userId: bob.id, withReplies: true }, alice);
- await api('/mute/create', { userId: carol.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
+ await api('following/update', { userId: bob.id, withReplies: true }, alice);
+ await api('mute/create', { userId: carol.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -321,13 +321,13 @@ describe('Timelines', () => {
const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
await sendEnvUpdateRequest({ key: 'FORCE_FOLLOW_REMOTE_USER_FOR_TESTING', value: 'true' });
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
const bobNote = await post(bob, { text: 'hi' });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -336,13 +336,13 @@ describe('Timelines', () => {
const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
await sendEnvUpdateRequest({ key: 'FORCE_FOLLOW_REMOTE_USER_FOR_TESTING', value: 'true' });
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
const bobNote = await post(bob, { text: 'hi', visibility: 'home' });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -350,7 +350,7 @@ describe('Timelines', () => {
test.concurrent('[withFiles: true] フォローしているユーザーのファイル付きノートのみ含まれる', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const [bobFile, carolFile] = await Promise.all([
uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png'),
@@ -363,7 +363,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100, withFiles: true }, alice);
+ const res = await api('notes/timeline', { limit: 100, withFiles: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
@@ -374,14 +374,14 @@ describe('Timelines', () => {
test.concurrent('フォローしているユーザーのチャンネル投稿が含まれない', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const channel = await api('/channels/create', { name: 'channel' }, bob).then(x => x.body);
- await api('/following/create', { userId: bob.id }, alice);
+ const channel = await api('channels/create', { name: 'channel' }, bob).then(x => x.body);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', channelId: channel.id });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -393,7 +393,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.find((note: any) => note.id === aliceNote.id).text, 'hi');
@@ -402,13 +402,13 @@ describe('Timelines', () => {
test.concurrent('フォローしているユーザーの自身を visibleUserIds に指定した visibility: specified なノートが含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'specified', visibleUserIds: [alice.id] });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'hi');
@@ -421,7 +421,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -429,13 +429,13 @@ describe('Timelines', () => {
test.concurrent('フォローしているユーザーの自身を visibleUserIds に指定していない visibility: specified なノートが含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'specified', visibleUserIds: [carol.id] });
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -448,7 +448,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.find((note: any) => note.id === aliceNote.id).text, 'ok');
@@ -463,7 +463,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'ok');
@@ -479,7 +479,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/timeline', { limit: 100 }, alice);
+ const res = await api('notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -494,7 +494,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100 }, alice);
+ const res = await api('notes/local-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -508,7 +508,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100 }, alice);
+ const res = await api('notes/local-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
@@ -522,7 +522,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100 }, alice);
+ const res = await api('notes/local-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
@@ -531,12 +531,12 @@ describe('Timelines', () => {
test.concurrent('チャンネル投稿が含まれない', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const channel = await api('/channels/create', { name: 'channel' }, bob).then(x => x.body);
+ const channel = await api('channels/create', { name: 'channel' }, bob).then(x => x.body);
const bobNote = await post(bob, { text: 'hi', channelId: channel.id });
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100 }, alice);
+ const res = await api('notes/local-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -548,7 +548,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100 }, alice);
+ const res = await api('notes/local-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -557,14 +557,14 @@ describe('Timelines', () => {
test.concurrent('フォローしているユーザーの visibility: home なノートが含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: carol.id }, alice);
+ await api('following/create', { userId: carol.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi', visibility: 'home' });
const bobNote = await post(bob, { text: 'hi' });
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100 }, alice);
+ const res = await api('notes/local-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -573,14 +573,14 @@ describe('Timelines', () => {
test.concurrent('ミュートしているユーザーのノートが含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/mute/create', { userId: carol.id }, alice);
+ await api('mute/create', { userId: carol.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi' });
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100 }, alice);
+ const res = await api('notes/local-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -589,15 +589,15 @@ describe('Timelines', () => {
test.concurrent('フォローしているユーザーが行ったミュートしているユーザーのリノートが含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
- await api('/mute/create', { userId: carol.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
+ await api('mute/create', { userId: carol.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', renoteId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100 }, alice);
+ const res = await api('notes/local-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -606,16 +606,16 @@ describe('Timelines', () => {
test.concurrent('withReplies: true でフォローしているユーザーが行ったミュートしているユーザーの投稿への返信が含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
- await api('/following/update', { userId: bob.id, withReplies: true }, alice);
- await api('/mute/create', { userId: carol.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
+ await api('following/update', { userId: bob.id, withReplies: true }, alice);
+ await api('mute/create', { userId: carol.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100 }, alice);
+ const res = await api('notes/local-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
@@ -624,14 +624,14 @@ describe('Timelines', () => {
test.concurrent('withReplies: false でフォローしているユーザーからの自分への返信が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const aliceNote = await post(alice, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id });
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100 }, alice);
+ const res = await api('notes/local-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
@@ -645,7 +645,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100, withReplies: true }, alice);
+ const res = await api('notes/local-timeline', { limit: 100, withReplies: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -659,7 +659,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100, withFiles: true }, alice);
+ const res = await api('notes/local-timeline', { limit: 100, withFiles: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
@@ -674,7 +674,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/hybrid-timeline', { limit: 100 }, alice);
+ const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -686,7 +686,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/hybrid-timeline', { limit: 100 }, alice);
+ const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -694,13 +694,13 @@ describe('Timelines', () => {
test.concurrent('フォローしているローカルユーザーの visibility: home なノートが含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'home' });
await waitForPushToTl();
- const res = await api('/notes/hybrid-timeline', { limit: 100 }, alice);
+ const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -708,14 +708,14 @@ describe('Timelines', () => {
test.concurrent('withReplies: false でフォローしているユーザーからの自分への返信が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const aliceNote = await post(alice, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id });
await waitForPushToTl();
- const res = await api('/notes/hybrid-timeline', { limit: 100 }, alice);
+ const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
@@ -729,7 +729,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/hybrid-timeline', { limit: 100 }, alice);
+ const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
@@ -742,7 +742,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/local-timeline', { limit: 100 }, alice);
+ const res = await api('notes/local-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -751,13 +751,13 @@ describe('Timelines', () => {
const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
await sendEnvUpdateRequest({ key: 'FORCE_FOLLOW_REMOTE_USER_FOR_TESTING', value: 'true' });
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
const bobNote = await post(bob, { text: 'hi' });
await waitForPushToTl();
- const res = await api('/notes/hybrid-timeline', { limit: 100 }, alice);
+ const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -766,13 +766,13 @@ describe('Timelines', () => {
const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
await sendEnvUpdateRequest({ key: 'FORCE_FOLLOW_REMOTE_USER_FOR_TESTING', value: 'true' });
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
const bobNote = await post(bob, { text: 'hi', visibility: 'home' });
await waitForPushToTl();
- const res = await api('/notes/hybrid-timeline', { limit: 100 }, alice);
+ const res = await api('notes/hybrid-timeline', { limit: 100 }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -785,7 +785,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/hybrid-timeline', { limit: 100, withReplies: true }, alice);
+ const res = await api('notes/hybrid-timeline', { limit: 100, withReplies: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -799,7 +799,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/notes/hybrid-timeline', { limit: 100, withFiles: true }, alice);
+ const res = await api('notes/hybrid-timeline', { limit: 100, withFiles: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
@@ -810,14 +810,14 @@ describe('Timelines', () => {
test.concurrent('リスインしているフォローしていないユーザーのノートが含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi' });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -825,14 +825,14 @@ describe('Timelines', () => {
test.concurrent('リスインしているフォローしていないユーザーの visibility: home なノートが含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'home' });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -840,14 +840,14 @@ describe('Timelines', () => {
test.concurrent('リスインしているフォローしていないユーザーの visibility: followers なノートが含まれない', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'followers' });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -855,15 +855,15 @@ describe('Timelines', () => {
test.concurrent('リスインしているフォローしていないユーザーの他人への返信が含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -871,15 +871,15 @@ describe('Timelines', () => {
test.concurrent('リスインしているフォローしていないユーザーのユーザー自身への返信が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
await sleep(1000);
const bobNote1 = await post(bob, { text: 'hi' });
const bobNote2 = await post(bob, { text: 'hi', replyId: bobNote1.id });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
@@ -888,32 +888,50 @@ describe('Timelines', () => {
test.concurrent('withReplies: false でリスインしているフォローしていないユーザーからの自分への返信が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ await api('users/lists/update-membership', { listId: list.id, userId: bob.id, withReplies: false }, alice);
await sleep(1000);
const aliceNote = await post(alice, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id, withReplies: false }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
+ test.concurrent('withReplies: false でリスインしているフォローしていないユーザーの他人への返信が含まれない', async () => {
+ const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
+
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ await api('users/lists/update-membership', { listId: list.id, userId: bob.id, withReplies: false }, alice);
+ await sleep(1000);
+ const carolNote = await post(carol, { text: 'hi' });
+ const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id });
+
+ await waitForPushToTl();
+
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
+
+ assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
+ });
+
test.concurrent('withReplies: true でリスインしているフォローしていないユーザーの他人への返信が含まれる', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
- await api('/users/lists/update-membership', { listId: list.id, userId: bob.id, withReplies: true }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ await api('users/lists/update-membership', { listId: list.id, userId: bob.id, withReplies: true }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -921,15 +939,15 @@ describe('Timelines', () => {
test.concurrent('リスインしているフォローしているユーザーの visibility: home なノートが含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'home' });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -937,15 +955,15 @@ describe('Timelines', () => {
test.concurrent('リスインしているフォローしているユーザーの visibility: followers なノートが含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'followers' });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'hi');
@@ -954,14 +972,14 @@ describe('Timelines', () => {
test.concurrent('リスインしている自分の visibility: followers なノートが含まれる', async () => {
const [alice] = await Promise.all([signup(), signup()]);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: alice.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: alice.id }, alice);
await sleep(1000);
const aliceNote = await post(alice, { text: 'hi', visibility: 'followers' });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.find((note: any) => note.id === aliceNote.id).text, 'hi');
@@ -970,15 +988,15 @@ describe('Timelines', () => {
test.concurrent('リスインしているユーザーのチャンネルノートが含まれない', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const channel = await api('/channels/create', { name: 'channel' }, bob).then(x => x.body);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ const channel = await api('channels/create', { name: 'channel' }, bob).then(x => x.body);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', channelId: channel.id });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -986,15 +1004,15 @@ describe('Timelines', () => {
test.concurrent('[withFiles: true] リスインしているユーザーのファイル付きノートのみ含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png');
const bobNote1 = await post(bob, { text: 'hi' });
const bobNote2 = await post(bob, { fileIds: [file.id] });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id, withFiles: true }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id, withFiles: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
@@ -1003,14 +1021,14 @@ describe('Timelines', () => {
test.concurrent('リスインしているユーザーの自身宛ての visibility: specified なノートが含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'specified', visibleUserIds: [alice.id] });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'hi');
@@ -1019,15 +1037,15 @@ describe('Timelines', () => {
test.concurrent('リスインしているユーザーの自身宛てではない visibility: specified なノートが含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
- await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
- await api('/users/lists/push', { listId: list.id, userId: carol.id }, alice);
+ const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body);
+ await api('users/lists/push', { listId: list.id, userId: bob.id }, alice);
+ await api('users/lists/push', { listId: list.id, userId: carol.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'specified', visibleUserIds: [carol.id] });
await waitForPushToTl();
- const res = await api('/notes/user-list-timeline', { listId: list.id }, alice);
+ const res = await api('notes/user-list-timeline', { listId: list.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -1041,7 +1059,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id }, alice);
+ const res = await api('users/notes', { userId: bob.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -1053,7 +1071,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id }, alice);
+ const res = await api('users/notes', { userId: bob.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -1061,13 +1079,13 @@ describe('Timelines', () => {
test.concurrent('フォローしているユーザーの visibility: followers なノートが含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- await api('/following/create', { userId: bob.id }, alice);
+ await api('following/create', { userId: bob.id }, alice);
await sleep(1000);
const bobNote = await post(bob, { text: 'hi', visibility: 'followers' });
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id }, alice);
+ const res = await api('users/notes', { userId: bob.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.find((note: any) => note.id === bobNote.id).text, 'hi');
@@ -1080,7 +1098,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/users/notes', { userId: alice.id }, alice);
+ const res = await api('users/notes', { userId: alice.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.find((note: any) => note.id === aliceNote.id).text, 'hi');
@@ -1089,12 +1107,12 @@ describe('Timelines', () => {
test.concurrent('チャンネル投稿が含まれない', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const channel = await api('/channels/create', { name: 'channel' }, bob).then(x => x.body);
+ const channel = await api('channels/create', { name: 'channel' }, bob).then(x => x.body);
const bobNote = await post(bob, { text: 'hi', channelId: channel.id });
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id }, alice);
+ const res = await api('users/notes', { userId: bob.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -1108,7 +1126,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id }, alice);
+ const res = await api('users/notes', { userId: bob.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), false);
@@ -1123,7 +1141,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id, withReplies: true }, alice);
+ const res = await api('users/notes', { userId: bob.id, withReplies: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
@@ -1138,7 +1156,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id, withReplies: true }, alice);
+ const res = await api('users/notes', { userId: bob.id, withReplies: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), false);
@@ -1153,7 +1171,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id, withFiles: true }, alice);
+ const res = await api('users/notes', { userId: bob.id, withFiles: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
@@ -1162,12 +1180,12 @@ describe('Timelines', () => {
test.concurrent('[withChannelNotes: true] チャンネル投稿が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const channel = await api('/channels/create', { name: 'channel' }, bob).then(x => x.body);
+ const channel = await api('channels/create', { name: 'channel' }, bob).then(x => x.body);
const bobNote = await post(bob, { text: 'hi', channelId: channel.id });
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id, withChannelNotes: true }, alice);
+ const res = await api('users/notes', { userId: bob.id, withChannelNotes: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -1175,12 +1193,12 @@ describe('Timelines', () => {
test.concurrent('[withChannelNotes: true] 他人が取得した場合センシティブチャンネル投稿が含まれない', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- const channel = await api('/channels/create', { name: 'channel', isSensitive: true }, bob).then(x => x.body);
+ const channel = await api('channels/create', { name: 'channel', isSensitive: true }, bob).then(x => x.body);
const bobNote = await post(bob, { text: 'hi', channelId: channel.id });
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id, withChannelNotes: true }, alice);
+ const res = await api('users/notes', { userId: bob.id, withChannelNotes: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -1188,12 +1206,12 @@ describe('Timelines', () => {
test.concurrent('[withChannelNotes: true] 自分が取得した場合センシティブチャンネル投稿が含まれる', async () => {
const [bob] = await Promise.all([signup()]);
- const channel = await api('/channels/create', { name: 'channel', isSensitive: true }, bob).then(x => x.body);
+ const channel = await api('channels/create', { name: 'channel', isSensitive: true }, bob).then(x => x.body);
const bobNote = await post(bob, { text: 'hi', channelId: channel.id });
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id, withChannelNotes: true }, bob);
+ const res = await api('users/notes', { userId: bob.id, withChannelNotes: true }, bob);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
});
@@ -1201,14 +1219,14 @@ describe('Timelines', () => {
test.concurrent('ミュートしているユーザーに関連する投稿が含まれない', async () => {
const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]);
- await api('/mute/create', { userId: carol.id }, alice);
+ await api('mute/create', { userId: carol.id }, alice);
await sleep(1000);
const carolNote = await post(carol, { text: 'hi' });
const bobNote = await post(bob, { text: 'hi', renoteId: carolNote.id });
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id }, alice);
+ const res = await api('users/notes', { userId: bob.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
@@ -1216,7 +1234,7 @@ describe('Timelines', () => {
test.concurrent('ミュートしていても userId に指定したユーザーの投稿が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
- await api('/mute/create', { userId: bob.id }, alice);
+ await api('mute/create', { userId: bob.id }, alice);
await sleep(1000);
const bobNote1 = await post(bob, { text: 'hi' });
const bobNote2 = await post(bob, { text: 'hi', replyId: bobNote1.id });
@@ -1224,7 +1242,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id }, alice);
+ const res = await api('users/notes', { userId: bob.id }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote1.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote2.id), true);
@@ -1238,7 +1256,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/users/notes', { userId: alice.id, withReplies: true }, alice);
+ const res = await api('users/notes', { userId: alice.id, withReplies: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
});
@@ -1250,7 +1268,7 @@ describe('Timelines', () => {
await waitForPushToTl();
- const res = await api('/users/notes', { userId: bob.id, withReplies: true }, alice);
+ const res = await api('users/notes', { userId: bob.id, withReplies: true }, alice);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
});
diff --git a/packages/backend/test/e2e/user-notes.ts b/packages/backend/test/e2e/user-notes.ts
index 6897cf08c6..331e053935 100644
--- a/packages/backend/test/e2e/user-notes.ts
+++ b/packages/backend/test/e2e/user-notes.ts
@@ -11,9 +11,9 @@ import type * as misskey from 'misskey-js';
describe('users/notes', () => {
let alice: misskey.entities.SignupResponse;
- let jpgNote: any;
- let pngNote: any;
- let jpgPngNote: any;
+ let jpgNote: misskey.entities.Note;
+ let pngNote: misskey.entities.Note;
+ let jpgPngNote: misskey.entities.Note;
beforeAll(async () => {
alice = await signup({ username: 'alice' });
@@ -31,7 +31,7 @@ describe('users/notes', () => {
}, 1000 * 60 * 2);
test('withFiles', async () => {
- const res = await api('/users/notes', {
+ const res = await api('users/notes', {
userId: alice.id,
withFiles: true,
}, alice);
diff --git a/packages/backend/test/e2e/users.ts b/packages/backend/test/e2e/users.ts
index 19b905dd47..f5e1234c57 100644
--- a/packages/backend/test/e2e/users.ts
+++ b/packages/backend/test/e2e/users.ts
@@ -8,7 +8,7 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import { inspect } from 'node:util';
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
-import { api, page, post, role, signup, successfulApiCall, uploadFile } from '../utils.js';
+import { api, post, role, signup, successfulApiCall, uploadFile } from '../utils.js';
import type * as misskey from 'misskey-js';
describe('ユーザー', () => {
@@ -24,31 +24,12 @@ describe('ユーザー', () => {
}, {});
};
- // BUG misskey-jsとjson-schemaと実際に返ってくるデータが全部違う
- type UserLite = misskey.entities.UserLite & {
- badgeRoles: any[],
- };
-
- type UserDetailedNotMe = UserLite &
- misskey.entities.UserDetailed & {
- roles: any[],
- };
-
- type MeDetailed = UserDetailedNotMe &
- misskey.entities.MeDetailed & {
- achievements: object[],
- loggedInDays: number,
- policies: object,
- };
-
- type User = MeDetailed & { token: string };
-
- const show = async (id: string, me = root): Promise<MeDetailed | UserDetailedNotMe> => {
- return successfulApiCall({ endpoint: 'users/show', parameters: { userId: id }, user: me }) as any;
+ const show = async (id: string, me = root): Promise<misskey.entities.UserDetailed> => {
+ return successfulApiCall({ endpoint: 'users/show', parameters: { userId: id }, user: me });
};
// UserLiteのキーが過不足なく入っている?
- const userLite = (user: User): Partial<UserLite> => {
+ const userLite = (user: misskey.entities.UserLite): Partial<misskey.entities.UserLite> => {
return stripUndefined({
id: user.id,
name: user.name,
@@ -72,7 +53,7 @@ describe('ユーザー', () => {
};
// UserDetailedNotMeのキーが過不足なく入っている?
- const userDetailedNotMe = (user: User): Partial<UserDetailedNotMe> => {
+ const userDetailedNotMe = (user: misskey.entities.SignupResponse): Partial<misskey.entities.UserDetailedNotMe> => {
return stripUndefined({
...userLite(user),
url: user.url,
@@ -114,7 +95,7 @@ describe('ユーザー', () => {
};
// Relations関連のキーが過不足なく入っている?
- const userDetailedNotMeWithRelations = (user: User): Partial<UserDetailedNotMe> => {
+ const userDetailedNotMeWithRelations = (user: misskey.entities.SignupResponse): Partial<misskey.entities.UserDetailedNotMe> => {
return stripUndefined({
...userDetailedNotMe(user),
isFollowing: user.isFollowing ?? false,
@@ -131,7 +112,7 @@ describe('ユーザー', () => {
};
// MeDetailedのキーが過不足なく入っている?
- const meDetailed = (user: User, security = false): Partial<MeDetailed> => {
+ const meDetailed = (user: misskey.entities.SignupResponse, security = false): Partial<misskey.entities.MeDetailed> => {
return stripUndefined({
...userDetailedNotMe(user),
avatarId: user.avatarId,
@@ -162,6 +143,7 @@ describe('ユーザー', () => {
mutedWords: user.mutedWords,
hardMutedWords: user.hardMutedWords,
mutedInstances: user.mutedInstances,
+ // @ts-expect-error 後方互換性
mutingNotificationTypes: user.mutingNotificationTypes,
notificationRecieveConfig: user.notificationRecieveConfig,
emailNotificationTypes: user.emailNotificationTypes,
@@ -176,61 +158,53 @@ describe('ユーザー', () => {
});
};
- let root: User;
- let alice: User;
+ let root: misskey.entities.SignupResponse;
+ let alice: misskey.entities.SignupResponse;
let aliceNote: misskey.entities.Note;
- let alicePage: misskey.entities.Page;
- let aliceList: misskey.entities.UserList;
- let bob: User;
- let bobNote: misskey.entities.Note;
+ let bob: misskey.entities.SignupResponse;
- let carol: User;
- let dave: User;
- let ellen: User;
- let frank: User;
+ // NOTE: これがないと落ちる(bob の updatedAt が null になってしまうため?)
+ let bobNote: misskey.entities.Note; // eslint-disable-line @typescript-eslint/no-unused-vars
- let usersReplying: User[];
+ let carol: misskey.entities.SignupResponse;
- let userNoNote: User;
- let userNotExplorable: User;
- let userLocking: User;
- let userAdmin: User;
- let roleAdmin: any;
- let userModerator: User;
- let roleModerator: any;
- let userRolePublic: User;
- let rolePublic: any;
- let userRoleBadge: User;
- let roleBadge: any;
- let userSilenced: User;
- let roleSilenced: any;
- let userSuspended: User;
- let userDeletedBySelf: User;
- let userDeletedByAdmin: User;
- let userFollowingAlice: User;
- let userFollowedByAlice: User;
- let userBlockingAlice: User;
- let userBlockedByAlice: User;
- let userMutingAlice: User;
- let userMutedByAlice: User;
- let userRnMutingAlice: User;
- let userRnMutedByAlice: User;
- let userFollowRequesting: User;
- let userFollowRequested: User;
+ let usersReplying: misskey.entities.SignupResponse[];
+
+ let userNoNote: misskey.entities.SignupResponse;
+ let userNotExplorable: misskey.entities.SignupResponse;
+ let userLocking: misskey.entities.SignupResponse;
+ let userAdmin: misskey.entities.SignupResponse;
+ let roleAdmin: misskey.entities.Role;
+ let userModerator: misskey.entities.SignupResponse;
+ let roleModerator: misskey.entities.Role;
+ let userRolePublic: misskey.entities.SignupResponse;
+ let rolePublic: misskey.entities.Role;
+ let userRoleBadge: misskey.entities.SignupResponse;
+ let roleBadge: misskey.entities.Role;
+ let userSilenced: misskey.entities.SignupResponse;
+ let roleSilenced: misskey.entities.Role;
+ let userSuspended: misskey.entities.SignupResponse;
+ let userDeletedBySelf: misskey.entities.SignupResponse;
+ let userDeletedByAdmin: misskey.entities.SignupResponse;
+ let userFollowingAlice: misskey.entities.SignupResponse;
+ let userFollowedByAlice: misskey.entities.SignupResponse;
+ let userBlockingAlice: misskey.entities.SignupResponse;
+ let userBlockedByAlice: misskey.entities.SignupResponse;
+ let userMutingAlice: misskey.entities.SignupResponse;
+ let userMutedByAlice: misskey.entities.SignupResponse;
+ let userRnMutingAlice: misskey.entities.SignupResponse;
+ let userRnMutedByAlice: misskey.entities.SignupResponse;
+ let userFollowRequesting: misskey.entities.SignupResponse;
+ let userFollowRequested: misskey.entities.SignupResponse;
beforeAll(async () => {
root = await signup({ username: 'root' });
alice = await signup({ username: 'alice' });
- aliceNote = await post(alice, { text: 'test' }) as any;
- alicePage = await page(alice);
- aliceList = (await api('users/list/create', { name: 'aliceList' }, alice)).body;
+ aliceNote = await post(alice, { text: 'test' });
bob = await signup({ username: 'bob' });
- bobNote = await post(bob, { text: 'test' }) as any;
+ bobNote = await post(bob, { text: 'test' });
carol = await signup({ username: 'carol' });
- dave = await signup({ username: 'dave' });
- ellen = await signup({ username: 'ellen' });
- frank = await signup({ username: 'frank' });
// @alice -> @replyingへのリプライ。Promise.allで一気に作るとtimeoutしてしまうのでreduceで一つ一つawaitする
usersReplying = await [...Array(10)].map((_, i) => i).reduce(async (acc, i) => {
@@ -241,7 +215,7 @@ describe('ユーザー', () => {
}
return (await acc).concat(u);
- }, Promise.resolve([] as User[]));
+ }, Promise.resolve([] as misskey.entities.SignupResponse[]));
userNoNote = await signup({ username: 'userNoNote' });
userNotExplorable = await signup({ username: 'userNotExplorable' });
@@ -309,7 +283,7 @@ describe('ユーザー', () => {
beforeEach(async () => {
alice = {
...alice,
- ...await successfulApiCall({ endpoint: 'i', parameters: {}, user: alice }) as any,
+ ...await successfulApiCall({ endpoint: 'i', parameters: {}, user: alice }),
};
aliceNote = await successfulApiCall({ endpoint: 'notes/show', parameters: { noteId: aliceNote.id }, user: alice });
});
@@ -322,7 +296,7 @@ describe('ユーザー', () => {
endpoint: 'signup',
parameters: { username: 'zoe', password: 'password' },
user: undefined,
- }) as unknown as User; // BUG MeDetailedに足りないキーがある
+ }) as unknown as misskey.entities.SignupResponse; // BUG MeDetailedに足りないキーがある
// signupの時はtokenが含まれる特別なMeDetailedが返ってくる
assert.match(response.token, /[a-zA-Z0-9]{16}/);
@@ -332,7 +306,7 @@ describe('ユーザー', () => {
assert.strictEqual(response.name, null);
assert.strictEqual(response.username, 'zoe');
assert.strictEqual(response.host, null);
- assert.match(response.avatarUrl, /^[-a-zA-Z0-9@:%._\+~#&?=\/]+$/);
+ response.avatarUrl && assert.match(response.avatarUrl, /^[-a-zA-Z0-9@:%._\+~#&?=\/]+$/);
assert.strictEqual(response.avatarBlurhash, null);
assert.deepStrictEqual(response.avatarDecorations, []);
assert.strictEqual(response.isBot, false);
@@ -407,6 +381,7 @@ describe('ユーザー', () => {
assert.deepStrictEqual(response.unreadAnnouncements, []);
assert.deepStrictEqual(response.mutedWords, []);
assert.deepStrictEqual(response.mutedInstances, []);
+ // @ts-expect-error 後方互換のため
assert.deepStrictEqual(response.mutingNotificationTypes, []);
assert.deepStrictEqual(response.notificationRecieveConfig, {});
assert.deepStrictEqual(response.emailNotificationTypes, ['follow', 'receiveFollowRequest']);
@@ -436,68 +411,66 @@ describe('ユーザー', () => {
//#region 自分の情報の更新(i/update)
test.each([
- { parameters: (): object => ({ name: null }) },
- { parameters: (): object => ({ name: 'x'.repeat(50) }) },
- { parameters: (): object => ({ name: 'x' }) },
- { parameters: (): object => ({ name: 'My name' }) },
- { parameters: (): object => ({ description: null }) },
- { parameters: (): object => ({ description: 'x'.repeat(1500) }) },
- { parameters: (): object => ({ description: 'x' }) },
- { parameters: (): object => ({ description: 'My description' }) },
- { parameters: (): object => ({ location: null }) },
- { parameters: (): object => ({ location: 'x'.repeat(50) }) },
- { parameters: (): object => ({ location: 'x' }) },
- { parameters: (): object => ({ location: 'My location' }) },
- { parameters: (): object => ({ birthday: '0000-00-00' }) },
- { parameters: (): object => ({ birthday: '9999-99-99' }) },
- { parameters: (): object => ({ lang: 'en-US' }) },
- { parameters: (): object => ({ fields: [] }) },
- { parameters: (): object => ({ fields: [{ name: 'x', value: 'x' }] }) },
- { parameters: (): object => ({ fields: [{ name: 'x'.repeat(3000), value: 'x'.repeat(3000) }] }) }, // BUG? fieldには制限がない
- { parameters: (): object => ({ fields: Array(16).fill({ name: 'x', value: 'y' }) }) },
- { parameters: (): object => ({ isLocked: true }) },
- { parameters: (): object => ({ isLocked: false }) },
- { parameters: (): object => ({ isExplorable: false }) },
- { parameters: (): object => ({ isExplorable: true }) },
- { parameters: (): object => ({ hideOnlineStatus: true }) },
- { parameters: (): object => ({ hideOnlineStatus: false }) },
- { parameters: (): object => ({ publicReactions: false }) },
- { parameters: (): object => ({ publicReactions: true }) },
- { parameters: (): object => ({ autoAcceptFollowed: true }) },
- { parameters: (): object => ({ autoAcceptFollowed: false }) },
- { parameters: (): object => ({ noCrawle: true }) },
- { parameters: (): object => ({ noCrawle: false }) },
- { parameters: (): object => ({ preventAiLearning: false }) },
- { parameters: (): object => ({ preventAiLearning: true }) },
- { parameters: (): object => ({ isBot: true }) },
- { parameters: (): object => ({ isBot: false }) },
- { parameters: (): object => ({ isCat: true }) },
- { parameters: (): object => ({ isCat: false }) },
- { parameters: (): object => ({ speakAsCat: true }) },
- { parameters: (): object => ({ speakAsCat: false }) },
- { parameters: (): object => ({ injectFeaturedNote: true }) },
- { parameters: (): object => ({ injectFeaturedNote: false }) },
- { parameters: (): object => ({ receiveAnnouncementEmail: true }) },
- { parameters: (): object => ({ receiveAnnouncementEmail: false }) },
- { parameters: (): object => ({ alwaysMarkNsfw: true }) },
- { parameters: (): object => ({ alwaysMarkNsfw: false }) },
- { parameters: (): object => ({ autoSensitive: true }) },
- { parameters: (): object => ({ autoSensitive: false }) },
- { parameters: (): object => ({ followingVisibility: 'private' }) },
- { parameters: (): object => ({ followingVisibility: 'followers' }) },
- { parameters: (): object => ({ followingVisibility: 'public' }) },
- { parameters: (): object => ({ followersVisibility: 'private' }) },
- { parameters: (): object => ({ followersVisibility: 'followers' }) },
- { parameters: (): object => ({ followersVisibility: 'public' }) },
- { parameters: (): object => ({ mutedWords: Array(19).fill(['xxxxx']) }) },
- { parameters: (): object => ({ mutedWords: [['x'.repeat(194)]] }) },
- { parameters: (): object => ({ mutedWords: [] }) },
- { parameters: (): object => ({ mutedInstances: ['xxxx.xxxxx'] }) },
- { parameters: (): object => ({ mutedInstances: [] }) },
- { parameters: (): object => ({ notificationRecieveConfig: { mention: { type: 'following' } } }) },
- { parameters: (): object => ({ notificationRecieveConfig: {} }) },
- { parameters: (): object => ({ emailNotificationTypes: ['mention', 'reply', 'quote', 'follow', 'receiveFollowRequest'] }) },
- { parameters: (): object => ({ emailNotificationTypes: [] }) },
+ { parameters: () => ({ name: null }) },
+ { parameters: () => ({ name: 'x'.repeat(50) }) },
+ { parameters: () => ({ name: 'x' }) },
+ { parameters: () => ({ name: 'My name' }) },
+ { parameters: () => ({ description: null }) },
+ { parameters: () => ({ description: 'x'.repeat(1500) }) },
+ { parameters: () => ({ description: 'x' }) },
+ { parameters: () => ({ description: 'My description' }) },
+ { parameters: () => ({ location: null }) },
+ { parameters: () => ({ location: 'x'.repeat(50) }) },
+ { parameters: () => ({ location: 'x' }) },
+ { parameters: () => ({ location: 'My location' }) },
+ { parameters: () => ({ birthday: '0000-00-00' }) },
+ { parameters: () => ({ birthday: '9999-99-99' }) },
+ { parameters: () => ({ lang: 'en-US' as const }) },
+ { parameters: () => ({ fields: [] }) },
+ { parameters: () => ({ fields: [{ name: 'x', value: 'x' }] }) },
+ { parameters: () => ({ fields: [{ name: 'x'.repeat(3000), value: 'x'.repeat(3000) }] }) }, // BUG? fieldには制限がない
+ { parameters: () => ({ fields: Array(16).fill({ name: 'x', value: 'y' }) }) },
+ { parameters: () => ({ isLocked: true }) },
+ { parameters: () => ({ isLocked: false }) },
+ { parameters: () => ({ isExplorable: false }) },
+ { parameters: () => ({ isExplorable: true }) },
+ { parameters: () => ({ hideOnlineStatus: true }) },
+ { parameters: () => ({ hideOnlineStatus: false }) },
+ { parameters: () => ({ publicReactions: false }) },
+ { parameters: () => ({ publicReactions: true }) },
+ { parameters: () => ({ autoAcceptFollowed: true }) },
+ { parameters: () => ({ autoAcceptFollowed: false }) },
+ { parameters: () => ({ noCrawle: true }) },
+ { parameters: () => ({ noCrawle: false }) },
+ { parameters: () => ({ preventAiLearning: false }) },
+ { parameters: () => ({ preventAiLearning: true }) },
+ { parameters: () => ({ isBot: true }) },
+ { parameters: () => ({ isBot: false }) },
+ { parameters: () => ({ isCat: true }) },
+ { parameters: () => ({ isCat: false }) },
+ { parameters: () => ({ injectFeaturedNote: true }) },
+ { parameters: () => ({ injectFeaturedNote: false }) },
+ { parameters: () => ({ receiveAnnouncementEmail: true }) },
+ { parameters: () => ({ receiveAnnouncementEmail: false }) },
+ { parameters: () => ({ alwaysMarkNsfw: true }) },
+ { parameters: () => ({ alwaysMarkNsfw: false }) },
+ { parameters: () => ({ autoSensitive: true }) },
+ { parameters: () => ({ autoSensitive: false }) },
+ { parameters: () => ({ followingVisibility: 'private' as const }) },
+ { parameters: () => ({ followingVisibility: 'followers' as const }) },
+ { parameters: () => ({ followingVisibility: 'public' as const }) },
+ { parameters: () => ({ followersVisibility: 'private' as const }) },
+ { parameters: () => ({ followersVisibility: 'followers' as const }) },
+ { parameters: () => ({ followersVisibility: 'public' as const }) },
+ { parameters: () => ({ mutedWords: Array(19).fill(['xxxxx']) }) },
+ { parameters: () => ({ mutedWords: [['x'.repeat(194)]] }) },
+ { parameters: () => ({ mutedWords: [] }) },
+ { parameters: () => ({ mutedInstances: ['xxxx.xxxxx'] }) },
+ { parameters: () => ({ mutedInstances: [] }) },
+ { parameters: () => ({ notificationRecieveConfig: { mention: { type: 'following' } } }) },
+ { parameters: () => ({ notificationRecieveConfig: {} }) },
+ { parameters: () => ({ emailNotificationTypes: ['mention', 'reply', 'quote', 'follow', 'receiveFollowRequest'] }) },
+ { parameters: () => ({ emailNotificationTypes: [] }) },
] as const)('を書き換えることができる($#)', async ({ parameters }) => {
const response = await successfulApiCall({ endpoint: 'i/update', parameters: parameters(), user: alice });
const expected = { ...meDetailed(alice, true), ...parameters() };
@@ -506,13 +479,13 @@ describe('ユーザー', () => {
test('を書き換えることができる(Avatar)', async () => {
const aliceFile = (await uploadFile(alice)).body;
- const parameters = { avatarId: aliceFile.id };
+ const parameters = { avatarId: aliceFile!.id };
const response = await successfulApiCall({ endpoint: 'i/update', parameters: parameters, user: alice });
assert.match(response.avatarUrl ?? '.', /^[-a-zA-Z0-9@:%._\+~#&?=\/]+$/);
assert.match(response.avatarBlurhash ?? '.', /[ -~]{54}/);
const expected = {
...meDetailed(alice, true),
- avatarId: aliceFile.id,
+ avatarId: aliceFile!.id,
avatarBlurhash: response.avatarBlurhash,
avatarUrl: response.avatarUrl,
};
@@ -531,13 +504,13 @@ describe('ユーザー', () => {
test('を書き換えることができる(Banner)', async () => {
const aliceFile = (await uploadFile(alice)).body;
- const parameters = { bannerId: aliceFile.id };
+ const parameters = { bannerId: aliceFile!.id };
const response = await successfulApiCall({ endpoint: 'i/update', parameters: parameters, user: alice });
assert.match(response.bannerUrl ?? '.', /^[-a-zA-Z0-9@:%._\+~#&?=\/]+$/);
assert.match(response.bannerBlurhash ?? '.', /[ -~]{54}/);
const expected = {
...meDetailed(alice, true),
- bannerId: aliceFile.id,
+ bannerId: aliceFile!.id,
bannerBlurhash: response.bannerBlurhash,
bannerUrl: response.bannerUrl,
};
@@ -612,13 +585,13 @@ describe('ユーザー', () => {
//#region ユーザー(users)
test.each([
- { label: 'ID昇順', parameters: { limit: 5 }, selector: (u: UserLite): string => u.id },
- { label: 'フォロワー昇順', parameters: { sort: '+follower' }, selector: (u: UserDetailedNotMe): string => String(u.followersCount) },
- { label: 'フォロワー降順', parameters: { sort: '-follower' }, selector: (u: UserDetailedNotMe): string => String(u.followersCount) },
- { label: '登録日時昇順', parameters: { sort: '+createdAt' }, selector: (u: UserDetailedNotMe): string => u.createdAt },
- { label: '登録日時降順', parameters: { sort: '-createdAt' }, selector: (u: UserDetailedNotMe): string => u.createdAt },
- { label: '投稿日時昇順', parameters: { sort: '+updatedAt' }, selector: (u: UserDetailedNotMe): string => String(u.updatedAt) },
- { label: '投稿日時降順', parameters: { sort: '-updatedAt' }, selector: (u: UserDetailedNotMe): string => String(u.updatedAt) },
+ { label: 'ID昇順', parameters: { limit: 5 }, selector: (u: misskey.entities.UserLite): string => u.id },
+ { label: 'フォロワー昇順', parameters: { sort: '+follower' }, selector: (u: misskey.entities.UserDetailedNotMe): string => String(u.followersCount) },
+ { label: 'フォロワー降順', parameters: { sort: '-follower' }, selector: (u: misskey.entities.UserDetailedNotMe): string => String(u.followersCount) },
+ { label: '登録日時昇順', parameters: { sort: '+createdAt' }, selector: (u: misskey.entities.UserDetailedNotMe): string => u.createdAt },
+ { label: '登録日時降順', parameters: { sort: '-createdAt' }, selector: (u: misskey.entities.UserDetailedNotMe): string => u.createdAt },
+ { label: '投稿日時昇順', parameters: { sort: '+updatedAt' }, selector: (u: misskey.entities.UserDetailedNotMe): string => String(u.updatedAt) },
+ { label: '投稿日時降順', parameters: { sort: '-updatedAt' }, selector: (u: misskey.entities.UserDetailedNotMe): string => String(u.updatedAt) },
] as const)('をリスト形式で取得することができる($label)', async ({ parameters, selector }) => {
const response = await successfulApiCall({ endpoint: 'users', parameters, user: alice });
@@ -631,15 +604,15 @@ describe('ユーザー', () => {
assert.deepStrictEqual(response, expected);
});
test.each([
- { label: '「見つけやすくする」がOFFのユーザーが含まれない', user: (): User => userNotExplorable, excluded: true },
- { label: 'ミュートユーザーが含まれない', user: (): User => userMutedByAlice, excluded: true },
- { label: 'ブロックされているユーザーが含まれない', user: (): User => userBlockedByAlice, excluded: true },
- { label: 'ブロックしてきているユーザーが含まれる', user: (): User => userBlockingAlice, excluded: true },
- { label: '承認制ユーザーが含まれる', user: (): User => userLocking },
- { label: 'サイレンスユーザーが含まれる', user: (): User => userSilenced },
- { label: 'サスペンドユーザーが含まれない', user: (): User => userSuspended, excluded: true },
- { label: '削除済ユーザーが含まれる', user: (): User => userDeletedBySelf },
- { label: '削除済(byAdmin)ユーザーが含まれる', user: (): User => userDeletedByAdmin },
+ { label: '「見つけやすくする」がOFFのユーザーが含まれない', user: () => userNotExplorable, excluded: true },
+ { label: 'ミュートユーザーが含まれない', user: () => userMutedByAlice, excluded: true },
+ { label: 'ブロックされているユーザーが含まれない', user: () => userBlockedByAlice, excluded: true },
+ { label: 'ブロックしてきているユーザーが含まれる', user: () => userBlockingAlice, excluded: true },
+ { label: '承認制ユーザーが含まれる', user: () => userLocking },
+ { label: 'サイレンスユーザーが含まれる', user: () => userSilenced },
+ { label: 'サスペンドユーザーが含まれない', user: () => userSuspended, excluded: true },
+ { label: '削除済ユーザーが含まれる', user: () => userDeletedBySelf },
+ { label: '削除済(byAdmin)ユーザーが含まれる', user: () => userDeletedByAdmin },
] as const)('をリスト形式で取得することができ、結果に$label', async ({ user, excluded }) => {
const parameters = { limit: 100 };
const response = await successfulApiCall({ endpoint: 'users', parameters, user: alice });
@@ -653,39 +626,44 @@ describe('ユーザー', () => {
//#region ユーザー情報(users/show)
test.each([
- { label: 'ID指定で自分自身を', parameters: (): object => ({ userId: alice.id }), user: (): User => alice, type: meDetailed },
- { label: 'ID指定で他人を', parameters: (): object => ({ userId: alice.id }), user: (): User => bob, type: userDetailedNotMeWithRelations },
- { label: 'ID指定かつ未認証', parameters: (): object => ({ userId: alice.id }), user: undefined, type: userDetailedNotMe },
- { label: '@指定で自分自身を', parameters: (): object => ({ username: alice.username }), user: (): User => alice, type: meDetailed },
- { label: '@指定で他人を', parameters: (): object => ({ username: alice.username }), user: (): User => bob, type: userDetailedNotMeWithRelations },
- { label: '@指定かつ未認証', parameters: (): object => ({ username: alice.username }), user: undefined, type: userDetailedNotMe },
+ { label: 'ID指定で自分自身を', parameters: () => ({ userId: alice.id }), user: () => alice, type: meDetailed },
+ { label: 'ID指定で他人を', parameters: () => ({ userId: alice.id }), user: () => bob, type: userDetailedNotMeWithRelations },
+ { label: 'ID指定かつ未認証', parameters: () => ({ userId: alice.id }), user: undefined, type: userDetailedNotMe },
+ { label: '@指定で自分自身を', parameters: () => ({ username: alice.username }), user: () => alice, type: meDetailed },
+ { label: '@指定で他人を', parameters: () => ({ username: alice.username }), user: () => bob, type: userDetailedNotMeWithRelations },
+ { label: '@指定かつ未認証', parameters: () => ({ username: alice.username }), user: undefined, type: userDetailedNotMe },
] as const)('を取得することができる($label)', async ({ parameters, user, type }) => {
const response = await successfulApiCall({ endpoint: 'users/show', parameters: parameters(), user: user?.() });
const expected = type(alice);
assert.deepStrictEqual(response, expected);
});
test.each([
- { label: 'Administratorになっている', user: (): User => userAdmin, me: (): User => userAdmin, selector: (user: User): unknown => user.isAdmin },
- { label: '自分以外から見たときはAdministratorか判定できない', user: (): User => userAdmin, selector: (user: User): unknown => user.isAdmin, expected: (): undefined => undefined },
- { label: 'Moderatorになっている', user: (): User => userModerator, me: (): User => userModerator, selector: (user: User): unknown => user.isModerator },
- { label: '自分以外から見たときはModeratorか判定できない', user: (): User => userModerator, selector: (user: User): unknown => user.isModerator, expected: (): undefined => undefined },
- { label: 'サイレンスになっている', user: (): User => userSilenced, selector: (user: User): unknown => user.isSilenced },
- //{ label: 'サスペンドになっている', user: (): User => userSuspended, selector: (user: User): unknown => user.isSuspended },
- { label: '削除済みになっている', user: (): User => userDeletedBySelf, me: (): User => userDeletedBySelf, selector: (user: User): unknown => user.isDeleted },
- { label: '自分以外から見たときは削除済みか判定できない', user: (): User => userDeletedBySelf, selector: (user: User): unknown => user.isDeleted, expected: (): undefined => undefined },
- { label: '削除済み(byAdmin)になっている', user: (): User => userDeletedByAdmin, me: (): User => userDeletedByAdmin, selector: (user: User): unknown => user.isDeleted },
- { label: '自分以外から見たときは削除済み(byAdmin)か判定できない', user: (): User => userDeletedByAdmin, selector: (user: User): unknown => user.isDeleted, expected: (): undefined => undefined },
- { label: 'フォロー中になっている', user: (): User => userFollowedByAlice, selector: (user: User): unknown => user.isFollowing },
- { label: 'フォローされている', user: (): User => userFollowingAlice, selector: (user: User): unknown => user.isFollowed },
- { label: 'ブロック中になっている', user: (): User => userBlockedByAlice, selector: (user: User): unknown => user.isBlocking },
- { label: 'ブロックされている', user: (): User => userBlockingAlice, selector: (user: User): unknown => user.isBlocked },
- { label: 'ミュート中になっている', user: (): User => userMutedByAlice, selector: (user: User): unknown => user.isMuted },
- { label: 'リノートミュート中になっている', user: (): User => userRnMutedByAlice, selector: (user: User): unknown => user.isRenoteMuted },
- { label: 'フォローリクエスト中になっている', user: (): User => userFollowRequested, me: (): User => userFollowRequesting, selector: (user: User): unknown => user.hasPendingFollowRequestFromYou },
- { label: 'フォローリクエストされている', user: (): User => userFollowRequesting, me: (): User => userFollowRequested, selector: (user: User): unknown => user.hasPendingFollowRequestToYou },
+ { label: 'Administratorになっている', user: () => userAdmin, me: () => userAdmin, selector: (user: misskey.entities.MeDetailed) => user.isAdmin },
+ // @ts-expect-error UserDetailedNotMe doesn't include isAdmin
+ { label: '自分以外から見たときはAdministratorか判定できない', user: () => userAdmin, selector: (user: misskey.entities.UserDetailedNotMe) => user.isAdmin, expected: () => undefined },
+ { label: 'Moderatorになっている', user: () => userModerator, me: () => userModerator, selector: (user: misskey.entities.MeDetailed) => user.isModerator },
+ // @ts-expect-error UserDetailedNotMe doesn't include isModerator
+ { label: '自分以外から見たときはModeratorか判定できない', user: () => userModerator, selector: (user: misskey.entities.UserDetailedNotMe) => user.isModerator, expected: () => undefined },
+ { label: 'サイレンスになっている', user: () => userSilenced, selector: (user: misskey.entities.UserDetailed) => user.isSilenced },
+ // FIXME: 落ちる
+ //{ label: 'サスペンドになっている', user: () => userSuspended, selector: (user: misskey.entities.UserDetailed) => user.isSuspended },
+ { label: '削除済みになっている', user: () => userDeletedBySelf, me: () => userDeletedBySelf, selector: (user: misskey.entities.MeDetailed) => user.isDeleted },
+ // @ts-expect-error UserDetailedNotMe doesn't include isDeleted
+ { label: '自分以外から見たときは削除済みか判定できない', user: () => userDeletedBySelf, selector: (user: misskey.entities.UserDetailedNotMe) => user.isDeleted, expected: () => undefined },
+ { label: '削除済み(byAdmin)になっている', user: () => userDeletedByAdmin, me: () => userDeletedByAdmin, selector: (user: misskey.entities.MeDetailed) => user.isDeleted },
+ // @ts-expect-error UserDetailedNotMe doesn't include isDeleted
+ { label: '自分以外から見たときは削除済み(byAdmin)か判定できない', user: () => userDeletedByAdmin, selector: (user: misskey.entities.UserDetailedNotMe) => user.isDeleted, expected: () => undefined },
+ { label: 'フォロー中になっている', user: () => userFollowedByAlice, selector: (user: misskey.entities.UserDetailed) => user.isFollowing },
+ { label: 'フォローされている', user: () => userFollowingAlice, selector: (user: misskey.entities.UserDetailed) => user.isFollowed },
+ { label: 'ブロック中になっている', user: () => userBlockedByAlice, selector: (user: misskey.entities.UserDetailed) => user.isBlocking },
+ { label: 'ブロックされている', user: () => userBlockingAlice, selector: (user: misskey.entities.UserDetailed) => user.isBlocked },
+ { label: 'ミュート中になっている', user: () => userMutedByAlice, selector: (user: misskey.entities.UserDetailed) => user.isMuted },
+ { label: 'リノートミュート中になっている', user: () => userRnMutedByAlice, selector: (user: misskey.entities.UserDetailed) => user.isRenoteMuted },
+ { label: 'フォローリクエスト中になっている', user: () => userFollowRequested, me: () => userFollowRequesting, selector: (user: misskey.entities.UserDetailed) => user.hasPendingFollowRequestFromYou },
+ { label: 'フォローリクエストされている', user: () => userFollowRequesting, me: () => userFollowRequested, selector: (user: misskey.entities.UserDetailed) => user.hasPendingFollowRequestToYou },
] as const)('を取得することができ、$labelこと', async ({ user, me, selector, expected }) => {
const response = await successfulApiCall({ endpoint: 'users/show', parameters: { userId: user().id }, user: me?.() ?? alice });
- assert.strictEqual(selector(response), (expected ?? ((): true => true))());
+ assert.strictEqual(selector(response as any), (expected ?? ((): true => true))());
});
test('を取得することができ、Publicなロールがセットされていること', async () => {
const response = await successfulApiCall({ endpoint: 'users/show', parameters: { userId: userRolePublic.id }, user: alice });
@@ -727,17 +705,18 @@ describe('ユーザー', () => {
assert.deepStrictEqual(response, expected);
});
test.each([
- { label: '「見つけやすくする」がOFFのユーザーが含まれる', user: (): User => userNotExplorable },
- { label: 'ミュートユーザーが含まれる', user: (): User => userMutedByAlice },
- { label: 'ブロックされているユーザーが含まれる', user: (): User => userBlockedByAlice },
- { label: 'ブロックしてきているユーザーが含まれる', user: (): User => userBlockingAlice },
- { label: '承認制ユーザーが含まれる', user: (): User => userLocking },
- { label: 'サイレンスユーザーが含まれる', user: (): User => userSilenced },
- { label: 'サスペンドユーザーが(モデレーターが見るときは)含まれる', user: (): User => userSuspended, me: (): User => root },
+ { label: '「見つけやすくする」がOFFのユーザーが含まれる', user: () => userNotExplorable },
+ { label: 'ミュートユーザーが含まれる', user: () => userMutedByAlice },
+ { label: 'ブロックされているユーザーが含まれる', user: () => userBlockedByAlice },
+ { label: 'ブロックしてきているユーザーが含まれる', user: () => userBlockingAlice },
+ { label: '承認制ユーザーが含まれる', user: () => userLocking },
+ { label: 'サイレンスユーザーが含まれる', user: () => userSilenced },
+ { label: 'サスペンドユーザーが(モデレーターが見るときは)含まれる', user: () => userSuspended, me: () => root },
// BUG サスペンドユーザーを一般ユーザーから見るとrootユーザーが返ってくる
- //{ label: 'サスペンドユーザーが(一般ユーザーが見るときは)含まれない', user: (): User => userSuspended, me: (): User => bob, excluded: true },
- { label: '削除済ユーザーが含まれる', user: (): User => userDeletedBySelf },
- { label: '削除済(byAdmin)ユーザーが含まれる', user: (): User => userDeletedByAdmin },
+ //{ label: 'サスペンドユーザーが(一般ユーザーが見るときは)含まれない', user: () => userSuspended, me: () => bob, excluded: true },
+ { label: '削除済ユーザーが含まれる', user: () => userDeletedBySelf },
+ { label: '削除済(byAdmin)ユーザーが含まれる', user: () => userDeletedByAdmin },
+ // @ts-expect-error excluded は上でコメントアウトされているので
] as const)('をID指定のリスト形式で取得することができ、結果に$label', async ({ user, me, excluded }) => {
const parameters = { userIds: [user().id] };
const response = await successfulApiCall({ endpoint: 'users/show', parameters, user: me?.() ?? alice });
@@ -762,15 +741,15 @@ describe('ユーザー', () => {
assert.deepStrictEqual(response, expected);
});
test.each([
- { label: '「見つけやすくする」がOFFのユーザーが含まれる', user: (): User => userNotExplorable },
- { label: 'ミュートユーザーが含まれる', user: (): User => userMutedByAlice },
- { label: 'ブロックされているユーザーが含まれる', user: (): User => userBlockedByAlice },
- { label: 'ブロックしてきているユーザーが含まれる', user: (): User => userBlockingAlice },
- { label: '承認制ユーザーが含まれる', user: (): User => userLocking },
- { label: 'サイレンスユーザーが含まれる', user: (): User => userSilenced },
- { label: 'サスペンドユーザーが含まれない', user: (): User => userSuspended, excluded: true },
- { label: '削除済ユーザーが含まれる', user: (): User => userDeletedBySelf },
- { label: '削除済(byAdmin)ユーザーが含まれる', user: (): User => userDeletedByAdmin },
+ { label: '「見つけやすくする」がOFFのユーザーが含まれる', user: () => userNotExplorable },
+ { label: 'ミュートユーザーが含まれる', user: () => userMutedByAlice },
+ { label: 'ブロックされているユーザーが含まれる', user: () => userBlockedByAlice },
+ { label: 'ブロックしてきているユーザーが含まれる', user: () => userBlockingAlice },
+ { label: '承認制ユーザーが含まれる', user: () => userLocking },
+ { label: 'サイレンスユーザーが含まれる', user: () => userSilenced },
+ { label: 'サスペンドユーザーが含まれない', user: () => userSuspended, excluded: true },
+ { label: '削除済ユーザーが含まれる', user: () => userDeletedBySelf },
+ { label: '削除済(byAdmin)ユーザーが含まれる', user: () => userDeletedByAdmin },
] as const)('を検索することができ、結果に$labelが含まれる', async ({ user, excluded }) => {
const parameters = { query: user().username, limit: 1 };
const response = await successfulApiCall({ endpoint: 'users/search', parameters, user: alice });
@@ -784,30 +763,30 @@ describe('ユーザー', () => {
//#region ID指定検索(users/search-by-username-and-host)
test.each([
- { label: '自分', parameters: { username: 'alice' }, user: (): User[] => [alice] },
- { label: '自分かつusernameが大文字', parameters: { username: 'ALICE' }, user: (): User[] => [alice] },
- { label: 'ローカルのフォロイーでノートなし', parameters: { username: 'userFollowedByAlice' }, user: (): User[] => [userFollowedByAlice] },
- { label: 'ローカルでノートなしは検索に載らない', parameters: { username: 'userNoNote' }, user: (): User[] => [] },
- { label: 'ローカルの他人1', parameters: { username: 'bob' }, user: (): User[] => [bob] },
- { label: 'ローカルの他人2', parameters: { username: 'bob', host: null }, user: (): User[] => [bob] },
- { label: 'ローカルの他人3', parameters: { username: 'bob', host: '.' }, user: (): User[] => [bob] },
- { label: 'ローカル', parameters: { host: null, limit: 1 }, user: (): User[] => [userFollowedByAlice] },
- { label: 'ローカル', parameters: { host: '.', limit: 1 }, user: (): User[] => [userFollowedByAlice] },
+ { label: '自分', parameters: { username: 'alice' }, user: () => [alice] },
+ { label: '自分かつusernameが大文字', parameters: { username: 'ALICE' }, user: () => [alice] },
+ { label: 'ローカルのフォロイーでノートなし', parameters: { username: 'userFollowedByAlice' }, user: () => [userFollowedByAlice] },
+ { label: 'ローカルでノートなしは検索に載らない', parameters: { username: 'userNoNote' }, user: () => [] },
+ { label: 'ローカルの他人1', parameters: { username: 'bob' }, user: () => [bob] },
+ { label: 'ローカルの他人2', parameters: { username: 'bob', host: null }, user: () => [bob] },
+ { label: 'ローカルの他人3', parameters: { username: 'bob', host: '.' }, user: () => [bob] },
+ { label: 'ローカル', parameters: { host: null, limit: 1 }, user: () => [userFollowedByAlice] },
+ { label: 'ローカル', parameters: { host: '.', limit: 1 }, user: () => [userFollowedByAlice] },
])('をID&ホスト指定で検索できる($label)', async ({ parameters, user }) => {
const response = await successfulApiCall({ endpoint: 'users/search-by-username-and-host', parameters, user: alice });
const expected = await Promise.all(user().map(u => show(u.id, alice)));
assert.deepStrictEqual(response, expected);
});
test.each([
- { label: '「見つけやすくする」がOFFのユーザーが含まれる', user: (): User => userNotExplorable },
- { label: 'ミュートユーザーが含まれる', user: (): User => userMutedByAlice },
- { label: 'ブロックされているユーザーが含まれる', user: (): User => userBlockedByAlice },
- { label: 'ブロックしてきているユーザーが含まれる', user: (): User => userBlockingAlice },
- { label: '承認制ユーザーが含まれる', user: (): User => userLocking },
- { label: 'サイレンスユーザーが含まれる', user: (): User => userSilenced },
- { label: 'サスペンドユーザーが含まれない', user: (): User => userSuspended, excluded: true },
- { label: '削除済ユーザーが含まれる', user: (): User => userDeletedBySelf },
- { label: '削除済(byAdmin)ユーザーが含まれる', user: (): User => userDeletedByAdmin },
+ { label: '「見つけやすくする」がOFFのユーザーが含まれる', user: () => userNotExplorable },
+ { label: 'ミュートユーザーが含まれる', user: () => userMutedByAlice },
+ { label: 'ブロックされているユーザーが含まれる', user: () => userBlockedByAlice },
+ { label: 'ブロックしてきているユーザーが含まれる', user: () => userBlockingAlice },
+ { label: '承認制ユーザーが含まれる', user: () => userLocking },
+ { label: 'サイレンスユーザーが含まれる', user: () => userSilenced },
+ { label: 'サスペンドユーザーが含まれない', user: () => userSuspended, excluded: true },
+ { label: '削除済ユーザーが含まれる', user: () => userDeletedBySelf },
+ { label: '削除済(byAdmin)ユーザーが含まれる', user: () => userDeletedByAdmin },
] as const)('をID&ホスト指定で検索でき、結果に$label', async ({ user, excluded }) => {
const parameters = { username: user().username };
const response = await successfulApiCall({ endpoint: 'users/search-by-username-and-host', parameters, user: alice });
@@ -829,15 +808,15 @@ describe('ユーザー', () => {
assert.deepStrictEqual(response, expected);
});
test.each([
- { label: '「見つけやすくする」がOFFのユーザーが含まれる', user: (): User => userNotExplorable },
- { label: 'ミュートユーザーが含まれる', user: (): User => userMutedByAlice },
- { label: 'ブロックされているユーザーが含まれる', user: (): User => userBlockedByAlice },
- { label: 'ブロックしてきているユーザーが含まれない', user: (): User => userBlockingAlice, excluded: true },
- { label: '承認制ユーザーが含まれる', user: (): User => userLocking },
- { label: 'サイレンスユーザーが含まれる', user: (): User => userSilenced },
- //{ label: 'サスペンドユーザーが含まれない', user: (): User => userSuspended, excluded: true },
- { label: '削除済ユーザーが含まれる', user: (): User => userDeletedBySelf },
- { label: '削除済(byAdmin)ユーザーが含まれる', user: (): User => userDeletedByAdmin },
+ { label: '「見つけやすくする」がOFFのユーザーが含まれる', user: () => userNotExplorable },
+ { label: 'ミュートユーザーが含まれる', user: () => userMutedByAlice },
+ { label: 'ブロックされているユーザーが含まれる', user: () => userBlockedByAlice },
+ { label: 'ブロックしてきているユーザーが含まれない', user: () => userBlockingAlice, excluded: true },
+ { label: '承認制ユーザーが含まれる', user: () => userLocking },
+ { label: 'サイレンスユーザーが含まれる', user: () => userSilenced },
+ //{ label: 'サスペンドユーザーが含まれない', user: () => userSuspended, excluded: true },
+ { label: '削除済ユーザーが含まれる', user: () => userDeletedBySelf },
+ { label: '削除済(byAdmin)ユーザーが含まれる', user: () => userDeletedByAdmin },
] as const)('がよくリプライをするユーザーのリストを取得でき、結果に$label', async ({ user, excluded }) => {
const replyTo = (await successfulApiCall({ endpoint: 'users/notes', parameters: { userId: user().id }, user: undefined }))[0];
await post(alice, { text: `@${user().username} test`, replyId: replyTo.id });
@@ -851,12 +830,12 @@ describe('ユーザー', () => {
//#region ハッシュタグ(hashtags/users)
test.each([
- { label: 'フォロワー昇順', sort: { sort: '+follower' }, selector: (u: UserDetailedNotMe): string => String(u.followersCount) },
- { label: 'フォロワー降順', sort: { sort: '-follower' }, selector: (u: UserDetailedNotMe): string => String(u.followersCount) },
- { label: '登録日時昇順', sort: { sort: '+createdAt' }, selector: (u: UserDetailedNotMe): string => u.createdAt },
- { label: '登録日時降順', sort: { sort: '-createdAt' }, selector: (u: UserDetailedNotMe): string => u.createdAt },
- { label: '投稿日時昇順', sort: { sort: '+updatedAt' }, selector: (u: UserDetailedNotMe): string => String(u.updatedAt) },
- { label: '投稿日時降順', sort: { sort: '-updatedAt' }, selector: (u: UserDetailedNotMe): string => String(u.updatedAt) },
+ { label: 'フォロワー昇順', sort: { sort: '+follower' }, selector: (u: misskey.entities.UserDetailedNotMe): string => String(u.followersCount) },
+ { label: 'フォロワー降順', sort: { sort: '-follower' }, selector: (u: misskey.entities.UserDetailedNotMe): string => String(u.followersCount) },
+ { label: '登録日時昇順', sort: { sort: '+createdAt' }, selector: (u: misskey.entities.UserDetailedNotMe): string => u.createdAt },
+ { label: '登録日時降順', sort: { sort: '-createdAt' }, selector: (u: misskey.entities.UserDetailedNotMe): string => u.createdAt },
+ { label: '投稿日時昇順', sort: { sort: '+updatedAt' }, selector: (u: misskey.entities.UserDetailedNotMe): string => String(u.updatedAt) },
+ { label: '投稿日時降順', sort: { sort: '-updatedAt' }, selector: (u: misskey.entities.UserDetailedNotMe): string => String(u.updatedAt) },
] as const)('をハッシュタグ指定で取得することができる($label)', async ({ sort, selector }) => {
const hashtag = 'test_hashtag';
await successfulApiCall({ endpoint: 'i/update', parameters: { description: `#${hashtag}` }, user: alice });
@@ -870,15 +849,15 @@ describe('ユーザー', () => {
assert.deepStrictEqual(response, expected);
});
test.each([
- { label: '「見つけやすくする」がOFFのユーザーが含まれる', user: (): User => userNotExplorable },
- { label: 'ミュートユーザーが含まれる', user: (): User => userMutedByAlice },
- { label: 'ブロックされているユーザーが含まれる', user: (): User => userBlockedByAlice },
- { label: 'ブロックしてきているユーザーが含まれる', user: (): User => userBlockingAlice },
- { label: '承認制ユーザーが含まれる', user: (): User => userLocking },
- { label: 'サイレンスユーザーが含まれる', user: (): User => userSilenced },
- { label: 'サスペンドユーザーが含まれない', user: (): User => userSuspended, excluded: true },
- { label: '削除済ユーザーが含まれる', user: (): User => userDeletedBySelf },
- { label: '削除済(byAdmin)ユーザーが含まれる', user: (): User => userDeletedByAdmin },
+ { label: '「見つけやすくする」がOFFのユーザーが含まれる', user: () => userNotExplorable },
+ { label: 'ミュートユーザーが含まれる', user: () => userMutedByAlice },
+ { label: 'ブロックされているユーザーが含まれる', user: () => userBlockedByAlice },
+ { label: 'ブロックしてきているユーザーが含まれる', user: () => userBlockingAlice },
+ { label: '承認制ユーザーが含まれる', user: () => userLocking },
+ { label: 'サイレンスユーザーが含まれる', user: () => userSilenced },
+ { label: 'サスペンドユーザーが含まれない', user: () => userSuspended, excluded: true },
+ { label: '削除済ユーザーが含まれる', user: () => userDeletedBySelf },
+ { label: '削除済(byAdmin)ユーザーが含まれる', user: () => userDeletedByAdmin },
] as const)('をハッシュタグ指定で取得することができ、結果に$label', async ({ user, excluded }) => {
const hashtag = `user_test${user().username}`;
if (user() !== userSuspended) {
diff --git a/packages/backend/test/global.d.ts b/packages/backend/test/global.d.ts
new file mode 100644
index 0000000000..0363073356
--- /dev/null
+++ b/packages/backend/test/global.d.ts
@@ -0,0 +1,7 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+type FIXME = any;
diff --git a/packages/backend/test/prelude/get-api-validator.ts b/packages/backend/test/prelude/get-api-validator.ts
index b86a7a978d..7aa7a92702 100644
--- a/packages/backend/test/prelude/get-api-validator.ts
+++ b/packages/backend/test/prelude/get-api-validator.ts
@@ -4,10 +4,10 @@
*/
import Ajv from 'ajv';
-import { Schema } from '@/misc/schema';
+import { Schema } from '@/misc/json-schema.js';
export const getValidator = (paramDef: Schema) => {
- const ajv = new Ajv({
+ const ajv = new Ajv.default({
useDefaults: true,
});
ajv.addFormat('misskey:id', /^[a-zA-Z0-9]+$/);
diff --git a/packages/backend/test/tsconfig.json b/packages/backend/test/tsconfig.json
index 4597ff8780..2b562acda8 100644
--- a/packages/backend/test/tsconfig.json
+++ b/packages/backend/test/tsconfig.json
@@ -5,7 +5,7 @@
"noImplicitAny": true,
"noImplicitReturns": true,
"noUnusedParameters": false,
- "noUnusedLocals": true,
+ "noUnusedLocals": false,
"noFallthroughCasesInSwitch": true,
"declaration": false,
"sourceMap": true,
@@ -18,6 +18,7 @@
"strict": true,
"strictNullChecks": true,
"strictPropertyInitialization": false,
+ "skipLibCheck": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"resolveJsonModule": true,
diff --git a/packages/backend/test/unit/AnnouncementService.ts b/packages/backend/test/unit/AnnouncementService.ts
index fc35837420..aa082ff2f2 100644
--- a/packages/backend/test/unit/AnnouncementService.ts
+++ b/packages/backend/test/unit/AnnouncementService.ts
@@ -51,7 +51,7 @@ describe('AnnouncementService', () => {
function createAnnouncement(data: Partial<MiAnnouncement & { createdAt: Date }> = {}) {
return announcementsRepository.insert({
- id: genAidx(data.createdAt ?? new Date()),
+ id: genAidx(data.createdAt?.getTime() ?? Date.now()),
updatedAt: null,
title: 'Title',
text: 'Text',
diff --git a/packages/backend/test/unit/FetchInstanceMetadataService.ts b/packages/backend/test/unit/FetchInstanceMetadataService.ts
index e6e68ccd6d..bf8f3ab0e3 100644
--- a/packages/backend/test/unit/FetchInstanceMetadataService.ts
+++ b/packages/backend/test/unit/FetchInstanceMetadataService.ts
@@ -19,8 +19,8 @@ import { DI } from '@/di-symbols.js';
import type { TestingModule } from '@nestjs/testing';
function mockRedis() {
- const hash = {};
- const set = jest.fn((key, value) => {
+ const hash = {} as any;
+ const set = jest.fn((key: string, value) => {
const ret = hash[key];
hash[key] = value;
return ret;
@@ -56,12 +56,13 @@ describe('FetchInstanceMetadataService', () => {
} else if (token === DI.redis) {
return mockRedis;
}
+ return null;
})
.compile();
app.enableShutdownHooks();
- fetchInstanceMetadataService = app.get<FetchInstanceMetadataService>(FetchInstanceMetadataService);
+ fetchInstanceMetadataService = app.get<FetchInstanceMetadataService>(FetchInstanceMetadataService) as jest.Mocked<FetchInstanceMetadataService>;
federatedInstanceService = app.get<FederatedInstanceService>(FederatedInstanceService) as jest.Mocked<FederatedInstanceService>;
redisClient = app.get<Redis>(DI.redis) as jest.Mocked<Redis>;
httpRequestService = app.get<HttpRequestService>(HttpRequestService) as jest.Mocked<HttpRequestService>;
@@ -74,11 +75,12 @@ describe('FetchInstanceMetadataService', () => {
test('Lock and update', async () => {
redisClient.set = mockRedis();
const now = Date.now();
- federatedInstanceService.fetch.mockReturnValue({ infoUpdatedAt: { getTime: () => { return now - 10 * 1000 * 60 * 60 * 24; } } });
+ federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => { return now - 10 * 1000 * 60 * 60 * 24; } } } as any);
httpRequestService.getJson.mockImplementation(() => { throw Error(); });
const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock');
const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock');
- await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' });
+
+ await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any);
expect(tryLockSpy).toHaveBeenCalledTimes(1);
expect(unlockSpy).toHaveBeenCalledTimes(1);
expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1);
@@ -88,11 +90,12 @@ describe('FetchInstanceMetadataService', () => {
test('Lock and don\'t update', async () => {
redisClient.set = mockRedis();
const now = Date.now();
- federatedInstanceService.fetch.mockReturnValue({ infoUpdatedAt: { getTime: () => now } });
+ federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => now } } as any);
httpRequestService.getJson.mockImplementation(() => { throw Error(); });
const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock');
const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock');
- await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' });
+
+ await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any);
expect(tryLockSpy).toHaveBeenCalledTimes(1);
expect(unlockSpy).toHaveBeenCalledTimes(1);
expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1);
@@ -101,15 +104,33 @@ describe('FetchInstanceMetadataService', () => {
test('Do nothing when lock not acquired', async () => {
redisClient.set = mockRedis();
- federatedInstanceService.fetch.mockReturnValue({ infoUpdatedAt: { getTime: () => now - 10 * 1000 * 60 * 60 * 24 } });
+ const now = Date.now();
+ federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => now - 10 * 1000 * 60 * 60 * 24 } } as any);
httpRequestService.getJson.mockImplementation(() => { throw Error(); });
+ await fetchInstanceMetadataService.tryLock('example.com');
const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock');
const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock');
- await fetchInstanceMetadataService.tryLock('example.com');
- await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' });
- expect(tryLockSpy).toHaveBeenCalledTimes(2);
+
+ await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any);
+ expect(tryLockSpy).toHaveBeenCalledTimes(1);
expect(unlockSpy).toHaveBeenCalledTimes(0);
expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(0);
expect(httpRequestService.getJson).toHaveBeenCalledTimes(0);
});
+
+ test('Do when lock not acquired but forced', async () => {
+ redisClient.set = mockRedis();
+ const now = Date.now();
+ federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => now - 10 * 1000 * 60 * 60 * 24 } } as any);
+ httpRequestService.getJson.mockImplementation(() => { throw Error(); });
+ await fetchInstanceMetadataService.tryLock('example.com');
+ const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock');
+ const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock');
+
+ await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any, true);
+ expect(tryLockSpy).toHaveBeenCalledTimes(0);
+ expect(unlockSpy).toHaveBeenCalledTimes(1);
+ expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(0);
+ expect(httpRequestService.getJson).toHaveBeenCalled();
+ });
});
diff --git a/packages/backend/test/unit/RelayService.ts b/packages/backend/test/unit/RelayService.ts
index f2a67dba46..9676abf07b 100644
--- a/packages/backend/test/unit/RelayService.ts
+++ b/packages/backend/test/unit/RelayService.ts
@@ -90,7 +90,8 @@ describe('RelayService', () => {
expect(queueService.deliver).toHaveBeenCalled();
expect(queueService.deliver.mock.lastCall![1]?.type).toBe('Undo');
- expect(queueService.deliver.mock.lastCall![1]?.object.type).toBe('Follow');
+ expect(typeof queueService.deliver.mock.lastCall![1]?.object).toBe('object');
+ expect((queueService.deliver.mock.lastCall![1]?.object as any).type).toBe('Follow');
expect(queueService.deliver.mock.lastCall![2]).toBe('https://example.com');
//expect(queueService.deliver.mock.lastCall![0].username).toBe('relay.actor');
diff --git a/packages/backend/test/unit/RoleService.ts b/packages/backend/test/unit/RoleService.ts
index fe5ad31597..19d03570e0 100644
--- a/packages/backend/test/unit/RoleService.ts
+++ b/packages/backend/test/unit/RoleService.ts
@@ -228,11 +228,14 @@ describe('RoleService', () => {
},
target: 'conditional',
condFormula: {
+ id: '232a4221-9816-49a6-a967-ae0fac52ec5e',
type: 'and',
values: [{
+ id: '2a37ef43-2d93-4c4d-87f6-f2fdb7d9b530',
type: 'followersMoreThanOrEq',
value: 10,
}, {
+ id: '1bd67839-b126-4f92-bad0-4e285dab453b',
type: 'createdMoreThan',
sec: 60 * 60 * 24 * 7,
}],
diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts
index cd5dddd68d..86814fffe0 100644
--- a/packages/backend/test/utils.ts
+++ b/packages/backend/test/utils.ts
@@ -9,11 +9,10 @@ import { basename, isAbsolute } from 'node:path';
import { randomUUID } from 'node:crypto';
import { inspect } from 'node:util';
import WebSocket, { ClientOptions } from 'ws';
-import fetch, { File, RequestInit } from 'node-fetch';
+import fetch, { File, RequestInit, type Headers } from 'node-fetch';
import { DataSource } from 'typeorm';
import { JSDOM } from 'jsdom';
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
-import { Packed } from '@/misc/json-schema.js';
import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/validator.js';
import { entities } from '../src/postgres.js';
import { loadConfig } from '../src/config.js';
@@ -21,7 +20,7 @@ import type * as misskey from 'misskey-js';
export { server as startServer, jobQueue as startJobQueue } from '@/boot/common.js';
-interface UserToken {
+export interface UserToken {
token: string;
bearer?: boolean;
}
@@ -35,20 +34,15 @@ export const cookie = (me: UserToken): string => {
return `token=${me.token};`;
};
-export const api = async (endpoint: string, params: any, me?: UserToken) => {
- const normalized = endpoint.replace(/^\//, '');
- return await request(`api/${normalized}`, params, me);
-};
-
-export type ApiRequest = {
- endpoint: string,
- parameters: object,
+export type ApiRequest<E extends keyof misskey.Endpoints, P extends misskey.Endpoints[E]['req'] = misskey.Endpoints[E]['req']> = {
+ endpoint: E,
+ parameters: P,
user: UserToken | undefined,
};
-export const successfulApiCall = async <T, >(request: ApiRequest, assertion: {
+export const successfulApiCall = async <E extends keyof misskey.Endpoints, P extends misskey.Endpoints[E]['req']>(request: ApiRequest<E, P>, assertion: {
status?: number,
-} = {}): Promise<T> => {
+} = {}): Promise<misskey.api.SwitchCaseResponseType<E, P>> => {
const { endpoint, parameters, user } = request;
const res = await api(endpoint, parameters, user);
const status = assertion.status ?? (res.body == null ? 204 : 200);
@@ -56,7 +50,7 @@ export const successfulApiCall = async <T, >(request: ApiRequest, assertion: {
return res.body;
};
-export const failedApiCall = async <T, >(request: ApiRequest, assertion: {
+export const failedApiCall = async <T, E extends keyof misskey.Endpoints, P extends misskey.Endpoints[E]['req']>(request: ApiRequest<E, P>, assertion: {
status: number,
code: string,
id: string
@@ -70,7 +64,7 @@ export const failedApiCall = async <T, >(request: ApiRequest, assertion: {
return res.body;
};
-const request = async (path: string, params: any, me?: UserToken): Promise<{
+export const api = async <E extends keyof misskey.Endpoints>(path: E, params: misskey.Endpoints[E]['req'], me?: UserToken): Promise<{
status: number,
headers: Headers,
body: any
@@ -86,7 +80,7 @@ const request = async (path: string, params: any, me?: UserToken): Promise<{
bodyAuth.i = me.token;
}
- const res = await relativeFetch(path, {
+ const res = await relativeFetch(`api/${path}`, {
method: 'POST',
headers,
body: JSON.stringify(Object.assign(bodyAuth, params)),
@@ -141,7 +135,7 @@ export const signup = async (params?: Partial<misskey.Endpoints['signup']['req']
return res.body;
};
-export const post = async (user: UserToken, params?: misskey.Endpoints['notes/create']['req']): Promise<misskey.entities.Note> => {
+export const post = async (user: UserToken, params: misskey.Endpoints['notes/create']['req']): Promise<misskey.entities.Note> => {
const q = params;
const res = await api('notes/create', q, user);
@@ -159,8 +153,8 @@ export const createAppToken = async (user: UserToken, permissions: (typeof missk
};
// 非公開ノートをAPI越しに見たときのノート NoteEntityService.ts
-export const hiddenNote = (note: any): any => {
- const temp = {
+export const hiddenNote = (note: misskey.entities.Note): misskey.entities.Note => {
+ const temp: misskey.entities.Note = {
...note,
fileIds: [],
files: [],
@@ -173,21 +167,22 @@ export const hiddenNote = (note: any): any => {
return temp;
};
-export const react = async (user: UserToken, note: any, reaction: string): Promise<any> => {
+export const react = async (user: UserToken, note: misskey.entities.Note, reaction: string): Promise<void> => {
await api('notes/reactions/create', {
noteId: note.id,
reaction: reaction,
}, user);
};
-export const userList = async (user: UserToken, userList: any = {}): Promise<any> => {
+export const userList = async (user: UserToken, userList: Partial<misskey.entities.UserList> = {}): Promise<misskey.entities.UserList> => {
const res = await api('users/lists/create', {
name: 'test',
+ ...userList,
}, user);
return res.body;
};
-export const page = async (user: UserToken, page: any = {}): Promise<any> => {
+export const page = async (user: UserToken, page: Partial<misskey.entities.Page> = {}): Promise<misskey.entities.Page> => {
const res = await api('pages/create', {
alignCenter: false,
content: [
@@ -198,7 +193,7 @@ export const page = async (user: UserToken, page: any = {}): Promise<any> => {
},
],
eyeCatchingImageId: null,
- font: 'sans-serif',
+ font: 'sans-serif' as any,
hideTitleWhenPinned: false,
name: '1678594845072',
script: '',
@@ -210,7 +205,7 @@ export const page = async (user: UserToken, page: any = {}): Promise<any> => {
return res.body;
};
-export const play = async (user: UserToken, play: any = {}): Promise<any> => {
+export const play = async (user: UserToken, play: Partial<misskey.entities.Flash> = {}): Promise<misskey.entities.Flash> => {
const res = await api('flash/create', {
permissions: [],
script: 'test',
@@ -221,7 +216,7 @@ export const play = async (user: UserToken, play: any = {}): Promise<any> => {
return res.body;
};
-export const clip = async (user: UserToken, clip: any = {}): Promise<any> => {
+export const clip = async (user: UserToken, clip: Partial<misskey.entities.Clip> = {}): Promise<misskey.entities.Clip> => {
const res = await api('clips/create', {
description: null,
isPublic: true,
@@ -231,18 +226,18 @@ export const clip = async (user: UserToken, clip: any = {}): Promise<any> => {
return res.body;
};
-export const galleryPost = async (user: UserToken, channel: any = {}): Promise<any> => {
+export const galleryPost = async (user: UserToken, galleryPost: Partial<misskey.entities.GalleryPost> = {}): Promise<misskey.entities.GalleryPost> => {
const res = await api('gallery/posts/create', {
description: null,
fileIds: [],
isSensitive: false,
title: 'test',
- ...channel,
+ ...galleryPost,
}, user);
return res.body;
};
-export const channel = async (user: UserToken, channel: any = {}): Promise<any> => {
+export const channel = async (user: UserToken, channel: Partial<misskey.entities.Channel> = {}): Promise<misskey.entities.Channel> => {
const res = await api('channels/create', {
bannerId: null,
description: null,
@@ -252,7 +247,7 @@ export const channel = async (user: UserToken, channel: any = {}): Promise<any>
return res.body;
};
-export const role = async (user: UserToken, role: any = {}, policies: any = {}): Promise<any> => {
+export const role = async (user: UserToken, role: Partial<misskey.entities.Role> = {}, policies: any = {}): Promise<misskey.entities.Role> => {
const res = await api('admin/roles/create', {
asBadge: false,
canEditMembersByModerator: false,
@@ -260,7 +255,7 @@ export const role = async (user: UserToken, role: any = {}, policies: any = {}):
condFormula: {
id: 'ebef1684-672d-49b6-ad82-1b3ec3784f85',
type: 'isRemote',
- },
+ } as any,
description: '',
displayOrder: 0,
iconUrl: null,
@@ -298,7 +293,7 @@ interface UploadOptions {
export const uploadFile = async (user?: UserToken, { path, name, blob }: UploadOptions = {}): Promise<{
status: number,
headers: Headers,
- body: misskey.Endpoints['drive/files/create']['res'] | null
+ body: misskey.entities.DriveFile | null
}> => {
const absPath = path == null
? new URL('resources/Lenna.jpg', import.meta.url)
@@ -335,14 +330,14 @@ export const uploadFile = async (user?: UserToken, { path, name, blob }: UploadO
};
};
-export const uploadUrl = async (user: UserToken, url: string): Promise<Packed<'DriveFile'>> => {
+export const uploadUrl = async (user: UserToken, url: string): Promise<misskey.entities.DriveFile> => {
const marker = Math.random().toString();
const catcher = makeStreamCatcher(
user,
'main',
(msg) => msg.type === 'urlUploadFinished' && msg.body.marker === marker,
- (msg) => msg.body.file as Packed<'DriveFile'>,
+ (msg) => msg.body.file,
60 * 1000,
);
diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts
index 34612fee73..18dfdcdc51 100644
--- a/packages/frontend/src/boot/main-boot.ts
+++ b/packages/frontend/src/boot/main-boot.ts
@@ -189,14 +189,26 @@ export async function mainBoot() {
if ($i.followersCount >= 500) claimAchievement('followers500');
if ($i.followersCount >= 1000) claimAchievement('followers1000');
- if (Date.now() - new Date($i.createdAt).getTime() > 1000 * 60 * 60 * 24 * 365) {
- claimAchievement('passedSinceAccountCreated1');
- }
- if (Date.now() - new Date($i.createdAt).getTime() > 1000 * 60 * 60 * 24 * 365 * 2) {
- claimAchievement('passedSinceAccountCreated2');
- }
- if (Date.now() - new Date($i.createdAt).getTime() > 1000 * 60 * 60 * 24 * 365 * 3) {
+ const createdAt = new Date($i.createdAt);
+ const createdAtThreeYearsLater = new Date($i.createdAt);
+ createdAtThreeYearsLater.setFullYear(createdAtThreeYearsLater.getFullYear() + 3);
+ if (now >= createdAtThreeYearsLater) {
claimAchievement('passedSinceAccountCreated3');
+ claimAchievement('passedSinceAccountCreated2');
+ claimAchievement('passedSinceAccountCreated1');
+ } else {
+ const createdAtTwoYearsLater = new Date($i.createdAt);
+ createdAtTwoYearsLater.setFullYear(createdAtTwoYearsLater.getFullYear() + 2);
+ if (now >= createdAtTwoYearsLater) {
+ claimAchievement('passedSinceAccountCreated2');
+ claimAchievement('passedSinceAccountCreated1');
+ } else {
+ const createdAtOneYearLater = new Date($i.createdAt);
+ createdAtOneYearLater.setFullYear(createdAtOneYearLater.getFullYear() + 1);
+ if (now >= createdAtOneYearLater) {
+ claimAchievement('passedSinceAccountCreated1');
+ }
+ }
}
if (claimedAchievements.length >= 30) {
@@ -231,7 +243,7 @@ export async function mainBoot() {
const latestDonationInfoShownAt = miLocalStorage.getItem('latestDonationInfoShownAt');
const neverShowDonationInfo = miLocalStorage.getItem('neverShowDonationInfo');
- if (neverShowDonationInfo !== 'true' && (new Date($i.createdAt).getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 3))) && !location.pathname.startsWith('/miauth')) {
+ if (neverShowDonationInfo !== 'true' && (createdAt.getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 3))) && !location.pathname.startsWith('/miauth')) {
if (latestDonationInfoShownAt == null || (new Date(latestDonationInfoShownAt).getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 30)))) {
popup(defineAsyncComponent(() => import('@/components/MkDonation.vue')), {}, {}, 'closed');
}
diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue
index 6351f5cfbe..23539427e3 100644
--- a/packages/frontend/src/components/MkMediaAudio.vue
+++ b/packages/frontend/src/components/MkMediaAudio.vue
@@ -69,7 +69,7 @@ import * as os from '@/os.js';
import bytes from '@/filters/bytes.js';
import { hms } from '@/filters/hms.js';
import MkMediaRange from '@/components/MkMediaRange.vue';
-import { iAmModerator } from '@/account.js';
+import { $i, iAmModerator } from '@/account.js';
const props = defineProps<{
audio: Misskey.entities.DriveFile;
@@ -99,8 +99,6 @@ function showMenu(ev: MouseEvent) {
if (iAmModerator) {
menu.push({
- type: 'divider',
- }, {
text: props.audio.isSensitive ? i18n.ts.unmarkAsSensitive : i18n.ts.markAsSensitive,
icon: props.audio.isSensitive ? 'ph-eye ph-bold ph-lg' : 'ph-eye-slash ph-bold ph-lg',
danger: true,
@@ -108,6 +106,17 @@ function showMenu(ev: MouseEvent) {
});
}
+ if ($i?.id === props.audio.userId) {
+ menu.push({
+ type: 'divider',
+ }, {
+ type: 'link' as const,
+ text: i18n.ts._fileViewer.title,
+ icon: 'ti ti-info-circle',
+ to: `/my/drive/file/${props.audio.id}`,
+ });
+ }
+
menuShowing.value = true;
os.popupMenu(menu, ev.currentTarget ?? ev.target, {
align: 'right',
diff --git a/packages/frontend/src/components/MkMediaImage.vue b/packages/frontend/src/components/MkMediaImage.vue
index 3f9cff8b71..af9d7d824c 100644
--- a/packages/frontend/src/components/MkMediaImage.vue
+++ b/packages/frontend/src/components/MkMediaImage.vue
@@ -60,7 +60,7 @@ import ImgWithBlurhash from '@/components/MkImgWithBlurhash.vue';
import { defaultStore } from '@/store.js';
import { i18n } from '@/i18n.js';
import * as os from '@/os.js';
-import { iAmModerator } from '@/account.js';
+import { $i, iAmModerator } from '@/account.js';
const props = withDefaults(defineProps<{
image: Misskey.entities.DriveFile;
@@ -115,6 +115,13 @@ function showMenu(ev: MouseEvent) {
action: () => {
os.apiWithDialog('drive/files/update', { fileId: props.image.id, isSensitive: true });
},
+ }] : []), ...($i?.id === props.image.userId ? [{
+ type: 'divider' as const,
+ }, {
+ type: 'link' as const,
+ text: i18n.ts._fileViewer.title,
+ icon: 'ti ti-info-circle',
+ to: `/my/drive/file/${props.image.id}`,
}] : [])], ev.currentTarget ?? ev.target);
}
diff --git a/packages/frontend/src/components/MkMediaVideo.vue b/packages/frontend/src/components/MkMediaVideo.vue
index 7c14ade130..c64d87e8d6 100644
--- a/packages/frontend/src/components/MkMediaVideo.vue
+++ b/packages/frontend/src/components/MkMediaVideo.vue
@@ -97,7 +97,7 @@ import * as os from '@/os.js';
import { isFullscreenNotSupported } from '@/scripts/device-kind.js';
import hasAudio from '@/scripts/media-has-audio.js';
import MkMediaRange from '@/components/MkMediaRange.vue';
-import { iAmModerator } from '@/account.js';
+import { $i, iAmModerator } from '@/account.js';
const props = defineProps<{
video: Misskey.entities.DriveFile;
@@ -125,8 +125,6 @@ function showMenu(ev: MouseEvent) {
if (iAmModerator) {
menu.push({
- type: 'divider',
- }, {
text: props.video.isSensitive ? i18n.ts.unmarkAsSensitive : i18n.ts.markAsSensitive,
icon: props.video.isSensitive ? 'ph-eye ph-bold ph-lg' : 'ph-eye-slash ph-bold ph-lg',
danger: true,
@@ -134,6 +132,17 @@ function showMenu(ev: MouseEvent) {
});
}
+ if ($i?.id === props.video.userId) {
+ menu.push({
+ type: 'divider',
+ }, {
+ type: 'link' as const,
+ text: i18n.ts._fileViewer.title,
+ icon: 'ti ti-info-circle',
+ to: `/my/drive/file/${props.video.id}`,
+ });
+ }
+
menuShowing.value = true;
os.popupMenu(menu, ev.currentTarget ?? ev.target, {
align: 'right',
diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue
index 9a667c3118..430f0269b8 100644
--- a/packages/frontend/src/components/MkNote.vue
+++ b/packages/frontend/src/components/MkNote.vue
@@ -97,7 +97,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<MkA v-if="appearNote.channel && !inChannel" :class="$style.channel" :to="`/channels/${appearNote.channel.id}`"><i class="ph-television ph-bold ph-lg"></i> {{ appearNote.channel.name }}</MkA>
</div>
- <MkReactionsViewer :note="appearNote" :maxNumber="16" @click.stop @mockUpdateMyReaction="emitUpdReaction">
+ <MkReactionsViewer v-if="appearNote.reactionAcceptance !== 'likeOnly'" :note="appearNote" :maxNumber="16" @click.stop @mockUpdateMyReaction="emitUpdReaction">
<template #more>
<div :class="$style.reactionOmitted">{{ i18n.ts.more }}</div>
</template>
@@ -105,7 +105,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<footer :class="$style.footer">
<button :class="$style.footerButton" class="_button" @click.stop @click="reply()">
<i class="ph-arrow-u-up-left ph-bold ph-lg"></i>
- <p v-if="appearNote.repliesCount > 0" :class="$style.footerButtonCount">{{ appearNote.repliesCount }}</p>
+ <p v-if="appearNote.repliesCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.repliesCount) }}</p>
</button>
<button
v-if="canRenote"
@@ -117,7 +117,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@mousedown="renoted ? undoRenote(appearNote) : boostVisibility()"
>
<i class="ph-rocket-launch ph-bold ph-lg"></i>
- <p v-if="appearNote.renoteCount > 0" :class="$style.footerButtonCount">{{ appearNote.renoteCount }}</p>
+ <p v-if="appearNote.renoteCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.renoteCount) }}</p>
</button>
<button v-else :class="$style.footerButton" class="_button" disabled>
<i class="ph-prohibit ph-bold ph-lg"></i>
@@ -135,12 +135,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<button v-if="appearNote.myReaction == null && appearNote.reactionAcceptance !== 'likeOnly'" ref="likeButton" :class="$style.footerButton" class="_button" @click.stop @click="like()">
<i class="ph-heart ph-bold ph-lg"></i>
</button>
- <button v-if="appearNote.myReaction == null" ref="reactButton" :class="$style.footerButton" class="_button" @mousedown="react()">
- <i v-if="appearNote.reactionAcceptance === 'likeOnly'" class="ph-heart ph-bold ph-lg"></i>
+ <button ref="reactButton" :class="$style.footerButton" class="_button" @click="toggleReact()">
+ <i v-if="appearNote.reactionAcceptance === 'likeOnly' && appearNote.myReaction != null" class="ph-heart ph-bold ph-lg" style="color: var(--eventReactionHeart);"></i>
+ <i v-else-if="appearNote.myReaction != null" class="ph-minus ph-bold ph-lg" style="color: var(--accent);"></i>
+ <i v-else-if="appearNote.reactionAcceptance === 'likeOnly'" class="ph-heart ph-bold ph-lg"></i>
<i v-else class="ph-smiley ph-bold ph-lg"></i>
- </button>
- <button v-if="appearNote.myReaction != null" ref="reactButton" :class="$style.footerButton" class="_button" @click.stop @click="undoReact(appearNote)">
- <i class="ph-minus ph-bold ph-lg"></i>
+ <p v-if="appearNote.reactionCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.reactionCount) }}</p>
</button>
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" :class="$style.footerButton" class="_button" @mousedown="clip()">
<i class="ph-paperclip ph-bold ph-lg"></i>
@@ -195,6 +195,7 @@ import { pleaseLogin } from '@/scripts/please-login.js';
import { focusPrev, focusNext } from '@/scripts/focus.js';
import { checkWordMute } from '@/scripts/check-word-mute.js';
import { userPage } from '@/filters/user.js';
+import number from '@/filters/number.js';
import * as os from '@/os.js';
import * as sound from '@/scripts/sound.js';
import { misskeyApi } from '@/scripts/misskey-api.js';
@@ -626,6 +627,14 @@ function undoRenote(note) : void {
}
}
+function toggleReact() {
+ if (appearNote.value.myReaction == null) {
+ react();
+ } else {
+ undoReact(appearNote.value);
+ }
+}
+
function onContextmenu(ev: MouseEvent): void {
if (props.mock) {
return;
diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue
index 3d15f69f73..a901010776 100644
--- a/packages/frontend/src/components/MkNoteDetailed.vue
+++ b/packages/frontend/src/components/MkNoteDetailed.vue
@@ -113,10 +113,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkTime :time="appearNote.createdAt" mode="detail" colored/>
</MkA>
</div>
- <MkReactionsViewer ref="reactionsViewer" :note="appearNote"/>
+ <MkReactionsViewer v-if="appearNote.reactionAcceptance !== 'likeOnly'" ref="reactionsViewer" :note="appearNote"/>
<button class="_button" :class="$style.noteFooterButton" @click="reply()">
<i class="ph-arrow-u-up-left ph-bold ph-lg"></i>
- <p v-if="appearNote.repliesCount > 0" :class="$style.noteFooterButtonCount">{{ appearNote.repliesCount }}</p>
+ <p v-if="appearNote.repliesCount > 0" :class="$style.noteFooterButtonCount">{{ number(appearNote.repliesCount) }}</p>
</button>
<button
v-if="canRenote"
@@ -127,7 +127,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@mousedown="renoted ? undoRenote() : boostVisibility()"
>
<i class="ph-rocket-launch ph-bold ph-lg"></i>
- <p v-if="appearNote.renoteCount > 0" :class="$style.noteFooterButtonCount">{{ appearNote.renoteCount }}</p>
+ <p v-if="appearNote.renoteCount > 0" :class="$style.noteFooterButtonCount">{{ number(appearNote.renoteCount) }}</p>
</button>
<button v-else class="_button" :class="$style.noteFooterButton" disabled>
<i class="ph-prohibit ph-bold ph-lg"></i>
@@ -144,12 +144,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<button v-if="appearNote.myReaction == null && appearNote.reactionAcceptance !== 'likeOnly'" ref="likeButton" :class="$style.noteFooterButton" class="_button" @mousedown="like()">
<i class="ph-heart ph-bold ph-lg"></i>
</button>
- <button v-if="appearNote.myReaction == null" ref="reactButton" :class="$style.noteFooterButton" class="_button" @mousedown="react()">
- <i v-if="appearNote.reactionAcceptance === 'likeOnly'" class="ph-heart ph-bold ph-lg"></i>
+ <button ref="reactButton" :class="$style.noteFooterButton" class="_button" @click="toggleReact()">
+ <i v-if="appearNote.reactionAcceptance === 'likeOnly' && appearNote.myReaction != null" class="ph-heart ph-bold ph-lg" style="color: var(--eventReactionHeart);"></i>
+ <i v-else-if="appearNote.myReaction != null" class="ph-minus ph-bold ph-lg" style="color: var(--accent);"></i>
+ <i v-else-if="appearNote.reactionAcceptance === 'likeOnly'" class="ph-heart ph-bold ph-lg"></i>
<i v-else class="ph-smiley ph-bold ph-lg"></i>
- </button>
- <button v-if="appearNote.myReaction != null" ref="reactButton" class="_button" :class="[$style.noteFooterButton, $style.reacted]" @click="undoReact(appearNote)">
- <i class="ph-minus ph-bold ph-lg"></i>
+ <p v-if="appearNote.reactionCount > 0" :class="$style.noteFooterButtonCount">{{ number(appearNote.reactionCount) }}</p>
</button>
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" class="_button" :class="$style.noteFooterButton" @mousedown="clip()">
<i class="ph-paperclip ph-bold ph-lg"></i>
@@ -236,6 +236,7 @@ import { pleaseLogin } from '@/scripts/please-login.js';
import { checkWordMute } from '@/scripts/check-word-mute.js';
import { userPage } from '@/filters/user.js';
import { notePage } from '@/filters/note.js';
+import number from '@/filters/number.js';
import * as os from '@/os.js';
import { misskeyApi } from '@/scripts/misskey-api.js';
import * as sound from '@/scripts/sound.js';
@@ -594,11 +595,11 @@ function like(): void {
}
}
-function undoReact(note): void {
- const oldReaction = note.myReaction;
+function undoReact(targetNote: Misskey.entities.Note): void {
+ const oldReaction = targetNote.myReaction;
if (!oldReaction) return;
misskeyApi('notes/reactions/delete', {
- noteId: note.id,
+ noteId: targetNote.id,
});
}
@@ -619,6 +620,14 @@ function undoRenote() : void {
}
}
+function toggleReact() {
+ if (appearNote.value.myReaction == null) {
+ react();
+ } else {
+ undoReact(appearNote.value);
+ }
+}
+
function onContextmenu(ev: MouseEvent): void {
const isLink = (el: HTMLElement): boolean => {
if (el.tagName === 'A') return true;
diff --git a/packages/frontend/src/components/MkNotification.vue b/packages/frontend/src/components/MkNotification.vue
index 562cc38bf3..656e6f6635 100644
--- a/packages/frontend/src/components/MkNotification.vue
+++ b/packages/frontend/src/components/MkNotification.vue
@@ -8,6 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="$style.head">
<MkAvatar v-if="['pollEnded', 'note', 'edited'].includes(notification.type) && notification.note" :class="$style.icon" :user="notification.note.user" link preview/>
<MkAvatar v-else-if="['roleAssigned', 'achievementEarned'].includes(notification.type)" :class="$style.icon" :user="$i" link preview/>
+ <div v-else-if="notification.type === 'reaction:grouped' && notification.note.reactionAcceptance === 'likeOnly'" :class="[$style.icon, $style.icon_reactionGroup]"><i class="ph-smiley ph-bold ph-lg" style="line-height: 1;"></i></div>
<div v-else-if="notification.type === 'reaction:grouped'" :class="[$style.icon, $style.icon_reactionGroup]"><i class="ph-smiley ph-bold ph-lg" style="line-height: 1;"></i></div>
<div v-else-if="notification.type === 'renote:grouped'" :class="[$style.icon, $style.icon_renoteGroup]"><i class="ph-rocket-launch ph-bold ph-lg" style="line-height: 1;"></i></div>
<img v-else-if="notification.type === 'test'" :class="$style.icon" :src="infoImageUrl"/>
@@ -60,6 +61,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<span v-else-if="notification.type === 'achievementEarned'">{{ i18n.ts._notification.achievementEarned }}</span>
<span v-else-if="notification.type === 'test'">{{ i18n.ts._notification.testNotification }}</span>
<MkA v-else-if="notification.type === 'follow' || notification.type === 'mention' || notification.type === 'reply' || notification.type === 'renote' || notification.type === 'quote' || notification.type === 'reaction' || notification.type === 'receiveFollowRequest' || notification.type === 'followRequestAccepted'" v-user-preview="notification.user.id" :class="$style.headerName" :to="userPage(notification.user)"><MkUserName :user="notification.user"/></MkA>
+ <span v-else-if="notification.type === 'reaction:grouped' && notification.note.reactionAcceptance === 'likeOnly'">{{ i18n.tsx._notification.likedBySomeUsers({ n: notification.reactions.length }) }}</span>
<span v-else-if="notification.type === 'reaction:grouped'">{{ i18n.tsx._notification.reactedBySomeUsers({ n: notification.reactions.length }) }}</span>
<span v-else-if="notification.type === 'renote:grouped'">{{ i18n.tsx._notification.renotedBySomeUsers({ n: notification.users.length }) }}</span>
<span v-else-if="notification.type === 'app'">{{ notification.header }}</span>
@@ -211,6 +213,7 @@ const rejectFollowRequest = () => {
}
.icon_reactionGroup,
+.icon_reactionGroupHeart,
.icon_renoteGroup {
display: grid;
align-items: center;
@@ -223,11 +226,15 @@ const rejectFollowRequest = () => {
}
.icon_reactionGroup {
- background: #e99a0b;
+ background: var(--eventReaction);
+}
+
+.icon_reactionGroupHeart {
+ background: var(--eventReactionHeart);
}
.icon_renoteGroup {
- background: #36d298;
+ background: var(--eventRenote);
}
.icon_app {
@@ -256,49 +263,49 @@ const rejectFollowRequest = () => {
.t_follow, .t_followRequestAccepted, .t_receiveFollowRequest {
padding: 3px;
- background: #36aed2;
+ background: var(--eventFollow);
pointer-events: none;
}
.t_renote {
padding: 3px;
- background: #36d298;
+ background: var(--eventRenote);
pointer-events: none;
}
.t_quote {
padding: 3px;
- background: #36d298;
+ background: var(--eventRenote);
pointer-events: none;
}
.t_reply {
padding: 3px;
- background: #007aff;
+ background: var(--eventReply);
pointer-events: none;
}
.t_mention {
padding: 3px;
- background: #88a6b7;
+ background: var(--eventOther);
pointer-events: none;
}
.t_pollEnded {
padding: 3px;
- background: #88a6b7;
+ background: var(--eventOther);
pointer-events: none;
}
.t_achievementEarned {
padding: 3px;
- background: #cb9a11;
+ background: var(--eventAchievement);
pointer-events: none;
}
.t_roleAssigned {
padding: 3px;
- background: #88a6b7;
+ background: var(--eventOther);
pointer-events: none;
}
diff --git a/packages/frontend/src/components/MkTutorialDialog.Note.vue b/packages/frontend/src/components/MkTutorialDialog.Note.vue
index 5544434b5f..57216058fd 100644
--- a/packages/frontend/src/components/MkTutorialDialog.Note.vue
+++ b/packages/frontend/src/components/MkTutorialDialog.Note.vue
@@ -63,6 +63,7 @@ const exampleNote = reactive<Misskey.entities.Note>({
reactionAcceptance: null,
renoteCount: 0,
repliesCount: 1,
+ reactionCount: 0,
reactions: {},
reactionEmojis: {},
fileIds: [],
diff --git a/packages/frontend/src/components/MkTutorialDialog.PostNote.vue b/packages/frontend/src/components/MkTutorialDialog.PostNote.vue
index 1771559a9b..b0561d4bae 100644
--- a/packages/frontend/src/components/MkTutorialDialog.PostNote.vue
+++ b/packages/frontend/src/components/MkTutorialDialog.PostNote.vue
@@ -68,6 +68,7 @@ const exampleCWNote = reactive<Misskey.entities.Note>({
reactionAcceptance: null,
renoteCount: 0,
repliesCount: 1,
+ reactionCount: 0,
reactions: {},
reactionEmojis: {},
fileIds: [],
diff --git a/packages/frontend/src/components/MkTutorialDialog.Sensitive.vue b/packages/frontend/src/components/MkTutorialDialog.Sensitive.vue
index 4b4e8ea8f8..f155ad7bcb 100644
--- a/packages/frontend/src/components/MkTutorialDialog.Sensitive.vue
+++ b/packages/frontend/src/components/MkTutorialDialog.Sensitive.vue
@@ -58,6 +58,7 @@ const exampleNote = reactive<Misskey.entities.Note>({
reactionAcceptance: null,
renoteCount: 0,
repliesCount: 1,
+ reactionCount: 0,
reactions: {},
reactionEmojis: {},
fileIds: ['0000000002'],
diff --git a/packages/frontend/src/components/global/MkAd.vue b/packages/frontend/src/components/global/MkAd.vue
index f13a161ae8..c01211443d 100644
--- a/packages/frontend/src/components/global/MkAd.vue
+++ b/packages/frontend/src/components/global/MkAd.vue
@@ -14,10 +14,20 @@ SPDX-License-Identifier: AGPL-3.0-only
[$style.form_vertical]: chosen.place === 'vertical',
}]"
>
- <a :href="chosen.url" target="_blank" :class="$style.link">
+ <component
+ :is="self ? 'MkA' : 'a'"
+ :class="$style.link"
+ v-bind="self ? {
+ to: chosen.url.substring(local.length),
+ } : {
+ href: chosen.url,
+ rel: 'nofollow noopener',
+ target: '_blank',
+ }"
+ >
<img :src="chosen.imageUrl" :class="$style.img">
<button class="_button" :class="$style.i" @click.prevent.stop="toggleMenu"><i :class="$style.iIcon" class="ph-info ph-bold ph-lg"></i></button>
- </a>
+ </component>
</div>
<div v-else :class="$style.menu">
<div :class="$style.menuContainer">
@@ -32,10 +42,10 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
-import { ref } from 'vue';
+import { ref, computed } from 'vue';
import { i18n } from '@/i18n.js';
import { instance } from '@/instance.js';
-import { host } from '@/config.js';
+import { url as local, host } from '@/config.js';
import MkButton from '@/components/MkButton.vue';
import { defaultStore } from '@/store.js';
import * as os from '@/os.js';
@@ -96,6 +106,9 @@ const choseAd = (): Ad | null => {
};
const chosen = ref(choseAd());
+
+const self = computed(() => chosen.value?.url.startsWith(local));
+
const shouldHide = ref(!defaultStore.state.forceShowAds && $i && $i.policies.canHideAds && (props.specify == null));
function reduceFrequency(): void {
diff --git a/packages/frontend/src/nirax.ts b/packages/frontend/src/nirax.ts
index 616fb104e6..6a8ea09ed6 100644
--- a/packages/frontend/src/nirax.ts
+++ b/packages/frontend/src/nirax.ts
@@ -373,7 +373,7 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
this.currentRoute.value = res.route;
this.currentKey = res.route.globalCacheKey ?? key ?? path;
- if (emitChange) {
+ if (emitChange && res.route.path !== '/:(*)') {
this.emit('change', {
beforePath,
path,
@@ -408,13 +408,17 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
if (cancel) return;
}
const res = this.navigate(path, null);
- this.emit('push', {
- beforePath,
- path: res._parsedRoute.fullPath,
- route: res.route,
- props: res.props,
- key: this.currentKey,
- });
+ if (res.route.path === '/:(*)') {
+ location.href = path;
+ } else {
+ this.emit('push', {
+ beforePath,
+ path: res._parsedRoute.fullPath,
+ route: res.route,
+ props: res.props,
+ key: this.currentKey,
+ });
+ }
}
public replace(path: string, key?: string | null) {
diff --git a/packages/frontend/src/scripts/use-note-capture.ts b/packages/frontend/src/scripts/use-note-capture.ts
index 3baa45d50f..1b3626bff5 100644
--- a/packages/frontend/src/scripts/use-note-capture.ts
+++ b/packages/frontend/src/scripts/use-note-capture.ts
@@ -54,6 +54,7 @@ export function useNoteCapture(props: {
const currentCount = (note.value.reactions || {})[reaction] || 0;
note.value.reactions[reaction] = currentCount + 1;
+ note.value.reactionCount += 1;
if ($i && (body.userId === $i.id)) {
note.value.myReaction = reaction;
@@ -68,6 +69,7 @@ export function useNoteCapture(props: {
const currentCount = (note.value.reactions || {})[reaction] || 0;
note.value.reactions[reaction] = Math.max(0, currentCount - 1);
+ note.value.reactionCount = Math.max(0, note.value.reactionCount - 1);
if (note.value.reactions[reaction] === 0) delete note.value.reactions[reaction];
if ($i && (body.userId === $i.id)) {
diff --git a/packages/frontend/src/style.scss b/packages/frontend/src/style.scss
index d876009961..e5a18134ee 100644
--- a/packages/frontend/src/style.scss
+++ b/packages/frontend/src/style.scss
@@ -41,6 +41,13 @@
--thread-width: 2px;
//--ad: rgb(255 169 0 / 10%);
+ --eventFollow: #36aed2;
+ --eventRenote: #36d298;
+ --eventReply: #007aff;
+ --eventReactionHeart: #dd2e44;
+ --eventReaction: #e99a0b;
+ --eventAchievement: #cb9a11;
+ --eventOther: #88a6b7;
}
html.radius-misskey {
diff --git a/packages/frontend/vite.config.local-dev.ts b/packages/frontend/vite.config.local-dev.ts
index 4c19dfbc66..3a02309a4f 100644
--- a/packages/frontend/vite.config.local-dev.ts
+++ b/packages/frontend/vite.config.local-dev.ts
@@ -49,6 +49,9 @@ const devConfig = {
},
'/url': httpUrl,
'/proxy': httpUrl,
+ '/_info_card_': httpUrl,
+ '/bios': httpUrl,
+ '/cli': httpUrl,
},
},
build: {
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index 6b4ee9361e..db14823d37 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -4119,6 +4119,7 @@ export type components = {
reactions: {
[key: string]: number;
};
+ reactionCount: number;
renoteCount: number;
repliesCount: number;
uri?: string;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b54383a88f..7074523beb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1102,10 +1102,10 @@ importers:
devDependencies:
'@typescript-eslint/eslint-plugin':
specifier: ^6.12.0
- version: 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.54.0)(typescript@5.1.6)
+ version: 6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.1.6)
'@typescript-eslint/parser':
specifier: ^6.12.0
- version: 6.21.0(eslint@8.54.0)(typescript@5.1.6)
+ version: 6.12.0(eslint@8.54.0)(typescript@5.1.6)
eslint:
specifier: ^8.54.0
version: 8.54.0
@@ -1325,7 +1325,7 @@ importers:
devDependencies:
'@misskey-dev/eslint-plugin':
specifier: 1.0.0
- version: 1.0.0(@typescript-eslint/eslint-plugin@6.21.0)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
+ version: 1.0.0(@typescript-eslint/eslint-plugin@6.18.1)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
'@typescript-eslint/parser':
specifier: 7.1.0
version: 7.1.0(eslint@8.57.0)(typescript@5.3.3)
@@ -1993,14 +1993,14 @@ packages:
dependencies:
'@ampproject/remapping': 2.2.1
'@babel/code-frame': 7.23.4
- '@babel/generator': 7.23.6
+ '@babel/generator': 7.23.4
'@babel/helper-compilation-targets': 7.22.15
'@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.3)
'@babel/helpers': 7.23.4
'@babel/parser': 7.23.4
'@babel/template': 7.22.15
- '@babel/traverse': 7.24.0
- '@babel/types': 7.24.0
+ '@babel/traverse': 7.23.4
+ '@babel/types': 7.23.4
convert-source-map: 2.0.0
debug: 4.3.4(supports-color@8.1.1)
gensync: 1.0.0-beta.2
@@ -2033,6 +2033,16 @@ packages:
- supports-color
dev: true
+ /@babel/generator@7.23.4:
+ resolution: {integrity: sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.23.4
+ '@jridgewell/gen-mapping': 0.3.3
+ '@jridgewell/trace-mapping': 0.3.20
+ jsesc: 2.5.2
+ dev: true
+
/@babel/generator@7.23.6:
resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==}
engines: {node: '>=6.9.0'}
@@ -2047,14 +2057,14 @@ packages:
resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@babel/helper-builder-binary-assignment-operator-visitor@7.22.15:
resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@babel/helper-compilation-targets@7.22.15:
@@ -2074,65 +2084,47 @@ packages:
dependencies:
'@babel/compat-data': 7.23.5
'@babel/helper-validator-option': 7.23.5
- browserslist: 4.23.0
+ browserslist: 4.22.2
lru-cache: 5.1.1
semver: 6.3.1
dev: true
- /@babel/helper-create-class-features-plugin@7.23.5(@babel/core@7.24.0):
- resolution: {integrity: sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==}
+ /@babel/helper-create-class-features-plugin@7.23.6(@babel/core@7.23.3):
+ resolution: {integrity: sha512-cBXU1vZni/CpGF29iTu4YRbOZt3Wat6zCoMDxRF1MayiEc4URxOj31tT65HUM0CRpMowA3HCJaAOVOUnMf96cw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-annotate-as-pure': 7.22.5
- '@babel/helper-environment-visitor': 7.22.20
- '@babel/helper-function-name': 7.23.0
- '@babel/helper-member-expression-to-functions': 7.23.0
- '@babel/helper-optimise-call-expression': 7.22.5
- '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0)
- '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
- '@babel/helper-split-export-declaration': 7.22.6
- semver: 6.3.1
- dev: true
-
- /@babel/helper-create-class-features-plugin@7.24.0(@babel/core@7.24.0):
- resolution: {integrity: sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0
- dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-function-name': 7.23.0
'@babel/helper-member-expression-to-functions': 7.23.0
'@babel/helper-optimise-call-expression': 7.22.5
- '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0)
+ '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.3)
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
semver: 6.3.1
dev: true
- /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.0):
+ /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.3):
resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-annotate-as-pure': 7.22.5
regexpu-core: 5.3.2
semver: 6.3.1
dev: true
- /@babel/helper-define-polyfill-provider@0.4.4(@babel/core@7.24.0):
+ /@babel/helper-define-polyfill-provider@0.4.4(@babel/core@7.23.3):
resolution: {integrity: sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==}
peerDependencies:
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-compilation-targets': 7.23.6
'@babel/helper-plugin-utils': 7.22.5
debug: 4.3.4(supports-color@8.1.1)
@@ -2151,29 +2143,29 @@ packages:
resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/template': 7.24.0
- '@babel/types': 7.24.0
+ '@babel/template': 7.22.15
+ '@babel/types': 7.23.4
dev: true
/@babel/helper-hoist-variables@7.22.5:
resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@babel/helper-member-expression-to-functions@7.23.0:
resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@babel/helper-module-imports@7.22.15:
resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@babel/helper-module-transforms@7.23.3(@babel/core@7.23.3):
@@ -2208,7 +2200,7 @@ packages:
resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@babel/helper-plugin-utils@7.22.5:
@@ -2216,25 +2208,25 @@ packages:
engines: {node: '>=6.9.0'}
dev: true
- /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.24.0):
+ /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.23.3):
resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-wrap-function': 7.22.20
dev: true
- /@babel/helper-replace-supers@7.22.20(@babel/core@7.24.0):
+ /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.3):
resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-member-expression-to-functions': 7.23.0
'@babel/helper-optimise-call-expression': 7.22.5
@@ -2244,27 +2236,35 @@ packages:
resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@babel/helper-skip-transparent-expression-wrappers@7.22.5:
resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@babel/helper-split-export-declaration@7.22.6:
resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
+ /@babel/helper-string-parser@7.22.5:
+ resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
+ engines: {node: '>=6.9.0'}
+
/@babel/helper-string-parser@7.23.4:
resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==}
engines: {node: '>=6.9.0'}
+ /@babel/helper-validator-identifier@7.22.15:
+ resolution: {integrity: sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==}
+ engines: {node: '>=6.9.0'}
+
/@babel/helper-validator-identifier@7.22.20:
resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
engines: {node: '>=6.9.0'}
@@ -2284,8 +2284,8 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-function-name': 7.23.0
- '@babel/template': 7.24.0
- '@babel/types': 7.24.0
+ '@babel/template': 7.22.15
+ '@babel/types': 7.23.4
dev: true
/@babel/helpers@7.23.4:
@@ -2293,8 +2293,8 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
'@babel/template': 7.22.15
- '@babel/traverse': 7.24.0
- '@babel/types': 7.24.0
+ '@babel/traverse': 7.23.4
+ '@babel/types': 7.23.4
transitivePeerDependencies:
- supports-color
dev: true
@@ -2323,22 +2323,14 @@ packages:
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.22.17
/@babel/parser@7.23.4:
resolution: {integrity: sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
- '@babel/types': 7.24.0
- dev: true
-
- /@babel/parser@7.23.6:
- resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==}
- engines: {node: '>=6.0.0'}
- hasBin: true
- dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@babel/parser@7.23.9:
@@ -2346,7 +2338,7 @@ packages:
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
/@babel/parser@7.24.0:
resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==}
@@ -2356,46 +2348,46 @@ packages:
'@babel/types': 7.24.0
dev: true
- /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.13.0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
- '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.24.0)
+ '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.3)
dev: true
- /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.0):
+ /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.3):
resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
dev: true
/@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.3):
@@ -2407,15 +2399,6 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.0):
- resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
/@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.3):
resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
peerDependencies:
@@ -2434,70 +2417,61 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.0):
- resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
- /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.0):
+ /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.3):
resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.0):
+ /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.3):
resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.0):
+ /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.3):
resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-flow@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-syntax-flow@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
@@ -2510,15 +2484,6 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.0):
- resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
/@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.3):
resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
peerDependencies:
@@ -2528,15 +2493,6 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.0):
- resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
/@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==}
engines: {node: '>=6.9.0'}
@@ -2547,16 +2503,6 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.24.0):
- resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
/@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.3):
resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
peerDependencies:
@@ -2566,15 +2512,6 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.0):
- resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
/@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.3):
resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
peerDependencies:
@@ -2584,15 +2521,6 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.0):
- resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
/@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.3):
resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
peerDependencies:
@@ -2602,15 +2530,6 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.0):
- resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
/@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.3):
resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
peerDependencies:
@@ -2620,15 +2539,6 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.0):
- resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
/@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.3):
resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
peerDependencies:
@@ -2638,15 +2548,6 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.0):
- resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
/@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.3):
resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
peerDependencies:
@@ -2656,22 +2557,13 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.0):
- resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
- /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.0):
+ /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.3):
resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
@@ -2685,16 +2577,6 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.0):
- resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
/@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==}
engines: {node: '>=6.9.0'}
@@ -2705,719 +2587,709 @@ packages:
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.24.0):
- resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
- dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-plugin-utils': 7.22.5
- dev: true
-
- /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.0):
+ /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.3):
resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-async-generator-functions@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-async-generator-functions@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-plugin-utils': 7.22.5
- '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.0)
- '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0)
+ '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.3)
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-async-to-generator@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-async-to-generator@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-module-imports': 7.22.15
'@babel/helper-plugin-utils': 7.22.5
- '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.0)
+ '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-create-class-features-plugin': 7.23.6(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.12.0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-create-class-features-plugin': 7.23.6(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.0)
+ '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-classes@7.23.5(@babel/core@7.24.0):
+ /@babel/plugin-transform-classes@7.23.5(@babel/core@7.23.3):
resolution: {integrity: sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-compilation-targets': 7.23.6
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-function-name': 7.23.0
'@babel/helper-optimise-call-expression': 7.22.5
'@babel/helper-plugin-utils': 7.22.5
- '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0)
+ '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.3)
'@babel/helper-split-export-declaration': 7.22.6
globals: 11.12.0
dev: true
- /@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
- '@babel/template': 7.24.0
+ '@babel/template': 7.22.15
dev: true
- /@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.0)
+ '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.0)
+ '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-flow-strip-types@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-flow-strip-types@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.24.0)
+ '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-for-of@7.23.6(@babel/core@7.24.0):
+ /@babel/plugin-transform-for-of@7.23.6(@babel/core@7.23.3):
resolution: {integrity: sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
dev: true
- /@babel/plugin-transform-function-name@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-function-name@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-compilation-targets': 7.23.6
'@babel/helper-function-name': 7.23.0
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0)
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-literals@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-literals@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0)
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-simple-access': 7.22.5
dev: true
- /@babel/plugin-transform-modules-systemjs@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-modules-systemjs@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-hoist-variables': 7.22.5
- '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
+ '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-validator-identifier': 7.22.20
dev: true
- /@babel/plugin-transform-modules-umd@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-modules-umd@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.24.0):
+ /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.3):
resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-new-target@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-new-target@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0)
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0)
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-object-rest-spread@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-object-rest-spread@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/compat-data': 7.23.5
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-compilation-targets': 7.23.6
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0)
- '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.24.0)
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-object-super@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-object-super@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
- '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0)
+ '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0)
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
- '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0)
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-parameters@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-parameters@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-create-class-features-plugin': 7.23.6(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.24.0):
+ /@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.23.3):
resolution: {integrity: sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-annotate-as-pure': 7.22.5
- '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.24.0)
+ '@babel/helper-create-class-features-plugin': 7.23.6(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.0)
+ '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
regenerator-transform: 0.15.2
dev: true
- /@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-shorthand-properties@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-shorthand-properties@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-spread@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-spread@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
dev: true
- /@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-typescript@7.23.6(@babel/core@7.24.0):
+ /@babel/plugin-transform-typescript@7.23.6(@babel/core@7.23.3):
resolution: {integrity: sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-annotate-as-pure': 7.22.5
- '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
+ '@babel/helper-create-class-features-plugin': 7.23.6(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
- '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.0)
+ '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.3)
dev: true
- /@babel/plugin-transform-unicode-escapes@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-unicode-escapes@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.24.0):
+ /@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.3)
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/preset-env@7.23.6(@babel/core@7.24.0):
+ /@babel/preset-env@7.23.6(@babel/core@7.23.3):
resolution: {integrity: sha512-2XPn/BqKkZCpzYhUUNZ1ssXw7DcXfKQEjv/uXZUXgaebCMYmkEsfZ2yY+vv+xtXv50WmL5SGhyB6/xsWxIvvOQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/compat-data': 7.23.5
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-compilation-targets': 7.23.6
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-validator-option': 7.23.5
- '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.0)
- '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0)
- '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.0)
- '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.0)
- '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.0)
- '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.0)
- '@babel/plugin-syntax-import-assertions': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.0)
- '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0)
- '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0)
- '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0)
- '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0)
- '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0)
- '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0)
- '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0)
- '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.0)
- '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.0)
- '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.0)
- '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-async-generator-functions': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-async-to-generator': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-block-scoped-functions': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-class-static-block': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-classes': 7.23.5(@babel/core@7.24.0)
- '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-dotall-regex': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-duplicate-keys': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-dynamic-import': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-exponentiation-operator': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-for-of': 7.23.6(@babel/core@7.24.0)
- '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-json-strings': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-logical-assignment-operators': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-member-expression-literals': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-modules-amd': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-modules-systemjs': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-modules-umd': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.24.0)
- '@babel/plugin-transform-new-target': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-numeric-separator': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-object-rest-spread': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-object-super': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-optional-catch-binding': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-private-property-in-object': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-property-literals': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-regenerator': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-reserved-words': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-sticky-regex': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-template-literals': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-typeof-symbol': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-unicode-escapes': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-unicode-property-regex': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-unicode-regex': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-unicode-sets-regex': 7.23.3(@babel/core@7.24.0)
- '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.0)
- babel-plugin-polyfill-corejs2: 0.4.7(@babel/core@7.24.0)
- babel-plugin-polyfill-corejs3: 0.8.7(@babel/core@7.24.0)
- babel-plugin-polyfill-regenerator: 0.5.4(@babel/core@7.24.0)
+ '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.3)
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.3)
+ '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.3)
+ '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.3)
+ '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.3)
+ '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.3)
+ '@babel/plugin-syntax-import-assertions': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.3)
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.3)
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.3)
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.3)
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.3)
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.3)
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.3)
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.3)
+ '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.3)
+ '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.3)
+ '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.3)
+ '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-async-generator-functions': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-async-to-generator': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-block-scoped-functions': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-class-static-block': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-classes': 7.23.5(@babel/core@7.23.3)
+ '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-dotall-regex': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-duplicate-keys': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-dynamic-import': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-exponentiation-operator': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-for-of': 7.23.6(@babel/core@7.23.3)
+ '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-json-strings': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-logical-assignment-operators': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-member-expression-literals': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-modules-amd': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-modules-systemjs': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-modules-umd': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.3)
+ '@babel/plugin-transform-new-target': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-numeric-separator': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-object-rest-spread': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-object-super': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-optional-catch-binding': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-private-property-in-object': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-property-literals': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-regenerator': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-reserved-words': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-sticky-regex': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-template-literals': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-typeof-symbol': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-unicode-escapes': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-unicode-property-regex': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-unicode-regex': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-unicode-sets-regex': 7.23.3(@babel/core@7.23.3)
+ '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.3)
+ babel-plugin-polyfill-corejs2: 0.4.7(@babel/core@7.23.3)
+ babel-plugin-polyfill-corejs3: 0.8.7(@babel/core@7.23.3)
+ babel-plugin-polyfill-regenerator: 0.5.4(@babel/core@7.23.3)
core-js-compat: 3.34.0
semver: 6.3.1
transitivePeerDependencies:
- supports-color
dev: true
- /@babel/preset-flow@7.23.3(@babel/core@7.24.0):
+ /@babel/preset-flow@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-7yn6hl8RIv+KNk6iIrGZ+D06VhVY35wLVf23Cz/mMu1zOr7u4MMP4j0nZ9tLf8+4ZFpnib8cFYgB/oYg9hfswA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-validator-option': 7.23.5
- '@babel/plugin-transform-flow-strip-types': 7.23.3(@babel/core@7.24.0)
+ '@babel/plugin-transform-flow-strip-types': 7.23.3(@babel/core@7.23.3)
dev: true
- /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.0):
+ /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.23.3):
resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==}
peerDependencies:
'@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
esutils: 2.0.3
dev: true
- /@babel/preset-typescript@7.23.3(@babel/core@7.24.0):
+ /@babel/preset-typescript@7.23.3(@babel/core@7.23.3):
resolution: {integrity: sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-validator-option': 7.23.5
- '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.24.0)
+ '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.23.3)
dev: true
- /@babel/register@7.22.15(@babel/core@7.24.0):
+ /@babel/register@7.22.15(@babel/core@7.23.3):
resolution: {integrity: sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
clone-deep: 4.0.1
find-cache-dir: 2.1.0
make-dir: 2.1.0
@@ -3448,7 +3320,7 @@ packages:
dependencies:
'@babel/code-frame': 7.23.4
'@babel/parser': 7.23.4
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@babel/template@7.24.0:
@@ -3460,6 +3332,24 @@ packages:
'@babel/types': 7.24.0
dev: true
+ /@babel/traverse@7.23.4:
+ resolution: {integrity: sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/code-frame': 7.23.4
+ '@babel/generator': 7.23.4
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-function-name': 7.23.0
+ '@babel/helper-hoist-variables': 7.22.5
+ '@babel/helper-split-export-declaration': 7.22.6
+ '@babel/parser': 7.23.4
+ '@babel/types': 7.23.4
+ debug: 4.3.4(supports-color@8.1.1)
+ globals: 11.12.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@babel/traverse@7.24.0:
resolution: {integrity: sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==}
engines: {node: '>=6.9.0'}
@@ -3478,6 +3368,22 @@ packages:
- supports-color
dev: true
+ /@babel/types@7.22.17:
+ resolution: {integrity: sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-string-parser': 7.22.5
+ '@babel/helper-validator-identifier': 7.22.15
+ to-fast-properties: 2.0.0
+
+ /@babel/types@7.23.4:
+ resolution: {integrity: sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-string-parser': 7.23.4
+ '@babel/helper-validator-identifier': 7.22.20
+ to-fast-properties: 2.0.0
+
/@babel/types@7.24.0:
resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==}
engines: {node: '>=6.9.0'}
@@ -3485,6 +3391,7 @@ packages:
'@babel/helper-string-parser': 7.23.4
'@babel/helper-validator-identifier': 7.22.20
to-fast-properties: 2.0.0
+ dev: true
/@base2/pretty-print-object@1.0.1:
resolution: {integrity: sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==}
@@ -4798,7 +4705,7 @@ packages:
resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@jest/types': 29.6.3
'@jridgewell/trace-mapping': 0.3.20
babel-plugin-istanbul: 6.1.1
@@ -4990,7 +4897,7 @@ packages:
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)
dev: true
- /@misskey-dev/eslint-plugin@1.0.0(@typescript-eslint/eslint-plugin@6.21.0)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0):
+ /@misskey-dev/eslint-plugin@1.0.0(@typescript-eslint/eslint-plugin@6.18.1)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0):
resolution: {integrity: sha512-dh6UbcrNDVg5DD8k8Qh4ab30OPpuEYIlJCqaBV/lkIV8wNN/AfCJ2V7iTP8V8KjryM4t+sf5IqzQLQnT0mWI4A==}
peerDependencies:
'@typescript-eslint/eslint-plugin': '>= 6'
@@ -4998,7 +4905,7 @@ packages:
eslint: '>= 3'
eslint-plugin-import: '>= 2'
dependencies:
- '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3)
+ '@typescript-eslint/eslint-plugin': 6.18.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
eslint: 8.57.0
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)
@@ -5440,7 +5347,7 @@ packages:
optional: true
dependencies:
'@rollup/pluginutils': 5.1.0(rollup@4.12.0)
- magic-string: 0.30.7
+ magic-string: 0.30.5
rollup: 4.12.0
dev: false
@@ -6172,7 +6079,7 @@ packages:
/@storybook/addon-docs@8.0.0-beta.6:
resolution: {integrity: sha512-VLys4EuL8XVhmu1QxUiUG5keID8v/FsC5L71Y0Wcf5D+ll6ZD8vCqEtbMY3TiJJ9NqqNIcmcG3bG6JVXOYcD8g==}
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
'@mdx-js/react': 3.0.1(@types/react@18.0.28)(react@18.2.0)
'@storybook/blocks': 8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
'@storybook/client-logger': 8.0.0-beta.6
@@ -6413,8 +6320,8 @@ packages:
resolution: {integrity: sha512-sREQYnPds2bwQS7FLbRy7oaxGvOmYhPEYVf93pWKyo/qwSWyXEXbqGCGT6bNhSl/xzqXX7VryLDmuOoHmVTh1g==}
hasBin: true
dependencies:
- '@babel/core': 7.24.0
- '@babel/types': 7.24.0
+ '@babel/core': 7.23.3
+ '@babel/types': 7.23.4
'@ndelangen/get-tarball': 3.0.7
'@storybook/codemod': 8.0.0-beta.6
'@storybook/core-common': 8.0.0-beta.6
@@ -6444,7 +6351,7 @@ packages:
prettier: 3.2.5
prompts: 2.4.2
read-pkg-up: 7.0.1
- semver: 7.6.0
+ semver: 7.5.4
strip-json-comments: 3.1.1
tempy: 1.0.1
tiny-invariant: 1.3.1
@@ -6468,9 +6375,9 @@ packages:
/@storybook/codemod@8.0.0-beta.6:
resolution: {integrity: sha512-ttQYDkhKmtU6Qbg+Kgn4K2XXf8XMpa2euuC6PmYffBD7/qLiGfABfBc4FHKRv4yScnvKK7Ehy7K0lvipfg6tXw==}
dependencies:
- '@babel/core': 7.24.0
- '@babel/preset-env': 7.23.6(@babel/core@7.24.0)
- '@babel/types': 7.24.0
+ '@babel/core': 7.23.3
+ '@babel/preset-env': 7.23.6(@babel/core@7.23.3)
+ '@babel/types': 7.23.4
'@storybook/csf': 0.1.2
'@storybook/csf-tools': 8.0.0-beta.6
'@storybook/node-logger': 8.0.0-beta.6
@@ -6617,10 +6524,10 @@ packages:
/@storybook/csf-tools@8.0.0-beta.6:
resolution: {integrity: sha512-wwzbE6f8ykrvIeZlXYTba0IA8D5GPSyZ4L0+PqRAYHm3ozu0DXqtm4USDHKrjYAzuD+W+fG/6qIOQmsWYbNmpA==}
dependencies:
- '@babel/generator': 7.23.6
- '@babel/parser': 7.24.0
- '@babel/traverse': 7.24.0
- '@babel/types': 7.24.0
+ '@babel/generator': 7.23.4
+ '@babel/parser': 7.23.9
+ '@babel/traverse': 7.23.4
+ '@babel/types': 7.23.4
'@storybook/csf': 0.1.2
'@storybook/types': 8.0.0-beta.6
fs-extra: 11.1.1
@@ -6936,7 +6843,7 @@ packages:
ts-dedent: 2.2.0
type-fest: 2.19.0
vue: 3.4.21(typescript@5.3.3)
- vue-component-type-helpers: 1.8.27
+ vue-component-type-helpers: 2.0.6
transitivePeerDependencies:
- encoding
- supports-color
@@ -7479,8 +7386,8 @@ packages:
/@types/babel__core@7.20.5:
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
dependencies:
- '@babel/parser': 7.23.6
- '@babel/types': 7.24.0
+ '@babel/parser': 7.23.9
+ '@babel/types': 7.23.4
'@types/babel__generator': 7.6.7
'@types/babel__template': 7.4.4
'@types/babel__traverse': 7.20.4
@@ -7489,20 +7396,20 @@ packages:
/@types/babel__generator@7.6.7:
resolution: {integrity: sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@types/babel__template@7.4.4:
resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
dependencies:
- '@babel/parser': 7.23.6
- '@babel/types': 7.24.0
+ '@babel/parser': 7.23.9
+ '@babel/types': 7.23.4
dev: true
/@types/babel__traverse@7.20.4:
resolution: {integrity: sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
dev: true
/@types/bcryptjs@2.4.6:
@@ -7675,7 +7582,7 @@ packages:
/@types/hast@3.0.4:
resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
dependencies:
- '@types/unist': 2.0.6
+ '@types/unist': 3.0.2
dev: true
/@types/htmlescape@1.1.3:
@@ -7770,7 +7677,7 @@ packages:
/@types/mdast@4.0.3:
resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==}
dependencies:
- '@types/unist': 2.0.6
+ '@types/unist': 3.0.2
dev: true
/@types/mdx@2.0.3:
@@ -8014,10 +7921,6 @@ packages:
resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==}
dev: true
- /@types/unist@2.0.6:
- resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
- dev: true
-
/@types/unist@3.0.2:
resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==}
dev: true
@@ -8102,8 +8005,8 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.54.0)(typescript@5.1.6):
- resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==}
+ /@typescript-eslint/eslint-plugin@6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.1.6):
+ resolution: {integrity: sha512-XOpZ3IyJUIV1b15M7HVOpgQxPPF7lGXgsfcEIu3yDxFPaf/xZKt7s9QO/pbk7vpWQyVulpJbu4E5LwpZiQo4kA==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
'@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
@@ -8114,25 +8017,25 @@ packages:
optional: true
dependencies:
'@eslint-community/regexpp': 4.10.0
- '@typescript-eslint/parser': 6.21.0(eslint@8.54.0)(typescript@5.1.6)
- '@typescript-eslint/scope-manager': 6.21.0
- '@typescript-eslint/type-utils': 6.21.0(eslint@8.54.0)(typescript@5.1.6)
- '@typescript-eslint/utils': 6.21.0(eslint@8.54.0)(typescript@5.1.6)
- '@typescript-eslint/visitor-keys': 6.21.0
+ '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.1.6)
+ '@typescript-eslint/scope-manager': 6.12.0
+ '@typescript-eslint/type-utils': 6.12.0(eslint@8.54.0)(typescript@5.1.6)
+ '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.1.6)
+ '@typescript-eslint/visitor-keys': 6.12.0
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.54.0
graphemer: 1.4.0
ignore: 5.3.0
natural-compare: 1.4.0
- semver: 7.6.0
+ semver: 7.5.4
ts-api-utils: 1.0.3(typescript@5.1.6)
typescript: 5.1.6
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3):
- resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==}
+ /@typescript-eslint/eslint-plugin@6.18.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3):
+ resolution: {integrity: sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
'@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
@@ -8144,10 +8047,10 @@ packages:
dependencies:
'@eslint-community/regexpp': 4.10.0
'@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
- '@typescript-eslint/scope-manager': 6.21.0
- '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.0)(typescript@5.3.3)
- '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.3.3)
- '@typescript-eslint/visitor-keys': 6.21.0
+ '@typescript-eslint/scope-manager': 6.18.1
+ '@typescript-eslint/type-utils': 6.18.1(eslint@8.57.0)(typescript@5.3.3)
+ '@typescript-eslint/utils': 6.18.1(eslint@8.57.0)(typescript@5.3.3)
+ '@typescript-eslint/visitor-keys': 6.18.1
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.57.0
graphemer: 1.4.0
@@ -8182,7 +8085,7 @@ packages:
graphemer: 1.4.0
ignore: 5.3.0
natural-compare: 1.4.0
- semver: 7.6.0
+ semver: 7.5.4
ts-api-utils: 1.0.3(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
@@ -8210,8 +8113,8 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/parser@6.21.0(eslint@8.54.0)(typescript@5.1.6):
- resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==}
+ /@typescript-eslint/parser@6.12.0(eslint@8.54.0)(typescript@5.1.6):
+ resolution: {integrity: sha512-s8/jNFPKPNRmXEnNXfuo1gemBdVmpQsK1pcu+QIvuNJuhFzGrpD7WjOcvDc/+uEdfzSYpNu7U/+MmbScjoQ6vg==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
@@ -8220,10 +8123,10 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/scope-manager': 6.21.0
- '@typescript-eslint/types': 6.21.0
- '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.1.6)
- '@typescript-eslint/visitor-keys': 6.21.0
+ '@typescript-eslint/scope-manager': 6.12.0
+ '@typescript-eslint/types': 6.12.0
+ '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.1.6)
+ '@typescript-eslint/visitor-keys': 6.12.0
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.54.0
typescript: 5.1.6
@@ -8260,12 +8163,20 @@ packages:
'@typescript-eslint/visitor-keys': 6.11.0
dev: true
- /@typescript-eslint/scope-manager@6.21.0:
- resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==}
+ /@typescript-eslint/scope-manager@6.12.0:
+ resolution: {integrity: sha512-5gUvjg+XdSj8pcetdL9eXJzQNTl3RD7LgUiYTl8Aabdi8hFkaGSYnaS6BLc0BGNaDH+tVzVwmKtWvu0jLgWVbw==}
engines: {node: ^16.0.0 || >=18.0.0}
dependencies:
- '@typescript-eslint/types': 6.21.0
- '@typescript-eslint/visitor-keys': 6.21.0
+ '@typescript-eslint/types': 6.12.0
+ '@typescript-eslint/visitor-keys': 6.12.0
+ dev: true
+
+ /@typescript-eslint/scope-manager@6.18.1:
+ resolution: {integrity: sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dependencies:
+ '@typescript-eslint/types': 6.18.1
+ '@typescript-eslint/visitor-keys': 6.18.1
dev: true
/@typescript-eslint/scope-manager@7.1.0:
@@ -8296,8 +8207,8 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/type-utils@6.21.0(eslint@8.54.0)(typescript@5.1.6):
- resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==}
+ /@typescript-eslint/type-utils@6.12.0(eslint@8.54.0)(typescript@5.1.6):
+ resolution: {integrity: sha512-WWmRXxhm1X8Wlquj+MhsAG4dU/Blvf1xDgGaYCzfvStP2NwPQh6KBvCDbiOEvaE0filhranjIlK/2fSTVwtBng==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
@@ -8306,8 +8217,8 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.1.6)
- '@typescript-eslint/utils': 6.21.0(eslint@8.54.0)(typescript@5.1.6)
+ '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.1.6)
+ '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.1.6)
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.54.0
ts-api-utils: 1.0.3(typescript@5.1.6)
@@ -8316,8 +8227,8 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/type-utils@6.21.0(eslint@8.57.0)(typescript@5.3.3):
- resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==}
+ /@typescript-eslint/type-utils@6.18.1(eslint@8.57.0)(typescript@5.3.3):
+ resolution: {integrity: sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
@@ -8326,8 +8237,8 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
- '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.3.3)
+ '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3)
+ '@typescript-eslint/utils': 6.18.1(eslint@8.57.0)(typescript@5.3.3)
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.57.0
ts-api-utils: 1.0.3(typescript@5.3.3)
@@ -8361,8 +8272,13 @@ packages:
engines: {node: ^16.0.0 || >=18.0.0}
dev: true
- /@typescript-eslint/types@6.21.0:
- resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==}
+ /@typescript-eslint/types@6.12.0:
+ resolution: {integrity: sha512-MA16p/+WxM5JG/F3RTpRIcuOghWO30//VEOvzubM8zuOOBYXsP+IfjoCXXiIfy2Ta8FRh9+IO9QLlaFQUU+10Q==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dev: true
+
+ /@typescript-eslint/types@6.18.1:
+ resolution: {integrity: sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==}
engines: {node: ^16.0.0 || >=18.0.0}
dev: true
@@ -8392,8 +8308,8 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/typescript-estree@6.21.0(typescript@5.1.6):
- resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==}
+ /@typescript-eslint/typescript-estree@6.12.0(typescript@5.1.6):
+ resolution: {integrity: sha512-vw9E2P9+3UUWzhgjyyVczLWxZ3GuQNT7QpnIY3o5OMeLO/c8oHljGc8ZpryBMIyympiAAaKgw9e5Hl9dCWFOYw==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
typescript: '*'
@@ -8401,21 +8317,20 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/types': 6.21.0
- '@typescript-eslint/visitor-keys': 6.21.0
+ '@typescript-eslint/types': 6.12.0
+ '@typescript-eslint/visitor-keys': 6.12.0
debug: 4.3.4(supports-color@8.1.1)
globby: 11.1.0
is-glob: 4.0.3
- minimatch: 9.0.3
- semver: 7.6.0
+ semver: 7.5.4
ts-api-utils: 1.0.3(typescript@5.1.6)
typescript: 5.1.6
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/typescript-estree@6.21.0(typescript@5.3.3):
- resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==}
+ /@typescript-eslint/typescript-estree@6.18.1(typescript@5.3.3):
+ resolution: {integrity: sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
typescript: '*'
@@ -8423,8 +8338,8 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/types': 6.21.0
- '@typescript-eslint/visitor-keys': 6.21.0
+ '@typescript-eslint/types': 6.18.1
+ '@typescript-eslint/visitor-keys': 6.18.1
debug: 4.3.4(supports-color@8.1.1)
globby: 11.1.0
is-glob: 4.0.3
@@ -8451,7 +8366,7 @@ packages:
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.3
- semver: 7.6.0
+ semver: 7.5.4
ts-api-utils: 1.0.3(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
@@ -8477,8 +8392,8 @@ packages:
- typescript
dev: true
- /@typescript-eslint/utils@6.21.0(eslint@8.54.0)(typescript@5.1.6):
- resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==}
+ /@typescript-eslint/utils@6.12.0(eslint@8.54.0)(typescript@5.1.6):
+ resolution: {integrity: sha512-LywPm8h3tGEbgfyjYnu3dauZ0U7R60m+miXgKcZS8c7QALO9uWJdvNoP+duKTk2XMWc7/Q3d/QiCuLN9X6SWyQ==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
@@ -8486,18 +8401,18 @@ packages:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0)
'@types/json-schema': 7.0.15
'@types/semver': 7.5.8
- '@typescript-eslint/scope-manager': 6.21.0
- '@typescript-eslint/types': 6.21.0
- '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.1.6)
+ '@typescript-eslint/scope-manager': 6.12.0
+ '@typescript-eslint/types': 6.12.0
+ '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.1.6)
eslint: 8.54.0
- semver: 7.6.0
+ semver: 7.5.4
transitivePeerDependencies:
- supports-color
- typescript
dev: true
- /@typescript-eslint/utils@6.21.0(eslint@8.57.0)(typescript@5.3.3):
- resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==}
+ /@typescript-eslint/utils@6.18.1(eslint@8.57.0)(typescript@5.3.3):
+ resolution: {integrity: sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
@@ -8505,9 +8420,9 @@ packages:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@types/json-schema': 7.0.15
'@types/semver': 7.5.8
- '@typescript-eslint/scope-manager': 6.21.0
- '@typescript-eslint/types': 6.21.0
- '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
+ '@typescript-eslint/scope-manager': 6.18.1
+ '@typescript-eslint/types': 6.18.1
+ '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3)
eslint: 8.57.0
semver: 7.6.0
transitivePeerDependencies:
@@ -8528,7 +8443,7 @@ packages:
'@typescript-eslint/types': 7.1.0
'@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3)
eslint: 8.57.0
- semver: 7.6.0
+ semver: 7.5.4
transitivePeerDependencies:
- supports-color
- typescript
@@ -8542,11 +8457,19 @@ packages:
eslint-visitor-keys: 3.4.3
dev: true
- /@typescript-eslint/visitor-keys@6.21.0:
- resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==}
+ /@typescript-eslint/visitor-keys@6.12.0:
+ resolution: {integrity: sha512-rg3BizTZHF1k3ipn8gfrzDXXSFKyOEB5zxYXInQ6z0hUvmQlhaZQzK+YmHmNViMA9HzW5Q9+bPPt90bU6GQwyw==}
engines: {node: ^16.0.0 || >=18.0.0}
dependencies:
- '@typescript-eslint/types': 6.21.0
+ '@typescript-eslint/types': 6.12.0
+ eslint-visitor-keys: 3.4.3
+ dev: true
+
+ /@typescript-eslint/visitor-keys@6.18.1:
+ resolution: {integrity: sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dependencies:
+ '@typescript-eslint/types': 6.18.1
eslint-visitor-keys: 3.4.3
dev: true
@@ -8621,7 +8544,7 @@ packages:
/@vitest/snapshot@0.34.6:
resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==}
dependencies:
- magic-string: 0.30.5
+ magic-string: 0.30.7
pathe: 1.1.2
pretty-format: 29.7.0
dev: true
@@ -9315,12 +9238,12 @@ packages:
resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==}
dev: false
- /babel-core@7.0.0-bridge.0(@babel/core@7.24.0):
+ /babel-core@7.0.0-bridge.0(@babel/core@7.23.3):
resolution: {integrity: sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.24.0
+ '@babel/core': 7.23.3
dev: true
/babel-jest@29.7.0(@babel/core@7.23.3):
@@ -9358,44 +9281,44 @@ packages:
resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@babel/template': 7.24.0
- '@babel/types': 7.24.0
+ '@babel/template': 7.22.15
+ '@babel/types': 7.23.4
'@types/babel__core': 7.20.5
'@types/babel__traverse': 7.20.4
dev: true
- /babel-plugin-polyfill-corejs2@0.4.7(@babel/core@7.24.0):
+ /babel-plugin-polyfill-corejs2@0.4.7(@babel/core@7.23.3):
resolution: {integrity: sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==}
peerDependencies:
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
dependencies:
'@babel/compat-data': 7.23.5
- '@babel/core': 7.24.0
- '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.23.3)
semver: 6.3.1
transitivePeerDependencies:
- supports-color
dev: true
- /babel-plugin-polyfill-corejs3@0.8.7(@babel/core@7.24.0):
+ /babel-plugin-polyfill-corejs3@0.8.7(@babel/core@7.23.3):
resolution: {integrity: sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==}
peerDependencies:
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.23.3)
core-js-compat: 3.34.0
transitivePeerDependencies:
- supports-color
dev: true
- /babel-plugin-polyfill-regenerator@0.5.4(@babel/core@7.24.0):
+ /babel-plugin-polyfill-regenerator@0.5.4(@babel/core@7.23.3):
resolution: {integrity: sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==}
peerDependencies:
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
dependencies:
- '@babel/core': 7.24.0
- '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.23.3)
transitivePeerDependencies:
- supports-color
dev: true
@@ -9435,7 +9358,7 @@ packages:
resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==}
engines: {node: '>= 10.0.0'}
dependencies:
- '@babel/types': 7.24.0
+ '@babel/types': 7.22.17
/bail@2.0.2:
resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
@@ -9621,7 +9544,7 @@ packages:
hasBin: true
dependencies:
caniuse-lite: 1.0.30001564
- electron-to-chromium: 1.4.686
+ electron-to-chromium: 1.4.591
node-releases: 2.0.13
update-browserslist-db: 1.0.13(browserslist@4.22.1)
dev: true
@@ -9631,8 +9554,8 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
- caniuse-lite: 1.0.30001591
- electron-to-chromium: 1.4.686
+ caniuse-lite: 1.0.30001571
+ electron-to-chromium: 1.4.616
node-releases: 2.0.14
update-browserslist-db: 1.0.13(browserslist@4.22.2)
dev: true
@@ -9642,10 +9565,11 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
- caniuse-lite: 1.0.30001591
- electron-to-chromium: 1.4.686
+ caniuse-lite: 1.0.30001594
+ electron-to-chromium: 1.4.692
node-releases: 2.0.14
update-browserslist-db: 1.0.13(browserslist@4.23.0)
+ dev: false
/bs-logger@0.2.6:
resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==}
@@ -9838,7 +9762,7 @@ packages:
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
dependencies:
browserslist: 4.23.0
- caniuse-lite: 1.0.30001591
+ caniuse-lite: 1.0.30001571
lodash.memoize: 4.1.2
lodash.uniq: 4.5.0
dev: false
@@ -9847,8 +9771,12 @@ packages:
resolution: {integrity: sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg==}
dev: true
- /caniuse-lite@1.0.30001591:
- resolution: {integrity: sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==}
+ /caniuse-lite@1.0.30001571:
+ resolution: {integrity: sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ==}
+
+ /caniuse-lite@1.0.30001594:
+ resolution: {integrity: sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==}
+ dev: false
/canonicalize@1.0.8:
resolution: {integrity: sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==}
@@ -10344,7 +10272,7 @@ packages:
resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==}
dependencies:
'@babel/parser': 7.22.16
- '@babel/types': 7.24.0
+ '@babel/types': 7.22.17
/content-disposition@0.5.4:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
@@ -10459,6 +10387,7 @@ packages:
node-fetch: 2.7.0
transitivePeerDependencies:
- encoding
+ dev: false
/cross-fetch@4.0.0:
resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==}
@@ -10836,15 +10765,9 @@ packages:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
- /deepmerge@4.2.2:
- resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
- engines: {node: '>=0.10.0'}
- dev: false
-
/deepmerge@4.3.1:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
- dev: true
/default-browser-id@3.0.0:
resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==}
@@ -11022,14 +10945,6 @@ packages:
dependencies:
domelementtype: 2.3.0
- /domutils@3.0.1:
- resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==}
- dependencies:
- dom-serializer: 2.0.0
- domelementtype: 2.3.0
- domhandler: 5.0.3
- dev: false
-
/domutils@3.1.0:
resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
dependencies:
@@ -11095,8 +11010,17 @@ packages:
dependencies:
jake: 10.8.5
- /electron-to-chromium@1.4.686:
- resolution: {integrity: sha512-3avY1B+vUzNxEgkBDpKOP8WarvUAEwpRaiCL0He5OKWEFxzaOFiq4WoZEZe7qh0ReS7DiWoHMnYoQCKxNZNzSg==}
+ /electron-to-chromium@1.4.591:
+ resolution: {integrity: sha512-vLv/P7wwAPKQoY+CVMyyI6rsTp+A14KGtPXx92oz1FY41AAqa9l6Wkizcixg0LDuJgyeo8xgNN9+9hsnGp66UA==}
+ dev: true
+
+ /electron-to-chromium@1.4.616:
+ resolution: {integrity: sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==}
+ dev: true
+
+ /electron-to-chromium@1.4.692:
+ resolution: {integrity: sha512-d5rZRka9n2Y3MkWRN74IoAsxR0HK3yaAt7T50e3iT9VZmCCQDT3geXUO5ZRMhDToa1pkCeQXuNo+0g+NfDOVPA==}
+ dev: false
/emittery@0.13.1:
resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
@@ -12905,15 +12829,6 @@ packages:
engines: {node: '>=0.10'}
dev: false
- /htmlparser2@8.0.1:
- resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==}
- dependencies:
- domelementtype: 2.3.0
- domhandler: 5.0.3
- domutils: 3.0.1
- entities: 4.5.0
- dev: false
-
/htmlparser2@8.0.2:
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
dependencies:
@@ -13557,7 +13472,7 @@ packages:
engines: {node: '>=8'}
dependencies:
'@babel/core': 7.23.3
- '@babel/parser': 7.23.6
+ '@babel/parser': 7.23.9
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.2
semver: 6.3.1
@@ -13570,7 +13485,7 @@ packages:
engines: {node: '>=10'}
dependencies:
'@babel/core': 7.23.3
- '@babel/parser': 7.23.6
+ '@babel/parser': 7.23.9
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.2
semver: 7.5.4
@@ -13969,10 +13884,10 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/core': 7.23.3
- '@babel/generator': 7.23.6
+ '@babel/generator': 7.23.4
'@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.3)
'@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.3)
- '@babel/types': 7.24.0
+ '@babel/types': 7.23.4
'@jest/expect-utils': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
@@ -14145,18 +14060,18 @@ packages:
'@babel/preset-env':
optional: true
dependencies:
- '@babel/core': 7.24.0
- '@babel/parser': 7.24.0
- '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.24.0)
- '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.24.0)
- '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.24.0)
- '@babel/preset-env': 7.23.6(@babel/core@7.24.0)
- '@babel/preset-flow': 7.23.3(@babel/core@7.24.0)
- '@babel/preset-typescript': 7.23.3(@babel/core@7.24.0)
- '@babel/register': 7.22.15(@babel/core@7.24.0)
- babel-core: 7.0.0-bridge.0(@babel/core@7.24.0)
+ '@babel/core': 7.23.3
+ '@babel/parser': 7.23.9
+ '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.3)
+ '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.3)
+ '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.23.3)
+ '@babel/preset-env': 7.23.6(@babel/core@7.23.3)
+ '@babel/preset-flow': 7.23.3(@babel/core@7.23.3)
+ '@babel/preset-typescript': 7.23.3(@babel/core@7.23.3)
+ '@babel/register': 7.22.15(@babel/core@7.23.3)
+ babel-core: 7.0.0-bridge.0(@babel/core@7.23.3)
chalk: 4.1.2
flow-parser: 0.202.0
graceful-fs: 4.2.11
@@ -14629,7 +14544,6 @@ packages:
engines: {node: '>=12'}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
- dev: true
/magic-string@0.30.7:
resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==}
@@ -17211,8 +17125,8 @@ packages:
engines: {node: '>=16.14.0'}
dependencies:
'@babel/core': 7.23.3
- '@babel/traverse': 7.24.0
- '@babel/types': 7.24.0
+ '@babel/traverse': 7.23.4
+ '@babel/types': 7.23.4
'@types/babel__core': 7.20.5
'@types/babel__traverse': 7.20.4
'@types/doctrine': 0.0.9
@@ -17733,9 +17647,9 @@ packages:
/sanitize-html@2.12.1:
resolution: {integrity: sha512-Plh+JAn0UVDpBRP/xEjsk+xDCoOvMBwQUf/K+/cBAVuTbtX8bj2VB7S1sL1dssVpykqp0/KPSesHrqXtokVBpA==}
dependencies:
- deepmerge: 4.2.2
+ deepmerge: 4.3.1
escape-string-regexp: 4.0.0
- htmlparser2: 8.0.1
+ htmlparser2: 8.0.2
is-plain-object: 5.0.0
parse-srcset: 1.0.2
postcss: 8.4.35
@@ -19449,6 +19363,7 @@ packages:
browserslist: 4.23.0
escalade: 3.1.1
picocolors: 1.0.0
+ dev: false
/uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
@@ -19627,7 +19542,7 @@ packages:
peerDependencies:
vitest: '>=0.16.0'
dependencies:
- cross-fetch: 3.1.6
+ cross-fetch: 3.1.5
vitest: 0.34.6(happy-dom@13.6.2)(sass@1.71.1)(terser@5.28.1)
transitivePeerDependencies:
- encoding
@@ -19770,6 +19685,10 @@ packages:
resolution: {integrity: sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==}
dev: true
+ /vue-component-type-helpers@2.0.6:
+ resolution: {integrity: sha512-qdGXCtoBrwqk1BT6r2+1Wcvl583ZVkuSZ3or7Y1O2w5AvWtlvvxwjGhmz5DdPJS9xqRdDlgTJ/38ehWnEi0tFA==}
+ dev: true
+
/vue-demi@0.14.7(vue@3.4.21):
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
engines: {node: '>=12'}
@@ -19790,8 +19709,8 @@ packages:
peerDependencies:
vue: '>=2'
dependencies:
- '@babel/parser': 7.24.0
- '@babel/types': 7.24.0
+ '@babel/parser': 7.23.9
+ '@babel/types': 7.23.4
'@vue/compiler-dom': 3.4.18
'@vue/compiler-sfc': 3.4.21
ast-types: 0.16.1
@@ -20056,7 +19975,7 @@ packages:
engines: {node: '>= 10.0.0'}
dependencies:
'@babel/parser': 7.22.16
- '@babel/types': 7.24.0
+ '@babel/types': 7.22.17
assert-never: 1.2.1
babel-walk: 3.0.0-canary-5