1
0
mirror of https://github.com/MisskeyIO/misskey synced 2025-01-24 02:33:48 +09:00

use biome

This commit is contained in:
あわわわとーにゅ 2024-11-24 22:27:58 +09:00
parent b4865fd9ae
commit 8f0710aac3
No known key found for this signature in database
GPG Key ID: 6AFBBF529601C1DB
71 changed files with 523 additions and 1594 deletions

View File

@ -13,14 +13,7 @@
"postCreateCommand": "sudo chmod 755 .devcontainer/init.sh && .devcontainer/init.sh",
"customizations": {
"vscode": {
"extensions": [
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint",
"Vue.volar",
"Orta.vscode-jest",
"dbaeumer.vscode-eslint",
"mrmlnc.vscode-json5"
]
"extensions": ["biomejs.biome", "editorconfig.editorconfig", "Vue.volar", "Orta.vscode-jest", "mrmlnc.vscode-json5"]
}
}
}

View File

@ -11,5 +11,5 @@ trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
[*.{json,yml,yaml}]
indent_style = space

View File

@ -11,14 +11,12 @@ on:
- packages/frontend/**
- packages/sw/**
- packages/misskey-js/**
- packages/shared/.eslintrc.js
pull_request:
paths:
- packages/backend/**
- packages/frontend/**
- packages/sw/**
- packages/misskey-js/**
- packages/shared/.eslintrc.js
jobs:
pnpm_install:
@ -63,7 +61,7 @@ jobs:
cache: 'pnpm'
- run: corepack enable
- run: pnpm i --frozen-lockfile
- run: pnpm --filter ${{ matrix.workspace }} run eslint
- run: pnpm --filter ${{ matrix.workspace }} run biome ci --reporter=github --max-diagnostics=none
typecheck:
needs: [pnpm_install]

View File

@ -1,9 +1,3 @@
{
"recommendations": [
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint",
"Vue.volar",
"Orta.vscode-jest",
"mrmlnc.vscode-json5"
]
"recommendations": ["biomejs.biome", "editorconfig.editorconfig", "Vue.volar", "Orta.vscode-jest", "mrmlnc.vscode-json5"]
}

154
biome.json Normal file
View File

@ -0,0 +1,154 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
"files": {
"ignore": [
"*.min.js",
"api.json",
"built",
"nsfw-model",
"packages/backend/built",
"packages/backend/nsfw-model",
"packages/frontend/built",
"packages/sw/built",
"packages/misskey-js/built",
"packages/misskey-reversi/built",
"packages/misskey-bubble-game/built",
"locales/index.d.ts",
"packages/misskey-js/generator/api.json"
]
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"ignore": ["packages/misskey-js/src/autogen"],
"rules": {
"recommended": true,
"complexity": {
"noForEach": "info",
"noUselessConstructor": {
"level": "info",
"fix": "none"
},
"noUselessLabel": {
"level": "info",
"fix": "none"
},
"noUselessUndefinedInitialization": {
"level": "info",
"fix": "none"
},
"useArrowFunction": {
"level": "info",
"fix": "none"
},
"useLiteralKeys": {
"level": "info",
"fix": "none"
},
"useOptionalChain": {
"level": "info",
"fix": "none"
}
},
"performance": {
"noDelete": {
"level": "info",
"fix": "none"
}
},
"style": {
"noCommaOperator": "warn",
"noNegationElse": {
"level": "off",
"fix": "none"
},
"noNonNullAssertion": {
"level": "info",
"fix": "none"
},
"noParameterAssign": "info",
"noUselessElse": {
"level": "info",
"fix": "none"
},
"useImportType": {
"level": "off",
"fix": "none"
},
"useNodejsImportProtocol": {
"level": "off",
"fix": "none"
},
"useTemplate": {
"level": "warn",
"fix": "safe"
}
},
"suspicious": {
"noAssignInExpressions": "info",
"noConfusingVoidType": {
"level": "warn",
"fix": "none"
},
"noDoubleEquals": {
"level": "warn",
"fix": "none",
"options": {
"ignoreNull": false
}
},
"noExplicitAny": "warn",
"noImplicitAnyLet": "warn"
}
}
},
"formatter": {
"enabled": true,
"lineWidth": 140,
"useEditorconfig": true
},
"javascript": {
"formatter": {
"arrowParentheses": "asNeeded",
"quoteStyle": "single"
},
"parser": {
"unsafeParameterDecoratorsEnabled": true
}
},
"overrides": [
{
"include": ["packages/backend/migration/*.js", "migration/*.js"],
"linter": {
"rules": {
"style": {
"noUnusedTemplateLiteral": {
"level": "off",
"fix": "none"
}
}
}
}
},
{
"include": ["*.vue"],
"linter": {
"rules": {
"style": {
"useConst": {
"level": "off",
"fix": "none"
},
"useImportType": {
"level": "off",
"fix": "none"
}
}
}
}
}
]
}

15
lefthook.yml Normal file
View File

@ -0,0 +1,15 @@
# Refer for explanation to following link:
# https://github.com/evilmartians/lefthook/blob/master/docs/configuration.md
pre-push:
commands:
check:
glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc,pug,vue}"
run: pnpm dlx @biomejs/biome check --no-errors-on-unmatched --files-ignore-unknown=true --colors=off --diagnostic-level=error {push_files}
pre-commit:
commands:
check:
glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc,pug,vue}"
run: pnpm dlx @biomejs/biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off --diagnostic-level=error {staged_files}
stage_fixed: true

View File

@ -5,13 +5,16 @@
import * as fs from 'node:fs';
import * as yaml from 'js-yaml';
const merge = (...args) => args.reduce((a, c) => ({
...a,
...c,
...Object.entries(a)
.filter(([k]) => c && typeof c[k] === 'object')
.reduce((a, [k, v]) => (a[k] = merge(v, c[k]), a), {})
}), {});
const merge = (...args) => args.reduce((a, c) => {
for (const [k, v] of Object.entries(c)) {
if (typeof v === 'object' && typeof a[k] === 'object') {
a[k] = merge(a[k], v);
} else {
a[k] = v;
}
}
return a;
}, {});
const languages = [
'ar-SA',

View File

@ -6,7 +6,7 @@
"type": "git",
"url": "https://github.com/MisskeyIO/misskey.git"
},
"packageManager": "pnpm@9.12.3",
"packageManager": "pnpm@9.14.2",
"workspaces": [
"packages/frontend",
"packages/backend",
@ -33,6 +33,8 @@
"migrateandstart:docker": "pnpm migrate && exec pnpm start:docker",
"watch": "pnpm dev",
"dev": "node scripts/dev.mjs",
"biome": "biome",
"format": "biome check --write",
"lint": "pnpm -r lint",
"cy:open": "pnpm cypress open --browser --e2e --config-file=cypress.config.ts",
"cy:run": "pnpm cypress run",
@ -68,12 +70,11 @@
"typescript": "5.6.3"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/node": "22.9.1",
"@typescript-eslint/eslint-plugin": "7.10.0",
"@typescript-eslint/parser": "7.10.0",
"cross-env": "7.0.3",
"cypress": "13.16.0",
"eslint": "8.57.1",
"lefthook": "1.8.4",
"ncp": "2.0.0",
"start-server-and-test": "2.0.8"
},

View File

@ -1,4 +0,0 @@
node_modules
/built
/.eslintrc.js
/@types/**/*

View File

@ -1,32 +0,0 @@
module.exports = {
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json', './test/tsconfig.json'],
},
extends: [
'../shared/.eslintrc.js',
],
rules: {
'import/order': ['warn', {
'groups': ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
'pathGroups': [
{
'pattern': '@/**',
'group': 'external',
'position': 'after'
}
],
}],
'no-restricted-globals': [
'error',
{
'name': '__dirname',
'message': 'Not in ESModule. Use `import.meta.url` instead.'
},
{
'name': '__filename',
'message': 'Not in ESModule. Use `import.meta.url` instead.'
}
]
},
};

View File

@ -20,8 +20,9 @@
"restart": "pnpm build && pnpm start",
"dev": "nodemon -w src -e ts,js,mjs,cjs,json --exec \"cross-env NODE_ENV=development pnpm run restart\"",
"typecheck": "tsc --noEmit && tsc -p test --noEmit",
"eslint": "eslint --quiet \"src/**/*.ts\"",
"lint": "pnpm typecheck && pnpm eslint",
"biome": "biome",
"format": "biome check --write",
"lint": "pnpm typecheck && biome check",
"jest": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.unit.cjs",
"jest:e2e": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.e2e.cjs",
"jest-and-coverage": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit --config jest.config.unit.cjs",
@ -191,8 +192,8 @@
"xmlbuilder": "15.1.1"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@jest/globals": "29.7.0",
"@misskey-dev/eslint-plugin": "1.0.0",
"@nestjs/platform-express": "10.4.8",
"@simplewebauthn/types": "11.0.0",
"@swc/jest": "0.2.37",
@ -234,12 +235,8 @@
"@types/vary": "1.1.3",
"@types/web-push": "3.6.4",
"@types/ws": "8.5.13",
"@typescript-eslint/eslint-plugin": "7.10.0",
"@typescript-eslint/parser": "7.10.0",
"aws-sdk-client-mock": "4.1.0",
"cross-env": "7.0.3",
"eslint": "8.57.1",
"eslint-plugin-import": "2.31.0",
"execa": "9.5.1",
"fkill": "^9.0.0",
"jest": "29.7.0",

View File

@ -273,7 +273,9 @@ export class FileInfoService {
watcher.close();
});
command.run();
for (let i = 1; true; i++) { // eslint-disable-line @typescript-eslint/no-unnecessary-condition
let i = 0;
while (true) {
i++;
const current = `${i}.png`;
const next = `${i + 1}.png`;
const framePath = join(cwd, current);

View File

@ -34,6 +34,7 @@ type PrivateKey = {
keyId: string;
};
// biome-ignore lint/complexity/noStaticOnlyClass: utility class
export class ApRequestCreator {
static createSignedPost(args: { key: PrivateKey, url: string, body: string, digest?: string, additionalHeaders: Record<string, string> }): Signed {
const u = new URL(args.url);

View File

@ -20,8 +20,7 @@ export function bindThis(target: any, key: string, descriptor: any) {
return {
configurable: true,
get() {
// eslint-disable-next-line no-prototype-builtins
if (this === target.prototype || this.hasOwnProperty(key) ||
if (this === target.prototype || Object.hasOwn(this, key) ||
typeof fn !== 'function') {
return fn;
}

View File

@ -14,6 +14,7 @@ export function parse(acct: string): Acct {
return { username: split[0], host: split[1] ?? null };
}
// biome-ignore lint/suspicious/noShadowRestrictedNames: desired behavior
export function toString(acct: Acct): string {
return acct.host == null ? acct.username : `${acct.username}@${acct.host}`;
}

View File

@ -4,5 +4,6 @@
*/
export function safeForSql(text: string): boolean {
// biome-ignore lint/suspicious/noControlCharactersInRegex: expected behavior
return !/[\0\x08\x09\x1a\n\r"'\\\%]/g.test(text);
}

View File

@ -121,6 +121,7 @@ export class ExportCustomEmojisProcessorService {
metaStream.end();
// Create archive
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: desired behavior
await new Promise<void>(async (resolve) => {
const [archivePath, archiveCleanup] = await createTemp();
const archiveStream = fs.createWriteStream(archivePath);

View File

@ -225,6 +225,7 @@ export const paramDef = {
},
},
},
// biome-ignore lint/suspicious/noThenProperty: api design
then: {
properties: {
text: {

View File

@ -195,7 +195,7 @@ function getQueryMode(issuerUrl: string): oauth2orize.grant.Options['modes'] {
parsed.searchParams.append(key, value as string);
}
return (res as OAuthHttpResponse).redirect(parsed.toString());
(res as OAuthHttpResponse).redirect(parsed.toString());
},
};
}

View File

@ -5,7 +5,7 @@
*/
* {
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
font-family: 'Fira code', 'Fira Mono', Consolas, Menlo, Courier, monospace;
}
html {

View File

@ -33,7 +33,7 @@
}
//#region Detect language & fetch translations
if (!localStorage.hasOwnProperty('locale')) {
if (!Object.hasOwn(localStorage, 'locale')) {
let lang = localStorage.getItem('lang');
if (lang == null || lang.toString == null || lang.toString() === 'null') {
lang = 'ja-JP';

View File

@ -5,7 +5,7 @@
*/
* {
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
font-family: 'Fira code', 'Fira Mono', Consolas, Menlo, Courier, monospace;
}
html {

View File

@ -39,7 +39,7 @@ message('Start flushing.');
console.error(e);
setTimeout(() => {
location = '/';
window.location = '/';
}, 10000)
}
})();

View File

@ -1,32 +0,0 @@
module.exports = {
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
extends: [
'../../shared/.eslintrc.js',
],
rules: {
'import/order': ['warn', {
'groups': ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
'pathGroups': [
{
'pattern': '@/**',
'group': 'external',
'position': 'after'
}
],
}],
'no-restricted-globals': [
'error',
{
'name': '__dirname',
'message': 'Not in ESModule. Use `import.meta.url` instead.'
},
{
'name': '__filename',
'message': 'Not in ESModule. Use `import.meta.url` instead.'
}
]
},
};

View File

@ -9,7 +9,7 @@
"noFallthroughCasesInSwitch": true,
"declaration": false,
"sourceMap": true,
"target": "ES2022",
"target": "es2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"allowSyntheticDefaultImports": true,

View File

@ -1,11 +0,0 @@
module.exports = {
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
extends: ['../.eslintrc.cjs'],
env: {
node: true,
jest: true,
},
};

View File

@ -54,7 +54,9 @@ describe('Note thread mute', () => {
assert.strictEqual(res.body.hasUnreadMentions, false);
});
test('ミュートしているスレッドからメンションされても、ストリームに unreadMention イベントが流れてこない', () => new Promise<void>(async done => {
test('ミュートしているスレッドからメンションされても、ストリームに unreadMention イベントが流れてこない', () =>
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: desired behavior
new Promise<void>(async done => {
// 状態リセット
await api('i/read-all-unread-notes', {}, alice);

View File

@ -9,7 +9,7 @@
"noFallthroughCasesInSwitch": true,
"declaration": false,
"sourceMap": true,
"target": "ES2022",
"target": "es2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"allowSyntheticDefaultImports": true,

View File

@ -9,7 +9,7 @@ import httpSignature from '@peertube/http-signature';
import { genRsaKeyPair } from '@/misc/gen-key-pair.js';
import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js';
export const buildParsedSignature = (signingString: string, signature: string, algorithm: string) => {
const buildParsedSignature = (signingString: string, signature: string, algorithm: string) => {
return {
scheme: 'Signature',
params: {

View File

@ -388,6 +388,7 @@ export function connectStream<C extends keyof misskey.Channels>(user: UserToken,
}
export const waitFire = async <C extends keyof misskey.Channels>(user: UserToken, channel: C, trgr: () => any, cond: (msg: Record<string, any>) => boolean, params?: misskey.Channels[C]['params']) => {
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: desired behavior
return new Promise<boolean>(async (res, rej) => {
let timer: NodeJS.Timeout | null = null;
@ -437,6 +438,7 @@ export function makeStreamCatcher<T>(
extractor: (message: Record<string, any>) => T,
timeout = 60 * 1000): Promise<T> {
let ws: WebSocket;
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: desired behavior
const p = new Promise<T>(async (resolve) => {
ws = await connectStream(user, channel, (msg) => {
if (cond(msg)) {

View File

@ -9,7 +9,7 @@
"noFallthroughCasesInSwitch": true,
"declaration": false,
"sourceMap": false,
"target": "ES2022",
"target": "es2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"allowSyntheticDefaultImports": true,

View File

@ -1,82 +0,0 @@
module.exports = {
root: true,
env: {
'node': false,
},
parser: 'vue-eslint-parser',
parserOptions: {
'parser': '@typescript-eslint/parser',
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
extraFileExtensions: ['.vue'],
},
extends: [
'../shared/.eslintrc.js',
'plugin:vue/vue3-recommended',
],
rules: {
'@typescript-eslint/no-empty-interface': [
'error',
{
'allowSingleExtends': true,
},
],
// window の禁止理由: グローバルスコープと衝突し、予期せぬ結果を招くため
// e の禁止理由: error や event など、複数のキーワードの頭文字であり分かりにくいため
'id-denylist': ['error', 'window', 'e'],
'no-shadow': ['warn'],
'vue/attributes-order': ['error', {
'alphabetical': false,
}],
'vue/no-use-v-if-with-v-for': ['error', {
'allowUsingIterationVar': false,
}],
'vue/no-ref-as-operand': 'error',
'vue/no-multi-spaces': ['error', {
'ignoreProperties': false,
}],
'vue/no-v-html': 'warn',
'vue/order-in-components': 'error',
'vue/html-indent': ['warn', 'tab', {
'attribute': 1,
'baseIndent': 0,
'closeBracket': 0,
'alignAttributesVertically': true,
'ignores': [],
}],
'vue/html-closing-bracket-spacing': ['warn', {
'startTag': 'never',
'endTag': 'never',
'selfClosingTag': 'never',
}],
'vue/multi-word-component-names': 'warn',
'vue/require-v-for-key': 'warn',
'vue/no-unused-components': 'warn',
'vue/no-unused-vars': 'warn',
'vue/no-dupe-keys': 'warn',
'vue/valid-v-for': 'warn',
'vue/return-in-computed-property': 'warn',
'vue/no-setup-props-destructure': 'warn',
'vue/max-attributes-per-line': 'off',
'vue/html-self-closing': 'off',
'vue/singleline-html-element-content-newline': 'off',
'vue/v-on-event-hyphenation': ['error', 'never', { autofix: true }],
'vue/attribute-hyphenation': ['error', 'never'],
},
globals: {
// Node.js
'module': false,
'require': false,
'__dirname': false,
// Misskey
'_DEV_': false,
'_LANGS_': false,
'_VERSION_': false,
'_ENV_': false,
'_PERF_PREFIX_': false,
'_DATA_TRANSFER_DRIVE_FILE_': false,
'_DATA_TRANSFER_DRIVE_FOLDER_': false,
'_DATA_TRANSFER_DECK_COLUMN_': false,
},
};

View File

@ -2,10 +2,5 @@
"typescript.tsdk": "node_modules\\typescript\\lib",
"path-intellisense.mappings": {
"@": "${workspaceRoot}/packages/frontend/src/"
},
"eslint.validate": [
"javascript",
"javascriptreact",
"vue"
]
}
}

View File

@ -3,7 +3,6 @@
"scope": "typescript",
"prefix": "storyimpl",
"body": [
"/* eslint-disable @typescript-eslint/explicit-function-return-type */",
"import { StoryObj } from '@storybook/vue3';",
"import $1 from './$1.vue';",
"export const Default = {",
@ -41,7 +40,6 @@
"scope": "typescript",
"prefix": "storyimplevent",
"body": [
"/* eslint-disable @typescript-eslint/explicit-function-return-type */",
"import { action } from '@storybook/addon-actions';",
"import { StoryObj } from '@storybook/vue3';",
"import $1 from './$1.vue';",

View File

@ -13,8 +13,9 @@
"test": "vitest --run --globals",
"test-and-coverage": "vitest --run --coverage --globals",
"typecheck": "vue-tsc --noEmit",
"eslint": "eslint --quiet \"src/**/*.{ts,vue}\"",
"lint": "pnpm typecheck && pnpm eslint"
"biome": "biome",
"format": "biome check --write",
"lint": "pnpm typecheck && biome check"
},
"dependencies": {
"@discordapp/twemoji": "15.1.0",
@ -79,7 +80,7 @@
"vuedraggable": "next"
},
"devDependencies": {
"@misskey-dev/eslint-plugin": "1.0.0",
"@biomejs/biome": "1.9.4",
"@misskey-dev/summaly": "MisskeyIO/summaly#5.1.1",
"@storybook/addon-actions": "8.4.5",
"@storybook/addon-essentials": "8.4.5",
@ -110,16 +111,11 @@
"@types/throttle-debounce": "5.0.2",
"@types/tinycolor2": "1.4.6",
"@types/ws": "8.5.13",
"@typescript-eslint/eslint-plugin": "7.10.0",
"@typescript-eslint/parser": "7.10.0",
"@vitest/coverage-v8": "2.1.5",
"@vue/runtime-core": "3.5.13",
"acorn": "8.14.0",
"cross-env": "7.0.3",
"cypress": "13.16.0",
"eslint": "8.57.1",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-vue": "9.31.0",
"fast-glob": "3.3.2",
"happy-dom": "15.11.6",
"intersection-observer": "0.12.2",
@ -137,7 +133,6 @@
"vitest": "2.1.5",
"vitest-fetch-mock": "0.3.0",
"vue-component-type-helpers": "2.1.10",
"vue-eslint-parser": "9.4.3",
"vue-tsc": "2.1.10"
}
}

View File

@ -62,6 +62,7 @@ let cropper: Cropper | null = null;
const loading = ref(true);
const ok = async () => {
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: desired behavior
const promise = new Promise<Misskey.entities.DriveFile>(async (res) => {
const croppedImage = await cropper?.getCropperImage();
const croppedSection = await cropper?.getCropperSelection();

View File

@ -288,7 +288,7 @@ const keymap = {
'down|j|tab': focusAfter,
'esc': blur,
'm|o': () => showMenu(true),
's': () => showContent.value !== showContent.value,
's': () => { showContent.value = !showContent.value; focus(); },
};
provide('react', (reaction: string) => {

View File

@ -305,7 +305,7 @@ const keymap = {
'q': () => renote(true),
'esc': blur,
'm|o': () => showMenu(true),
's': () => showContent.value !== showContent.value,
's': () => { showContent.value = !showContent.value; focus(); },
};
provide('react', (reaction: string) => {

View File

@ -53,7 +53,10 @@ const props = withDefaults(defineProps<{
const dialog = shallowRef<InstanceType<typeof MkModalWindow>>();
const typesMap: TypesMap = notificationTypes.reduce((p, t) => ({ ...p, [t]: ref<boolean>(!props.excludeTypes.includes(t)) }), {} as any);
const typesMap: TypesMap = notificationTypes.reduce((p, t) => {
p[t] = ref<boolean>(!props.excludeTypes.includes(t));
return p;
}, {});
function ok() {
emit('done', {

View File

@ -116,16 +116,15 @@ function get(): PollEditorModelValue {
};
const calcAfter = () => {
let base = parseInt(after.value.toString());
let base = Number.parseInt(after.value.toString());
switch (unit.value) {
// @ts-expect-error fallthrough
// biome-ignore lint/suspicious/noFallthroughSwitchClause: desired behavior
case 'day': base *= 24;
// @ts-expect-error fallthrough
// biome-ignore lint/suspicious/noFallthroughSwitchClause: desired behavior
case 'hour': base *= 60;
// @ts-expect-error fallthrough
// biome-ignore lint/suspicious/noFallthroughSwitchClause: desired behavior
case 'minute': base *= 60;
// eslint-disable-next-line no-fallthrough
case 'second': return base *= 1000;
case 'second': return base * 1000;
default: return null;
}
};

View File

@ -60,9 +60,7 @@ const props = withDefaults(defineProps<{
tabs: () => ([] as Tab[]),
});
const emit = defineEmits<{
(ev: 'update:tab', key: string);
}>();
const emit = defineEmits<(ev: 'update:tab', key: string) => void>();
const pageMetadata = injectReactiveMetadata();

View File

@ -302,8 +302,12 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
}
if (route.query != null && queryString != null) {
const queryObject = [...new URLSearchParams(queryString).entries()]
.reduce((obj, entry) => ({ ...obj, [entry[0]]: entry[1] }), {});
const queryObject = [
...new URLSearchParams(queryString).entries(),
].reduce((obj, entry) => {
obj[entry[0]] = entry[1];
return obj;
}, {});
for (const q in route.query) {
const as = route.query[q];

View File

@ -61,9 +61,7 @@ const props = defineProps<{
thin?: boolean;
}>();
const emit = defineEmits<{
(ev: 'update:tab', key: string);
}>();
const emit = defineEmits<(ev: 'update:tab', key: string) => void>();
const pageMetadata = injectReactiveMetadata();

View File

@ -543,6 +543,7 @@ interface Watcher {
import lightTheme from '@/themes/l-light.json5';
import darkTheme from '@/themes/d-green-lime.json5';
// biome-ignore lint/complexity/noStaticOnlyClass: utility class
export class ColdDeviceStorage {
public static default = {
lightTheme,

View File

@ -305,8 +305,6 @@
"👸": ["girl", "woman", "female", "blond", "crown", "royal", "queen"],
"🤴": ["boy", "man", "male", "crown", "royal", "king"],
"👰": ["couple", "marriage", "wedding", "woman", "bride"],
"👰": ["couple", "marriage", "wedding", "woman", "bride"],
"🤵": ["couple", "marriage", "wedding", "groom"],
"🤵": ["couple", "marriage", "wedding", "groom"],
"🏃‍♀️": ["woman", "walking", "exercise", "race", "running", "female"],
"🏃": ["man", "walking", "exercise", "race", "running"],

View File

@ -18,9 +18,7 @@ export type WidgetComponentProps<P extends Record<string, unknown>> = {
widget?: Widget<P>;
};
export type WidgetComponentEmits<P extends Record<string, unknown>> = {
(ev: 'updateProps', props: P);
};
export type WidgetComponentEmits<P extends Record<string, unknown>> = (ev: 'updateProps', props: P) => void;
export type WidgetComponentExpose = {
name: string;

View File

@ -7,6 +7,7 @@ import { render } from 'buraha';
const canvas = new OffscreenCanvas(64, 64);
// biome-ignore lint/suspicious/noGlobalAssign: web worker
onmessage = (event) => {
// console.log(event.data);
if (!('id' in event.data && typeof event.data.id === 'string')) {

View File

@ -9,7 +9,7 @@
"noFallthroughCasesInSwitch": true,
"declaration": false,
"sourceMap": true,
"target": "ES2022",
"target": "es2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"allowSyntheticDefaultImports": true,

View File

@ -9,7 +9,7 @@
"noFallthroughCasesInSwitch": true,
"declaration": false,
"sourceMap": false,
"target": "ES2022",
"target": "es2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"removeComments": false,
@ -25,29 +25,12 @@
"paths": {
"@/*": ["./src/*"]
},
"typeRoots": [
"./@types",
"./node_modules/@types",
"./node_modules/@vue-macros",
"./node_modules"
],
"types": [
"vite/client",
"vitest/importMeta",
],
"lib": [
"esnext",
"dom"
],
"typeRoots": ["./@types", "./node_modules/@types", "./node_modules/@vue-macros", "./node_modules"],
"types": ["vite/client", "vitest/importMeta"],
"lib": ["esnext", "dom"],
"jsx": "preserve"
},
"compileOnSave": false,
"include": [
".eslintrc.js",
"./**/*.ts",
"./**/*.vue"
],
"exclude": [
".storybook/**/*"
]
"include": ["./**/*.ts", "./**/*.vue"],
"exclude": [".storybook/**/*"]
}

View File

@ -1,7 +0,0 @@
node_modules
/built
/coverage
/.eslintrc.js
/jest.config.ts
/test
/test-d

View File

@ -1,9 +0,0 @@
module.exports = {
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
extends: [
'../shared/.eslintrc.js',
],
};

View File

@ -19,24 +19,20 @@
"tsc-esm": "tsc --outDir built/esm",
"tsc-dts": "tsc --outDir built/dts --declaration true --emitDeclarationOnly true --declarationMap true",
"watch": "nodemon -w src -e ts,js,cjs,mjs,json --exec \"pnpm run build:tsc\"",
"eslint": "eslint . --ext .js,.jsx,.ts,.tsx",
"typecheck": "tsc --noEmit",
"lint": "pnpm typecheck && pnpm eslint"
"biome": "biome",
"format": "biome check --write",
"lint": "pnpm typecheck && biome check"
},
"devDependencies": {
"@misskey-dev/eslint-plugin": "1.0.0",
"@biomejs/biome": "1.9.4",
"@types/matter-js": "0.19.7",
"@types/node": "22.9.1",
"@types/seedrandom": "3.0.8",
"@typescript-eslint/eslint-plugin": "7.10.0",
"@typescript-eslint/parser": "7.10.0",
"eslint": "8.57.1",
"nodemon": "3.1.7",
"typescript": "5.6.3"
},
"files": [
"built"
],
"files": ["built"],
"dependencies": {
"esbuild": "0.24.0",
"eventemitter3": "5.0.1",

View File

@ -204,10 +204,10 @@ export class DropAndFusionGame extends EventEmitter<{
} else if (mono.shape === 'rectangle') {
return Matter.Bodies.rectangle(x, y, mono.sizeX, mono.sizeY, options);
} else if (mono.shape === 'custom') {
return Matter.Bodies.fromVertices(x, y, mono.vertices!.map(i => i.map(j => ({
return Matter.Bodies.fromVertices(x, y, mono.vertices?.map(i => i.map(j => ({
x: (j.x / mono.verticesSize!) * mono.sizeX,
y: (j.y / mono.verticesSize!) * mono.sizeY,
}))), options);
}))) ?? [], options);
} else {
throw new Error('unrecognized shape');
}

View File

@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"target": "ES2022",
"target": "es2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"declaration": true,

View File

@ -1,7 +0,0 @@
node_modules
/built
/coverage
/.eslintrc.js
/jest.config.ts
/test
/test-d

View File

@ -1,9 +0,0 @@
module.exports = {
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
extends: [
'../shared/.eslintrc.js',
],
};

View File

@ -1,9 +0,0 @@
module.exports = {
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
extends: [
'../../shared/.eslintrc.js',
],
};

View File

@ -4,22 +4,16 @@
"description": "Misskey TypeGenerator",
"type": "module",
"scripts": {
"generate": "tsx src/generator.ts && eslint ./built/**/* --ext .ts --fix"
"generate": "tsx src/generator.ts"
},
"devDependencies": {
"@misskey-dev/eslint-plugin": "^1.0.0",
"@readme/openapi-parser": "2.6.0",
"@types/node": "22.9.1",
"@typescript-eslint/eslint-plugin": "7.10.0",
"@typescript-eslint/parser": "7.10.0",
"eslint": "8.57.1",
"openapi-types": "12.1.3",
"openapi-typescript": "6.7.6",
"ts-case-convert": "2.1.0",
"tsx": "4.19.2",
"typescript": "5.6.3"
},
"files": [
"built"
]
"files": ["built"]
}

View File

@ -23,26 +23,24 @@
"tsd": "tsd",
"api": "pnpm api-extractor run --local --verbose",
"api-prod": "pnpm api-extractor run --verbose",
"eslint": "eslint . --ext .js,.jsx,.ts,.tsx",
"typecheck": "tsc --noEmit",
"lint": "pnpm typecheck && pnpm eslint",
"biome": "biome",
"format": "biome check --write",
"lint": "pnpm typecheck && biome check",
"jest": "jest --coverage --detectOpenHandles",
"test": "pnpm jest && pnpm tsd",
"update-autogen-code": "pnpm --filter misskey-js-type-generator generate && ncp generator/built/autogen src/autogen"
"update-autogen-code": "pnpm --filter misskey-js-type-generator generate && ncp generator/built/autogen src/autogen && biome check --write --unsafe --diagnostic-level=error src/autogen"
},
"repository": {
"type": "git",
"url": "git+https://github.com/misskey-dev/misskey.js.git"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@microsoft/api-extractor": "7.47.12",
"@misskey-dev/eslint-plugin": "1.0.0",
"@swc/jest": "0.2.37",
"@types/jest": "29.5.14",
"@types/node": "22.9.1",
"@typescript-eslint/eslint-plugin": "7.10.0",
"@typescript-eslint/parser": "7.10.0",
"eslint": "8.57.1",
"jest": "29.7.0",
"jest-fetch-mock": "3.0.3",
"jest-websocket-mock": "2.5.0",
@ -52,11 +50,7 @@
"tsd": "0.31.2",
"typescript": "5.6.3"
},
"files": [
"built",
"built/esm",
"built/dts"
],
"files": ["built", "built/esm", "built/dts"],
"dependencies": {
"@swc/cli": "0.5.1",
"@swc/core": "1.9.3",

View File

@ -9,6 +9,7 @@ export function parse(acct: string): Acct {
return { username: split[0], host: split[1] || null };
}
// biome-ignore lint/suspicious/noShadowRestrictedNames: desired behavior
export function toString(acct: Acct): string {
return acct.host == null ? acct.username : `${acct.username}@${acct.host}`;
}

View File

@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"target": "ES2022",
"target": "es2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"declaration": true,

View File

@ -1,7 +0,0 @@
node_modules
/built
/coverage
/.eslintrc.js
/jest.config.ts
/test
/test-d

View File

@ -1,10 +0,0 @@
module.exports = {
root: true,
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
extends: [
'../shared/.eslintrc.js',
],
};

View File

@ -19,16 +19,14 @@
"tsc-esm": "tsc --outDir built/esm",
"tsc-dts": "tsc --outDir built/dts --declaration true --emitDeclarationOnly true --declarationMap true",
"watch": "nodemon -w src -e ts,js,cjs,mjs,json --exec \"pnpm run build:tsc\"",
"eslint": "eslint . --ext .js,.jsx,.ts,.tsx",
"typecheck": "tsc --noEmit",
"lint": "pnpm typecheck && pnpm eslint"
"biome": "biome",
"format": "biome check --write",
"lint": "pnpm typecheck && biome check"
},
"devDependencies": {
"@misskey-dev/eslint-plugin": "1.0.0",
"@biomejs/biome": "1.9.4",
"@types/node": "22.9.1",
"@typescript-eslint/eslint-plugin": "7.10.0",
"@typescript-eslint/parser": "7.10.0",
"eslint": "8.57.1",
"nodemon": "3.1.7",
"typescript": "5.6.3"
},
@ -37,7 +35,5 @@
"esbuild": "0.24.0",
"glob": "11.0.0"
},
"files": [
"built"
]
"files": ["built"]
}

View File

@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"target": "ES2022",
"target": "es2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"declaration": true,

View File

@ -1,7 +0,0 @@
module.exports = {
root: true,
ignorePatterns: ['**/.eslintrc.cjs'],
extends: [
'plugin:@misskey-dev/recommended',
],
};

View File

@ -1,20 +0,0 @@
module.exports = {
root: true,
env: {
node: false,
},
parserOptions: {
parser: '@typescript-eslint/parser',
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
extends: ['../shared/.eslintrc.js'],
globals: {
require: false,
_DEV_: false,
_LANGS_: false,
_VERSION_: false,
_ENV_: false,
_PERF_PREFIX_: false,
},
};

View File

@ -5,8 +5,9 @@
"watch": "nodemon -w ../../package.json -e json --exec \"node build.js watch\"",
"build": "node build.js",
"typecheck": "tsc --noEmit",
"eslint": "eslint --quiet src/**/*.ts",
"lint": "pnpm typecheck && pnpm eslint"
"biome": "biome",
"format": "biome check --write",
"lint": "pnpm typecheck && biome check"
},
"dependencies": {
"esbuild": "0.24.0",
@ -14,11 +15,8 @@
"misskey-js": "workspace:*"
},
"devDependencies": {
"@misskey-dev/eslint-plugin": "1.0.0",
"@biomejs/biome": "1.9.4",
"@types/serviceworker": "0.0.105",
"@typescript-eslint/parser": "7.10.0",
"eslint": "8.57.1",
"eslint-plugin-import": "2.31.0",
"nodemon": "3.1.7",
"typescript": "5.6.3"
},

View File

@ -250,6 +250,7 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif
}
export async function createEmptyNotification(): Promise<void> {
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: desired behavior
return new Promise<void>(async res => {
const i18n = await (swLang.i18n ?? swLang.fetchLocale());
const { t } = i18n;

View File

@ -9,7 +9,7 @@
"noFallthroughCasesInSwitch": true,
"declaration": false,
"sourceMap": false,
"target": "ES2022",
"target": "es2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"removeComments": false,

1428
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff