object-rewrite
Advanced tools
Comparing version 9.0.1 to 10.0.0
@@ -1,16 +0,9 @@ | ||
"use strict"; | ||
import { injectPlugin, filterPlugin, sortPlugin } from './module/plugin'; | ||
import rewriter from './module/rewriter'; | ||
const { | ||
export default { | ||
injectPlugin, | ||
filterPlugin, | ||
sortPlugin | ||
} = require('./module/plugin'); | ||
const rewriter = require('./module/rewriter'); | ||
module.exports = { | ||
injectPlugin, | ||
filterPlugin, | ||
sortPlugin, | ||
rewriter | ||
}; | ||
}; |
@@ -1,13 +0,7 @@ | ||
"use strict"; | ||
import assert from 'assert'; | ||
import Joi from 'joi-strict'; | ||
import validationCompile from './plugin/validation-compile'; | ||
import validationExtractKeys from './plugin/validation-extract-keys'; | ||
import joinPath from './plugin/join-path'; | ||
const assert = require('assert'); | ||
const Joi = require('joi-strict'); | ||
const validationCompile = require('./plugin/validation-compile'); | ||
const validationExtractKeys = require('./plugin/validation-extract-keys'); | ||
const joinPath = require('./plugin/join-path'); | ||
const plugin = (type, options) => { | ||
@@ -17,38 +11,40 @@ assert(['FILTER', 'INJECT', 'SORT'].includes(type)); | ||
name: Joi.string(), | ||
target: Joi.string(), | ||
// target can not be "", use "*" instead | ||
requires: Joi.alternatives(Joi.array().items(Joi.string()), Joi.function().arity(1)), | ||
contextSchema: Joi.alternatives(Joi.object(), Joi.array(), Joi.function()).optional(), | ||
valueSchema: Joi.alternatives(Joi.object(), Joi.array(), Joi.function()).optional(), | ||
target: Joi.string(), // target can not be "", use "*" instead | ||
requires: Joi.alternatives( | ||
Joi.array().items(Joi.string()), | ||
Joi.function().arity(1) | ||
), | ||
schema: Joi.object({ | ||
initContext: Joi.alternatives(Joi.object(), Joi.array(), Joi.function()).optional(), | ||
rewriteContext: Joi.alternatives(Joi.object(), Joi.array(), Joi.function()).optional(), | ||
fnInput: Joi.alternatives(Joi.object(), Joi.array(), Joi.function()).optional(), | ||
fnOutput: type === 'INJECT' ? Joi.alternatives(Joi.object(), Joi.array(), Joi.function()) : Joi.forbidden() | ||
})[type === 'INJECT' ? 'required' : 'optional'](), | ||
onInit: Joi.function().optional(), | ||
onRewrite: Joi.function().optional(), | ||
fn: Joi.function(), | ||
fnSchema: type === 'INJECT' ? Joi.alternatives(Joi.object(), Joi.array(), Joi.function()) : Joi.forbidden(), | ||
limit: type === 'SORT' ? Joi.function().optional() : Joi.forbidden() | ||
})); | ||
const { | ||
name, | ||
target, | ||
requires, | ||
contextSchema, | ||
valueSchema, | ||
onInit, | ||
onRewrite, | ||
fn, | ||
fnSchema, | ||
limit | ||
name, target, requires, schema, onInit, onRewrite, fn, limit | ||
} = options; | ||
const contextSchemaCompiled = contextSchema === undefined ? () => true : validationCompile(contextSchema, false); | ||
const schemaCompiled = { | ||
initContext: schema?.initContext ? validationCompile(schema.initContext, false) : () => true, | ||
rewriteContext: schema?.rewriteContext ? validationCompile(schema.rewriteContext, false) : () => true, | ||
fnInput: schema?.fnInput ? validationCompile(schema.fnInput, false) : null, | ||
fnOutput: schema?.fnOutput ? validationCompile(schema.fnOutput) : null | ||
}; | ||
let localCache; | ||
let localContext; | ||
const wrap = f => { | ||
const wrap = (f) => { | ||
if (f === undefined) { | ||
return undefined; | ||
} | ||
return (kwargs = {}) => { | ||
// eslint-disable-next-line no-param-reassign | ||
kwargs.cache = localCache; // eslint-disable-next-line no-param-reassign | ||
kwargs.cache = localCache; | ||
// eslint-disable-next-line no-param-reassign | ||
kwargs.context = localContext; | ||
@@ -58,35 +54,24 @@ return f(kwargs); | ||
}; | ||
const wrapInject = f => { | ||
const schema = validationCompile(fnSchema); | ||
const validate = r => { | ||
if (schema(r) !== true) { | ||
const wrapInject = (f) => { | ||
const validate = (r) => { | ||
if (schemaCompiled.fnOutput(r) !== true) { | ||
throw new Error(`${name}: bad fn return value "${r}"`); | ||
} | ||
return r; | ||
}; | ||
return kwargs => { | ||
return (kwargs) => { | ||
const result = f(kwargs); | ||
if (result instanceof Promise) { | ||
return result.then(r => validate(r)); | ||
return result.then((r) => validate(r)); | ||
} | ||
return validate(result); | ||
}; | ||
}; | ||
const fnWrapped = (() => { | ||
const wrapped = type === 'INJECT' ? wrapInject(wrap(fn)) : wrap(fn); | ||
if (valueSchema === undefined) { | ||
if (schemaCompiled.fnInput === null) { | ||
return wrapped; | ||
} | ||
const valueSchemaCompiled = validationCompile(valueSchema, false); | ||
return kwargs => { | ||
if (valueSchemaCompiled(kwargs.value) !== true) { | ||
return (kwargs) => { | ||
if (schemaCompiled.fnInput(kwargs.value) !== true) { | ||
throw new Error(`Value Schema validation failure\n${JSON.stringify({ | ||
@@ -98,3 +83,2 @@ origin: 'object-rewrite', | ||
} | ||
return wrapped(kwargs); | ||
@@ -115,6 +99,5 @@ }; | ||
targetRel: target, | ||
requires: initContext => { | ||
requires: (initContext) => { | ||
assert(initContext.constructor === Object); | ||
let r = requires; | ||
if (typeof requires === 'function') { | ||
@@ -124,4 +107,3 @@ r = requires(initContext); | ||
} | ||
return r.map(f => f.startsWith('/') ? f.slice(1) : joinPath([prefix, f])); | ||
return r.map((f) => (f.startsWith('/') ? f.slice(1) : joinPath([prefix, f]))); | ||
}, | ||
@@ -132,50 +114,61 @@ type, | ||
}; | ||
if (type === 'INJECT') { | ||
result.targetNormalized = prefix; | ||
result.targets = validationExtractKeys(targetAbs, fnSchema); | ||
result.targets = validationExtractKeys(targetAbs, schema.fnOutput); | ||
} | ||
return result; | ||
}; | ||
self.meta = { | ||
name, | ||
contextSchema, | ||
onInit: initContext => { | ||
localCache = {}; | ||
localContext = initContext; | ||
if (onInit === undefined) { | ||
return true; | ||
} | ||
return wrap(onInit)(); | ||
}, | ||
onRewrite: (data, context, logger) => { | ||
if (contextSchemaCompiled(context) === false) { | ||
logger.warn(`Context validation failure\n${JSON.stringify({ | ||
origin: 'object-rewrite', | ||
options | ||
})}`); | ||
return false; | ||
} | ||
localContext = contextSchema instanceof Object && !Array.isArray(contextSchema) ? Object.keys(contextSchema).reduce((p, k) => { | ||
const handleCb = ({ | ||
type: cbType, | ||
before: cbBefore, | ||
kwargs, | ||
fn: cbFn, | ||
context, | ||
logger | ||
}) => { | ||
const fnName = `${cbType}Context`; | ||
if (schemaCompiled[fnName](context) === false) { | ||
logger.warn(`${cbType[0].toUpperCase()}${cbType.slice(1)} Context validation failure\n${JSON.stringify({ | ||
origin: 'object-rewrite', | ||
options | ||
})}`); | ||
return false; | ||
} | ||
cbBefore(); | ||
localContext = schema?.[fnName] instanceof Object && !Array.isArray(schema?.[fnName]) | ||
? Object.keys(schema?.[fnName]).reduce((p, k) => { | ||
// eslint-disable-next-line no-param-reassign | ||
p[k] = context[k]; | ||
return p; | ||
}, {}) : context; | ||
return onRewrite === undefined ? true : wrap(onRewrite)({ | ||
data | ||
}); | ||
} | ||
}, {}) | ||
: context; | ||
return cbFn === undefined ? true : wrap(cbFn)(kwargs); | ||
}; | ||
self.meta = { | ||
name, | ||
schema, | ||
onInit: (context, logger) => handleCb({ | ||
type: 'init', | ||
before: () => { | ||
localCache = {}; | ||
}, | ||
kwargs: {}, | ||
fn: onInit, | ||
context, | ||
logger | ||
}), | ||
onRewrite: (data, context, logger) => handleCb({ | ||
type: 'rewrite', | ||
before: () => {}, | ||
kwargs: { data }, | ||
fn: onRewrite, | ||
logger, | ||
context | ||
}) | ||
}; | ||
return self; | ||
}; | ||
module.exports = { | ||
filterPlugin: opts => plugin('FILTER', opts), | ||
injectPlugin: opts => plugin('INJECT', opts), | ||
sortPlugin: opts => plugin('SORT', opts) | ||
}; | ||
export const filterPlugin = (opts) => plugin('FILTER', opts); | ||
export const injectPlugin = (opts) => plugin('INJECT', opts); | ||
export const sortPlugin = (opts) => plugin('SORT', opts); |
@@ -1,15 +0,10 @@ | ||
"use strict"; | ||
module.exports = input => { | ||
const result = input.filter(e => !!e).join('.'); | ||
export default (input) => { | ||
const result = input.filter((e) => !!e).join('.'); | ||
if (result === '*') { | ||
return ''; | ||
} | ||
if (result.endsWith('.*')) { | ||
return result.slice(0, -1); | ||
} | ||
return result; | ||
}; | ||
}; |
@@ -1,5 +0,3 @@ | ||
"use strict"; | ||
import assert from 'assert'; | ||
const assert = require('assert'); | ||
const validationCompile = (input, strict = true) => { | ||
@@ -9,13 +7,18 @@ if (typeof input === 'function') { | ||
} | ||
if (Array.isArray(input)) { | ||
const compiled = input.map(v => validationCompile(v, strict)); | ||
return r => Array.isArray(r) && r.every(e => compiled.some(v => v(e) === true)); | ||
const compiled = input.map((v) => validationCompile(v, strict)); | ||
return (r) => ( | ||
Array.isArray(r) | ||
&& r.every((e) => compiled.some((v) => v(e) === true)) | ||
); | ||
} | ||
assert(input instanceof Object); | ||
const compiled = Object.entries(input).map(([k, v]) => [k, validationCompile(v, strict)]); | ||
return r => r instanceof Object && !Array.isArray(r) && (strict === false || Object.keys(r).length === compiled.length) && compiled.every(([k, v]) => v(r[k]) === true); | ||
return (r) => ( | ||
r instanceof Object | ||
&& !Array.isArray(r) | ||
&& (strict === false || Object.keys(r).length === compiled.length) | ||
&& compiled.every(([k, v]) => v(r[k]) === true) | ||
); | ||
}; | ||
module.exports = validationCompile; | ||
export default validationCompile; |
@@ -1,5 +0,3 @@ | ||
"use strict"; | ||
import assert from 'assert'; | ||
const assert = require('assert'); | ||
const validationExtractKeys = (prefix, input) => { | ||
@@ -9,3 +7,2 @@ if (typeof input === 'function') { | ||
} | ||
if (Array.isArray(input)) { | ||
@@ -15,10 +12,9 @@ assert(input.length === 1); | ||
} | ||
assert(input instanceof Object); | ||
return Object.entries(input).reduce((p, [k, v]) => { | ||
validationExtractKeys(`${prefix}.${k}`, v).forEach(e => p.push(e)); | ||
validationExtractKeys(`${prefix}.${k}`, v) | ||
.forEach((e) => p.push(e)); | ||
return p; | ||
}, []); | ||
}; | ||
module.exports = validationExtractKeys; | ||
export default validationExtractKeys; |
@@ -1,27 +0,19 @@ | ||
"use strict"; | ||
import assert from 'assert'; | ||
import objectFields from 'object-fields'; | ||
import compileMeta from './rewriter/compile-meta'; | ||
import mkInjectRewriter from './rewriter/mk-inject-rewriter'; | ||
import mkFilterRewriter from './rewriter/mk-filter-rewriter'; | ||
import mkSortRewriter from './rewriter/mk-sort-rewriter'; | ||
import initPluginMap from './rewriter/init-plugin-map'; | ||
const assert = require('assert'); | ||
export default (pluginMap, dataStoreFields_, logger = console) => { | ||
assert(pluginMap instanceof Object && !Array.isArray(pluginMap)); | ||
assert(Array.isArray(dataStoreFields_) && dataStoreFields_.every((e) => typeof e === 'string')); | ||
const objectFields = require('object-fields'); | ||
const compileMeta = require('./rewriter/compile-meta'); | ||
const mkInjectRewriter = require('./rewriter/mk-inject-rewriter'); | ||
const mkFilterRewriter = require('./rewriter/mk-filter-rewriter'); | ||
const mkSortRewriter = require('./rewriter/mk-sort-rewriter'); | ||
const initPluginMap = require('./rewriter/init-plugin-map'); | ||
module.exports = (pluginMap, dataStoreFields_, logger = console) => { | ||
assert(pluginMap instanceof Object && !Array.isArray(pluginMap)); | ||
assert(Array.isArray(dataStoreFields_) && dataStoreFields_.every(e => typeof e === 'string')); | ||
const pluginNames = {}; | ||
const plugins = Object.entries(pluginMap).reduce((prev, [prefix, ps], prefixIndex) => { | ||
ps.forEach(p => { | ||
ps.forEach((p) => { | ||
if (p.meta.name in pluginNames && p !== pluginNames[p.meta.name]) { | ||
throw new Error(`Plugin name "${p.meta.name}" not unique`); | ||
} | ||
pluginNames[p.meta.name] = p; | ||
@@ -33,6 +25,9 @@ prev.push(p(prefix, prefixIndex)); | ||
const dataStoreFields = new Set(dataStoreFields_); | ||
const allowedFields = plugins.filter(p => p.type === 'INJECT').reduce((p, c) => { | ||
c.targets.forEach(t => p.add(t)); | ||
return p; | ||
}, new Set(dataStoreFields)); | ||
const allowedFields = plugins | ||
.filter((p) => p.type === 'INJECT') | ||
.reduce((p, c) => { | ||
c.targets.forEach((t) => p.add(t)); | ||
return p; | ||
}, new Set(dataStoreFields)); | ||
return { | ||
@@ -43,16 +38,12 @@ allowedFields: [...allowedFields], | ||
if (!fields.every(f => allowedFields.has(f))) { | ||
throw new Error(`Bad Field Requested: ${fields.filter(f => !allowedFields.has(f)).join(', ')}`); | ||
if (!fields.every((f) => allowedFields.has(f))) { | ||
throw new Error(`Bad Field Requested: ${fields.filter((f) => !allowedFields.has(f)).join(', ')}`); | ||
} | ||
const { | ||
injectMap, | ||
filterMap, | ||
sortMap, | ||
fieldsToRequest, | ||
activePlugins | ||
} = compileMeta(plugins, fields, initContext); | ||
injectMap, filterMap, sortMap, fieldsToRequest, activePlugins | ||
} = compileMeta(plugins, fields, initContext, logger); | ||
if (!fieldsToRequest.every(f => dataStoreFields.has(f))) { | ||
throw new Error(`Bad Field Requested: ${fieldsToRequest.filter(f => !dataStoreFields.has(f))}`); | ||
if (!fieldsToRequest.every((f) => dataStoreFields.has(f))) { | ||
throw new Error(`Bad Field Requested: ${fieldsToRequest.filter((f) => !dataStoreFields.has(f))}`); | ||
} | ||
@@ -67,5 +58,3 @@ | ||
assert(context instanceof Object && !Array.isArray(context)); | ||
const { | ||
promises | ||
} = injectRewriter(input, { | ||
const { promises } = injectRewriter(input, { | ||
injectMap: initPluginMap(injectMap, input, context, logger), | ||
@@ -76,3 +65,2 @@ promises: [] | ||
}; | ||
const rewriteEnd = (input, context) => { | ||
@@ -88,3 +76,2 @@ filterRewriter(input, { | ||
}; | ||
return { | ||
@@ -94,5 +81,3 @@ fieldsToRequest, | ||
rewrite: (input, context_ = {}) => { | ||
const context = { ...context_, | ||
...initContext | ||
}; | ||
const context = { ...context_, ...initContext }; | ||
const promises = rewriteStart(input, context); | ||
@@ -103,7 +88,5 @@ assert(promises.length === 0, 'Please use rewriteAsync() for async logic'); | ||
rewriteAsync: async (input, context_ = {}) => { | ||
const context = { ...context_, | ||
...initContext | ||
}; | ||
const context = { ...context_, ...initContext }; | ||
const promises = rewriteStart(input, context); | ||
await Promise.all(promises.map(p => p())); | ||
await Promise.all(promises.map((p) => p())); | ||
rewriteEnd(input, context); | ||
@@ -114,2 +97,2 @@ } | ||
}; | ||
}; | ||
}; |
@@ -1,29 +0,21 @@ | ||
"use strict"; | ||
module.exports = keys => { | ||
export default (keys) => { | ||
const lookups = keys.reduce((p, c, idx) => { | ||
const index = Math.max(0, c.lastIndexOf('.')); | ||
const k = c.slice(0, index); | ||
if (!(k in p)) { | ||
// eslint-disable-next-line no-param-reassign | ||
p[k] = {}; | ||
} // eslint-disable-next-line no-param-reassign | ||
} | ||
// eslint-disable-next-line no-param-reassign | ||
p[k][c.slice(index)] = idx; | ||
return p; | ||
}, {}); | ||
return ({ | ||
key | ||
}) => { | ||
const k = key.filter(e => typeof e === 'string').join('.'); | ||
return ({ key }) => { | ||
const k = key.filter((e) => typeof e === 'string').join('.'); | ||
if (!(k in lookups)) { | ||
return undefined; | ||
} | ||
const lookup = lookups[k]; | ||
return (a, b) => lookup[b] - lookup[a]; | ||
}; | ||
}; | ||
}; |
@@ -1,7 +0,5 @@ | ||
"use strict"; | ||
import compileTargetMap from './compile-target-map'; | ||
const compileTargetMap = require('./compile-target-map'); // todo: write separate test | ||
module.exports = (plugins, fields, initContext) => { | ||
// todo: write separate test | ||
export default (plugins, fields, initContext, logger) => { | ||
const pluginsByType = { | ||
@@ -12,3 +10,5 @@ FILTER: [], | ||
}; | ||
const activeLookup = new Map(); | ||
const activePlugins = new Set(); | ||
@@ -20,16 +20,20 @@ const inactivePlugins = [...plugins]; | ||
const field = requiredFields[i]; | ||
for (let j = 0; j < inactivePlugins.length; j += 1) { | ||
const plugin = inactivePlugins[j]; | ||
if (!activeLookup.has(plugin.self)) { | ||
activeLookup.set(plugin.self, plugin.self.meta.onInit(initContext)); | ||
activeLookup.set(plugin.self, plugin.self.meta.onInit(initContext, logger)); | ||
} | ||
if (activeLookup.get(plugin.self) === true && (plugin.targets.includes(field) || (plugin.type !== 'INJECT' || plugin.targetRel === '*') && (`${field}.` === plugin.target || field.startsWith(plugin.target)))) { | ||
if ( | ||
activeLookup.get(plugin.self) === true | ||
&& ( | ||
plugin.targets.includes(field) | ||
|| ( | ||
(plugin.type !== 'INJECT' || plugin.targetRel === '*') | ||
&& (`${field}.` === plugin.target || field.startsWith(plugin.target)) | ||
) | ||
) | ||
) { | ||
const requires = [...plugin.requires(initContext)]; | ||
for (let x = requiredFields.length - 1; x >= 0; x -= 1) { | ||
const idx = requires.indexOf(requiredFields[x]); | ||
if (idx !== -1) { | ||
@@ -43,3 +47,2 @@ if (x > i) { | ||
} | ||
requiredFields.splice(i + 1, 0, ...requires); | ||
@@ -55,8 +58,13 @@ pluginsByType[plugin.type].push(plugin); | ||
const injectedFields = new Set(); | ||
pluginsByType.INJECT.forEach(p => { | ||
p.targets.filter(target => !p.requires(initContext).includes(target)).forEach(t => injectedFields.add(t)); | ||
}); | ||
['FILTER', 'INJECT', 'SORT'].forEach(f => { | ||
pluginsByType.INJECT | ||
.forEach((p) => { | ||
p.targets | ||
.filter((target) => !p.requires(initContext).includes(target)) | ||
.forEach((t) => injectedFields.add(t)); | ||
}); | ||
['FILTER', 'INJECT', 'SORT'].forEach((f) => { | ||
pluginsByType[f].sort((a, b) => a.prefixIndex - b.prefixIndex); | ||
}); | ||
return { | ||
@@ -66,5 +74,5 @@ filterMap: compileTargetMap('FILTER', pluginsByType.FILTER, initContext), | ||
sortMap: compileTargetMap('SORT', pluginsByType.SORT, initContext), | ||
fieldsToRequest: requiredFields.filter(e => !injectedFields.has(e)), | ||
fieldsToRequest: requiredFields.filter((e) => !injectedFields.has(e)), | ||
activePlugins: [...activePlugins] | ||
}; | ||
}; | ||
}; |
@@ -1,16 +0,10 @@ | ||
"use strict"; | ||
module.exports = (type, plugins, initContext) => { | ||
export default (type, plugins, initContext) => { | ||
const result = {}; | ||
for (let i = 0; i < plugins.length; i += 1) { | ||
const plugin = plugins[i]; | ||
const key = plugin.targetNormalized; | ||
if (!(key in result)) { | ||
result[key] = []; | ||
} | ||
let insertIdx = result[key].length; | ||
for (let idx = 0; idx < result[key].length; idx += 1) { | ||
@@ -22,7 +16,5 @@ if (result[key][idx].requires(initContext).includes(plugin.target)) { | ||
} | ||
result[key].splice(insertIdx, 0, plugin); | ||
} | ||
return result; | ||
}; | ||
}; |
@@ -1,12 +0,9 @@ | ||
"use strict"; | ||
module.exports = (map, data, context, logger) => { | ||
export default (map, data, context, logger) => { | ||
const result = {}; | ||
const activeLookup = new Map(); | ||
Object.entries(map).forEach(([prefix, pls]) => { | ||
result[prefix] = pls.filter(pl => { | ||
result[prefix] = pls.filter((pl) => { | ||
if (!activeLookup.has(pl.self)) { | ||
activeLookup.set(pl.self, pl.self.meta.onRewrite(data, context, logger)); | ||
} | ||
return activeLookup.get(pl.self) === true; | ||
@@ -16,2 +13,2 @@ }); | ||
return result; | ||
}; | ||
}; |
@@ -1,22 +0,13 @@ | ||
"use strict"; | ||
import assert from 'assert'; | ||
import objectScan from 'object-scan'; | ||
import CompareFn from './compare-fn'; | ||
const assert = require('assert'); | ||
const objectScan = require('object-scan'); | ||
const CompareFn = require('./compare-fn'); | ||
module.exports = keys => objectScan(keys, { | ||
export default (keys) => objectScan(keys, { | ||
useArraySelector: false, | ||
compareFn: CompareFn(keys), | ||
filterFn: ({ | ||
matchedBy, | ||
getKey, | ||
getValue, | ||
getParents, | ||
context | ||
matchedBy, getKey, getValue, getParents, context | ||
}) => { | ||
assert(matchedBy.length === 1); | ||
const plugins = context.filterMap[matchedBy[0]]; | ||
if (plugins.length === 0) { | ||
@@ -34,4 +25,3 @@ return true; | ||
}; | ||
const result = plugins.every(plugin => plugin.fn(kwargs)) === true; | ||
const result = plugins.every((plugin) => plugin.fn(kwargs)) === true; | ||
if (result === false) { | ||
@@ -44,5 +34,4 @@ if (Array.isArray(parents[0])) { | ||
} | ||
return result; | ||
} | ||
}); | ||
}); |
@@ -1,24 +0,14 @@ | ||
"use strict"; | ||
import assert from 'assert'; | ||
import objectScan from 'object-scan'; | ||
import set from 'lodash.set'; | ||
import CompareFn from './compare-fn'; | ||
const assert = require('assert'); | ||
const objectScan = require('object-scan'); | ||
const set = require('lodash.set'); | ||
const CompareFn = require('./compare-fn'); | ||
module.exports = keys => objectScan(keys, { | ||
export default (keys) => objectScan(keys, { | ||
useArraySelector: false, | ||
compareFn: CompareFn(keys), | ||
filterFn: ({ | ||
matchedBy, | ||
getKey, | ||
getValue, | ||
getParents, | ||
context | ||
matchedBy, getKey, getValue, getParents, context | ||
}) => { | ||
assert(matchedBy.length === 1); | ||
const plugins = context.injectMap[matchedBy[0]]; | ||
if (plugins.length === 0) { | ||
@@ -37,4 +27,4 @@ return true; | ||
const promises = []; | ||
plugins.forEach(plugin => { | ||
const exec = r => { | ||
plugins.forEach((plugin) => { | ||
const exec = (r) => { | ||
if (plugin.targetRel === '*') { | ||
@@ -46,5 +36,3 @@ Object.assign(kwargs.value, r); | ||
}; | ||
const result = plugin.fn(kwargs); | ||
if (result instanceof Promise) { | ||
@@ -59,2 +47,2 @@ promises.push(async () => exec(await result)); | ||
} | ||
}); | ||
}); |
@@ -1,24 +0,14 @@ | ||
"use strict"; | ||
import assert from 'assert'; | ||
import objectScan from 'object-scan'; | ||
import cmpFn from '../../util/cmp-fn'; | ||
import CompareFn from './compare-fn'; | ||
const assert = require('assert'); | ||
const objectScan = require('object-scan'); | ||
const cmpFn = require('../../util/cmp-fn'); | ||
const CompareFn = require('./compare-fn'); | ||
module.exports = keys => objectScan(keys, { | ||
export default (keys) => objectScan(keys, { | ||
useArraySelector: false, | ||
compareFn: CompareFn(keys), | ||
filterFn: ({ | ||
matchedBy, | ||
getKey, | ||
getValue, | ||
getParents, | ||
context | ||
matchedBy, getKey, getValue, getParents, context | ||
}) => { | ||
assert(matchedBy.length === 1); | ||
const plugins = context.sortMap[matchedBy[0]]; | ||
if (plugins.length === 0) { | ||
@@ -32,7 +22,5 @@ return true; | ||
assert(Array.isArray(parents[0]), 'Sort must be on "Array" type.'); | ||
if (context.lookups[key.length - 1] === undefined) { | ||
context.lookups[key.length - 1] = new Map(); | ||
} | ||
const lookup = context.lookups[key.length - 1]; | ||
@@ -44,20 +32,17 @@ const kwargs = { | ||
}; | ||
lookup.set(value, plugins.map(plugin => plugin.fn(kwargs))); | ||
lookup.set(value, plugins.map((plugin) => plugin.fn(kwargs))); | ||
if (key[key.length - 1] === 0) { | ||
parents[0].sort((a, b) => cmpFn(lookup.get(a), lookup.get(b))); | ||
const limits = plugins.filter(p => p.limit !== undefined).map(p => p.limit({ | ||
context: context.context | ||
})).filter(l => l !== undefined); | ||
const limits = plugins | ||
.filter((p) => p.limit !== undefined) | ||
.map((p) => p.limit({ context: context.context })) | ||
.filter((l) => l !== undefined); | ||
if (limits.length !== 0) { | ||
assert(limits.every(l => Number.isInteger(l) && l >= 0)); | ||
assert(limits.every((l) => Number.isInteger(l) && l >= 0)); | ||
parents[0].splice(Math.min(...limits)); | ||
} | ||
context.lookups.splice(key.length - 1); | ||
} | ||
return true; | ||
} | ||
}); | ||
}); |
@@ -1,5 +0,3 @@ | ||
"use strict"; | ||
import assert from 'assert'; | ||
const assert = require('assert'); | ||
const fn = (a, b) => { | ||
@@ -9,6 +7,4 @@ if (Array.isArray(a)) { | ||
assert(a.length === b.length); | ||
for (let idx = 0; idx < a.length; idx += 1) { | ||
const sign = fn(a[idx], b[idx]); | ||
if (sign !== 0) { | ||
@@ -18,13 +14,9 @@ return sign; | ||
} | ||
return 0; | ||
} | ||
if (a === b) { | ||
return 0; | ||
} | ||
return a < b ? -1 : 1; | ||
}; | ||
module.exports = fn; | ||
export default fn; |
{ | ||
"name": "object-rewrite", | ||
"version": "9.0.1", | ||
"version": "10.0.0", | ||
"description": "Rewrite Object(s) in place using plugins.", | ||
@@ -10,32 +10,32 @@ "main": "lib/index.js", | ||
"dependencies": { | ||
"joi-strict": "2.0.0", | ||
"joi-strict": "2.0.1", | ||
"lodash.set": "4.3.2", | ||
"object-fields": "3.0.0", | ||
"object-scan": "17.0.0" | ||
"object-fields": "3.0.1", | ||
"object-scan": "17.1.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "7.14.8", | ||
"@babel/core": "7.15.0", | ||
"@babel/register": "7.15.3", | ||
"@blackflux/eslint-plugin-rules": "2.0.3", | ||
"@blackflux/robo-config-plugin": "5.3.0", | ||
"babel-eslint": "10.1.0", | ||
"babel-preset-latest-node": "5.5.1", | ||
"@babel/cli": "7.16.8", | ||
"@babel/core": "7.16.10", | ||
"@babel/eslint-parser": "7.16.5", | ||
"@babel/preset-env": "7.16.11", | ||
"@babel/register": "7.16.9", | ||
"@blackflux/eslint-plugin-rules": "2.0.4", | ||
"@blackflux/robo-config-plugin": "5.3.26", | ||
"babel-plugin-istanbul": "6.1.1", | ||
"chai": "4.3.4", | ||
"coveralls": "3.1.1", | ||
"eslint": "7.32.0", | ||
"eslint-config-airbnb-base": "14.2.1", | ||
"eslint-plugin-import": "2.24.2", | ||
"eslint": "8.7.0", | ||
"eslint-config-airbnb-base": "15.0.0", | ||
"eslint-plugin-import": "2.25.4", | ||
"eslint-plugin-json": "3.1.0", | ||
"eslint-plugin-markdown": "2.2.0", | ||
"eslint-plugin-mocha": "9.0.0", | ||
"js-gardener": "3.0.3", | ||
"eslint-plugin-markdown": "2.2.1", | ||
"eslint-plugin-mocha": "10.0.3", | ||
"js-gardener": "3.0.5", | ||
"lodash.get": "4.4.2", | ||
"lodash.shuffle": "4.2.0", | ||
"nyc": "15.1.0", | ||
"semantic-release": "17.4.7" | ||
"nyc": "15.1.0" | ||
}, | ||
"scripts": { | ||
"clean": "rm -rf lib", | ||
"build": "npx babel src --out-dir lib --copy-files --include-dotfiles --config-file ./.babelrc", | ||
"build": "cp -rf ./src ./lib", | ||
"build-clean": "yarn run clean && yarn run build", | ||
@@ -93,3 +93,5 @@ "test-simple": "nyc mocha \"./test/**/*.spec.js\"", | ||
"lib/*" | ||
] | ||
], | ||
"sourceMap": false, | ||
"instrument": false | ||
}, | ||
@@ -104,3 +106,3 @@ "licenses": [ | ||
"engines": { | ||
"node": ">= 12" | ||
"node": ">= 14" | ||
}, | ||
@@ -107,0 +109,0 @@ "repository": { |
@@ -27,3 +27,3 @@ # object-rewrite | ||
```js | ||
const { | ||
import { | ||
injectPlugin, | ||
@@ -33,3 +33,3 @@ filterPlugin, | ||
rewriter | ||
} = require('object-rewrite'); | ||
} from 'object-rewrite'; | ||
@@ -78,4 +78,3 @@ const queryDataStore = (fields) => { /* ... */ }; | ||
- `onRewrite({ data, context, cache })` _Function_ (optional): if present called once per rewrite, used to update cache, if returns other than `true`, the plugin is disabled | ||
- `contextSchema`: Object schema structure of what is expected to be present in rewrite `context` (subset) | ||
- `valueSchema` (optional): Used to validate value before passed into `fn` | ||
- `schema`: Object schema structure of form `{ initContext: {}, rewriteContext: {}, fnInput: {}, fnOutput: {} }` of what is expected to be present in corresponding `context` (subset) | ||
@@ -88,2 +87,4 @@ where: | ||
- `cache = {}` is locally defined per plugin | ||
- `schema.fnInput` (optional) is used to validate value before passed into `fn` | ||
- `schema.fnOutput` is used by the inject plugin only | ||
@@ -97,3 +98,3 @@ ### Inject Plugin | ||
- `fn`: return value is used for target. Relative to prefix | ||
- `fnSchema`: Object schema structure of what is being injected (strict result of `fn`) | ||
- `schema.fnOutput`: Object schema structure of what is being injected (strict result of `fn`) | ||
@@ -132,3 +133,3 @@ ### Filter Plugin | ||
```js | ||
const { injectPlugin, rewriter } = require('object-rewrite'); | ||
import { injectPlugin, rewriter } from 'object-rewrite'; | ||
@@ -135,0 +136,0 @@ const plugin = injectPlugin(/* ... */); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
29057
559
180
+ Addedjoi@17.4.2(transitive)
+ Addedjoi-strict@2.0.1(transitive)
+ Addedobject-fields@3.0.1(transitive)
+ Addedobject-scan@17.1.0(transitive)
- Removedjoi@17.4.0(transitive)
- Removedjoi-strict@2.0.0(transitive)
- Removedobject-fields@3.0.0(transitive)
- Removedobject-scan@14.0.0(transitive)
Updatedjoi-strict@2.0.1
Updatedobject-fields@3.0.1
Updatedobject-scan@17.1.0