From 029b92935c6119a01759c0e687eb0d9cef2dcf68 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Fri, 6 Jul 2018 12:17:38 +0900
Subject: [PATCH] wip

---
 gulpfile.ts                            |   2 +-
 locales/index.js                       |  27 ++++
 locales/index.ts                       |  34 -----
 src/build/i18n.ts                      |  10 +-
 src/client/docs/api/endpoints/view.pug |   4 +-
 src/client/docs/api/gulpfile.ts        | 201 -------------------------
 src/client/docs/api/mixins.pug         |  14 +-
 src/client/docs/gulpfile.ts            |  59 --------
 src/server/web/docs.ts                 |   8 +-
 webpack.config.ts                      |   2 +-
 10 files changed, 49 insertions(+), 312 deletions(-)
 create mode 100644 locales/index.js
 delete mode 100644 locales/index.ts
 delete mode 100644 src/client/docs/api/gulpfile.ts

diff --git a/gulpfile.ts b/gulpfile.ts
index 49a80879d2..607f77fc31 100644
--- a/gulpfile.ts
+++ b/gulpfile.ts
@@ -20,7 +20,7 @@ import * as replace from 'gulp-replace';
 import * as htmlmin from 'gulp-htmlmin';
 const uglifyes = require('uglify-es');
 
-import locales from './locales';
+const locales = require('./locales');
 import { fa } from './src/build/fa';
 const client = require('./built/client/meta.json');
 import config from './src/config';
diff --git a/locales/index.js b/locales/index.js
new file mode 100644
index 0000000000..95cc339169
--- /dev/null
+++ b/locales/index.js
@@ -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;
diff --git a/locales/index.ts b/locales/index.ts
deleted file mode 100644
index 45b5df0957..0000000000
--- a/locales/index.ts
+++ /dev/null
@@ -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;
diff --git a/src/build/i18n.ts b/src/build/i18n.ts
index dc48251c95..4ed3c7a2df 100644
--- a/src/build/i18n.ts
+++ b/src/build/i18n.ts
@@ -2,7 +2,7 @@
  * Replace i18n texts
  */
 
-import locale, { isAvailableLanguage, LocaleObject } from '../../locales';
+const locale = require('../../locales');
 
 export default class Replacer {
 	private lang: string;
@@ -16,8 +16,8 @@ export default class Replacer {
 		this.replacement = this.replacement.bind(this);
 	}
 
-	private get(path: string, key: string): string {
-		if (!isAvailableLanguage(this.lang)) {
+	public get(path: string, key: string): string {
+		if (!(this.lang in locale)) {
 			console.warn(`lang '${this.lang}' is not supported`);
 			return key; // Fallback
 		}
@@ -28,7 +28,7 @@ export default class Replacer {
 
 		if (path) {
 			if (text.hasOwnProperty(path)) {
-				text = text[path] as LocaleObject;
+				text = text[path];
 			} else {
 				console.warn(`path '${path}' not found in '${this.lang}'`);
 				return key; // Fallback
@@ -38,7 +38,7 @@ export default class Replacer {
 		// Check the key existance
 		const error = key.split('.').some(k => {
 			if (text.hasOwnProperty(k)) {
-				text = (text as LocaleObject)[k];
+				text = text[k];
 				return false;
 			} else {
 				return true;
diff --git a/src/client/docs/api/endpoints/view.pug b/src/client/docs/api/endpoints/view.pug
index f8795c8442..24fff1b798 100644
--- a/src/client/docs/api/endpoints/view.pug
+++ b/src/client/docs/api/endpoints/view.pug
@@ -17,7 +17,7 @@ block main
 	p#desc= desc[lang] || desc['ja']
 
 	section
-		h2 %i18n:docs.api.endpoints.params%
+		h2= i18n('docs.api.endpoints.params')
 		+propTable(params)
 
 		if paramDefs
@@ -28,5 +28,5 @@ block main
 
 	if res
 		section
-			h2 %i18n:docs.api.endpoints.res%
+			h2= i18n('docs.api.endpoints.res')
 			+propTable(res)
diff --git a/src/client/docs/api/gulpfile.ts b/src/client/docs/api/gulpfile.ts
deleted file mode 100644
index 4b38058b5c..0000000000
--- a/src/client/docs/api/gulpfile.ts
+++ /dev/null
@@ -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');
-					});
-				});
-			});
-		});
-	});
-});
diff --git a/src/client/docs/api/mixins.pug b/src/client/docs/api/mixins.pug
index 913135a85f..6762158f86 100644
--- a/src/client/docs/api/mixins.pug
+++ b/src/client/docs/api/mixins.pug
@@ -1,10 +1,10 @@
 mixin propTable(props)
 	table.props
 		thead: tr
-			th %i18n:docs.api.props.name%
-			th %i18n:docs.api.props.type%
-			th %i18n:docs.api.props.optional%
-			th %i18n:docs.api.props.description%
+			th= i18n('docs.api.props.name')
+			th= i18n('docs.api.props.type')
+			th= i18n('docs.api.props.optional')
+			th= i18n('docs.api.props.description')
 		tbody
 			each prop in props
 				tr
@@ -31,7 +31,7 @@ mixin propTable(props)
 							|  (Date)
 					td.optional
 						if prop.optional
-							| %i18n:docs.api.props.yes%
+							= i18n('docs.api.props.yes')
 						else
-							| %i18n:docs.api.props.no%
-					td.desc!= prop.desc[lang] || prop.desc['ja']
+							= i18n('docs.api.props.no')
+					td.desc!= prop.desc ? prop.desc[lang] || prop.desc['ja'] : null
diff --git a/src/client/docs/gulpfile.ts b/src/client/docs/gulpfile.ts
index 5ef87315fb..2a95dfbfee 100644
--- a/src/client/docs/gulpfile.ts
+++ b/src/client/docs/gulpfile.ts
@@ -2,73 +2,14 @@
  * 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 mkdirp from 'mkdirp';
 const stylus = require('gulp-stylus');
 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', [
-	'doc:docs',
-	//'doc:api',
 	'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.src('./src/client/docs/**/*.styl')
 		.pipe(stylus())
diff --git a/src/server/web/docs.ts b/src/server/web/docs.ts
index 849194388c..b1916abc13 100644
--- a/src/server/web/docs.ts
+++ b/src/server/web/docs.ts
@@ -9,6 +9,7 @@ import { Context } from 'cafy';
 import ObjectContext from 'cafy/built/types/object';
 import config from '../../config';
 import generateVars from '../../client/docs/vars';
+import I18n from '../../build/i18n';
 
 const docs = `${__dirname}/../../client/docs/`;
 
@@ -63,6 +64,7 @@ router.get('/assets/*', 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 vars = {
@@ -76,14 +78,16 @@ router.get('/*/api/endpoints/*', async ctx => {
 		params: sortParams(Object.keys(ep.params).map(k => parseEPDefParam(k, ep.params[k]))),
 		paramDefs: extractDefs(Object.keys(ep.params).map(k => ep.params[k])),
 	};
-	console.log(vars);
 
 	const commonVars = await generateVars();
 
+	const i18n = new I18n(lang);
+
 	await ctx.render('../../../../src/client/docs/api/endpoints/view', Object.assign({}, vars, {
-		lang: 'ja',
+		lang,
 		title: ep.name,
 		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
 	}));
 });
diff --git a/webpack.config.ts b/webpack.config.ts
index 3c426ebb49..1e49043764 100644
--- a/webpack.config.ts
+++ b/webpack.config.ts
@@ -19,7 +19,7 @@ const constants = require('./src/const.json');
 import config from './src/config';
 import { licenseHtml } from './src/build/license';
 
-import locales from './locales';
+const locales = require('./locales');
 const meta = require('./package.json');
 const version = meta.clientVersion;
 const codename = meta.codename;