@swaggerexpert/jsonpath 3.2.4 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +225 -18
- package/cjs/errors/JSONNormalizedPathError.cjs +8 -0
- package/cjs/errors/JSONPathError.cjs +1 -1
- package/cjs/errors/{JSONPathCompileError.cjs → JSONPathEvaluateError.cjs} +2 -2
- package/cjs/evaluate/evaluators/comparable.cjs +44 -0
- package/cjs/evaluate/evaluators/comparison-expr.cjs +37 -0
- package/cjs/evaluate/evaluators/filter-query.cjs +182 -0
- package/cjs/evaluate/evaluators/function-expr.cjs +106 -0
- package/cjs/evaluate/evaluators/literal.cjs +25 -0
- package/cjs/evaluate/evaluators/logical-expr.cjs +96 -0
- package/cjs/evaluate/evaluators/singular-query.cjs +103 -0
- package/cjs/evaluate/functions/count.cjs +35 -0
- package/cjs/evaluate/functions/index.cjs +15 -0
- package/cjs/evaluate/functions/length.cjs +42 -0
- package/cjs/evaluate/functions/match.cjs +49 -0
- package/cjs/evaluate/functions/search.cjs +49 -0
- package/cjs/evaluate/functions/value.cjs +36 -0
- package/cjs/evaluate/index.cjs +182 -0
- package/cjs/evaluate/realms/EvaluationRealm.cjs +154 -0
- package/cjs/evaluate/realms/json/index.cjs +246 -0
- package/cjs/evaluate/utils/guards.cjs +129 -0
- package/cjs/evaluate/utils/i-regexp.cjs +118 -0
- package/cjs/evaluate/visitors/bracketed-selection.cjs +35 -0
- package/cjs/evaluate/visitors/filter-selector.cjs +43 -0
- package/cjs/evaluate/visitors/index-selector.cjs +55 -0
- package/cjs/evaluate/visitors/name-selector.cjs +38 -0
- package/cjs/evaluate/visitors/segment.cjs +99 -0
- package/cjs/evaluate/visitors/selector.cjs +47 -0
- package/cjs/evaluate/visitors/slice-selector.cjs +115 -0
- package/cjs/evaluate/visitors/wildcard-selector.cjs +32 -0
- package/cjs/index.cjs +16 -7
- package/cjs/normalized-path.cjs +145 -0
- package/cjs/parse/callbacks/cst.cjs +2 -4
- package/cjs/parse/index.cjs +3 -1
- package/cjs/parse/translators/ASTTranslator/index.cjs +1 -1
- package/cjs/parse/translators/ASTTranslator/transformers.cjs +246 -5
- package/cjs/parse/translators/CSTOptimizedTranslator.cjs +1 -3
- package/cjs/parse/translators/CSTTranslator.cjs +1 -2
- package/cjs/test/index.cjs +4 -2
- package/es/errors/JSONNormalizedPathError.mjs +3 -0
- package/es/errors/JSONPathError.mjs +1 -1
- package/es/errors/JSONPathEvaluateError.mjs +3 -0
- package/es/evaluate/evaluators/comparable.mjs +38 -0
- package/es/evaluate/evaluators/comparison-expr.mjs +31 -0
- package/es/evaluate/evaluators/filter-query.mjs +175 -0
- package/es/evaluate/evaluators/function-expr.mjs +99 -0
- package/es/evaluate/evaluators/literal.mjs +21 -0
- package/es/evaluate/evaluators/logical-expr.mjs +89 -0
- package/es/evaluate/evaluators/singular-query.mjs +97 -0
- package/es/evaluate/functions/count.mjs +30 -0
- package/es/evaluate/functions/index.mjs +13 -0
- package/es/evaluate/functions/length.mjs +37 -0
- package/es/evaluate/functions/match.mjs +44 -0
- package/es/evaluate/functions/search.mjs +44 -0
- package/es/evaluate/functions/value.mjs +31 -0
- package/es/evaluate/index.mjs +174 -0
- package/es/evaluate/realms/EvaluationRealm.mjs +148 -0
- package/es/evaluate/realms/json/index.mjs +240 -0
- package/es/evaluate/utils/guards.mjs +114 -0
- package/es/evaluate/utils/i-regexp.mjs +113 -0
- package/es/evaluate/visitors/bracketed-selection.mjs +29 -0
- package/es/evaluate/visitors/filter-selector.mjs +37 -0
- package/es/evaluate/visitors/index-selector.mjs +51 -0
- package/es/evaluate/visitors/name-selector.mjs +34 -0
- package/es/evaluate/visitors/segment.mjs +91 -0
- package/es/evaluate/visitors/selector.mjs +41 -0
- package/es/evaluate/visitors/slice-selector.mjs +111 -0
- package/es/evaluate/visitors/wildcard-selector.mjs +28 -0
- package/es/index.mjs +7 -3
- package/es/normalized-path.mjs +136 -0
- package/es/parse/callbacks/cst.mjs +2 -4
- package/es/parse/index.mjs +3 -1
- package/es/parse/translators/ASTTranslator/index.mjs +1 -1
- package/es/parse/translators/ASTTranslator/transformers.mjs +246 -5
- package/es/parse/translators/CSTOptimizedTranslator.mjs +1 -3
- package/es/parse/translators/CSTTranslator.mjs +1 -2
- package/es/test/index.mjs +4 -2
- package/package.json +4 -2
- package/types/index.d.ts +135 -8
- package/cjs/compile.cjs +0 -50
- package/cjs/escape.cjs +0 -59
- package/es/compile.mjs +0 -45
- package/es/errors/JSONPathCompileError.mjs +0 -3
- package/es/escape.mjs +0 -55
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.setLogicalExprEvaluator = exports.default = void 0;
|
|
5
|
+
var _comparable = _interopRequireDefault(require("./comparable.cjs"));
|
|
6
|
+
var _filterQuery = _interopRequireDefault(require("./filter-query.cjs"));
|
|
7
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
/**
|
|
9
|
+
* Function expression evaluator.
|
|
10
|
+
*
|
|
11
|
+
* Evaluates function calls like length(@.items), match(@.name, "pattern"), etc.
|
|
12
|
+
*
|
|
13
|
+
* @see https://www.rfc-editor.org/rfc/rfc9535#section-2.4
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Evaluate a function argument.
|
|
18
|
+
* Arguments can be:
|
|
19
|
+
* - Literals
|
|
20
|
+
* - Singular queries (@.path, $.path)
|
|
21
|
+
* - Filter queries (for NodesType parameters)
|
|
22
|
+
* - Function expressions (nested calls)
|
|
23
|
+
* - Logical expressions (for LogicalType parameters)
|
|
24
|
+
*
|
|
25
|
+
* Special case: When a TestExpr contains only a FilterQuery,
|
|
26
|
+
* we evaluate it as a nodelist (for functions like count() that expect NodesType).
|
|
27
|
+
*
|
|
28
|
+
* @param {object} ctx - Evaluation context
|
|
29
|
+
* @param {unknown} root - Root value ($)
|
|
30
|
+
* @param {unknown} current - Current value (@)
|
|
31
|
+
* @param {object} arg - Argument AST node
|
|
32
|
+
* @returns {unknown} - Evaluated argument value
|
|
33
|
+
*/
|
|
34
|
+
const evaluateArgument = (ctx, root, current, arg) => {
|
|
35
|
+
switch (arg.type) {
|
|
36
|
+
case 'Literal':
|
|
37
|
+
case 'RelSingularQuery':
|
|
38
|
+
case 'AbsSingularQuery':
|
|
39
|
+
case 'FunctionExpr':
|
|
40
|
+
return (0, _comparable.default)(ctx, root, current, arg);
|
|
41
|
+
case 'FilterQuery':
|
|
42
|
+
// FilterQuery produces a nodelist (array of values)
|
|
43
|
+
return (0, _filterQuery.default)(ctx, root, current, arg);
|
|
44
|
+
case 'TestExpr':
|
|
45
|
+
// TestExpr can contain FilterQuery (for NodesType/ValueType) or FunctionExpr
|
|
46
|
+
if (arg.expression.type === 'FilterQuery') {
|
|
47
|
+
// Always return the nodelist - functions handle type coercion internally
|
|
48
|
+
// Per RFC 9535 Section 2.4.1: if a function expects ValueType and gets NodesType,
|
|
49
|
+
// it auto-converts (single node -> value, otherwise -> Nothing)
|
|
50
|
+
return (0, _filterQuery.default)(ctx, root, current, arg.expression);
|
|
51
|
+
}
|
|
52
|
+
if (arg.expression.type === 'FunctionExpr') {
|
|
53
|
+
// FunctionExpr as argument - evaluate the nested function
|
|
54
|
+
return (0, _comparable.default)(ctx, root, current, arg.expression);
|
|
55
|
+
}
|
|
56
|
+
// Otherwise evaluate as logical expression
|
|
57
|
+
// eslint-disable-next-line no-use-before-define
|
|
58
|
+
return evaluateLogicalExpr(ctx, root, current, arg);
|
|
59
|
+
case 'LogicalOrExpr':
|
|
60
|
+
case 'LogicalAndExpr':
|
|
61
|
+
case 'LogicalNotExpr':
|
|
62
|
+
case 'ComparisonExpr':
|
|
63
|
+
// Import dynamically to avoid circular dependency
|
|
64
|
+
// eslint-disable-next-line no-use-before-define
|
|
65
|
+
return evaluateLogicalExpr(ctx, root, current, arg);
|
|
66
|
+
default:
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// Lazy import to avoid circular dependency
|
|
72
|
+
let evaluateLogicalExpr;
|
|
73
|
+
const setLogicalExprEvaluator = fn => {
|
|
74
|
+
evaluateLogicalExpr = fn;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Evaluate a function expression.
|
|
79
|
+
*
|
|
80
|
+
* @param {object} ctx - Evaluation context
|
|
81
|
+
* @param {unknown} root - Root value ($)
|
|
82
|
+
* @param {unknown} current - Current value (@)
|
|
83
|
+
* @param {object} node - AST node
|
|
84
|
+
* @param {string} node.name - Function name
|
|
85
|
+
* @param {object[]} node.arguments - Array of argument AST nodes
|
|
86
|
+
* @returns {unknown} - Function result
|
|
87
|
+
*/
|
|
88
|
+
exports.setLogicalExprEvaluator = setLogicalExprEvaluator;
|
|
89
|
+
const evaluateFunctionExpr = (ctx, root, current, node) => {
|
|
90
|
+
const {
|
|
91
|
+
name,
|
|
92
|
+
arguments: args
|
|
93
|
+
} = node;
|
|
94
|
+
const fn = ctx.functions[name];
|
|
95
|
+
if (typeof fn !== 'function') {
|
|
96
|
+
// Unknown function returns Nothing
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Evaluate all arguments
|
|
101
|
+
const evaluatedArgs = args.map(arg => evaluateArgument(ctx, root, current, arg));
|
|
102
|
+
|
|
103
|
+
// Call the function with realm and evaluated arguments
|
|
104
|
+
return fn(ctx.realm, ...evaluatedArgs);
|
|
105
|
+
};
|
|
106
|
+
var _default = exports.default = evaluateFunctionExpr;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
/**
|
|
6
|
+
* Literal evaluator.
|
|
7
|
+
*
|
|
8
|
+
* Evaluates a literal value (string, number, boolean, null).
|
|
9
|
+
* Literals appear in comparisons and function arguments.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Evaluate a literal AST node.
|
|
14
|
+
*
|
|
15
|
+
* @param {object} ctx - Evaluation context (unused for literals)
|
|
16
|
+
* @param {unknown} root - Root value (unused for literals)
|
|
17
|
+
* @param {unknown} current - Current value (unused for literals)
|
|
18
|
+
* @param {object} node - AST node
|
|
19
|
+
* @param {unknown} node.value - The literal value
|
|
20
|
+
* @returns {unknown} - The literal value
|
|
21
|
+
*/
|
|
22
|
+
const evaluateLiteral = (ctx, root, current, node) => {
|
|
23
|
+
return node.value;
|
|
24
|
+
};
|
|
25
|
+
var _default = exports.default = evaluateLiteral;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _comparisonExpr = _interopRequireDefault(require("./comparison-expr.cjs"));
|
|
6
|
+
var _functionExpr = _interopRequireWildcard(require("./function-expr.cjs"));
|
|
7
|
+
var _filterQuery = _interopRequireDefault(require("./filter-query.cjs"));
|
|
8
|
+
var _guards = require("../utils/guards.cjs");
|
|
9
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
/**
|
|
12
|
+
* Logical expression evaluator.
|
|
13
|
+
*
|
|
14
|
+
* Evaluates logical expressions:
|
|
15
|
+
* - LogicalOrExpr (||)
|
|
16
|
+
* - LogicalAndExpr (&&)
|
|
17
|
+
* - LogicalNotExpr (!)
|
|
18
|
+
* - TestExpr (existence test or function result)
|
|
19
|
+
* - ComparisonExpr (routed to comparison evaluator)
|
|
20
|
+
*
|
|
21
|
+
* @see https://www.rfc-editor.org/rfc/rfc9535#section-2.3.5.2
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Evaluate a logical expression.
|
|
26
|
+
*
|
|
27
|
+
* @param {object} ctx - Evaluation context
|
|
28
|
+
* @param {unknown} root - Root value ($)
|
|
29
|
+
* @param {unknown} current - Current value (@)
|
|
30
|
+
* @param {object} node - Logical expression AST node
|
|
31
|
+
* @returns {boolean} - Logical result
|
|
32
|
+
*/
|
|
33
|
+
const evaluateLogicalExpr = (ctx, root, current, node) => {
|
|
34
|
+
switch (node.type) {
|
|
35
|
+
case 'LogicalOrExpr':
|
|
36
|
+
{
|
|
37
|
+
// Short-circuit OR
|
|
38
|
+
const left = evaluateLogicalExpr(ctx, root, current, node.left);
|
|
39
|
+
if (left) return true;
|
|
40
|
+
return evaluateLogicalExpr(ctx, root, current, node.right);
|
|
41
|
+
}
|
|
42
|
+
case 'LogicalAndExpr':
|
|
43
|
+
{
|
|
44
|
+
// Short-circuit AND
|
|
45
|
+
const left = evaluateLogicalExpr(ctx, root, current, node.left);
|
|
46
|
+
if (!left) return false;
|
|
47
|
+
return evaluateLogicalExpr(ctx, root, current, node.right);
|
|
48
|
+
}
|
|
49
|
+
case 'LogicalNotExpr':
|
|
50
|
+
{
|
|
51
|
+
return !evaluateLogicalExpr(ctx, root, current, node.expression);
|
|
52
|
+
}
|
|
53
|
+
case 'TestExpr':
|
|
54
|
+
{
|
|
55
|
+
// TestExpr wraps a FilterQuery or FunctionExpr
|
|
56
|
+
const {
|
|
57
|
+
expression
|
|
58
|
+
} = node;
|
|
59
|
+
if (expression.type === 'FilterQuery') {
|
|
60
|
+
// Existence test: true if nodelist is non-empty
|
|
61
|
+
const nodelist = (0, _filterQuery.default)(ctx, root, current, expression);
|
|
62
|
+
return nodelist.length > 0;
|
|
63
|
+
}
|
|
64
|
+
if (expression.type === 'FunctionExpr') {
|
|
65
|
+
// Function result converted to boolean
|
|
66
|
+
const result = (0, _functionExpr.default)(ctx, root, current, expression);
|
|
67
|
+
// LogicalType functions return boolean directly
|
|
68
|
+
// ValueType functions: undefined (Nothing) is false, truthy values are true
|
|
69
|
+
if (typeof result === 'boolean') {
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
// Nothing is false
|
|
73
|
+
if (result === undefined) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
// NodesType (array): non-empty is true
|
|
77
|
+
if ((0, _guards.isArray)(result)) {
|
|
78
|
+
return result.length > 0;
|
|
79
|
+
}
|
|
80
|
+
// Other ValueType: truthy check
|
|
81
|
+
return Boolean(result);
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
case 'ComparisonExpr':
|
|
86
|
+
{
|
|
87
|
+
return (0, _comparisonExpr.default)(ctx, root, current, node);
|
|
88
|
+
}
|
|
89
|
+
default:
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Register with function-expr to break circular dependency
|
|
95
|
+
(0, _functionExpr.setLogicalExprEvaluator)(evaluateLogicalExpr);
|
|
96
|
+
var _default = exports.default = evaluateLogicalExpr;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.evaluateRelSingularQuery = exports.evaluateAbsSingularQuery = void 0;
|
|
5
|
+
/**
|
|
6
|
+
* Singular query evaluator.
|
|
7
|
+
*
|
|
8
|
+
* Evaluates RelSingularQuery (@.path) and AbsSingularQuery ($.path) expressions.
|
|
9
|
+
* These appear in comparison expressions within filters.
|
|
10
|
+
*
|
|
11
|
+
* A singular query can only contain name selectors and index selectors,
|
|
12
|
+
* ensuring it produces at most one value.
|
|
13
|
+
*
|
|
14
|
+
* @see https://www.rfc-editor.org/rfc/rfc9535#section-2.3.5.2.2
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Apply a singular query segment (name or index selector).
|
|
19
|
+
*
|
|
20
|
+
* @param {object} ctx - Evaluation context
|
|
21
|
+
* @param {unknown} value - Current value
|
|
22
|
+
* @param {object} segment - Segment AST node
|
|
23
|
+
* @returns {unknown} - Selected value or undefined (Nothing)
|
|
24
|
+
*/
|
|
25
|
+
const applySingularSegment = (ctx, value, segment) => {
|
|
26
|
+
const {
|
|
27
|
+
realm
|
|
28
|
+
} = ctx;
|
|
29
|
+
const {
|
|
30
|
+
selector
|
|
31
|
+
} = segment;
|
|
32
|
+
switch (selector.type) {
|
|
33
|
+
case 'NameSelector':
|
|
34
|
+
{
|
|
35
|
+
const {
|
|
36
|
+
value: name
|
|
37
|
+
} = selector;
|
|
38
|
+
if (realm.isObject(value) && realm.hasProperty(value, name)) {
|
|
39
|
+
return realm.getProperty(value, name);
|
|
40
|
+
}
|
|
41
|
+
return undefined; // Nothing
|
|
42
|
+
}
|
|
43
|
+
case 'IndexSelector':
|
|
44
|
+
{
|
|
45
|
+
const {
|
|
46
|
+
value: index
|
|
47
|
+
} = selector;
|
|
48
|
+
if (!realm.isArray(value)) return undefined;
|
|
49
|
+
const length = realm.getLength(value);
|
|
50
|
+
const normalizedIndex = index >= 0 ? index : length + index;
|
|
51
|
+
if (normalizedIndex >= 0 && normalizedIndex < length) {
|
|
52
|
+
return realm.getElement(value, normalizedIndex);
|
|
53
|
+
}
|
|
54
|
+
return undefined; // Nothing
|
|
55
|
+
}
|
|
56
|
+
default:
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Evaluate a RelSingularQuery (@.path).
|
|
63
|
+
*
|
|
64
|
+
* @param {object} ctx - Evaluation context
|
|
65
|
+
* @param {unknown} root - Root value (unused)
|
|
66
|
+
* @param {unknown} current - Current value (@)
|
|
67
|
+
* @param {object} node - AST node
|
|
68
|
+
* @param {object[]} node.segments - Array of singular query segments
|
|
69
|
+
* @returns {unknown} - Result value or undefined (Nothing)
|
|
70
|
+
*/
|
|
71
|
+
const evaluateRelSingularQuery = (ctx, root, current, node) => {
|
|
72
|
+
let value = current;
|
|
73
|
+
for (const segment of node.segments) {
|
|
74
|
+
value = applySingularSegment(ctx, value, segment);
|
|
75
|
+
if (value === undefined) {
|
|
76
|
+
return undefined; // Nothing - short circuit
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return value;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Evaluate an AbsSingularQuery ($.path).
|
|
84
|
+
*
|
|
85
|
+
* @param {object} ctx - Evaluation context
|
|
86
|
+
* @param {unknown} root - Root value ($)
|
|
87
|
+
* @param {unknown} current - Current value (unused)
|
|
88
|
+
* @param {object} node - AST node
|
|
89
|
+
* @param {object[]} node.segments - Array of singular query segments
|
|
90
|
+
* @returns {unknown} - Result value or undefined (Nothing)
|
|
91
|
+
*/
|
|
92
|
+
exports.evaluateRelSingularQuery = evaluateRelSingularQuery;
|
|
93
|
+
const evaluateAbsSingularQuery = (ctx, root, current, node) => {
|
|
94
|
+
let value = root;
|
|
95
|
+
for (const segment of node.segments) {
|
|
96
|
+
value = applySingularSegment(ctx, value, segment);
|
|
97
|
+
if (value === undefined) {
|
|
98
|
+
return undefined; // Nothing - short circuit
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return value;
|
|
102
|
+
};
|
|
103
|
+
exports.evaluateAbsSingularQuery = evaluateAbsSingularQuery;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _guards = require("../utils/guards.cjs");
|
|
6
|
+
/**
|
|
7
|
+
* RFC 9535 count() function.
|
|
8
|
+
*
|
|
9
|
+
* @see https://www.rfc-editor.org/rfc/rfc9535#section-2.4.4
|
|
10
|
+
*
|
|
11
|
+
* Parameters:
|
|
12
|
+
* NodesType (nodelist)
|
|
13
|
+
*
|
|
14
|
+
* Returns:
|
|
15
|
+
* ValueType (number)
|
|
16
|
+
*
|
|
17
|
+
* Result:
|
|
18
|
+
* The number of nodes in the nodelist.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Count the number of nodes in a nodelist.
|
|
23
|
+
*
|
|
24
|
+
* @param {object} realm - Evaluation realm (unused, for consistent signature)
|
|
25
|
+
* @param {unknown} nodelist - A nodelist (array of values)
|
|
26
|
+
* @returns {number} - Number of nodes
|
|
27
|
+
*/
|
|
28
|
+
const count = (realm, nodelist) => {
|
|
29
|
+
if ((0, _guards.isNodelist)(nodelist)) {
|
|
30
|
+
return nodelist.length;
|
|
31
|
+
}
|
|
32
|
+
// Not a nodelist (NodesType): return Nothing per RFC 9535
|
|
33
|
+
return undefined;
|
|
34
|
+
};
|
|
35
|
+
var _default = exports.default = count;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.value = exports.search = exports.match = exports.length = exports.count = void 0;
|
|
5
|
+
var _length = _interopRequireDefault(require("./length.cjs"));
|
|
6
|
+
exports.length = _length.default;
|
|
7
|
+
var _count = _interopRequireDefault(require("./count.cjs"));
|
|
8
|
+
exports.count = _count.default;
|
|
9
|
+
var _value = _interopRequireDefault(require("./value.cjs"));
|
|
10
|
+
exports.value = _value.default;
|
|
11
|
+
var _match = _interopRequireDefault(require("./match.cjs"));
|
|
12
|
+
exports.match = _match.default;
|
|
13
|
+
var _search = _interopRequireDefault(require("./search.cjs"));
|
|
14
|
+
exports.search = _search.default;
|
|
15
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _guards = require("../utils/guards.cjs");
|
|
6
|
+
/**
|
|
7
|
+
* RFC 9535 length() function.
|
|
8
|
+
*
|
|
9
|
+
* @see https://www.rfc-editor.org/rfc/rfc9535#section-2.4.5
|
|
10
|
+
*
|
|
11
|
+
* Parameters:
|
|
12
|
+
* ValueType (single value)
|
|
13
|
+
*
|
|
14
|
+
* Returns:
|
|
15
|
+
* ValueType (number or Nothing)
|
|
16
|
+
*
|
|
17
|
+
* Result:
|
|
18
|
+
* - String: number of Unicode scalar values (not UTF-16 code units)
|
|
19
|
+
* - Array: number of elements
|
|
20
|
+
* - Object: number of members (key-value pairs)
|
|
21
|
+
* - Other: Nothing (undefined)
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get the length of a value.
|
|
26
|
+
*
|
|
27
|
+
* @param {object} realm - Evaluation realm
|
|
28
|
+
* @param {unknown} value - The value to measure (may be a nodelist)
|
|
29
|
+
* @returns {number | undefined} - Length or Nothing (undefined)
|
|
30
|
+
*/
|
|
31
|
+
const length = (realm, value) => {
|
|
32
|
+
// Coerce nodelist to single value if needed
|
|
33
|
+
const coerced = (0, _guards.coerceToValueType)(value);
|
|
34
|
+
|
|
35
|
+
// Nothing returns Nothing
|
|
36
|
+
if ((0, _guards.isNothing)(coerced)) return undefined;
|
|
37
|
+
|
|
38
|
+
// Use realm to get length (handles strings, arrays, objects)
|
|
39
|
+
const len = realm.getLength(coerced);
|
|
40
|
+
return len > 0 || realm.isString(coerced) || realm.isArray(coerced) || realm.isObject(coerced) ? len : undefined;
|
|
41
|
+
};
|
|
42
|
+
var _default = exports.default = length;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _guards = require("../utils/guards.cjs");
|
|
6
|
+
var _iRegexp = require("../utils/i-regexp.cjs");
|
|
7
|
+
/**
|
|
8
|
+
* RFC 9535 match() function.
|
|
9
|
+
*
|
|
10
|
+
* @see https://www.rfc-editor.org/rfc/rfc9535#section-2.4.1
|
|
11
|
+
*
|
|
12
|
+
* Parameters:
|
|
13
|
+
* ValueType (string), ValueType (I-Regexp pattern string)
|
|
14
|
+
*
|
|
15
|
+
* Returns:
|
|
16
|
+
* LogicalType (boolean)
|
|
17
|
+
*
|
|
18
|
+
* Result:
|
|
19
|
+
* true if the entire string matches the I-Regexp pattern, false otherwise.
|
|
20
|
+
* The pattern is implicitly anchored (^(?:pattern)$).
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Test if entire string matches I-Regexp pattern.
|
|
25
|
+
*
|
|
26
|
+
* @param {object} realm - Evaluation realm
|
|
27
|
+
* @param {unknown} value - The string to test (may be a nodelist)
|
|
28
|
+
* @param {unknown} pattern - The I-Regexp pattern (may be a nodelist)
|
|
29
|
+
* @returns {boolean} - true if entire string matches
|
|
30
|
+
*/
|
|
31
|
+
const match = (realm, value, pattern) => {
|
|
32
|
+
// Coerce nodelists to single values
|
|
33
|
+
const coercedValue = (0, _guards.coerceToValueType)(value);
|
|
34
|
+
const coercedPattern = (0, _guards.coerceToValueType)(pattern);
|
|
35
|
+
|
|
36
|
+
// Get raw string values from realm
|
|
37
|
+
const strValue = realm.getString(coercedValue);
|
|
38
|
+
const strPattern = realm.getString(coercedPattern);
|
|
39
|
+
if (strValue === undefined || strPattern === undefined) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const regex = (0, _iRegexp.constructRegex)(strPattern, true); // anchored
|
|
43
|
+
if (regex === null) {
|
|
44
|
+
// Invalid I-Regexp pattern
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return regex.test(strValue);
|
|
48
|
+
};
|
|
49
|
+
var _default = exports.default = match;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _guards = require("../utils/guards.cjs");
|
|
6
|
+
var _iRegexp = require("../utils/i-regexp.cjs");
|
|
7
|
+
/**
|
|
8
|
+
* RFC 9535 search() function.
|
|
9
|
+
*
|
|
10
|
+
* @see https://www.rfc-editor.org/rfc/rfc9535#section-2.4.2
|
|
11
|
+
*
|
|
12
|
+
* Parameters:
|
|
13
|
+
* ValueType (string), ValueType (I-Regexp pattern string)
|
|
14
|
+
*
|
|
15
|
+
* Returns:
|
|
16
|
+
* LogicalType (boolean)
|
|
17
|
+
*
|
|
18
|
+
* Result:
|
|
19
|
+
* true if any substring matches the I-Regexp pattern, false otherwise.
|
|
20
|
+
* The pattern is not anchored (can match anywhere in string).
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Test if any substring matches I-Regexp pattern.
|
|
25
|
+
*
|
|
26
|
+
* @param {object} realm - Evaluation realm
|
|
27
|
+
* @param {unknown} value - The string to search (may be a nodelist)
|
|
28
|
+
* @param {unknown} pattern - The I-Regexp pattern (may be a nodelist)
|
|
29
|
+
* @returns {boolean} - true if any substring matches
|
|
30
|
+
*/
|
|
31
|
+
const search = (realm, value, pattern) => {
|
|
32
|
+
// Coerce nodelists to single values
|
|
33
|
+
const coercedValue = (0, _guards.coerceToValueType)(value);
|
|
34
|
+
const coercedPattern = (0, _guards.coerceToValueType)(pattern);
|
|
35
|
+
|
|
36
|
+
// Get raw string values from realm
|
|
37
|
+
const strValue = realm.getString(coercedValue);
|
|
38
|
+
const strPattern = realm.getString(coercedPattern);
|
|
39
|
+
if (strValue === undefined || strPattern === undefined) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const regex = (0, _iRegexp.constructRegex)(strPattern, false); // not anchored
|
|
43
|
+
if (regex === null) {
|
|
44
|
+
// Invalid I-Regexp pattern
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return regex.test(strValue);
|
|
48
|
+
};
|
|
49
|
+
var _default = exports.default = search;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _guards = require("../utils/guards.cjs");
|
|
6
|
+
/**
|
|
7
|
+
* RFC 9535 value() function.
|
|
8
|
+
*
|
|
9
|
+
* @see https://www.rfc-editor.org/rfc/rfc9535#section-2.4.7
|
|
10
|
+
*
|
|
11
|
+
* Parameters:
|
|
12
|
+
* NodesType (nodelist)
|
|
13
|
+
*
|
|
14
|
+
* Returns:
|
|
15
|
+
* ValueType (the single value or Nothing)
|
|
16
|
+
*
|
|
17
|
+
* Result:
|
|
18
|
+
* - If nodelist has exactly one node: that node's value
|
|
19
|
+
* - Otherwise: Nothing (undefined)
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Extract the single value from a nodelist.
|
|
24
|
+
*
|
|
25
|
+
* @param {object} realm - Evaluation realm (unused, for consistent signature)
|
|
26
|
+
* @param {unknown} nodelist - A nodelist (array of values)
|
|
27
|
+
* @returns {unknown} - The single value or Nothing (undefined)
|
|
28
|
+
*/
|
|
29
|
+
const value = (realm, nodelist) => {
|
|
30
|
+
if ((0, _guards.isNodelist)(nodelist) && nodelist.length === 1) {
|
|
31
|
+
return nodelist[0];
|
|
32
|
+
}
|
|
33
|
+
// Nothing for empty nodelist, multiple values, or non-nodelist
|
|
34
|
+
return undefined;
|
|
35
|
+
};
|
|
36
|
+
var _default = exports.default = value;
|