forked from FoundKeyGang/FoundKey
Merge branch 'develop'
This commit is contained in:
commit
090f8eff67
39 changed files with 315 additions and 112 deletions
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
|
@ -16,7 +16,7 @@ jobs:
|
||||||
submodules: true
|
submodules: true
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 12.x
|
node-version: 16.x
|
||||||
- uses: actions/cache@v2
|
- uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: '**/node_modules'
|
path: '**/node_modules'
|
||||||
|
|
|
@ -10,6 +10,12 @@
|
||||||
You should also include the user name that made the change.
|
You should also include the user name that made the change.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
## 12.109.2 (2022/04/03)
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
- API: admin/update-meta was not working @syuilo
|
||||||
|
- Client: テーマを切り替えたり読み込んだりするとmeta[name="theme-color"]のcontentがundefinedになる問題を修正 @tamaina
|
||||||
|
|
||||||
## 12.109.1 (2022/04/02)
|
## 12.109.1 (2022/04/02)
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "12.109.1",
|
"version": "12.109.2",
|
||||||
"codename": "indigo",
|
"codename": "indigo",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -p tsconfig.json || echo done. && tsc-alias -p tsconfig.json",
|
"build": "tsc -p tsconfig.json || echo done. && tsc-alias -p tsconfig.json",
|
||||||
"watch": "node watch.mjs",
|
"watch": "node watch.mjs",
|
||||||
"lint": "eslint --quiet src/**/*.ts",
|
"lint": "eslint --quiet 'src/**/*.ts'",
|
||||||
"mocha": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
|
"mocha": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
|
||||||
"test": "npm run mocha"
|
"test": "npm run mocha"
|
||||||
},
|
},
|
||||||
|
|
|
@ -27,6 +27,7 @@ export const packedEmojiSchema = {
|
||||||
host: {
|
host: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: true,
|
optional: false, nullable: true,
|
||||||
|
description: 'The local host is represented with `null`.',
|
||||||
},
|
},
|
||||||
url: {
|
url: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|
|
@ -21,6 +21,7 @@ export const packedUserLiteSchema = {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
nullable: true, optional: false,
|
nullable: true, optional: false,
|
||||||
example: 'misskey.example.com',
|
example: 'misskey.example.com',
|
||||||
|
description: 'The local host is represented with `null`.',
|
||||||
},
|
},
|
||||||
avatarUrl: {
|
avatarUrl: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|
|
@ -27,7 +27,12 @@ export const paramDef = {
|
||||||
untilId: { type: 'string', format: 'misskey:id' },
|
untilId: { type: 'string', format: 'misskey:id' },
|
||||||
type: { type: 'string', nullable: true, pattern: /^[a-zA-Z0-9\/\-*]+$/.toString().slice(1, -1) },
|
type: { type: 'string', nullable: true, pattern: /^[a-zA-Z0-9\/\-*]+$/.toString().slice(1, -1) },
|
||||||
origin: { type: 'string', enum: ['combined', 'local', 'remote'], default: "local" },
|
origin: { type: 'string', enum: ['combined', 'local', 'remote'], default: "local" },
|
||||||
hostname: { type: 'string', nullable: true, default: null },
|
hostname: {
|
||||||
|
type: 'string',
|
||||||
|
nullable: true,
|
||||||
|
default: null,
|
||||||
|
description: 'The local host is represented with `null`.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
required: [],
|
required: [],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -40,6 +40,7 @@ export const meta = {
|
||||||
userHost: {
|
userHost: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: true,
|
optional: false, nullable: true,
|
||||||
|
description: 'The local host is represented with `null`.',
|
||||||
},
|
},
|
||||||
md5: {
|
md5: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
@ -151,11 +152,20 @@ export const meta = {
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
anyOf: [
|
||||||
fileId: { type: 'string', format: 'misskey:id' },
|
{
|
||||||
url: { type: 'string' },
|
properties: {
|
||||||
},
|
fileId: { type: 'string', format: 'misskey:id' },
|
||||||
required: [],
|
},
|
||||||
|
required: ['fileId'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
url: { type: 'string' },
|
||||||
|
},
|
||||||
|
required: ['url'],
|
||||||
|
},
|
||||||
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
|
|
@ -40,6 +40,7 @@ export const meta = {
|
||||||
host: {
|
host: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: true,
|
optional: false, nullable: true,
|
||||||
|
description: 'The local host is represented with `null`.',
|
||||||
},
|
},
|
||||||
url: {
|
url: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
@ -54,7 +55,12 @@ export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
query: { type: 'string', nullable: true, default: null },
|
query: { type: 'string', nullable: true, default: null },
|
||||||
host: { type: 'string', nullable: true, default: null },
|
host: {
|
||||||
|
type: 'string',
|
||||||
|
nullable: true,
|
||||||
|
default: null,
|
||||||
|
description: 'Use `null` to represent the local host.',
|
||||||
|
},
|
||||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||||
sinceId: { type: 'string', format: 'misskey:id' },
|
sinceId: { type: 'string', format: 'misskey:id' },
|
||||||
untilId: { type: 'string', format: 'misskey:id' },
|
untilId: { type: 'string', format: 'misskey:id' },
|
||||||
|
|
|
@ -38,8 +38,9 @@ export const meta = {
|
||||||
optional: false, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
host: {
|
host: {
|
||||||
type: 'string',
|
type: 'null',
|
||||||
optional: false, nullable: true,
|
optional: false,
|
||||||
|
description: 'The local host is represented with `null`. The field exists for compatibility with other API endpoints that return files.',
|
||||||
},
|
},
|
||||||
url: {
|
url: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|
|
@ -17,7 +17,11 @@ export const paramDef = {
|
||||||
ids: { type: 'array', items: {
|
ids: { type: 'array', items: {
|
||||||
type: 'string', format: 'misskey:id',
|
type: 'string', format: 'misskey:id',
|
||||||
} },
|
} },
|
||||||
category: { type: 'string', nullable: true },
|
category: {
|
||||||
|
type: 'string',
|
||||||
|
nullable: true,
|
||||||
|
description: 'Use `null` to reset the category.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
required: ['ids'],
|
required: ['ids'],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -23,7 +23,11 @@ export const paramDef = {
|
||||||
properties: {
|
properties: {
|
||||||
id: { type: 'string', format: 'misskey:id' },
|
id: { type: 'string', format: 'misskey:id' },
|
||||||
name: { type: 'string' },
|
name: { type: 'string' },
|
||||||
category: { type: 'string', nullable: true },
|
category: {
|
||||||
|
type: 'string',
|
||||||
|
nullable: true,
|
||||||
|
description: 'Use `null` to reset the category.',
|
||||||
|
},
|
||||||
aliases: { type: 'array', items: {
|
aliases: { type: 'array', items: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
} },
|
} },
|
||||||
|
|
|
@ -26,8 +26,13 @@ export const paramDef = {
|
||||||
sort: { type: 'string', enum: ['+follower', '-follower', '+createdAt', '-createdAt', '+updatedAt', '-updatedAt'] },
|
sort: { type: 'string', enum: ['+follower', '-follower', '+createdAt', '-createdAt', '+updatedAt', '-updatedAt'] },
|
||||||
state: { type: 'string', enum: ['all', 'available', 'admin', 'moderator', 'adminOrModerator', 'silenced', 'suspended'], default: "all" },
|
state: { type: 'string', enum: ['all', 'available', 'admin', 'moderator', 'adminOrModerator', 'silenced', 'suspended'], default: "all" },
|
||||||
origin: { type: 'string', enum: ['combined', 'local', 'remote'], default: "local" },
|
origin: { type: 'string', enum: ['combined', 'local', 'remote'], default: "local" },
|
||||||
username: { type: 'string', default: null },
|
username: { type: 'string', nullable: true, default: null },
|
||||||
hostname: { type: 'string', default: null },
|
hostname: {
|
||||||
|
type: 'string',
|
||||||
|
nullable: true,
|
||||||
|
default: null,
|
||||||
|
description: 'The local host is represented with `null`.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
required: [],
|
required: [],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -397,12 +397,14 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.transaction(async transactionalEntityManager => {
|
await db.transaction(async transactionalEntityManager => {
|
||||||
const meta = await transactionalEntityManager.findOne(Meta, {
|
const metas = await transactionalEntityManager.find(Meta, {
|
||||||
order: {
|
order: {
|
||||||
id: 'DESC',
|
id: 'DESC',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const meta = metas[0];
|
||||||
|
|
||||||
if (meta) {
|
if (meta) {
|
||||||
await transactionalEntityManager.update(Meta, meta.id, set);
|
await transactionalEntityManager.update(Meta, meta.id, set);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,7 +20,7 @@ export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
name: { type: 'string', minLength: 1, maxLength: 100 },
|
name: { type: 'string', minLength: 1, maxLength: 100 },
|
||||||
isPublic: { type: 'boolean' },
|
isPublic: { type: 'boolean', default: false },
|
||||||
description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 },
|
description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 },
|
||||||
},
|
},
|
||||||
required: ['name'],
|
required: ['name'],
|
||||||
|
|
|
@ -28,22 +28,25 @@ export const meta = {
|
||||||
code: 'ACCESS_DENIED',
|
code: 'ACCESS_DENIED',
|
||||||
id: '25b73c73-68b1-41d0-bad1-381cfdf6579f',
|
id: '25b73c73-68b1-41d0-bad1-381cfdf6579f',
|
||||||
},
|
},
|
||||||
|
|
||||||
fileIdOrUrlRequired: {
|
|
||||||
message: 'fileId or url required.',
|
|
||||||
code: 'INVALID_PARAM',
|
|
||||||
id: '89674805-722c-440c-8d88-5641830dc3e4',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
anyOf: [
|
||||||
fileId: { type: 'string', format: 'misskey:id' },
|
{
|
||||||
url: { type: 'string' },
|
properties: {
|
||||||
},
|
fileId: { type: 'string', format: 'misskey:id' },
|
||||||
required: [],
|
},
|
||||||
|
required: ['fileId'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
url: { type: 'string' },
|
||||||
|
},
|
||||||
|
required: ['url'],
|
||||||
|
},
|
||||||
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
@ -62,8 +65,6 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
thumbnailUrl: ps.url,
|
thumbnailUrl: ps.url,
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
throw new ApiError(meta.errors.fileIdOrUrlRequired);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ export const meta = {
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
host: { type: 'string', nullable: true },
|
host: { type: 'string', nullable: true, description: 'Omit or use `null` to not filter by host.' },
|
||||||
blocked: { type: 'boolean', nullable: true },
|
blocked: { type: 'boolean', nullable: true },
|
||||||
notResponding: { type: 'boolean', nullable: true },
|
notResponding: { type: 'boolean', nullable: true },
|
||||||
suspended: { type: 'boolean', nullable: true },
|
suspended: { type: 'boolean', nullable: true },
|
||||||
|
|
|
@ -47,14 +47,25 @@ export const meta = {
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
userId: { type: 'string', format: 'misskey:id' },
|
|
||||||
groupId: { type: 'string', format: 'misskey:id' },
|
|
||||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||||
sinceId: { type: 'string', format: 'misskey:id' },
|
sinceId: { type: 'string', format: 'misskey:id' },
|
||||||
untilId: { type: 'string', format: 'misskey:id' },
|
untilId: { type: 'string', format: 'misskey:id' },
|
||||||
markAsRead: { type: 'boolean', default: true },
|
markAsRead: { type: 'boolean', default: true },
|
||||||
},
|
},
|
||||||
required: [],
|
anyOf: [
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
userId: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
|
required: ['userId'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
groupId: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
|
required: ['groupId'],
|
||||||
|
},
|
||||||
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
@ -126,7 +137,5 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
return await Promise.all(messages.map(message => MessagingMessages.pack(message, user, {
|
return await Promise.all(messages.map(message => MessagingMessages.pack(message, user, {
|
||||||
populateGroup: false,
|
populateGroup: false,
|
||||||
})));
|
})));
|
||||||
} else {
|
|
||||||
throw new Error();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -67,12 +67,23 @@ export const meta = {
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
userId: { type: 'string', format: 'misskey:id' },
|
|
||||||
groupId: { type: 'string', format: 'misskey:id' },
|
|
||||||
text: { type: 'string', nullable: true, maxLength: 3000 },
|
text: { type: 'string', nullable: true, maxLength: 3000 },
|
||||||
fileId: { type: 'string', format: 'misskey:id' },
|
fileId: { type: 'string', format: 'misskey:id' },
|
||||||
},
|
},
|
||||||
required: [],
|
anyOf: [
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
userId: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
|
required: ['userId'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
groupId: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
|
required: ['groupId'],
|
||||||
|
},
|
||||||
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
|
|
@ -169,6 +169,7 @@ export const meta = {
|
||||||
host: {
|
host: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: true,
|
optional: false, nullable: true,
|
||||||
|
description: 'The local host is represented with `null`.',
|
||||||
},
|
},
|
||||||
url: {
|
url: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|
|
@ -38,7 +38,11 @@ export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
userId: { type: 'string', format: 'misskey:id' },
|
userId: { type: 'string', format: 'misskey:id' },
|
||||||
expiresAt: { type: 'integer', nullable: true },
|
expiresAt: {
|
||||||
|
type: 'integer',
|
||||||
|
nullable: true,
|
||||||
|
description: 'A Unix Epoch timestamp that must lie in the future. `null` means an indefinite mute.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
required: ['userId'],
|
required: ['userId'],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -19,7 +19,7 @@ export const meta = {
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
local: { type: 'boolean' },
|
local: { type: 'boolean', default: false },
|
||||||
reply: { type: 'boolean' },
|
reply: { type: 'boolean' },
|
||||||
renote: { type: 'boolean' },
|
renote: { type: 'boolean' },
|
||||||
withFiles: { type: 'boolean' },
|
withFiles: { type: 'boolean' },
|
||||||
|
|
|
@ -59,12 +59,6 @@ export const meta = {
|
||||||
id: '3ac74a84-8fd5-4bb0-870f-01804f82ce15',
|
id: '3ac74a84-8fd5-4bb0-870f-01804f82ce15',
|
||||||
},
|
},
|
||||||
|
|
||||||
contentRequired: {
|
|
||||||
message: 'Content required. You need to set text, fileIds, renoteId or poll.',
|
|
||||||
code: 'CONTENT_REQUIRED',
|
|
||||||
id: '6f57e42b-c348-439b-bc45-993995cc515a',
|
|
||||||
},
|
|
||||||
|
|
||||||
cannotCreateAlreadyExpiredPoll: {
|
cannotCreateAlreadyExpiredPoll: {
|
||||||
message: 'Poll is already expired.',
|
message: 'Poll is already expired.',
|
||||||
code: 'CANNOT_CREATE_ALREADY_EXPIRED_POLL',
|
code: 'CANNOT_CREATE_ALREADY_EXPIRED_POLL',
|
||||||
|
@ -92,29 +86,41 @@ export const paramDef = {
|
||||||
visibleUserIds: { type: 'array', uniqueItems: true, items: {
|
visibleUserIds: { type: 'array', uniqueItems: true, items: {
|
||||||
type: 'string', format: 'misskey:id',
|
type: 'string', format: 'misskey:id',
|
||||||
} },
|
} },
|
||||||
text: { type: 'string', nullable: true, maxLength: MAX_NOTE_TEXT_LENGTH, default: null },
|
text: { type: 'string', maxLength: MAX_NOTE_TEXT_LENGTH, nullable: true },
|
||||||
cw: { type: 'string', nullable: true, maxLength: 100 },
|
cw: { type: 'string', nullable: true, maxLength: 100 },
|
||||||
localOnly: { type: 'boolean', default: false },
|
localOnly: { type: 'boolean', default: false },
|
||||||
noExtractMentions: { type: 'boolean', default: false },
|
noExtractMentions: { type: 'boolean', default: false },
|
||||||
noExtractHashtags: { type: 'boolean', default: false },
|
noExtractHashtags: { type: 'boolean', default: false },
|
||||||
noExtractEmojis: { type: 'boolean', default: false },
|
noExtractEmojis: { type: 'boolean', default: false },
|
||||||
fileIds: { type: 'array', uniqueItems: true, minItems: 1, maxItems: 16, items: {
|
fileIds: {
|
||||||
type: 'string', format: 'misskey:id',
|
type: 'array',
|
||||||
} },
|
uniqueItems: true,
|
||||||
mediaIds: { type: 'array', uniqueItems: true, minItems: 1, maxItems: 16, items: {
|
minItems: 1,
|
||||||
type: 'string', format: 'misskey:id',
|
maxItems: 16,
|
||||||
} },
|
items: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
|
mediaIds: {
|
||||||
|
deprecated: true,
|
||||||
|
description: 'Use `fileIds` instead. If both are specified, this property is discarded.',
|
||||||
|
type: 'array',
|
||||||
|
uniqueItems: true,
|
||||||
|
minItems: 1,
|
||||||
|
maxItems: 16,
|
||||||
|
items: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
replyId: { type: 'string', format: 'misskey:id', nullable: true },
|
replyId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
renoteId: { type: 'string', format: 'misskey:id', nullable: true },
|
renoteId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
channelId: { type: 'string', format: 'misskey:id', nullable: true },
|
channelId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
poll: {
|
poll: {
|
||||||
type: 'object', nullable: true,
|
type: 'object',
|
||||||
|
nullable: true,
|
||||||
properties: {
|
properties: {
|
||||||
choices: {
|
choices: {
|
||||||
type: 'array', uniqueItems: true, minItems: 2, maxItems: 10,
|
type: 'array',
|
||||||
items: {
|
uniqueItems: true,
|
||||||
type: 'string', minLength: 1, maxLength: 50,
|
minItems: 2,
|
||||||
},
|
maxItems: 10,
|
||||||
|
items: { type: 'string', minLength: 1, maxLength: 50 },
|
||||||
},
|
},
|
||||||
multiple: { type: 'boolean', default: false },
|
multiple: { type: 'boolean', default: false },
|
||||||
expiresAt: { type: 'integer', nullable: true },
|
expiresAt: { type: 'integer', nullable: true },
|
||||||
|
@ -123,7 +129,34 @@ export const paramDef = {
|
||||||
required: ['choices'],
|
required: ['choices'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
required: [],
|
anyOf: [
|
||||||
|
{
|
||||||
|
// (re)note with text, files and poll are optional
|
||||||
|
properties: {
|
||||||
|
text: { type: 'string', maxLength: MAX_NOTE_TEXT_LENGTH, nullable: false },
|
||||||
|
},
|
||||||
|
required: ['text'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// (re)note with files, text and poll are optional
|
||||||
|
required: ['fileIds'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// (re)note with files, text and poll are optional
|
||||||
|
required: ['mediaIds'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// (re)note with poll, text and files are optional
|
||||||
|
properties: {
|
||||||
|
poll: { type: 'object', nullable: false, },
|
||||||
|
},
|
||||||
|
required: ['poll'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// pure renote
|
||||||
|
required: ['renoteId'],
|
||||||
|
},
|
||||||
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
@ -152,7 +185,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
|
||||||
if (renote == null) {
|
if (renote == null) {
|
||||||
throw new ApiError(meta.errors.noSuchRenoteTarget);
|
throw new ApiError(meta.errors.noSuchRenoteTarget);
|
||||||
} else if (renote.renoteId && !renote.text && !renote.fileIds) {
|
} else if (renote.renoteId && !renote.text && !renote.fileIds && !renote.poll) {
|
||||||
throw new ApiError(meta.errors.cannotReRenote);
|
throw new ApiError(meta.errors.cannotReRenote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,10 +208,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
|
||||||
if (reply == null) {
|
if (reply == null) {
|
||||||
throw new ApiError(meta.errors.noSuchReplyTarget);
|
throw new ApiError(meta.errors.noSuchReplyTarget);
|
||||||
}
|
} else if (reply.renoteId && !reply.text && !reply.fileIds && !renote.poll) {
|
||||||
|
|
||||||
// 返信対象が引用でないRenoteだったらエラー
|
|
||||||
if (reply.renoteId && !reply.text && !reply.fileIds) {
|
|
||||||
throw new ApiError(meta.errors.cannotReplyToPureRenote);
|
throw new ApiError(meta.errors.cannotReplyToPureRenote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,11 +234,6 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// テキストが無いかつ添付ファイルが無いかつRenoteも無いかつ投票も無かったらエラー
|
|
||||||
if (!(ps.text || files.length || renote || ps.poll)) {
|
|
||||||
throw new ApiError(meta.errors.contentRequired);
|
|
||||||
}
|
|
||||||
|
|
||||||
let channel: Channel | undefined;
|
let channel: Channel | undefined;
|
||||||
if (ps.channelId != null) {
|
if (ps.channelId != null) {
|
||||||
channel = await Channels.findOneBy({ id: ps.channelId });
|
channel = await Channels.findOneBy({ id: ps.channelId });
|
||||||
|
|
|
@ -35,7 +35,11 @@ export const meta = {
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
withFiles: { type: 'boolean' },
|
withFiles: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Only show notes that have attached files.',
|
||||||
|
},
|
||||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||||
sinceId: { type: 'string', format: 'misskey:id' },
|
sinceId: { type: 'string', format: 'misskey:id' },
|
||||||
untilId: { type: 'string', format: 'misskey:id' },
|
untilId: { type: 'string', format: 'misskey:id' },
|
||||||
|
|
|
@ -48,7 +48,11 @@ export const paramDef = {
|
||||||
includeMyRenotes: { type: 'boolean', default: true },
|
includeMyRenotes: { type: 'boolean', default: true },
|
||||||
includeRenotedMyNotes: { type: 'boolean', default: true },
|
includeRenotedMyNotes: { type: 'boolean', default: true },
|
||||||
includeLocalRenotes: { type: 'boolean', default: true },
|
includeLocalRenotes: { type: 'boolean', default: true },
|
||||||
withFiles: { type: 'boolean' },
|
withFiles: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Only show notes that have attached files.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
required: [],
|
required: [],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -37,7 +37,11 @@ export const meta = {
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
withFiles: { type: 'boolean' },
|
withFiles: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Only show notes that have attached files.',
|
||||||
|
},
|
||||||
fileType: { type: 'array', items: {
|
fileType: { type: 'array', items: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
} },
|
} },
|
||||||
|
|
|
@ -25,21 +25,44 @@ export const meta = {
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
tag: { type: 'string' },
|
|
||||||
query: { type: 'array', items: {
|
|
||||||
type: 'array', items: {
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
} },
|
|
||||||
reply: { type: 'boolean', nullable: true, default: null },
|
reply: { type: 'boolean', nullable: true, default: null },
|
||||||
renote: { type: 'boolean', nullable: true, default: null },
|
renote: { type: 'boolean', nullable: true, default: null },
|
||||||
withFiles: { type: 'boolean' },
|
withFiles: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Only show notes that have attached files.',
|
||||||
|
},
|
||||||
poll: { type: 'boolean', nullable: true, default: null },
|
poll: { type: 'boolean', nullable: true, default: null },
|
||||||
sinceId: { type: 'string', format: 'misskey:id' },
|
sinceId: { type: 'string', format: 'misskey:id' },
|
||||||
untilId: { type: 'string', format: 'misskey:id' },
|
untilId: { type: 'string', format: 'misskey:id' },
|
||||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||||
},
|
},
|
||||||
required: [],
|
anyOf: [
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
tag: { type: 'string', minLength: 1 },
|
||||||
|
},
|
||||||
|
required: ['tag'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
query: {
|
||||||
|
type: 'array',
|
||||||
|
description: 'The outer arrays are chained with OR, the inner arrays are chained with AND.',
|
||||||
|
items: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'string',
|
||||||
|
minLength: 1,
|
||||||
|
},
|
||||||
|
minItems: 1,
|
||||||
|
},
|
||||||
|
minItems: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ['query'],
|
||||||
|
},
|
||||||
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
|
|
@ -35,7 +35,11 @@ export const paramDef = {
|
||||||
untilId: { type: 'string', format: 'misskey:id' },
|
untilId: { type: 'string', format: 'misskey:id' },
|
||||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||||
offset: { type: 'integer', default: 0 },
|
offset: { type: 'integer', default: 0 },
|
||||||
host: { type: 'string', nullable: true },
|
host: {
|
||||||
|
type: 'string',
|
||||||
|
nullable: true,
|
||||||
|
description: 'The local host is represented with `null`.',
|
||||||
|
},
|
||||||
userId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
|
userId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
|
||||||
channelId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
|
channelId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
|
||||||
},
|
},
|
||||||
|
|
|
@ -38,7 +38,11 @@ export const paramDef = {
|
||||||
includeMyRenotes: { type: 'boolean', default: true },
|
includeMyRenotes: { type: 'boolean', default: true },
|
||||||
includeRenotedMyNotes: { type: 'boolean', default: true },
|
includeRenotedMyNotes: { type: 'boolean', default: true },
|
||||||
includeLocalRenotes: { type: 'boolean', default: true },
|
includeLocalRenotes: { type: 'boolean', default: true },
|
||||||
withFiles: { type: 'boolean' },
|
withFiles: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Only show notes that have attached files.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
required: [],
|
required: [],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -42,7 +42,11 @@ export const paramDef = {
|
||||||
includeMyRenotes: { type: 'boolean', default: true },
|
includeMyRenotes: { type: 'boolean', default: true },
|
||||||
includeRenotedMyNotes: { type: 'boolean', default: true },
|
includeRenotedMyNotes: { type: 'boolean', default: true },
|
||||||
includeLocalRenotes: { type: 'boolean', default: true },
|
includeLocalRenotes: { type: 'boolean', default: true },
|
||||||
withFiles: { type: 'boolean' },
|
withFiles: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Only show notes that have attached files.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
required: ['listId'],
|
required: ['listId'],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -26,12 +26,21 @@ export const meta = {
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
anyOf: [
|
||||||
pageId: { type: 'string', format: 'misskey:id' },
|
{
|
||||||
name: { type: 'string' },
|
properties: {
|
||||||
username: { type: 'string' },
|
pageId: { type: 'string', format: 'misskey:id' },
|
||||||
},
|
},
|
||||||
required: [],
|
required: ['pageId'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
name: { type: 'string' },
|
||||||
|
username: { type: 'string' },
|
||||||
|
},
|
||||||
|
required: ['name', 'username'],
|
||||||
|
},
|
||||||
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
|
|
@ -38,14 +38,29 @@ export const meta = {
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
userId: { type: 'string', format: 'misskey:id' },
|
|
||||||
username: { type: 'string' },
|
|
||||||
host: { type: 'string', nullable: true },
|
|
||||||
sinceId: { type: 'string', format: 'misskey:id' },
|
sinceId: { type: 'string', format: 'misskey:id' },
|
||||||
untilId: { type: 'string', format: 'misskey:id' },
|
untilId: { type: 'string', format: 'misskey:id' },
|
||||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||||
},
|
},
|
||||||
required: [],
|
anyOf: [
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
userId: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
|
required: ['userId'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
username: { type: 'string' },
|
||||||
|
host: {
|
||||||
|
type: 'string',
|
||||||
|
nullable: true,
|
||||||
|
description: 'The local host is represented with `null`.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ['username', 'host'],
|
||||||
|
},
|
||||||
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
|
|
@ -38,14 +38,29 @@ export const meta = {
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
userId: { type: 'string', format: 'misskey:id' },
|
|
||||||
username: { type: 'string' },
|
|
||||||
host: { type: 'string', nullable: true },
|
|
||||||
sinceId: { type: 'string', format: 'misskey:id' },
|
sinceId: { type: 'string', format: 'misskey:id' },
|
||||||
untilId: { type: 'string', format: 'misskey:id' },
|
untilId: { type: 'string', format: 'misskey:id' },
|
||||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||||
},
|
},
|
||||||
required: [],
|
anyOf: [
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
userId: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
|
required: ['userId'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
username: { type: 'string' },
|
||||||
|
host: {
|
||||||
|
type: 'string',
|
||||||
|
nullable: true,
|
||||||
|
description: 'The local host is represented with `null`.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ['username', 'host'],
|
||||||
|
},
|
||||||
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
|
|
@ -28,7 +28,10 @@ export const paramDef = {
|
||||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||||
detail: { type: 'boolean', default: true },
|
detail: { type: 'boolean', default: true },
|
||||||
},
|
},
|
||||||
required: [],
|
anyOf: [
|
||||||
|
{ required: ['username'] },
|
||||||
|
{ required: ['host'] },
|
||||||
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// TODO: avatar,bannerをJOINしたいけどエラーになる
|
// TODO: avatar,bannerをJOINしたいけどエラーになる
|
||||||
|
|
|
@ -46,15 +46,33 @@ export const meta = {
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
anyOf: [
|
||||||
userId: { type: 'string', format: 'misskey:id' },
|
{
|
||||||
userIds: { type: 'array', uniqueItems: true, items: {
|
properties: {
|
||||||
type: 'string', format: 'misskey:id',
|
userId: { type: 'string', format: 'misskey:id' },
|
||||||
} },
|
},
|
||||||
username: { type: 'string' },
|
required: ['userId'],
|
||||||
host: { type: 'string', nullable: true },
|
},
|
||||||
},
|
{
|
||||||
required: [],
|
properties: {
|
||||||
|
userIds: { type: 'array', uniqueItems: true, items: {
|
||||||
|
type: 'string', format: 'misskey:id',
|
||||||
|
} },
|
||||||
|
},
|
||||||
|
required: ['userIds'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
username: { type: 'string' },
|
||||||
|
host: {
|
||||||
|
type: 'string',
|
||||||
|
nullable: true,
|
||||||
|
description: 'The local host is represented with `null`.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ['username', 'host'],
|
||||||
|
},
|
||||||
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"watch": "webpack --watch",
|
"watch": "webpack --watch",
|
||||||
"build": "webpack",
|
"build": "webpack",
|
||||||
"lint": "eslint --quiet src/**/*.{ts,vue}"
|
"lint": "eslint --quiet 'src/**/*.{ts,vue}'"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"chokidar": "^3.3.1",
|
"chokidar": "^3.3.1",
|
||||||
|
|
|
@ -51,14 +51,14 @@ export function applyTheme(theme: Theme, persist = true) {
|
||||||
|
|
||||||
if (_theme.base) {
|
if (_theme.base) {
|
||||||
const base = [lightTheme, darkTheme].find(x => x.id === _theme.base);
|
const base = [lightTheme, darkTheme].find(x => x.id === _theme.base);
|
||||||
_theme.props = Object.assign({}, base.props, _theme.props);
|
if (base) _theme.props = Object.assign({}, base.props, _theme.props);
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = compile(_theme);
|
const props = compile(_theme);
|
||||||
|
|
||||||
for (const tag of document.head.children) {
|
for (const tag of document.head.children) {
|
||||||
if (tag.tagName === 'META' && tag.getAttribute('name') === 'theme-color') {
|
if (tag.tagName === 'META' && tag.getAttribute('name') === 'theme-color') {
|
||||||
tag.setAttribute('content', props['html']);
|
tag.setAttribute('content', props['htmlThemeColor']);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue