bindra 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/LICENSE +21 -0
  3. package/README.md +229 -0
  4. package/dist/core/Container.d.ts +88 -0
  5. package/dist/core/Container.d.ts.map +1 -0
  6. package/dist/core/Container.js +185 -0
  7. package/dist/core/Container.js.map +1 -0
  8. package/dist/core/DataSource.d.ts +272 -0
  9. package/dist/core/DataSource.d.ts.map +1 -0
  10. package/dist/core/DataSource.js +903 -0
  11. package/dist/core/DataSource.js.map +1 -0
  12. package/dist/core/Dispatcher.d.ts +6 -0
  13. package/dist/core/Dispatcher.d.ts.map +1 -0
  14. package/dist/core/Dispatcher.js +44 -0
  15. package/dist/core/Dispatcher.js.map +1 -0
  16. package/dist/core/EventEmitter.d.ts +11 -0
  17. package/dist/core/EventEmitter.d.ts.map +1 -0
  18. package/dist/core/EventEmitter.js +34 -0
  19. package/dist/core/EventEmitter.js.map +1 -0
  20. package/dist/core/MiddlewareManager.d.ts +47 -0
  21. package/dist/core/MiddlewareManager.d.ts.map +1 -0
  22. package/dist/core/MiddlewareManager.js +86 -0
  23. package/dist/core/MiddlewareManager.js.map +1 -0
  24. package/dist/core/Observable.d.ts +12 -0
  25. package/dist/core/Observable.d.ts.map +1 -0
  26. package/dist/core/Observable.js +43 -0
  27. package/dist/core/Observable.js.map +1 -0
  28. package/dist/core/errors.d.ts +124 -0
  29. package/dist/core/errors.d.ts.map +1 -0
  30. package/dist/core/errors.js +149 -0
  31. package/dist/core/errors.js.map +1 -0
  32. package/dist/core/validation.d.ts +100 -0
  33. package/dist/core/validation.d.ts.map +1 -0
  34. package/dist/core/validation.js +217 -0
  35. package/dist/core/validation.js.map +1 -0
  36. package/dist/examples.d.ts +52 -0
  37. package/dist/examples.d.ts.map +1 -0
  38. package/dist/examples.js +242 -0
  39. package/dist/examples.js.map +1 -0
  40. package/dist/index.d.ts +13 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +14 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/utils/performance.d.ts +49 -0
  45. package/dist/utils/performance.d.ts.map +1 -0
  46. package/dist/utils/performance.js +94 -0
  47. package/dist/utils/performance.js.map +1 -0
  48. package/package.json +64 -0
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Custom error classes for Bindra
3
+ *
4
+ * Provides structured error handling with error codes and details
5
+ */
6
+ /**
7
+ * Base error class for all Bindra errors
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * throw new BindraError('Something went wrong', 'GENERAL_ERROR', { detail: 'info' });
12
+ * ```
13
+ */
14
+ export class BindraError extends Error {
15
+ /**
16
+ * Creates a new BindraError
17
+ *
18
+ * @param message - Human-readable error message
19
+ * @param code - Machine-readable error code
20
+ * @param details - Additional error details
21
+ */
22
+ constructor(message, code, details) {
23
+ super(message);
24
+ this.code = code;
25
+ this.details = details;
26
+ this.name = 'BindraError';
27
+ // Maintains proper stack trace for where error was thrown (only available on V8)
28
+ if (typeof Error.captureStackTrace === 'function') {
29
+ Error.captureStackTrace(this, BindraError);
30
+ }
31
+ }
32
+ }
33
+ /**
34
+ * Network-related errors (HTTP, fetch failures, etc.)
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * throw new NetworkError('Failed to fetch data', 404);
39
+ * ```
40
+ */
41
+ export class NetworkError extends BindraError {
42
+ /**
43
+ * Creates a new NetworkError
44
+ *
45
+ * @param message - Human-readable error message
46
+ * @param statusCode - HTTP status code (optional)
47
+ * @param response - Response body or additional info (optional)
48
+ */
49
+ constructor(message, statusCode, response) {
50
+ super(message, 'NETWORK_ERROR', { statusCode, response });
51
+ this.statusCode = statusCode;
52
+ this.response = response;
53
+ this.name = 'NetworkError';
54
+ }
55
+ }
56
+ /**
57
+ * Validation errors for invalid data
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * throw new ValidationError('Validation failed', {
62
+ * email: 'Invalid email format',
63
+ * age: 'Must be a positive number'
64
+ * });
65
+ * ```
66
+ */
67
+ export class ValidationError extends BindraError {
68
+ /**
69
+ * Creates a new ValidationError
70
+ *
71
+ * @param message - Human-readable error message
72
+ * @param fields - Map of field names to error messages (optional)
73
+ */
74
+ constructor(message, fields) {
75
+ super(message, 'VALIDATION_ERROR', { fields });
76
+ this.fields = fields;
77
+ this.name = 'ValidationError';
78
+ }
79
+ }
80
+ /**
81
+ * Permission/authorization errors
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * throw new PermissionError('Insert operation not allowed');
86
+ * ```
87
+ */
88
+ export class PermissionError extends BindraError {
89
+ /**
90
+ * Creates a new PermissionError
91
+ *
92
+ * @param message - Human-readable error message
93
+ * @param operation - The operation that was denied (optional)
94
+ */
95
+ constructor(message, operation) {
96
+ super(message, 'PERMISSION_DENIED', { operation });
97
+ this.operation = operation;
98
+ this.name = 'PermissionError';
99
+ }
100
+ }
101
+ /**
102
+ * Configuration errors
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * throw new ConfigurationError('Invalid DataSource configuration');
107
+ * ```
108
+ */
109
+ export class ConfigurationError extends BindraError {
110
+ /**
111
+ * Creates a new ConfigurationError
112
+ *
113
+ * @param message - Human-readable error message
114
+ * @param config - The invalid configuration (optional)
115
+ */
116
+ constructor(message, config) {
117
+ super(message, 'CONFIGURATION_ERROR', { config });
118
+ this.config = config;
119
+ this.name = 'ConfigurationError';
120
+ }
121
+ }
122
+ /**
123
+ * Type guard to check if an error is a BindraError
124
+ *
125
+ * @param error - The error to check
126
+ * @returns True if the error is a BindraError
127
+ */
128
+ export function isBindraError(error) {
129
+ return error instanceof BindraError;
130
+ }
131
+ /**
132
+ * Type guard to check if an error is a NetworkError
133
+ *
134
+ * @param error - The error to check
135
+ * @returns True if the error is a NetworkError
136
+ */
137
+ export function isNetworkError(error) {
138
+ return error instanceof NetworkError;
139
+ }
140
+ /**
141
+ * Type guard to check if an error is a ValidationError
142
+ *
143
+ * @param error - The error to check
144
+ * @returns True if the error is a ValidationError
145
+ */
146
+ export function isValidationError(error) {
147
+ return error instanceof ValidationError;
148
+ }
149
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC;;;;;;OAMG;IACH,YACE,OAAe,EACR,IAAY,EACZ,OAAa;QAEpB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAAM;QAGpB,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAE1B,iFAAiF;QACjF,IAAI,OAAQ,KAAa,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;YAC1D,KAAa,CAAC,iBAAiB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,YAAa,SAAQ,WAAW;IAC3C;;;;;;OAMG;IACH,YACE,OAAe,EACR,UAAmB,EACnB,QAAc;QAErB,KAAK,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;QAHnD,eAAU,GAAV,UAAU,CAAS;QACnB,aAAQ,GAAR,QAAQ,CAAM;QAGrB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,eAAgB,SAAQ,WAAW;IAC9C;;;;;OAKG;IACH,YACE,OAAe,EACR,MAA+B;QAEtC,KAAK,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAFxC,WAAM,GAAN,MAAM,CAAyB;QAGtC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,eAAgB,SAAQ,WAAW;IAC9C;;;;;OAKG;IACH,YACE,OAAe,EACR,SAAkB;QAEzB,KAAK,CAAC,OAAO,EAAE,mBAAmB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAF5C,cAAS,GAAT,SAAS,CAAS;QAGzB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,kBAAmB,SAAQ,WAAW;IACjD;;;;;OAKG;IACH,YACE,OAAe,EACR,MAAY;QAEnB,KAAK,CAAC,OAAO,EAAE,qBAAqB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAF3C,WAAM,GAAN,MAAM,CAAM;QAGnB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,KAAK,YAAY,WAAW,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,KAAK,YAAY,YAAY,CAAC;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,KAAK,YAAY,eAAe,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Field validation rules
3
+ */
4
+ export interface FieldValidation<T extends Record<string, any>> {
5
+ /** Whether the field is required */
6
+ required?: boolean;
7
+ /** Data type validation */
8
+ type?: 'string' | 'number' | 'boolean' | 'date' | 'email' | 'url' | 'array' | 'object';
9
+ /** Minimum value (for numbers) or length (for strings/arrays) */
10
+ min?: number;
11
+ /** Maximum value (for numbers) or length (for strings/arrays) */
12
+ max?: number;
13
+ /** RegEx pattern for string validation */
14
+ pattern?: RegExp;
15
+ /** Custom validation function. Return true for valid, false or error message for invalid */
16
+ custom?: (value: any, record: Partial<T>) => boolean | string | Promise<boolean | string>;
17
+ /** Error message override */
18
+ message?: string;
19
+ }
20
+ /**
21
+ * Field configuration with validation
22
+ */
23
+ export interface FieldConfig<T extends Record<string, any>> {
24
+ /** Field name */
25
+ name: keyof T;
26
+ /** Display label */
27
+ label?: string;
28
+ /** Validation rules */
29
+ validation?: FieldValidation<T>;
30
+ /** Default value */
31
+ defaultValue?: any;
32
+ /** Computed field function */
33
+ computed?: (record: T) => any;
34
+ /** Read-only field (won't be validated or saved) */
35
+ readOnly?: boolean;
36
+ /** Transform value before validation */
37
+ transform?: (value: any) => any;
38
+ }
39
+ /**
40
+ * Validation utility class
41
+ */
42
+ export declare class Validator<T extends Record<string, any>> {
43
+ private fields;
44
+ constructor(fields: FieldConfig<T>[]);
45
+ /**
46
+ * Validate a single field value
47
+ *
48
+ * @param fieldName - Name of the field to validate
49
+ * @param value - Value to validate
50
+ * @param record - Full record for context (used in custom validators)
51
+ * @returns Error message if invalid, null if valid
52
+ */
53
+ validateField(fieldName: keyof T, value: any, record?: Partial<T>): Promise<string | null>;
54
+ /**
55
+ * Validate a complete record
56
+ *
57
+ * @param record - Record to validate
58
+ * @param options - Validation options
59
+ * @returns Object with field errors, or null if valid
60
+ */
61
+ validateRecord(record: Partial<T>, options?: {
62
+ skipReadOnly?: boolean;
63
+ skipComputed?: boolean;
64
+ }): Promise<Record<string, string> | null>;
65
+ /**
66
+ * Apply default values to a record
67
+ *
68
+ * @param record - Partial record to apply defaults to
69
+ * @returns Record with defaults applied
70
+ */
71
+ applyDefaults(record: Partial<T>): Partial<T>;
72
+ /**
73
+ * Apply computed fields to a record
74
+ *
75
+ * @param record - Record to compute fields for
76
+ * @returns Record with computed fields
77
+ */
78
+ applyComputed(record: T): T;
79
+ /**
80
+ * Check if a value is empty
81
+ */
82
+ private isEmpty;
83
+ /**
84
+ * Validate type
85
+ */
86
+ private validateType;
87
+ /**
88
+ * Validate range (min/max)
89
+ */
90
+ private validateRange;
91
+ /**
92
+ * Get field configuration by name
93
+ */
94
+ getField(name: keyof T): FieldConfig<T> | undefined;
95
+ /**
96
+ * Check if a field exists
97
+ */
98
+ hasField(name: keyof T): boolean;
99
+ }
100
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC5D,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IAEvF,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;IAE1F,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IACxD,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC,CAAC;IAEd,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,uBAAuB;IACvB,UAAU,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAEhC,oBAAoB;IACpB,YAAY,CAAC,EAAE,GAAG,CAAC;IAEnB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,GAAG,CAAC;IAE9B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,wCAAwC;IACxC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;CACjC;AAED;;GAEG;AACH,qBAAa,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IACtC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE;IAE5C;;;;;;;OAOG;IACG,aAAa,CACjB,SAAS,EAAE,MAAM,CAAC,EAClB,KAAK,EAAE,GAAG,EACV,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAqDzB;;;;;;OAMG;IACG,cAAc,CAClB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAClB,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAO,GAC/D,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAsBzC;;;;;OAKG;IACH,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAY7C;;;;;OAKG;IACH,aAAa,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC;IAY3B;;OAEG;IACH,OAAO,CAAC,OAAO;IASf;;OAEG;IACH,OAAO,CAAC,YAAY;IAgEpB;;OAEG;IACH,OAAO,CAAC,aAAa;IA0BrB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS;IAInD;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO;CAGjC"}
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Validation utility class
3
+ */
4
+ export class Validator {
5
+ constructor(fields) {
6
+ this.fields = fields;
7
+ }
8
+ /**
9
+ * Validate a single field value
10
+ *
11
+ * @param fieldName - Name of the field to validate
12
+ * @param value - Value to validate
13
+ * @param record - Full record for context (used in custom validators)
14
+ * @returns Error message if invalid, null if valid
15
+ */
16
+ async validateField(fieldName, value, record) {
17
+ const field = this.fields.find(f => f.name === fieldName);
18
+ if (!field?.validation)
19
+ return null;
20
+ const v = field.validation;
21
+ const fieldLabel = field.label || String(fieldName);
22
+ // Transform value if transformer provided
23
+ if (field.transform) {
24
+ value = field.transform(value);
25
+ }
26
+ // Required check
27
+ if (v.required && this.isEmpty(value)) {
28
+ return v.message || `${fieldLabel} is required`;
29
+ }
30
+ // If value is empty and not required, skip other validations
31
+ if (this.isEmpty(value) && !v.required) {
32
+ return null;
33
+ }
34
+ // Type validation
35
+ if (v.type) {
36
+ const typeError = this.validateType(fieldLabel, value, v.type);
37
+ if (typeError)
38
+ return v.message || typeError;
39
+ }
40
+ // Min/Max validation
41
+ if (v.min !== undefined || v.max !== undefined) {
42
+ const rangeError = this.validateRange(fieldLabel, value, v.min, v.max);
43
+ if (rangeError)
44
+ return v.message || rangeError;
45
+ }
46
+ // Pattern validation
47
+ if (v.pattern && typeof value === 'string') {
48
+ if (!v.pattern.test(value)) {
49
+ return v.message || `${fieldLabel} format is invalid`;
50
+ }
51
+ }
52
+ // Custom validation
53
+ if (v.custom) {
54
+ const result = await v.custom(value, record || {});
55
+ if (typeof result === 'string')
56
+ return result;
57
+ if (result === false) {
58
+ return v.message || `${fieldLabel} validation failed`;
59
+ }
60
+ }
61
+ return null;
62
+ }
63
+ /**
64
+ * Validate a complete record
65
+ *
66
+ * @param record - Record to validate
67
+ * @param options - Validation options
68
+ * @returns Object with field errors, or null if valid
69
+ */
70
+ async validateRecord(record, options = {}) {
71
+ const errors = {};
72
+ const { skipReadOnly = true, skipComputed = true } = options;
73
+ // Validate each field
74
+ const validationPromises = this.fields.map(async (field) => {
75
+ // Skip read-only and computed fields
76
+ if ((skipReadOnly && field.readOnly) || (skipComputed && field.computed)) {
77
+ return;
78
+ }
79
+ const error = await this.validateField(field.name, record[field.name], record);
80
+ if (error) {
81
+ errors[String(field.name)] = error;
82
+ }
83
+ });
84
+ await Promise.all(validationPromises);
85
+ return Object.keys(errors).length > 0 ? errors : null;
86
+ }
87
+ /**
88
+ * Apply default values to a record
89
+ *
90
+ * @param record - Partial record to apply defaults to
91
+ * @returns Record with defaults applied
92
+ */
93
+ applyDefaults(record) {
94
+ const result = { ...record };
95
+ for (const field of this.fields) {
96
+ if (field.defaultValue !== undefined && result[field.name] === undefined) {
97
+ result[field.name] = field.defaultValue;
98
+ }
99
+ }
100
+ return result;
101
+ }
102
+ /**
103
+ * Apply computed fields to a record
104
+ *
105
+ * @param record - Record to compute fields for
106
+ * @returns Record with computed fields
107
+ */
108
+ applyComputed(record) {
109
+ const result = { ...record };
110
+ for (const field of this.fields) {
111
+ if (field.computed) {
112
+ result[field.name] = field.computed(record);
113
+ }
114
+ }
115
+ return result;
116
+ }
117
+ /**
118
+ * Check if a value is empty
119
+ */
120
+ isEmpty(value) {
121
+ return (value === null ||
122
+ value === undefined ||
123
+ value === '' ||
124
+ (Array.isArray(value) && value.length === 0));
125
+ }
126
+ /**
127
+ * Validate type
128
+ */
129
+ validateType(fieldLabel, value, type) {
130
+ switch (type) {
131
+ case 'string':
132
+ if (typeof value !== 'string') {
133
+ return `${fieldLabel} must be a string`;
134
+ }
135
+ break;
136
+ case 'number':
137
+ if (typeof value !== 'number' || isNaN(value)) {
138
+ return `${fieldLabel} must be a number`;
139
+ }
140
+ break;
141
+ case 'boolean':
142
+ if (typeof value !== 'boolean') {
143
+ return `${fieldLabel} must be a boolean`;
144
+ }
145
+ break;
146
+ case 'date':
147
+ const date = new Date(value);
148
+ if (isNaN(date.getTime())) {
149
+ return `${fieldLabel} must be a valid date`;
150
+ }
151
+ break;
152
+ case 'email':
153
+ if (typeof value !== 'string' || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
154
+ return `${fieldLabel} must be a valid email`;
155
+ }
156
+ break;
157
+ case 'url':
158
+ if (typeof value !== 'string') {
159
+ return `${fieldLabel} must be a valid URL`;
160
+ }
161
+ try {
162
+ new URL(value);
163
+ }
164
+ catch {
165
+ return `${fieldLabel} must be a valid URL`;
166
+ }
167
+ break;
168
+ case 'array':
169
+ if (!Array.isArray(value)) {
170
+ return `${fieldLabel} must be an array`;
171
+ }
172
+ break;
173
+ case 'object':
174
+ if (typeof value !== 'object' || Array.isArray(value) || value === null) {
175
+ return `${fieldLabel} must be an object`;
176
+ }
177
+ break;
178
+ }
179
+ return null;
180
+ }
181
+ /**
182
+ * Validate range (min/max)
183
+ */
184
+ validateRange(fieldLabel, value, min, max) {
185
+ if (typeof value === 'number') {
186
+ if (min !== undefined && value < min) {
187
+ return `${fieldLabel} must be at least ${min}`;
188
+ }
189
+ if (max !== undefined && value > max) {
190
+ return `${fieldLabel} must be at most ${max}`;
191
+ }
192
+ }
193
+ else if (typeof value === 'string' || Array.isArray(value)) {
194
+ const length = value.length;
195
+ if (min !== undefined && length < min) {
196
+ return `${fieldLabel} must have at least ${min} ${Array.isArray(value) ? 'items' : 'characters'}`;
197
+ }
198
+ if (max !== undefined && length > max) {
199
+ return `${fieldLabel} must have at most ${max} ${Array.isArray(value) ? 'items' : 'characters'}`;
200
+ }
201
+ }
202
+ return null;
203
+ }
204
+ /**
205
+ * Get field configuration by name
206
+ */
207
+ getField(name) {
208
+ return this.fields.find(f => f.name === name);
209
+ }
210
+ /**
211
+ * Check if a field exists
212
+ */
213
+ hasField(name) {
214
+ return this.fields.some(f => f.name === name);
215
+ }
216
+ }
217
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Bindra TypeScript Usage Examples
3
+ *
4
+ * This file demonstrates how to use Bindra with TypeScript for type-safe
5
+ * reactive data management.
6
+ */
7
+ import { DataSource } from './index';
8
+ import type { Signal } from './index';
9
+ interface User {
10
+ id: number;
11
+ name: string;
12
+ email: string;
13
+ age: number;
14
+ isActive?: boolean;
15
+ }
16
+ declare const usersDS: DataSource<User>;
17
+ declare function crudExample(): Promise<void>;
18
+ interface Product {
19
+ id: number;
20
+ name: string;
21
+ price: number;
22
+ category: string;
23
+ inStock: boolean;
24
+ }
25
+ declare const productsDS: DataSource<Product>;
26
+ declare function remoteExample(): Promise<void>;
27
+ declare class UserForm {
28
+ private ds;
29
+ private unsubscribers;
30
+ constructor(dataSource: DataSource<User>);
31
+ private bindToCurrentRecord;
32
+ private populateForm;
33
+ save(formData: Partial<User>): Promise<void>;
34
+ cleanup(): void;
35
+ }
36
+ interface Task {
37
+ id: number;
38
+ title: string;
39
+ completed: boolean;
40
+ priority: 'low' | 'medium' | 'high';
41
+ dueDate: Date;
42
+ }
43
+ declare const tasksDS: DataSource<Task>;
44
+ declare const taskStats: {
45
+ total: Signal<number>;
46
+ completed: Signal<number>;
47
+ pending: Signal<number>;
48
+ highPriority: Signal<number>;
49
+ };
50
+ declare function isValidUser(obj: any): obj is User;
51
+ export { usersDS, productsDS, tasksDS, crudExample, remoteExample, UserForm, isValidUser, taskStats };
52
+ //# sourceMappingURL=examples.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"examples.d.ts","sourceRoot":"","sources":["../src/examples.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAA0B,MAAM,SAAS,CAAC;AAC7D,OAAO,KAAK,EAAE,MAAM,EAAoB,MAAM,SAAS,CAAC;AAMxD,UAAU,IAAI;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAGD,QAAA,MAAM,OAAO,kBAMX,CAAC;AAoBH,iBAAe,WAAW,kBA4BzB;AAwHD,UAAU,OAAO;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAMD,QAAA,MAAM,UAAU,qBAA0C,CAAC;AAG3D,iBAAe,aAAa,kBAmB3B;AAMD,cAAM,QAAQ;IACZ,OAAO,CAAC,EAAE,CAAmB;IAC7B,OAAO,CAAC,aAAa,CAAyB;gBAElC,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC;IAKxC,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,YAAY;IAMd,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IASlD,OAAO,IAAI,IAAI;CAGhB;AAUD,UAAU,IAAI;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE,IAAI,CAAC;CACf;AAED,QAAA,MAAM,OAAO,kBAKX,CAAC;AAGH,QAAA,MAAM,SAAS;;;;;CAKd,CAAC;AAqBF,iBAAS,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,IAAI,CAQ1C;AAgBD,OAAO,EACL,OAAO,EACP,UAAU,EACV,OAAO,EACP,WAAW,EACX,aAAa,EACb,QAAQ,EACR,WAAW,EACX,SAAS,EACV,CAAC"}