UNPKG

mili

Version:

Scaffolding with continuous control over the development of the project.

193 lines (192 loc) 7.22 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import AJV from 'ajv8'; import ajvFormats from 'ajv-formats'; import * as fs from 'fs-extra'; import * as path from 'path'; import * as JSON5 from 'json5'; import * as YAML from 'js-yaml'; import * as configSchema from './schema/config.json'; import * as hooksSchema from './schema/hooks.json'; import * as questionsSchema from './schema/questions.json'; import * as templatesSchema from './schema/templates.json'; import * as R from 'ramda'; const ajv = new AJV(); ajvFormats(ajv); function validate(schema, data, dataVar) { const validator = ajv.compile(schema); const valid = validator(data); if (!valid) throw new Error(ajv.errorsText(validator.errors, { dataVar })); return true; } function exist(filepath) { return __awaiter(this, void 0, void 0, function* () { try { yield fs.access(filepath); return true; } catch (error) { return false; } }); } function readJson(filepath) { return __awaiter(this, void 0, void 0, function* () { const content = yield fs.readFile(filepath, { encoding: 'utf8' }); return JSON5.parse(content); }); } function readYaml(filepath) { return __awaiter(this, void 0, void 0, function* () { const content = yield fs.readFile(filepath, { encoding: 'utf8' }); return YAML.load(content); }); } function readConfig(filepath) { return __awaiter(this, void 0, void 0, function* () { const ymlFilepath = `${filepath}.yml`; const jsonFilepath = `${filepath}.json`; if (yield exist(ymlFilepath)) { return readYaml(ymlFilepath); } else if (yield exist(jsonFilepath)) { return readJson(jsonFilepath); } }); } const buildInLoaders = fs.readdirSync(path.join(__dirname, '../loader')); const buildInHanlders = fs.readdirSync(path.join(__dirname, '../handler')); export function loadMiliConfig(dir) { return __awaiter(this, void 0, void 0, function* () { const config = yield readConfig(path.join(dir, 'mili')); validate(configSchema, config, 'config'); if (!config.version) { const packageJson = yield readJson(path.join(dir, 'package.json')); config.version = packageJson.version; } if (!config.extends) config.extends = []; if (!config.loaders) config.loaders = []; config.loaders = config.loaders.map(loader => { if (typeof loader === 'string') { return { name: loader, options: {}, }; } return loader; }); config.loaders = config.loaders.map(loader => { if (buildInLoaders.includes(`${loader.name}.js`) || buildInLoaders.includes(loader.name)) { return { name: path.join(__dirname, '../loader', loader.name), options: loader.options, }; } else { return { name: path.join(dir, 'node_modules', loader.name), options: loader.options, }; } }); config.extends = config.extends.map(ext => { if (typeof ext === 'string') { return { template: ext, version: 'latest', }; } return ext; }); return config; }); } export function loadHooksConfig(dir) { return __awaiter(this, void 0, void 0, function* () { const config = yield readConfig(path.join(dir, 'hooks')); if (!config) return []; validate(hooksSchema, config, 'hooks'); const pair = Object.entries(config); return pair.map(([name, exec]) => ({ name, exec })); }); } export function loadQuestionsConfig(dir) { return __awaiter(this, void 0, void 0, function* () { const config = yield readConfig(path.join(dir, 'questions')); if (!config) return []; validate(questionsSchema, config, 'questions'); return config; }); } export function loadTemplateConfig(dir) { return __awaiter(this, void 0, void 0, function* () { const config = yield readConfig(path.join(dir, 'templates')); validate(templatesSchema, config, 'templates'); config.push({ path: '**', encoding: 'utf8', handlers: ['overwrite'], }); return R.unnest(config.map(item => { if (!item.encoding) item.encoding = 'utf8'; if (!item.handlers || !item.handlers.length) item.handlers = ['overwrite']; item.handlers = item.handlers.map(handler => { if (typeof handler === 'string') { return { name: handler, options: {}, }; } return handler; }); if (item.handlers[item.handlers.length - 1].name !== 'overwrite') { item.handlers.push({ name: 'overwrite', options: {}, }); } item.handlers = item.handlers.map(handler => { if (buildInHanlders.includes(`${handler.name}.js`) || buildInHanlders.includes(handler.name)) { return { name: path.join(__dirname, '../handler', handler.name), options: handler.options, }; } else { return { name: path.join(dir, 'node_modules', handler.name), options: handler.options, }; } }); if (Array.isArray(item.path)) { return item.path.map(subpath => { const handler = R.clone(item); handler.path = subpath; return handler; }); } return item; })); }); } export function loadConfig(dir) { return __awaiter(this, void 0, void 0, function* () { const config = yield loadMiliConfig(dir); return Object.assign(Object.assign({}, config), { hooks: yield loadHooksConfig(dir), questions: yield loadQuestionsConfig(dir), templates: yield loadTemplateConfig(dir) }); }); }