@ng-forge/dynamic-forms 1.3.0-next.4 → 1.3.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/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-B6WH0Etk.mjs → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-DJinfAnV.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-B6WH0Etk.mjs.map → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-DJinfAnV.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-bootstrap-web-mcp-VjJn-JeD.mjs → ng-forge-dynamic-forms-bootstrap-web-mcp-Ce93FPLR.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-bootstrap-web-mcp-VjJn-JeD.mjs.map → ng-forge-dynamic-forms-bootstrap-web-mcp-Ce93FPLR.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-form-state-manager-BJKBX4FL.mjs → ng-forge-dynamic-forms-form-state-manager-3Ng7d_U2.mjs} +5 -22
- package/fesm2022/ng-forge-dynamic-forms-form-state-manager-3Ng7d_U2.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-internal.mjs +37 -1
- package/fesm2022/ng-forge-dynamic-forms-internal.mjs.map +1 -1
- package/fesm2022/ng-forge-dynamic-forms.mjs +3 -3
- package/internal/src/lib/core/expressions/parser/evaluator.d.ts +26 -0
- package/internal/src/lib/core/expressions/parser/evaluator.d.ts.map +1 -0
- package/internal/src/lib/core/expressions/parser/expression-parser.d.ts +20 -0
- package/internal/src/lib/core/expressions/parser/expression-parser.d.ts.map +1 -0
- package/internal/src/lib/core/expressions/parser/parser.d.ts +51 -0
- package/internal/src/lib/core/expressions/parser/parser.d.ts.map +1 -0
- package/internal/src/lib/core/expressions/parser/static-check.d.ts +25 -0
- package/internal/src/lib/core/expressions/parser/static-check.d.ts.map +1 -0
- package/internal/src/lib/core/expressions/parser/tokenizer.d.ts +19 -0
- package/internal/src/lib/core/expressions/parser/tokenizer.d.ts.map +1 -0
- package/internal/src/lib/core/expressions/parser/types.d.ts +117 -0
- package/internal/src/lib/core/expressions/parser/types.d.ts.map +1 -0
- package/internal/src/lib/errors/dynamic-form-error.d.ts +6 -0
- package/internal/src/lib/errors/dynamic-form-error.d.ts.map +1 -0
- package/package.json +1 -1
- package/types/ng-forge-dynamic-forms-integration.d.ts +10 -2
- package/types/ng-forge-dynamic-forms-internal.d.ts +62 -3
- package/fesm2022/ng-forge-dynamic-forms-form-state-manager-BJKBX4FL.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { d as FieldViewportObserver, f as resolveFieldParking, h as FIELD_WINDOWING, i as initializationComponentKey, m as clampWindowSize, n as collectInitializingContainerKeys, p as resolveFieldWindowing, t as DfFieldOutlet, u as resolveWrappers } from "./ng-forge-dynamic-forms-df-field-outlet.directive-CQsDMV-s.mjs";
|
|
2
|
-
import { a as walkAndValidateAddons, n as FormStateManager, o as normalizeSimplifiedArrays, r as VALUE_EXCLUSION_DEFAULTS, s as FormSubmitEvent, t as FORM_STATE_DEPS } from "./ng-forge-dynamic-forms-form-state-manager-
|
|
2
|
+
import { a as walkAndValidateAddons, n as FormStateManager, o as normalizeSimplifiedArrays, r as VALUE_EXCLUSION_DEFAULTS, s as FormSubmitEvent, t as FORM_STATE_DEPS } from "./ng-forge-dynamic-forms-form-state-manager-3Ng7d_U2.mjs";
|
|
3
3
|
import { c as PROPERTY_OVERRIDE_STORE, l as createPropertyOverrideStore, u as injectFieldRegistry } from "./ng-forge-dynamic-forms-resolve-field-ByGa5cpo.mjs";
|
|
4
4
|
import { a as resolveDefaultExport, n as loadWrapperComponent } from "./ng-forge-dynamic-forms-wrapper-chain-BnntfNU1.mjs";
|
|
5
5
|
import { n as getNormalizedArrayMetadata } from "./ng-forge-dynamic-forms-default-value-D5M4MNE-.mjs";
|
|
@@ -624,7 +624,7 @@ function createDerivationRenderGate() {
|
|
|
624
624
|
explicitEffect([hasDerivations], ([has]) => {
|
|
625
625
|
if (!has || engine() !== "idle") return;
|
|
626
626
|
engine.set("loading");
|
|
627
|
-
pendingTasks.run(() => import("./ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-
|
|
627
|
+
pendingTasks.run(() => import("./ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-DJinfAnV.mjs").then(({ bootstrapDerivationOrchestrator }) => {
|
|
628
628
|
runInInjectionContext(injector, () => bootstrapDerivationOrchestrator());
|
|
629
629
|
engine.set("wired");
|
|
630
630
|
}).catch((error) => {
|
|
@@ -677,7 +677,7 @@ function createWebMcpGate() {
|
|
|
677
677
|
const controller = new AbortController();
|
|
678
678
|
epoch = controller;
|
|
679
679
|
status.set("registering");
|
|
680
|
-
import("./ng-forge-dynamic-forms-bootstrap-web-mcp-
|
|
680
|
+
import("./ng-forge-dynamic-forms-bootstrap-web-mcp-Ce93FPLR.mjs").then(({ bootstrapWebMcp }) => {
|
|
681
681
|
if (thisEpoch !== epochId || controller.signal.aborted) return;
|
|
682
682
|
return runInInjectionContext(injector, () => bootstrapWebMcp(input.options, controller.signal));
|
|
683
683
|
}).then((result) => {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ASTNode } from './types';
|
|
2
|
+
/** Evaluation context for safe expression evaluation */
|
|
3
|
+
export interface EvaluationScope {
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
/** Every method name callable on some receiver type. A name outside this set can never be called. */
|
|
7
|
+
export declare const ALLOWED_METHOD_NAMES: ReadonlySet<string>;
|
|
8
|
+
/** Safely evaluates an AST node with a given context */
|
|
9
|
+
export declare class Evaluator {
|
|
10
|
+
private readonly scope;
|
|
11
|
+
private readonly expression;
|
|
12
|
+
constructor(scope: EvaluationScope, expression: string);
|
|
13
|
+
/** Evaluate an AST node */
|
|
14
|
+
evaluate(node: ASTNode): unknown;
|
|
15
|
+
private evaluateIdentifier;
|
|
16
|
+
private evaluateMemberAccess;
|
|
17
|
+
private evaluateComputedMemberAccess;
|
|
18
|
+
private evaluateBinaryOp;
|
|
19
|
+
private evaluateUnaryOp;
|
|
20
|
+
private evaluateCallExpression;
|
|
21
|
+
private evaluateArrayLiteral;
|
|
22
|
+
private evaluateObjectLiteral;
|
|
23
|
+
private evaluateArrowFunction;
|
|
24
|
+
private isMethodSafe;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/dynamic-forms/internal/src/lib/core/expressions/parser/evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAyB,MAAM,SAAS,CAAC;AAEzD,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAiGD,qGAAqG;AACrG,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAA2E,CAAC;AAgBjI,wDAAwD;AACxD,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM;IAKtD,2BAA2B;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAwChC,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,4BAA4B;IA0BpC,OAAO,CAAC,gBAAgB;IAyDxB,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,sBAAsB;IA4C9B,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,YAAY;CAcrB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EvaluationScope } from './evaluator';
|
|
2
|
+
import { ASTNode } from './types';
|
|
3
|
+
/** Secure expression parser that uses AST-based evaluation */
|
|
4
|
+
export declare class ExpressionParser {
|
|
5
|
+
/**
|
|
6
|
+
* Parse an expression string into an AST
|
|
7
|
+
* Results are cached for performance using LRU eviction
|
|
8
|
+
*/
|
|
9
|
+
static parse(expression: string): ASTNode;
|
|
10
|
+
/** Evaluate an expression with a given scope */
|
|
11
|
+
static evaluate(expression: string, scope: EvaluationScope): unknown;
|
|
12
|
+
/** Clear the AST cache */
|
|
13
|
+
static clearCache(): void;
|
|
14
|
+
/** Get cache statistics */
|
|
15
|
+
static getCacheStats(): {
|
|
16
|
+
size: number;
|
|
17
|
+
maxSize: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=expression-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expression-parser.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/dynamic-forms/internal/src/lib/core/expressions/parser/expression-parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,OAAO,EAAyB,MAAM,SAAS,CAAC;AAyDzD,8DAA8D;AAC9D,qBAAa,gBAAgB;IAC3B;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAiBzC,gDAAgD;IAChD,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO;IAkBpE,0BAA0B;IAC1B,MAAM,CAAC,UAAU,IAAI,IAAI;IAIzB,2BAA2B;IAC3B,MAAM,CAAC,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAM1D"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ASTNode } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Parses tokens into an Abstract Syntax Tree (AST)
|
|
4
|
+
* Uses recursive descent parsing with operator precedence
|
|
5
|
+
*/
|
|
6
|
+
export declare class Parser {
|
|
7
|
+
private tokens;
|
|
8
|
+
private current;
|
|
9
|
+
private readonly expression;
|
|
10
|
+
constructor(expression: string);
|
|
11
|
+
/** Parse the expression into an AST */
|
|
12
|
+
parse(): ASTNode;
|
|
13
|
+
private parseExpression;
|
|
14
|
+
/**
|
|
15
|
+
* Ternary `test ? consequent : alternate` — right-associative, sits between
|
|
16
|
+
* the arrow-function check and logical-or in precedence.
|
|
17
|
+
*/
|
|
18
|
+
private parseConditional;
|
|
19
|
+
/**
|
|
20
|
+
* Attempts to parse an arrow function. Returns null and leaves position
|
|
21
|
+
* unchanged if the next tokens don't form an arrow function head.
|
|
22
|
+
*/
|
|
23
|
+
private tryParseArrowFunction;
|
|
24
|
+
private checkAt;
|
|
25
|
+
/**
|
|
26
|
+
* `a ?? b` or an `||`/`&&` chain. As in JavaScript, `??` can't be mixed with
|
|
27
|
+
* `&&` or `||` without parentheses.
|
|
28
|
+
*/
|
|
29
|
+
private parseShortCircuit;
|
|
30
|
+
private throwMixedNullish;
|
|
31
|
+
private parseLogicalOr;
|
|
32
|
+
private parseLogicalAnd;
|
|
33
|
+
private parseEquality;
|
|
34
|
+
private parseComparison;
|
|
35
|
+
private parseAddition;
|
|
36
|
+
private parseMultiplication;
|
|
37
|
+
private parseUnary;
|
|
38
|
+
private parsePostfix;
|
|
39
|
+
private parsePrimary;
|
|
40
|
+
private parseArgumentList;
|
|
41
|
+
private parseArrayElements;
|
|
42
|
+
private parseObjectProperties;
|
|
43
|
+
private match;
|
|
44
|
+
private check;
|
|
45
|
+
private advance;
|
|
46
|
+
private isAtEnd;
|
|
47
|
+
private peek;
|
|
48
|
+
private previous;
|
|
49
|
+
private consume;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/dynamic-forms/internal/src/lib/core/expressions/parser/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,OAAO,EAAyB,MAAM,SAAS,CAAC;AAG3E;;;GAGG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,UAAU,EAAE,MAAM;IAI9B,uCAAuC;IACvC,KAAK,IAAI,OAAO;IAuBhB,OAAO,CAAC,eAAe;IAQvB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAmD7B,OAAO,CAAC,OAAO;IAKf;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,YAAY;IA6CpB,OAAO,CAAC,YAAY;IAuDpB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,qBAAqB;IA8B7B,OAAO,CAAC,KAAK;IAUb,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,OAAO;CAKhB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ASTNode } from './types';
|
|
2
|
+
/** Variables a condition expression can read (the keys of `EvaluationContext`). */
|
|
3
|
+
export declare const CONDITION_SCOPE_VARIABLES: ReadonlySet<string>;
|
|
4
|
+
/**
|
|
5
|
+
* Finds constructs that parse but can never work at runtime: a direct function call
|
|
6
|
+
* (`String(x)`), a method outside the allow-list, or a name that isn't in scope (`Math`),
|
|
7
|
+
* which reads as `undefined` and makes the expression quietly wrong.
|
|
8
|
+
*/
|
|
9
|
+
export declare function findStaticExpressionProblems(ast: ASTNode, scope: ReadonlySet<string>): string[];
|
|
10
|
+
/** An expression in a field's own config that can never work. */
|
|
11
|
+
export interface FieldExpressionProblem {
|
|
12
|
+
/** Where in the field's config, e.g. `logic[0].condition`. */
|
|
13
|
+
path: string;
|
|
14
|
+
/** The expression, absent for an empty and/or group. */
|
|
15
|
+
expression?: string;
|
|
16
|
+
/** What is wrong, e.g. `'Math' is not available in expressions`. */
|
|
17
|
+
message: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Checks the expressions in one field's own config: javascript conditions, derivation
|
|
21
|
+
* expressions (`logic` entries and the `derivation` shorthand) and empty and/or groups.
|
|
22
|
+
* Child `fields` are skipped, so callers walking the field tree see each one once.
|
|
23
|
+
*/
|
|
24
|
+
export declare function findFieldExpressionProblems(field: unknown): FieldExpressionProblem[];
|
|
25
|
+
//# sourceMappingURL=static-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-check.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/dynamic-forms/internal/src/lib/core/expressions/parser/static-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIlC,mFAAmF;AACnF,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAYxD,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAoD/F;AAMD,iEAAiE;AACjE,MAAM,WAAW,sBAAsB;IACrC,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,sBAAsB,EAAE,CAyCpF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Token } from './types';
|
|
2
|
+
/** Tokenizes an expression string into tokens */
|
|
3
|
+
export declare class Tokenizer {
|
|
4
|
+
private position;
|
|
5
|
+
private readonly expression;
|
|
6
|
+
constructor(expression: string);
|
|
7
|
+
/** Tokenize the entire expression */
|
|
8
|
+
tokenize(): Token[];
|
|
9
|
+
private skipWhitespace;
|
|
10
|
+
private nextToken;
|
|
11
|
+
private readString;
|
|
12
|
+
private readNumber;
|
|
13
|
+
private readIdentifierOrKeyword;
|
|
14
|
+
/** Reads the whole code point at `position`, keeping surrogate pairs intact. */
|
|
15
|
+
private codePointAt;
|
|
16
|
+
private getKeywordType;
|
|
17
|
+
private readOperatorOrPunctuation;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=tokenizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/dynamic-forms/internal/src/lib/core/expressions/parser/tokenizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAoC,MAAM,SAAS,CAAC;AAQlE,iDAAiD;AACjD,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,UAAU,EAAE,MAAM;IAI9B,qCAAqC;IACrC,QAAQ,IAAI,KAAK,EAAE;IAkBnB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,SAAS;IAsBjB,OAAO,CAAC,UAAU;IA8ClB,OAAO,CAAC,UAAU;IAgBlB,OAAO,CAAC,uBAAuB;IAkB/B,gFAAgF;IAChF,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,yBAAyB;CA4FlC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { DynamicFormError } from '../../../errors/dynamic-form-error';
|
|
2
|
+
/** Token types for expression parsing */
|
|
3
|
+
export declare enum TokenType {
|
|
4
|
+
NUMBER = "NUMBER",
|
|
5
|
+
STRING = "STRING",
|
|
6
|
+
TRUE = "TRUE",
|
|
7
|
+
FALSE = "FALSE",
|
|
8
|
+
NULL = "NULL",
|
|
9
|
+
UNDEFINED = "UNDEFINED",
|
|
10
|
+
IDENTIFIER = "IDENTIFIER",
|
|
11
|
+
PLUS = "PLUS",
|
|
12
|
+
MINUS = "MINUS",
|
|
13
|
+
MULTIPLY = "MULTIPLY",
|
|
14
|
+
DIVIDE = "DIVIDE",
|
|
15
|
+
MODULO = "MODULO",
|
|
16
|
+
EQUAL = "EQUAL",
|
|
17
|
+
NOT_EQUAL = "NOT_EQUAL",
|
|
18
|
+
GREATER = "GREATER",
|
|
19
|
+
LESS = "LESS",
|
|
20
|
+
GREATER_EQUAL = "GREATER_EQUAL",
|
|
21
|
+
LESS_EQUAL = "LESS_EQUAL",
|
|
22
|
+
AND = "AND",
|
|
23
|
+
OR = "OR",
|
|
24
|
+
NULLISH = "NULLISH",
|
|
25
|
+
NOT = "NOT",
|
|
26
|
+
DOT = "DOT",
|
|
27
|
+
COMMA = "COMMA",
|
|
28
|
+
COLON = "COLON",
|
|
29
|
+
LPAREN = "LPAREN",
|
|
30
|
+
RPAREN = "RPAREN",
|
|
31
|
+
LBRACKET = "LBRACKET",
|
|
32
|
+
RBRACKET = "RBRACKET",
|
|
33
|
+
LBRACE = "LBRACE",
|
|
34
|
+
RBRACE = "RBRACE",
|
|
35
|
+
ARROW = "ARROW",
|
|
36
|
+
QUESTION = "QUESTION",
|
|
37
|
+
OPTIONAL_DOT = "OPTIONAL_DOT",
|
|
38
|
+
EOF = "EOF"
|
|
39
|
+
}
|
|
40
|
+
/** Token with type, value, and position */
|
|
41
|
+
export interface Token {
|
|
42
|
+
type: TokenType;
|
|
43
|
+
value: string;
|
|
44
|
+
position: number;
|
|
45
|
+
}
|
|
46
|
+
/** AST Node types */
|
|
47
|
+
export type ASTNode = LiteralNode | IdentifierNode | MemberAccessNode | ComputedMemberAccessNode | BinaryOpNode | UnaryOpNode | CallExpressionNode | ConditionalNode | ArrayLiteralNode | ObjectLiteralNode | ArrowFunctionNode;
|
|
48
|
+
export interface LiteralNode {
|
|
49
|
+
type: 'Literal';
|
|
50
|
+
value: string | number | boolean | null | undefined;
|
|
51
|
+
}
|
|
52
|
+
export interface IdentifierNode {
|
|
53
|
+
type: 'Identifier';
|
|
54
|
+
name: string;
|
|
55
|
+
}
|
|
56
|
+
export interface MemberAccessNode {
|
|
57
|
+
type: 'MemberAccess';
|
|
58
|
+
object: ASTNode;
|
|
59
|
+
property: string;
|
|
60
|
+
/** True when this access used `?.` (optional chaining). */
|
|
61
|
+
optional?: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface ComputedMemberAccessNode {
|
|
64
|
+
type: 'ComputedMemberAccess';
|
|
65
|
+
object: ASTNode;
|
|
66
|
+
/** Expression evaluated at runtime to produce the property key. */
|
|
67
|
+
property: ASTNode;
|
|
68
|
+
/** True when this access used `?.[ ... ]` (optional chaining). */
|
|
69
|
+
optional?: boolean;
|
|
70
|
+
}
|
|
71
|
+
export interface ConditionalNode {
|
|
72
|
+
type: 'Conditional';
|
|
73
|
+
test: ASTNode;
|
|
74
|
+
consequent: ASTNode;
|
|
75
|
+
alternate: ASTNode;
|
|
76
|
+
}
|
|
77
|
+
export interface BinaryOpNode {
|
|
78
|
+
type: 'BinaryOp';
|
|
79
|
+
operator: string;
|
|
80
|
+
left: ASTNode;
|
|
81
|
+
right: ASTNode;
|
|
82
|
+
}
|
|
83
|
+
export interface UnaryOpNode {
|
|
84
|
+
type: 'UnaryOp';
|
|
85
|
+
operator: string;
|
|
86
|
+
operand: ASTNode;
|
|
87
|
+
}
|
|
88
|
+
export interface CallExpressionNode {
|
|
89
|
+
type: 'CallExpression';
|
|
90
|
+
callee: ASTNode;
|
|
91
|
+
arguments: ASTNode[];
|
|
92
|
+
/** True when this call used `?.( ... )` (optional chaining). */
|
|
93
|
+
optional?: boolean;
|
|
94
|
+
}
|
|
95
|
+
export interface ArrayLiteralNode {
|
|
96
|
+
type: 'ArrayLiteral';
|
|
97
|
+
elements: ASTNode[];
|
|
98
|
+
}
|
|
99
|
+
export interface ObjectLiteralNode {
|
|
100
|
+
type: 'ObjectLiteral';
|
|
101
|
+
properties: Array<{
|
|
102
|
+
key: string;
|
|
103
|
+
value: ASTNode;
|
|
104
|
+
}>;
|
|
105
|
+
}
|
|
106
|
+
export interface ArrowFunctionNode {
|
|
107
|
+
type: 'ArrowFunction';
|
|
108
|
+
params: string[];
|
|
109
|
+
body: ASTNode;
|
|
110
|
+
}
|
|
111
|
+
/** Parser error with position information */
|
|
112
|
+
export declare class ExpressionParserError extends DynamicFormError {
|
|
113
|
+
position: number;
|
|
114
|
+
expression: string;
|
|
115
|
+
constructor(message: string, position: number, expression: string);
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/dynamic-forms/internal/src/lib/core/expressions/parser/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-form-error.d.ts","sourceRoot":"","sources":["../../../../../../../packages/dynamic-forms/internal/src/lib/errors/dynamic-form-error.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAqB;gBAEvC,OAAO,EAAE,MAAM;CAI5B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ng-forge/dynamic-forms",
|
|
3
|
-
"version": "1.3.0
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Type-safe, signal-powered dynamic forms for Angular. Build complex forms from configuration with full TypeScript inference.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@ interface CheckboxField<TProps, TNullable extends boolean = boolean> extends Bas
|
|
|
34
34
|
* extend this with adapter-specific options (startView, appearance, hint, etc.).
|
|
35
35
|
*/
|
|
36
36
|
type DatepickerProps = object;
|
|
37
|
-
interface DatepickerField<TProps, TNullable extends boolean = boolean> extends BaseValueField<TProps, Date | string, FieldMeta, TNullable> {
|
|
37
|
+
interface DatepickerField<TProps, TNullable extends boolean = boolean> extends BaseValueField<TProps, Date | string | readonly (Date | string)[], FieldMeta, TNullable> {
|
|
38
38
|
type: 'datepicker';
|
|
39
39
|
minDate?: Date | string | null;
|
|
40
40
|
maxDate?: Date | string | null;
|
|
@@ -189,7 +189,15 @@ interface SelectField<T, TProps = SelectProps, TNullable extends boolean = boole
|
|
|
189
189
|
type: 'select';
|
|
190
190
|
readonly options: readonly FieldOption<T>[];
|
|
191
191
|
}
|
|
192
|
-
|
|
192
|
+
/**
|
|
193
|
+
* A number, or a range from kits that have one: PrimeNG `range` gives `number[]`, Ionic
|
|
194
|
+
* `dualKnobs` gives `{ lower, upper }`. The inferred form value follows the props.
|
|
195
|
+
*/
|
|
196
|
+
type SliderValue = number | readonly number[] | {
|
|
197
|
+
lower: number;
|
|
198
|
+
upper: number;
|
|
199
|
+
};
|
|
200
|
+
interface SliderField<TProps, TNullable extends boolean = boolean> extends BaseValueField<TProps, SliderValue, FieldMeta, TNullable> {
|
|
193
201
|
type: 'slider';
|
|
194
202
|
minValue?: number;
|
|
195
203
|
maxValue?: number;
|
|
@@ -986,13 +986,53 @@ type Depth = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
|
986
986
|
* This prevents `as const` from over-narrowing types like `''` to literal `''` instead of `string`.
|
|
987
987
|
*/
|
|
988
988
|
type Widen<T, D extends number = 5> = [D] extends [never] ? T : T extends string ? string : T extends number ? number : T extends boolean ? boolean : T extends readonly (infer U)[] ? Widen<U, Depth[D]>[] : T extends Record<string, unknown> ? { -readonly [K in keyof T]: Widen<T[K], Depth[D]>; } : T;
|
|
989
|
+
/**
|
|
990
|
+
* An explicit non-empty array `value` keeps its widened item type. An empty one (`[]`, whose
|
|
991
|
+
* items are `never`) or no array at all falls back to the kit's default item type.
|
|
992
|
+
*/
|
|
993
|
+
type MultiItems<V, TItem> = V extends readonly unknown[] ? ([V[number]] extends [never] ? TItem[] : Widen<V>) : TItem[];
|
|
994
|
+
/**
|
|
995
|
+
* Value shape for fields whose props switch them to several values: `select` / `datepicker` with
|
|
996
|
+
* `multiple`, a PrimeNG datepicker in `multiple`/`range` mode (ISO strings), a PrimeNG `range`
|
|
997
|
+
* slider (number[]) and an Ionic `dualKnobs` slider ({ lower, upper }). `never` for single-value fields.
|
|
998
|
+
*/
|
|
999
|
+
type MultiValueType<T, V> = T extends {
|
|
1000
|
+
type: 'select';
|
|
1001
|
+
props: {
|
|
1002
|
+
multiple: true;
|
|
1003
|
+
};
|
|
1004
|
+
} ? MultiItems<V, string> : T extends {
|
|
1005
|
+
type: 'datepicker';
|
|
1006
|
+
props: {
|
|
1007
|
+
multiple: true;
|
|
1008
|
+
};
|
|
1009
|
+
} ? MultiItems<V, Date> : T extends {
|
|
1010
|
+
type: 'datepicker';
|
|
1011
|
+
props: {
|
|
1012
|
+
selectionMode: 'multiple' | 'range';
|
|
1013
|
+
};
|
|
1014
|
+
} ? MultiItems<V, string> : T extends {
|
|
1015
|
+
type: 'slider';
|
|
1016
|
+
props: {
|
|
1017
|
+
range: true;
|
|
1018
|
+
};
|
|
1019
|
+
} ? number[] : T extends {
|
|
1020
|
+
type: 'slider';
|
|
1021
|
+
props: {
|
|
1022
|
+
dualKnobs: true;
|
|
1023
|
+
};
|
|
1024
|
+
} ? {
|
|
1025
|
+
lower: number;
|
|
1026
|
+
upper: number;
|
|
1027
|
+
} : never;
|
|
989
1028
|
/**
|
|
990
1029
|
* Resolves the "underlying" non-null value type for a field, based on its `type`
|
|
991
1030
|
* discriminator and (where it matters) its `value` literal. Used when we need a
|
|
992
1031
|
* base type independent of whether the literal happens to be `null` — i.e., when
|
|
993
1032
|
* computing the nullable widening for `value: null, nullable: true`.
|
|
994
1033
|
*/
|
|
995
|
-
type ResolveBaseValueType<T, V> = T extends
|
|
1034
|
+
type ResolveBaseValueType<T, V> = [MultiValueType<T, V>] extends [never] ? ResolveSingleValueType<T, V> : MultiValueType<T, V>;
|
|
1035
|
+
type ResolveSingleValueType<T, V> = T extends {
|
|
996
1036
|
type: 'slider';
|
|
997
1037
|
} ? number : T extends {
|
|
998
1038
|
type: 'input';
|
|
@@ -1089,9 +1129,13 @@ type ProcessField<T, D extends number = 5> = [D] extends [never] ? Record<string
|
|
|
1089
1129
|
value: infer V;
|
|
1090
1130
|
} ? K extends string ? { [P in K]: MaybeOptional<T, InferValueType<T, V>>; } : never : T extends {
|
|
1091
1131
|
key: infer K;
|
|
1092
|
-
} ? K extends string ? { [P in K]: MaybeOptional<T, T
|
|
1132
|
+
} ? K extends string ? { [P in K]: MaybeOptional<T, InferUnvaluedType<T>>; } : never : never;
|
|
1133
|
+
/** Value fields without `value`: string, unless props switch the field to several values. */
|
|
1134
|
+
type InferUnvaluedType<T> = [MultiValueType<T, null>] extends [never] ? T extends {
|
|
1135
|
+
nullable: true;
|
|
1136
|
+
} ? string | null : string : T extends {
|
|
1093
1137
|
nullable: true;
|
|
1094
|
-
} ?
|
|
1138
|
+
} ? MultiValueType<T, null> | null : MultiValueType<T, null>;
|
|
1095
1139
|
/** Internal helper with depth tracking */
|
|
1096
1140
|
type InferFormValueWithDepth<T extends RegisteredFieldTypes[], D extends number = 5> = UnionToIntersection<ProcessField<T[number], D>>;
|
|
1097
1141
|
/** Helper to extract fields from either fields array or FormConfig */
|
|
@@ -2794,6 +2838,21 @@ export declare const CONDITION_SCOPE_VARIABLES: ReadonlySet<string>;
|
|
|
2794
2838
|
* which reads as `undefined` and makes the expression quietly wrong.
|
|
2795
2839
|
*/
|
|
2796
2840
|
export declare function findStaticExpressionProblems(ast: ASTNode, scope: ReadonlySet<string>): string[];
|
|
2841
|
+
/** An expression in a field's own config that can never work. */
|
|
2842
|
+
export interface FieldExpressionProblem {
|
|
2843
|
+
/** Where in the field's config, e.g. `logic[0].condition`. */
|
|
2844
|
+
path: string;
|
|
2845
|
+
/** The expression, absent for an empty and/or group. */
|
|
2846
|
+
expression?: string;
|
|
2847
|
+
/** What is wrong, e.g. `'Math' is not available in expressions`. */
|
|
2848
|
+
message: string;
|
|
2849
|
+
}
|
|
2850
|
+
/**
|
|
2851
|
+
* Checks the expressions in one field's own config: javascript conditions, derivation
|
|
2852
|
+
* expressions (`logic` entries and the `derivation` shorthand) and empty and/or groups.
|
|
2853
|
+
* Child `fields` are skipped, so callers walking the field tree see each one once.
|
|
2854
|
+
*/
|
|
2855
|
+
export declare function findFieldExpressionProblems(field: unknown): FieldExpressionProblem[];
|
|
2797
2856
|
/** TTL cache for HTTP condition responses with max entries eviction. */
|
|
2798
2857
|
export declare class HttpConditionCache {
|
|
2799
2858
|
private readonly cache;
|