summaryrefslogtreecommitdiff
path: root/packages/backend/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'packages/backend/src/server')
-rw-r--r--packages/backend/src/server/api/endpoints/drive/files.ts2
-rw-r--r--packages/backend/src/server/api/endpoints/federation/instances.ts1
-rw-r--r--packages/backend/src/server/api/endpoints/i/2fa/register-key.ts33
-rw-r--r--packages/backend/src/server/api/endpoints/notes/create.test.ts14
-rw-r--r--packages/backend/src/server/api/endpoints/notes/create.ts34
-rw-r--r--packages/backend/src/server/api/openapi/gen-spec.ts10
-rw-r--r--packages/backend/src/server/api/openapi/schemas.ts37
7 files changed, 85 insertions, 46 deletions
diff --git a/packages/backend/src/server/api/endpoints/drive/files.ts b/packages/backend/src/server/api/endpoints/drive/files.ts
index b7e9d12e94..0ca31dc993 100644
--- a/packages/backend/src/server/api/endpoints/drive/files.ts
+++ b/packages/backend/src/server/api/endpoints/drive/files.ts
@@ -36,7 +36,7 @@ export const paramDef = {
untilId: { type: 'string', format: 'misskey:id' },
folderId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
type: { type: 'string', nullable: true, pattern: /^[a-zA-Z\/\-*]+$/.toString().slice(1, -1) },
- sort: { type: 'string', nullable: true, enum: ['+createdAt', '-createdAt', '+name', '-name', '+size', '-size'] },
+ sort: { type: 'string', nullable: true, enum: ['+createdAt', '-createdAt', '+name', '-name', '+size', '-size', null] },
},
required: [],
} as const;
diff --git a/packages/backend/src/server/api/endpoints/federation/instances.ts b/packages/backend/src/server/api/endpoints/federation/instances.ts
index e5a90715f5..457309731f 100644
--- a/packages/backend/src/server/api/endpoints/federation/instances.ts
+++ b/packages/backend/src/server/api/endpoints/federation/instances.ts
@@ -60,6 +60,7 @@ export const paramDef = {
'-firstRetrievedAt',
'+latestRequestReceivedAt',
'-latestRequestReceivedAt',
+ null,
],
},
},
diff --git a/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts b/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts
index 0fac96d58f..15c5011db9 100644
--- a/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts
+++ b/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts
@@ -103,13 +103,13 @@ export const meta = {
items: {
type: 'string',
enum: [
- "ble",
- "cable",
- "hybrid",
- "internal",
- "nfc",
- "smart-card",
- "usb",
+ 'ble',
+ 'cable',
+ 'hybrid',
+ 'internal',
+ 'nfc',
+ 'smart-card',
+ 'usb',
],
},
},
@@ -123,8 +123,8 @@ export const meta = {
authenticatorAttachment: {
type: 'string',
enum: [
- "cross-platform",
- "platform",
+ 'cross-platform',
+ 'platform',
],
},
requireResidentKey: {
@@ -133,9 +133,9 @@ export const meta = {
userVerification: {
type: 'string',
enum: [
- "discouraged",
- "preferred",
- "required",
+ 'discouraged',
+ 'preferred',
+ 'required',
],
},
},
@@ -144,10 +144,11 @@ export const meta = {
type: 'string',
nullable: true,
enum: [
- "direct",
- "enterprise",
- "indirect",
- "none",
+ 'direct',
+ 'enterprise',
+ 'indirect',
+ 'none',
+ null,
],
},
extensions: {
diff --git a/packages/backend/src/server/api/endpoints/notes/create.test.ts b/packages/backend/src/server/api/endpoints/notes/create.test.ts
index 6086f99c92..3228bbd014 100644
--- a/packages/backend/src/server/api/endpoints/notes/create.test.ts
+++ b/packages/backend/src/server/api/endpoints/notes/create.test.ts
@@ -34,11 +34,10 @@ describe('api:notes/create', () => {
.toBe(VALID);
});
- // TODO
- //test('null post', () => {
- // expect(v({ text: null }))
- // .toBe(INVALID);
- //});
+ test('null post', () => {
+ expect(v({ text: null }))
+ .toBe(INVALID);
+ });
test('0 characters post', () => {
expect(v({ text: '' }))
@@ -49,6 +48,11 @@ describe('api:notes/create', () => {
expect(v({ text: await tooLong }))
.toBe(INVALID);
});
+
+ test('whitespace-only post', () => {
+ expect(v({ text: ' ' }))
+ .toBe(INVALID);
+ });
});
describe('cw', () => {
diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts
index c5d42dabe4..29a0f7418c 100644
--- a/packages/backend/src/server/api/endpoints/notes/create.ts
+++ b/packages/backend/src/server/api/endpoints/notes/create.ts
@@ -172,13 +172,33 @@ export const paramDef = {
},
},
// (re)note with text, files and poll are optional
- anyOf: [
- { required: ['text'] },
- { required: ['renoteId'] },
- { required: ['fileIds'] },
- { required: ['mediaIds'] },
- { required: ['poll'] },
- ],
+ if: {
+ properties: {
+ renoteId: {
+ type: 'null',
+ },
+ fileIds: {
+ type: 'null',
+ },
+ mediaIds: {
+ type: 'null',
+ },
+ poll: {
+ type: 'null',
+ },
+ },
+ },
+ then: {
+ properties: {
+ text: {
+ type: 'string',
+ minLength: 1,
+ maxLength: MAX_NOTE_TEXT_LENGTH,
+ pattern: '[^\\s]+',
+ },
+ },
+ required: ['text'],
+ },
} as const;
@Injectable()
diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts
index 0e71510b48..971a6116bf 100644
--- a/packages/backend/src/server/api/openapi/gen-spec.ts
+++ b/packages/backend/src/server/api/openapi/gen-spec.ts
@@ -10,7 +10,7 @@ import { schemas, convertSchemaToOpenApiSchema } from './schemas.js';
export function genOpenapiSpec(config: Config) {
const spec = {
- openapi: '3.0.0',
+ openapi: '3.1.0',
info: {
version: config.version,
@@ -56,7 +56,7 @@ export function genOpenapiSpec(config: Config) {
}
}
- const resSchema = endpoint.meta.res ? convertSchemaToOpenApiSchema(endpoint.meta.res) : {};
+ const resSchema = endpoint.meta.res ? convertSchemaToOpenApiSchema(endpoint.meta.res, 'res') : {};
let desc = (endpoint.meta.description ? endpoint.meta.description : 'No description provided.') + '\n\n';
@@ -71,7 +71,7 @@ export function genOpenapiSpec(config: Config) {
}
const requestType = endpoint.meta.requireFile ? 'multipart/form-data' : 'application/json';
- const schema = { ...endpoint.params };
+ const schema = { ...convertSchemaToOpenApiSchema(endpoint.params, 'param') };
if (endpoint.meta.requireFile) {
schema.properties = {
@@ -210,7 +210,9 @@ export function genOpenapiSpec(config: Config) {
};
spec.paths['/' + endpoint.name] = {
- ...(endpoint.meta.allowGet ? { get: info } : {}),
+ ...(endpoint.meta.allowGet ? {
+ get: info,
+ } : {}),
post: info,
};
}
diff --git a/packages/backend/src/server/api/openapi/schemas.ts b/packages/backend/src/server/api/openapi/schemas.ts
index 2716f5f162..a862a7b742 100644
--- a/packages/backend/src/server/api/openapi/schemas.ts
+++ b/packages/backend/src/server/api/openapi/schemas.ts
@@ -6,32 +6,35 @@
import type { Schema } from '@/misc/json-schema.js';
import { refs } from '@/misc/json-schema.js';
-export function convertSchemaToOpenApiSchema(schema: Schema) {
- // optional, refはスキーマ定義に含まれないので分離しておく
+export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 'res') {
+ // optional, nullable, refはスキーマ定義に含まれないので分離しておく
// eslint-disable-next-line @typescript-eslint/no-unused-vars
- const { optional, ref, ...res }: any = schema;
+ const { optional, nullable, ref, ...res }: any = schema;
if (schema.type === 'object' && schema.properties) {
- const required = Object.entries(schema.properties).filter(([k, v]) => !v.optional).map(([k]) => k);
- if (required.length > 0) {
+ if (type === 'res') {
+ const required = Object.entries(schema.properties).filter(([k, v]) => !v.optional).map(([k]) => k);
+ if (required.length > 0) {
// 空配列は許可されない
- res.required = required;
+ res.required = required;
+ }
}
for (const k of Object.keys(schema.properties)) {
- res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k]);
+ res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k], type);
}
}
if (schema.type === 'array' && schema.items) {
- res.items = convertSchemaToOpenApiSchema(schema.items);
+ res.items = convertSchemaToOpenApiSchema(schema.items, type);
}
- if (schema.anyOf) res.anyOf = schema.anyOf.map(convertSchemaToOpenApiSchema);
- if (schema.oneOf) res.oneOf = schema.oneOf.map(convertSchemaToOpenApiSchema);
- if (schema.allOf) res.allOf = schema.allOf.map(convertSchemaToOpenApiSchema);
+ for (const o of ['anyOf', 'oneOf', 'allOf'] as const) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ if (o in schema) res[o] = schema[o]!.map(schema => convertSchemaToOpenApiSchema(schema, type));
+ }
- if (schema.ref) {
+ if (type === 'res' && schema.ref) {
const $ref = `#/components/schemas/${schema.ref}`;
if (schema.nullable || schema.optional) {
res.allOf = [{ $ref }];
@@ -40,6 +43,14 @@ export function convertSchemaToOpenApiSchema(schema: Schema) {
}
}
+ if (schema.nullable) {
+ if (Array.isArray(schema.type) && !schema.type.includes('null')) {
+ res.type.push('null');
+ } else if (typeof schema.type === 'string') {
+ res.type = [res.type, 'null'];
+ }
+ }
+
return res;
}
@@ -72,6 +83,6 @@ export const schemas = {
},
...Object.fromEntries(
- Object.entries(refs).map(([key, schema]) => [key, convertSchemaToOpenApiSchema(schema)]),
+ Object.entries(refs).map(([key, schema]) => [key, convertSchemaToOpenApiSchema(schema, 'res')]),
),
};