@streamscloud/kit 0.0.1-1770364570820
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/continuation-token.d.ts +10 -0
- package/dist/core/continuation-token.js +32 -0
- package/dist/core/css/index.d.ts +1 -0
- package/dist/core/css/index.js +1 -0
- package/dist/core/css/style-functions.d.ts +5 -0
- package/dist/core/css/style-functions.js +12 -0
- package/dist/core/cursor-result.d.ts +9 -0
- package/dist/core/cursor-result.js +1 -0
- package/dist/core/data-loaders/cursor-data-loader-with-search.svelte.d.ts +19 -0
- package/dist/core/data-loaders/cursor-data-loader-with-search.svelte.js +57 -0
- package/dist/core/data-loaders/cursor-data-loader.svelte.d.ts +13 -0
- package/dist/core/data-loaders/cursor-data-loader.svelte.js +33 -0
- package/dist/core/data-loaders/data-loader.d.ts +4 -0
- package/dist/core/data-loaders/data-loader.js +1 -0
- package/dist/core/data-loaders/index.d.ts +4 -0
- package/dist/core/data-loaders/index.js +4 -0
- package/dist/core/data-loaders/page-data-loader.svelte.d.ts +15 -0
- package/dist/core/data-loaders/page-data-loader.svelte.js +37 -0
- package/dist/core/deferred.d.ts +6 -0
- package/dist/core/deferred.js +13 -0
- package/dist/core/event-dispatcher.d.ts +9 -0
- package/dist/core/event-dispatcher.js +28 -0
- package/dist/core/files/base64-helper.d.ts +4 -0
- package/dist/core/files/base64-helper.js +22 -0
- package/dist/core/files/blob-storage.d.ts +1 -0
- package/dist/core/files/blob-storage.js +19 -0
- package/dist/core/files/file-helper.d.ts +6 -0
- package/dist/core/files/file-helper.js +27 -0
- package/dist/core/files/file-service.d.ts +4 -0
- package/dist/core/files/file-service.js +54 -0
- package/dist/core/files/file-types.d.ts +16 -0
- package/dist/core/files/file-types.js +28 -0
- package/dist/core/files/file-with-blob-data-helper.d.ts +19 -0
- package/dist/core/files/file-with-blob-data-helper.js +86 -0
- package/dist/core/files/files-provider.d.ts +8 -0
- package/dist/core/files/files-provider.js +38 -0
- package/dist/core/files/image-resizer.d.ts +31 -0
- package/dist/core/files/image-resizer.js +92 -0
- package/dist/core/files/index.d.ts +9 -0
- package/dist/core/files/index.js +9 -0
- package/dist/core/files/types.d.ts +12 -0
- package/dist/core/files/types.js +10 -0
- package/dist/core/graphql.d.ts +4 -0
- package/dist/core/graphql.js +10 -0
- package/dist/core/handle-generator.d.ts +1 -0
- package/dist/core/handle-generator.js +32 -0
- package/dist/core/i18n/index.d.ts +1 -0
- package/dist/core/i18n/index.js +1 -0
- package/dist/core/i18n/plural.d.ts +14 -0
- package/dist/core/i18n/plural.js +18 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.js +6 -0
- package/dist/core/repository/index.d.ts +2 -0
- package/dist/core/repository/index.js +2 -0
- package/dist/core/repository/map-container.svelte.d.ts +9 -0
- package/dist/core/repository/map-container.svelte.js +22 -0
- package/dist/core/repository/repository-notifier.d.ts +19 -0
- package/dist/core/repository/repository-notifier.js +88 -0
- package/dist/core/repository/repository.svelte.d.ts +2 -0
- package/dist/core/repository/repository.svelte.js +59 -0
- package/dist/core/repository/types.d.ts +15 -0
- package/dist/core/repository/types.js +1 -0
- package/dist/core/theme/app-theme.svelte.d.ts +15 -0
- package/dist/core/theme/app-theme.svelte.js +48 -0
- package/dist/core/theme/index.d.ts +4 -0
- package/dist/core/theme/index.js +3 -0
- package/dist/core/theme/theme-cookie.d.ts +5 -0
- package/dist/core/theme/theme-cookie.js +19 -0
- package/dist/core/theme/types.d.ts +5 -0
- package/dist/core/theme/types.js +8 -0
- package/dist/core/toastr/index.d.ts +3 -0
- package/dist/core/toastr/index.js +2 -0
- package/dist/core/toastr/toaster-host.svelte.d.ts +5 -0
- package/dist/core/toastr/toaster-host.svelte.js +40 -0
- package/dist/core/toastr/toastr.scss +27 -0
- package/dist/core/toastr/toastr.svelte.d.ts +8 -0
- package/dist/core/toastr/toastr.svelte.js +27 -0
- package/dist/core/toastr/types.d.ts +14 -0
- package/dist/core/toastr/types.js +1 -0
- package/dist/core/transitions/index.d.ts +1 -0
- package/dist/core/transitions/index.js +1 -0
- package/dist/core/transitions/slide-horizontally.d.ts +8 -0
- package/dist/core/transitions/slide-horizontally.js +54 -0
- package/dist/core/utils/array-helper.d.ts +21 -0
- package/dist/core/utils/array-helper.js +130 -0
- package/dist/core/utils/base64-serializer.d.ts +4 -0
- package/dist/core/utils/base64-serializer.js +21 -0
- package/dist/core/utils/browser.d.ts +1 -0
- package/dist/core/utils/browser.js +1 -0
- package/dist/core/utils/date-helper.d.ts +51 -0
- package/dist/core/utils/date-helper.js +244 -0
- package/dist/core/utils/dom-helper.d.ts +10 -0
- package/dist/core/utils/dom-helper.js +34 -0
- package/dist/core/utils/href-validator.d.ts +22 -0
- package/dist/core/utils/href-validator.js +52 -0
- package/dist/core/utils/html-helper.d.ts +12 -0
- package/dist/core/utils/html-helper.js +104 -0
- package/dist/core/utils/index.d.ts +13 -0
- package/dist/core/utils/index.js +13 -0
- package/dist/core/utils/lazy-init.d.ts +1 -0
- package/dist/core/utils/lazy-init.js +7 -0
- package/dist/core/utils/number-helper.d.ts +5 -0
- package/dist/core/utils/number-helper.js +32 -0
- package/dist/core/utils/string-generator.d.ts +2 -0
- package/dist/core/utils/string-generator.js +5 -0
- package/dist/core/utils/string-helper.d.ts +12 -0
- package/dist/core/utils/string-helper.js +75 -0
- package/dist/core/utils/url-helper.d.ts +3 -0
- package/dist/core/utils/url-helper.js +13 -0
- package/dist/core/utils/utils.d.ts +29 -0
- package/dist/core/utils/utils.js +108 -0
- package/dist/core/validation/form-validation-handler/form-validation-handler.svelte.d.ts +47 -0
- package/dist/core/validation/form-validation-handler/form-validation-handler.svelte.js +182 -0
- package/dist/core/validation/form-validation-handler/index.d.ts +4 -0
- package/dist/core/validation/form-validation-handler/index.js +3 -0
- package/dist/core/validation/form-validation-handler/stub-form-validator.d.ts +5 -0
- package/dist/core/validation/form-validation-handler/stub-form-validator.js +12 -0
- package/dist/core/validation/form-validation-handler/types.d.ts +10 -0
- package/dist/core/validation/form-validation-handler/types.js +1 -0
- package/dist/core/validation/form-validation-handler/yup-form-validator.d.ts +11 -0
- package/dist/core/validation/form-validation-handler/yup-form-validator.js +49 -0
- package/dist/core/validation/form-validator.svelte.d.ts +12 -0
- package/dist/core/validation/form-validator.svelte.js +21 -0
- package/dist/core/validation/i-validator.d.ts +6 -0
- package/dist/core/validation/i-validator.js +1 -0
- package/dist/core/validation/index.d.ts +5 -0
- package/dist/core/validation/index.js +4 -0
- package/dist/core/validation/validation-schemas/email-validation.d.ts +3 -0
- package/dist/core/validation/validation-schemas/email-validation.js +17 -0
- package/dist/core/validation/validation-schemas/handle-validations.d.ts +3 -0
- package/dist/core/validation/validation-schemas/handle-validations.js +16 -0
- package/dist/core/validation/validation-schemas/index.d.ts +6 -0
- package/dist/core/validation/validation-schemas/index.js +5 -0
- package/dist/core/validation/validation-schemas/number-validations.d.ts +4 -0
- package/dist/core/validation/validation-schemas/number-validations.js +30 -0
- package/dist/core/validation/validation-schemas/text-validations.d.ts +4 -0
- package/dist/core/validation/validation-schemas/text-validations.js +19 -0
- package/dist/core/validation/validation-schemas/types.d.ts +19 -0
- package/dist/core/validation/validation-schemas/types.js +1 -0
- package/dist/core/validation/validation-schemas/validation-messages.d.ts +11 -0
- package/dist/core/validation/validation-schemas/validation-messages.js +14 -0
- package/dist/core/validation/validators-hub.svelte.d.ts +14 -0
- package/dist/core/validation/validators-hub.svelte.js +51 -0
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +2 -0
- package/package.json +125 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class UrlHelper {
|
|
2
|
+
static getRootDomain(url) {
|
|
3
|
+
let tokens = url.hostname.split('.');
|
|
4
|
+
if (tokens.length <= 2) {
|
|
5
|
+
return url.hostname;
|
|
6
|
+
}
|
|
7
|
+
tokens = tokens.slice(-3);
|
|
8
|
+
if (['co', 'com', 'org', 'net', 'gov', 'edu', 'ac'].includes(tokens[1])) {
|
|
9
|
+
return tokens.join('.');
|
|
10
|
+
}
|
|
11
|
+
return tokens.slice(-2).join('.');
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare class Utils {
|
|
2
|
+
static areEqual(value: unknown, other: unknown): boolean;
|
|
3
|
+
static assertUnreachable(_x: never): never;
|
|
4
|
+
static clone<T>(value: T): T;
|
|
5
|
+
/**
|
|
6
|
+
* Find the greatest common divisor of 2 numbers
|
|
7
|
+
*/
|
|
8
|
+
static gcd(a: number, b: number): number;
|
|
9
|
+
/**
|
|
10
|
+
* Find the least dividend and divisor by given quotient
|
|
11
|
+
*/
|
|
12
|
+
static ldd(quotient: number, divisorLimit?: number): {
|
|
13
|
+
dividend: number;
|
|
14
|
+
divisor: number;
|
|
15
|
+
} | null;
|
|
16
|
+
/**
|
|
17
|
+
* Returns a function, that, as long as it continues to be invoked, will not
|
|
18
|
+
* be triggered. The function will be called after it stops being called for
|
|
19
|
+
* N milliseconds.
|
|
20
|
+
*/
|
|
21
|
+
static debounce(func: (...args: any[]) => void, wait: number): (...args: unknown[]) => void;
|
|
22
|
+
static throttle<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => ReturnType<T>;
|
|
23
|
+
static sleep: (ms: number) => Promise<unknown>;
|
|
24
|
+
static poll: <T>(fn: () => Promise<T>, continueWhileTrueFn: (input: T) => boolean, ms?: number) => Promise<T>;
|
|
25
|
+
static nameof: <T>(name: keyof T) => keyof T;
|
|
26
|
+
static unsubscribe(sub: UnsubscribeMethod | UnsubscribeMethod[] | null | undefined): void;
|
|
27
|
+
}
|
|
28
|
+
export type Without<T, K> = Pick<T, Exclude<keyof T, K>>;
|
|
29
|
+
export type UnsubscribeMethod = () => void;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { dequal as isEqual } from 'dequal/lite';
|
|
2
|
+
import rfdc from 'rfdc';
|
|
3
|
+
export class Utils {
|
|
4
|
+
static areEqual(value, other) {
|
|
5
|
+
return isEqual(value, other);
|
|
6
|
+
}
|
|
7
|
+
static assertUnreachable(_x) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
static clone(value) {
|
|
11
|
+
return rfdc()(value);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Find the greatest common divisor of 2 numbers
|
|
15
|
+
*/
|
|
16
|
+
static gcd(a, b) {
|
|
17
|
+
a = Math.abs(a);
|
|
18
|
+
b = Math.abs(b);
|
|
19
|
+
if (b > a) {
|
|
20
|
+
const temp = a;
|
|
21
|
+
a = b;
|
|
22
|
+
b = temp;
|
|
23
|
+
}
|
|
24
|
+
while (true) {
|
|
25
|
+
if (b === 0) {
|
|
26
|
+
return a;
|
|
27
|
+
}
|
|
28
|
+
a %= b;
|
|
29
|
+
if (a === 0) {
|
|
30
|
+
return b;
|
|
31
|
+
}
|
|
32
|
+
b %= a;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Find the least dividend and divisor by given quotient
|
|
37
|
+
*/
|
|
38
|
+
static ldd(quotient, divisorLimit = 1000000) {
|
|
39
|
+
let divisor = 1;
|
|
40
|
+
while (divisor <= divisorLimit) {
|
|
41
|
+
const dividend = quotient * divisor;
|
|
42
|
+
if (dividend % 1 === 0) {
|
|
43
|
+
return { dividend, divisor };
|
|
44
|
+
}
|
|
45
|
+
divisor++;
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Returns a function, that, as long as it continues to be invoked, will not
|
|
51
|
+
* be triggered. The function will be called after it stops being called for
|
|
52
|
+
* N milliseconds.
|
|
53
|
+
*/
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
55
|
+
static debounce(func, wait) {
|
|
56
|
+
let timeout;
|
|
57
|
+
return (...args) => {
|
|
58
|
+
const later = () => {
|
|
59
|
+
func.apply(this, args);
|
|
60
|
+
};
|
|
61
|
+
clearTimeout(timeout);
|
|
62
|
+
timeout = window.setTimeout(later, wait);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
|
+
static throttle(func, wait) {
|
|
67
|
+
// Capture the current time
|
|
68
|
+
let time = Date.now() - wait;
|
|
69
|
+
return (...args) => {
|
|
70
|
+
if (time + wait - Date.now() <= 0) {
|
|
71
|
+
time = Date.now();
|
|
72
|
+
// Run the function we've passed to our throttler,
|
|
73
|
+
// and reset the `time` variable (so we can check again).
|
|
74
|
+
return func.apply(this, args);
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
static sleep = async (ms) => {
|
|
80
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
81
|
+
};
|
|
82
|
+
static poll = async (fn, continueWhileTrueFn, ms = 1000) => {
|
|
83
|
+
let result = await fn();
|
|
84
|
+
while (continueWhileTrueFn(result)) {
|
|
85
|
+
await Utils.sleep(ms);
|
|
86
|
+
result = await fn();
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
};
|
|
90
|
+
static nameof = (name) => name;
|
|
91
|
+
static unsubscribe(sub) {
|
|
92
|
+
if (!sub) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const unsubscribeSingle = (sub) => {
|
|
96
|
+
if (!sub) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
sub();
|
|
100
|
+
};
|
|
101
|
+
if (sub instanceof Array) {
|
|
102
|
+
sub.forEach(unsubscribeSingle);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
unsubscribeSingle(sub);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { IValidator } from '../i-validator';
|
|
2
|
+
import type { IFormHandlerValidator } from './types';
|
|
3
|
+
type TypeToValidate<T> = {
|
|
4
|
+
[K in keyof T]: T[K];
|
|
5
|
+
};
|
|
6
|
+
export declare class FormValidationHandler<T extends TypeToValidate<T> = TypeToValidate<unknown>, TSubmitResult = void> implements IValidator {
|
|
7
|
+
readonly formStringified: Record<string, string>;
|
|
8
|
+
readonly modified: Record<keyof T, boolean>;
|
|
9
|
+
readonly isValid: boolean;
|
|
10
|
+
readonly isModified: boolean;
|
|
11
|
+
private _form;
|
|
12
|
+
private _errors;
|
|
13
|
+
private _touched;
|
|
14
|
+
private _isValidating;
|
|
15
|
+
private _isSubmitting;
|
|
16
|
+
private _validator;
|
|
17
|
+
private _initialValues;
|
|
18
|
+
private readonly _onSubmit;
|
|
19
|
+
private readonly _onReset;
|
|
20
|
+
private _initials;
|
|
21
|
+
constructor(context: {
|
|
22
|
+
initialValues: T;
|
|
23
|
+
validator: IFormHandlerValidator<T>;
|
|
24
|
+
onSubmit?: (values: T) => TSubmitResult;
|
|
25
|
+
onReset?: () => void;
|
|
26
|
+
});
|
|
27
|
+
get form(): T;
|
|
28
|
+
get errors(): { [P in keyof Partial<T>]: string; };
|
|
29
|
+
get touched(): Record<keyof T, boolean>;
|
|
30
|
+
get isValidating(): boolean;
|
|
31
|
+
get isSubmitting(): boolean;
|
|
32
|
+
updateField: <K extends keyof T>(field: K, value: T[K]) => void;
|
|
33
|
+
updateValidateField: <K extends keyof T>(field: K, value: T[K]) => Promise<void>;
|
|
34
|
+
updateTouched: (field: keyof T, value: boolean) => void;
|
|
35
|
+
updateTouchedForAllFields: (value: boolean) => void;
|
|
36
|
+
validateField: (field: keyof T) => Promise<void>;
|
|
37
|
+
updateInitialValues: (newValues: T) => void;
|
|
38
|
+
updateValidator: (validator: IFormHandlerValidator<T>) => void;
|
|
39
|
+
handleReset: () => void;
|
|
40
|
+
handleInputValueChanged: (event: Event) => Promise<void>;
|
|
41
|
+
validate: (values?: T) => Promise<boolean>;
|
|
42
|
+
handleSubmit: (event: Event | null) => Promise<void>;
|
|
43
|
+
dispose(): void;
|
|
44
|
+
private validateFieldValue;
|
|
45
|
+
private stringify;
|
|
46
|
+
}
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { Utils } from '../../utils';
|
|
2
|
+
import { dequal as isEqual } from 'dequal/lite';
|
|
3
|
+
const NO_ERROR = '';
|
|
4
|
+
export class FormValidationHandler {
|
|
5
|
+
formStringified = $derived.by(() => {
|
|
6
|
+
if (!this.form) {
|
|
7
|
+
return {};
|
|
8
|
+
}
|
|
9
|
+
return Object.entries(this.form).reduce((acc, [key, value]) => ({ ...acc, [key]: this.stringify(value) }), {});
|
|
10
|
+
});
|
|
11
|
+
modified = $derived.by(() => {
|
|
12
|
+
if (!this.form) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const object = ValidationUtils.assignDeep(this.form, false);
|
|
16
|
+
for (const key in this.form) {
|
|
17
|
+
object[key] = !isEqual(this.form[key], this._initialValues[key]);
|
|
18
|
+
}
|
|
19
|
+
return object;
|
|
20
|
+
});
|
|
21
|
+
isValid = $derived(ValidationUtils.getValues(this.errors).every((field) => field === NO_ERROR));
|
|
22
|
+
isModified = $derived.by(() => {
|
|
23
|
+
return ValidationUtils.getValues(this.modified).includes(true);
|
|
24
|
+
});
|
|
25
|
+
_form = $state(null);
|
|
26
|
+
_errors = $state(null);
|
|
27
|
+
_touched = $state(null);
|
|
28
|
+
_isValidating = $state(false);
|
|
29
|
+
_isSubmitting = $state(false);
|
|
30
|
+
_validator;
|
|
31
|
+
_initialValues = $state(null);
|
|
32
|
+
_onSubmit;
|
|
33
|
+
_onReset;
|
|
34
|
+
_initials = {
|
|
35
|
+
values: () => Utils.clone(this._initialValues),
|
|
36
|
+
errors: () => ValidationUtils.assignDeep(this._initialValues, NO_ERROR),
|
|
37
|
+
touched: () => ValidationUtils.assignDeep(this._initialValues, false)
|
|
38
|
+
};
|
|
39
|
+
constructor(context) {
|
|
40
|
+
this._initialValues = context.initialValues || {};
|
|
41
|
+
this._onSubmit = context.onSubmit ? context.onSubmit : () => ({});
|
|
42
|
+
this._onReset = context.onReset ? context.onReset : () => ({});
|
|
43
|
+
this._validator = context.validator;
|
|
44
|
+
this._form = this._initials.values();
|
|
45
|
+
this._errors = this._initials.errors();
|
|
46
|
+
this._touched = this._initials.touched();
|
|
47
|
+
}
|
|
48
|
+
get form() {
|
|
49
|
+
return this._form;
|
|
50
|
+
}
|
|
51
|
+
get errors() {
|
|
52
|
+
return this._errors;
|
|
53
|
+
}
|
|
54
|
+
get touched() {
|
|
55
|
+
return this._touched;
|
|
56
|
+
}
|
|
57
|
+
get isValidating() {
|
|
58
|
+
return this._isValidating;
|
|
59
|
+
}
|
|
60
|
+
get isSubmitting() {
|
|
61
|
+
return this._isSubmitting;
|
|
62
|
+
}
|
|
63
|
+
updateField = (field, value) => {
|
|
64
|
+
ValidationUtils.update(this._form, field, value);
|
|
65
|
+
};
|
|
66
|
+
updateValidateField = async (field, value) => {
|
|
67
|
+
this.updateField(field, value);
|
|
68
|
+
await this.validateFieldValue(field);
|
|
69
|
+
};
|
|
70
|
+
updateTouched = (field, value) => {
|
|
71
|
+
ValidationUtils.update(this._touched, field, value);
|
|
72
|
+
};
|
|
73
|
+
updateTouchedForAllFields = (value) => {
|
|
74
|
+
Object.keys(this._initialValues).forEach((key) => {
|
|
75
|
+
ValidationUtils.update(this._touched, key, value);
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
validateField = async (field) => {
|
|
79
|
+
return await this.validateFieldValue(field);
|
|
80
|
+
};
|
|
81
|
+
updateInitialValues = (newValues) => {
|
|
82
|
+
this._initialValues = newValues;
|
|
83
|
+
this.handleReset();
|
|
84
|
+
};
|
|
85
|
+
updateValidator = (validator) => {
|
|
86
|
+
this._validator = validator;
|
|
87
|
+
this.handleReset();
|
|
88
|
+
};
|
|
89
|
+
handleReset = () => {
|
|
90
|
+
this._form = this._initials.values();
|
|
91
|
+
this._errors = this._initials.errors();
|
|
92
|
+
this._touched = this._initials.touched();
|
|
93
|
+
this._onReset();
|
|
94
|
+
};
|
|
95
|
+
handleInputValueChanged = (event) => {
|
|
96
|
+
const element = event.target;
|
|
97
|
+
const field = (element.name || element.id);
|
|
98
|
+
const resolveValue = () => {
|
|
99
|
+
if (element.getAttribute && element.getAttribute('type') === 'file') {
|
|
100
|
+
return element.files;
|
|
101
|
+
}
|
|
102
|
+
else if (element.getAttribute && element.getAttribute('type') === 'checkbox') {
|
|
103
|
+
return element.checked;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
return element.value;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const value = resolveValue();
|
|
110
|
+
return this.updateValidateField(field, value);
|
|
111
|
+
};
|
|
112
|
+
validate = async (values) => {
|
|
113
|
+
this.updateTouchedForAllFields(true);
|
|
114
|
+
values = values || this.form;
|
|
115
|
+
this._isValidating = true;
|
|
116
|
+
const result = await this._validator.validate(values);
|
|
117
|
+
this._errors = result.errors;
|
|
118
|
+
this._isValidating = false;
|
|
119
|
+
return result.isValid;
|
|
120
|
+
};
|
|
121
|
+
handleSubmit = async (event) => {
|
|
122
|
+
if (event && event.preventDefault) {
|
|
123
|
+
event.preventDefault();
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
this._isSubmitting = true;
|
|
127
|
+
const values = this.form;
|
|
128
|
+
const isValid = await this.validate(values);
|
|
129
|
+
if (!isValid) {
|
|
130
|
+
this._isSubmitting = false;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
this._errors = this._initials.errors();
|
|
134
|
+
await this._onSubmit(values);
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
this._isSubmitting = false;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
dispose() {
|
|
141
|
+
// do nothing
|
|
142
|
+
}
|
|
143
|
+
validateFieldValue = async (field) => {
|
|
144
|
+
this.updateTouched(field, true);
|
|
145
|
+
this._isValidating = true;
|
|
146
|
+
const error = await this._validator.validateAt(this._form, field);
|
|
147
|
+
ValidationUtils.update(this.errors, field, error || '');
|
|
148
|
+
this._isValidating = false;
|
|
149
|
+
};
|
|
150
|
+
stringify = (value) => {
|
|
151
|
+
if (typeof value !== 'number' && !value) {
|
|
152
|
+
return '';
|
|
153
|
+
}
|
|
154
|
+
if (typeof value === 'string') {
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
return JSON.stringify(value);
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
class ValidationUtils {
|
|
161
|
+
static update = (object, path, value) => {
|
|
162
|
+
ValidationUtils.set(object, path, value);
|
|
163
|
+
};
|
|
164
|
+
static getValues = (object) => {
|
|
165
|
+
const results = [];
|
|
166
|
+
for (const [, value] of Object.entries(object)) {
|
|
167
|
+
results.push(value);
|
|
168
|
+
}
|
|
169
|
+
return results;
|
|
170
|
+
};
|
|
171
|
+
static assignDeep(object, value) {
|
|
172
|
+
const copy = {};
|
|
173
|
+
for (const key in object) {
|
|
174
|
+
copy[key] = value;
|
|
175
|
+
}
|
|
176
|
+
return copy;
|
|
177
|
+
}
|
|
178
|
+
static set(object, path, value) {
|
|
179
|
+
object[path] = value;
|
|
180
|
+
return object;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type IFormHandlerValidator<T> = {
|
|
2
|
+
validate: (obj: T) => Promise<FormValidateResult<Partial<T>>>;
|
|
3
|
+
validateAt: (obj: T, field: keyof T) => Promise<string | null>;
|
|
4
|
+
};
|
|
5
|
+
export type FormValidateResult<T> = {
|
|
6
|
+
isValid: boolean;
|
|
7
|
+
errors: {
|
|
8
|
+
[P in keyof T]: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FormValidateResult, IFormHandlerValidator } from './types';
|
|
2
|
+
import type { ObjectSchema } from 'yup';
|
|
3
|
+
export declare class YupFormValidator<T> implements IFormHandlerValidator<T> {
|
|
4
|
+
private validationSchema;
|
|
5
|
+
private validationOptions;
|
|
6
|
+
constructor(validationSchema: ObjectSchema<Partial<T>>, validationOptions?: {
|
|
7
|
+
trimErrorPath: boolean;
|
|
8
|
+
});
|
|
9
|
+
validate: (obj: T) => Promise<FormValidateResult<Partial<T>>>;
|
|
10
|
+
validateAt: (obj: T, field: keyof T) => Promise<string | null>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export class YupFormValidator {
|
|
2
|
+
validationSchema;
|
|
3
|
+
validationOptions;
|
|
4
|
+
constructor(validationSchema, validationOptions = { trimErrorPath: true }) {
|
|
5
|
+
this.validationSchema = validationSchema;
|
|
6
|
+
this.validationOptions = validationOptions;
|
|
7
|
+
}
|
|
8
|
+
validate = async (obj) => {
|
|
9
|
+
const errors = {};
|
|
10
|
+
try {
|
|
11
|
+
await this.validationSchema.validate(obj, { abortEarly: false });
|
|
12
|
+
return {
|
|
13
|
+
isValid: true,
|
|
14
|
+
errors
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
const yupErrors = error;
|
|
19
|
+
if (yupErrors && yupErrors.inner) {
|
|
20
|
+
const updatedPathMap = {};
|
|
21
|
+
yupErrors.inner.forEach((e) => {
|
|
22
|
+
if (!e.path) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (updatedPathMap[e.path]) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const errorPath = this.validationOptions.trimErrorPath ? e.path.split('.')[0] : e.path;
|
|
29
|
+
errors[errorPath] = e.message;
|
|
30
|
+
updatedPathMap[e.path] = true;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
isValid: false,
|
|
35
|
+
errors
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
validateAt = async (obj, field) => {
|
|
40
|
+
try {
|
|
41
|
+
await this.validationSchema.validateAt(field, obj);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
const error = e;
|
|
46
|
+
return error.message;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FormValidationHandler } from './form-validation-handler';
|
|
2
|
+
import type { IValidator } from './i-validator';
|
|
3
|
+
export declare class FormValidator<T> implements IValidator {
|
|
4
|
+
private _formHandler;
|
|
5
|
+
private _isValid;
|
|
6
|
+
private _isModified;
|
|
7
|
+
constructor(formHandler: FormValidationHandler<T>);
|
|
8
|
+
get isValid(): boolean;
|
|
9
|
+
get isModified(): boolean;
|
|
10
|
+
dispose(): void;
|
|
11
|
+
validate(): Promise<boolean>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FormValidationHandler } from './form-validation-handler';
|
|
2
|
+
export class FormValidator {
|
|
3
|
+
_formHandler = $state.raw(null);
|
|
4
|
+
_isValid = $derived(!!this._formHandler && this._formHandler.isValid);
|
|
5
|
+
_isModified = $derived(!!this._formHandler && this._formHandler.isModified);
|
|
6
|
+
constructor(formHandler) {
|
|
7
|
+
this._formHandler = formHandler;
|
|
8
|
+
}
|
|
9
|
+
get isValid() {
|
|
10
|
+
return this._isValid;
|
|
11
|
+
}
|
|
12
|
+
get isModified() {
|
|
13
|
+
return this._isModified;
|
|
14
|
+
}
|
|
15
|
+
dispose() {
|
|
16
|
+
// do nothing
|
|
17
|
+
}
|
|
18
|
+
async validate() {
|
|
19
|
+
return await this._formHandler.validate();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getValidationMessages } from './validation-messages';
|
|
2
|
+
import * as yup from 'yup';
|
|
3
|
+
const EMAIL_REGEX = /^[a-zA-Z0-9_]([.+-]?[a-zA-Z0-9_])+@[a-zA-Z0-9]([.-]?[a-zA-Z0-9])+\.[a-zA-Z]{2,}$/;
|
|
4
|
+
export const emailValidationSchema = () => {
|
|
5
|
+
const msg = getValidationMessages();
|
|
6
|
+
return yup.string().required(msg.required).matches(EMAIL_REGEX, {
|
|
7
|
+
excludeEmptyString: true,
|
|
8
|
+
message: msg.email
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
export const nullableEmailValidationSchema = () => {
|
|
12
|
+
const msg = getValidationMessages();
|
|
13
|
+
return yup.string().nullable().matches(EMAIL_REGEX, {
|
|
14
|
+
excludeEmptyString: true,
|
|
15
|
+
message: msg.email
|
|
16
|
+
});
|
|
17
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { getValidationMessages } from './validation-messages';
|
|
2
|
+
import * as yup from 'yup';
|
|
3
|
+
const DEFAULT_MIN_LENGTH = 3;
|
|
4
|
+
const DEFAULT_MAX_LENGTH = 30;
|
|
5
|
+
const HANDLE_REGEX = /^[a-z_]([a-z0-9_]|[.-](?![.-]))*[a-z0-9_]$/;
|
|
6
|
+
export const handleValidationSchema = (lengthValidation) => {
|
|
7
|
+
const msg = getValidationMessages();
|
|
8
|
+
const minLength = lengthValidation?.minLength ?? DEFAULT_MIN_LENGTH;
|
|
9
|
+
const maxLength = lengthValidation?.maxLength ?? DEFAULT_MAX_LENGTH;
|
|
10
|
+
return yup
|
|
11
|
+
.string()
|
|
12
|
+
.required(msg.required)
|
|
13
|
+
.min(minLength, msg.minLength(minLength))
|
|
14
|
+
.max(maxLength, msg.maxLength(maxLength))
|
|
15
|
+
.test('handle-format', msg.badFormat, (val) => !!val && HANDLE_REGEX.test(val));
|
|
16
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { TextValidation, TextWithFormatValidation, NumberValidation, MinNumberValidation } from './types';
|
|
2
|
+
export { setValidationMessages } from './validation-messages';
|
|
3
|
+
export { emailValidationSchema, nullableEmailValidationSchema } from './email-validation';
|
|
4
|
+
export { textValidationSchema, formattedTextValidationSchema } from './text-validations';
|
|
5
|
+
export { handleValidationSchema } from './handle-validations';
|
|
6
|
+
export { numberValidationSchema, minNumberValidationSchema } from './number-validations';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { setValidationMessages } from './validation-messages';
|
|
2
|
+
export { emailValidationSchema, nullableEmailValidationSchema } from './email-validation';
|
|
3
|
+
export { textValidationSchema, formattedTextValidationSchema } from './text-validations';
|
|
4
|
+
export { handleValidationSchema } from './handle-validations';
|
|
5
|
+
export { numberValidationSchema, minNumberValidationSchema } from './number-validations';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MinNumberValidation, NumberValidation } from './types';
|
|
2
|
+
import * as yup from 'yup';
|
|
3
|
+
export declare const numberValidationSchema: (rules: NumberValidation) => yup.NumberSchema<number | undefined, yup.AnyObject, undefined, "">;
|
|
4
|
+
export declare const minNumberValidationSchema: (rules: MinNumberValidation) => yup.NumberSchema<number | undefined, yup.AnyObject, undefined, "">;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getValidationMessages } from './validation-messages';
|
|
2
|
+
import * as yup from 'yup';
|
|
3
|
+
export const numberValidationSchema = (rules) => {
|
|
4
|
+
const msg = getValidationMessages();
|
|
5
|
+
let schema = yup.number().typeError(msg.badFormat);
|
|
6
|
+
if (rules.isRequired) {
|
|
7
|
+
schema = schema.required(msg.required);
|
|
8
|
+
}
|
|
9
|
+
if (rules.minValue !== null) {
|
|
10
|
+
const minValue = rules.minExclusive ? rules.minValue + 1 : rules.minValue;
|
|
11
|
+
schema = schema.min(minValue, msg.min(minValue));
|
|
12
|
+
}
|
|
13
|
+
if (rules.maxValue !== null) {
|
|
14
|
+
const maxValue = rules.maxExclusive ? rules.maxValue - 1 : rules.maxValue;
|
|
15
|
+
schema = schema.max(maxValue, msg.max(maxValue));
|
|
16
|
+
}
|
|
17
|
+
return schema;
|
|
18
|
+
};
|
|
19
|
+
export const minNumberValidationSchema = (rules) => {
|
|
20
|
+
const msg = getValidationMessages();
|
|
21
|
+
let schema = yup.number().typeError(msg.badFormat);
|
|
22
|
+
if (rules.isRequired) {
|
|
23
|
+
schema = schema.required(msg.required);
|
|
24
|
+
}
|
|
25
|
+
if (rules.minValue !== null) {
|
|
26
|
+
const minValue = rules.minExclusive ? rules.minValue + 1 : rules.minValue;
|
|
27
|
+
schema = schema.min(minValue, msg.min(minValue));
|
|
28
|
+
}
|
|
29
|
+
return schema;
|
|
30
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TextValidation, TextWithFormatValidation } from './types';
|
|
2
|
+
import * as yup from 'yup';
|
|
3
|
+
export declare const textValidationSchema: (rules: TextValidation) => yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|
|
4
|
+
export declare const formattedTextValidationSchema: (rules: TextWithFormatValidation, fieldName: string, formatMessage?: string) => yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|