From 3fb6834f7d06d52163102b69afe353f8c65ee003 Mon Sep 17 00:00:00 2001
From: Akihiko Odaki <nekomanma@pixiv.co.jp>
Date: Mon, 2 Apr 2018 13:15:53 +0900
Subject: [PATCH] Introduce config module

---
 gulpfile.ts                                   |   2 +-
 src/client/docs/api/gulpfile.ts               |   2 +-
 src/client/docs/vars.ts                       |   2 +-
 src/conf.ts                                   |   3 -
 src/config.ts                                 | 154 ------------------
 src/config/index.ts                           |   3 +
 src/config/load.ts                            |  57 +++++++
 src/config/types.ts                           |  97 +++++++++++
 src/db/elasticsearch.ts                       |   2 +-
 src/db/mongodb.ts                             |   2 +-
 src/db/redis.ts                               |   2 +-
 src/drive/add-file.ts                         |   2 +-
 src/event.ts                                  |   2 +-
 src/index.ts                                  |  19 ++-
 src/models/app.ts                             |   2 +-
 src/models/drive-file.ts                      |   2 +-
 src/models/user.ts                            |   2 +-
 src/othello/ai/back.ts                        |   2 +-
 src/othello/ai/front.ts                       |   2 +-
 src/processor/http/follow.ts                  |   2 +-
 src/push-sw.ts                                |   2 +-
 src/queue.ts                                  |   2 +-
 src/remote/activitypub/create.ts              |   2 +-
 src/remote/activitypub/renderer/document.ts   |   2 +-
 src/remote/activitypub/renderer/follow.ts     |   2 +-
 src/remote/activitypub/renderer/hashtag.ts    |   2 +-
 src/remote/activitypub/renderer/image.ts      |   2 +-
 src/remote/activitypub/renderer/key.ts        |   2 +-
 src/remote/activitypub/renderer/note.ts       |   2 +-
 src/remote/activitypub/renderer/person.ts     |   2 +-
 src/server/activitypub/outbox.ts              |   2 +-
 src/server/activitypub/publickey.ts           |   2 +-
 src/server/activitypub/user.ts                |   2 +-
 src/server/api/bot/interfaces/line.ts         |   2 +-
 src/server/api/common/signin.ts               |   2 +-
 .../api/endpoints/auth/session/generate.ts    |   2 +-
 src/server/api/endpoints/i/2fa/register.ts    |   2 +-
 src/server/api/endpoints/i/update.ts          |   2 +-
 .../endpoints/messaging/messages/create.ts    |   2 +-
 src/server/api/endpoints/meta.ts              |   2 +-
 src/server/api/endpoints/posts/create.ts      |   2 +-
 src/server/api/endpoints/users/search.ts      |   2 +-
 src/server/api/private/signin.ts              |   2 +-
 src/server/api/private/signup.ts              |   2 +-
 src/server/api/service/github.ts              |   2 +-
 src/server/api/service/twitter.ts             |   2 +-
 src/server/api/streaming.ts                   |   2 +-
 src/server/index.ts                           |   2 +-
 src/server/webfinger.ts                       |   2 +-
 webpack.config.ts                             |   2 +-
 50 files changed, 213 insertions(+), 208 deletions(-)
 delete mode 100644 src/conf.ts
 delete mode 100644 src/config.ts
 create mode 100644 src/config/index.ts
 create mode 100644 src/config/load.ts
 create mode 100644 src/config/types.ts

diff --git a/gulpfile.ts b/gulpfile.ts
index a6e9e53df3..f372ed2993 100644
--- a/gulpfile.ts
+++ b/gulpfile.ts
@@ -24,7 +24,7 @@ const uglifyes = require('uglify-es');
 
 import { fa } from './src/build/fa';
 import version from './src/version';
-import config from './src/conf';
+import config from './src/config';
 
 const uglify = uglifyComposer(uglifyes, console);
 
diff --git a/src/client/docs/api/gulpfile.ts b/src/client/docs/api/gulpfile.ts
index 4b962fe0c6..c986e0353a 100644
--- a/src/client/docs/api/gulpfile.ts
+++ b/src/client/docs/api/gulpfile.ts
@@ -13,7 +13,7 @@ import * as mkdirp from 'mkdirp';
 import locales from '../../../../locales';
 import I18nReplacer from '../../../build/i18n';
 import fa from '../../../build/fa';
-import config from './../../../conf';
+import config from './../../../config';
 
 import generateVars from '../vars';
 
diff --git a/src/client/docs/vars.ts b/src/client/docs/vars.ts
index 1a3b48bd76..dbdc880611 100644
--- a/src/client/docs/vars.ts
+++ b/src/client/docs/vars.ts
@@ -6,7 +6,7 @@ import * as licenseChecker from 'license-checker';
 import * as tmp from 'tmp';
 
 import { fa } from '../../build/fa';
-import config from '../../conf';
+import config from '../../config';
 import { licenseHtml } from '../../build/license';
 const constants = require('../../const.json');
 
diff --git a/src/conf.ts b/src/conf.ts
deleted file mode 100644
index b04a4c8594..0000000000
--- a/src/conf.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import load from './config';
-
-export default load();
diff --git a/src/config.ts b/src/config.ts
deleted file mode 100644
index 6d3e7740b1..0000000000
--- a/src/config.ts
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * Config loader
- */
-
-import * as fs from 'fs';
-import { URL } from 'url';
-import * as yaml from 'js-yaml';
-import isUrl = require('is-url');
-
-/**
- * Path of configuration directory
- */
-const dir = `${__dirname}/../.config`;
-
-/**
- * Path of configuration file
- */
-export const path = process.env.NODE_ENV == 'test'
-	? `${dir}/test.yml`
-	: `${dir}/default.yml`;
-
-/**
- * ユーザーが設定する必要のある情報
- */
-type Source = {
-	/**
-	 * メンテナ情報
-	 */
-	maintainer: {
-		/**
-		 * メンテナの名前
-		 */
-		name: string;
-		/**
-		 * メンテナの連絡先(URLかmailto形式のURL)
-		 */
-		url: string;
-	};
-	url: string;
-	port: number;
-	https?: { [x: string]: string };
-	mongodb: {
-		host: string;
-		port: number;
-		db: string;
-		user: string;
-		pass: string;
-	};
-	redis: {
-		host: string;
-		port: number;
-		pass: string;
-	};
-	elasticsearch: {
-		enable: boolean;
-		host: string;
-		port: number;
-		pass: string;
-	};
-	recaptcha: {
-		site_key: string;
-		secret_key: string;
-	};
-	accesslog?: string;
-	accesses?: {
-		enable: boolean;
-		port: number;
-	};
-	twitter?: {
-		consumer_key: string;
-		consumer_secret: string;
-	};
-	github_bot?: {
-		hook_secret: string;
-		username: string;
-	};
-	othello_ai?: {
-		id: string;
-		i: string;
-	};
-	line_bot?: {
-		channel_secret: string;
-		channel_access_token: string;
-	};
-	analysis?: {
-		mecab_command?: string;
-	};
-
-	/**
-	 * Service Worker
-	 */
-	sw?: {
-		public_key: string;
-		private_key: string;
-	};
-
-	google_maps_api_key: string;
-};
-
-/**
- * Misskeyが自動的に(ユーザーが設定した情報から推論して)設定する情報
- */
-type Mixin = {
-	host: string;
-	hostname: string;
-	scheme: string;
-	ws_scheme: string;
-	api_url: string;
-	ws_url: string;
-	auth_url: string;
-	docs_url: string;
-	stats_url: string;
-	status_url: string;
-	dev_url: string;
-	drive_url: string;
-};
-
-export type Config = Source & Mixin;
-
-export default function load() {
-	const config = yaml.safeLoad(fs.readFileSync(path, 'utf-8')) as Source;
-
-	const mixin = {} as Mixin;
-
-	// Validate URLs
-	if (!isUrl(config.url)) urlError(config.url);
-
-	const url = new URL(config.url);
-	config.url = normalizeUrl(config.url);
-
-	mixin.host = url.host;
-	mixin.hostname = url.hostname;
-	mixin.scheme = url.protocol.replace(/:$/, '');
-	mixin.ws_scheme = mixin.scheme.replace('http', 'ws');
-	mixin.ws_url = `${mixin.ws_scheme}://${mixin.host}`;
-	mixin.api_url = `${mixin.scheme}://${mixin.host}/api`;
-	mixin.auth_url = `${mixin.scheme}://${mixin.host}/auth`;
-	mixin.dev_url = `${mixin.scheme}://${mixin.host}/dev`;
-	mixin.docs_url = `${mixin.scheme}://${mixin.host}/docs`;
-	mixin.stats_url = `${mixin.scheme}://${mixin.host}/stats`;
-	mixin.status_url = `${mixin.scheme}://${mixin.host}/status`;
-	mixin.drive_url = `${mixin.scheme}://${mixin.host}/files`;
-
-	return Object.assign(config, mixin);
-}
-
-function normalizeUrl(url: string) {
-	return url[url.length - 1] === '/' ? url.substr(0, url.length - 1) : url;
-}
-
-function urlError(url: string) {
-	console.error(`「${url}」は、正しいURLではありません。先頭に http:// または https:// をつけ忘れてないかなど確認してください。`);
-	process.exit();
-}
diff --git a/src/config/index.ts b/src/config/index.ts
new file mode 100644
index 0000000000..7bfdca4612
--- /dev/null
+++ b/src/config/index.ts
@@ -0,0 +1,3 @@
+import load from './load';
+
+export default load();
diff --git a/src/config/load.ts b/src/config/load.ts
new file mode 100644
index 0000000000..9f4e2151f3
--- /dev/null
+++ b/src/config/load.ts
@@ -0,0 +1,57 @@
+/**
+ * Config loader
+ */
+
+import * as fs from 'fs';
+import { URL } from 'url';
+import * as yaml from 'js-yaml';
+import { Source, Mixin } from './types';
+import isUrl = require('is-url');
+
+/**
+ * Path of configuration directory
+ */
+const dir = `${__dirname}/../../.config`;
+
+/**
+ * Path of configuration file
+ */
+const path = process.env.NODE_ENV == 'test'
+	? `${dir}/test.yml`
+	: `${dir}/default.yml`;
+
+export default function load() {
+	const config = yaml.safeLoad(fs.readFileSync(path, 'utf-8')) as Source;
+
+	const mixin = {} as Mixin;
+
+	// Validate URLs
+	if (!isUrl(config.url)) urlError(config.url);
+
+	const url = new URL(config.url);
+	config.url = normalizeUrl(config.url);
+
+	mixin.host = url.host;
+	mixin.hostname = url.hostname;
+	mixin.scheme = url.protocol.replace(/:$/, '');
+	mixin.ws_scheme = mixin.scheme.replace('http', 'ws');
+	mixin.ws_url = `${mixin.ws_scheme}://${mixin.host}`;
+	mixin.api_url = `${mixin.scheme}://${mixin.host}/api`;
+	mixin.auth_url = `${mixin.scheme}://${mixin.host}/auth`;
+	mixin.dev_url = `${mixin.scheme}://${mixin.host}/dev`;
+	mixin.docs_url = `${mixin.scheme}://${mixin.host}/docs`;
+	mixin.stats_url = `${mixin.scheme}://${mixin.host}/stats`;
+	mixin.status_url = `${mixin.scheme}://${mixin.host}/status`;
+	mixin.drive_url = `${mixin.scheme}://${mixin.host}/files`;
+
+	return Object.assign(config, mixin);
+}
+
+function normalizeUrl(url: string) {
+	return url[url.length - 1] === '/' ? url.substr(0, url.length - 1) : url;
+}
+
+function urlError(url: string) {
+	console.error(`「${url}」は、正しいURLではありません。先頭に http:// または https:// をつけ忘れてないかなど確認してください。`);
+	process.exit();
+}
diff --git a/src/config/types.ts b/src/config/types.ts
new file mode 100644
index 0000000000..f802e70d1e
--- /dev/null
+++ b/src/config/types.ts
@@ -0,0 +1,97 @@
+/**
+ * ユーザーが設定する必要のある情報
+ */
+export type Source = {
+	/**
+	 * メンテナ情報
+	 */
+	maintainer: {
+		/**
+		 * メンテナの名前
+		 */
+		name: string;
+		/**
+		 * メンテナの連絡先(URLかmailto形式のURL)
+		 */
+		url: string;
+	};
+	url: string;
+	port: number;
+	https?: { [x: string]: string };
+	mongodb: {
+		host: string;
+		port: number;
+		db: string;
+		user: string;
+		pass: string;
+	};
+	redis: {
+		host: string;
+		port: number;
+		pass: string;
+	};
+	elasticsearch: {
+		enable: boolean;
+		host: string;
+		port: number;
+		pass: string;
+	};
+	recaptcha: {
+		site_key: string;
+		secret_key: string;
+	};
+	accesslog?: string;
+	accesses?: {
+		enable: boolean;
+		port: number;
+	};
+	twitter?: {
+		consumer_key: string;
+		consumer_secret: string;
+	};
+	github_bot?: {
+		hook_secret: string;
+		username: string;
+	};
+	othello_ai?: {
+		id: string;
+		i: string;
+	};
+	line_bot?: {
+		channel_secret: string;
+		channel_access_token: string;
+	};
+	analysis?: {
+		mecab_command?: string;
+	};
+
+	/**
+	 * Service Worker
+	 */
+	sw?: {
+		public_key: string;
+		private_key: string;
+	};
+
+	google_maps_api_key: string;
+};
+
+/**
+ * Misskeyが自動的に(ユーザーが設定した情報から推論して)設定する情報
+ */
+export type Mixin = {
+	host: string;
+	hostname: string;
+	scheme: string;
+	ws_scheme: string;
+	api_url: string;
+	ws_url: string;
+	auth_url: string;
+	docs_url: string;
+	stats_url: string;
+	status_url: string;
+	dev_url: string;
+	drive_url: string;
+};
+
+export type Config = Source & Mixin;
diff --git a/src/db/elasticsearch.ts b/src/db/elasticsearch.ts
index 75054a31c2..957b7ad97d 100644
--- a/src/db/elasticsearch.ts
+++ b/src/db/elasticsearch.ts
@@ -1,5 +1,5 @@
 import * as elasticsearch from 'elasticsearch';
-import config from '../conf';
+import config from '../config';
 
 // Init ElasticSearch connection
 const client = new elasticsearch.Client({
diff --git a/src/db/mongodb.ts b/src/db/mongodb.ts
index 233f2f3d79..05bb72bfde 100644
--- a/src/db/mongodb.ts
+++ b/src/db/mongodb.ts
@@ -1,4 +1,4 @@
-import config from '../conf';
+import config from '../config';
 
 const u = config.mongodb.user ? encodeURIComponent(config.mongodb.user) : null;
 const p = config.mongodb.pass ? encodeURIComponent(config.mongodb.pass) : null;
diff --git a/src/db/redis.ts b/src/db/redis.ts
index 2e0867de61..f8d66ebda0 100644
--- a/src/db/redis.ts
+++ b/src/db/redis.ts
@@ -1,5 +1,5 @@
 import * as redis from 'redis';
-import config from '../conf';
+import config from '../config';
 
 export default redis.createClient(
 	config.redis.port,
diff --git a/src/drive/add-file.ts b/src/drive/add-file.ts
index f356af00d8..db13e04be0 100644
--- a/src/drive/add-file.ts
+++ b/src/drive/add-file.ts
@@ -15,7 +15,7 @@ import DriveFolder from '../models/drive-folder';
 import { pack } from '../models/drive-file';
 import event, { publishDriveStream } from '../event';
 import getAcct from '../user/get-acct';
-import config from '../conf';
+import config from '../config';
 
 const gm = _gm.subClass({
 	imageMagick: true
diff --git a/src/event.ts b/src/event.ts
index df79f0c90d..81876b3cf4 100644
--- a/src/event.ts
+++ b/src/event.ts
@@ -1,7 +1,7 @@
 import * as mongo from 'mongodb';
 import * as redis from 'redis';
 import swPush from './push-sw';
-import config from './conf';
+import config from './config';
 
 type ID = string | mongo.ObjectID;
 
diff --git a/src/index.ts b/src/index.ts
index f86c768fdc..b43e152854 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -4,7 +4,6 @@
 
 Error.stackTraceLimit = Infinity;
 
-import * as fs from 'fs';
 import * as os from 'os';
 import * as cluster from 'cluster';
 import * as debug from 'debug';
@@ -21,8 +20,8 @@ import MachineInfo from './utils/machineInfo';
 import DependencyInfo from './utils/dependencyInfo';
 import stats from './utils/stats';
 
-import { Config, path as configPath } from './config';
-import loadConfig from './config';
+import loadConfig from './config/load';
+import { Config } from './config/types';
 
 import parseOpt from './parse-opt';
 
@@ -116,11 +115,17 @@ async function init(): Promise<Config> {
 	new DependencyInfo().showAll();
 
 	const configLogger = new Logger('Config');
-	if (!fs.existsSync(configPath)) {
-		throw 'Configuration not found - Please run "npm run config" command.';
-	}
+	let config;
 
-	const config = loadConfig();
+	try {
+		config = loadConfig();
+	} catch (exception) {
+		if (exception.code === 'ENOENT') {
+			throw 'Configuration not found - Please run "npm run config" command.';
+		}
+
+		throw exception;
+	}
 
 	configLogger.info('Successfully loaded');
 	configLogger.info(`maintainer: ${config.maintainer}`);
diff --git a/src/models/app.ts b/src/models/app.ts
index 3b80a1602f..83162a6b99 100644
--- a/src/models/app.ts
+++ b/src/models/app.ts
@@ -2,7 +2,7 @@ import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
 import AccessToken from './access-token';
 import db from '../db/mongodb';
-import config from '../conf';
+import config from '../config';
 
 const App = db.get<IApp>('apps');
 App.createIndex('nameId');
diff --git a/src/models/drive-file.ts b/src/models/drive-file.ts
index 9e0df58c45..fba1aebdae 100644
--- a/src/models/drive-file.ts
+++ b/src/models/drive-file.ts
@@ -1,7 +1,7 @@
 import * as mongodb from 'mongodb';
 import deepcopy = require('deepcopy');
 import { pack as packFolder } from './drive-folder';
-import config from '../conf';
+import config from '../config';
 import monkDb, { nativeDbConn } from '../db/mongodb';
 
 const DriveFile = monkDb.get<IDriveFile>('driveFiles.files');
diff --git a/src/models/user.ts b/src/models/user.ts
index c9a25a35e9..d3c94cab3e 100644
--- a/src/models/user.ts
+++ b/src/models/user.ts
@@ -6,7 +6,7 @@ import { IPost, pack as packPost } from './post';
 import Following from './following';
 import Mute from './mute';
 import getFriends from '../server/api/common/get-friends';
-import config from '../conf';
+import config from '../config';
 
 const User = db.get<IUser>('users');
 
diff --git a/src/othello/ai/back.ts b/src/othello/ai/back.ts
index a67f6fe835..d6704b1750 100644
--- a/src/othello/ai/back.ts
+++ b/src/othello/ai/back.ts
@@ -8,7 +8,7 @@
 
 import * as request from 'request-promise-native';
 import Othello, { Color } from '../core';
-import conf from '../../conf';
+import conf from '../../config';
 
 let game;
 let form;
diff --git a/src/othello/ai/front.ts b/src/othello/ai/front.ts
index 3414d64340..9d0b5f9800 100644
--- a/src/othello/ai/front.ts
+++ b/src/othello/ai/front.ts
@@ -10,7 +10,7 @@ import * as childProcess from 'child_process';
 const WebSocket = require('ws');
 import * as ReconnectingWebSocket from 'reconnecting-websocket';
 import * as request from 'request-promise-native';
-import conf from '../../conf';
+import conf from '../../config';
 
 // 設定 ////////////////////////////////////////////////////////
 
diff --git a/src/processor/http/follow.ts b/src/processor/http/follow.ts
index e81b410cb7..d6ce00006f 100644
--- a/src/processor/http/follow.ts
+++ b/src/processor/http/follow.ts
@@ -7,7 +7,7 @@ import event from '../../event';
 import notify from '../../notify';
 import context from '../../remote/activitypub/renderer/context';
 import render from '../../remote/activitypub/renderer/follow';
-import config from '../../conf';
+import config from '../../config';
 
 export default ({ data }, done) => Following.findOne({ _id: data.following }).then(({ followerId, followeeId }) => {
 	const promisedFollower: Promise<ILocalUser> = User.findOne({ _id: followerId });
diff --git a/src/push-sw.ts b/src/push-sw.ts
index 5b5ec52071..fcef7796d9 100644
--- a/src/push-sw.ts
+++ b/src/push-sw.ts
@@ -1,7 +1,7 @@
 const push = require('web-push');
 import * as mongo from 'mongodb';
 import Subscription from './models/sw-subscription';
-import config from './conf';
+import config from './config';
 
 if (config.sw) {
 	// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
diff --git a/src/queue.ts b/src/queue.ts
index 6089e0a7f1..08ea13c2a3 100644
--- a/src/queue.ts
+++ b/src/queue.ts
@@ -1,5 +1,5 @@
 import { createQueue } from 'kue';
-import config from './conf';
+import config from './config';
 
 export default createQueue({
 	redis: {
diff --git a/src/remote/activitypub/create.ts b/src/remote/activitypub/create.ts
index 6d135685ef..8ea8a85fd8 100644
--- a/src/remote/activitypub/create.ts
+++ b/src/remote/activitypub/create.ts
@@ -1,5 +1,5 @@
 import { JSDOM } from 'jsdom';
-import config from '../../conf';
+import config from '../../config';
 import Post from '../../models/post';
 import RemoteUserObject, { IRemoteUserObject } from '../../models/remote-user-object';
 import uploadFromUrl from '../../drive/upload-from-url';
diff --git a/src/remote/activitypub/renderer/document.ts b/src/remote/activitypub/renderer/document.ts
index fdd52c1b6c..91a9f7df38 100644
--- a/src/remote/activitypub/renderer/document.ts
+++ b/src/remote/activitypub/renderer/document.ts
@@ -1,4 +1,4 @@
-import config from '../../../conf';
+import config from '../../../config';
 
 export default ({ _id, contentType }) => ({
 	type: 'Document',
diff --git a/src/remote/activitypub/renderer/follow.ts b/src/remote/activitypub/renderer/follow.ts
index c99bc375a2..6d1ded9a95 100644
--- a/src/remote/activitypub/renderer/follow.ts
+++ b/src/remote/activitypub/renderer/follow.ts
@@ -1,4 +1,4 @@
-import config from '../../../conf';
+import config from '../../../config';
 import { IRemoteUser } from '../../../models/user';
 
 export default ({ username }, followee: IRemoteUser) => ({
diff --git a/src/remote/activitypub/renderer/hashtag.ts b/src/remote/activitypub/renderer/hashtag.ts
index c2d261ed21..cf0b07b48a 100644
--- a/src/remote/activitypub/renderer/hashtag.ts
+++ b/src/remote/activitypub/renderer/hashtag.ts
@@ -1,4 +1,4 @@
-import config from '../../../conf';
+import config from '../../../config';
 
 export default tag => ({
 	type: 'Hashtag',
diff --git a/src/remote/activitypub/renderer/image.ts b/src/remote/activitypub/renderer/image.ts
index 3d1c71cb95..d671a57e7c 100644
--- a/src/remote/activitypub/renderer/image.ts
+++ b/src/remote/activitypub/renderer/image.ts
@@ -1,4 +1,4 @@
-import config from '../../../conf';
+import config from '../../../config';
 
 export default ({ _id }) => ({
 	type: 'Image',
diff --git a/src/remote/activitypub/renderer/key.ts b/src/remote/activitypub/renderer/key.ts
index 904a69e081..85be7b1367 100644
--- a/src/remote/activitypub/renderer/key.ts
+++ b/src/remote/activitypub/renderer/key.ts
@@ -1,4 +1,4 @@
-import config from '../../../conf';
+import config from '../../../config';
 import { extractPublic } from '../../../crypto_key';
 import { ILocalUser } from '../../../models/user';
 
diff --git a/src/remote/activitypub/renderer/note.ts b/src/remote/activitypub/renderer/note.ts
index 74806f14b4..43531b121a 100644
--- a/src/remote/activitypub/renderer/note.ts
+++ b/src/remote/activitypub/renderer/note.ts
@@ -1,6 +1,6 @@
 import renderDocument from './document';
 import renderHashtag from './hashtag';
-import config from '../../../conf';
+import config from '../../../config';
 import DriveFile from '../../../models/drive-file';
 import Post from '../../../models/post';
 import User from '../../../models/user';
diff --git a/src/remote/activitypub/renderer/person.ts b/src/remote/activitypub/renderer/person.ts
index c6c7893165..7ea6f532fb 100644
--- a/src/remote/activitypub/renderer/person.ts
+++ b/src/remote/activitypub/renderer/person.ts
@@ -1,6 +1,6 @@
 import renderImage from './image';
 import renderKey from './key';
-import config from '../../../conf';
+import config from '../../../config';
 
 export default user => {
 	const id = `${config.url}/@${user.username}`;
diff --git a/src/server/activitypub/outbox.ts b/src/server/activitypub/outbox.ts
index 2018d8797b..9ecb0c0711 100644
--- a/src/server/activitypub/outbox.ts
+++ b/src/server/activitypub/outbox.ts
@@ -2,7 +2,7 @@ import * as express from 'express';
 import context from '../../remote/activitypub/renderer/context';
 import renderNote from '../../remote/activitypub/renderer/note';
 import renderOrderedCollection from '../../remote/activitypub/renderer/ordered-collection';
-import config from '../../conf';
+import config from '../../config';
 import Post from '../../models/post';
 import withUser from './with-user';
 
diff --git a/src/server/activitypub/publickey.ts b/src/server/activitypub/publickey.ts
index a23d11c156..c564c437e6 100644
--- a/src/server/activitypub/publickey.ts
+++ b/src/server/activitypub/publickey.ts
@@ -1,7 +1,7 @@
 import * as express from 'express';
 import context from '../../remote/activitypub/renderer/context';
 import render from '../../remote/activitypub/renderer/key';
-import config from '../../conf';
+import config from '../../config';
 import withUser from './with-user';
 
 const app = express();
diff --git a/src/server/activitypub/user.ts b/src/server/activitypub/user.ts
index 0d0b84bad4..baf2dc9a05 100644
--- a/src/server/activitypub/user.ts
+++ b/src/server/activitypub/user.ts
@@ -1,5 +1,5 @@
 import * as express from 'express';
-import config from '../../conf';
+import config from '../../config';
 import context from '../../remote/activitypub/renderer/context';
 import render from '../../remote/activitypub/renderer/person';
 import withUser from './with-user';
diff --git a/src/server/api/bot/interfaces/line.ts b/src/server/api/bot/interfaces/line.ts
index 847b13aa78..27248c9b9d 100644
--- a/src/server/api/bot/interfaces/line.ts
+++ b/src/server/api/bot/interfaces/line.ts
@@ -3,7 +3,7 @@ import * as express from 'express';
 import * as request from 'request';
 import * as crypto from 'crypto';
 import User from '../../../../models/user';
-import config from '../../../../conf';
+import config from '../../../../config';
 import BotCore from '../core';
 import _redis from '../../../../db/redis';
 import prominence = require('prominence');
diff --git a/src/server/api/common/signin.ts b/src/server/api/common/signin.ts
index a11ea56c0c..f9688790c4 100644
--- a/src/server/api/common/signin.ts
+++ b/src/server/api/common/signin.ts
@@ -1,4 +1,4 @@
-import config from '../../../conf';
+import config from '../../../config';
 
 export default function(res, user, redirect: boolean) {
 	const expires = 1000 * 60 * 60 * 24 * 365; // One Year
diff --git a/src/server/api/endpoints/auth/session/generate.ts b/src/server/api/endpoints/auth/session/generate.ts
index ad03e538ce..9857b31d87 100644
--- a/src/server/api/endpoints/auth/session/generate.ts
+++ b/src/server/api/endpoints/auth/session/generate.ts
@@ -5,7 +5,7 @@ import * as uuid from 'uuid';
 import $ from 'cafy';
 import App from '../../../../../models/app';
 import AuthSess from '../../../../../models/auth-session';
-import config from '../../../../../conf';
+import config from '../../../../../config';
 
 /**
  * @swagger
diff --git a/src/server/api/endpoints/i/2fa/register.ts b/src/server/api/endpoints/i/2fa/register.ts
index d2683fb617..dc7fb959bb 100644
--- a/src/server/api/endpoints/i/2fa/register.ts
+++ b/src/server/api/endpoints/i/2fa/register.ts
@@ -6,7 +6,7 @@ import * as bcrypt from 'bcryptjs';
 import * as speakeasy from 'speakeasy';
 import * as QRCode from 'qrcode';
 import User from '../../../../../models/user';
-import config from '../../../../../conf';
+import config from '../../../../../config';
 
 module.exports = async (params, user) => new Promise(async (res, rej) => {
 	// Get 'password' parameter
diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts
index 76ceede8d9..c4ec413399 100644
--- a/src/server/api/endpoints/i/update.ts
+++ b/src/server/api/endpoints/i/update.ts
@@ -4,7 +4,7 @@
 import $ from 'cafy';
 import User, { isValidName, isValidDescription, isValidLocation, isValidBirthday, pack } from '../../../../models/user';
 import event from '../../../../event';
-import config from '../../../../conf';
+import config from '../../../../config';
 
 /**
  * Update myself
diff --git a/src/server/api/endpoints/messaging/messages/create.ts b/src/server/api/endpoints/messaging/messages/create.ts
index e0ec1f216d..604da32d2e 100644
--- a/src/server/api/endpoints/messaging/messages/create.ts
+++ b/src/server/api/endpoints/messaging/messages/create.ts
@@ -13,7 +13,7 @@ import publishUserStream from '../../../../../event';
 import { publishMessagingStream, publishMessagingIndexStream, pushSw } from '../../../../../event';
 import html from '../../../../../text/html';
 import parse from '../../../../../text/parse';
-import config from '../../../../../conf';
+import config from '../../../../../config';
 
 /**
  * Create a message
diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts
index 4f0ae2a60a..70ae7e99cc 100644
--- a/src/server/api/endpoints/meta.ts
+++ b/src/server/api/endpoints/meta.ts
@@ -3,7 +3,7 @@
  */
 import * as os from 'os';
 import version from '../../../version';
-import config from '../../../conf';
+import config from '../../../config';
 import Meta from '../../../models/meta';
 
 /**
diff --git a/src/server/api/endpoints/posts/create.ts b/src/server/api/endpoints/posts/create.ts
index e74ac7582e..bf08fe2839 100644
--- a/src/server/api/endpoints/posts/create.ts
+++ b/src/server/api/endpoints/posts/create.ts
@@ -19,7 +19,7 @@ import event, { pushSw, publishChannelStream } from '../../../../event';
 import notify from '../../../../notify';
 import getAcct from '../../../../user/get-acct';
 import parseAcct from '../../../../user/parse-acct';
-import config from '../../../../conf';
+import config from '../../../../config';
 
 /**
  * Create a post
diff --git a/src/server/api/endpoints/users/search.ts b/src/server/api/endpoints/users/search.ts
index 335043b02e..da30f47c2a 100644
--- a/src/server/api/endpoints/users/search.ts
+++ b/src/server/api/endpoints/users/search.ts
@@ -4,7 +4,7 @@
 import * as mongo from 'mongodb';
 import $ from 'cafy';
 import User, { pack } from '../../../../models/user';
-import config from '../../../../conf';
+import config from '../../../../config';
 const escapeRegexp = require('escape-regexp');
 
 /**
diff --git a/src/server/api/private/signin.ts b/src/server/api/private/signin.ts
index 99ba51b416..bf883ee27a 100644
--- a/src/server/api/private/signin.ts
+++ b/src/server/api/private/signin.ts
@@ -5,7 +5,7 @@ import User, { ILocalUser } from '../../../models/user';
 import Signin, { pack } from '../../../models/signin';
 import event from '../../../event';
 import signin from '../common/signin';
-import config from '../../../conf';
+import config from '../../../config';
 
 export default async (req: express.Request, res: express.Response) => {
 	res.header('Access-Control-Allow-Origin', config.url);
diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts
index 45b978d0b6..4203ce526d 100644
--- a/src/server/api/private/signup.ts
+++ b/src/server/api/private/signup.ts
@@ -5,7 +5,7 @@ import { generate as generateKeypair } from '../../../crypto_key';
 import recaptcha = require('recaptcha-promise');
 import User, { IUser, validateUsername, validatePassword, pack } from '../../../models/user';
 import generateUserToken from '../common/generate-native-user-token';
-import config from '../../../conf';
+import config from '../../../config';
 
 recaptcha.init({
 	secret_key: config.recaptcha.secret_key
diff --git a/src/server/api/service/github.ts b/src/server/api/service/github.ts
index b4068c729e..4fd59c2a94 100644
--- a/src/server/api/service/github.ts
+++ b/src/server/api/service/github.ts
@@ -2,7 +2,7 @@ import * as EventEmitter from 'events';
 import * as express from 'express';
 //const crypto = require('crypto');
 import User from '../../../models/user';
-import config from '../../../conf';
+import config from '../../../config';
 import queue from '../../../queue';
 
 module.exports = async (app: express.Application) => {
diff --git a/src/server/api/service/twitter.ts b/src/server/api/service/twitter.ts
index 61a1d56397..69fa5f3c67 100644
--- a/src/server/api/service/twitter.ts
+++ b/src/server/api/service/twitter.ts
@@ -7,7 +7,7 @@ import autwh from 'autwh';
 import redis from '../../../db/redis';
 import User, { pack } from '../../../models/user';
 import event from '../../../event';
-import config from '../../../conf';
+import config from '../../../config';
 import signin from '../common/signin';
 
 module.exports = (app: express.Application) => {
diff --git a/src/server/api/streaming.ts b/src/server/api/streaming.ts
index c86c6a8b4a..edcf505d24 100644
--- a/src/server/api/streaming.ts
+++ b/src/server/api/streaming.ts
@@ -1,7 +1,7 @@
 import * as http from 'http';
 import * as websocket from 'websocket';
 import * as redis from 'redis';
-import config from '../../conf';
+import config from '../../config';
 import { default as User, IUser } from '../../models/user';
 import AccessToken from '../../models/access-token';
 import isNativeToken from './common/is-native-token';
diff --git a/src/server/index.ts b/src/server/index.ts
index 1874790116..61a8739b43 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -12,7 +12,7 @@ import Accesses from 'accesses';
 import activityPub from './activitypub';
 import webFinger from './webfinger';
 import log from './log-request';
-import config from '../conf';
+import config from '../config';
 
 /**
  * Init app
diff --git a/src/server/webfinger.ts b/src/server/webfinger.ts
index 7a28b1bec8..3b0f416d6f 100644
--- a/src/server/webfinger.ts
+++ b/src/server/webfinger.ts
@@ -1,4 +1,4 @@
-import config from '../conf';
+import config from '../config';
 import parseAcct from '../user/parse-acct';
 import User from '../models/user';
 const express = require('express');
diff --git a/webpack.config.ts b/webpack.config.ts
index d486e100a2..60dbfd2ff7 100644
--- a/webpack.config.ts
+++ b/webpack.config.ts
@@ -14,7 +14,7 @@ const ProgressBarPlugin = require('progress-bar-webpack-plugin');
 import I18nReplacer from './src/build/i18n';
 import { pattern as faPattern, replacement as faReplacement } from './src/build/fa';
 const constants = require('./src/const.json');
-import config from './src/conf';
+import config from './src/config';
 import { licenseHtml } from './src/build/license';
 
 import locales from './locales';