unmock-core
Version:
[][npmjs] [](https://circleci.com/gh/unmock/unmock-js) [](h
148 lines • 6.66 kB
JavaScript
;
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 Ajv = require("ajv");
const debug_1 = require("debug");
const dsl_1 = require("../dsl");
const interfaces_1 = require("../interfaces");
const ajv = new Ajv({ unknownFormats: ["int32", "int64"] });
const debugLog = debug_1.default("unmock:state:transformers");
const genBuilder = (fn) => {
try {
return { spreadState: fn() };
}
catch (err) {
return { spreadState: {}, error: err.message };
}
};
exports.objResponse = (state) => ({
isEmpty: state === undefined || Object.keys(state).length === 0,
top: dsl_1.getTopLevelDSL(state || {}),
gen: (schema) => genBuilder(() => {
const spread = spreadStateFromService(schema, dsl_1.filterTopLevelDSL(state || {}));
const missingParam = DFSVerifyNoneAreNull(spread);
if (missingParam !== undefined) {
throw new Error(missingParam.msg);
}
return spread;
}),
state,
});
exports.functionResponse = (responseFunction, dsl) => ({
isEmpty: responseFunction === undefined,
top: dsl_1.getTopLevelDSL((dsl || {})),
gen: (schema) => genBuilder(() => ({
"x-unmock-function": (req) => responseFunction(req, schema),
})),
state: responseFunction.toString(),
});
exports.textResponse = (state, dsl) => ({
isEmpty: typeof state !== "string" || state.length === 0,
top: dsl_1.getTopLevelDSL((dsl || {})),
gen: (schema) => genBuilder(() => generateTextResponse(schema, state)),
state,
});
const generateTextResponse = (schema, state) => {
debugLog(`generateTextResponse: Verifying ${schema} can contain a simple string`);
if (state === undefined || schema === undefined || schema.type !== "string") {
throw new Error("Can't set text response for non-string schemas");
}
return Object.assign(Object.assign({}, schema), { const: state });
};
const matchWhenMissingKey = (schema, state, key) => {
if (hasNoNestedItems(schema)) {
return { [key]: null };
}
debugLog(`matchWhenMissingKey: traversing nested items for ${key}`);
const { translated, cleaned } = dsl_1.DSL.translateDSLToOAS(state, schema);
const spread = Object.assign(Object.assign({}, oneLevelOfIndirectNestedness(schema, cleaned)), translated);
if (Object.keys(spread).length === 0) {
spread[key] = null;
}
return spread;
};
const matchWithConcreteValue = (schema, value, key) => {
const _a = schema, { faker } = _a, rest = __rest(_a, ["faker"]);
return {
[key]: interfaces_1.isSchema(rest) && ajv.validate(rest, value)
? Object.assign(Object.assign({}, schema), { const: value }) : typeof value === "function"
? Object.assign(Object.assign({}, schema), { "x-unmock-function": value }) : null,
};
};
const matchWithNonConcreteValue = (schema, state, key) => {
const stateValue = state[key];
if ([undefined, null].includes(stateValue)) {
throw new Error(`${key} in '${JSON.stringify(state)}' is undefined or null!`);
}
if (hasNoNestedItems(schema) && isEmptyObject(schema)) {
debugLog(`matchWithNonConcreteValue: but more traversal is needed and not possible -> missing value found`);
return { [key]: null };
}
debugLog(`matchWithNonConcreteValue: traversing ${JSON.stringify(schema)} and ${JSON.stringify(stateValue)}`);
const { translated, cleaned } = dsl_1.DSL.translateDSLToOAS(stateValue, schema);
const spread = {
[key]: Object.assign(Object.assign({}, spreadStateFromService(schema, cleaned)), translated),
};
return oneLevelOfIndirectNestedness(schema, state, spread);
};
const spreadStateFromService = (serviceSchema, statePath) => {
debugLog(`spreadStateFromService: Looking to match ${JSON.stringify(statePath)} in ${JSON.stringify(serviceSchema)}`);
return Object.keys(statePath)
.map(key => {
debugLog(`spreadStateFromService: traversing the given state, looking to match ${key}`);
const scm = serviceSchema[key];
const stateValue = statePath[key];
return scm === undefined
? matchWhenMissingKey(serviceSchema, statePath, key)
: isConcreteValue(stateValue)
? matchWithConcreteValue(scm, stateValue, key)
: matchWithNonConcreteValue(scm, statePath, key);
})
.reduce((obj, el) => (Object.assign(Object.assign({}, obj), el)), {});
};
const NESTED_SCHEMA_ITEMS = ["properties", "items", "additionalProperties"];
const hasNoNestedItems = (obj) => NESTED_SCHEMA_ITEMS.every((key) => obj[key] === undefined);
const isConcreteValue = (obj) => ["string", "number", "boolean", "function"].includes(typeof obj);
const isEmptyObject = (obj) => Object.keys(obj).length === 0;
const oneLevelOfIndirectNestedness = (schema, path, initObj = {}) => NESTED_SCHEMA_ITEMS.reduce((o, key) => {
if (schema[key] === undefined) {
return o;
}
const maybeContents = spreadStateFromService(schema[key], path);
const hasContents = maybeContents !== undefined &&
Object.keys(maybeContents).length > 0 &&
Object.keys(maybeContents).every((k) => maybeContents[k] !== null);
return hasContents
? o[key] !== undefined
? Object.assign(Object.assign({}, o), { [key]: Object.assign(Object.assign({}, o[key]), { [key]: maybeContents }) }) : Object.assign(Object.assign({}, o), { [key]: maybeContents })
: o;
}, initObj);
const DFSVerifyNoneAreNull = (obj, nestedLevel = 0) => {
if (obj === undefined) {
return undefined;
}
for (const key of Object.keys(obj)) {
if (obj[key] === null) {
return {
msg: `Can't find definition for '${key}', or its type is incorrect`,
nestedLevel,
};
}
if (typeof obj[key] === "object") {
return DFSVerifyNoneAreNull(obj[key], nestedLevel + 1);
}
}
return undefined;
};
exports.default = { textResponse: exports.textResponse, functionResponse: exports.functionResponse, objResponse: exports.objResponse };
//# sourceMappingURL=transformers.js.map