UNPKG

mihawk

Version:

A tiny & simple mock server tool, support json,js,cjs,ts(typescript).

152 lines (151 loc) 5.95 kB
'use strict'; import { join, basename } from 'path'; import Colors from 'color-cc'; import { cosmiconfig } from 'cosmiconfig'; import { existsSync } from 'fs-extra'; import deepmerge from 'deepmerge'; import { writeFileSafeSync } from '../utils/file'; import { CWD, DEFAULT_OPTIONS, MOCK_DIR_NAME, MOCK_DATA_DIR_NAME, PKG_NAME } from '../consts'; import { Debugger, Printer } from '../utils/print'; import { absifyPath, getLogicFileExt } from '../utils/path'; import { isObjStrict } from '../utils/is'; export async function initRCfile(name, options = { fileType: 'json' }) { const { fileType = 'json', overwrite = false, initConfig = {}, tsInfo = null } = options; const rcType = fileType || 'json'; const rcName = `${name}.${rcType}`; Printer.log(`init ${rcName} file..`); const rcFilePath = join(CWD, `./${rcName}`); if (existsSync(rcFilePath)) { if (overwrite) { Printer.log(`Force Update file ${rcName}..`); } else { Printer.log(`${rcName} file already exists. Will skip it..`); return; } } let initContent = JSON.stringify(initConfig || {}, null, 2); switch (rcType) { case 'ts': { const { typeName, typeImportId } = tsInfo || {}; const hasTypeInfo = typeName && typeImportId; const importTypeCode = hasTypeInfo ? `import type { ${typeName} } from '${typeImportId}';` : ''; initContent = [ '"use strict";', '/**', ` * ${name}.ts`, ' */', importTypeCode, '', `const config: ${hasTypeInfo ? typeName : 'any'} = ${initContent};`, 'export default config;', '', ].join('\n'); break; } case 'js': { initContent = [ '"use strict";', '/**', ` * ${name}.js`, ' */', '', `module.exports = ${initContent};`, '', ].join('\n'); break; } case 'json': default: initConfig.$schema = `./node_modules/${PKG_NAME}/assets/schema/root-config.json`; initContent = JSON.stringify(initConfig || {}, null, 2); break; } writeFileSafeSync(rcFilePath, initContent); } export async function getRcData(name, options) { const { initConfig = {} } = options || {}; const defConfig = Object.assign({}, initConfig); const rcNames = [`${name}.json`, `${name}.js`, `${name}.ts`]; try { if (rcNames.some(fileName => existsSync(join(CWD, fileName)))) { const explorer = cosmiconfig(name, { stopDir: CWD, searchPlaces: rcNames, packageProp: name.replace(/^\.+/g, ''), }); const res = await explorer.search(CWD); const { config, filepath } = res || {}; Printer.log(Colors.success(`load root-config file: ${Colors.gray(basename(filepath))}`)); Debugger.log('root-config: ', config); return config || defConfig; } else { Printer.log(Colors.yellow(`Can't found rc-file(.${name}.js|json|ts). Will auto create & init it..`)); await initRCfile(name, { fileType: 'json', initConfig: defConfig, overwrite: false }); return defConfig; } } catch (error) { Printer.error(Colors.error('Load config file error..'), '\n', error); return defConfig; } } export function formatOptionsByConfig(config) { const options = deepmerge({}, { ...DEFAULT_OPTIONS, ...config, }); ['_', '--', 'h', 'H', 'help', 'v', 'V', 'version'].forEach(key => delete options[key]); if (options.p !== undefined) { options.port = options.p; delete options.p; } if (options.d !== undefined) { options.mockDir = options.d || MOCK_DIR_NAME; delete options.d; } if (options.w !== undefined) { options.watch = options.w; delete options.w; } const { mockDataFileType, mockLogicFileType } = options || {}; options.port = Number(options.port); options.mockDirPath = absifyPath(options.mockDir || MOCK_DIR_NAME); options.mockDataDirPath = join(options.mockDirPath, MOCK_DATA_DIR_NAME); const isTypesctiptMode = mockLogicFileType === 'ts' || mockLogicFileType === 'typescript'; options.isTypesctiptMode = isTypesctiptMode; if (isTypesctiptMode) { if (options.tsconfigPath) { options.tsconfigPath = absifyPath(options.tsconfigPath); } else { options.tsconfigPath = join(options.mockDirPath, 'tsconfig.json'); } } const dataFileExt = mockDataFileType; options.dataFileExt = dataFileExt; const useLogicFile = mockLogicFileType !== 'none'; options.useLogicFile = useLogicFile; const logicFileExt = getLogicFileExt(mockLogicFileType); options.logicFileExt = logicFileExt; if (useLogicFile) { options.middlewareFilePath = join(options.mockDirPath, `./middleware.${logicFileExt}`); } options.routesFilePath = join(options.mockDirPath, `./routes.${logicFileExt || dataFileExt}`); options.useHttps = !!options.https || isObjStrict(options.https); options.useWS = !!options.socketConfig; if (options.useWS) { if (typeof options.socketConfig !== 'object') { options.socketConfig = { host: options.host, port: options.port, secure: options.useHttps, stomp: false, }; } options.socketFilePath = join(options.mockDirPath, `./socket.${logicFileExt}`); } options.useRemoteData = typeof options.setJsonByRemote === 'object' && options.setJsonByRemote?.enable; return options; }