@coldsmirk/abacus-core 0.10.0 → 0.11.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/dist/index.cjs +13 -7
- package/dist/index.d.cts +40 -2
- package/dist/index.d.ts +40 -2
- package/dist/index.js +11 -8
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -361,7 +361,7 @@ function isZenConsistentNumber(value) {
|
|
|
361
361
|
const SUBJECT_PATTERN = /^[A-Z_$][\w$]*(?:\.[A-Z_$][\w$]*|\[\d+\])*$/i;
|
|
362
362
|
const SUBJECT_IDENTIFIER_PATTERN = /[A-Z_$][\w$]*/gi;
|
|
363
363
|
const SUBJECT_INDEX_PATTERN = /\[(?<index>\d+)\]/g;
|
|
364
|
-
const
|
|
364
|
+
const ZEN_RESERVED_WORDS = new Set([
|
|
365
365
|
"and",
|
|
366
366
|
"or",
|
|
367
367
|
"not",
|
|
@@ -371,10 +371,13 @@ const ZEN_ROOT_RESERVED_WORDS = new Set([
|
|
|
371
371
|
"null"
|
|
372
372
|
]);
|
|
373
373
|
const ZEN_MEMBER_RESERVED_WORDS = new Set(["true", "false"]);
|
|
374
|
+
function isZenReservedWord(word) {
|
|
375
|
+
return ZEN_RESERVED_WORDS.has(word);
|
|
376
|
+
}
|
|
374
377
|
function isIdentifierPath(subject) {
|
|
375
378
|
if (!SUBJECT_PATTERN.test(subject)) return false;
|
|
376
379
|
const [root, ...members] = subject.match(SUBJECT_IDENTIFIER_PATTERN) ?? [];
|
|
377
|
-
if (root === void 0 ||
|
|
380
|
+
if (root === void 0 || isZenReservedWord(root) || members.some((member) => ZEN_MEMBER_RESERVED_WORDS.has(member))) return false;
|
|
378
381
|
for (const match of subject.matchAll(SUBJECT_INDEX_PATTERN)) if (match.groups?.index === void 0 || !isZenUnsignedIntegerText(match.groups.index)) return false;
|
|
379
382
|
return true;
|
|
380
383
|
}
|
|
@@ -640,14 +643,14 @@ function compileRule(rule) {
|
|
|
640
643
|
function matchesOperatorArity(rule) {
|
|
641
644
|
switch (conditionOperatorArity(rule.operator)) {
|
|
642
645
|
case "scalar": return isConditionScalar(rule.right);
|
|
643
|
-
case "array": return
|
|
646
|
+
case "array": return isConditionScalarArray(rule.right);
|
|
644
647
|
case "none": return rule.right === void 0;
|
|
645
648
|
}
|
|
646
649
|
}
|
|
647
650
|
function isConditionScalar(value) {
|
|
648
651
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
649
652
|
}
|
|
650
|
-
function
|
|
653
|
+
function isConditionScalarArray(value) {
|
|
651
654
|
return isArray(value) && value.every((item) => isConditionScalar(item));
|
|
652
655
|
}
|
|
653
656
|
const TWO_CHAR_PUNCTUATION = new Set([
|
|
@@ -672,7 +675,7 @@ const IDENT_PART = /[\w$]/;
|
|
|
672
675
|
const DIGIT = /\d/;
|
|
673
676
|
const NUMBER_PATTERN = /^\d+(?:\.\d+)?(?:e[+-]?\d+)?/i;
|
|
674
677
|
const INTEGER_PATTERN = /^\d+$/;
|
|
675
|
-
function
|
|
678
|
+
function parseCanonicalZenNumber(text) {
|
|
676
679
|
const value = Number(text);
|
|
677
680
|
return String(value) === text && isZenRepresentableNumber(value) ? value : null;
|
|
678
681
|
}
|
|
@@ -734,7 +737,7 @@ function liftConditionTree(expression) {
|
|
|
734
737
|
return token.value;
|
|
735
738
|
}
|
|
736
739
|
if (token.kind === "number") {
|
|
737
|
-
const value =
|
|
740
|
+
const value = parseCanonicalZenNumber(token.value);
|
|
738
741
|
if (value === null) return null;
|
|
739
742
|
pos += 1;
|
|
740
743
|
return value;
|
|
@@ -753,7 +756,7 @@ function liftConditionTree(expression) {
|
|
|
753
756
|
if (token.kind === "punct" && token.value === "-") {
|
|
754
757
|
const digits = peek(1);
|
|
755
758
|
if (digits === void 0 || digits.kind !== "number") return null;
|
|
756
|
-
const value =
|
|
759
|
+
const value = parseCanonicalZenNumber(digits.value);
|
|
757
760
|
if (value === null || value === 0 || !isZenRepresentableNumber(-value)) return null;
|
|
758
761
|
pos += 2;
|
|
759
762
|
return -value;
|
|
@@ -1367,11 +1370,14 @@ exports.getEngineSync = getEngineSync;
|
|
|
1367
1370
|
exports.getExpressionMessages = getExpressionMessages;
|
|
1368
1371
|
exports.getTemplateDiagnostics = getTemplateDiagnostics;
|
|
1369
1372
|
exports.getTemplateDiagnosticsSync = getTemplateDiagnosticsSync;
|
|
1373
|
+
exports.isConditionScalarArray = isConditionScalarArray;
|
|
1370
1374
|
exports.isEngineReady = isEngineReady;
|
|
1371
1375
|
exports.isZenRepresentableNumber = isZenRepresentableNumber;
|
|
1376
|
+
exports.isZenReservedWord = isZenReservedWord;
|
|
1372
1377
|
exports.liftConditionTree = liftConditionTree;
|
|
1373
1378
|
exports.loadEngine = loadEngine;
|
|
1374
1379
|
exports.newConditionNodeId = newConditionNodeId;
|
|
1380
|
+
exports.parseCanonicalZenNumber = parseCanonicalZenNumber;
|
|
1375
1381
|
exports.parseTemplateHoles = parseTemplateHoles;
|
|
1376
1382
|
exports.registerExpressionLocale = registerExpressionLocale;
|
|
1377
1383
|
exports.resetEngine = resetEngine;
|
package/dist/index.d.cts
CHANGED
|
@@ -541,15 +541,53 @@ declare function emptyConditionGroup(): ConditionTreeGroup;
|
|
|
541
541
|
* the tree is compilable (see the module note for the drop semantics).
|
|
542
542
|
*/
|
|
543
543
|
declare function compileConditionTree(tree: ConditionTreeGroup): string;
|
|
544
|
+
/**
|
|
545
|
+
* Whether a rule's `right` is an array of scalars — the membership-operand shape.
|
|
546
|
+
* Deliberately stricter than `Array.isArray`: every element must itself be a
|
|
547
|
+
* {@link ConditionScalar}, because a `null` slipping through the type as JSON data
|
|
548
|
+
* would make `toZenLiteral` serialize a `null` literal outside the canonical
|
|
549
|
+
* grammar rather than throw. Also the narrowing predicate for the
|
|
550
|
+
* scalar-or-array {@link ConditionTreeValue} union, which a bare `Array.isArray`
|
|
551
|
+
* narrows poorly over `readonly` arrays.
|
|
552
|
+
*/
|
|
553
|
+
declare function isConditionScalarArray(value: ConditionTreeValue | undefined): value is readonly ConditionScalar[];
|
|
554
|
+
/**
|
|
555
|
+
* Parse `text` as a **canonical** ZEN number — exactly what the condition compiler
|
|
556
|
+
* emits: the `String(n)` rendering of a ZEN-representable value
|
|
557
|
+
* ({@link isZenRepresentableNumber}). Anything else — extra precision float64
|
|
558
|
+
* cannot hold (`9007199254740993` would silently round to `…992`), a magnitude
|
|
559
|
+
* that collapses to Infinity (`1e999`), redundant digits (`1.50`), or a value
|
|
560
|
+
* outside ZEN's decimal domain — returns `null`. For this lifter those are shapes
|
|
561
|
+
* {@link compileConditionTree} can never produce (lifting one would silently
|
|
562
|
+
* rewrite the expression instead of returning `null` as the module contract
|
|
563
|
+
* requires); for a value editor they are inputs whose numeric meaning would
|
|
564
|
+
* change if committed as a number.
|
|
565
|
+
*/
|
|
566
|
+
declare function parseCanonicalZenNumber(text: string): number | null;
|
|
544
567
|
/**
|
|
545
568
|
* Lift a ZEN expression to a condition tree, or `null` when it is not in the
|
|
546
569
|
* canonical form {@link compileConditionTree} produces (the consumer then keeps the
|
|
547
570
|
* raw expression). Groups nested deeper than 64 parenthesized levels are refused as
|
|
548
571
|
* non-canonical rather than risking parser-stack overflow on adversarial input, and
|
|
549
|
-
* number literals must be canonical (see
|
|
572
|
+
* number literals must be canonical (see {@link parseCanonicalZenNumber}). The returned root
|
|
550
573
|
* is always a group, and every node carries a fresh {@link ConditionTreeRule.id}.
|
|
551
574
|
*/
|
|
552
575
|
declare function liftConditionTree(expression: string): ConditionTreeGroup | null;
|
|
576
|
+
/**
|
|
577
|
+
* Shared subject-path guard for the condition compilers. A subject / left-hand
|
|
578
|
+
* path is emitted **verbatim** into ZEN source, so both {@link compileCondition}
|
|
579
|
+
* (which writes that source) and {@link liftConditionTree} (which reads it back)
|
|
580
|
+
* gate paths through this one predicate — a single definition of "what is a safe
|
|
581
|
+
* field path" that cannot drift between the writer and the reader, which matters
|
|
582
|
+
* because the guard is also the compiler's injection defense.
|
|
583
|
+
*/
|
|
584
|
+
/**
|
|
585
|
+
* Whether `word` is one of ZEN's reserved words — the keywords the grammar
|
|
586
|
+
* claims as operators (`and`, `or`, `not`, `in`) or literals (`true`, `false`,
|
|
587
|
+
* `null`). A reserved word can never start an identifier path, and editor
|
|
588
|
+
* tooling treats one as not reachable through plain dot access.
|
|
589
|
+
*/
|
|
590
|
+
declare function isZenReservedWord(word: string): boolean;
|
|
553
591
|
/**
|
|
554
592
|
* Return `tree` with every node carrying a stable UI id. The shared structural
|
|
555
593
|
* policy is checked before recursive normalization, so invalid external data fails
|
|
@@ -743,4 +781,4 @@ declare function getTemplateDiagnosticsSync(source: string): ExpressionDiagnosti
|
|
|
743
781
|
* Async {@link getTemplateDiagnosticsSync}, loading the engine on first use.
|
|
744
782
|
*/
|
|
745
783
|
declare function getTemplateDiagnostics(source: string): Promise<ExpressionDiagnostic[]>;
|
|
746
|
-
export { type BranchSelection, type BuiltInExpressionLocale, CONDITION_OPERATORS, CONDITION_TREE_OPERATORS, type ConditionBranchInput, type ConditionGroupInput, type ConditionInput, type ConditionOperator, type ConditionOperatorArity, type ConditionScalar, type ConditionTreeGroup, type ConditionTreeNode, type ConditionTreeOperator, type ConditionTreeRule, type ConditionTreeValue, type ConfigureMessagesOptions, type ExpressionAnalysis, type ExpressionCompletion, type ExpressionConditionInput, type ExpressionContext, type ExpressionDiagnostic, type ExpressionEngine, ExpressionError, type ExpressionLocale, type ExpressionMessages, type ExpressionMessagesListener, type ExpressionMode, ExpressionNotReadyError, type ExpressionType, type ExpressionTypeSpan, type FieldConditionInput, type LoadEngineOptions, MAX_CONDITION_TREE_DEPTH, type TemplateHole, analyzeTemplate, analyzeTemplateSync, analyzeTypes, analyzeTypesSync, compileBranch, compileCondition, compileConditionTree, compileGroup, conditionOperatorArity, configureEngine, configureExpressionMessages, emptyConditionGroup, enMessages, ensureConditionNodeIds, evaluate, evaluateSync, evaluateUnary, evaluateUnarySync, getCompletionItems, getCompletionItemsSync, getDiagnostics, getDiagnosticsSync, getEngineError, getEngineSync, getExpressionMessages, getTemplateDiagnostics, getTemplateDiagnosticsSync, isEngineReady, isZenRepresentableNumber, liftConditionTree, loadEngine, newConditionNodeId, parseTemplateHoles, registerExpressionLocale, resetEngine, satisfiesType, satisfiesTypeSync, schemaTreeToExpressionType, selectBranch, selectBranchWith, subscribeExpressionMessages, templateHoleAt, toZenLiteral, zhCNMessages };
|
|
784
|
+
export { type BranchSelection, type BuiltInExpressionLocale, CONDITION_OPERATORS, CONDITION_TREE_OPERATORS, type ConditionBranchInput, type ConditionGroupInput, type ConditionInput, type ConditionOperator, type ConditionOperatorArity, type ConditionScalar, type ConditionTreeGroup, type ConditionTreeNode, type ConditionTreeOperator, type ConditionTreeRule, type ConditionTreeValue, type ConfigureMessagesOptions, type ExpressionAnalysis, type ExpressionCompletion, type ExpressionConditionInput, type ExpressionContext, type ExpressionDiagnostic, type ExpressionEngine, ExpressionError, type ExpressionLocale, type ExpressionMessages, type ExpressionMessagesListener, type ExpressionMode, ExpressionNotReadyError, type ExpressionType, type ExpressionTypeSpan, type FieldConditionInput, type LoadEngineOptions, MAX_CONDITION_TREE_DEPTH, type TemplateHole, analyzeTemplate, analyzeTemplateSync, analyzeTypes, analyzeTypesSync, compileBranch, compileCondition, compileConditionTree, compileGroup, conditionOperatorArity, configureEngine, configureExpressionMessages, emptyConditionGroup, enMessages, ensureConditionNodeIds, evaluate, evaluateSync, evaluateUnary, evaluateUnarySync, getCompletionItems, getCompletionItemsSync, getDiagnostics, getDiagnosticsSync, getEngineError, getEngineSync, getExpressionMessages, getTemplateDiagnostics, getTemplateDiagnosticsSync, isConditionScalarArray, isEngineReady, isZenRepresentableNumber, isZenReservedWord, liftConditionTree, loadEngine, newConditionNodeId, parseCanonicalZenNumber, parseTemplateHoles, registerExpressionLocale, resetEngine, satisfiesType, satisfiesTypeSync, schemaTreeToExpressionType, selectBranch, selectBranchWith, subscribeExpressionMessages, templateHoleAt, toZenLiteral, zhCNMessages };
|
package/dist/index.d.ts
CHANGED
|
@@ -541,15 +541,53 @@ declare function emptyConditionGroup(): ConditionTreeGroup;
|
|
|
541
541
|
* the tree is compilable (see the module note for the drop semantics).
|
|
542
542
|
*/
|
|
543
543
|
declare function compileConditionTree(tree: ConditionTreeGroup): string;
|
|
544
|
+
/**
|
|
545
|
+
* Whether a rule's `right` is an array of scalars — the membership-operand shape.
|
|
546
|
+
* Deliberately stricter than `Array.isArray`: every element must itself be a
|
|
547
|
+
* {@link ConditionScalar}, because a `null` slipping through the type as JSON data
|
|
548
|
+
* would make `toZenLiteral` serialize a `null` literal outside the canonical
|
|
549
|
+
* grammar rather than throw. Also the narrowing predicate for the
|
|
550
|
+
* scalar-or-array {@link ConditionTreeValue} union, which a bare `Array.isArray`
|
|
551
|
+
* narrows poorly over `readonly` arrays.
|
|
552
|
+
*/
|
|
553
|
+
declare function isConditionScalarArray(value: ConditionTreeValue | undefined): value is readonly ConditionScalar[];
|
|
554
|
+
/**
|
|
555
|
+
* Parse `text` as a **canonical** ZEN number — exactly what the condition compiler
|
|
556
|
+
* emits: the `String(n)` rendering of a ZEN-representable value
|
|
557
|
+
* ({@link isZenRepresentableNumber}). Anything else — extra precision float64
|
|
558
|
+
* cannot hold (`9007199254740993` would silently round to `…992`), a magnitude
|
|
559
|
+
* that collapses to Infinity (`1e999`), redundant digits (`1.50`), or a value
|
|
560
|
+
* outside ZEN's decimal domain — returns `null`. For this lifter those are shapes
|
|
561
|
+
* {@link compileConditionTree} can never produce (lifting one would silently
|
|
562
|
+
* rewrite the expression instead of returning `null` as the module contract
|
|
563
|
+
* requires); for a value editor they are inputs whose numeric meaning would
|
|
564
|
+
* change if committed as a number.
|
|
565
|
+
*/
|
|
566
|
+
declare function parseCanonicalZenNumber(text: string): number | null;
|
|
544
567
|
/**
|
|
545
568
|
* Lift a ZEN expression to a condition tree, or `null` when it is not in the
|
|
546
569
|
* canonical form {@link compileConditionTree} produces (the consumer then keeps the
|
|
547
570
|
* raw expression). Groups nested deeper than 64 parenthesized levels are refused as
|
|
548
571
|
* non-canonical rather than risking parser-stack overflow on adversarial input, and
|
|
549
|
-
* number literals must be canonical (see
|
|
572
|
+
* number literals must be canonical (see {@link parseCanonicalZenNumber}). The returned root
|
|
550
573
|
* is always a group, and every node carries a fresh {@link ConditionTreeRule.id}.
|
|
551
574
|
*/
|
|
552
575
|
declare function liftConditionTree(expression: string): ConditionTreeGroup | null;
|
|
576
|
+
/**
|
|
577
|
+
* Shared subject-path guard for the condition compilers. A subject / left-hand
|
|
578
|
+
* path is emitted **verbatim** into ZEN source, so both {@link compileCondition}
|
|
579
|
+
* (which writes that source) and {@link liftConditionTree} (which reads it back)
|
|
580
|
+
* gate paths through this one predicate — a single definition of "what is a safe
|
|
581
|
+
* field path" that cannot drift between the writer and the reader, which matters
|
|
582
|
+
* because the guard is also the compiler's injection defense.
|
|
583
|
+
*/
|
|
584
|
+
/**
|
|
585
|
+
* Whether `word` is one of ZEN's reserved words — the keywords the grammar
|
|
586
|
+
* claims as operators (`and`, `or`, `not`, `in`) or literals (`true`, `false`,
|
|
587
|
+
* `null`). A reserved word can never start an identifier path, and editor
|
|
588
|
+
* tooling treats one as not reachable through plain dot access.
|
|
589
|
+
*/
|
|
590
|
+
declare function isZenReservedWord(word: string): boolean;
|
|
553
591
|
/**
|
|
554
592
|
* Return `tree` with every node carrying a stable UI id. The shared structural
|
|
555
593
|
* policy is checked before recursive normalization, so invalid external data fails
|
|
@@ -743,4 +781,4 @@ declare function getTemplateDiagnosticsSync(source: string): ExpressionDiagnosti
|
|
|
743
781
|
* Async {@link getTemplateDiagnosticsSync}, loading the engine on first use.
|
|
744
782
|
*/
|
|
745
783
|
declare function getTemplateDiagnostics(source: string): Promise<ExpressionDiagnostic[]>;
|
|
746
|
-
export { type BranchSelection, type BuiltInExpressionLocale, CONDITION_OPERATORS, CONDITION_TREE_OPERATORS, type ConditionBranchInput, type ConditionGroupInput, type ConditionInput, type ConditionOperator, type ConditionOperatorArity, type ConditionScalar, type ConditionTreeGroup, type ConditionTreeNode, type ConditionTreeOperator, type ConditionTreeRule, type ConditionTreeValue, type ConfigureMessagesOptions, type ExpressionAnalysis, type ExpressionCompletion, type ExpressionConditionInput, type ExpressionContext, type ExpressionDiagnostic, type ExpressionEngine, ExpressionError, type ExpressionLocale, type ExpressionMessages, type ExpressionMessagesListener, type ExpressionMode, ExpressionNotReadyError, type ExpressionType, type ExpressionTypeSpan, type FieldConditionInput, type LoadEngineOptions, MAX_CONDITION_TREE_DEPTH, type TemplateHole, analyzeTemplate, analyzeTemplateSync, analyzeTypes, analyzeTypesSync, compileBranch, compileCondition, compileConditionTree, compileGroup, conditionOperatorArity, configureEngine, configureExpressionMessages, emptyConditionGroup, enMessages, ensureConditionNodeIds, evaluate, evaluateSync, evaluateUnary, evaluateUnarySync, getCompletionItems, getCompletionItemsSync, getDiagnostics, getDiagnosticsSync, getEngineError, getEngineSync, getExpressionMessages, getTemplateDiagnostics, getTemplateDiagnosticsSync, isEngineReady, isZenRepresentableNumber, liftConditionTree, loadEngine, newConditionNodeId, parseTemplateHoles, registerExpressionLocale, resetEngine, satisfiesType, satisfiesTypeSync, schemaTreeToExpressionType, selectBranch, selectBranchWith, subscribeExpressionMessages, templateHoleAt, toZenLiteral, zhCNMessages };
|
|
784
|
+
export { type BranchSelection, type BuiltInExpressionLocale, CONDITION_OPERATORS, CONDITION_TREE_OPERATORS, type ConditionBranchInput, type ConditionGroupInput, type ConditionInput, type ConditionOperator, type ConditionOperatorArity, type ConditionScalar, type ConditionTreeGroup, type ConditionTreeNode, type ConditionTreeOperator, type ConditionTreeRule, type ConditionTreeValue, type ConfigureMessagesOptions, type ExpressionAnalysis, type ExpressionCompletion, type ExpressionConditionInput, type ExpressionContext, type ExpressionDiagnostic, type ExpressionEngine, ExpressionError, type ExpressionLocale, type ExpressionMessages, type ExpressionMessagesListener, type ExpressionMode, ExpressionNotReadyError, type ExpressionType, type ExpressionTypeSpan, type FieldConditionInput, type LoadEngineOptions, MAX_CONDITION_TREE_DEPTH, type TemplateHole, analyzeTemplate, analyzeTemplateSync, analyzeTypes, analyzeTypesSync, compileBranch, compileCondition, compileConditionTree, compileGroup, conditionOperatorArity, configureEngine, configureExpressionMessages, emptyConditionGroup, enMessages, ensureConditionNodeIds, evaluate, evaluateSync, evaluateUnary, evaluateUnarySync, getCompletionItems, getCompletionItemsSync, getDiagnostics, getDiagnosticsSync, getEngineError, getEngineSync, getExpressionMessages, getTemplateDiagnostics, getTemplateDiagnosticsSync, isConditionScalarArray, isEngineReady, isZenRepresentableNumber, isZenReservedWord, liftConditionTree, loadEngine, newConditionNodeId, parseCanonicalZenNumber, parseTemplateHoles, registerExpressionLocale, resetEngine, satisfiesType, satisfiesTypeSync, schemaTreeToExpressionType, selectBranch, selectBranchWith, subscribeExpressionMessages, templateHoleAt, toZenLiteral, zhCNMessages };
|
package/dist/index.js
CHANGED
|
@@ -360,7 +360,7 @@ function isZenConsistentNumber(value) {
|
|
|
360
360
|
const SUBJECT_PATTERN = /^[A-Z_$][\w$]*(?:\.[A-Z_$][\w$]*|\[\d+\])*$/i;
|
|
361
361
|
const SUBJECT_IDENTIFIER_PATTERN = /[A-Z_$][\w$]*/gi;
|
|
362
362
|
const SUBJECT_INDEX_PATTERN = /\[(?<index>\d+)\]/g;
|
|
363
|
-
const
|
|
363
|
+
const ZEN_RESERVED_WORDS = new Set([
|
|
364
364
|
"and",
|
|
365
365
|
"or",
|
|
366
366
|
"not",
|
|
@@ -370,10 +370,13 @@ const ZEN_ROOT_RESERVED_WORDS = new Set([
|
|
|
370
370
|
"null"
|
|
371
371
|
]);
|
|
372
372
|
const ZEN_MEMBER_RESERVED_WORDS = new Set(["true", "false"]);
|
|
373
|
+
function isZenReservedWord(word) {
|
|
374
|
+
return ZEN_RESERVED_WORDS.has(word);
|
|
375
|
+
}
|
|
373
376
|
function isIdentifierPath(subject) {
|
|
374
377
|
if (!SUBJECT_PATTERN.test(subject)) return false;
|
|
375
378
|
const [root, ...members] = subject.match(SUBJECT_IDENTIFIER_PATTERN) ?? [];
|
|
376
|
-
if (root === void 0 ||
|
|
379
|
+
if (root === void 0 || isZenReservedWord(root) || members.some((member) => ZEN_MEMBER_RESERVED_WORDS.has(member))) return false;
|
|
377
380
|
for (const match of subject.matchAll(SUBJECT_INDEX_PATTERN)) if (match.groups?.index === void 0 || !isZenUnsignedIntegerText(match.groups.index)) return false;
|
|
378
381
|
return true;
|
|
379
382
|
}
|
|
@@ -639,14 +642,14 @@ function compileRule(rule) {
|
|
|
639
642
|
function matchesOperatorArity(rule) {
|
|
640
643
|
switch (conditionOperatorArity(rule.operator)) {
|
|
641
644
|
case "scalar": return isConditionScalar(rule.right);
|
|
642
|
-
case "array": return
|
|
645
|
+
case "array": return isConditionScalarArray(rule.right);
|
|
643
646
|
case "none": return rule.right === void 0;
|
|
644
647
|
}
|
|
645
648
|
}
|
|
646
649
|
function isConditionScalar(value) {
|
|
647
650
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
648
651
|
}
|
|
649
|
-
function
|
|
652
|
+
function isConditionScalarArray(value) {
|
|
650
653
|
return isArray(value) && value.every((item) => isConditionScalar(item));
|
|
651
654
|
}
|
|
652
655
|
const TWO_CHAR_PUNCTUATION = new Set([
|
|
@@ -671,7 +674,7 @@ const IDENT_PART = /[\w$]/;
|
|
|
671
674
|
const DIGIT = /\d/;
|
|
672
675
|
const NUMBER_PATTERN = /^\d+(?:\.\d+)?(?:e[+-]?\d+)?/i;
|
|
673
676
|
const INTEGER_PATTERN = /^\d+$/;
|
|
674
|
-
function
|
|
677
|
+
function parseCanonicalZenNumber(text) {
|
|
675
678
|
const value = Number(text);
|
|
676
679
|
return String(value) === text && isZenRepresentableNumber(value) ? value : null;
|
|
677
680
|
}
|
|
@@ -733,7 +736,7 @@ function liftConditionTree(expression) {
|
|
|
733
736
|
return token.value;
|
|
734
737
|
}
|
|
735
738
|
if (token.kind === "number") {
|
|
736
|
-
const value =
|
|
739
|
+
const value = parseCanonicalZenNumber(token.value);
|
|
737
740
|
if (value === null) return null;
|
|
738
741
|
pos += 1;
|
|
739
742
|
return value;
|
|
@@ -752,7 +755,7 @@ function liftConditionTree(expression) {
|
|
|
752
755
|
if (token.kind === "punct" && token.value === "-") {
|
|
753
756
|
const digits = peek(1);
|
|
754
757
|
if (digits === void 0 || digits.kind !== "number") return null;
|
|
755
|
-
const value =
|
|
758
|
+
const value = parseCanonicalZenNumber(digits.value);
|
|
756
759
|
if (value === null || value === 0 || !isZenRepresentableNumber(-value)) return null;
|
|
757
760
|
pos += 2;
|
|
758
761
|
return -value;
|
|
@@ -1334,4 +1337,4 @@ async function getTemplateDiagnostics(source) {
|
|
|
1334
1337
|
await loadEngine();
|
|
1335
1338
|
return getTemplateDiagnosticsSync(source);
|
|
1336
1339
|
}
|
|
1337
|
-
export { CONDITION_OPERATORS, CONDITION_TREE_OPERATORS, ExpressionError, ExpressionNotReadyError, MAX_CONDITION_TREE_DEPTH, analyzeTemplate, analyzeTemplateSync, analyzeTypes, analyzeTypesSync, compileBranch, compileCondition, compileConditionTree, compileGroup, conditionOperatorArity, configureEngine, configureExpressionMessages, emptyConditionGroup, enMessages, ensureConditionNodeIds, evaluate, evaluateSync, evaluateUnary, evaluateUnarySync, getCompletionItems, getCompletionItemsSync, getDiagnostics, getDiagnosticsSync, getEngineError, getEngineSync, getExpressionMessages, getTemplateDiagnostics, getTemplateDiagnosticsSync, isEngineReady, isZenRepresentableNumber, liftConditionTree, loadEngine, newConditionNodeId, parseTemplateHoles, registerExpressionLocale, resetEngine, satisfiesType, satisfiesTypeSync, schemaTreeToExpressionType, selectBranch, selectBranchWith, subscribeExpressionMessages, templateHoleAt, toZenLiteral, zhCNMessages };
|
|
1340
|
+
export { CONDITION_OPERATORS, CONDITION_TREE_OPERATORS, ExpressionError, ExpressionNotReadyError, MAX_CONDITION_TREE_DEPTH, analyzeTemplate, analyzeTemplateSync, analyzeTypes, analyzeTypesSync, compileBranch, compileCondition, compileConditionTree, compileGroup, conditionOperatorArity, configureEngine, configureExpressionMessages, emptyConditionGroup, enMessages, ensureConditionNodeIds, evaluate, evaluateSync, evaluateUnary, evaluateUnarySync, getCompletionItems, getCompletionItemsSync, getDiagnostics, getDiagnosticsSync, getEngineError, getEngineSync, getExpressionMessages, getTemplateDiagnostics, getTemplateDiagnosticsSync, isConditionScalarArray, isEngineReady, isZenRepresentableNumber, isZenReservedWord, liftConditionTree, loadEngine, newConditionNodeId, parseCanonicalZenNumber, parseTemplateHoles, registerExpressionLocale, resetEngine, satisfiesType, satisfiesTypeSync, schemaTreeToExpressionType, selectBranch, selectBranchWith, subscribeExpressionMessages, templateHoleAt, toZenLiteral, zhCNMessages };
|
package/package.json
CHANGED