UNPKG

@calvin_von/proxy-plugin-cache

Version:

A dalao-proxy plugin for cache response

283 lines (260 loc) 8.05 kB
const chalk = require('chalk'); const defaultFilenameTpl = '{method}_{basename}{query}{jsonExt}{htmlAppend}'; const cacheDefaults = { "enable": true, "dirname": ".dalao-cache", "contentType": [ "application/json" ], /** * Define how url maps to FS */ "filenameTpl": defaultFilenameTpl, /** * Filters of query params maps to FS * * @example queryFilter: { foo: false, bar: true } * * @type {null|Record<string, boolean>} */ "queryFilter": null, "maxAge": [ 0, "second" ], "filters": [ { /** * filter when request or response * Options: `response`, `request` */ when: "response", /** * filter by response body or header * Options: `status`, `data`, `header` for `response` * Options: `body`, `query`, `header` for `request` */ where: "status", /** * filter field */ field: null, /** * filter field value */ value: 200, /** * custom filter function * @return Boolean */ custom: null, /** * filter applied to specific route */ applyRoute: "*" } ], "logger": true }; const mockDefaults = { "enable": true, "dirname": "mocks", "prefix": "", "cors": true, "ignoreQuery": false }; const cacheUiDefaults = { "enable": false, "container": '#app', "requestPrefix": "" }; /** * Parser raw cache options * @param {any} cacheOptions */ function cacheParser(cacheOptions) { if (isType(cacheOptions, 'Object')) { return { ...cacheDefaults, ...cacheOptions, contentType: parseContentType(cacheOptions.contentType), maxAge: parseMaxAge(cacheOptions.maxAge), filters: parseFilters(cacheOptions.filters), dirname: parseCacheDirname(cacheOptions.dirname), }; } else { return cacheDefaults; } } /** * Parser raw mock options * @param {any} mockOptions */ function mockParser(mockOptions) { if (mockOptions) { return { ...mockDefaults, ...mockOptions, prefix: parsePrefix(mockOptions.prefix), dirname: parseMockDirname(mockOptions.dirname), enable: typeof mockOptions.enable === 'undefined' ? mockDefaults.enable : mockOptions.enable, cors: typeof mockOptions.cors === 'undefined' ? mockDefaults.cors : mockOptions.cors, }; } else { return mockDefaults; } } function parseContentType(value) { return makeSureFieldType(cacheDefaults, 'contentType', 'Array', value); } function parseMaxAge(value) { let maxAge = []; if (isType(value, 'Array')) { if (value[0] !== '*' && Number.isNaN(Number(value[0]))) { configWarn('type of field `cache.maxAge[0]` should be Number'); maxAge[0] = cacheDefaults.maxAge[0]; } else { maxAge[0] = value[0]; } if (!/^(s(econds?)?|m(inutes?)?|h(ours?)?|d(ays?)?|M(onths?)?|y(ears?)?)$/.test(value[1])) { configWarn('value of field `cache.maxAge[1]` should match `/^(s(econds?)?|m(inutes?)?|h(ours?)?|d(ays?)?|M(onths?)?|y(ears?)?)$/`'); maxAge[1] = cacheDefaults.maxAge[1]; } else { maxAge[1] = value[1]; } } else { if (value) { configWarn('type of field `cache.maxAge` should be Array'); } maxAge = cacheDefaults.maxAge; } return maxAge; } function parseFilters(value) { let filters; if (isType(value, 'Array')) { filters = value .map((item, index) => { if (item.custom) { if (!isType(item.custom, 'Function')) { configWarn(`type of \`cache.filters[${index}].custom\` should be \`Function\``); item.custom = null; } else { return Object.assign({ field: null, value: null, custom: null, applyRoute: '*' }, item); } } if (item.when === 'request') { if (!/^(header|body|query)$/.test(item.where)) { configWarn(`value of \`cache.filters[${index}].where\` should be \`header\`, \`body\` or \`query\` when \`filter.when\` is \`request\``); item._disabled = true; } } else if (item.when === 'response') { if (!/^(header|data|status)$/.test(item.where)) { configWarn(`value of \`cache.filters[${index}].where\` should be \`header\`, \`status\` or \`data\` when \`filter.when\` is \`response\``); item._disabled = true; } } else { configWarn(`value of \`cache.filters[${index}].when\` should be \`request\` or \`response\``); item._disabled = true; } if (item.applyRoute) { if (!isType(item.applyRoute, 'String')) { configWarn(`type of \`cache.filters[${index}].applyRoute\` should be \`String\``); item.applyRoute = '*'; } } return Object.assign({ field: null, value: null, custom: null, applyRoute: '*' }, item); }) .filter(item => !item._disabled) } else { if (value) { configWarn('type of field `cache.filters` should be Array'); } filters = cacheDefaults.filters; } return filters; } function parsePrefix(value) { return makeSureFieldType(mockDefaults, 'prefix', 'String', value, () => { if (value && value[0] !== '/') { configWarn('`mock.prefix` must start with `/`'); return mockDefaults.prefix; } return value; }); } function parseCacheDirname(value) { return makeSureFieldType(cacheDefaults, 'dirname', 'String', value); } function parseMockDirname(value) { if (isType(value, 'String')) { return value; } else { if (value) { configWarn(`type of field \`mock.dirname\` should be ${type}`) } return mockDefaults.dirname; } } function isType(value, type) { return Object.prototype.toString.call(value) === `[object ${type}]`; } function makeSureFieldType(source, field, type, value, callback) { if (isType(value, type)) { if (callback) { return callback(); } else { return value; } } else { if (value) { configWarn(`type of field \`cache.${field}\` should be ${type}`) } return source[field]; } } function configWarn(message) { console.warn(chalk.red('[Plugin cache]: ' + message)); } module.exports = { setting: { defaultEnable: true, optionsField: ['cache', 'mock', 'cache-ui'], dependFields: ['requestHijack.prefix'], enableField: 'enable', }, parser(cacheOptions, mockOptions, uiOptions, requestPrefix) { return { cache: cacheParser(cacheOptions), mock: mockParser(mockOptions), ['cache-ui']: { ...cacheUiDefaults, ...(uiOptions || {}), requestPrefix: requestPrefix || '' } }; }, defaultFilenameTpl };