UNPKG

unmock-core

Version:

[![npm](https://img.shields.io/npm/v/unmock-core.svg)][npmjs] [![CircleCI](https://circleci.com/gh/unmock/unmock-js.svg?style=svg)](https://circleci.com/gh/unmock/unmock-js) [![codecov](https://codecov.io/gh/unmock/unmock-js/branch/dev/graph/badge.svg)](h

216 lines 13.2 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); const Array_1 = require("fp-ts/lib/Array"); const Option_1 = require("fp-ts/lib/Option"); const io = require("io-ts"); const json_schema_poet_1 = require("json-schema-poet"); const json_schema_strictly_typed_1 = require("json-schema-strictly-typed"); const monocle_ts_1 = require("monocle-ts"); const openapi_refinements_1 = require("openapi-refinements"); const querystring = require("query-string"); const generator_1 = require("./generator"); const DynamicJSONSymbol = Symbol(); const isDynamic = (unk) => typeof unk === "object" && unk !== null && unk.dynamic === DynamicJSONSymbol; const DynamicJSONValue = new io.Type("DynamicJSONValueType", isDynamic, (input, context) => isDynamic(input) ? io.success(input) : io.failure(input, context), io.identity); const MaybeJSONSymbol = Symbol(); const isMaybe = (unk) => typeof unk === "object" && unk !== null && unk.maybe === MaybeJSONSymbol && ExtendedValue.is(unk.val); const MaybeJSONValue = new io.Type("MaybeJSONValueType", isMaybe, (input, context) => isMaybe(input) ? io.success(input) : io.failure(input, context), io.identity); const RecursiveUnion = io.recursion("JSO", () => io.union([ json_schema_strictly_typed_1.JSONPrimitive, json_schema_strictly_typed_1.JSONObject, json_schema_strictly_typed_1.JSONArray, ExtendedArray, ExtendedObject, ])); const JSO = io.recursion("JSO", () => json_schema_strictly_typed_1.JSONSchemaObject(RecursiveUnion, DynamicJSONValue)); const rejectOptionals = (i) => new monocle_ts_1.Iso(a => Object.entries(a), q => q.reduce((a, b) => (Object.assign(Object.assign({}, a), { [b[0]]: b[1] })), {})) .composeTraversal(monocle_ts_1.fromTraversable(Array_1.array)()) .composePrism(new monocle_ts_1.Prism(a => ((q, r) => MaybeJSONValue.is(r) ? Option_1.none : Option_1.some([q, r]))(a[0], a[1]), a => a)) .composeGetter(generator_1.identityGetter()) .getAll(i) .reduce((a, b) => (Object.assign(Object.assign({}, a), { [b[0]]: b[1] })), {}); const keepOptionals = (i) => new monocle_ts_1.Iso(a => Object.entries(a), q => q.reduce((a, b) => (Object.assign(Object.assign({}, a), { [b[0]]: b[1] })), {})) .composeTraversal(monocle_ts_1.fromTraversable(Array_1.array)()) .composePrism(new monocle_ts_1.Prism(a => (MaybeJSONValue.is(a[1]) ? Option_1.some([a[0], a[1].val]) : Option_1.none), a => a)) .composeGetter(generator_1.identityGetter()) .getAll(i) .reduce((a, b) => (Object.assign(Object.assign({}, a), { [b[0]]: b[1] })), {}); const IORegExp = new io.Type("IORegExp", (unk) => unk instanceof RegExp, (input, context) => input instanceof RegExp ? io.success(input) : io.failure(input, context), io.identity); const ExtendedPrimitive = io.union([json_schema_strictly_typed_1.JSONPrimitive, JSO, IORegExp]); const ExtendedValue = io.recursion("ExtendedValue", () => io.union([ ExtendedPrimitive, json_schema_strictly_typed_1.JSONArray, json_schema_strictly_typed_1.JSONObject, ExtendedObject, ExtendedArray, ])); const ExtendedObject = io.recursion("ExtendedObject", () => io.record(io.string, io.union([ExtendedValue, MaybeJSONValue]))); const ExtendedArray = io.recursion("ExtendedArray", () => io.array(ExtendedValue)); const spreadAndSchemify = (e, f) => e ? Object.entries(e).reduce((a, b) => (Object.assign(Object.assign({}, a), { [b[0]]: f(b[1]) })), {}) : {}; const removeDynamicSymbol = (schema) => { const { dynamic } = schema, rest = __rest(schema, ["dynamic"]); return rest; }; const fuzzNoop = (schema) => schema; const simpleConstantTransformer = (e) => openapi_refinements_1.valAsConst(json_schema_poet_1.cnst_({})(e).const); const fuzz = (e) => typeof e === "string" ? jspt.string() : typeof e === "number" && Math.floor(e) === e ? jspt.integer() : typeof e === "number" ? jspt.number() : typeof e === "boolean" ? jspt.boolean() : jspt.nul(); const unfuzz = (e) => typeof e === "string" ? jspt.cnst(e) : typeof e === "number" ? jspt.cnst(e) : typeof e === "boolean" ? jspt.cnst(e) : jspt.cnst(null); exports.JSONSchemify = (c) => (schemaToSchemaTransformer) => (constantHandler) => (e) => isDynamic(e) ? schemaToSchemaTransformer(json_schema_strictly_typed_1.JSSTAllOf(RecursiveUnion, DynamicJSONValue).is(e) ? Object.assign(Object.assign({}, e), { allOf: e.allOf.map(exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler)) }) : json_schema_strictly_typed_1.JSSTAnyOf(RecursiveUnion, DynamicJSONValue).is(e) ? Object.assign(Object.assign({}, e), { anyOf: e.anyOf.map(exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler)) }) : json_schema_strictly_typed_1.JSSTOneOf(RecursiveUnion, DynamicJSONValue).is(e) ? Object.assign(Object.assign({}, e), { oneOf: e.oneOf.map(exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler)) }) : json_schema_strictly_typed_1.JSSTNot(RecursiveUnion, DynamicJSONValue).is(e) ? Object.assign(Object.assign({}, e), { not: exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler)(e.not) }) : json_schema_strictly_typed_1.JSSTList(RecursiveUnion, DynamicJSONValue).is(e) ? Object.assign(Object.assign({}, e), { items: exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler)(e.items) }) : json_schema_strictly_typed_1.JSSTTuple(RecursiveUnion, DynamicJSONValue).is(e) ? Object.assign(Object.assign({}, e), { oneOf: e.items.map(exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler)) }) : json_schema_strictly_typed_1.JSSTObject(RecursiveUnion, DynamicJSONValue).is(e) ? Object.assign(Object.assign(Object.assign(Object.assign({}, e), (e.additionalProperties ? { additionalProperties: exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler)(e.additionalProperties), } : {})), (e.patternProperties ? { patternProperties: spreadAndSchemify(e.patternProperties, exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler)), } : {})), (e.properties ? { properties: spreadAndSchemify(e.properties, exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler)), } : {})) : e) : ExtendedArray.is(e) || json_schema_strictly_typed_1.JSONArray.is(e) ? json_schema_poet_1.tuple_(c)(e.map(exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler))) : ExtendedObject.is(e) || json_schema_strictly_typed_1.JSONObject.is(e) ? json_schema_poet_1.type_(c)(spreadAndSchemify(rejectOptionals(e), exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler)), spreadAndSchemify(keepOptionals(e), exports.JSONSchemify(c)(schemaToSchemaTransformer)(constantHandler))) : e instanceof RegExp ? Object.assign({ type: "string", pattern: e.source }, c) : constantHandler(e); const jspt = json_schema_poet_1.extendT({ dynamic: DynamicJSONSymbol, }); exports.u = Object.assign(Object.assign({}, jspt), { fuzz: exports.JSONSchemify({ dynamic: DynamicJSONSymbol, })(fuzzNoop)(fuzz), unfuzz: exports.JSONSchemify({ dynamic: DynamicJSONSymbol, })(fuzzNoop)(unfuzz), opt: (e) => ({ maybe: MaybeJSONSymbol, val: e, }) }); exports.vanillaJSONSchemify = exports.JSONSchemify({})(removeDynamicSymbol)(simpleConstantTransformer); class DynamicServiceSpec { constructor(updater, statusCode = 200, baseUrl, accumulatedQueries, requestHeaders, serviceStore, name) { this.updater = updater; this.statusCode = statusCode; this.baseUrl = baseUrl; this.accumulatedQueries = accumulatedQueries; this.requestHeaders = requestHeaders; this.serviceStore = serviceStore; this.name = name; this.data = {}; this.headers = {}; this.queriesFromCallToQueries = {}; } query(data) { this.queriesFromCallToQueries = Object.assign(Object.assign(Object.assign({}, this.queriesFromCallToQueries), this.accumulatedQueries), (data ? Object.entries(data).reduce((a, b) => (Object.assign(Object.assign({}, a), { [b[0]]: exports.vanillaJSONSchemify(b[1]) })), {}) : {})); const methods = buildFluentNock(this.serviceStore, this.baseUrl, this.requestHeaders, this.name); const dss = new DynamicServiceSpec(this.updater, this.statusCode, this.baseUrl, this.queriesFromCallToQueries, this.requestHeaders, this.serviceStore, this.name); return Object.assign(Object.assign({}, methods), { query: dss.query.bind(dss), reply: dss.reply.bind(dss) }); } reply(maybeStatusCode, maybeData, maybeHeaders) { if (maybeData !== undefined) { this.data = exports.vanillaJSONSchemify(maybeData); this.statusCode = maybeStatusCode; } else if ((typeof maybeStatusCode === "number" && maybeStatusCode >= 100 && maybeStatusCode <= 599) || maybeStatusCode === "default") { this.statusCode = maybeStatusCode; } else { this.data = exports.vanillaJSONSchemify(maybeStatusCode); } this.headers = maybeHeaders ? Object.entries(maybeHeaders).reduce((a, b) => (Object.assign(Object.assign({}, a), { [b[0]]: exports.vanillaJSONSchemify(b[1]) })), {}) : {}; const store = this.updater(this.serviceStore)(Object.assign(Object.assign({}, this.queriesFromCallToQueries), this.accumulatedQueries))({ data: this.data, headers: this.headers, statusCode: this.statusCode, }); const methods = buildFluentNock(store, this.baseUrl, this.requestHeaders, this.name); const dss = new DynamicServiceSpec(this.updater, this.statusCode, this.baseUrl, Object.assign(Object.assign({}, this.queriesFromCallToQueries), this.accumulatedQueries), this.requestHeaders, store, this.name); return Object.assign(Object.assign({}, methods), { query: dss.query.bind(dss), reply: dss.reply.bind(dss) }); } } exports.DynamicServiceSpec = DynamicServiceSpec; const updateStore = (baseUrl, method, endpoint, query, requestHeaders, body, name) => (store) => (queriesFromCallToQueries) => ({ statusCode, headers, data, }) => store.updateOrAdd({ baseUrl, method, endpoint, query: Object.assign(Object.assign({}, query), queriesFromCallToQueries), requestHeaders, responseHeaders: headers, body, statusCode, response: data, name, }); const endpointToQs = (endpoint) => Object.entries(querystring.parse(typeof endpoint === "string" ? endpoint.split("?")[1] || "" : "")).reduce((a, b) => (Object.assign(Object.assign({}, a), { [b[0]]: exports.vanillaJSONSchemify(b[1] === undefined ? null : b[1]) })), {}) || {}; const naked = (endpoint) => typeof endpoint === "string" ? endpoint.split("?")[0] : endpoint; const HTTPMethodsWithCommonStatusResponses = { get: 200, head: 200, post: 201, put: 204, patch: 204, delete: 200, options: 200, trace: 200, }; const buildFluentNock = (store, baseUrl, requestHeaders, name) => ((fds) => (Object.assign(Object.assign({}, fds), { tldr: () => [ "/", "/{a}", "/{a}/{b}", "/{a}/{b}/{c}", "/{a}/{b}/{c}/{d}", "/{a}/{b}/{c}/{d}/{e}", "/{a}/{b}/{c}/{d}/{e}/{f}", "/{a}/{b}/{c}/{d}/{e}/{f}/{g}", "/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}", ].forEach(p => Object.entries(HTTPMethodsWithCommonStatusResponses).forEach(([method, code]) => fds[method](p).reply(code))) })))(Object.entries(HTTPMethodsWithCommonStatusResponses).reduce((o, [method, code]) => (Object.assign(Object.assign({}, o), { [method]: method === "post" || method === "patch" || method === "put" ? (endpoint, requestBody) => new DynamicServiceSpec(updateStore(baseUrl, method, naked(endpoint), endpointToQs(endpoint) || {}, requestHeaders, requestBody !== undefined ? exports.vanillaJSONSchemify(requestBody) : undefined, name), code, baseUrl, endpointToQs(endpoint) || {}, requestHeaders, store, name) : (endpoint) => new DynamicServiceSpec(updateStore(baseUrl, method, naked(endpoint), endpointToQs(endpoint) || {}, requestHeaders, undefined, name), code, baseUrl, endpointToQs(endpoint) || {}, requestHeaders, store, name) })), {})); exports.nockify = ({ serviceStore, baseUrl, requestHeaders, name, }) => buildFluentNock(serviceStore, baseUrl, requestHeaders, name); //# sourceMappingURL=nock.js.map