Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@rimbu/deep

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rimbu/deep - npm Package Compare versions

Comparing version 0.12.1 to 0.13.0

143

dist/main/match.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.match = void 0;
var tslib_1 = require("tslib");
var base_1 = require("@rimbu/base");

@@ -11,3 +12,3 @@ /**

* @param matcher - a matcher object or a function taking the matcher API and returning a match object
* @param errorCollector - (optional) a string array that can be passed to collect reasons why the match failed
* @param failureLog - (optional) a string array that can be passed to collect reasons why the match failed
* @example

@@ -25,5 +26,4 @@ * ```ts

*/
function match(source, matcher, errorCollector) {
if (errorCollector === void 0) { errorCollector = undefined; }
return matchEntry(source, source, source, matcher, errorCollector);
function match(source, matcher, failureLog) {
return matchEntry(source, source, source, matcher, failureLog);
}

@@ -34,3 +34,3 @@ exports.match = match;

*/
function matchEntry(source, parent, root, matcher, errorCollector) {
function matchEntry(source, parent, root, matcher, failureLog) {
if (Object.is(source, matcher)) {

@@ -43,3 +43,3 @@ // value and target are exactly the same, always will be true

// they are not equal
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("value ".concat(JSON.stringify(source), " did not match matcher ").concat(matcher));
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("value ".concat(JSON.stringify(source), " did not match matcher ").concat(matcher));
return false;

@@ -51,3 +51,3 @@ }

if (!result) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("both value and matcher are functions, but they do not have the same reference");
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("both value and matcher are functions, but they do not have the same reference");
}

@@ -62,3 +62,3 @@ return result;

if (!matcherResult) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("function matcher returned false for value ".concat(JSON.stringify(source)));
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("function matcher returned false for value ".concat(JSON.stringify(source)));
}

@@ -68,14 +68,14 @@ return matcherResult;

// function resulted in a value that needs to be further matched
return matchEntry(source, parent, root, matcherResult, errorCollector);
return matchEntry(source, parent, root, matcherResult, failureLog);
}
if ((0, base_1.isPlainObj)(source)) {
// source ia a plain object, can be partially matched
return matchPlainObj(source, parent, root, matcher, errorCollector);
return matchPlainObj(source, parent, root, matcher, failureLog);
}
if (Array.isArray(source)) {
// source is an array
return matchArr(source, root, matcher, errorCollector);
return matchArr(source, parent, root, matcher, failureLog);
}
// already determined above that the source and matcher are not equal
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("value ".concat(JSON.stringify(source), " does not match given matcher ").concat(JSON.stringify(matcher)));
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("value ".concat(JSON.stringify(source), " does not match given matcher ").concat(JSON.stringify(matcher)));
return false;

@@ -86,3 +86,3 @@ }

*/
function matchArr(source, root, matcher, errorCollector) {
function matchArr(source, parent, root, matcher, failureLog) {
if (Array.isArray(matcher)) {

@@ -93,3 +93,3 @@ // directly compare array contents

// if lengths not equal, arrays are not equal
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("array lengths are not equal: value length ".concat(source.length, " !== matcher length ").concat(matcher.length));
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("array lengths are not equal: value length ".concat(source.length, " !== matcher length ").concat(matcher.length));
return false;

@@ -100,5 +100,5 @@ }

while (++index < length_1) {
if (!Object.is(source[index], matcher[index])) {
if (!matchEntry(source[index], source, root, matcher[index], failureLog)) {
// item did not match, return false
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("index ".concat(index, " does not match with value ").concat(JSON.stringify(source[index]), " and matcher ").concat(matcher[index]));
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("index ".concat(index, " does not match with value ").concat(JSON.stringify(source[index]), " and matcher ").concat(matcher[index]));
return false;

@@ -110,2 +110,27 @@ }

}
// matcher is plain object
if ("every" in matcher) {
return matchCompound(source, parent, root, tslib_1.__spreadArray(['every'], tslib_1.__read(matcher.every), false), failureLog);
}
if ("some" in matcher) {
return matchCompound(source, parent, root, tslib_1.__spreadArray(['some'], tslib_1.__read(matcher.some), false), failureLog);
}
if ("none" in matcher) {
return matchCompound(source, parent, root, tslib_1.__spreadArray(['none'], tslib_1.__read(matcher.none), false), failureLog);
}
if ("single" in matcher) {
return matchCompound(source, parent, root, tslib_1.__spreadArray(['single'], tslib_1.__read(matcher.single), false), failureLog);
}
if ("someItem" in matcher) {
return matchTraversal(source, root, 'someItem', matcher.someItem, failureLog);
}
if ("everyItem" in matcher) {
return matchTraversal(source, root, 'everyItem', matcher.everyItem, failureLog);
}
if ("noneItem" in matcher) {
return matchTraversal(source, root, 'noneItem', matcher.noneItem, failureLog);
}
if ("singleItem" in matcher) {
return matchTraversal(source, root, 'singleItem', matcher.singleItem, failureLog);
}
// matcher is plain object with index keys

@@ -116,10 +141,10 @@ for (var index in matcher) {

// source does not have item at given index
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("index ".concat(index, " does not exist in source ").concat(JSON.stringify(source), " but should match matcher ").concat(JSON.stringify(matcherAtIndex)));
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("index ".concat(index, " does not exist in source ").concat(JSON.stringify(source), " but should match matcher ").concat(JSON.stringify(matcherAtIndex)));
return false;
}
// match the source item at the given index
var result = matchEntry(source[index], source, root, matcherAtIndex, errorCollector);
var result = matchEntry(source[index], source, root, matcherAtIndex, failureLog);
if (!result) {
// item did not match
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("index ".concat(index, " does not match with value ").concat(JSON.stringify(source[index]), " and matcher ").concat(JSON.stringify(matcherAtIndex)));
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("index ".concat(index, " does not match with value ").concat(JSON.stringify(source[index]), " and matcher ").concat(JSON.stringify(matcherAtIndex)));
return false;

@@ -134,6 +159,6 @@ }

*/
function matchPlainObj(source, parent, root, matcher, errorCollector) {
function matchPlainObj(source, parent, root, matcher, failureLog) {
if (Array.isArray(matcher)) {
// the matcher is of compound type
return matchCompound(source, parent, root, matcher, errorCollector);
return matchCompound(source, parent, root, matcher, failureLog);
}

@@ -144,9 +169,9 @@ // partial object props matcher

// the source does not have the given key
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("key ".concat(key, " is specified in matcher but not present in value ").concat(JSON.stringify(source)));
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("key ".concat(key, " is specified in matcher but not present in value ").concat(JSON.stringify(source)));
return false;
}
// match the source value at the given key with the matcher at given key
var result = matchEntry(source[key], source, root, matcher[key], errorCollector);
var result = matchEntry(source[key], source, root, matcher[key], failureLog);
if (!result) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("key ".concat(key, " does not match in value ").concat(JSON.stringify(source[key]), " with matcher ").concat(JSON.stringify(matcher[key])));
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("key ".concat(key, " does not match in value ").concat(JSON.stringify(source[key]), " with matcher ").concat(JSON.stringify(matcher[key])));
return false;

@@ -161,3 +186,3 @@ }

*/
function matchCompound(source, parent, root, compound, errorCollector) {
function matchCompound(source, parent, root, compound, failureLog) {
// first item indicates compound match type

@@ -172,5 +197,5 @@ var matchType = compound[0];

// if any item does not match, return false
var result = matchEntry(source, parent, root, compound[index], errorCollector);
var result = matchEntry(source, parent, root, compound[index], failureLog);
if (!result) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("in compound \"every\": match at index ".concat(index, " failed"));
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("in compound \"every\": match at index ".concat(index, " failed"));
return false;

@@ -184,5 +209,5 @@ }

while (++index < length) {
var result = matchEntry(source, parent, root, compound[index], errorCollector);
var result = matchEntry(source, parent, root, compound[index], failureLog);
if (result) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("in compound \"none\": match at index ".concat(index, " succeeded"));
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("in compound \"none\": match at index ".concat(index, " succeeded"));
return false;

@@ -197,6 +222,6 @@ }

while (++index < length) {
var result = matchEntry(source, parent, root, compound[index], errorCollector);
var result = matchEntry(source, parent, root, compound[index], failureLog);
if (result) {
if (onePassed) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("in compound \"single\": multiple matches succeeded");
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("in compound \"single\": multiple matches succeeded");
return false;

@@ -208,3 +233,3 @@ }

if (!onePassed) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("in compound \"single\": no matches succeeded");
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("in compound \"single\": no matches succeeded");
}

@@ -216,3 +241,3 @@ return onePassed;

while (++index < length) {
var result = matchEntry(source, parent, root, compound[index], errorCollector);
var result = matchEntry(source, parent, root, compound[index], failureLog);
if (result) {

@@ -222,3 +247,3 @@ return true;

}
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push("in compound \"some\": no matches succeeded");
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("in compound \"some\": no matches succeeded");
return false;

@@ -228,2 +253,52 @@ }

}
function matchTraversal(source, root, matchType, matcher, failureLog) {
var index = -1;
var length = source.length;
switch (matchType) {
case 'someItem': {
while (++index < length) {
if (matchEntry(source[index], source, root, matcher, failureLog)) {
return true;
}
}
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("in array traversal \"someItem\": no items matched given matcher");
return false;
}
case 'everyItem': {
while (++index < length) {
if (!matchEntry(source[index], source, root, matcher, failureLog)) {
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("in array traversal \"everyItem\": at least one item did not match given matcher");
return false;
}
}
return true;
}
case 'noneItem': {
while (++index < length) {
if (matchEntry(source[index], source, root, matcher, failureLog)) {
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("in array traversal \"noneItem\": at least one item matched given matcher");
return false;
}
}
return true;
}
case 'singleItem': {
var singleMatched = false;
while (++index < length) {
if (matchEntry(source[index], source, root, matcher, failureLog)) {
if (singleMatched) {
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("in array traversal \"singleItem\": more than one item matched given matcher");
return false;
}
singleMatched = true;
}
}
if (!singleMatched) {
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push("in array traversal \"singleItem\": no item matched given matcher");
return false;
}
return true;
}
}
}
//# sourceMappingURL=match.js.map

@@ -8,3 +8,3 @@ import { isPlainObj, } from '@rimbu/base';

* @param matcher - a matcher object or a function taking the matcher API and returning a match object
* @param errorCollector - (optional) a string array that can be passed to collect reasons why the match failed
* @param failureLog - (optional) a string array that can be passed to collect reasons why the match failed
* @example

@@ -22,4 +22,4 @@ * ```ts

*/
export function match(source, matcher, errorCollector = undefined) {
return matchEntry(source, source, source, matcher, errorCollector);
export function match(source, matcher, failureLog) {
return matchEntry(source, source, source, matcher, failureLog);
}

@@ -29,3 +29,3 @@ /**

*/
function matchEntry(source, parent, root, matcher, errorCollector) {
function matchEntry(source, parent, root, matcher, failureLog) {
if (Object.is(source, matcher)) {

@@ -38,3 +38,3 @@ // value and target are exactly the same, always will be true

// they are not equal
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`value ${JSON.stringify(source)} did not match matcher ${matcher}`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`value ${JSON.stringify(source)} did not match matcher ${matcher}`);
return false;

@@ -46,3 +46,3 @@ }

if (!result) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`both value and matcher are functions, but they do not have the same reference`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`both value and matcher are functions, but they do not have the same reference`);
}

@@ -57,3 +57,3 @@ return result;

if (!matcherResult) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`function matcher returned false for value ${JSON.stringify(source)}`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`function matcher returned false for value ${JSON.stringify(source)}`);
}

@@ -63,14 +63,14 @@ return matcherResult;

// function resulted in a value that needs to be further matched
return matchEntry(source, parent, root, matcherResult, errorCollector);
return matchEntry(source, parent, root, matcherResult, failureLog);
}
if (isPlainObj(source)) {
// source ia a plain object, can be partially matched
return matchPlainObj(source, parent, root, matcher, errorCollector);
return matchPlainObj(source, parent, root, matcher, failureLog);
}
if (Array.isArray(source)) {
// source is an array
return matchArr(source, root, matcher, errorCollector);
return matchArr(source, parent, root, matcher, failureLog);
}
// already determined above that the source and matcher are not equal
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`value ${JSON.stringify(source)} does not match given matcher ${JSON.stringify(matcher)}`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`value ${JSON.stringify(source)} does not match given matcher ${JSON.stringify(matcher)}`);
return false;

@@ -81,3 +81,3 @@ }

*/
function matchArr(source, root, matcher, errorCollector) {
function matchArr(source, parent, root, matcher, failureLog) {
if (Array.isArray(matcher)) {

@@ -88,3 +88,3 @@ // directly compare array contents

// if lengths not equal, arrays are not equal
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`array lengths are not equal: value length ${source.length} !== matcher length ${matcher.length}`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`array lengths are not equal: value length ${source.length} !== matcher length ${matcher.length}`);
return false;

@@ -95,5 +95,5 @@ }

while (++index < length) {
if (!Object.is(source[index], matcher[index])) {
if (!matchEntry(source[index], source, root, matcher[index], failureLog)) {
// item did not match, return false
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`index ${index} does not match with value ${JSON.stringify(source[index])} and matcher ${matcher[index]}`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`index ${index} does not match with value ${JSON.stringify(source[index])} and matcher ${matcher[index]}`);
return false;

@@ -105,2 +105,27 @@ }

}
// matcher is plain object
if (`every` in matcher) {
return matchCompound(source, parent, root, ['every', ...matcher.every], failureLog);
}
if (`some` in matcher) {
return matchCompound(source, parent, root, ['some', ...matcher.some], failureLog);
}
if (`none` in matcher) {
return matchCompound(source, parent, root, ['none', ...matcher.none], failureLog);
}
if (`single` in matcher) {
return matchCompound(source, parent, root, ['single', ...matcher.single], failureLog);
}
if (`someItem` in matcher) {
return matchTraversal(source, root, 'someItem', matcher.someItem, failureLog);
}
if (`everyItem` in matcher) {
return matchTraversal(source, root, 'everyItem', matcher.everyItem, failureLog);
}
if (`noneItem` in matcher) {
return matchTraversal(source, root, 'noneItem', matcher.noneItem, failureLog);
}
if (`singleItem` in matcher) {
return matchTraversal(source, root, 'singleItem', matcher.singleItem, failureLog);
}
// matcher is plain object with index keys

@@ -111,10 +136,10 @@ for (const index in matcher) {

// source does not have item at given index
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`index ${index} does not exist in source ${JSON.stringify(source)} but should match matcher ${JSON.stringify(matcherAtIndex)}`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`index ${index} does not exist in source ${JSON.stringify(source)} but should match matcher ${JSON.stringify(matcherAtIndex)}`);
return false;
}
// match the source item at the given index
const result = matchEntry(source[index], source, root, matcherAtIndex, errorCollector);
const result = matchEntry(source[index], source, root, matcherAtIndex, failureLog);
if (!result) {
// item did not match
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`index ${index} does not match with value ${JSON.stringify(source[index])} and matcher ${JSON.stringify(matcherAtIndex)}`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`index ${index} does not match with value ${JSON.stringify(source[index])} and matcher ${JSON.stringify(matcherAtIndex)}`);
return false;

@@ -129,6 +154,6 @@ }

*/
function matchPlainObj(source, parent, root, matcher, errorCollector) {
function matchPlainObj(source, parent, root, matcher, failureLog) {
if (Array.isArray(matcher)) {
// the matcher is of compound type
return matchCompound(source, parent, root, matcher, errorCollector);
return matchCompound(source, parent, root, matcher, failureLog);
}

@@ -139,9 +164,9 @@ // partial object props matcher

// the source does not have the given key
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`key ${key} is specified in matcher but not present in value ${JSON.stringify(source)}`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`key ${key} is specified in matcher but not present in value ${JSON.stringify(source)}`);
return false;
}
// match the source value at the given key with the matcher at given key
const result = matchEntry(source[key], source, root, matcher[key], errorCollector);
const result = matchEntry(source[key], source, root, matcher[key], failureLog);
if (!result) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`key ${key} does not match in value ${JSON.stringify(source[key])} with matcher ${JSON.stringify(matcher[key])}`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`key ${key} does not match in value ${JSON.stringify(source[key])} with matcher ${JSON.stringify(matcher[key])}`);
return false;

@@ -156,3 +181,3 @@ }

*/
function matchCompound(source, parent, root, compound, errorCollector) {
function matchCompound(source, parent, root, compound, failureLog) {
// first item indicates compound match type

@@ -167,5 +192,5 @@ const matchType = compound[0];

// if any item does not match, return false
const result = matchEntry(source, parent, root, compound[index], errorCollector);
const result = matchEntry(source, parent, root, compound[index], failureLog);
if (!result) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`in compound "every": match at index ${index} failed`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`in compound "every": match at index ${index} failed`);
return false;

@@ -179,5 +204,5 @@ }

while (++index < length) {
const result = matchEntry(source, parent, root, compound[index], errorCollector);
const result = matchEntry(source, parent, root, compound[index], failureLog);
if (result) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`in compound "none": match at index ${index} succeeded`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`in compound "none": match at index ${index} succeeded`);
return false;

@@ -192,6 +217,6 @@ }

while (++index < length) {
const result = matchEntry(source, parent, root, compound[index], errorCollector);
const result = matchEntry(source, parent, root, compound[index], failureLog);
if (result) {
if (onePassed) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`in compound "single": multiple matches succeeded`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`in compound "single": multiple matches succeeded`);
return false;

@@ -203,3 +228,3 @@ }

if (!onePassed) {
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`in compound "single": no matches succeeded`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`in compound "single": no matches succeeded`);
}

@@ -211,3 +236,3 @@ return onePassed;

while (++index < length) {
const result = matchEntry(source, parent, root, compound[index], errorCollector);
const result = matchEntry(source, parent, root, compound[index], failureLog);
if (result) {

@@ -217,3 +242,3 @@ return true;

}
errorCollector === null || errorCollector === void 0 ? void 0 : errorCollector.push(`in compound "some": no matches succeeded`);
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`in compound "some": no matches succeeded`);
return false;

@@ -223,2 +248,52 @@ }

}
function matchTraversal(source, root, matchType, matcher, failureLog) {
let index = -1;
const length = source.length;
switch (matchType) {
case 'someItem': {
while (++index < length) {
if (matchEntry(source[index], source, root, matcher, failureLog)) {
return true;
}
}
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`in array traversal "someItem": no items matched given matcher`);
return false;
}
case 'everyItem': {
while (++index < length) {
if (!matchEntry(source[index], source, root, matcher, failureLog)) {
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`in array traversal "everyItem": at least one item did not match given matcher`);
return false;
}
}
return true;
}
case 'noneItem': {
while (++index < length) {
if (matchEntry(source[index], source, root, matcher, failureLog)) {
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`in array traversal "noneItem": at least one item matched given matcher`);
return false;
}
}
return true;
}
case 'singleItem': {
let singleMatched = false;
while (++index < length) {
if (matchEntry(source[index], source, root, matcher, failureLog)) {
if (singleMatched) {
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`in array traversal "singleItem": more than one item matched given matcher`);
return false;
}
singleMatched = true;
}
}
if (!singleMatched) {
failureLog === null || failureLog === void 0 ? void 0 : failureLog.push(`in array traversal "singleItem": no item matched given matcher`);
return false;
}
return true;
}
}
}
//# sourceMappingURL=match.js.map

@@ -15,7 +15,6 @@ import { IsAnyFunc, IsArray, IsPlainObj, NotIterable } from '@rimbu/base';

* @typeparam C - utility type
* @typeparam P - the parant type
* @typeparam P - the parent type
* @typeparam R - the root object type
*/
type Entry<T, C, P, R> = IsAnyFunc<T> extends true ? T : IsPlainObj<T> extends true ? Match.WithResult<T, P, R, Match.Obj<T, C, P, R>> : IsArray<T> extends true ? // determine allowed match values for array or tuple
Match.Arr<T, C, P, R> | Match.Func<T, P, R, Match.Arr<T, C, P, R>> : Match.WithResult<T, P, R, {
type Entry<T, C, P, R> = IsAnyFunc<T> extends true ? T : IsPlainObj<T> extends true ? Match.WithResult<T, P, R, Match.Obj<T, C, P, R>> : IsArray<T> extends true ? Match.Arr<T, C, P, R> | Match.Entry<T[number & keyof T], C[number & keyof C], P, R>[] | Match.Func<T, P, R, Match.Arr<T, C, P, R> | Match.Entry<T[number & keyof T], C[number & keyof C], P, R>[]> : Match.WithResult<T, P, R, {
[K in keyof C]: C[K & keyof T];

@@ -27,3 +26,3 @@ }>;

* @typeparam C - utility type
* @typeparam P - the parant type
* @typeparam P - the parent type
* @typeparam R - the root object type

@@ -45,8 +44,16 @@ */

* @typeparam C - utility type
* @typeparam P - the parant type
* @typeparam P - the parent type
* @typeparam R - the root object type
*/
type Arr<T, C, P, R> = C | Match.CompoundForArr<T, C, P, R> | (Match.TupIndices<T, C, R> & {
[K in Match.CompoundType]?: never;
type Arr<T, C, P, R> = C | Match.CompoundForArr<T, C, P, R> | Match.TraversalForArr<T, C, R> | (Match.TupIndices<T, C, R> & {
[K in Match.CompoundType | Match.ArrayTraversalType]?: never;
});
/**
* A type that either directly results in result type `S` or is a function taking the value, parent, and root values, and
* returns a value of type `S`.
* @typeparam T - the input value type
* @typeparam P - the parent type
* @typeparam R - the root object type
* @typeparam S - the result type
*/
type WithResult<T, P, R, S> = S | Match.Func<T, P, R, S>;

@@ -56,3 +63,3 @@ /**

* @typeparam T - the input value type
* @typeparam P - the parant type
* @typeparam P - the parent type
* @typeparam R - the root object type

@@ -76,2 +83,6 @@ * @typeparam S - the allowed return value type

/**
* Keys used to indicate an array match traversal.
*/
type ArrayTraversalType = `${CompoundType}Item`;
/**
* Compount matcher for objects, can only be an array staring with a compound type keyword.

@@ -95,10 +106,21 @@ * @typeparam T - the input value type

type CompoundForArr<T, C, P, R> = {
[K in CompoundType]: {
[K2 in CompoundType]?: K2 extends K ? Match.Entry<T, C, P, R>[] : never;
[K in Match.CompoundType]: {
[K2 in Match.CompoundType]?: K2 extends K ? Match.Entry<T, C, P, R>[] : never;
};
}[CompoundType];
}[Match.CompoundType];
/**
* Utility type for collecting errors
* Defines an object containing exactly one `TraversalType` key, having a matcher for the array element type.
* @typeparam T - the input value type
* @typeparam C - utility type
* @typeparam R - the root object type
*/
type ErrorCollector = string[] | undefined;
type TraversalForArr<T, C, R> = {
[K in Match.ArrayTraversalType]: {
[K2 in Match.ArrayTraversalType]?: K2 extends K ? Match.Entry<T[number & keyof T], C[number & keyof C], T, R> : never;
};
}[Match.ArrayTraversalType];
/**
* Utility type for collecting match failure reasons
*/
type FailureLog = string[];
}

@@ -111,3 +133,3 @@ /**

* @param matcher - a matcher object or a function taking the matcher API and returning a match object
* @param errorCollector - (optional) a string array that can be passed to collect reasons why the match failed
* @param failureLog - (optional) a string array that can be passed to collect reasons why the match failed
* @example

@@ -125,2 +147,2 @@ * ```ts

*/
export declare function match<T, C extends Partial<T> = Partial<T>>(source: T, matcher: Match<T, C>, errorCollector?: Match.ErrorCollector): boolean;
export declare function match<T, C extends Partial<T> = Partial<T>>(source: T, matcher: Match<T, C>, failureLog?: Match.FailureLog): boolean;
{
"name": "@rimbu/deep",
"version": "0.12.1",
"version": "0.13.0",
"description": "Tools to use handle plain JS objects as immutable objects",

@@ -71,3 +71,3 @@ "keywords": [

},
"gitHead": "ef217d1ea7a8287bec3b4755fdb9d717318e1941"
"gitHead": "92420ee29abdd7241014c9a5a10210c127f314d0"
}

@@ -28,3 +28,3 @@ import {

* @typeparam C - utility type
* @typeparam P - the parant type
* @typeparam P - the parent type
* @typeparam R - the root object type

@@ -40,3 +40,11 @@ */

? // determine allowed match values for array or tuple
Match.Arr<T, C, P, R> | Match.Func<T, P, R, Match.Arr<T, C, P, R>>
| Match.Arr<T, C, P, R>
| Match.Entry<T[number & keyof T], C[number & keyof C], P, R>[]
| Match.Func<
T,
P,
R,
| Match.Arr<T, C, P, R>
| Match.Entry<T[number & keyof T], C[number & keyof C], P, R>[]
>
: // only accept values with same interface

@@ -49,3 +57,3 @@ Match.WithResult<T, P, R, { [K in keyof C]: C[K & keyof T] }>;

* @typeparam C - utility type
* @typeparam P - the parant type
* @typeparam P - the parent type
* @typeparam R - the root object type

@@ -71,3 +79,3 @@ */

* @typeparam C - utility type
* @typeparam P - the parant type
* @typeparam P - the parent type
* @typeparam R - the root object type

@@ -78,4 +86,15 @@ */

| Match.CompoundForArr<T, C, P, R>
| (Match.TupIndices<T, C, R> & { [K in Match.CompoundType]?: never });
| Match.TraversalForArr<T, C, R>
| (Match.TupIndices<T, C, R> & {
[K in Match.CompoundType | Match.ArrayTraversalType]?: never;
});
/**
* A type that either directly results in result type `S` or is a function taking the value, parent, and root values, and
* returns a value of type `S`.
* @typeparam T - the input value type
* @typeparam P - the parent type
* @typeparam R - the root object type
* @typeparam S - the result type
*/
export type WithResult<T, P, R, S> = S | Match.Func<T, P, R, S>;

@@ -86,3 +105,3 @@

* @typeparam T - the input value type
* @typeparam P - the parant type
* @typeparam P - the parent type
* @typeparam R - the root object type

@@ -113,2 +132,7 @@ * @typeparam S - the allowed return value type

/**
* Keys used to indicate an array match traversal.
*/
export type ArrayTraversalType = `${CompoundType}Item`;
/**
* Compount matcher for objects, can only be an array staring with a compound type keyword.

@@ -133,11 +157,27 @@ * @typeparam T - the input value type

export type CompoundForArr<T, C, P, R> = {
[K in CompoundType]: {
[K2 in CompoundType]?: K2 extends K ? Match.Entry<T, C, P, R>[] : never;
[K in Match.CompoundType]: {
[K2 in Match.CompoundType]?: K2 extends K
? Match.Entry<T, C, P, R>[]
: never;
};
}[CompoundType];
}[Match.CompoundType];
/**
* Utility type for collecting errors
* Defines an object containing exactly one `TraversalType` key, having a matcher for the array element type.
* @typeparam T - the input value type
* @typeparam C - utility type
* @typeparam R - the root object type
*/
export type ErrorCollector = string[] | undefined;
export type TraversalForArr<T, C, R> = {
[K in Match.ArrayTraversalType]: {
[K2 in Match.ArrayTraversalType]?: K2 extends K
? Match.Entry<T[number & keyof T], C[number & keyof C], T, R>
: never;
};
}[Match.ArrayTraversalType];
/**
* Utility type for collecting match failure reasons
*/
export type FailureLog = string[];
}

@@ -151,3 +191,3 @@

* @param matcher - a matcher object or a function taking the matcher API and returning a match object
* @param errorCollector - (optional) a string array that can be passed to collect reasons why the match failed
* @param failureLog - (optional) a string array that can be passed to collect reasons why the match failed
* @example

@@ -168,5 +208,5 @@ * ```ts

matcher: Match<T, C>,
errorCollector: Match.ErrorCollector = undefined
failureLog?: Match.FailureLog
): boolean {
return matchEntry(source, source, source, matcher as any, errorCollector);
return matchEntry(source, source, source, matcher as any, failureLog);
}

@@ -182,3 +222,3 @@

matcher: Match.Entry<T, C, P, R>,
errorCollector: Match.ErrorCollector
failureLog?: Match.FailureLog
): boolean {

@@ -193,3 +233,3 @@ if (Object.is(source, matcher)) {

// they are not equal
errorCollector?.push(
failureLog?.push(
`value ${JSON.stringify(source)} did not match matcher ${matcher}`

@@ -206,3 +246,3 @@ );

if (!result) {
errorCollector?.push(
failureLog?.push(
`both value and matcher are functions, but they do not have the same reference`

@@ -223,3 +263,3 @@ );

if (!matcherResult) {
errorCollector?.push(
failureLog?.push(
`function matcher returned false for value ${JSON.stringify(source)}`

@@ -233,3 +273,3 @@ );

// function resulted in a value that needs to be further matched
return matchEntry(source, parent, root, matcherResult, errorCollector);
return matchEntry(source, parent, root, matcherResult, failureLog);
}

@@ -239,3 +279,3 @@

// source ia a plain object, can be partially matched
return matchPlainObj(source, parent, root, matcher as any, errorCollector);
return matchPlainObj(source, parent, root, matcher as any, failureLog);
}

@@ -245,3 +285,3 @@

// source is an array
return matchArr(source, root, matcher as any, errorCollector);
return matchArr(source, parent, root, matcher as any, failureLog);
}

@@ -251,3 +291,3 @@

errorCollector?.push(
failureLog?.push(
`value ${JSON.stringify(

@@ -266,5 +306,6 @@ source

source: T,
parent: P,
root: R,
matcher: Match.Arr<T, C, P, R>,
errorCollector: Match.ErrorCollector
failureLog?: Match.FailureLog
): boolean {

@@ -278,3 +319,3 @@ if (Array.isArray(matcher)) {

errorCollector?.push(
failureLog?.push(
`array lengths are not equal: value length ${source.length} !== matcher length ${matcher.length}`

@@ -289,6 +330,8 @@ );

while (++index < length) {
if (!Object.is(source[index], matcher[index])) {
if (
!matchEntry(source[index], source, root, matcher[index], failureLog)
) {
// item did not match, return false
errorCollector?.push(
failureLog?.push(
`index ${index} does not match with value ${JSON.stringify(

@@ -307,2 +350,77 @@ source[index]

// matcher is plain object
if (`every` in matcher) {
return matchCompound(
source,
parent,
root,
['every', ...(matcher.every as any)],
failureLog
);
}
if (`some` in matcher) {
return matchCompound(
source,
parent,
root,
['some', ...(matcher.some as any)],
failureLog
);
}
if (`none` in matcher) {
return matchCompound(
source,
parent,
root,
['none', ...(matcher.none as any)],
failureLog
);
}
if (`single` in matcher) {
return matchCompound(
source,
parent,
root,
['single', ...(matcher.single as any)],
failureLog
);
}
if (`someItem` in matcher) {
return matchTraversal(
source,
root,
'someItem',
matcher.someItem as any,
failureLog
);
}
if (`everyItem` in matcher) {
return matchTraversal(
source,
root,
'everyItem',
matcher.everyItem as any,
failureLog
);
}
if (`noneItem` in matcher) {
return matchTraversal(
source,
root,
'noneItem',
matcher.noneItem as any,
failureLog
);
}
if (`singleItem` in matcher) {
return matchTraversal(
source,
root,
'singleItem',
matcher.singleItem as any,
failureLog
);
}
// matcher is plain object with index keys

@@ -316,3 +434,3 @@

errorCollector?.push(
failureLog?.push(
`index ${index} does not exist in source ${JSON.stringify(

@@ -332,3 +450,3 @@ source

matcherAtIndex,
errorCollector
failureLog
);

@@ -339,3 +457,3 @@

errorCollector?.push(
failureLog?.push(
`index ${index} does not match with value ${JSON.stringify(

@@ -363,7 +481,7 @@ (source as any)[index]

matcher: Match.Obj<T, C, P, R>,
errorCollector: Match.ErrorCollector
failureLog?: Match.FailureLog
): boolean {
if (Array.isArray(matcher)) {
// the matcher is of compound type
return matchCompound(source, parent, root, matcher as any, errorCollector);
return matchCompound(source, parent, root, matcher as any, failureLog);
}

@@ -377,3 +495,3 @@

errorCollector?.push(
failureLog?.push(
`key ${key} is specified in matcher but not present in value ${JSON.stringify(

@@ -393,7 +511,7 @@ source

matcher[key],
errorCollector
failureLog
);
if (!result) {
errorCollector?.push(
failureLog?.push(
`key ${key} does not match in value ${JSON.stringify(

@@ -420,3 +538,3 @@ (source as any)[key]

compound: [Match.CompoundType, ...Match.Entry<T, C, P, R>[]],
errorCollector: string[] | undefined
failureLog?: Match.FailureLog
): boolean {

@@ -442,7 +560,7 @@ // first item indicates compound match type

compound[index] as Entry,
errorCollector
failureLog
);
if (!result) {
errorCollector?.push(
failureLog?.push(
`in compound "every": match at index ${index} failed`

@@ -465,7 +583,7 @@ );

compound[index] as Entry,
errorCollector
failureLog
);
if (result) {
errorCollector?.push(
failureLog?.push(
`in compound "none": match at index ${index} succeeded`

@@ -490,3 +608,3 @@ );

compound[index] as Entry,
errorCollector
failureLog
);

@@ -496,3 +614,3 @@

if (onePassed) {
errorCollector?.push(
failureLog?.push(
`in compound "single": multiple matches succeeded`

@@ -509,3 +627,3 @@ );

if (!onePassed) {
errorCollector?.push(`in compound "single": no matches succeeded`);
failureLog?.push(`in compound "single": no matches succeeded`);
}

@@ -523,3 +641,3 @@

compound[index] as Entry,
errorCollector
failureLog
);

@@ -532,3 +650,3 @@

errorCollector?.push(`in compound "some": no matches succeeded`);
failureLog?.push(`in compound "some": no matches succeeded`);

@@ -539,1 +657,79 @@ return false;

}
function matchTraversal<T extends any[], C extends any[], R>(
source: T,
root: R,
matchType: Match.ArrayTraversalType,
matcher: Match.Entry<T[keyof T], C[keyof C], T, R>,
failureLog?: Match.FailureLog
): boolean {
let index = -1;
const length = source.length;
switch (matchType) {
case 'someItem': {
while (++index < length) {
if (matchEntry(source[index], source, root, matcher, failureLog)) {
return true;
}
}
failureLog?.push(
`in array traversal "someItem": no items matched given matcher`
);
return false;
}
case 'everyItem': {
while (++index < length) {
if (!matchEntry(source[index], source, root, matcher, failureLog)) {
failureLog?.push(
`in array traversal "everyItem": at least one item did not match given matcher`
);
return false;
}
}
return true;
}
case 'noneItem': {
while (++index < length) {
if (matchEntry(source[index], source, root, matcher, failureLog)) {
failureLog?.push(
`in array traversal "noneItem": at least one item matched given matcher`
);
return false;
}
}
return true;
}
case 'singleItem': {
let singleMatched = false;
while (++index < length) {
if (matchEntry(source[index], source, root, matcher, failureLog)) {
if (singleMatched) {
failureLog?.push(
`in array traversal "singleItem": more than one item matched given matcher`
);
return false;
}
singleMatched = true;
}
}
if (!singleMatched) {
failureLog?.push(
`in array traversal "singleItem": no item matched given matcher`
);
return false;
}
return true;
}
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc