@ng-forge/dynamic-forms 1.2.0-next.5 → 1.2.0-next.7
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-array-field.component-D-VWBM-t.mjs → ng-forge-dynamic-forms-array-field.component-DK7dAQv7.mjs} +6 -10
- package/fesm2022/ng-forge-dynamic-forms-array-field.component-DK7dAQv7.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-OBDy6qd9.mjs → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-BfxYqAQA.mjs} +29 -7
- package/fesm2022/ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-BfxYqAQA.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-container-field.component-BpeFyhAt.mjs → ng-forge-dynamic-forms-container-field.component-Cj2msZp_.mjs} +9 -12
- package/fesm2022/ng-forge-dynamic-forms-container-field.component-Cj2msZp_.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-debounce-C9F4v1Ke.mjs +17 -0
- package/fesm2022/ng-forge-dynamic-forms-debounce-C9F4v1Ke.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-field-errors-wrapper.component-ZdaC4Bit.mjs +25 -0
- package/fesm2022/ng-forge-dynamic-forms-field-errors-wrapper.component-ZdaC4Bit.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-form-schema.service-C3cVSmft.mjs +24 -0
- package/fesm2022/ng-forge-dynamic-forms-form-schema.service-C3cVSmft.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-group-field.component-BNjYMTqT.mjs → ng-forge-dynamic-forms-group-field.component-DN6X506r.mjs} +6 -10
- package/fesm2022/ng-forge-dynamic-forms-group-field.component-DN6X506r.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs +10 -72
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
- package/fesm2022/ng-forge-dynamic-forms-internal.mjs +252 -95
- package/fesm2022/ng-forge-dynamic-forms-internal.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-DSXZJHcu.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-DCX7tvaB.mjs} +1089 -1288
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-DCX7tvaB.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-B92kLZkH.mjs → ng-forge-dynamic-forms-page-field.component-D16ey8r-.mjs} +54 -13
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-D16ey8r-.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-schema-builder-DO-su9sF.mjs +570 -0
- package/fesm2022/ng-forge-dynamic-forms-schema-builder-DO-su9sF.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms.mjs +2 -2
- package/package.json +2 -2
- package/types/ng-forge-dynamic-forms-integration.d.ts +7 -31
- package/types/ng-forge-dynamic-forms-internal.d.ts +429 -222
- package/types/ng-forge-dynamic-forms.d.ts +33 -17
- package/fesm2022/ng-forge-dynamic-forms-array-field.component-D-VWBM-t.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-OBDy6qd9.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-container-field.component-BpeFyhAt.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-container-utils-BZFz6ztF.mjs +0 -24
- package/fesm2022/ng-forge-dynamic-forms-container-utils-BZFz6ztF.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-emit-initialization-DhHwU6FJ.mjs +0 -17
- package/fesm2022/ng-forge-dynamic-forms-emit-initialization-DhHwU6FJ.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-group-field.component-BNjYMTqT.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-DSXZJHcu.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-B92kLZkH.mjs.map +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, computed, isSignal, inject, Injector, input, signal, ChangeDetectionStrategy, Component, untracked, Injectable, linkedSignal, resourceFromSnapshots, Pipe } from '@angular/core';
|
|
2
|
+
import { InjectionToken, computed, isSignal, inject, Injector, input, signal, ChangeDetectionStrategy, Component, untracked, Injectable, linkedSignal, resourceFromSnapshots, Pipe, viewChild, ViewContainerRef, Directive, forwardRef } from '@angular/core';
|
|
3
3
|
import { NgComponentOutlet } from '@angular/common';
|
|
4
4
|
import { explicitEffect } from 'ngxtension/explicit-effect';
|
|
5
5
|
import { toSignal, toObservable, rxResource } from '@angular/core/rxjs-interop';
|
|
6
6
|
import { isObservable, defer, combineLatest, pipe, debounceTime, distinctUntilChanged, map, tap, catchError, of, from, startWith, Subject, filter, TimeoutError, throwError } from 'rxjs';
|
|
7
7
|
import { HttpClient } from '@angular/common/http';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { switchMap, map as map$1, scan, filter as filter$1, take, timeout, catchError as catchError$1, shareReplay } from 'rxjs/operators';
|
|
9
|
+
import { email, min, max, minLength, maxLength, pattern, required, validateTree, validate, validateAsync, validateHttp } from '@angular/forms/signals';
|
|
10
10
|
|
|
11
11
|
const ADDON_TYPE_DEFINITIONS = new InjectionToken('ADDON_TYPE_DEFINITIONS');
|
|
12
12
|
|
|
@@ -1576,10 +1576,14 @@ function safeReadPathKeys(fieldContext) {
|
|
|
1576
1576
|
}
|
|
1577
1577
|
|
|
1578
1578
|
function createFieldValueProxy(getRootForm, getRootFormValue) {
|
|
1579
|
-
const
|
|
1579
|
+
const resolveAccessor = (key) => {
|
|
1580
1580
|
const root = getRootForm();
|
|
1581
1581
|
const accessor = root?.[key];
|
|
1582
|
-
|
|
1582
|
+
return typeof accessor === 'function' ? accessor : undefined;
|
|
1583
|
+
};
|
|
1584
|
+
const readField = (key) => {
|
|
1585
|
+
const accessor = resolveAccessor(key);
|
|
1586
|
+
if (accessor) {
|
|
1583
1587
|
const state = untracked(() => accessor());
|
|
1584
1588
|
const valueSig = state && state.value;
|
|
1585
1589
|
if (typeof valueSig === 'function') {
|
|
@@ -1598,8 +1602,7 @@ function createFieldValueProxy(getRootForm, getRootFormValue) {
|
|
|
1598
1602
|
has(_target, prop) {
|
|
1599
1603
|
if (typeof prop === 'symbol')
|
|
1600
1604
|
return false;
|
|
1601
|
-
|
|
1602
|
-
if (root && prop in root)
|
|
1605
|
+
if (resolveAccessor(prop))
|
|
1603
1606
|
return true;
|
|
1604
1607
|
return prop in getRootFormValue();
|
|
1605
1608
|
},
|
|
@@ -2662,6 +2665,187 @@ function injectNonFieldEvaluationContext(fieldDef, options = {}) {
|
|
|
2662
2665
|
};
|
|
2663
2666
|
}
|
|
2664
2667
|
|
|
2668
|
+
function dynamicTextToObservable(value, injector) {
|
|
2669
|
+
if (value === undefined) {
|
|
2670
|
+
return of('');
|
|
2671
|
+
}
|
|
2672
|
+
if (isObservable(value)) {
|
|
2673
|
+
return value;
|
|
2674
|
+
}
|
|
2675
|
+
if (isSignal(value)) {
|
|
2676
|
+
return untracked(() => toObservable(value, { injector }));
|
|
2677
|
+
}
|
|
2678
|
+
return of(String(value));
|
|
2679
|
+
}
|
|
2680
|
+
|
|
2681
|
+
const PLACEHOLDER_PATTERN = /\{\{([^{}]*)\}\}/g;
|
|
2682
|
+
function interpolateParams(message, error) {
|
|
2683
|
+
const params = extractErrorParams(error);
|
|
2684
|
+
return message.replace(PLACEHOLDER_PATTERN, (placeholder, rawKey) => {
|
|
2685
|
+
const key = rawKey.trim();
|
|
2686
|
+
return Object.hasOwn(params, key) ? safeToString(params[key]) : placeholder;
|
|
2687
|
+
});
|
|
2688
|
+
}
|
|
2689
|
+
function safeToString(value) {
|
|
2690
|
+
if (value === null || value === undefined) {
|
|
2691
|
+
return '';
|
|
2692
|
+
}
|
|
2693
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
2694
|
+
return String(value);
|
|
2695
|
+
}
|
|
2696
|
+
if (value instanceof RegExp) {
|
|
2697
|
+
return value.toString();
|
|
2698
|
+
}
|
|
2699
|
+
if (value instanceof Date) {
|
|
2700
|
+
return value.toISOString();
|
|
2701
|
+
}
|
|
2702
|
+
if (Array.isArray(value)) {
|
|
2703
|
+
return value.join(', ');
|
|
2704
|
+
}
|
|
2705
|
+
try {
|
|
2706
|
+
if (typeof value === 'object' && value.toString !== Object.prototype.toString) {
|
|
2707
|
+
return value.toString();
|
|
2708
|
+
}
|
|
2709
|
+
return JSON.stringify(value);
|
|
2710
|
+
}
|
|
2711
|
+
catch {
|
|
2712
|
+
return '[object]';
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
function extractErrorParams(error) {
|
|
2716
|
+
const params = {};
|
|
2717
|
+
if ('min' in error)
|
|
2718
|
+
params.min = error.min;
|
|
2719
|
+
if ('max' in error)
|
|
2720
|
+
params.max = error.max;
|
|
2721
|
+
if ('pattern' in error)
|
|
2722
|
+
params.pattern = error.pattern;
|
|
2723
|
+
if ('actual' in error)
|
|
2724
|
+
params.actual = error.actual;
|
|
2725
|
+
if ('expected' in error)
|
|
2726
|
+
params.expected = error.expected;
|
|
2727
|
+
if ('requiredLength' in error) {
|
|
2728
|
+
params.requiredLength = error.requiredLength;
|
|
2729
|
+
}
|
|
2730
|
+
else if ('minLength' in error) {
|
|
2731
|
+
params.requiredLength = error.minLength;
|
|
2732
|
+
params.minLength = error.minLength;
|
|
2733
|
+
}
|
|
2734
|
+
else if ('maxLength' in error) {
|
|
2735
|
+
params.requiredLength = error.maxLength;
|
|
2736
|
+
params.maxLength = error.maxLength;
|
|
2737
|
+
}
|
|
2738
|
+
if ('actualLength' in error)
|
|
2739
|
+
params.actualLength = error.actualLength;
|
|
2740
|
+
Object.keys(error).forEach((key) => {
|
|
2741
|
+
if (key !== 'kind' && !(key in params)) {
|
|
2742
|
+
params[key] = error[key];
|
|
2743
|
+
}
|
|
2744
|
+
});
|
|
2745
|
+
return params;
|
|
2746
|
+
}
|
|
2747
|
+
|
|
2748
|
+
function createResolvedErrorsSignal(field, validationMessages, defaultValidationMessages = signal(undefined), injector = inject(Injector)) {
|
|
2749
|
+
const logger = injector.get(DynamicFormLogger);
|
|
2750
|
+
const messages = computed(() => validationMessages() ?? {}, /* @ts-ignore */
|
|
2751
|
+
...(ngDevMode ? [{ debugName: "messages" }] : /* istanbul ignore next */ []));
|
|
2752
|
+
const defaultMessages = computed(() => defaultValidationMessages() ?? {}, /* @ts-ignore */
|
|
2753
|
+
...(ngDevMode ? [{ debugName: "defaultMessages" }] : /* istanbul ignore next */ []));
|
|
2754
|
+
const errors = computed(() => field()?.().errors() ?? [], /* @ts-ignore */
|
|
2755
|
+
...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
2756
|
+
const errors$ = toObservable(errors, { injector });
|
|
2757
|
+
const messages$ = toObservable(messages, { injector });
|
|
2758
|
+
const defaultMessages$ = toObservable(defaultMessages, { injector });
|
|
2759
|
+
const resolvedErrors$ = combineLatest([errors$, messages$, defaultMessages$]).pipe(switchMap(([currentErrors, msgs, defaultMsgs]) => {
|
|
2760
|
+
if (!currentErrors || currentErrors.length === 0) {
|
|
2761
|
+
return of([]);
|
|
2762
|
+
}
|
|
2763
|
+
const errorResolvers = currentErrors.map((error) => resolveErrorMessage(error, msgs, defaultMsgs, injector, logger));
|
|
2764
|
+
return errorResolvers.length > 0
|
|
2765
|
+
? combineLatest(errorResolvers).pipe(map$1((errors) => errors.filter((e) => e !== null)))
|
|
2766
|
+
: of([]);
|
|
2767
|
+
}));
|
|
2768
|
+
return toSignal(resolvedErrors$, { initialValue: [], injector });
|
|
2769
|
+
}
|
|
2770
|
+
function isMessageResolver(message) {
|
|
2771
|
+
return typeof message === 'function' && !isSignal(message);
|
|
2772
|
+
}
|
|
2773
|
+
function resolveMessageFunction(resolver, error, logger) {
|
|
2774
|
+
try {
|
|
2775
|
+
return resolver(error) ?? error.message ?? '';
|
|
2776
|
+
}
|
|
2777
|
+
catch (err) {
|
|
2778
|
+
logger.error(`Validation message resolver for error kind "${error.kind}" threw; falling back to error.message.`, err);
|
|
2779
|
+
return error.message ?? '';
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
function resolveErrorMessage(error, fieldMessages, defaultMessages, injector, logger) {
|
|
2783
|
+
const fieldMessage = fieldMessages[error.kind];
|
|
2784
|
+
const defaultMessage = defaultMessages[error.kind];
|
|
2785
|
+
const messageToUse = fieldMessage ?? defaultMessage ?? error.message;
|
|
2786
|
+
if (!messageToUse) {
|
|
2787
|
+
logger.warn(`No validation message found for error kind "${error.kind}". ` +
|
|
2788
|
+
`Please provide a message via field-level validationMessages or form-level defaultValidationMessages.`);
|
|
2789
|
+
return of(null);
|
|
2790
|
+
}
|
|
2791
|
+
const isSchemaMessage = fieldMessage === undefined && defaultMessage === undefined;
|
|
2792
|
+
const messageText = isMessageResolver(messageToUse) ? resolveMessageFunction(messageToUse, error, logger) : messageToUse;
|
|
2793
|
+
const messageObservable = isSchemaMessage
|
|
2794
|
+
? of(messageToUse) : dynamicTextToObservable(messageText, injector);
|
|
2795
|
+
return messageObservable.pipe(map$1((msg) => ({
|
|
2796
|
+
kind: error.kind,
|
|
2797
|
+
message: interpolateParams(msg, error),
|
|
2798
|
+
})));
|
|
2799
|
+
}
|
|
2800
|
+
|
|
2801
|
+
function shouldShowErrors(field) {
|
|
2802
|
+
return computed(() => {
|
|
2803
|
+
const control = field()?.();
|
|
2804
|
+
if (!control)
|
|
2805
|
+
return false;
|
|
2806
|
+
return control.invalid() && control.touched() && control.errors().length > 0;
|
|
2807
|
+
});
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2810
|
+
const FIELD_ERROR_DISPLAY = new InjectionToken('FIELD_ERROR_DISPLAY');
|
|
2811
|
+
function injectFieldErrors(options) {
|
|
2812
|
+
const injector = options.injector ?? inject(Injector);
|
|
2813
|
+
const defaultValidationMessages = inject(DEFAULT_VALIDATION_MESSAGES, { optional: true });
|
|
2814
|
+
const fieldSignalContext = inject(FIELD_SIGNAL_CONTEXT, { optional: true });
|
|
2815
|
+
const fieldState = computed(() => {
|
|
2816
|
+
const inputs = options.fieldInputs();
|
|
2817
|
+
if (!inputs)
|
|
2818
|
+
return undefined;
|
|
2819
|
+
if (inputs.field)
|
|
2820
|
+
return inputs.field;
|
|
2821
|
+
const parentTree = fieldSignalContext?.form;
|
|
2822
|
+
const node = inputs.key ? parentTree?.[inputs.key] : undefined;
|
|
2823
|
+
return node ? node() : undefined;
|
|
2824
|
+
}, /* @ts-ignore */
|
|
2825
|
+
...(ngDevMode ? [{ debugName: "fieldState" }] : /* istanbul ignore next */ []));
|
|
2826
|
+
const fieldTree = computed(() => {
|
|
2827
|
+
const state = fieldState();
|
|
2828
|
+
return state ? (() => state) : undefined;
|
|
2829
|
+
}, /* @ts-ignore */
|
|
2830
|
+
...(ngDevMode ? [{ debugName: "fieldTree" }] : /* istanbul ignore next */ []));
|
|
2831
|
+
const messages = computed(() => options.validationMessages?.() ?? options.fieldInputs()?.validationMessages, /* @ts-ignore */
|
|
2832
|
+
...(ngDevMode ? [{ debugName: "messages" }] : /* istanbul ignore next */ []));
|
|
2833
|
+
const errors = createResolvedErrorsSignal(fieldTree, messages, computed(() => defaultValidationMessages?.()), injector);
|
|
2834
|
+
const showErrors = shouldShowErrors(fieldTree);
|
|
2835
|
+
return {
|
|
2836
|
+
errors,
|
|
2837
|
+
showErrors,
|
|
2838
|
+
errorsToDisplay: computed(() => (showErrors() ? errors() : [])),
|
|
2839
|
+
errorId: computed(() => `${options.fieldInputs()?.key ?? ''}-error`),
|
|
2840
|
+
};
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
function rowError(ctx, index, key, error) {
|
|
2844
|
+
const rows = ctx.fieldTree;
|
|
2845
|
+
const fieldTree = rows?.[index]?.[key];
|
|
2846
|
+
return fieldTree ? { ...error, fieldTree } : error;
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2665
2849
|
function isFunctionHttpValidator(config) {
|
|
2666
2850
|
const c = config;
|
|
2667
2851
|
return typeof c.functionName === 'string' || (c.fn !== null && typeof c.fn === 'object');
|
|
@@ -2773,7 +2957,8 @@ function applyPatternValidator(path, value, expression, when) {
|
|
|
2773
2957
|
function createConditionalLogic(when) {
|
|
2774
2958
|
return when ? createLogicFunction(when) : undefined;
|
|
2775
2959
|
}
|
|
2776
|
-
function applyValidator(config,
|
|
2960
|
+
function applyValidator(config,
|
|
2961
|
+
fieldPath, attachment = 'field') {
|
|
2777
2962
|
const path = fieldPath;
|
|
2778
2963
|
switch (config.type) {
|
|
2779
2964
|
case 'required':
|
|
@@ -2820,7 +3005,7 @@ function applyValidator(config, fieldPath) {
|
|
|
2820
3005
|
}
|
|
2821
3006
|
break;
|
|
2822
3007
|
case 'custom':
|
|
2823
|
-
applyCustomValidator(config, path);
|
|
3008
|
+
applyCustomValidator(config, path, attachment);
|
|
2824
3009
|
break;
|
|
2825
3010
|
case 'async':
|
|
2826
3011
|
applyAsyncValidator(config, path);
|
|
@@ -2830,7 +3015,7 @@ function applyValidator(config, fieldPath) {
|
|
|
2830
3015
|
break;
|
|
2831
3016
|
}
|
|
2832
3017
|
}
|
|
2833
|
-
function applyCustomValidator(config, fieldPath) {
|
|
3018
|
+
function applyCustomValidator(config, fieldPath, attachment = 'field') {
|
|
2834
3019
|
let validatorFn;
|
|
2835
3020
|
if (config.expression) {
|
|
2836
3021
|
validatorFn = createExpressionValidator(config);
|
|
@@ -2842,11 +3027,16 @@ function applyCustomValidator(config, fieldPath) {
|
|
|
2842
3027
|
throw new DynamicFormError('Custom validator requires one of "expression", "functionName", or "fn".');
|
|
2843
3028
|
}
|
|
2844
3029
|
const whenLogic = createConditionalLogic(config.when);
|
|
2845
|
-
|
|
3030
|
+
const run = (ctx) => {
|
|
2846
3031
|
if (whenLogic && !whenLogic(ctx))
|
|
2847
3032
|
return null;
|
|
2848
3033
|
return validatorFn(ctx);
|
|
2849
|
-
}
|
|
3034
|
+
};
|
|
3035
|
+
if (attachment === 'tree') {
|
|
3036
|
+
validateTree(fieldPath, run);
|
|
3037
|
+
return;
|
|
3038
|
+
}
|
|
3039
|
+
validate(fieldPath, run);
|
|
2850
3040
|
}
|
|
2851
3041
|
function createFunctionValidator(config) {
|
|
2852
3042
|
const logger = inject(DynamicFormLogger);
|
|
@@ -2998,8 +3188,9 @@ function applyDeclarativeHttpValidator(config, fieldPath) {
|
|
|
2998
3188
|
},
|
|
2999
3189
|
});
|
|
3000
3190
|
}
|
|
3001
|
-
function applyValidators(configs,
|
|
3002
|
-
|
|
3191
|
+
function applyValidators(configs,
|
|
3192
|
+
fieldPath, attachment = 'field') {
|
|
3193
|
+
configs.forEach((config) => applyValidator(config, fieldPath, attachment));
|
|
3003
3194
|
}
|
|
3004
3195
|
|
|
3005
3196
|
function isCheckedField(field) {
|
|
@@ -3485,19 +3676,6 @@ function isDisplayOnlyField(field) {
|
|
|
3485
3676
|
}
|
|
3486
3677
|
|
|
3487
3678
|
|
|
3488
|
-
function dynamicTextToObservable(value, injector) {
|
|
3489
|
-
if (value === undefined) {
|
|
3490
|
-
return of('');
|
|
3491
|
-
}
|
|
3492
|
-
if (isObservable(value)) {
|
|
3493
|
-
return value;
|
|
3494
|
-
}
|
|
3495
|
-
if (isSignal(value)) {
|
|
3496
|
-
return untracked(() => toObservable(value, { injector }));
|
|
3497
|
-
}
|
|
3498
|
-
return of(String(value));
|
|
3499
|
-
}
|
|
3500
|
-
|
|
3501
3679
|
class DynamicTextPipe {
|
|
3502
3680
|
injector = inject(Injector);
|
|
3503
3681
|
transform(value) {
|
|
@@ -3559,74 +3737,15 @@ function setupInitializationTracking(options) {
|
|
|
3559
3737
|
}), shareReplay({ bufferSize: 1, refCount: false }));
|
|
3560
3738
|
}
|
|
3561
3739
|
|
|
3562
|
-
const PLACEHOLDER_PATTERN = /\{\{([^{}]*)\}\}/g;
|
|
3563
|
-
function interpolateParams(message, error) {
|
|
3564
|
-
const params = extractErrorParams(error);
|
|
3565
|
-
return message.replace(PLACEHOLDER_PATTERN, (placeholder, rawKey) => {
|
|
3566
|
-
const key = rawKey.trim();
|
|
3567
|
-
return Object.hasOwn(params, key) ? safeToString(params[key]) : placeholder;
|
|
3568
|
-
});
|
|
3569
|
-
}
|
|
3570
|
-
function safeToString(value) {
|
|
3571
|
-
if (value === null || value === undefined) {
|
|
3572
|
-
return '';
|
|
3573
|
-
}
|
|
3574
|
-
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
3575
|
-
return String(value);
|
|
3576
|
-
}
|
|
3577
|
-
if (value instanceof RegExp) {
|
|
3578
|
-
return value.toString();
|
|
3579
|
-
}
|
|
3580
|
-
if (value instanceof Date) {
|
|
3581
|
-
return value.toISOString();
|
|
3582
|
-
}
|
|
3583
|
-
if (Array.isArray(value)) {
|
|
3584
|
-
return value.join(', ');
|
|
3585
|
-
}
|
|
3586
|
-
try {
|
|
3587
|
-
if (typeof value === 'object' && value.toString !== Object.prototype.toString) {
|
|
3588
|
-
return value.toString();
|
|
3589
|
-
}
|
|
3590
|
-
return JSON.stringify(value);
|
|
3591
|
-
}
|
|
3592
|
-
catch {
|
|
3593
|
-
return '[object]';
|
|
3594
|
-
}
|
|
3595
|
-
}
|
|
3596
|
-
function extractErrorParams(error) {
|
|
3597
|
-
const params = {};
|
|
3598
|
-
if ('min' in error)
|
|
3599
|
-
params.min = error.min;
|
|
3600
|
-
if ('max' in error)
|
|
3601
|
-
params.max = error.max;
|
|
3602
|
-
if ('pattern' in error)
|
|
3603
|
-
params.pattern = error.pattern;
|
|
3604
|
-
if ('actual' in error)
|
|
3605
|
-
params.actual = error.actual;
|
|
3606
|
-
if ('expected' in error)
|
|
3607
|
-
params.expected = error.expected;
|
|
3608
|
-
if ('requiredLength' in error) {
|
|
3609
|
-
params.requiredLength = error.requiredLength;
|
|
3610
|
-
}
|
|
3611
|
-
else if ('minLength' in error) {
|
|
3612
|
-
params.requiredLength = error.minLength;
|
|
3613
|
-
params.minLength = error.minLength;
|
|
3614
|
-
}
|
|
3615
|
-
else if ('maxLength' in error) {
|
|
3616
|
-
params.requiredLength = error.maxLength;
|
|
3617
|
-
params.maxLength = error.maxLength;
|
|
3618
|
-
}
|
|
3619
|
-
if ('actualLength' in error)
|
|
3620
|
-
params.actualLength = error.actualLength;
|
|
3621
|
-
Object.keys(error).forEach((key) => {
|
|
3622
|
-
if (key !== 'kind' && !(key in params)) {
|
|
3623
|
-
params[key] = error[key];
|
|
3624
|
-
}
|
|
3625
|
-
});
|
|
3626
|
-
return params;
|
|
3627
|
-
}
|
|
3628
|
-
|
|
3629
3740
|
function isEqual(a, b) {
|
|
3741
|
+
if (a === b)
|
|
3742
|
+
return true;
|
|
3743
|
+
if (typeof a === 'number' && typeof b === 'number')
|
|
3744
|
+
return Object.is(a, b);
|
|
3745
|
+
if (a == null || b == null)
|
|
3746
|
+
return false;
|
|
3747
|
+
if (typeof a !== 'object' || typeof b !== 'object')
|
|
3748
|
+
return Object.is(a, b);
|
|
3630
3749
|
return isEqualInternal(a, b, new WeakMap(), new WeakMap());
|
|
3631
3750
|
}
|
|
3632
3751
|
function isEqualInternal(a, b, seenA, seenB) {
|
|
@@ -3788,6 +3907,22 @@ function memoize(fn, resolverOrOptions) {
|
|
|
3788
3907
|
function normalizeFieldsArray(fields) {
|
|
3789
3908
|
return Array.isArray(fields) ? [...fields] : Object.values(fields);
|
|
3790
3909
|
}
|
|
3910
|
+
function getChangedKeysWithin(previous, current, keys) {
|
|
3911
|
+
const changed = new Set();
|
|
3912
|
+
if (keys.size === 0)
|
|
3913
|
+
return changed;
|
|
3914
|
+
const before = previous ?? {};
|
|
3915
|
+
const after = current ?? {};
|
|
3916
|
+
for (const key of keys) {
|
|
3917
|
+
const inBefore = key in before;
|
|
3918
|
+
const inAfter = key in after;
|
|
3919
|
+
if (!inBefore && !inAfter)
|
|
3920
|
+
continue;
|
|
3921
|
+
if (inBefore !== inAfter || !isEqual(before[key], after[key]))
|
|
3922
|
+
changed.add(key);
|
|
3923
|
+
}
|
|
3924
|
+
return changed;
|
|
3925
|
+
}
|
|
3791
3926
|
function getChangedKeys(previous, current) {
|
|
3792
3927
|
const changedKeys = new Set();
|
|
3793
3928
|
if (!previous && !current)
|
|
@@ -3820,7 +3955,29 @@ function createWarningTracker() {
|
|
|
3820
3955
|
return { warnedKeys: new Set() };
|
|
3821
3956
|
}
|
|
3822
3957
|
|
|
3958
|
+
class FieldErrorsWrapperBase {
|
|
3959
|
+
fieldComponent = viewChild.required('fieldComponent', { read: ViewContainerRef });
|
|
3960
|
+
validationMessages = input(/* @ts-ignore */
|
|
3961
|
+
...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : /* istanbul ignore next */ []));
|
|
3962
|
+
fieldInputs = input(/* @ts-ignore */
|
|
3963
|
+
...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
|
|
3964
|
+
claimedKey = computed(() => this.fieldInputs()?.key, /* @ts-ignore */
|
|
3965
|
+
...(ngDevMode ? [{ debugName: "claimedKey" }] : /* istanbul ignore next */ []));
|
|
3966
|
+
ngf = injectFieldErrors({
|
|
3967
|
+
fieldInputs: this.fieldInputs,
|
|
3968
|
+
validationMessages: this.validationMessages,
|
|
3969
|
+
});
|
|
3970
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: FieldErrorsWrapperBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3971
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.1", type: FieldErrorsWrapperBase, isStandalone: true, inputs: { validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, fieldInputs: { classPropertyName: "fieldInputs", publicName: "fieldInputs", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "fieldComponent", first: true, predicate: ["fieldComponent"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0 });
|
|
3972
|
+
}
|
|
3973
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: FieldErrorsWrapperBase, decorators: [{
|
|
3974
|
+
type: Directive
|
|
3975
|
+
}], propDecorators: { fieldComponent: [{ type: i0.ViewChild, args: ['fieldComponent', { ...{ read: ViewContainerRef }, isSignal: true }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], fieldInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldInputs", required: false }] }] } });
|
|
3976
|
+
function provideFieldErrorDisplay(wrapper) {
|
|
3977
|
+
return { provide: FIELD_ERROR_DISPLAY, useExisting: forwardRef(wrapper) };
|
|
3978
|
+
}
|
|
3979
|
+
|
|
3823
3980
|
|
|
3824
3981
|
|
|
3825
|
-
export { ADDON_ACTION_HANDLERS, ADDON_ACTION_REGISTRY, ADDON_TYPE_COMPONENT_CACHE, ADDON_TYPE_DEFINITIONS, ADDON_TYPE_REGISTRY, ARRAY_CONTEXT, AsyncConditionFunctionCacheService, ComponentInitializedEvent, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DEFAULT_WRAPPERS, DEPRECATION_WARNING_TRACKER, DF_FIELD_TEMPLATES, DfAddonSlot, DynamicFormError, DynamicFormLogger, DynamicTextPipe, DynamicValueFunctionCacheService, EMIT_FORM_VALUE_ON_EVENTS, EXTERNAL_DATA, EventBus, ExpressionParser, ExpressionParserError, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_ID_PREFIX, FORM_OPTIONS, FieldContextRegistryService, FunctionRegistryService, GROUP_CONTEXT, HTTP_CONDITION_CACHE, HttpConditionCache, HttpConditionFunctionCacheService, INITIALIZATION_TIMEOUT_MS, LogicFunctionCacheService, NoopLogger, READONLY_FIELD_TREE_CACHE, RootFormRegistryService, TokenType, WRAPPER_AUTO_ASSOCIATIONS, WRAPPER_COMPONENT_CACHE, WRAPPER_REGISTRY, applyMetaToElement, applyValidator, applyValidators, arrayFieldMapper, assertNever, baseFieldMapper, buildBaseInputs, buildClassName, compareValues, containerFieldMapper, createAddonActionRegistry, createDebouncedLogicFunction, createDefaultDerivationLogConfig, createDynamicValueFunction, createFieldValueProxy, createFormFieldStateMap, createFormStateLogicFunction, createInitializationTracker, createLogicFunction, createWarningTracker, deepMergeDefaults, derivedFromDeferred, detectFormMode, dynamicTextToObservable, evaluateCondition, evaluateNonFieldDisabled, evaluateNonFieldHidden, extractExpressionDependencies, extractStringDependencies, getArrayLength, getChangedKeys, getFieldValueHandling, getGridClassString, getNestedValue, groupFieldMapper, hasChildFields, hasCrossFieldWhenCondition, hasFormValue, hasNestedProperty, hasTargetProperty, injectAddonTypeRegistry, injectFieldSignalContext, injectFieldsSupportingAddons, injectNonFieldEvaluationContext, interpolateParams, isArrayField, isCheckedField, isContainerField, isCrossFieldBuiltInValidator, isCrossFieldExpression, isCrossFieldSchema, isCrossFieldStateLogic, isCrossFieldValidator, isDerivationLogicConfig, isDisplayOnlyField, isEqual, isFieldBoundContext, isFormStateCondition, isFunctionHttpValidator, isGenericContainerField, isGroupField, isHiddenField, isLeafField, isNonPagedForm, isPageField, isPagedForm, isResourceBasedValidator, isRowField, isSimplifiedArrayField, isStateLogicConfig, isValidNonPagedForm, isValidPagedForm, isValueBearingField, isValueField, isWrapperTypeDefinition, keyBy, mapValues, memoize, normalizeFieldsArray, omit, pageFieldMapper, readFieldStateInfo, resolveDynamicValue, resolveHttpRequest, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, runPresetAction, setupInitializationTracking, shouldLog, textFieldMapper, toReadonlyFieldTree, toReadonlyFieldTreeCached, validatePageNesting, withPreviousValue, writeToFieldValue };
|
|
3982
|
+
export { ADDON_ACTION_HANDLERS, ADDON_ACTION_REGISTRY, ADDON_TYPE_COMPONENT_CACHE, ADDON_TYPE_DEFINITIONS, ADDON_TYPE_REGISTRY, ARRAY_CONTEXT, AsyncConditionFunctionCacheService, ComponentInitializedEvent, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DEFAULT_WRAPPERS, DEPRECATION_WARNING_TRACKER, DF_FIELD_TEMPLATES, DfAddonSlot, DynamicFormError, DynamicFormLogger, DynamicTextPipe, DynamicValueFunctionCacheService, EMIT_FORM_VALUE_ON_EVENTS, EXTERNAL_DATA, EventBus, ExpressionParser, ExpressionParserError, FIELD_ERROR_DISPLAY, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_ID_PREFIX, FORM_OPTIONS, FieldContextRegistryService, FieldErrorsWrapperBase, FunctionRegistryService, GROUP_CONTEXT, HTTP_CONDITION_CACHE, HttpConditionCache, HttpConditionFunctionCacheService, INITIALIZATION_TIMEOUT_MS, LogicFunctionCacheService, NoopLogger, READONLY_FIELD_TREE_CACHE, RootFormRegistryService, TokenType, WRAPPER_AUTO_ASSOCIATIONS, WRAPPER_COMPONENT_CACHE, WRAPPER_REGISTRY, applyMetaToElement, applyValidator, applyValidators, arrayFieldMapper, assertNever, baseFieldMapper, buildBaseInputs, buildClassName, compareValues, containerFieldMapper, createAddonActionRegistry, createDebouncedLogicFunction, createDefaultDerivationLogConfig, createDynamicValueFunction, createFieldValueProxy, createFormFieldStateMap, createFormStateLogicFunction, createInitializationTracker, createLogicFunction, createResolvedErrorsSignal, createWarningTracker, deepMergeDefaults, derivedFromDeferred, detectFormMode, dynamicTextToObservable, evaluateCondition, evaluateNonFieldDisabled, evaluateNonFieldHidden, extractExpressionDependencies, extractStringDependencies, getArrayLength, getChangedKeys, getChangedKeysWithin, getFieldValueHandling, getGridClassString, getNestedValue, groupFieldMapper, hasChildFields, hasCrossFieldWhenCondition, hasFormValue, hasNestedProperty, hasTargetProperty, injectAddonTypeRegistry, injectFieldErrors, injectFieldSignalContext, injectFieldsSupportingAddons, injectNonFieldEvaluationContext, interpolateParams, isArrayField, isCheckedField, isContainerField, isCrossFieldBuiltInValidator, isCrossFieldExpression, isCrossFieldSchema, isCrossFieldStateLogic, isCrossFieldValidator, isDerivationLogicConfig, isDisplayOnlyField, isEqual, isFieldBoundContext, isFormStateCondition, isFunctionHttpValidator, isGenericContainerField, isGroupField, isHiddenField, isLeafField, isNonPagedForm, isPageField, isPagedForm, isResourceBasedValidator, isRowField, isSimplifiedArrayField, isStateLogicConfig, isValidNonPagedForm, isValidPagedForm, isValueBearingField, isValueField, isWrapperTypeDefinition, keyBy, mapValues, memoize, normalizeFieldsArray, omit, pageFieldMapper, provideFieldErrorDisplay, readFieldStateInfo, resolveDynamicValue, resolveHttpRequest, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowError, rowFieldMapper, runPresetAction, setupInitializationTracking, shouldLog, shouldShowErrors, textFieldMapper, toReadonlyFieldTree, toReadonlyFieldTreeCached, validatePageNesting, withPreviousValue, writeToFieldValue };
|
|
3826
3983
|
//# sourceMappingURL=ng-forge-dynamic-forms-internal.mjs.map
|