@xsolla/payment-client-core 0.1.2 → 0.1.4
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/esm2020/lib/core/credit-card/credit-card-settings.interface.mjs +2 -0
- package/esm2020/lib/core/credit-card/credit-card-types.enum.mjs +20 -0
- package/esm2020/lib/core/credit-card/credit-card.interface.mjs +2 -0
- package/esm2020/lib/core/credit-card/credit-card.service.mjs +41 -0
- package/esm2020/lib/core/credit-card/credit-cards-map.const.mjs +36 -0
- package/esm2020/lib/core/credit-card/default-mask.const.mjs +2 -0
- package/esm2020/lib/core/credit-card/four-block-mask.const.mjs +2 -0
- package/esm2020/lib/core/credit-card/ordered-cards-settings.const.mjs +45 -0
- package/esm2020/lib/core/credit-card/types/american-express.mjs +13 -0
- package/esm2020/lib/core/credit-card/types/aura.mjs +15 -0
- package/esm2020/lib/core/credit-card/types/china-union-pay.mjs +12 -0
- package/esm2020/lib/core/credit-card/types/dankort.mjs +15 -0
- package/esm2020/lib/core/credit-card/types/default-card.mjs +13 -0
- package/esm2020/lib/core/credit-card/types/diners-clubs.mjs +13 -0
- package/esm2020/lib/core/credit-card/types/discover.mjs +13 -0
- package/esm2020/lib/core/credit-card/types/elo.mjs +13 -0
- package/esm2020/lib/core/credit-card/types/hipercard.mjs +13 -0
- package/esm2020/lib/core/credit-card/types/jcb.mjs +13 -0
- package/esm2020/lib/core/credit-card/types/maestro.mjs +14 -0
- package/esm2020/lib/core/credit-card/types/mastercard.mjs +16 -0
- package/esm2020/lib/core/credit-card/types/mir.mjs +15 -0
- package/esm2020/lib/core/credit-card/types/naranja.mjs +15 -0
- package/esm2020/lib/core/credit-card/types/postepay.mjs +13 -0
- package/esm2020/lib/core/credit-card/types/visa.mjs +13 -0
- package/esm2020/lib/core/payment/actions/next-action.interface.mjs +1 -1
- package/esm2020/lib/core/payment/actions/next-actions.mjs +1 -3
- package/esm2020/lib/core/payment/actions/show-fields/show-fields.action.token.mjs +3 -2
- package/esm2020/lib/core/payment/credit-card-state/credit-card-state.interface.mjs +2 -0
- package/esm2020/lib/core/payment/credit-card-state/credit-card-state.service.mjs +14 -0
- package/esm2020/lib/core/payment/form/controls/card-number-control.config.mjs +10 -0
- package/esm2020/lib/core/payment/form/converters/card-number.converter.mjs +45 -0
- package/esm2020/lib/core/payment/form/converters/converter.abstract.mjs +8 -6
- package/esm2020/lib/core/payment/form/converters/converters-map.mjs +3 -1
- package/esm2020/lib/core/payment/form/converters/email.converter.mjs +3 -3
- package/esm2020/lib/core/payment/form/converters/zip.converter.mjs +4 -5
- package/esm2020/lib/core/payment/form/field-status.interface.mjs +2 -0
- package/esm2020/lib/core/payment/form/form-fields-status.interface.mjs +2 -0
- package/esm2020/lib/core/payment/form/form.module.mjs +8 -4
- package/esm2020/lib/core/payment/form/input-event.enum.mjs +6 -0
- package/esm2020/lib/core/payment/form/validators/async-validator-fn.type.mjs +2 -0
- package/esm2020/lib/core/payment/form/validators/convert.function.mjs +6 -14
- package/esm2020/lib/core/payment/form/validators/credit-card-min-length.validator.mjs +32 -0
- package/esm2020/lib/core/payment/form/validators/email-validator.mjs +3 -4
- package/esm2020/lib/core/payment/form/validators/is-empty-input-value.function.mjs +4 -0
- package/esm2020/lib/core/payment/form/validators/luhn-formula-validator/luhn-formula.validator.mjs +40 -0
- package/esm2020/lib/core/payment/form/validators/required-validator.mjs +3 -4
- package/esm2020/lib/core/payment/form/validators/validation-error.interface.mjs +1 -1
- package/esm2020/lib/core/payment/form/validators/validators.module.mjs +18 -0
- package/esm2020/lib/core/payment/payment.interface.mjs +1 -1
- package/esm2020/lib/core/payment/payment.service.mjs +57 -46
- package/esm2020/lib/core/payment/sync/field-async-validation.interface.mjs +2 -0
- package/esm2020/lib/core/payment/sync/sync-response.class.mjs +7 -4
- package/esm2020/lib/core/payment/sync/sync.service.mjs +14 -11
- package/esm2020/lib/core/payment/xps-response.interface.mjs +1 -1
- package/esm2020/lib/core/type-guards/is-string.function.mjs +4 -0
- package/esm2020/lib/core-library.service.mjs +20 -7
- package/fesm2015/xsolla-payment-client-core.mjs +559 -120
- package/fesm2015/xsolla-payment-client-core.mjs.map +1 -1
- package/fesm2020/xsolla-payment-client-core.mjs +558 -119
- package/fesm2020/xsolla-payment-client-core.mjs.map +1 -1
- package/lib/core/credit-card/credit-card-settings.interface.d.ts +10 -0
- package/lib/core/credit-card/credit-card-types.enum.d.ts +18 -0
- package/lib/core/credit-card/credit-card.interface.d.ts +9 -0
- package/lib/core/credit-card/credit-card.service.d.ts +11 -0
- package/lib/core/credit-card/credit-cards-map.const.d.ts +5 -0
- package/lib/core/credit-card/default-mask.const.d.ts +1 -0
- package/lib/core/credit-card/four-block-mask.const.d.ts +1 -0
- package/lib/core/credit-card/ordered-cards-settings.const.d.ts +12 -0
- package/lib/core/credit-card/types/american-express.d.ts +2 -0
- package/lib/core/credit-card/types/aura.d.ts +2 -0
- package/lib/core/credit-card/types/china-union-pay.d.ts +2 -0
- package/lib/core/credit-card/types/dankort.d.ts +2 -0
- package/lib/core/credit-card/types/default-card.d.ts +2 -0
- package/lib/core/credit-card/types/diners-clubs.d.ts +2 -0
- package/lib/core/credit-card/types/discover.d.ts +2 -0
- package/lib/core/credit-card/types/elo.d.ts +2 -0
- package/lib/core/credit-card/types/hipercard.d.ts +2 -0
- package/lib/core/credit-card/types/jcb.d.ts +2 -0
- package/lib/core/credit-card/types/maestro.d.ts +2 -0
- package/lib/core/credit-card/types/mastercard.d.ts +2 -0
- package/lib/core/credit-card/types/mir.d.ts +2 -0
- package/lib/core/credit-card/types/naranja.d.ts +2 -0
- package/lib/core/credit-card/types/postepay.d.ts +2 -0
- package/lib/core/credit-card/types/visa.d.ts +2 -0
- package/lib/core/payment/actions/next-action.interface.d.ts +1 -2
- package/lib/core/payment/credit-card-state/credit-card-state.interface.d.ts +3 -0
- package/lib/core/payment/credit-card-state/credit-card-state.service.d.ts +7 -0
- package/lib/core/payment/form/controls/card-number-control.config.d.ts +11 -0
- package/lib/core/payment/form/converters/card-number.converter.d.ts +19 -0
- package/lib/core/payment/form/converters/converter.abstract.d.ts +4 -1
- package/lib/core/payment/form/converters/email.converter.d.ts +1 -1
- package/lib/core/payment/form/field-status.interface.d.ts +7 -0
- package/lib/core/payment/form/form-fields-status.interface.d.ts +4 -0
- package/lib/core/payment/form/form.module.d.ts +2 -1
- package/lib/core/payment/form/validators/async-validator-fn.type.d.ts +4 -0
- package/lib/core/payment/form/validators/convert.function.d.ts +1 -1
- package/lib/core/payment/form/validators/credit-card-min-length.validator.d.ts +12 -0
- package/lib/core/payment/form/validators/email-validator.d.ts +1 -1
- package/lib/core/payment/form/validators/is-empty-input-value.function.d.ts +1 -0
- package/lib/core/payment/form/validators/luhn-formula-validator/luhn-formula.validator.d.ts +6 -0
- package/lib/core/payment/form/validators/required-validator.d.ts +1 -1
- package/lib/core/payment/form/validators/validation-error.interface.d.ts +0 -1
- package/lib/core/payment/form/validators/validators.module.d.ts +7 -0
- package/lib/core/payment/payment.interface.d.ts +3 -1
- package/lib/core/payment/payment.service.d.ts +12 -4
- package/lib/core/payment/sync/field-async-validation.interface.d.ts +7 -0
- package/lib/core/payment/sync/sync-response.class.d.ts +2 -4
- package/lib/core/payment/sync/sync.service.d.ts +4 -0
- package/lib/core/payment/xps-response.interface.d.ts +1 -0
- package/lib/core/type-guards/is-string.function.d.ts +1 -0
- package/lib/core-library.service.d.ts +10 -1
- package/package.json +1 -1
- package/xsolla-payment-client-core-0.1.4.tgz +0 -0
- package/esm2020/lib/core/payment/actions/show-field-state/show-field-state.action.class.mjs +0 -12
- package/esm2020/lib/core/payment/actions/show-field-state/show-field-state.action.token.mjs +0 -13
- package/esm2020/lib/core/payment/actions/show-field-state/show-field-state.action.type.mjs +0 -2
- package/esm2020/lib/core/payment/form/input-events.enum.mjs +0 -6
- package/esm2020/lib/core/payment/form/validators/errors-codes.enum.mjs +0 -8
- package/esm2020/lib/core/payment/show-field-state.interface.mjs +0 -2
- package/lib/core/payment/actions/show-field-state/show-field-state.action.class.d.ts +0 -8
- package/lib/core/payment/actions/show-field-state/show-field-state.action.token.d.ts +0 -4
- package/lib/core/payment/actions/show-field-state/show-field-state.action.type.d.ts +0 -11
- package/lib/core/payment/form/validators/errors-codes.enum.d.ts +0 -6
- package/lib/core/payment/show-field-state.interface.d.ts +0 -8
- package/xsolla-payment-client-core-0.1.2.tgz +0 -0
- /package/lib/core/payment/form/{input-events.enum.d.ts → input-event.enum.d.ts} +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { InjectionToken, Injectable, Inject, isDevMode, NgModule } from '@angular/core';
|
|
3
|
-
import { firstValueFrom, lastValueFrom, map, Subject, tap, BehaviorSubject, filter as filter$1, takeUntil, skip,
|
|
3
|
+
import { firstValueFrom, lastValueFrom, map, Subject, tap, BehaviorSubject, filter as filter$1, takeUntil, skip, throwError } from 'rxjs';
|
|
4
4
|
import * as i1 from '@angular/common/http';
|
|
5
5
|
import { HttpParams, HttpHeaders, HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
6
6
|
import { UntypedFormGroup, Validators, UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
|
|
7
7
|
import { filter, map as map$1, catchError } from 'rxjs/operators';
|
|
8
8
|
import * as i1$1 from '@angular/router';
|
|
9
|
+
import { CommonModule } from '@angular/common';
|
|
9
10
|
|
|
10
11
|
const masksFunctionsMap = {
|
|
11
12
|
zip: () => {
|
|
@@ -573,18 +574,6 @@ const isSubmitResponse = (value) => {
|
|
|
573
574
|
return value instanceof SubmitResponse;
|
|
574
575
|
};
|
|
575
576
|
|
|
576
|
-
class ShowFieldStateAction {
|
|
577
|
-
constructor(control) {
|
|
578
|
-
this.type = 'show_field_state';
|
|
579
|
-
this.data = {
|
|
580
|
-
fieldName: control.fieldName,
|
|
581
|
-
fieldState: control.fieldState,
|
|
582
|
-
error: control.error,
|
|
583
|
-
isFocused: control.isFocused,
|
|
584
|
-
};
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
|
|
588
577
|
var InputEventName;
|
|
589
578
|
(function (InputEventName) {
|
|
590
579
|
InputEventName["blur"] = "blur";
|
|
@@ -671,7 +660,8 @@ const showFieldsActionFactoryProvider = {
|
|
|
671
660
|
useValue: {
|
|
672
661
|
factory: (...args) => new ShowFieldsAction(...args),
|
|
673
662
|
isSuitable: (response) => {
|
|
674
|
-
return response.currentCommand === XpsCommand.check
|
|
663
|
+
return (response.currentCommand === XpsCommand.check ||
|
|
664
|
+
response.currentCommand === XpsCommand.form);
|
|
675
665
|
},
|
|
676
666
|
},
|
|
677
667
|
};
|
|
@@ -769,17 +759,6 @@ const showErrorsActionFactoryProvider = {
|
|
|
769
759
|
},
|
|
770
760
|
};
|
|
771
761
|
|
|
772
|
-
const showFieldStateActionFactoryToken = new InjectionToken('ShowFieldStateAction');
|
|
773
|
-
const showFieldStateActionFactoryProvider = {
|
|
774
|
-
provide: showFieldStateActionFactoryToken,
|
|
775
|
-
useValue: {
|
|
776
|
-
factory: (...args) => new ShowFieldStateAction(...args),
|
|
777
|
-
isSuitable: () => {
|
|
778
|
-
return true;
|
|
779
|
-
},
|
|
780
|
-
},
|
|
781
|
-
};
|
|
782
|
-
|
|
783
762
|
const nextActionsToken = new InjectionToken('Action');
|
|
784
763
|
const nextActions = [
|
|
785
764
|
showFieldsActionFactoryProvider,
|
|
@@ -789,7 +768,6 @@ const nextActions = [
|
|
|
789
768
|
const flowUpdateNextActions = [
|
|
790
769
|
statusUpdatedActionFactoryProvider,
|
|
791
770
|
showErrorsActionFactoryProvider,
|
|
792
|
-
showFieldStateActionFactoryProvider,
|
|
793
771
|
];
|
|
794
772
|
|
|
795
773
|
class NextActionService {
|
|
@@ -1217,11 +1195,14 @@ const syncRequestFactoryProvider = {
|
|
|
1217
1195
|
|
|
1218
1196
|
class SyncResponse {
|
|
1219
1197
|
constructor(changedField, response) {
|
|
1198
|
+
this.error = null;
|
|
1220
1199
|
const fieldError = response?.errors?.find((error) => error.element_name === changedField.name);
|
|
1221
1200
|
if (fieldError) {
|
|
1222
|
-
this.
|
|
1223
|
-
|
|
1224
|
-
|
|
1201
|
+
this.error = {
|
|
1202
|
+
asyncError: {
|
|
1203
|
+
code: fieldError.code,
|
|
1204
|
+
message: fieldError.message,
|
|
1205
|
+
},
|
|
1225
1206
|
};
|
|
1226
1207
|
}
|
|
1227
1208
|
this.fields = Object.keys(response.form).map((key) => response.form[key]);
|
|
@@ -1247,6 +1228,10 @@ class SyncService extends EmitDataService {
|
|
|
1247
1228
|
this.prevFieldSyncStates = {};
|
|
1248
1229
|
this.form = new UntypedFormGroup({});
|
|
1249
1230
|
this.fields = [];
|
|
1231
|
+
this.fieldAsyncValidation = new Subject();
|
|
1232
|
+
}
|
|
1233
|
+
get fieldAsyncValidation$() {
|
|
1234
|
+
return this.fieldAsyncValidation.asObservable();
|
|
1250
1235
|
}
|
|
1251
1236
|
setup(form, fields) {
|
|
1252
1237
|
this.reset();
|
|
@@ -1271,24 +1256,23 @@ class SyncService extends EmitDataService {
|
|
|
1271
1256
|
}
|
|
1272
1257
|
if (prevFieldState && value === prevFieldState.value) {
|
|
1273
1258
|
return Promise.resolve(prevFieldState.result).then((response) => {
|
|
1274
|
-
return response?.
|
|
1259
|
+
return response?.error ?? null;
|
|
1275
1260
|
});
|
|
1276
1261
|
}
|
|
1277
1262
|
const requestPromise = this.request(field);
|
|
1278
1263
|
this.setPrevFieldSyncState(field, value, requestPromise);
|
|
1279
1264
|
return requestPromise.then((response) => {
|
|
1280
|
-
|
|
1265
|
+
this.fieldAsyncValidation.next({
|
|
1266
|
+
value,
|
|
1267
|
+
field,
|
|
1268
|
+
response,
|
|
1269
|
+
});
|
|
1270
|
+
return response.error ?? null;
|
|
1281
1271
|
});
|
|
1282
1272
|
}
|
|
1283
1273
|
getSyncValidationErrors(field) {
|
|
1284
1274
|
const control = this.form.get(field.name);
|
|
1285
|
-
|
|
1286
|
-
return null;
|
|
1287
|
-
}
|
|
1288
|
-
const rewritableError = control.errors?.rewritableError;
|
|
1289
|
-
return rewritableError
|
|
1290
|
-
? { message: rewritableError.message, code: rewritableError.code }
|
|
1291
|
-
: null;
|
|
1275
|
+
return control?.errors ?? null;
|
|
1292
1276
|
}
|
|
1293
1277
|
async request(field) {
|
|
1294
1278
|
const requestParams = this.requestFactory({
|
|
@@ -1348,44 +1332,28 @@ class TextControlConfig extends ControlConfig {
|
|
|
1348
1332
|
}
|
|
1349
1333
|
}
|
|
1350
1334
|
|
|
1351
|
-
function convert(validator, message
|
|
1335
|
+
function convert(validator, message) {
|
|
1352
1336
|
return (control) => {
|
|
1353
1337
|
const errors = validator(control);
|
|
1354
1338
|
if (!errors) {
|
|
1355
1339
|
return errors;
|
|
1356
1340
|
}
|
|
1357
1341
|
const firstErrorKey = Object.keys(errors)[0];
|
|
1358
|
-
|
|
1359
|
-
error = typeof
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
rewritableError.code = errorCode;
|
|
1363
|
-
if (error[firstErrorKey] != null) {
|
|
1364
|
-
rewritableError.value = error[firstErrorKey];
|
|
1365
|
-
}
|
|
1366
|
-
if (rewritableError.requiredLength) {
|
|
1367
|
-
rewritableError.number = rewritableError.requiredLength;
|
|
1368
|
-
}
|
|
1369
|
-
errors.rewritableError = rewritableError;
|
|
1342
|
+
const firstError = errors[firstErrorKey];
|
|
1343
|
+
const error = typeof firstError === 'object' && firstError !== null ? firstError : {};
|
|
1344
|
+
error.message = message;
|
|
1345
|
+
errors[firstErrorKey] = error;
|
|
1370
1346
|
return errors;
|
|
1371
1347
|
};
|
|
1372
1348
|
}
|
|
1373
1349
|
|
|
1374
|
-
var ErrorsCodes;
|
|
1375
|
-
(function (ErrorsCodes) {
|
|
1376
|
-
ErrorsCodes["minLength"] = "min-length";
|
|
1377
|
-
ErrorsCodes["maxLength"] = "max-length";
|
|
1378
|
-
ErrorsCodes["invalidValue"] = "invalid-value";
|
|
1379
|
-
ErrorsCodes["required"] = "required";
|
|
1380
|
-
})(ErrorsCodes || (ErrorsCodes = {}));
|
|
1381
|
-
|
|
1382
1350
|
const emailRegexp = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i; // eslint-disable-line
|
|
1383
|
-
function
|
|
1384
|
-
return convert(Validators.pattern(emailRegexp), 'Enter a valid email'
|
|
1351
|
+
function convertedEmailValidator() {
|
|
1352
|
+
return convert(Validators.pattern(emailRegexp), 'Enter a valid email');
|
|
1385
1353
|
}
|
|
1386
1354
|
|
|
1387
|
-
function
|
|
1388
|
-
return convert(Validators.required, 'Required'
|
|
1355
|
+
function convertedRequiredValidator() {
|
|
1356
|
+
return convert(Validators.required, 'Required');
|
|
1389
1357
|
}
|
|
1390
1358
|
|
|
1391
1359
|
class Converter {
|
|
@@ -1400,12 +1368,12 @@ class Converter {
|
|
|
1400
1368
|
return config;
|
|
1401
1369
|
}
|
|
1402
1370
|
convertToFormControl(field) {
|
|
1403
|
-
return new UntypedFormControl(this.getValue(field), this.getValidators(field));
|
|
1371
|
+
return new UntypedFormControl(this.getValue(field), this.getValidators(field), this.getAsyncValidators(field));
|
|
1404
1372
|
}
|
|
1405
1373
|
getValidators(field) {
|
|
1406
1374
|
const validators = [];
|
|
1407
1375
|
if (field.isMandatory === "1" /* XpsBoolean.true */) {
|
|
1408
|
-
validators.push(
|
|
1376
|
+
validators.push(convertedRequiredValidator());
|
|
1409
1377
|
}
|
|
1410
1378
|
if (field.regex) {
|
|
1411
1379
|
const match = /^\/(.*)\/([gim]*)$/.exec(field.regex);
|
|
@@ -1414,11 +1382,14 @@ class Converter {
|
|
|
1414
1382
|
const errorMessage = field.validation_error_msg
|
|
1415
1383
|
? field.validation_error_msg
|
|
1416
1384
|
: 'Enter valid data';
|
|
1417
|
-
validators.push(convert(Validators.pattern(pattern), errorMessage
|
|
1385
|
+
validators.push(convert(Validators.pattern(pattern), errorMessage));
|
|
1418
1386
|
}
|
|
1419
1387
|
}
|
|
1420
1388
|
return validators;
|
|
1421
1389
|
}
|
|
1390
|
+
getAsyncValidators(field) {
|
|
1391
|
+
return async () => this.syncService.validate(field);
|
|
1392
|
+
}
|
|
1422
1393
|
createDefaultControlConfig(controlConfigClass, field) {
|
|
1423
1394
|
const config = new controlConfigClass();
|
|
1424
1395
|
this.copyCommonOptions(config, field);
|
|
@@ -1462,7 +1433,7 @@ class EmailConverter extends Converter {
|
|
|
1462
1433
|
super(syncService);
|
|
1463
1434
|
}
|
|
1464
1435
|
getValidators(field) {
|
|
1465
|
-
return super.getValidators(field).concat([
|
|
1436
|
+
return super.getValidators(field).concat([convertedEmailValidator()]);
|
|
1466
1437
|
}
|
|
1467
1438
|
createControlConfig(field) {
|
|
1468
1439
|
const config = this.createDefaultControlConfig(TextControlConfig, field);
|
|
@@ -1503,11 +1474,11 @@ class ZipConverter extends Converter {
|
|
|
1503
1474
|
const validators = super
|
|
1504
1475
|
.getValidators(field)
|
|
1505
1476
|
.concat([
|
|
1506
|
-
convert(Validators.minLength(minLength), `Enter at least ${minLength} characters
|
|
1507
|
-
convert(Validators.maxLength(maxLength), `Enter no more than ${maxLength} characters
|
|
1477
|
+
convert(Validators.minLength(minLength), `Enter at least ${minLength} characters`),
|
|
1478
|
+
convert(Validators.maxLength(maxLength), `Enter no more than ${maxLength} characters`),
|
|
1508
1479
|
]);
|
|
1509
1480
|
if (this.isUsCountry) {
|
|
1510
|
-
validators.push(convert(restrictedValueValidator('00000'), 'Enter a valid ZIP code'
|
|
1481
|
+
validators.push(convert(restrictedValueValidator('00000'), 'Enter a valid ZIP code'));
|
|
1511
1482
|
}
|
|
1512
1483
|
return validators;
|
|
1513
1484
|
}
|
|
@@ -1543,10 +1514,430 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
1543
1514
|
type: Injectable
|
|
1544
1515
|
}], ctorParameters: function () { return [{ type: SyncService }, { type: CountryService }]; } });
|
|
1545
1516
|
|
|
1517
|
+
function isEmptyInputValue(value) {
|
|
1518
|
+
return value == null || value.length === 0;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
function isString(value) {
|
|
1522
|
+
return typeof value === 'string';
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
/**
|
|
1526
|
+
* Checks number match Luhn algorithm.
|
|
1527
|
+
* Based on http://en.wikipedia.org/wiki/Luhn.
|
|
1528
|
+
*/
|
|
1529
|
+
const luhnFormulaValidator = ({ value }) => {
|
|
1530
|
+
if (isEmptyInputValue(value) || !isString(value)) {
|
|
1531
|
+
return null;
|
|
1532
|
+
}
|
|
1533
|
+
const error = {
|
|
1534
|
+
rewritableError: {
|
|
1535
|
+
message: `Enter a valid card number`,
|
|
1536
|
+
},
|
|
1537
|
+
};
|
|
1538
|
+
if (/[^0-9 -]+/.test(value)) {
|
|
1539
|
+
// accept only spaces, digits and dashes
|
|
1540
|
+
return error;
|
|
1541
|
+
}
|
|
1542
|
+
let resultSum = 0;
|
|
1543
|
+
let digit = 0;
|
|
1544
|
+
let isEven = false;
|
|
1545
|
+
const modBase = 10;
|
|
1546
|
+
const digitRadix = 10;
|
|
1547
|
+
const maxNumber = 9;
|
|
1548
|
+
const digits = value.replace(/\D/g, '');
|
|
1549
|
+
// Checks if number match Luhn algorithm
|
|
1550
|
+
// based on http://en.wikipedia.org/wiki/Luhn
|
|
1551
|
+
for (let index = digits.length - 1; index >= 0; index--) {
|
|
1552
|
+
const char = digits.charAt(index);
|
|
1553
|
+
digit = parseInt(char, digitRadix);
|
|
1554
|
+
if (isEven && (digit *= 2) > maxNumber) {
|
|
1555
|
+
digit -= maxNumber;
|
|
1556
|
+
}
|
|
1557
|
+
resultSum += digit;
|
|
1558
|
+
isEven = !isEven;
|
|
1559
|
+
}
|
|
1560
|
+
return resultSum % modBase === 0 ? null : error;
|
|
1561
|
+
};
|
|
1562
|
+
|
|
1563
|
+
class CardNumberConfig extends ControlConfig {
|
|
1564
|
+
constructor() {
|
|
1565
|
+
super(...arguments);
|
|
1566
|
+
this.controlType = 'card-number';
|
|
1567
|
+
this.availableCardTypes = [];
|
|
1568
|
+
this.customError = '';
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
const fourBlockMask = '9999 9999 9999 9999';
|
|
1573
|
+
|
|
1574
|
+
var CreditCardTypes;
|
|
1575
|
+
(function (CreditCardTypes) {
|
|
1576
|
+
CreditCardTypes["DEFAULT"] = "0";
|
|
1577
|
+
CreditCardTypes["VISA"] = "1";
|
|
1578
|
+
CreditCardTypes["MASTERCARD"] = "2";
|
|
1579
|
+
CreditCardTypes["MAESTRO"] = "3";
|
|
1580
|
+
CreditCardTypes["AMERICAN_EXPRESS"] = "4";
|
|
1581
|
+
CreditCardTypes["DINERS_CLUBS"] = "5";
|
|
1582
|
+
CreditCardTypes["DISCOVER"] = "6";
|
|
1583
|
+
CreditCardTypes["JCB"] = "9";
|
|
1584
|
+
CreditCardTypes["DANKORT"] = "11";
|
|
1585
|
+
CreditCardTypes["HIPERCARD"] = "12";
|
|
1586
|
+
CreditCardTypes["ELO"] = "13";
|
|
1587
|
+
CreditCardTypes["AURA"] = "14";
|
|
1588
|
+
CreditCardTypes["NARANJA"] = "15";
|
|
1589
|
+
CreditCardTypes["MIR"] = "16";
|
|
1590
|
+
CreditCardTypes["CHINA_UNION_PAY"] = "17";
|
|
1591
|
+
CreditCardTypes["POSTEPAY"] = "18";
|
|
1592
|
+
})(CreditCardTypes || (CreditCardTypes = {}));
|
|
1593
|
+
|
|
1594
|
+
const visa = {
|
|
1595
|
+
id: CreditCardTypes.VISA,
|
|
1596
|
+
minLength: 13,
|
|
1597
|
+
maxLength: 16,
|
|
1598
|
+
iconName: 'visa',
|
|
1599
|
+
mask: fourBlockMask,
|
|
1600
|
+
checkNumber(number) {
|
|
1601
|
+
return number.startsWith('4');
|
|
1602
|
+
},
|
|
1603
|
+
};
|
|
1604
|
+
|
|
1605
|
+
const mastercard = {
|
|
1606
|
+
id: CreditCardTypes.MASTERCARD,
|
|
1607
|
+
minLength: 16,
|
|
1608
|
+
maxLength: 16,
|
|
1609
|
+
iconName: 'mastercard',
|
|
1610
|
+
mask: fourBlockMask,
|
|
1611
|
+
checkNumber(number) {
|
|
1612
|
+
const subLength = 6;
|
|
1613
|
+
const cardNumberSub = number.substring(0, subLength);
|
|
1614
|
+
return (new RegExp(/^5[1-5]/).test(number) ||
|
|
1615
|
+
(cardNumberSub >= '222100' && cardNumberSub <= '272099'));
|
|
1616
|
+
},
|
|
1617
|
+
};
|
|
1618
|
+
|
|
1619
|
+
const defaultMask = '9999 9999 9999 9999 999';
|
|
1620
|
+
|
|
1621
|
+
const maestro = {
|
|
1622
|
+
id: CreditCardTypes.MAESTRO,
|
|
1623
|
+
minLength: 12,
|
|
1624
|
+
maxLength: 19,
|
|
1625
|
+
iconName: 'maestro',
|
|
1626
|
+
mask: defaultMask,
|
|
1627
|
+
checkNumber(number) {
|
|
1628
|
+
return new RegExp(/^(5018)|^(5020)|^(5038)|^(5893)|^(6304)|^(6759)|^(6761)|^(6762)|^(6763)|^(0604)|^(6706)|^(6771)|^(6709)/).test(number);
|
|
1629
|
+
},
|
|
1630
|
+
maxCvvLength: 3,
|
|
1631
|
+
};
|
|
1632
|
+
|
|
1633
|
+
const americanExpress = {
|
|
1634
|
+
id: CreditCardTypes.AMERICAN_EXPRESS,
|
|
1635
|
+
minLength: 15,
|
|
1636
|
+
maxLength: 15,
|
|
1637
|
+
iconName: 'american-express',
|
|
1638
|
+
mask: '9999 999999 99999',
|
|
1639
|
+
checkNumber(number) {
|
|
1640
|
+
return new RegExp(/^(34)|^(37)/).test(number);
|
|
1641
|
+
},
|
|
1642
|
+
maxCvvLength: 4,
|
|
1643
|
+
};
|
|
1644
|
+
|
|
1645
|
+
const dinersClubs = {
|
|
1646
|
+
id: CreditCardTypes.DINERS_CLUBS,
|
|
1647
|
+
minLength: 14,
|
|
1648
|
+
maxLength: 14,
|
|
1649
|
+
iconName: 'dinersclub',
|
|
1650
|
+
mask: '9999 9999 9999 99',
|
|
1651
|
+
checkNumber(number) {
|
|
1652
|
+
const regex = /^(36[0-9]|3(?:0[0-59]|[68][0-9])[0-9])/;
|
|
1653
|
+
return regex.test(number);
|
|
1654
|
+
},
|
|
1655
|
+
};
|
|
1656
|
+
|
|
1657
|
+
const discover = {
|
|
1658
|
+
id: CreditCardTypes.DISCOVER,
|
|
1659
|
+
minLength: 16,
|
|
1660
|
+
maxLength: 19,
|
|
1661
|
+
iconName: 'discover',
|
|
1662
|
+
mask: defaultMask,
|
|
1663
|
+
checkNumber(number) {
|
|
1664
|
+
return new RegExp(/^(6011)|^(622(1(2[6-9]|[3-9][0-9])|[2-8][0-9]{2}|9([01][0-9]|2[0-5])))|^(64[4-9])|^65/).test(number);
|
|
1665
|
+
},
|
|
1666
|
+
};
|
|
1667
|
+
|
|
1668
|
+
const jcb = {
|
|
1669
|
+
id: CreditCardTypes.JCB,
|
|
1670
|
+
minLength: 15,
|
|
1671
|
+
maxLength: 16,
|
|
1672
|
+
iconName: 'jcb',
|
|
1673
|
+
mask: fourBlockMask,
|
|
1674
|
+
checkNumber(number) {
|
|
1675
|
+
return new RegExp(/^35(2[89]|[3-8][0-9])/).test(number);
|
|
1676
|
+
},
|
|
1677
|
+
};
|
|
1678
|
+
|
|
1679
|
+
const dankort = {
|
|
1680
|
+
id: CreditCardTypes.DANKORT,
|
|
1681
|
+
minLength: 16,
|
|
1682
|
+
maxLength: 16,
|
|
1683
|
+
iconName: 'dankort',
|
|
1684
|
+
mask: fourBlockMask,
|
|
1685
|
+
checkNumber(number) {
|
|
1686
|
+
const subLength = 4;
|
|
1687
|
+
const cardNumberSub = number.substring(0, subLength);
|
|
1688
|
+
return cardNumberSub === '5019';
|
|
1689
|
+
},
|
|
1690
|
+
};
|
|
1691
|
+
|
|
1692
|
+
const hipercard = {
|
|
1693
|
+
id: CreditCardTypes.HIPERCARD,
|
|
1694
|
+
minLength: 13,
|
|
1695
|
+
maxLength: 19,
|
|
1696
|
+
iconName: 'hipercard',
|
|
1697
|
+
mask: defaultMask,
|
|
1698
|
+
checkNumber(number) {
|
|
1699
|
+
return new RegExp(/^((606282|637095|637568)[0-9]|38[0-9]{14,17})/).test(number);
|
|
1700
|
+
},
|
|
1701
|
+
};
|
|
1702
|
+
|
|
1703
|
+
const elo = {
|
|
1704
|
+
id: CreditCardTypes.ELO,
|
|
1705
|
+
minLength: 16,
|
|
1706
|
+
maxLength: 19,
|
|
1707
|
+
iconName: 'elo',
|
|
1708
|
+
mask: defaultMask,
|
|
1709
|
+
checkNumber(number) {
|
|
1710
|
+
return new RegExp(/^(40117[8-9]|431274|438935|451416|457393|45763[1-2]|506(699|7[0-6][0-9]|77[0-8])|509\d{3}|504175|627780|636297|636368|65003[1-3]|6500(3[5-9]|4[0-9]|5[0-1])|6504(0[5-9]|[1-3][0-9])|650(4[8-9][0-9]|5[0-2][0-9]|53[0-8])|6505(4[1-9]|[5-8][0-9]|9[0-8])|6507(0[0-9]|1[0-8])|65072[0-7]|6509(0[1-9]|1[0-9]|20)|6516(5[2-9]|[6-7][0-9])|6550([0-1][0-9]|2[1-9]|[3-4][0-9]|5[0-8]))/).test(number);
|
|
1711
|
+
},
|
|
1712
|
+
};
|
|
1713
|
+
|
|
1714
|
+
const aura = {
|
|
1715
|
+
id: CreditCardTypes.AURA,
|
|
1716
|
+
minLength: 16,
|
|
1717
|
+
maxLength: 19,
|
|
1718
|
+
iconName: 'aura',
|
|
1719
|
+
mask: defaultMask,
|
|
1720
|
+
checkNumber(number) {
|
|
1721
|
+
const subLength = 8;
|
|
1722
|
+
const cardNumberSub = number.substring(0, subLength);
|
|
1723
|
+
return ['50786000', '50786018', '50786019'].includes(cardNumberSub);
|
|
1724
|
+
},
|
|
1725
|
+
};
|
|
1726
|
+
|
|
1727
|
+
const naranja = {
|
|
1728
|
+
id: CreditCardTypes.NARANJA,
|
|
1729
|
+
minLength: 12,
|
|
1730
|
+
maxLength: 19,
|
|
1731
|
+
iconName: 'naranja',
|
|
1732
|
+
mask: defaultMask,
|
|
1733
|
+
checkNumber(number) {
|
|
1734
|
+
const subLength = 6;
|
|
1735
|
+
const cardNumberSub = number.substring(0, subLength);
|
|
1736
|
+
return cardNumberSub === '589562';
|
|
1737
|
+
},
|
|
1738
|
+
};
|
|
1739
|
+
|
|
1740
|
+
const mir = {
|
|
1741
|
+
id: CreditCardTypes.MIR,
|
|
1742
|
+
minLength: 16,
|
|
1743
|
+
maxLength: 16,
|
|
1744
|
+
iconName: 'mir',
|
|
1745
|
+
mask: defaultMask,
|
|
1746
|
+
checkNumber(number) {
|
|
1747
|
+
const subLength = 4;
|
|
1748
|
+
const cardNumberSub = number.substring(0, subLength);
|
|
1749
|
+
return cardNumberSub >= '2200' && cardNumberSub <= '2204';
|
|
1750
|
+
},
|
|
1751
|
+
};
|
|
1752
|
+
|
|
1753
|
+
const chinaUnionPay = {
|
|
1754
|
+
id: CreditCardTypes.CHINA_UNION_PAY,
|
|
1755
|
+
minLength: 16,
|
|
1756
|
+
maxLength: 19,
|
|
1757
|
+
iconName: 'unionpay',
|
|
1758
|
+
mask: '999 9999 9999 99999999',
|
|
1759
|
+
checkNumber(number) {
|
|
1760
|
+
return number.startsWith('62');
|
|
1761
|
+
},
|
|
1762
|
+
};
|
|
1763
|
+
|
|
1764
|
+
const defaultCard = {
|
|
1765
|
+
id: CreditCardTypes.DEFAULT,
|
|
1766
|
+
minLength: 12,
|
|
1767
|
+
maxLength: 19,
|
|
1768
|
+
iconName: null,
|
|
1769
|
+
mask: defaultMask,
|
|
1770
|
+
checkNumber() {
|
|
1771
|
+
return false;
|
|
1772
|
+
},
|
|
1773
|
+
};
|
|
1774
|
+
|
|
1775
|
+
const postePay = {
|
|
1776
|
+
id: CreditCardTypes.POSTEPAY,
|
|
1777
|
+
minLength: 12,
|
|
1778
|
+
maxLength: 19,
|
|
1779
|
+
iconName: 'poste_pay',
|
|
1780
|
+
mask: '9999 9999 9999 9999 999',
|
|
1781
|
+
checkNumber(number) {
|
|
1782
|
+
const regex = /^(5018)|^(5020)|^(5038)|^(5893)|^(6304)|^(6759)|^(6761)|^(6762)|^(6763)|^(0604)|^(6706)|^(6771)|^(6709)/;
|
|
1783
|
+
return regex.test(number);
|
|
1784
|
+
},
|
|
1785
|
+
};
|
|
1786
|
+
|
|
1787
|
+
/**
|
|
1788
|
+
* order does matter
|
|
1789
|
+
* settings with more specific pattern should be placed above
|
|
1790
|
+
* Example:
|
|
1791
|
+
* - 12*
|
|
1792
|
+
* - 12
|
|
1793
|
+
* - 1
|
|
1794
|
+
* "12*" pattern should be checked first, otherwise pattern "1" will be taken
|
|
1795
|
+
* before "12*" checked
|
|
1796
|
+
*/
|
|
1797
|
+
const orderedCardSettings = [
|
|
1798
|
+
aura,
|
|
1799
|
+
naranja,
|
|
1800
|
+
maestro,
|
|
1801
|
+
postePay,
|
|
1802
|
+
elo,
|
|
1803
|
+
discover,
|
|
1804
|
+
dankort,
|
|
1805
|
+
hipercard,
|
|
1806
|
+
mir,
|
|
1807
|
+
jcb,
|
|
1808
|
+
dinersClubs,
|
|
1809
|
+
americanExpress,
|
|
1810
|
+
mastercard,
|
|
1811
|
+
chinaUnionPay,
|
|
1812
|
+
visa,
|
|
1813
|
+
defaultCard,
|
|
1814
|
+
];
|
|
1815
|
+
|
|
1816
|
+
const creditCardsMap = {
|
|
1817
|
+
[CreditCardTypes.DEFAULT]: defaultCard,
|
|
1818
|
+
[CreditCardTypes.VISA]: visa,
|
|
1819
|
+
[CreditCardTypes.MASTERCARD]: mastercard,
|
|
1820
|
+
[CreditCardTypes.MAESTRO]: maestro,
|
|
1821
|
+
[CreditCardTypes.AMERICAN_EXPRESS]: americanExpress,
|
|
1822
|
+
[CreditCardTypes.DINERS_CLUBS]: dinersClubs,
|
|
1823
|
+
[CreditCardTypes.DISCOVER]: discover,
|
|
1824
|
+
[CreditCardTypes.JCB]: jcb,
|
|
1825
|
+
[CreditCardTypes.DANKORT]: dankort,
|
|
1826
|
+
[CreditCardTypes.HIPERCARD]: hipercard,
|
|
1827
|
+
[CreditCardTypes.ELO]: elo,
|
|
1828
|
+
[CreditCardTypes.AURA]: aura,
|
|
1829
|
+
[CreditCardTypes.NARANJA]: naranja,
|
|
1830
|
+
[CreditCardTypes.MIR]: mir,
|
|
1831
|
+
[CreditCardTypes.CHINA_UNION_PAY]: chinaUnionPay,
|
|
1832
|
+
[CreditCardTypes.POSTEPAY]: postePay,
|
|
1833
|
+
};
|
|
1834
|
+
|
|
1835
|
+
class CreditCardService {
|
|
1836
|
+
getBinNumber(cardNumber) {
|
|
1837
|
+
const binNumberLength = 6;
|
|
1838
|
+
return cardNumber.replace(/\s+/g, '').substring(0, binNumberLength);
|
|
1839
|
+
}
|
|
1840
|
+
getAccountSuffix(cardNumber) {
|
|
1841
|
+
const accountSuffixLength = 4;
|
|
1842
|
+
return cardNumber
|
|
1843
|
+
.replace(/\s+/g, '')
|
|
1844
|
+
.substring(cardNumber.length - accountSuffixLength);
|
|
1845
|
+
}
|
|
1846
|
+
getTypeByNumber(cardNumber) {
|
|
1847
|
+
cardNumber = cardNumber.replace(/\s+/g, '');
|
|
1848
|
+
const cardSettings = orderedCardSettings.find((settings) => {
|
|
1849
|
+
const isNumberMatched = settings.checkNumber(cardNumber);
|
|
1850
|
+
return isNumberMatched ? settings.id : false;
|
|
1851
|
+
});
|
|
1852
|
+
return cardSettings ? cardSettings.id : defaultCard.id;
|
|
1853
|
+
}
|
|
1854
|
+
getCreditCardSettings(cardType) {
|
|
1855
|
+
const creditCard = creditCardsMap[cardType];
|
|
1856
|
+
if (!creditCard) {
|
|
1857
|
+
return defaultCard;
|
|
1858
|
+
}
|
|
1859
|
+
return creditCard;
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
CreditCardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1863
|
+
CreditCardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, providedIn: 'root' });
|
|
1864
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, decorators: [{
|
|
1865
|
+
type: Injectable,
|
|
1866
|
+
args: [{
|
|
1867
|
+
providedIn: 'root',
|
|
1868
|
+
}]
|
|
1869
|
+
}] });
|
|
1870
|
+
|
|
1871
|
+
class CreditCardMinLengthValidator {
|
|
1872
|
+
constructor(creditService) {
|
|
1873
|
+
this.creditService = creditService;
|
|
1874
|
+
this.validate = (field) => {
|
|
1875
|
+
if (isEmptyInputValue(field.value) || !isString(field.value)) {
|
|
1876
|
+
return null;
|
|
1877
|
+
}
|
|
1878
|
+
const length = field.value.length;
|
|
1879
|
+
const cardType = this.creditService.getTypeByNumber(field.value);
|
|
1880
|
+
const { minLength } = this.creditService.getCreditCardSettings(cardType);
|
|
1881
|
+
return length < minLength
|
|
1882
|
+
? {
|
|
1883
|
+
rewritableError: {
|
|
1884
|
+
message: `Enter at least ${minLength} characters`,
|
|
1885
|
+
number: minLength,
|
|
1886
|
+
},
|
|
1887
|
+
}
|
|
1888
|
+
: null;
|
|
1889
|
+
};
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
CreditCardMinLengthValidator.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator, deps: [{ token: CreditCardService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1893
|
+
CreditCardMinLengthValidator.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator });
|
|
1894
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator, decorators: [{
|
|
1895
|
+
type: Injectable
|
|
1896
|
+
}], ctorParameters: function () { return [{ type: CreditCardService }]; } });
|
|
1897
|
+
|
|
1898
|
+
class CardNumberConverter extends Converter {
|
|
1899
|
+
constructor(syncService, maxLengthValidator, minLengthValidator) {
|
|
1900
|
+
super(syncService);
|
|
1901
|
+
this.maxLengthValidator = maxLengthValidator;
|
|
1902
|
+
this.minLengthValidator = minLengthValidator;
|
|
1903
|
+
}
|
|
1904
|
+
getValidators(field) {
|
|
1905
|
+
return super
|
|
1906
|
+
.getValidators(field)
|
|
1907
|
+
.concat([
|
|
1908
|
+
luhnFormulaValidator,
|
|
1909
|
+
this.minLengthValidator.validate,
|
|
1910
|
+
this.maxLengthValidator.validate,
|
|
1911
|
+
]);
|
|
1912
|
+
}
|
|
1913
|
+
createControlConfig(field, formState) {
|
|
1914
|
+
const config = this.createDefaultControlConfig(CardNumberConfig, field);
|
|
1915
|
+
config.placeholder = config.title;
|
|
1916
|
+
config.availableCardTypes =
|
|
1917
|
+
formState?.availableCardTypes ?? [];
|
|
1918
|
+
config.activeCardType = formState?.activeCardType;
|
|
1919
|
+
config.customError = formState?.customError;
|
|
1920
|
+
config.disabled = formState?.disabled ?? false;
|
|
1921
|
+
return config;
|
|
1922
|
+
}
|
|
1923
|
+
getAutocomplete() {
|
|
1924
|
+
return 'cc-number';
|
|
1925
|
+
}
|
|
1926
|
+
getDataType() {
|
|
1927
|
+
return 'text';
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
CardNumberConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardNumberConverter, deps: [{ token: SyncService }, { token: CreditCardMinLengthValidator }, { token: CreditCardMinLengthValidator }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1931
|
+
CardNumberConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardNumberConverter });
|
|
1932
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardNumberConverter, decorators: [{
|
|
1933
|
+
type: Injectable
|
|
1934
|
+
}], ctorParameters: function () { return [{ type: SyncService }, { type: CreditCardMinLengthValidator }, { type: CreditCardMinLengthValidator }]; } });
|
|
1935
|
+
|
|
1546
1936
|
const convertersMapToken = new InjectionToken('ConvertersTokensMap');
|
|
1547
1937
|
const convertersMap = {
|
|
1548
1938
|
zip: ZipConverter,
|
|
1549
1939
|
email: EmailConverter,
|
|
1940
|
+
card_number: CardNumberConverter,
|
|
1550
1941
|
};
|
|
1551
1942
|
|
|
1552
1943
|
class ControlConfigService {
|
|
@@ -3007,22 +3398,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
3007
3398
|
args: [financeDetailsResponseFactoryToken]
|
|
3008
3399
|
}] }]; } });
|
|
3009
3400
|
|
|
3401
|
+
class CreditCardStateService extends EmitDataService {
|
|
3402
|
+
}
|
|
3403
|
+
CreditCardStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardStateService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
3404
|
+
CreditCardStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardStateService, providedIn: 'root' });
|
|
3405
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardStateService, decorators: [{
|
|
3406
|
+
type: Injectable,
|
|
3407
|
+
args: [{
|
|
3408
|
+
providedIn: 'root',
|
|
3409
|
+
}]
|
|
3410
|
+
}] });
|
|
3411
|
+
|
|
3010
3412
|
class PaymentService {
|
|
3011
|
-
|
|
3413
|
+
get formFieldsStatus$() {
|
|
3414
|
+
return this.formFieldsStatusSubject.asObservable().pipe(filter$1(Boolean));
|
|
3415
|
+
}
|
|
3416
|
+
constructor(initializeService, submitService, syncService, formService, statusService, financeDetailsService, creditCardStateService, nextActionService, controlConfigService) {
|
|
3012
3417
|
this.initializeService = initializeService;
|
|
3013
3418
|
this.submitService = submitService;
|
|
3014
3419
|
this.syncService = syncService;
|
|
3015
3420
|
this.formService = formService;
|
|
3016
3421
|
this.statusService = statusService;
|
|
3017
3422
|
this.financeDetailsService = financeDetailsService;
|
|
3423
|
+
this.creditCardStateService = creditCardStateService;
|
|
3018
3424
|
this.nextActionService = nextActionService;
|
|
3019
3425
|
this.controlConfigService = controlConfigService;
|
|
3020
3426
|
this.form = null;
|
|
3021
3427
|
this.data = null;
|
|
3022
3428
|
this.financeDetails = null;
|
|
3429
|
+
this.focusFieldName = null;
|
|
3023
3430
|
this.fields = [];
|
|
3024
3431
|
this.destroy$ = new Subject();
|
|
3025
3432
|
this.formDestroy$ = new Subject();
|
|
3433
|
+
this.formFieldsStatusSubject = new BehaviorSubject(null);
|
|
3026
3434
|
}
|
|
3027
3435
|
async initialize(config) {
|
|
3028
3436
|
this.destroy$ = new Subject();
|
|
@@ -3032,9 +3440,10 @@ class PaymentService {
|
|
|
3032
3440
|
this.data = await this.initializeService.request(config);
|
|
3033
3441
|
this.fields = this.getFields();
|
|
3034
3442
|
this.form = this.formService.createForm(this.fields);
|
|
3035
|
-
this.listenSyncValidationErrors(this.form);
|
|
3036
|
-
this.emitFinanceDetails(this.data.paymentForm?.summary);
|
|
3037
3443
|
this.setupSyncService(this.form, this.fields);
|
|
3444
|
+
this.listenFormStatusChanges(this.form);
|
|
3445
|
+
this.emitFinanceDetails(this.data.paymentForm?.summary);
|
|
3446
|
+
this.emitFormFieldsStatus(this.form);
|
|
3038
3447
|
return this.fields.filter((field) => field?.isVisible === "1" /* XpsBoolean.true */);
|
|
3039
3448
|
}
|
|
3040
3449
|
async submit() {
|
|
@@ -3043,13 +3452,7 @@ class PaymentService {
|
|
|
3043
3452
|
}
|
|
3044
3453
|
if (!this.form.valid) {
|
|
3045
3454
|
this.form.markAllAsTouched();
|
|
3046
|
-
|
|
3047
|
-
const control = this.form?.get(controlKey);
|
|
3048
|
-
if (control) {
|
|
3049
|
-
const controlObject = this.getControlState(controlKey, control);
|
|
3050
|
-
this.nextActionService.emitFlowUpdates(new ShowFieldStateAction({ ...controlObject, isFocused: true }));
|
|
3051
|
-
}
|
|
3052
|
-
});
|
|
3455
|
+
this.emitFormFieldsStatus(this.form);
|
|
3053
3456
|
return;
|
|
3054
3457
|
}
|
|
3055
3458
|
const submitResponse = await this.submitService.request(this.fields, this.form);
|
|
@@ -3098,22 +3501,22 @@ class PaymentService {
|
|
|
3098
3501
|
}
|
|
3099
3502
|
changeFieldState(name, state) {
|
|
3100
3503
|
const formControl = this.form?.get(name);
|
|
3101
|
-
if (!formControl) {
|
|
3504
|
+
if (!this.form || !formControl) {
|
|
3102
3505
|
return;
|
|
3103
3506
|
}
|
|
3104
|
-
const controlObject = this.getControlState(name, formControl);
|
|
3105
3507
|
switch (state) {
|
|
3106
3508
|
case InputEventName.blur: {
|
|
3107
3509
|
formControl.markAsTouched();
|
|
3108
|
-
this.
|
|
3109
|
-
|
|
3510
|
+
this.focusFieldName = null;
|
|
3511
|
+
break;
|
|
3110
3512
|
}
|
|
3111
3513
|
case InputEventName.focus: {
|
|
3112
3514
|
formControl.markAsUntouched();
|
|
3113
|
-
this.
|
|
3114
|
-
|
|
3515
|
+
this.focusFieldName = name;
|
|
3516
|
+
break;
|
|
3115
3517
|
}
|
|
3116
3518
|
}
|
|
3519
|
+
this.emitFormFieldsStatus(this.form);
|
|
3117
3520
|
}
|
|
3118
3521
|
destroy() {
|
|
3119
3522
|
this.data = null;
|
|
@@ -3126,48 +3529,57 @@ class PaymentService {
|
|
|
3126
3529
|
emitFinanceDetails(summary) {
|
|
3127
3530
|
this.financeDetailsService.emit(summary);
|
|
3128
3531
|
}
|
|
3532
|
+
emitCreditCardState(idCardType) {
|
|
3533
|
+
this.creditCardStateService.emit({ idCardType });
|
|
3534
|
+
}
|
|
3535
|
+
emitFormFieldsStatus(form) {
|
|
3536
|
+
const formFieldsStatus = {};
|
|
3537
|
+
Object.keys(form.controls).forEach((name) => {
|
|
3538
|
+
const control = form.controls[name];
|
|
3539
|
+
formFieldsStatus[name] = {
|
|
3540
|
+
name: name,
|
|
3541
|
+
validationStatus: control.status,
|
|
3542
|
+
errors: control.errors,
|
|
3543
|
+
isFocused: this.focusFieldName === name,
|
|
3544
|
+
};
|
|
3545
|
+
});
|
|
3546
|
+
this.formFieldsStatusSubject.next(formFieldsStatus);
|
|
3547
|
+
}
|
|
3129
3548
|
setupSyncService(form, fields) {
|
|
3130
3549
|
this.syncService.setup(form, fields);
|
|
3131
3550
|
this.syncService.data$
|
|
3132
3551
|
.pipe(takeUntil(this.destroy$))
|
|
3133
|
-
.subscribe((response) =>
|
|
3552
|
+
.subscribe((response) => {
|
|
3553
|
+
this.emitFinanceDetails(response.summary);
|
|
3554
|
+
});
|
|
3555
|
+
this.syncService.fieldAsyncValidation$
|
|
3556
|
+
.pipe(takeUntil(this.destroy$))
|
|
3557
|
+
.subscribe((fieldAsyncValidation) => {
|
|
3558
|
+
switch (fieldAsyncValidation.field.name) {
|
|
3559
|
+
case FieldNames.cardNumber:
|
|
3560
|
+
this.emitCreditCardState(fieldAsyncValidation.response.parameters.idCardType);
|
|
3561
|
+
}
|
|
3562
|
+
});
|
|
3134
3563
|
}
|
|
3135
3564
|
listenFinanceDetails() {
|
|
3136
3565
|
this.financeDetailsService.data$
|
|
3137
3566
|
.pipe(takeUntil(this.destroy$))
|
|
3138
3567
|
.subscribe((financeDetails) => (this.financeDetails = financeDetails));
|
|
3139
3568
|
}
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
control.statusChanges
|
|
3145
|
-
.pipe(distinctUntilChanged(), takeUntil(this.formDestroy$))
|
|
3146
|
-
.subscribe((status) => {
|
|
3147
|
-
const controlObject = this.getControlState(key, control, status);
|
|
3148
|
-
this.nextActionService.emitFlowUpdates(new ShowFieldStateAction(controlObject));
|
|
3149
|
-
});
|
|
3150
|
-
}
|
|
3151
|
-
});
|
|
3152
|
-
}
|
|
3153
|
-
getControlState(controlName, controlObject, status) {
|
|
3154
|
-
const controlError = controlObject.errors?.['rewritableError'] ??
|
|
3155
|
-
null;
|
|
3156
|
-
return {
|
|
3157
|
-
fieldName: controlName,
|
|
3158
|
-
fieldState: status ?? controlObject.status,
|
|
3159
|
-
error: controlError,
|
|
3160
|
-
};
|
|
3569
|
+
listenFormStatusChanges(form) {
|
|
3570
|
+
form.statusChanges
|
|
3571
|
+
.pipe(takeUntil(this.formDestroy$))
|
|
3572
|
+
.subscribe(() => this.emitFormFieldsStatus(form));
|
|
3161
3573
|
}
|
|
3162
3574
|
}
|
|
3163
|
-
PaymentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, deps: [{ token: InitializeService }, { token: SubmitService }, { token: SyncService }, { token: FormService }, { token: StatusService }, { token: FinanceDetailsService }, { token: NextActionService }, { token: ControlConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3575
|
+
PaymentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, deps: [{ token: InitializeService }, { token: SubmitService }, { token: SyncService }, { token: FormService }, { token: StatusService }, { token: FinanceDetailsService }, { token: CreditCardStateService }, { token: NextActionService }, { token: ControlConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3164
3576
|
PaymentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, providedIn: 'root' });
|
|
3165
3577
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, decorators: [{
|
|
3166
3578
|
type: Injectable,
|
|
3167
3579
|
args: [{
|
|
3168
3580
|
providedIn: 'root',
|
|
3169
3581
|
}]
|
|
3170
|
-
}], ctorParameters: function () { return [{ type: InitializeService }, { type: SubmitService }, { type: SyncService }, { type: FormService }, { type: StatusService }, { type: FinanceDetailsService }, { type: NextActionService }, { type: ControlConfigService }]; } });
|
|
3582
|
+
}], ctorParameters: function () { return [{ type: InitializeService }, { type: SubmitService }, { type: SyncService }, { type: FormService }, { type: StatusService }, { type: FinanceDetailsService }, { type: CreditCardStateService }, { type: NextActionService }, { type: ControlConfigService }]; } });
|
|
3171
3583
|
|
|
3172
3584
|
class RefundPolicyService {
|
|
3173
3585
|
constructor(settingsService) {
|
|
@@ -3272,7 +3684,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
3272
3684
|
}], ctorParameters: function () { return [{ type: SettingsService }, { type: RefundPolicyService }, { type: SecureConnectionService }, { type: DisclaimerService }]; } });
|
|
3273
3685
|
|
|
3274
3686
|
class CoreLibraryService {
|
|
3275
|
-
constructor(settingsService, countryService, paymentMethodsService, savedMethodsService, userBalanceService, paymentConfigService, paymentService, deviceFingerPrintService, financeDetailsService, legalService, statusService, nextActionService) {
|
|
3687
|
+
constructor(settingsService, countryService, paymentMethodsService, savedMethodsService, userBalanceService, paymentConfigService, paymentService, deviceFingerPrintService, financeDetailsService, legalService, statusService, nextActionService, creditCardService, creditCardStateService) {
|
|
3276
3688
|
this.settingsService = settingsService;
|
|
3277
3689
|
this.countryService = countryService;
|
|
3278
3690
|
this.paymentMethodsService = paymentMethodsService;
|
|
@@ -3285,6 +3697,8 @@ class CoreLibraryService {
|
|
|
3285
3697
|
this.legalService = legalService;
|
|
3286
3698
|
this.statusService = statusService;
|
|
3287
3699
|
this.nextActionService = nextActionService;
|
|
3700
|
+
this.creditCardService = creditCardService;
|
|
3701
|
+
this.creditCardStateService = creditCardStateService;
|
|
3288
3702
|
this.paymentMethods = {
|
|
3289
3703
|
getList: async () => this.paymentMethodsService.getList(),
|
|
3290
3704
|
getQuickMethods: async () => this.paymentMethodsService.getQuickMethods(),
|
|
@@ -3315,14 +3729,23 @@ class CoreLibraryService {
|
|
|
3315
3729
|
flowUpdates$: this.nextActionService.flowUpdates$,
|
|
3316
3730
|
financeDetailsUpdates$: this.financeDetailsService.data$,
|
|
3317
3731
|
form: {
|
|
3732
|
+
fieldsStatus$: this.paymentService.formFieldsStatus$,
|
|
3318
3733
|
getControlConfig: (field) => this.paymentService.getFieldConfig(field),
|
|
3319
3734
|
changeFieldValue: (name, value) => this.paymentService.changeFieldValue(name, value),
|
|
3320
|
-
changeFieldState: (name, state) =>
|
|
3321
|
-
this.paymentService.changeFieldState(name, state);
|
|
3322
|
-
},
|
|
3735
|
+
changeFieldState: (name, state) => this.paymentService.changeFieldState(name, state),
|
|
3323
3736
|
},
|
|
3324
3737
|
};
|
|
3325
3738
|
}
|
|
3739
|
+
getCreditCardService() {
|
|
3740
|
+
return {
|
|
3741
|
+
getTypeByNumber: (cardNumber) => this.creditCardService.getTypeByNumber(cardNumber),
|
|
3742
|
+
getCreditCardSettings: (cardType) => this.creditCardService.getCreditCardSettings(cardType),
|
|
3743
|
+
cardTypeUpdates$: this.creditCardStateService.data$,
|
|
3744
|
+
};
|
|
3745
|
+
}
|
|
3746
|
+
get cardTypeUpdates$() {
|
|
3747
|
+
return this.creditCardStateService.data$;
|
|
3748
|
+
}
|
|
3326
3749
|
getLegalComponentConfig() {
|
|
3327
3750
|
return this.legalService.getLegalComponentConfig();
|
|
3328
3751
|
}
|
|
@@ -3331,14 +3754,14 @@ class CoreLibraryService {
|
|
|
3331
3754
|
return masksFunctionsMap[sanitizedName];
|
|
3332
3755
|
}
|
|
3333
3756
|
}
|
|
3334
|
-
CoreLibraryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryService, deps: [{ token: SettingsService }, { token: CountryService }, { token: PaymentMethodsService }, { token: SavedMethodsService }, { token: UserBalanceService }, { token: PaymentConfigService }, { token: PaymentService }, { token: DeviceFingerPrintService }, { token: FinanceDetailsService }, { token: LegalService }, { token: StatusService }, { token: NextActionService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3757
|
+
CoreLibraryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryService, deps: [{ token: SettingsService }, { token: CountryService }, { token: PaymentMethodsService }, { token: SavedMethodsService }, { token: UserBalanceService }, { token: PaymentConfigService }, { token: PaymentService }, { token: DeviceFingerPrintService }, { token: FinanceDetailsService }, { token: LegalService }, { token: StatusService }, { token: NextActionService }, { token: CreditCardService }, { token: CreditCardStateService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3335
3758
|
CoreLibraryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryService, providedIn: 'root' });
|
|
3336
3759
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryService, decorators: [{
|
|
3337
3760
|
type: Injectable,
|
|
3338
3761
|
args: [{
|
|
3339
3762
|
providedIn: 'root',
|
|
3340
3763
|
}]
|
|
3341
|
-
}], ctorParameters: function () { return [{ type: SettingsService }, { type: CountryService }, { type: PaymentMethodsService }, { type: SavedMethodsService }, { type: UserBalanceService }, { type: PaymentConfigService }, { type: PaymentService }, { type: DeviceFingerPrintService }, { type: FinanceDetailsService }, { type: LegalService }, { type: StatusService }, { type: NextActionService }]; } });
|
|
3764
|
+
}], ctorParameters: function () { return [{ type: SettingsService }, { type: CountryService }, { type: PaymentMethodsService }, { type: SavedMethodsService }, { type: UserBalanceService }, { type: PaymentConfigService }, { type: PaymentService }, { type: DeviceFingerPrintService }, { type: FinanceDetailsService }, { type: LegalService }, { type: StatusService }, { type: NextActionService }, { type: CreditCardService }, { type: CreditCardStateService }]; } });
|
|
3342
3765
|
|
|
3343
3766
|
class HttpError extends AppError {
|
|
3344
3767
|
constructor(error, req) {
|
|
@@ -3395,26 +3818,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
3395
3818
|
type: Injectable
|
|
3396
3819
|
}], ctorParameters: function () { return [{ type: i1$1.Router }]; } });
|
|
3397
3820
|
|
|
3821
|
+
class ValidatorsModule {
|
|
3822
|
+
}
|
|
3823
|
+
ValidatorsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ValidatorsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
3824
|
+
ValidatorsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.7", ngImport: i0, type: ValidatorsModule, imports: [CommonModule] });
|
|
3825
|
+
ValidatorsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ValidatorsModule, providers: [CreditCardMinLengthValidator], imports: [CommonModule] });
|
|
3826
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ValidatorsModule, decorators: [{
|
|
3827
|
+
type: NgModule,
|
|
3828
|
+
args: [{
|
|
3829
|
+
declarations: [],
|
|
3830
|
+
imports: [CommonModule],
|
|
3831
|
+
providers: [CreditCardMinLengthValidator],
|
|
3832
|
+
}]
|
|
3833
|
+
}] });
|
|
3834
|
+
|
|
3398
3835
|
class FormModule {
|
|
3399
3836
|
}
|
|
3400
3837
|
FormModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: FormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
3401
|
-
FormModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.7", ngImport: i0, type: FormModule, imports: [ReactiveFormsModule] });
|
|
3838
|
+
FormModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.7", ngImport: i0, type: FormModule, imports: [ReactiveFormsModule, ValidatorsModule] });
|
|
3402
3839
|
FormModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: FormModule, providers: [
|
|
3403
3840
|
FormService,
|
|
3404
3841
|
ControlConfigService,
|
|
3405
3842
|
ZipConverter,
|
|
3406
3843
|
EmailConverter,
|
|
3844
|
+
CardNumberConverter,
|
|
3407
3845
|
{ provide: convertersMapToken, useValue: convertersMap },
|
|
3408
|
-
], imports: [ReactiveFormsModule] });
|
|
3846
|
+
], imports: [ReactiveFormsModule, ValidatorsModule] });
|
|
3409
3847
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: FormModule, decorators: [{
|
|
3410
3848
|
type: NgModule,
|
|
3411
3849
|
args: [{
|
|
3412
|
-
imports: [ReactiveFormsModule],
|
|
3850
|
+
imports: [ReactiveFormsModule, ValidatorsModule],
|
|
3413
3851
|
providers: [
|
|
3414
3852
|
FormService,
|
|
3415
3853
|
ControlConfigService,
|
|
3416
3854
|
ZipConverter,
|
|
3417
3855
|
EmailConverter,
|
|
3856
|
+
CardNumberConverter,
|
|
3418
3857
|
{ provide: convertersMapToken, useValue: convertersMap },
|
|
3419
3858
|
],
|
|
3420
3859
|
}]
|