forked from FoundKeyGang/FoundKey
wip
This commit is contained in:
parent
9b41023c43
commit
029b92935c
10 changed files with 49 additions and 312 deletions
|
@ -20,7 +20,7 @@ import * as replace from 'gulp-replace';
|
||||||
import * as htmlmin from 'gulp-htmlmin';
|
import * as htmlmin from 'gulp-htmlmin';
|
||||||
const uglifyes = require('uglify-es');
|
const uglifyes = require('uglify-es');
|
||||||
|
|
||||||
import locales from './locales';
|
const locales = require('./locales');
|
||||||
import { fa } from './src/build/fa';
|
import { fa } from './src/build/fa';
|
||||||
const client = require('./built/client/meta.json');
|
const client = require('./built/client/meta.json');
|
||||||
import config from './src/config';
|
import config from './src/config';
|
||||||
|
|
27
locales/index.js
Normal file
27
locales/index.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* Languages Loader
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const yaml = require('js-yaml');
|
||||||
|
|
||||||
|
const loadLang = lang => yaml.safeLoad(
|
||||||
|
fs.readFileSync(`./locales/${lang}.yml`, 'utf-8'));
|
||||||
|
|
||||||
|
const native = loadLang('ja');
|
||||||
|
|
||||||
|
const langs = {
|
||||||
|
'de': loadLang('de'),
|
||||||
|
'en': loadLang('en'),
|
||||||
|
'fr': loadLang('fr'),
|
||||||
|
'ja': native,
|
||||||
|
'pl': loadLang('pl'),
|
||||||
|
'es': loadLang('es')
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(langs).map(([, locale]) => {
|
||||||
|
// Extend native language (Japanese)
|
||||||
|
locale = Object.assign({}, native, locale);
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = langs;
|
|
@ -1,34 +0,0 @@
|
||||||
/**
|
|
||||||
* Languages Loader
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as yaml from 'js-yaml';
|
|
||||||
|
|
||||||
export type LangKey = 'de' | 'en' | 'fr' | 'ja' | 'pl' | 'es';
|
|
||||||
export type LocaleObject = { [key: string]: any };
|
|
||||||
|
|
||||||
const loadLang = (lang: LangKey) => yaml.safeLoad(
|
|
||||||
fs.readFileSync(`./locales/${lang}.yml`, 'utf-8')) as LocaleObject;
|
|
||||||
|
|
||||||
const native = loadLang('ja');
|
|
||||||
|
|
||||||
const langs: { [key: string]: LocaleObject } = {
|
|
||||||
'de': loadLang('de'),
|
|
||||||
'en': loadLang('en'),
|
|
||||||
'fr': loadLang('fr'),
|
|
||||||
'ja': native,
|
|
||||||
'pl': loadLang('pl'),
|
|
||||||
'es': loadLang('es')
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.entries(langs).map(([, locale]) => {
|
|
||||||
// Extend native language (Japanese)
|
|
||||||
locale = Object.assign({}, native, locale);
|
|
||||||
});
|
|
||||||
|
|
||||||
export function isAvailableLanguage(lang: string): lang is LangKey {
|
|
||||||
return lang in langs;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default langs;
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Replace i18n texts
|
* Replace i18n texts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import locale, { isAvailableLanguage, LocaleObject } from '../../locales';
|
const locale = require('../../locales');
|
||||||
|
|
||||||
export default class Replacer {
|
export default class Replacer {
|
||||||
private lang: string;
|
private lang: string;
|
||||||
|
@ -16,8 +16,8 @@ export default class Replacer {
|
||||||
this.replacement = this.replacement.bind(this);
|
this.replacement = this.replacement.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private get(path: string, key: string): string {
|
public get(path: string, key: string): string {
|
||||||
if (!isAvailableLanguage(this.lang)) {
|
if (!(this.lang in locale)) {
|
||||||
console.warn(`lang '${this.lang}' is not supported`);
|
console.warn(`lang '${this.lang}' is not supported`);
|
||||||
return key; // Fallback
|
return key; // Fallback
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ export default class Replacer {
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
if (text.hasOwnProperty(path)) {
|
if (text.hasOwnProperty(path)) {
|
||||||
text = text[path] as LocaleObject;
|
text = text[path];
|
||||||
} else {
|
} else {
|
||||||
console.warn(`path '${path}' not found in '${this.lang}'`);
|
console.warn(`path '${path}' not found in '${this.lang}'`);
|
||||||
return key; // Fallback
|
return key; // Fallback
|
||||||
|
@ -38,7 +38,7 @@ export default class Replacer {
|
||||||
// Check the key existance
|
// Check the key existance
|
||||||
const error = key.split('.').some(k => {
|
const error = key.split('.').some(k => {
|
||||||
if (text.hasOwnProperty(k)) {
|
if (text.hasOwnProperty(k)) {
|
||||||
text = (text as LocaleObject)[k];
|
text = text[k];
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -17,7 +17,7 @@ block main
|
||||||
p#desc= desc[lang] || desc['ja']
|
p#desc= desc[lang] || desc['ja']
|
||||||
|
|
||||||
section
|
section
|
||||||
h2 %i18n:docs.api.endpoints.params%
|
h2= i18n('docs.api.endpoints.params')
|
||||||
+propTable(params)
|
+propTable(params)
|
||||||
|
|
||||||
if paramDefs
|
if paramDefs
|
||||||
|
@ -28,5 +28,5 @@ block main
|
||||||
|
|
||||||
if res
|
if res
|
||||||
section
|
section
|
||||||
h2 %i18n:docs.api.endpoints.res%
|
h2= i18n('docs.api.endpoints.res')
|
||||||
+propTable(res)
|
+propTable(res)
|
||||||
|
|
|
@ -1,201 +0,0 @@
|
||||||
/**
|
|
||||||
* Gulp tasks
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
import * as glob from 'glob';
|
|
||||||
import * as gulp from 'gulp';
|
|
||||||
import * as pug from 'pug';
|
|
||||||
import * as yaml from 'js-yaml';
|
|
||||||
import * as mkdirp from 'mkdirp';
|
|
||||||
|
|
||||||
import locales from '../../../../locales';
|
|
||||||
import I18nReplacer from '../../../build/i18n';
|
|
||||||
import fa from '../../../build/fa';
|
|
||||||
import config from './../../../config';
|
|
||||||
|
|
||||||
import generateVars from '../vars';
|
|
||||||
import { Context } from 'cafy';
|
|
||||||
import ObjectContext from 'cafy/built/types/object';
|
|
||||||
|
|
||||||
const langs = Object.keys(locales);
|
|
||||||
|
|
||||||
const kebab = (string: string) => string.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\s+/g, '-').toLowerCase();
|
|
||||||
|
|
||||||
const parseParam = (param: any) => {
|
|
||||||
const id = param.type.match(/^id\((.+?)\)|^id/);
|
|
||||||
const entity = param.type.match(/^entity\((.+?)\)/);
|
|
||||||
const isObject = /^object/.test(param.type);
|
|
||||||
const isDate = /^date/.test(param.type);
|
|
||||||
const isArray = /\[\]$/.test(param.type);
|
|
||||||
if (id) {
|
|
||||||
param.kind = 'id';
|
|
||||||
param.type = 'string';
|
|
||||||
param.entity = id[1];
|
|
||||||
if (isArray) {
|
|
||||||
param.type += '[]';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (entity) {
|
|
||||||
param.kind = 'entity';
|
|
||||||
param.type = 'object';
|
|
||||||
param.entity = entity[1];
|
|
||||||
if (isArray) {
|
|
||||||
param.type += '[]';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isObject) {
|
|
||||||
param.kind = 'object';
|
|
||||||
}
|
|
||||||
if (isDate) {
|
|
||||||
param.kind = 'date';
|
|
||||||
param.type = 'string';
|
|
||||||
if (isArray) {
|
|
||||||
param.type += '[]';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return param;
|
|
||||||
};
|
|
||||||
|
|
||||||
// WIP type
|
|
||||||
const parseEPDefParam = (key: string, param: Context) => {
|
|
||||||
return Object.assign({
|
|
||||||
name: key,
|
|
||||||
type: param.getType()
|
|
||||||
}, param.data);
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
// WIP type
|
|
||||||
const extractDefs = (params: Context[]) => {
|
|
||||||
let defs: any[] = [];
|
|
||||||
|
|
||||||
params.forEach(param => {
|
|
||||||
if (param.data && param.data.ref) {
|
|
||||||
const props = (param as ObjectContext<any>).props;
|
|
||||||
defs.push({
|
|
||||||
name: param.data.ref,
|
|
||||||
params: sortParams(Object.keys(props).map(k => parseEPDefParam(k, props[k])))
|
|
||||||
});
|
|
||||||
|
|
||||||
const childDefs = extractDefs(Object.keys(props).map(k => props[k]));
|
|
||||||
|
|
||||||
defs = defs.concat(childDefs);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return sortParams(defs);
|
|
||||||
};
|
|
||||||
|
|
||||||
gulp.task('doc:api', [
|
|
||||||
'doc:api:endpoints',
|
|
||||||
'doc:api:entities'
|
|
||||||
]);
|
|
||||||
|
|
||||||
gulp.task('doc:api:endpoints', ['build:ts'], async () => {
|
|
||||||
const commonVars = await generateVars();
|
|
||||||
glob('./built/server/api/endpoints/**/*.js', (globErr, files) => {
|
|
||||||
if (globErr) {
|
|
||||||
console.error(globErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log(files.map(file => require('../../../../' + file)));
|
|
||||||
|
|
||||||
files.map(file => require('../../../../' + file)).filter(x => x.meta).map(x => x.meta).forEach(ep => {
|
|
||||||
console.log(ep);
|
|
||||||
const vars = {
|
|
||||||
endpoint: ep.name,
|
|
||||||
url: {
|
|
||||||
host: config.api_url,
|
|
||||||
path: ep.name
|
|
||||||
},
|
|
||||||
desc: ep.desc,
|
|
||||||
// @ts-ignore
|
|
||||||
params: sortParams(ep.params.map(p => parseEPDefParam(p))),
|
|
||||||
paramDefs: extractDefs(ep.params),
|
|
||||||
};
|
|
||||||
langs.forEach(lang => {
|
|
||||||
pug.renderFile('./src/client/docs/api/endpoints/view.pug', Object.assign({}, vars, {
|
|
||||||
lang,
|
|
||||||
title: ep.name,
|
|
||||||
src: `https://github.com/syuilo/misskey/tree/master/src/client/docs/api/endpoints/${ep.name}.yaml`,
|
|
||||||
kebab,
|
|
||||||
common: commonVars
|
|
||||||
}), (renderErr, html) => {
|
|
||||||
if (renderErr) {
|
|
||||||
console.error(renderErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const i18n = new I18nReplacer(lang);
|
|
||||||
html = html.replace(i18n.pattern, i18n.replacement);
|
|
||||||
html = fa(html);
|
|
||||||
const htmlPath = `./built/client/docs/${lang}/api/endpoints/${ep.name}.html`;
|
|
||||||
mkdirp(path.dirname(htmlPath), (mkdirErr) => {
|
|
||||||
if (mkdirErr) {
|
|
||||||
console.error(mkdirErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fs.writeFileSync(htmlPath, html, 'utf-8');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('doc:api:entities', async () => {
|
|
||||||
const commonVars = await generateVars();
|
|
||||||
glob('./src/client/docs/api/entities/**/*.yaml', (globErr, files) => {
|
|
||||||
if (globErr) {
|
|
||||||
console.error(globErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
files.forEach(file => {
|
|
||||||
const entity = yaml.safeLoad(fs.readFileSync(file, 'utf-8')) as any;
|
|
||||||
const vars = {
|
|
||||||
name: entity.name,
|
|
||||||
desc: entity.desc,
|
|
||||||
// WIP type
|
|
||||||
props: sortParams(entity.props.map((p: any) => parseParam(p))),
|
|
||||||
propDefs: extractDefs(entity.props),
|
|
||||||
};
|
|
||||||
langs.forEach(lang => {
|
|
||||||
pug.renderFile('./src/client/docs/api/entities/view.pug', Object.assign({}, vars, {
|
|
||||||
lang,
|
|
||||||
title: entity.name,
|
|
||||||
src: `https://github.com/syuilo/misskey/tree/master/src/client/docs/api/entities/${kebab(entity.name)}.yaml`,
|
|
||||||
kebab,
|
|
||||||
common: commonVars
|
|
||||||
}), (renderErr, html) => {
|
|
||||||
if (renderErr) {
|
|
||||||
console.error(renderErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const i18n = new I18nReplacer(lang);
|
|
||||||
html = html.replace(i18n.pattern, i18n.replacement);
|
|
||||||
html = fa(html);
|
|
||||||
const htmlPath = `./built/client/docs/${lang}/api/entities/${kebab(entity.name)}.html`;
|
|
||||||
mkdirp(path.dirname(htmlPath), (mkdirErr) => {
|
|
||||||
if (mkdirErr) {
|
|
||||||
console.error(mkdirErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fs.writeFileSync(htmlPath, html, 'utf-8');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,10 +1,10 @@
|
||||||
mixin propTable(props)
|
mixin propTable(props)
|
||||||
table.props
|
table.props
|
||||||
thead: tr
|
thead: tr
|
||||||
th %i18n:docs.api.props.name%
|
th= i18n('docs.api.props.name')
|
||||||
th %i18n:docs.api.props.type%
|
th= i18n('docs.api.props.type')
|
||||||
th %i18n:docs.api.props.optional%
|
th= i18n('docs.api.props.optional')
|
||||||
th %i18n:docs.api.props.description%
|
th= i18n('docs.api.props.description')
|
||||||
tbody
|
tbody
|
||||||
each prop in props
|
each prop in props
|
||||||
tr
|
tr
|
||||||
|
@ -31,7 +31,7 @@ mixin propTable(props)
|
||||||
| (Date)
|
| (Date)
|
||||||
td.optional
|
td.optional
|
||||||
if prop.optional
|
if prop.optional
|
||||||
| %i18n:docs.api.props.yes%
|
= i18n('docs.api.props.yes')
|
||||||
else
|
else
|
||||||
| %i18n:docs.api.props.no%
|
= i18n('docs.api.props.no')
|
||||||
td.desc!= prop.desc[lang] || prop.desc['ja']
|
td.desc!= prop.desc ? prop.desc[lang] || prop.desc['ja'] : null
|
||||||
|
|
|
@ -2,73 +2,14 @@
|
||||||
* Gulp tasks
|
* Gulp tasks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
import * as glob from 'glob';
|
|
||||||
import * as gulp from 'gulp';
|
import * as gulp from 'gulp';
|
||||||
import * as pug from 'pug';
|
|
||||||
import * as mkdirp from 'mkdirp';
|
|
||||||
const stylus = require('gulp-stylus');
|
const stylus = require('gulp-stylus');
|
||||||
const cssnano = require('gulp-cssnano');
|
const cssnano = require('gulp-cssnano');
|
||||||
|
|
||||||
import I18nReplacer from '../../build/i18n';
|
|
||||||
import fa from '../../build/fa';
|
|
||||||
import generateVars from './vars';
|
|
||||||
|
|
||||||
//require('./api/gulpfile.ts');
|
|
||||||
|
|
||||||
gulp.task('doc', [
|
gulp.task('doc', [
|
||||||
'doc:docs',
|
|
||||||
//'doc:api',
|
|
||||||
'doc:styles'
|
'doc:styles'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
gulp.task('doc:docs', async () => {
|
|
||||||
const commonVars = await generateVars();
|
|
||||||
|
|
||||||
glob('./src/client/docs/**/*.*.pug', (globErr, files) => {
|
|
||||||
if (globErr) {
|
|
||||||
console.error(globErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
files.forEach(file => {
|
|
||||||
const [, name, lang] = file.match(/docs\/(.+?)\.(.+?)\.pug$/);
|
|
||||||
const vars = {
|
|
||||||
common: commonVars,
|
|
||||||
lang: lang,
|
|
||||||
title: fs.readFileSync(file, 'utf-8').match(/^h1 (.+?)\r?\n/)[1],
|
|
||||||
src: `https://github.com/syuilo/misskey/tree/master/src/client/docs/${name}.${lang}.pug`,
|
|
||||||
};
|
|
||||||
pug.renderFile(file, vars, (renderErr, content) => {
|
|
||||||
if (renderErr) {
|
|
||||||
console.error(renderErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pug.renderFile('./src/client/docs/layout.pug', Object.assign({}, vars, {
|
|
||||||
content
|
|
||||||
}), (renderErr2, html) => {
|
|
||||||
if (renderErr2) {
|
|
||||||
console.error(renderErr2);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const i18n = new I18nReplacer(lang);
|
|
||||||
html = html.replace(i18n.pattern, i18n.replacement);
|
|
||||||
html = fa(html);
|
|
||||||
const htmlPath = `./built/client/docs/${lang}/${name}.html`;
|
|
||||||
mkdirp(path.dirname(htmlPath), (mkdirErr) => {
|
|
||||||
if (mkdirErr) {
|
|
||||||
console.error(mkdirErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fs.writeFileSync(htmlPath, html, 'utf-8');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('doc:styles', () =>
|
gulp.task('doc:styles', () =>
|
||||||
gulp.src('./src/client/docs/**/*.styl')
|
gulp.src('./src/client/docs/**/*.styl')
|
||||||
.pipe(stylus())
|
.pipe(stylus())
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { Context } from 'cafy';
|
||||||
import ObjectContext from 'cafy/built/types/object';
|
import ObjectContext from 'cafy/built/types/object';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import generateVars from '../../client/docs/vars';
|
import generateVars from '../../client/docs/vars';
|
||||||
|
import I18n from '../../build/i18n';
|
||||||
|
|
||||||
const docs = `${__dirname}/../../client/docs/`;
|
const docs = `${__dirname}/../../client/docs/`;
|
||||||
|
|
||||||
|
@ -63,6 +64,7 @@ router.get('/assets/*', async ctx => {
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/*/api/endpoints/*', async ctx => {
|
router.get('/*/api/endpoints/*', async ctx => {
|
||||||
|
const lang = ctx.params[0];
|
||||||
const ep = require('../../../built/server/api/endpoints/' + ctx.params[1]).meta;
|
const ep = require('../../../built/server/api/endpoints/' + ctx.params[1]).meta;
|
||||||
|
|
||||||
const vars = {
|
const vars = {
|
||||||
|
@ -76,14 +78,16 @@ router.get('/*/api/endpoints/*', async ctx => {
|
||||||
params: sortParams(Object.keys(ep.params).map(k => parseEPDefParam(k, ep.params[k]))),
|
params: sortParams(Object.keys(ep.params).map(k => parseEPDefParam(k, ep.params[k]))),
|
||||||
paramDefs: extractDefs(Object.keys(ep.params).map(k => ep.params[k])),
|
paramDefs: extractDefs(Object.keys(ep.params).map(k => ep.params[k])),
|
||||||
};
|
};
|
||||||
console.log(vars);
|
|
||||||
|
|
||||||
const commonVars = await generateVars();
|
const commonVars = await generateVars();
|
||||||
|
|
||||||
|
const i18n = new I18n(lang);
|
||||||
|
|
||||||
await ctx.render('../../../../src/client/docs/api/endpoints/view', Object.assign({}, vars, {
|
await ctx.render('../../../../src/client/docs/api/endpoints/view', Object.assign({}, vars, {
|
||||||
lang: 'ja',
|
lang,
|
||||||
title: ep.name,
|
title: ep.name,
|
||||||
kebab: (string: string) => string.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\s+/g, '-').toLowerCase(),
|
kebab: (string: string) => string.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\s+/g, '-').toLowerCase(),
|
||||||
|
i18n: (key: string) => i18n.get(null, key),
|
||||||
common: commonVars
|
common: commonVars
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,7 +19,7 @@ const constants = require('./src/const.json');
|
||||||
import config from './src/config';
|
import config from './src/config';
|
||||||
import { licenseHtml } from './src/build/license';
|
import { licenseHtml } from './src/build/license';
|
||||||
|
|
||||||
import locales from './locales';
|
const locales = require('./locales');
|
||||||
const meta = require('./package.json');
|
const meta = require('./package.json');
|
||||||
const version = meta.clientVersion;
|
const version = meta.clientVersion;
|
||||||
const codename = meta.codename;
|
const codename = meta.codename;
|
||||||
|
|
Loading…
Reference in a new issue