object-rewrite
Advanced tools
Comparing version 4.2.8 to 4.3.0
@@ -19,2 +19,3 @@ "use strict"; | ||
requires: Joi.array().items(Joi.string()), | ||
init: Joi.function().optional(), | ||
fn: Joi.function(), | ||
@@ -27,2 +28,3 @@ schema: type === 'INJECT' ? Joi.alternatives(Joi.object(), Joi.array(), Joi.function()) : Joi.forbidden(), | ||
requires, | ||
init, | ||
fn, | ||
@@ -34,2 +36,3 @@ schema, | ||
const targetAbs = joinPath([prefix, target]); | ||
let cache; | ||
const result = { | ||
@@ -43,3 +46,12 @@ prefix, | ||
type, | ||
fn, | ||
init: context => { | ||
cache = {}; | ||
return init === undefined ? true : init({ | ||
context, | ||
cache | ||
}); | ||
}, | ||
fn: kwargs => fn({ ...kwargs, | ||
cache | ||
}), | ||
limit | ||
@@ -46,0 +58,0 @@ }; |
@@ -5,54 +5,17 @@ "use strict"; | ||
const objectScan = require('object-scan'); | ||
const objectFields = require('object-fields'); | ||
const cmpFn = require('../util/cmp-fn'); | ||
const compileMeta = require('./rewriter/compile-meta'); | ||
const compileTargetMap = require('./rewriter/compile-target-map'); | ||
const mkInjectRewriter = require('./rewriter/mk-inject-rewriter'); | ||
const compileMeta = (plugins, fields) => { | ||
const pluginsByType = { | ||
FILTER: [], | ||
INJECT: [], | ||
SORT: [] | ||
}; | ||
const inactivePlugins = [...plugins]; | ||
const requiredFields = [...fields]; | ||
const ignoredFields = new Set(); | ||
const mkFilterRewriter = require('./rewriter/mk-filter-rewriter'); | ||
for (let i = 0; i < requiredFields.length; i += 1) { | ||
const field = requiredFields[i]; | ||
const mkSortRewriter = require('./rewriter/mk-sort-rewriter'); | ||
for (let j = 0; j < inactivePlugins.length; j += 1) { | ||
const plugin = inactivePlugins[j]; | ||
const initPluginMap = require('./rewriter/init-plugin-map'); | ||
if (plugin.targets.includes(field) || (plugin.type !== 'INJECT' || plugin.targetRel === '*') && (`${field}.` === plugin.target || field.startsWith(plugin.target))) { | ||
requiredFields.push(...plugin.requires); | ||
inactivePlugins.splice(j, 1); | ||
j -= 1; | ||
pluginsByType[plugin.type].push(plugin); | ||
if (plugin.type === 'INJECT') { | ||
plugin.targets.forEach(target => { | ||
if (!plugin.requires.includes(target)) { | ||
ignoredFields.add(target); | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
return { | ||
filterCbs: compileTargetMap('FILTER', pluginsByType.FILTER), | ||
injectCbs: compileTargetMap('INJECT', pluginsByType.INJECT), | ||
sortCbs: compileTargetMap('SORT', pluginsByType.SORT), | ||
fieldsToRequest: [...new Set(requiredFields)].filter(e => !ignoredFields.has(e)) | ||
}; | ||
}; | ||
module.exports = (pluginMap, dataStoreFields) => { | ||
module.exports = (pluginMap, dataStoreFields_) => { | ||
assert(pluginMap instanceof Object && !Array.isArray(pluginMap)); | ||
assert(Array.isArray(dataStoreFields) && dataStoreFields.every(e => typeof e === 'string')); | ||
assert(Array.isArray(dataStoreFields_) && dataStoreFields_.every(e => typeof e === 'string')); | ||
const plugins = Object.entries(pluginMap).reduce((prev, [prefix, ps]) => { | ||
@@ -62,118 +25,30 @@ ps.forEach(p => prev.push(p(prefix))); | ||
}, []); | ||
const allowedFields = [...plugins.reduce((p, c) => { | ||
if (c.type === 'INJECT') { | ||
c.targets.forEach(t => p.add(t)); | ||
} | ||
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))]; | ||
}, new Set(dataStoreFields)); | ||
return { | ||
allowedFields, | ||
allowedFields: [...allowedFields], | ||
init: fields => { | ||
assert(Array.isArray(fields)); | ||
if (!fields.every(f => allowedFields.includes(f))) { | ||
throw new Error(`Bad field requested: ${fields.filter(f => !allowedFields.includes(f)).join(', ')}`); | ||
if (!fields.every(f => allowedFields.has(f))) { | ||
throw new Error(`Bad Field Requested: ${fields.filter(f => !allowedFields.has(f)).join(', ')}`); | ||
} | ||
const { | ||
injectCbs, | ||
filterCbs, | ||
sortCbs, | ||
injectMap, | ||
filterMap, | ||
sortMap, | ||
fieldsToRequest | ||
} = compileMeta(plugins, fields); | ||
assert(fieldsToRequest.every(f => dataStoreFields.includes(f)), `Bad Field Requested: ${fieldsToRequest.filter(f => !dataStoreFields.includes(f))}`); | ||
const injectRewriter = objectScan(Object.keys(injectCbs), { | ||
useArraySelector: false, | ||
joined: false, | ||
filterFn: ({ | ||
key, | ||
value, | ||
parents, | ||
matchedBy, | ||
context | ||
}) => { | ||
matchedBy.forEach(m => { | ||
const promises = injectCbs[m].fn({ | ||
key, | ||
value, | ||
parents, | ||
context: context.context | ||
}); | ||
context.promises.push(...promises); | ||
}); | ||
return true; | ||
} | ||
}); | ||
const filterRewriter = objectScan(Object.keys(filterCbs), { | ||
useArraySelector: false, | ||
joined: false, | ||
filterFn: ({ | ||
key, | ||
value, | ||
parents, | ||
matchedBy, | ||
context | ||
}) => { | ||
const result = matchedBy.some(m => filterCbs[m].fn({ | ||
key, | ||
value, | ||
parents, | ||
context: context.context | ||
}) === true); | ||
if (result === false) { | ||
const parent = key.length === 1 ? context.input : parents[0]; | ||
if (!fieldsToRequest.every(f => dataStoreFields.has(f))) { | ||
throw new Error(`Bad Field Requested: ${fieldsToRequest.filter(f => !dataStoreFields.has(f))}`); | ||
} | ||
if (Array.isArray(parent)) { | ||
parent.splice(key[key.length - 1], 1); | ||
} else { | ||
delete parent[key[key.length - 1]]; | ||
} | ||
} | ||
return result; | ||
} | ||
}); | ||
const sortRewriter = objectScan(Object.keys(sortCbs), { | ||
useArraySelector: false, | ||
joined: false, | ||
filterFn: ({ | ||
key, | ||
value, | ||
parents, | ||
matchedBy, | ||
context | ||
}) => { | ||
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]; | ||
lookup.set(value, sortCbs[matchedBy[0]].fn({ | ||
key, | ||
value, | ||
parents, | ||
context: context.context | ||
})); | ||
if (key[key.length - 1] === 0) { | ||
parents[0].sort((a, b) => cmpFn(lookup.get(a), lookup.get(b))); | ||
const limits = sortCbs[matchedBy[0]].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)); | ||
parents[0].splice(Math.min(...limits)); | ||
} | ||
context.lookups.splice(key.length - 1); | ||
} | ||
return true; | ||
} | ||
}); | ||
const injectRewriter = mkInjectRewriter(Object.keys(injectMap)); | ||
const filterRewriter = mkFilterRewriter(Object.keys(filterMap)); | ||
const sortRewriter = mkSortRewriter(Object.keys(sortMap)); | ||
const retainResult = objectFields.Retainer(fields); | ||
@@ -187,2 +62,3 @@ | ||
context, | ||
injectMap: initPluginMap(injectMap, context), | ||
promises: [] | ||
@@ -195,8 +71,9 @@ }); | ||
filterRewriter(input, { | ||
input, | ||
context | ||
context, | ||
filterMap: initPluginMap(filterMap, context) | ||
}); | ||
sortRewriter(input, { | ||
lookups: [], | ||
context | ||
context, | ||
sortMap: initPluginMap(sortMap, context), | ||
lookups: [] | ||
}); | ||
@@ -203,0 +80,0 @@ retainResult(input); |
"use strict"; | ||
const compilePlugins = require('./compile-plugins'); | ||
module.exports = (type, plugins) => { | ||
@@ -28,9 +26,3 @@ const result = {}; | ||
Object.entries(result).forEach(([target, ps]) => { | ||
result[target] = { | ||
fn: compilePlugins(type, ps), | ||
plugins: ps | ||
}; | ||
}); | ||
return result; | ||
}; |
{ | ||
"name": "object-rewrite", | ||
"version": "4.2.8", | ||
"version": "4.3.0", | ||
"description": "Rewrite Object(s) in place using plugins.", | ||
@@ -10,6 +10,6 @@ "main": "lib/index.js", | ||
"dependencies": { | ||
"joi-strict": "1.2.6", | ||
"joi-strict": "1.2.9", | ||
"lodash.set": "4.3.2", | ||
"object-fields": "2.0.17", | ||
"object-scan": "13.6.9" | ||
"object-fields": "2.0.19", | ||
"object-scan": "13.7.1" | ||
}, | ||
@@ -20,4 +20,4 @@ "devDependencies": { | ||
"@babel/register": "7.12.10", | ||
"@blackflux/eslint-plugin-rules": "1.3.42", | ||
"@blackflux/robo-config-plugin": "3.10.16", | ||
"@blackflux/eslint-plugin-rules": "1.3.43", | ||
"@blackflux/robo-config-plugin": "3.10.17", | ||
"babel-eslint": "10.1.0", | ||
@@ -27,3 +27,3 @@ "babel-preset-latest-node": "5.2.0", | ||
"coveralls": "3.1.0", | ||
"eslint": "7.15.0", | ||
"eslint": "7.17.0", | ||
"eslint-config-airbnb-base": "14.2.1", | ||
@@ -34,6 +34,6 @@ "eslint-plugin-import": "2.22.1", | ||
"eslint-plugin-mocha": "8.0.0", | ||
"js-gardener": "2.0.181", | ||
"js-gardener": "2.0.182", | ||
"lodash.get": "4.4.2", | ||
"nyc": "15.1.0", | ||
"semantic-release": "17.3.0" | ||
"semantic-release": "17.3.1" | ||
}, | ||
@@ -40,0 +40,0 @@ "scripts": { |
@@ -69,8 +69,16 @@ # object-rewrite | ||
All plugins require: | ||
All plugins define: | ||
- `target` _String_: target field relative to the plugin path. | ||
- `required` _Array_: required fields relative to the plugin path. Can specify relative to root by prefixing with `/`.Will influence `fieldsToRequest`. | ||
- `fn` _Function_: result of this function is used by the plugin. Signature is `fn({ key, value, parents, context })`. | ||
- `fn` _Function_: result of this function is used by the plugin. Signature is `fn({ key, value, parents, context, cache })`. | ||
- `init({ context, cache })` _Function_ (optional): if present called once per run, if returns other than `true`, the plugin is disabled for the run | ||
where: | ||
- `key`: is the key for the processed entity | ||
- `value` is the value of the processed entity | ||
- `parents` are the parents of the processed entity | ||
- `context` is global as passed into the execution | ||
- `cache = {}` is locally defined per plugin | ||
### Inject Plugin | ||
@@ -77,0 +85,0 @@ |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
22540
17
382
176
1
+ Addedjoi-strict@1.2.9(transitive)
+ Addedobject-fields@2.0.19(transitive)
+ Addedobject-scan@13.7.1(transitive)
- Removedjoi-strict@1.2.6(transitive)
- Removedobject-fields@2.0.17(transitive)
- Removedobject-scan@13.6.6(transitive)
Updatedjoi-strict@1.2.9
Updatedobject-fields@2.0.19
Updatedobject-scan@13.7.1