UNPKG

mihawk

Version:

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

251 lines (250 loc) 11.6 kB
'use strict'; 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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.initMockLogicFile = exports.initMockMiddlewareFile = exports.initMockRoutesFile = exports.initMockDataDir = void 0; const path_1 = require("path"); const color_cc_1 = __importDefault(require("color-cc")); const fs_extra_1 = require("fs-extra"); const file_1 = require("../utils/file"); const print_1 = require("../utils/print"); const path_2 = require("../utils/path"); const consts_1 = require("../consts"); const dataDemo = { code: 200, data: { str: 'test', }, message: 'success', }; const routesDemo = { 'GET /test': './GET/test', 'GET /test-*': './GET/test', }; function initMockDataDir(mockDirName = consts_1.MOCK_DIR_NAME) { return __awaiter(this, void 0, void 0, function* () { const mockDataDir = (0, path_1.join)(mockDirName || consts_1.MOCK_DIR_NAME, consts_1.MOCK_DATA_DIR_NAME); const mockDataDirPath = (0, path_1.join)(consts_1.CWD, mockDataDir); if (!(0, fs_extra_1.existsSync)(mockDataDirPath)) { (0, fs_extra_1.ensureDirSync)(mockDataDirPath); print_1.Printer.log(color_cc_1.default.success(`Create mock data dir ${color_cc_1.default.green(mockDataDir)} success!`)); } for (const subDir of ['PUT', 'DELETE', 'POST', 'GET']) { const subDirPath = (0, path_1.join)(mockDataDirPath, subDir); if (!(0, fs_extra_1.existsSync)(subDirPath)) { (0, fs_extra_1.ensureFileSync)((0, path_1.join)(subDirPath, '.gitkeep')); const subDirPathRel = (0, path_1.join)(mockDataDir, subDir); print_1.Printer.log(color_cc_1.default.success(`Create mock data dir ${color_cc_1.default.green(subDirPathRel)} success!`)); } } const demoFilePathRel = (0, path_1.join)(mockDataDir, './GET/test.json'); const demoFilePath = (0, path_1.join)(consts_1.CWD, demoFilePathRel); if (!(0, fs_extra_1.existsSync)(demoFilePath)) { (0, file_1.writeJSONSafeSync)(demoFilePath, dataDemo); print_1.Printer.log(color_cc_1.default.success(`Create mock data file ${color_cc_1.default.green(demoFilePathRel)} success!`)); } }); } exports.initMockDataDir = initMockDataDir; function initMockRoutesFile(fileType = 'none', mockDirName = 'mocks') { return __awaiter(this, void 0, void 0, function* () { const fileExt = (0, path_2.getRoutesFileExt)(fileType) || 'json'; const routesFileName = `routes.${fileExt}`; const routesFilePathRel = (0, path_1.join)(mockDirName, routesFileName); const routesFilePathAbs = (0, path_1.join)(consts_1.CWD, mockDirName, routesFileName); if ((0, fs_extra_1.existsSync)(routesFilePathAbs)) { print_1.Printer.log(`Mock routes file ${color_cc_1.default.yellow(routesFilePathRel)} is already existed, skip init!`); return; } else { const demoRouteMap = JSON.stringify(routesDemo, null, 2); let initContent = demoRouteMap; const comPrefixs = [ '/**', ` * ${consts_1.PKG_NAME}'s routes file:`, ' */', ]; switch (fileType) { case 'js': case 'cjs': case 'javascript': { initContent = [ ...comPrefixs, `module.exports = ${demoRouteMap};`, '', ].join('\n'); break; } case 'ts': case 'typescript': initContent = [ ...comPrefixs, `const routes: Record<string, string> = ${demoRouteMap}`, '//', 'export default routes;', '', ].join('\n'); break; case 'none': default: { break; } } (0, fs_extra_1.ensureDirSync)((0, path_1.join)(consts_1.CWD, mockDirName)); (0, file_1.writeFileSafeSync)(routesFilePathAbs, initContent); print_1.Printer.log(color_cc_1.default.success(`Init mock routes file ${color_cc_1.default.green(routesFilePathRel)} success!`)); } }); } exports.initMockRoutesFile = initMockRoutesFile; function initMockMiddlewareFile(fileType = 'none', mockDirName = 'mocks') { return __awaiter(this, void 0, void 0, function* () { const fileExt = (0, path_2.getLogicFileExt)(fileType); const middlewareFileName = `middleware.${fileExt || 'cjs'}`; const middlewareFilePathRel = (0, path_1.join)(mockDirName, middlewareFileName); const middlewareFilePathAbs = (0, path_1.join)(consts_1.CWD, mockDirName, middlewareFileName); if ((0, fs_extra_1.existsSync)(middlewareFilePathAbs)) { print_1.Printer.log(`Mock middleware file ${color_cc_1.default.yellow(middlewareFilePathRel)} is already existed, skip init!`); return; } else { const comPrefixs = [ '/**', ` * ${consts_1.PKG_NAME}'s custom koa2-middleware file:`, ' * - just a Koa Middleware', ' */', ]; const methodCommentCode = [ '/**', ' * Middleware functions, to implement some special data deal logic,', ' * - This function exec before the default-mock-logic. Simply return or don`t call "await next()" could skip default-mock-logic', ' * - This function is a standard Koa2 middleware that follows the KOA-onion-ring-model', ' * - see more:https://koajs.com/#middleware', ' * @param {KoaContext} ctx', ' * @param {KoaNext} next', ' * @returns {Promise<void>}', ' */', ]; const methodBodyCode = [ ' // do something here', ' console.log(ctx.url);', ' if (ctx.peth === "/diy") {', ' ctx.body = "it is my diy logic";', ' } else {', ' await next(); // default logic (such like mock json logic)', ' }', ]; let initContent = ''; switch (fileType) { case 'ts': case 'typescript': initContent = [ ...comPrefixs, `// import typs { Context: KoaContext, Next: KoaNext } from 'koa'; // need koa@v2.0.0+ (eg: koa@^2.15.3)`, `import type { KoaContext, KoaNext } from '${consts_1.PKG_NAME}/com-types';`, '', ...methodCommentCode, 'export default async function middleware(ctx: KoaContext, next: KoaNext) {', ...methodBodyCode, '}', '', ].join('\n'); break; case 'none': case 'js': case 'cjs': case 'javascript': default: initContent = [ ...comPrefixs, '', ...methodCommentCode, 'module.exports = async function middleware(ctx, next) {', ...methodBodyCode, '}', '', ].join('\n'); break; } (0, fs_extra_1.ensureDirSync)((0, path_1.join)(consts_1.CWD, mockDirName)); (0, file_1.writeFileSafeSync)(middlewareFilePathAbs, initContent); print_1.Printer.log(color_cc_1.default.success(`Init mock middleware file ${color_cc_1.default.green(middlewareFilePathRel)} success!`)); } }); } exports.initMockMiddlewareFile = initMockMiddlewareFile; function initMockLogicFile(mockLogicFilePath, options) { mockLogicFilePath = (0, path_2.absifyPath)(mockLogicFilePath); const { logicFileExt, routePath, jsonPath4log, overwrite } = options; if (!logicFileExt) { print_1.Printer.warn('Empty logic file ext, skip init logic file.'); return; } if (!overwrite && (0, fs_extra_1.existsSync)(mockLogicFilePath)) { print_1.Printer.warn('File is already exists, skip init logic file.', color_cc_1.default.gray(mockLogicFilePath)); return; } let initContent = ''; const commentCode = [ "'use strict;'", '/**', ` * ${routePath}`, ' * This file isn‘t mandatory. If it is not needed (such as when there is no need to modify response data), it can be deleted directly', ' */', ]; const methodCommentCode = [ '/**', ' * Mock data resolve function, the original data source is the JSON file with the same name as this file', ` * @param {object} originData (${jsonPath4log})`, ' * @param {MhkCvtrExtra} extra { url,method,path,query,body }', ' * @returns {object} newData', ' */', ]; switch (logicFileExt) { case 'ts': { const useTypeDefine = true; initContent = [ ...commentCode, useTypeDefine ? `import { MhkCvtrExtra } from '${consts_1.PKG_NAME}/com-types';\n` : '', ...methodCommentCode, useTypeDefine ? 'export default async function convertData(originData: Record<string, any>, extra: MhkCvtrExtra) {' : 'export default async function convertData(originData: Record<string, any>, extra: Record<string, any>) {', ' // 👇🏻 write your logic here...', ' return originData;', '}', ].join('\n'); break; } case 'js': case 'cjs': initContent = [ ...commentCode, '', ...methodCommentCode, 'module.exports = async function convertData(originData, extra) {', ' // 👇🏻 write your logic here...', ' return originData;', '};', ].join('\n'); break; default: break; } if (!initContent) { print_1.Printer.warn('No logic file ext was matched, skip init logic file.', logicFileExt); return; } (0, file_1.writeFileSafeSync)(mockLogicFilePath, initContent); } exports.initMockLogicFile = initMockLogicFile;