taro-bluetooth-print 2.9.0 → 2.9.2

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 (65) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/README.md +53 -4
  3. package/dist/index.cjs.js +1 -1
  4. package/dist/index.es.js +1 -1
  5. package/dist/index.umd.js +1 -1
  6. package/dist/types/core/di/Container.d.ts +84 -0
  7. package/dist/types/core/di/Tokens.d.ts +29 -0
  8. package/dist/types/core/di/index.d.ts +3 -0
  9. package/dist/types/core/event/EventBus.d.ts +66 -0
  10. package/dist/types/core/event/index.d.ts +2 -0
  11. package/dist/types/core/index.d.ts +5 -4
  12. package/dist/types/core/plugin/PluginManager.d.ts +64 -0
  13. package/dist/types/core/plugin/index.d.ts +2 -0
  14. package/dist/types/device/MultiPrinterManager.d.ts +2 -0
  15. package/dist/types/factory/di-factory.d.ts +52 -0
  16. package/dist/types/index.d.ts +5 -1
  17. package/dist/types/providers/ServiceProvider.d.ts +56 -0
  18. package/dist/types/providers/index.d.ts +2 -0
  19. package/dist/types/template/TemplateEngine.d.ts +24 -68
  20. package/dist/types/template/engines/TemplateRenderer.d.ts +71 -0
  21. package/dist/types/template/parsers/TemplateParser.d.ts +23 -0
  22. package/dist/types/utils/index.d.ts +8 -0
  23. package/dist/types/utils/logger.d.ts +4 -3
  24. package/dist/types/utils/outputLimiter.d.ts +87 -0
  25. package/dist/types/utils/validation.d.ts +11 -309
  26. package/dist/types/utils/validators/array.d.ts +19 -0
  27. package/dist/types/utils/validators/buffer.d.ts +18 -0
  28. package/dist/types/utils/validators/chain.d.ts +31 -0
  29. package/dist/types/utils/validators/common.d.ts +22 -0
  30. package/dist/types/utils/validators/number.d.ts +20 -0
  31. package/dist/types/utils/validators/object.d.ts +24 -0
  32. package/dist/types/utils/validators/printer.d.ts +40 -0
  33. package/dist/types/utils/validators/types.d.ts +125 -0
  34. package/dist/types/utils/validators/uuid.d.ts +23 -0
  35. package/package.json +1 -1
  36. package/src/core/BluetoothPrinter.ts +2 -1
  37. package/src/core/di/Container.ts +332 -0
  38. package/src/core/di/Tokens.ts +45 -0
  39. package/src/core/di/index.ts +3 -0
  40. package/src/core/event/EventBus.ts +251 -0
  41. package/src/core/event/index.ts +2 -0
  42. package/src/core/index.ts +10 -4
  43. package/src/core/plugin/PluginManager.ts +161 -0
  44. package/src/core/plugin/index.ts +2 -0
  45. package/src/device/MultiPrinterManager.ts +15 -6
  46. package/src/factory/di-factory.ts +61 -0
  47. package/src/index.ts +50 -1
  48. package/src/providers/ServiceProvider.ts +213 -0
  49. package/src/providers/index.ts +2 -0
  50. package/src/template/TemplateEngine.ts +27 -792
  51. package/src/template/engines/TemplateRenderer.ts +762 -0
  52. package/src/template/parsers/TemplateParser.ts +94 -0
  53. package/src/utils/index.ts +9 -0
  54. package/src/utils/logger.ts +17 -4
  55. package/src/utils/outputLimiter.ts +227 -0
  56. package/src/utils/validation.ts +21 -1138
  57. package/src/utils/validators/array.ts +95 -0
  58. package/src/utils/validators/buffer.ts +81 -0
  59. package/src/utils/validators/chain.ts +181 -0
  60. package/src/utils/validators/common.ts +216 -0
  61. package/src/utils/validators/number.ts +101 -0
  62. package/src/utils/validators/object.ts +63 -0
  63. package/src/utils/validators/printer.ts +294 -0
  64. package/src/utils/validators/types.ts +105 -0
  65. package/src/utils/validators/uuid.ts +49 -0
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Array validation
3
+ */
4
+
5
+ import { ValidationCodes, type ValidationError, type ValidationResult } from './types';
6
+
7
+ /**
8
+ * Validate an array of items
9
+ *
10
+ * @param items - Array to validate
11
+ * @param itemValidator - Validator function for each item
12
+ * @param options - Array validation options
13
+ * @returns Validation result
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const result = validateArray(items, item => validatePrintJob(item, schema), { minItems: 1, maxItems: 100 });
18
+ * ```
19
+ */
20
+ export function validateArray<T>(
21
+ items: unknown,
22
+ itemValidator: (item: T, index: number) => ValidationResult,
23
+ options?: {
24
+ required?: boolean;
25
+ minItems?: number;
26
+ maxItems?: number;
27
+ }
28
+ ): ValidationResult {
29
+ const errors: ValidationError[] = [];
30
+ const warnings: ValidationError[] = [];
31
+
32
+ if (items === undefined || items === null) {
33
+ if (options?.required) {
34
+ errors.push({
35
+ field: 'array',
36
+ message: 'Array is required',
37
+ code: ValidationCodes.REQUIRED,
38
+ });
39
+ }
40
+ return { valid: errors.length === 0, errors, warnings };
41
+ }
42
+
43
+ if (!Array.isArray(items)) {
44
+ errors.push({
45
+ field: 'array',
46
+ message: 'Expected an array',
47
+ code: ValidationCodes.INVALID_TYPE,
48
+ value: typeof items,
49
+ });
50
+ return { valid: false, errors, warnings };
51
+ }
52
+
53
+ if (options?.minItems !== undefined && items.length < options.minItems) {
54
+ errors.push({
55
+ field: 'array',
56
+ message: `Array must have at least ${options.minItems} items`,
57
+ code: ValidationCodes.ARRAY_TOO_SHORT,
58
+ value: items.length,
59
+ });
60
+ }
61
+
62
+ if (options?.maxItems !== undefined && items.length > options.maxItems) {
63
+ errors.push({
64
+ field: 'array',
65
+ message: `Array must have at most ${options.maxItems} items`,
66
+ code: ValidationCodes.ARRAY_TOO_LONG,
67
+ value: items.length,
68
+ });
69
+ }
70
+
71
+ // Validate each item
72
+ for (let i = 0; i < items.length; i++) {
73
+ const itemResult = itemValidator(items[i] as T, i);
74
+ errors.push(
75
+ ...itemResult.errors.map(err => ({
76
+ ...err,
77
+ field: `${err.field}[${i}]`,
78
+ }))
79
+ );
80
+ if (itemResult.warnings) {
81
+ warnings.push(
82
+ ...itemResult.warnings.map(w => ({
83
+ ...w,
84
+ field: `${w.field}[${i}]`,
85
+ }))
86
+ );
87
+ }
88
+ }
89
+
90
+ return {
91
+ valid: errors.length === 0,
92
+ errors,
93
+ ...(warnings.length > 0 ? { warnings } : {}),
94
+ };
95
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * ArrayBuffer validation
3
+ */
4
+
5
+ import { ValidationCodes, type ValidationError, type ValidationResult } from './types';
6
+
7
+ /**
8
+ * Validate an ArrayBuffer
9
+ *
10
+ * @param buffer - Buffer to validate
11
+ * @param options - Validation options
12
+ * @returns Validation result
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const result = isValidBuffer(data, { minSize: 1, maxSize: 1024 * 1024 });
17
+ * ```
18
+ */
19
+ export function isValidBuffer(
20
+ buffer: unknown,
21
+ options?: {
22
+ minSize?: number;
23
+ maxSize?: number;
24
+ required?: boolean;
25
+ }
26
+ ): ValidationResult {
27
+ const errors: ValidationError[] = [];
28
+ const warnings: ValidationError[] = [];
29
+
30
+ if (!(buffer instanceof ArrayBuffer)) {
31
+ errors.push({
32
+ field: 'buffer',
33
+ message: 'Expected an ArrayBuffer',
34
+ code: ValidationCodes.INVALID_TYPE,
35
+ value: typeof buffer,
36
+ });
37
+ return {
38
+ valid: false,
39
+ errors,
40
+ ...(warnings.length > 0 ? { warnings } : {}),
41
+ };
42
+ }
43
+
44
+ const byteLength = buffer.byteLength;
45
+ // When required is true without explicit minSize, treat empty buffer as TOO_SHORT
46
+ const effectiveMinSize =
47
+ options?.required && options?.minSize === undefined ? 1 : options?.minSize;
48
+
49
+ if (effectiveMinSize !== undefined && byteLength < effectiveMinSize) {
50
+ errors.push({
51
+ field: 'buffer',
52
+ message: `Buffer must be at least ${effectiveMinSize} bytes`,
53
+ code: ValidationCodes.TOO_SHORT,
54
+ value: byteLength,
55
+ });
56
+ }
57
+
58
+ if (options?.maxSize !== undefined && byteLength > options.maxSize) {
59
+ errors.push({
60
+ field: 'buffer',
61
+ message: `Buffer exceeds maximum size of ${options.maxSize} bytes`,
62
+ code: ValidationCodes.TOO_LONG,
63
+ value: byteLength,
64
+ });
65
+ }
66
+
67
+ if (byteLength === 0) {
68
+ warnings.push({
69
+ field: 'buffer',
70
+ message: 'Buffer is empty',
71
+ code: ValidationCodes.EMPTY_ARRAY,
72
+ value: byteLength,
73
+ });
74
+ }
75
+
76
+ return {
77
+ valid: errors.length === 0,
78
+ errors,
79
+ ...(warnings.length > 0 ? { warnings } : {}),
80
+ };
81
+ }
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Chainable validation helper
3
+ */
4
+
5
+ import { ValidationCodes, type ValidationError, type ValidationResult } from './types';
6
+
7
+ export interface ChainableValidator {
8
+ addError(message: string, code: string): ChainableValidator;
9
+ required(): ChainableValidator;
10
+ string(): ChainableValidator;
11
+ number(): ChainableValidator;
12
+ integer(): ChainableValidator;
13
+ range(min: number, max: number): ChainableValidator;
14
+ length(min: number, max: number): ChainableValidator;
15
+ pattern(regex: RegExp, message?: string): ChainableValidator;
16
+ oneOf<T>(values: readonly T[], message?: string): ChainableValidator;
17
+ result(): ValidationResult;
18
+ }
19
+
20
+ /**
21
+ * Create a chainable validation helper
22
+ *
23
+ * @param value - Value to validate
24
+ * @param field - Field name
25
+ * @returns Chainable validator
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const result = check(value, 'timeout')
30
+ * .required()
31
+ * .number()
32
+ * .range(0, 30000)
33
+ * .integer()
34
+ * .result();
35
+ * ```
36
+ */
37
+ export function check(value: unknown, field: string): ChainableValidator {
38
+ const errors: ValidationError[] = [];
39
+
40
+ const self: ChainableValidator = {
41
+ /** Add error manually */
42
+ addError(message: string, code: string) {
43
+ errors.push({ field, message, code, value });
44
+ return this;
45
+ },
46
+
47
+ /** Validate required */
48
+ required() {
49
+ if (value === undefined || value === null || value === '') {
50
+ errors.push({
51
+ field,
52
+ message: `${field} is required`,
53
+ code: ValidationCodes.REQUIRED,
54
+ value,
55
+ });
56
+ }
57
+ return this;
58
+ },
59
+
60
+ /** Validate type is string */
61
+ string() {
62
+ if (value !== undefined && value !== null && typeof value !== 'string') {
63
+ errors.push({
64
+ field,
65
+ message: `${field} must be a string`,
66
+ code: ValidationCodes.INVALID_TYPE,
67
+ value: typeof value,
68
+ });
69
+ }
70
+ return this;
71
+ },
72
+
73
+ /** Validate type is number */
74
+ number() {
75
+ if (value !== undefined && value !== null && typeof value !== 'number') {
76
+ errors.push({
77
+ field,
78
+ message: `${field} must be a number`,
79
+ code: ValidationCodes.INVALID_TYPE,
80
+ value: typeof value,
81
+ });
82
+ }
83
+ return this;
84
+ },
85
+
86
+ /** Validate is integer */
87
+ integer() {
88
+ if (typeof value === 'number' && !Number.isInteger(value)) {
89
+ errors.push({
90
+ field,
91
+ message: `${field} must be an integer`,
92
+ code: ValidationCodes.INVALID_TYPE,
93
+ value,
94
+ });
95
+ }
96
+ return this;
97
+ },
98
+
99
+ /** Validate range */
100
+ range(min: number, max: number) {
101
+ if (typeof value === 'number') {
102
+ if (value < min) {
103
+ errors.push({
104
+ field,
105
+ message: `${field} must be at least ${min}`,
106
+ code: ValidationCodes.OUT_OF_RANGE,
107
+ value,
108
+ });
109
+ }
110
+ if (value > max) {
111
+ errors.push({
112
+ field,
113
+ message: `${field} must be at most ${max}`,
114
+ code: ValidationCodes.OUT_OF_RANGE,
115
+ value,
116
+ });
117
+ }
118
+ }
119
+ return this;
120
+ },
121
+
122
+ /** Validate string length */
123
+ length(min: number, max: number) {
124
+ if (typeof value === 'string') {
125
+ if (value.length < min) {
126
+ errors.push({
127
+ field,
128
+ message: `${field} must be at least ${min} characters`,
129
+ code: ValidationCodes.TOO_SHORT,
130
+ value,
131
+ });
132
+ }
133
+ if (value.length > max) {
134
+ errors.push({
135
+ field,
136
+ message: `${field} must be at most ${max} characters`,
137
+ code: ValidationCodes.TOO_LONG,
138
+ value,
139
+ });
140
+ }
141
+ }
142
+ return this;
143
+ },
144
+
145
+ /** Validate matches pattern */
146
+ pattern(regex: RegExp, message?: string) {
147
+ if (typeof value === 'string' && !regex.test(value)) {
148
+ errors.push({
149
+ field,
150
+ message: message ?? `${field} format is invalid`,
151
+ code: ValidationCodes.PATTERN_MISMATCH,
152
+ value,
153
+ });
154
+ }
155
+ return this;
156
+ },
157
+
158
+ /** Validate is one of values */
159
+ oneOf<T>(values: readonly T[], message?: string) {
160
+ if (!values.includes(value as T)) {
161
+ errors.push({
162
+ field,
163
+ message: message ?? `${field} must be one of: ${values.join(', ')}`,
164
+ code: ValidationCodes.INVALID_ENUM,
165
+ value,
166
+ });
167
+ }
168
+ return this;
169
+ },
170
+
171
+ /** Get validation result */
172
+ result() {
173
+ return {
174
+ valid: errors.length === 0,
175
+ errors,
176
+ };
177
+ },
178
+ };
179
+
180
+ return self;
181
+ }
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Common validation helpers
3
+ */
4
+
5
+ import { ValidationCodes, type ValidationError } from './types';
6
+
7
+ /**
8
+ * Common validation rules
9
+ */
10
+ export const CommonValidators = {
11
+ /** Required string (non-empty) */
12
+ requiredString: (field: string, value: unknown): ValidationError | null => {
13
+ if (value === undefined || value === null || value === '') {
14
+ return {
15
+ field,
16
+ message: `${field} is required`,
17
+ code: ValidationCodes.REQUIRED,
18
+ value,
19
+ };
20
+ }
21
+ if (typeof value !== 'string') {
22
+ return {
23
+ field,
24
+ message: `${field} must be a string`,
25
+ code: ValidationCodes.INVALID_TYPE,
26
+ value,
27
+ };
28
+ }
29
+ return null;
30
+ },
31
+
32
+ /** Positive number */
33
+ positiveNumber: (field: string, value: unknown): ValidationError | null => {
34
+ if (typeof value !== 'number') {
35
+ return {
36
+ field,
37
+ message: `${field} must be a number`,
38
+ code: ValidationCodes.INVALID_TYPE,
39
+ value,
40
+ };
41
+ }
42
+ if (isNaN(value)) {
43
+ return {
44
+ field,
45
+ message: `${field} must be a valid number`,
46
+ code: ValidationCodes.NOT_A_NUMBER,
47
+ value,
48
+ };
49
+ }
50
+ if (!isFinite(value)) {
51
+ return {
52
+ field,
53
+ message: `${field} must be a finite number`,
54
+ code: ValidationCodes.INFINITY_VALUE,
55
+ value,
56
+ };
57
+ }
58
+ if (value <= 0) {
59
+ return {
60
+ field,
61
+ message: `${field} must be positive`,
62
+ code: ValidationCodes.NEGATIVE_VALUE,
63
+ value,
64
+ };
65
+ }
66
+ return null;
67
+ },
68
+
69
+ /** Non-negative number */
70
+ nonNegativeNumber: (field: string, value: unknown): ValidationError | null => {
71
+ if (typeof value !== 'number') {
72
+ return {
73
+ field,
74
+ message: `${field} must be a number`,
75
+ code: ValidationCodes.INVALID_TYPE,
76
+ value,
77
+ };
78
+ }
79
+ if (isNaN(value)) {
80
+ return {
81
+ field,
82
+ message: `${field} must be a valid number`,
83
+ code: ValidationCodes.NOT_A_NUMBER,
84
+ value,
85
+ };
86
+ }
87
+ if (value < 0) {
88
+ return {
89
+ field,
90
+ message: `${field} cannot be negative`,
91
+ code: ValidationCodes.NEGATIVE_VALUE,
92
+ value,
93
+ };
94
+ }
95
+ return null;
96
+ },
97
+
98
+ /** Array with items */
99
+ nonEmptyArray: (field: string, value: unknown): ValidationError | null => {
100
+ if (!Array.isArray(value)) {
101
+ return {
102
+ field,
103
+ message: `${field} must be an array`,
104
+ code: ValidationCodes.INVALID_TYPE,
105
+ value,
106
+ };
107
+ }
108
+ if (value.length === 0) {
109
+ return {
110
+ field,
111
+ message: `${field} cannot be empty`,
112
+ code: ValidationCodes.EMPTY_ARRAY,
113
+ value,
114
+ };
115
+ }
116
+ return null;
117
+ },
118
+
119
+ /** In range */
120
+ inRange: (field: string, value: unknown, min: number, max: number): ValidationError | null => {
121
+ if (typeof value !== 'number') {
122
+ return {
123
+ field,
124
+ message: `${field} must be a number`,
125
+ code: ValidationCodes.INVALID_TYPE,
126
+ value,
127
+ };
128
+ }
129
+ if (value < min || value > max) {
130
+ return {
131
+ field,
132
+ message: `${field} must be between ${min} and ${max}`,
133
+ code: ValidationCodes.OUT_OF_RANGE,
134
+ value,
135
+ };
136
+ }
137
+ return null;
138
+ },
139
+
140
+ /** String length */
141
+ stringLength: (
142
+ field: string,
143
+ value: unknown,
144
+ min: number,
145
+ max: number
146
+ ): ValidationError | null => {
147
+ if (typeof value !== 'string') {
148
+ return {
149
+ field,
150
+ message: `${field} must be a string`,
151
+ code: ValidationCodes.INVALID_TYPE,
152
+ value,
153
+ };
154
+ }
155
+ if (value.length < min) {
156
+ return {
157
+ field,
158
+ message: `${field} must be at least ${min} characters`,
159
+ code: ValidationCodes.TOO_SHORT,
160
+ value,
161
+ };
162
+ }
163
+ if (value.length > max) {
164
+ return {
165
+ field,
166
+ message: `${field} must be at most ${max} characters`,
167
+ code: ValidationCodes.TOO_LONG,
168
+ value,
169
+ };
170
+ }
171
+ return null;
172
+ },
173
+
174
+ /** Matches pattern */
175
+ matchesPattern: (
176
+ field: string,
177
+ value: unknown,
178
+ pattern: RegExp,
179
+ message?: string
180
+ ): ValidationError | null => {
181
+ if (typeof value !== 'string') {
182
+ return {
183
+ field,
184
+ message: `${field} must be a string`,
185
+ code: ValidationCodes.INVALID_TYPE,
186
+ value,
187
+ };
188
+ }
189
+ if (!pattern.test(value)) {
190
+ return {
191
+ field,
192
+ message: message ?? `${field} format is invalid`,
193
+ code: ValidationCodes.PATTERN_MISMATCH,
194
+ value,
195
+ };
196
+ }
197
+ return null;
198
+ },
199
+
200
+ /** Is one of enum values */
201
+ isEnum: <T extends string>(
202
+ field: string,
203
+ value: unknown,
204
+ enumValues: readonly T[]
205
+ ): ValidationError | null => {
206
+ if (!enumValues.includes(value as T)) {
207
+ return {
208
+ field,
209
+ message: `${field} must be one of: ${enumValues.join(', ')}`,
210
+ code: ValidationCodes.INVALID_ENUM,
211
+ value,
212
+ };
213
+ }
214
+ return null;
215
+ },
216
+ };
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Numeric range validation
3
+ */
4
+
5
+ import { ValidationCodes, type ValidationError, type ValidationResult } from './types';
6
+
7
+ /**
8
+ * Validate numeric range
9
+ *
10
+ * @param value - Value to validate
11
+ * @param field - Field name for error messages
12
+ * @param options - Range options
13
+ * @returns Validation result
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const result = validateRange(value, 'timeout', { min: 0, max: 30000, integer: true });
18
+ * ```
19
+ */
20
+ export function validateRange(
21
+ value: unknown,
22
+ field: string,
23
+ options?: {
24
+ required?: boolean;
25
+ min?: number;
26
+ max?: number;
27
+ integer?: boolean;
28
+ }
29
+ ): ValidationResult {
30
+ const errors: ValidationError[] = [];
31
+
32
+ if (value === undefined || value === null) {
33
+ if (options?.required) {
34
+ errors.push({
35
+ field,
36
+ message: `${field} is required`,
37
+ code: ValidationCodes.REQUIRED,
38
+ });
39
+ }
40
+ return { valid: errors.length === 0, errors };
41
+ }
42
+
43
+ if (typeof value !== 'number') {
44
+ errors.push({
45
+ field,
46
+ message: `${field} must be a number`,
47
+ code: ValidationCodes.INVALID_TYPE,
48
+ value: typeof value,
49
+ });
50
+ return { valid: false, errors };
51
+ }
52
+
53
+ if (isNaN(value)) {
54
+ errors.push({
55
+ field,
56
+ message: `${field} must be a valid number`,
57
+ code: ValidationCodes.NOT_A_NUMBER,
58
+ value,
59
+ });
60
+ return { valid: false, errors };
61
+ }
62
+
63
+ if (!isFinite(value)) {
64
+ errors.push({
65
+ field,
66
+ message: `${field} must be a finite number`,
67
+ code: ValidationCodes.INFINITY_VALUE,
68
+ value,
69
+ });
70
+ return { valid: false, errors };
71
+ }
72
+
73
+ if (options?.integer && !Number.isInteger(value)) {
74
+ errors.push({
75
+ field,
76
+ message: `${field} must be an integer`,
77
+ code: ValidationCodes.INVALID_TYPE,
78
+ value,
79
+ });
80
+ }
81
+
82
+ if (options?.min !== undefined && value < options.min) {
83
+ errors.push({
84
+ field,
85
+ message: `${field} must be at least ${options.min}`,
86
+ code: ValidationCodes.OUT_OF_RANGE,
87
+ value,
88
+ });
89
+ }
90
+
91
+ if (options?.max !== undefined && value > options.max) {
92
+ errors.push({
93
+ field,
94
+ message: `${field} must be at most ${options.max}`,
95
+ code: ValidationCodes.OUT_OF_RANGE,
96
+ value,
97
+ });
98
+ }
99
+
100
+ return { valid: errors.length === 0, errors };
101
+ }