UNPKG

stable-ts-type

Version:

Obtain the most stable type code of 'typescript' through multiple network requests

177 lines (176 loc) 8.01 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.generate = exports.simpleGenerate = exports.Generator = void 0; const axios_1 = __importDefault(require("axios")); const prefer_delay_1 = require("prefer-delay"); const eventemitter2_1 = __importDefault(require("eventemitter2")); const merge_1 = __importDefault(require("merge")); const json2type_1 = __importDefault(require("./json2type")); const fetch_1 = __importDefault(require("./fetch")); const type_opts_1 = require("./type-opts"); const utils_1 = require("./utils"); const input_1 = require("./input"); const TOP_TYPE_NAME = 'Response'; // quicktype@21.0.13的ts转换直接定死了大驼峰,没法改风格 const defaultGenerateOpts = { requestInterval: 0, topTypeName: TOP_TYPE_NAME, quickTypeOpts: type_opts_1.defaultTypeOpts, requireMockSort: 'random', }; var GenerateEvent; (function (GenerateEvent) { GenerateEvent["CHUNK_DONE_EVENT"] = "CHUNK_DONE"; GenerateEvent["DONE_EVENT"] = "DONE"; GenerateEvent["ERROR_EVENT"] = "ERROR"; })(GenerateEvent || (GenerateEvent = {})); class Generator { constructor(input, opts = {}) { this.opts = {}; this.jsonExamples = []; this.requestInputs = []; this.eventEmitter = new eventemitter2_1.default(); this.stopped = false; // status this.code = ''; this.jsonList = []; this.opts = merge_1.default.recursive(true, defaultGenerateOpts, opts); const easyInputs = Generator.getEasyInputs(Array.isArray(input) ? input : [input]); this.jsonExamples = easyInputs.jsonExamples; this.requestInputs = (0, input_1.getOnceMockInputList)(easyInputs.requestInputs, opts.requireMockSort); if (this.opts.on) { // @ts-ignore this.eventEmitter.onAny(this.opts.on); } const CancelToken = axios_1.default.CancelToken; const { token: fetchCancelToken, cancel: fetchCancel } = CancelToken.source(); this.fetch = (0, prefer_delay_1.promiseDelay)((request, requestConfig, requestMock) => (0, fetch_1.default)(request, Object.assign(Object.assign({}, requestConfig), { cancelToken: fetchCancelToken }), requestMock), opts.requestInterval); this.fetchCancel = () => fetchCancel('the stable-ts-type generator has been interrupted'); } onGenerateChunk(jsonList) { return __awaiter(this, void 0, void 0, function* () { const { opts, eventEmitter, stopped } = this; if (stopped) return; this.jsonList.push(...jsonList); const code = yield (0, json2type_1.default)(opts.topTypeName, [JSON.stringify(this.jsonList)], opts.quickTypeOpts); this.code = code; eventEmitter.emit(GenerateEvent.CHUNK_DONE_EVENT, code); }); } generate() { return __awaiter(this, void 0, void 0, function* () { const { jsonExamples, requestInputs, eventEmitter, fetch } = this; const promises = []; const p = this.onGenerateChunk(jsonExamples) .catch((error) => { this.eventEmitter.emit(GenerateEvent.ERROR_EVENT, error); }); promises.push(p); for (const fetchInput of requestInputs) { // @ts-ignore const p = fetch(fetchInput.value, {}, fetchInput.mock) .then(data => { if ((0, utils_1.isValidJSON)(data)) { return data; } const showFetchInput = { type: fetchInput.type, value: fetchInput.value, }; throw (0, utils_1.simpleError)(`json conversion failed, from fetchInput: ${JSON.stringify(showFetchInput, null, 2)}`); }) .then(json => this.onGenerateChunk([json])) .catch((error) => { this.eventEmitter.emit(GenerateEvent.ERROR_EVENT, error); }); promises.push(p); } yield Promise.all(promises); eventEmitter.emit(GenerateEvent.DONE_EVENT, this.code); }); } stop() { this.stopped = true; this.eventEmitter.removeAllListeners(); this.fetchCancel(); } static getEasyInputs(inputs) { const jsonExamplesInput = inputs .filter(input => input.type === 'example-json'); const jsonExamples = jsonExamplesInput .map(input => typeof input.value === 'string' ? (0, utils_1.easyJSONParse)(input.value) : input.value); const requestInputs = inputs .filter(input => input.type !== 'example-json'); return { jsonExamples, requestInputs, }; } } exports.Generator = Generator; Generator.CHUNK_DONE_EVENT = GenerateEvent.CHUNK_DONE_EVENT; Generator.DONE_EVENT = GenerateEvent.DONE_EVENT; Generator.ERROR_EVENT = GenerateEvent.ERROR_EVENT; const simpleGenerate = (input, opts = {}) => __awaiter(void 0, void 0, void 0, function* () { return new Promise((resolve, reject) => { const inputs = Array.isArray(input) ? input : [input]; const generator = new Generator(inputs, Object.assign(Object.assign({}, opts), { on: (event, codeOrError) => { switch (event) { case 'DONE': resolve(codeOrError); break; case 'ERROR': reject(codeOrError); break; } } })); generator.generate(); }); }); exports.simpleGenerate = simpleGenerate; /** @deprecated */ const generate = (input, opts = {}) => __awaiter(void 0, void 0, void 0, function* () { var _a; const inputs = Array.isArray(input) ? input : [input]; const quickTypeOpts = Object.assign({}, type_opts_1.defaultTypeOpts, opts.quickTypeOpts); const jsonExamplesInput = inputs .filter(input => input.type === 'example-json'); const jsonExamples = jsonExamplesInput .map(input => typeof input.value === 'string' ? (0, utils_1.easyJSONParse)(input.value) : JSON.stringify(input.value)); const requiredFetchInputs = inputs .filter(input => input.type !== 'example-json'); // @ts-ignore const fetches = requiredFetchInputs.map(input => (0, fetch_1.default)(input.value)); const respDataList = yield Promise.all(fetches); try { const respDataStrList = respDataList.map(data => JSON.stringify(data)); const typeCode = yield (0, json2type_1.default)((_a = opts.topTypeName) !== null && _a !== void 0 ? _a : TOP_TYPE_NAME, [ ...jsonExamples, ...respDataStrList, ], quickTypeOpts); return typeCode; } catch (error) { throw (0, utils_1.simpleError)(`failed to generate typeCode, json-list: ${JSON.stringify([ ...respDataList, ...jsonExamplesInput.map(item => item.value), ], null, 2)}`); } }); exports.generate = generate;