✌️
This commit is contained in:
parent
5ea0f23389
commit
2cdcbcc80e
6 changed files with 127 additions and 117 deletions
|
@ -30,3 +30,9 @@ block main
|
||||||
section
|
section
|
||||||
h2= i18n('docs.api.endpoints.res')
|
h2= i18n('docs.api.endpoints.res')
|
||||||
+propTable(res)
|
+propTable(res)
|
||||||
|
|
||||||
|
if resDefs
|
||||||
|
each resDef in resDefs
|
||||||
|
section(id= resDef.name)
|
||||||
|
h3= resDef.name
|
||||||
|
+propTable(resDef.props)
|
||||||
|
|
|
@ -5,167 +5,171 @@ desc:
|
||||||
en: "A user."
|
en: "A user."
|
||||||
|
|
||||||
props:
|
props:
|
||||||
- name: "id"
|
id:
|
||||||
type: "id"
|
type: "id"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "ユーザーID"
|
ja: "ユーザーID"
|
||||||
en: "The ID of this user"
|
en: "The ID of this user"
|
||||||
- name: "createdAt"
|
|
||||||
|
createdAt:
|
||||||
type: "date"
|
type: "date"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "アカウント作成日時"
|
ja: "アカウント作成日時"
|
||||||
en: "The registered date of this user"
|
en: "The registered date of this user"
|
||||||
- name: "username"
|
|
||||||
|
username:
|
||||||
type: "string"
|
type: "string"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "ユーザー名"
|
ja: "ユーザー名"
|
||||||
en: "The username of this user"
|
en: "The username of this user"
|
||||||
- name: "description"
|
|
||||||
|
description:
|
||||||
type: "string"
|
type: "string"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "アカウントの説明(自己紹介)"
|
ja: "アカウントの説明(自己紹介)"
|
||||||
en: "The description of this user"
|
en: "The description of this user"
|
||||||
- name: "avatarId"
|
|
||||||
|
avatarId:
|
||||||
type: "id(DriveFile)"
|
type: "id(DriveFile)"
|
||||||
optional: true
|
optional: true
|
||||||
desc:
|
desc:
|
||||||
ja: "アバターのID"
|
ja: "アバターのID"
|
||||||
en: "The ID of the avatar of this user"
|
en: "The ID of the avatar of this user"
|
||||||
- name: "avatarUrl"
|
|
||||||
|
avatarUrl:
|
||||||
type: "string"
|
type: "string"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "アバターのURL"
|
ja: "アバターのURL"
|
||||||
en: "The URL of the avatar of this user"
|
en: "The URL of the avatar of this user"
|
||||||
- name: "bannerId"
|
|
||||||
|
bannerId:
|
||||||
type: "id(DriveFile)"
|
type: "id(DriveFile)"
|
||||||
optional: true
|
optional: true
|
||||||
desc:
|
desc:
|
||||||
ja: "バナーのID"
|
ja: "バナーのID"
|
||||||
en: "The ID of the banner of this user"
|
en: "The ID of the banner of this user"
|
||||||
- name: "bannerUrl"
|
|
||||||
|
bannerUrl:
|
||||||
type: "string"
|
type: "string"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "バナーのURL"
|
ja: "バナーのURL"
|
||||||
en: "The URL of the banner of this user"
|
en: "The URL of the banner of this user"
|
||||||
- name: "followersCount"
|
|
||||||
|
followersCount:
|
||||||
type: "number"
|
type: "number"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "フォロワーの数"
|
ja: "フォロワーの数"
|
||||||
en: "The number of the followers for this user"
|
en: "The number of the followers for this user"
|
||||||
- name: "followingCount"
|
|
||||||
|
followingCount:
|
||||||
type: "number"
|
type: "number"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "フォローしているユーザーの数"
|
ja: "フォローしているユーザーの数"
|
||||||
en: "The number of the following users for this user"
|
en: "The number of the following users for this user"
|
||||||
- name: "isFollowing"
|
|
||||||
|
isFollowing:
|
||||||
type: "boolean"
|
type: "boolean"
|
||||||
optional: true
|
optional: true
|
||||||
desc:
|
desc:
|
||||||
ja: "自分がこのユーザーをフォローしているか"
|
ja: "自分がこのユーザーをフォローしているか"
|
||||||
- name: "isFollowed"
|
|
||||||
|
isFollowed:
|
||||||
type: "boolean"
|
type: "boolean"
|
||||||
optional: true
|
optional: true
|
||||||
desc:
|
desc:
|
||||||
ja: "自分がこのユーザーにフォローされているか"
|
ja: "自分がこのユーザーにフォローされているか"
|
||||||
- name: "isMuted"
|
|
||||||
|
isMuted:
|
||||||
type: "boolean"
|
type: "boolean"
|
||||||
optional: true
|
optional: true
|
||||||
desc:
|
desc:
|
||||||
ja: "自分がこのユーザーをミュートしているか"
|
ja: "自分がこのユーザーをミュートしているか"
|
||||||
en: "Whether you muted this user"
|
en: "Whether you muted this user"
|
||||||
- name: "notesCount"
|
|
||||||
|
notesCount:
|
||||||
type: "number"
|
type: "number"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "投稿の数"
|
ja: "投稿の数"
|
||||||
en: "The number of the notes of this user"
|
en: "The number of the notes of this user"
|
||||||
- name: "pinnedNote"
|
|
||||||
|
pinnedNote:
|
||||||
type: "entity(Note)"
|
type: "entity(Note)"
|
||||||
optional: true
|
optional: true
|
||||||
desc:
|
desc:
|
||||||
ja: "ピン留めされた投稿"
|
ja: "ピン留めされた投稿"
|
||||||
en: "The pinned note of this user"
|
en: "The pinned note of this user"
|
||||||
- name: "pinnedNoteId"
|
|
||||||
|
pinnedNoteId:
|
||||||
type: "id(Note)"
|
type: "id(Note)"
|
||||||
optional: true
|
optional: true
|
||||||
desc:
|
desc:
|
||||||
ja: "ピン留めされた投稿のID"
|
ja: "ピン留めされた投稿のID"
|
||||||
en: "The ID of the pinned note of this user"
|
en: "The ID of the pinned note of this user"
|
||||||
- name: "driveCapacity"
|
|
||||||
|
driveCapacity:
|
||||||
type: "number"
|
type: "number"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "ドライブの容量(bytes)"
|
ja: "ドライブの容量(bytes)"
|
||||||
en: "The capacity of drive of this user (bytes)"
|
en: "The capacity of drive of this user (bytes)"
|
||||||
- name: "host"
|
|
||||||
|
host:
|
||||||
type: "string | null"
|
type: "string | null"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "ホスト (例: example.com:3000)"
|
ja: "ホスト (例: example.com:3000)"
|
||||||
en: "Host (e.g. example.com:3000)"
|
en: "Host (e.g. example.com:3000)"
|
||||||
- name: "account"
|
|
||||||
type: "object"
|
twitter:
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja: "このサーバーにおけるアカウント"
|
|
||||||
en: "The account of this user on this server"
|
|
||||||
defName: "account"
|
|
||||||
def:
|
|
||||||
- name: "lastUsedAt"
|
|
||||||
type: "date"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja: "最終利用日時"
|
|
||||||
en: "The last used date of this user"
|
|
||||||
- name: "isBot"
|
|
||||||
type: "boolean"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja: "botか否か(自己申告であることに留意)"
|
|
||||||
en: "Whether is bot or not"
|
|
||||||
- name: "twitter"
|
|
||||||
type: "object"
|
type: "object"
|
||||||
optional: true
|
optional: true
|
||||||
desc:
|
desc:
|
||||||
ja: "連携されているTwitterアカウント情報"
|
ja: "連携されているTwitterアカウント情報"
|
||||||
en: "The info of the connected twitter account of this user"
|
en: "The info of the connected twitter account of this user"
|
||||||
defName: "twitter"
|
props:
|
||||||
def:
|
userId:
|
||||||
- name: "userId"
|
|
||||||
type: "string"
|
type: "string"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "ユーザーID"
|
ja: "ユーザーID"
|
||||||
en: "The user ID"
|
en: "The user ID"
|
||||||
- name: "screenName"
|
screenName:
|
||||||
type: "string"
|
type: "string"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "ユーザー名"
|
ja: "ユーザー名"
|
||||||
en: "The screen name of this user"
|
en: "The screen name of this user"
|
||||||
- name: "profile"
|
|
||||||
|
isBot:
|
||||||
|
type: "boolean"
|
||||||
|
optional: true
|
||||||
|
desc:
|
||||||
|
ja: "botか否か(自己申告であることに留意)"
|
||||||
|
en: "Whether is bot or not"
|
||||||
|
|
||||||
|
profile:
|
||||||
type: "object"
|
type: "object"
|
||||||
optional: false
|
optional: false
|
||||||
desc:
|
desc:
|
||||||
ja: "プロフィール"
|
ja: "プロフィール"
|
||||||
en: "The profile of this user"
|
en: "The profile of this user"
|
||||||
defName: "profile"
|
props:
|
||||||
def:
|
location:
|
||||||
- name: "location"
|
|
||||||
type: "string"
|
type: "string"
|
||||||
optional: true
|
optional: true
|
||||||
desc:
|
desc:
|
||||||
ja: "場所"
|
ja: "場所"
|
||||||
en: "The location of this user"
|
en: "The location of this user"
|
||||||
- name: "birthday"
|
birthday:
|
||||||
type: "string"
|
type: "string"
|
||||||
optional: true
|
optional: true
|
||||||
desc:
|
desc:
|
||||||
|
|
|
@ -17,4 +17,4 @@ block main
|
||||||
each propDef in propDefs
|
each propDef in propDefs
|
||||||
section(id= propDef.name)
|
section(id= propDef.name)
|
||||||
h3= propDef.name
|
h3= propDef.name
|
||||||
+propTable(propDef.params)
|
+propTable(propDef.props)
|
||||||
|
|
|
@ -22,9 +22,9 @@ mixin propTable(props)
|
||||||
a(href=`/docs/${lang}/api/entities/${kebab(prop.entity)}`)= prop.entity
|
a(href=`/docs/${lang}/api/entities/${kebab(prop.entity)}`)= prop.entity
|
||||||
| )
|
| )
|
||||||
else if prop.kind == 'object'
|
else if prop.kind == 'object'
|
||||||
if prop.def
|
if prop.hasDef
|
||||||
| (
|
| (
|
||||||
a(href=`#${prop.defName}`)= prop.defName
|
a(href=`#${prop.name}`)= prop.name
|
||||||
| )
|
| )
|
||||||
else if prop.kind == 'date'
|
else if prop.kind == 'date'
|
||||||
| (Date)
|
| (Date)
|
||||||
|
|
|
@ -90,7 +90,7 @@ export const meta = {
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
object: {
|
props: {
|
||||||
createdNote: {
|
createdNote: {
|
||||||
type: 'entity(Note)',
|
type: 'entity(Note)',
|
||||||
desc: {
|
desc: {
|
||||||
|
|
|
@ -63,66 +63,64 @@ async function genVars(lang: string): Promise<{ [key: string]: any }> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WIP type
|
// WIP type
|
||||||
const parseEPDefParam = (key: string, param: Context) => {
|
const parseParamDefinition = (key: string, param: Context) => {
|
||||||
return Object.assign({
|
return Object.assign({
|
||||||
name: key,
|
name: key,
|
||||||
type: param.getType()
|
type: param.getType()
|
||||||
}, param.data);
|
}, param.data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseParam = (param: any) => {
|
const parsePropDefinition = (key: string, prop: any) => {
|
||||||
const id = param.type.match(/^id\((.+?)\)|^id/);
|
const id = prop.type.match(/^id\((.+?)\)|^id/);
|
||||||
const entity = param.type.match(/^entity\((.+?)\)/);
|
const entity = prop.type.match(/^entity\((.+?)\)/);
|
||||||
const isObject = /^object/.test(param.type);
|
const isObject = /^object/.test(prop.type);
|
||||||
const isDate = /^date/.test(param.type);
|
const isDate = /^date/.test(prop.type);
|
||||||
const isArray = /\[\]$/.test(param.type);
|
const isArray = /\[\]$/.test(prop.type);
|
||||||
if (id) {
|
if (id) {
|
||||||
param.kind = 'id';
|
prop.kind = 'id';
|
||||||
param.type = 'string';
|
prop.type = 'string';
|
||||||
param.entity = id[1];
|
prop.entity = id[1];
|
||||||
if (isArray) {
|
if (isArray) {
|
||||||
param.type += '[]';
|
prop.type += '[]';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entity) {
|
if (entity) {
|
||||||
param.kind = 'entity';
|
prop.kind = 'entity';
|
||||||
param.type = 'object';
|
prop.type = 'object';
|
||||||
param.entity = entity[1];
|
prop.entity = entity[1];
|
||||||
if (isArray) {
|
if (isArray) {
|
||||||
param.type += '[]';
|
prop.type += '[]';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isObject) {
|
if (isObject) {
|
||||||
param.kind = 'object';
|
prop.kind = 'object';
|
||||||
|
if (prop.props) {
|
||||||
|
prop.hasDef = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isDate) {
|
if (isDate) {
|
||||||
param.kind = 'date';
|
prop.kind = 'date';
|
||||||
param.type = 'string';
|
prop.type = 'string';
|
||||||
if (isArray) {
|
if (isArray) {
|
||||||
param.type += '[]';
|
prop.type += '[]';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param.optional) {
|
if (prop.optional) {
|
||||||
param.type += '?';
|
prop.type += '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
return param;
|
prop.name = key;
|
||||||
|
|
||||||
|
return prop;
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortParams = (params: Array<{name: string}>) => {
|
const sortParams = (params: Array<{name: string}>) => {
|
||||||
params.sort((a, b) => {
|
|
||||||
if (a.name < b.name)
|
|
||||||
return -1;
|
|
||||||
if (a.name > b.name)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
return params;
|
return params;
|
||||||
};
|
};
|
||||||
|
|
||||||
// WIP type
|
// WIP type
|
||||||
const extractEPDefs = (params: Context[]) => {
|
const extractParamDefRef = (params: Context[]) => {
|
||||||
let defs: any[] = [];
|
let defs: any[] = [];
|
||||||
|
|
||||||
params.forEach(param => {
|
params.forEach(param => {
|
||||||
|
@ -130,10 +128,10 @@ const extractEPDefs = (params: Context[]) => {
|
||||||
const props = (param as ObjectContext<any>).props;
|
const props = (param as ObjectContext<any>).props;
|
||||||
defs.push({
|
defs.push({
|
||||||
name: param.data.ref,
|
name: param.data.ref,
|
||||||
params: sortParams(Object.keys(props).map(k => parseEPDefParam(k, props[k])))
|
params: sortParams(Object.keys(props).map(k => parseParamDefinition(k, props[k])))
|
||||||
});
|
});
|
||||||
|
|
||||||
const childDefs = extractEPDefs(Object.keys(props).map(k => props[k]));
|
const childDefs = extractParamDefRef(Object.keys(props).map(k => props[k]));
|
||||||
|
|
||||||
defs = defs.concat(childDefs);
|
defs = defs.concat(childDefs);
|
||||||
}
|
}
|
||||||
|
@ -142,17 +140,17 @@ const extractEPDefs = (params: Context[]) => {
|
||||||
return sortParams(defs);
|
return sortParams(defs);
|
||||||
};
|
};
|
||||||
|
|
||||||
const extractDefs = (params: any[]) => {
|
const extractPropDefRef = (props: any[]) => {
|
||||||
let defs: any[] = [];
|
let defs: any[] = [];
|
||||||
|
|
||||||
params.forEach(param => {
|
Object.entries(props).forEach(([k, v]) => {
|
||||||
if (param.def) {
|
if (v.props) {
|
||||||
defs.push({
|
defs.push({
|
||||||
name: param.defName,
|
name: k,
|
||||||
params: sortParams(param.def.map((p: any) => parseParam(p)))
|
props: sortParams(Object.entries(v.props).map(([k, v]) => parsePropDefinition(k, v)))
|
||||||
});
|
});
|
||||||
|
|
||||||
const childDefs = extractDefs(param.def);
|
const childDefs = extractPropDefRef(v.props);
|
||||||
|
|
||||||
defs = defs.concat(childDefs);
|
defs = defs.concat(childDefs);
|
||||||
}
|
}
|
||||||
|
@ -184,8 +182,10 @@ router.get('/*/api/endpoints/*', async ctx => {
|
||||||
},
|
},
|
||||||
desc: ep.desc,
|
desc: ep.desc,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
params: sortParams(Object.keys(ep.params).map(k => parseEPDefParam(k, ep.params[k]))),
|
params: sortParams(Object.entries(ep.params).map(([k, v]) => parseParamDefinition(k, v))),
|
||||||
paramDefs: extractEPDefs(Object.keys(ep.params).map(k => ep.params[k])),
|
paramDefs: extractParamDefRef(Object.entries(ep.params).map(([k, v]) => v)),
|
||||||
|
res: ep.res.props ? sortParams(Object.entries(ep.res.props).map(([k, v]) => parsePropDefinition(k, v))) : null,
|
||||||
|
resDefs: null//extractPropDefRef(Object.entries(ep.res.props).map(([k, v]) => parsePropDefinition(k, v)))
|
||||||
};
|
};
|
||||||
|
|
||||||
await ctx.render('../../../../src/client/docs/api/endpoints/view', Object.assign(await genVars(lang), vars));
|
await ctx.render('../../../../src/client/docs/api/endpoints/view', Object.assign(await genVars(lang), vars));
|
||||||
|
@ -200,8 +200,8 @@ router.get('/*/api/entities/*', async ctx => {
|
||||||
await ctx.render('../../../../src/client/docs/api/entities/view', Object.assign(await genVars(lang), {
|
await ctx.render('../../../../src/client/docs/api/entities/view', Object.assign(await genVars(lang), {
|
||||||
name: x.name,
|
name: x.name,
|
||||||
desc: x.desc,
|
desc: x.desc,
|
||||||
props: sortParams(x.props.map((p: any) => parseParam(p))),
|
props: sortParams(Object.entries(x.props).map(([k, v]) => parsePropDefinition(k, v))),
|
||||||
propDefs: extractDefs(x.props)
|
propDefs: extractPropDefRef(x.props)
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue