@trustchex/react-native-sdk 1.163.7 → 1.163.10

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 (59) hide show
  1. package/TrustchexSDK.podspec +0 -1
  2. package/ios/VisionCameraPlugins/BarcodeScanner/BarcodeScannerFrameProcessorPlugin-Bridging-Header.h +9 -0
  3. package/ios/VisionCameraPlugins/BarcodeScanner/BarcodeScannerFrameProcessorPlugin.swift +173 -157
  4. package/lib/module/Shared/Components/QrCodeScannerCamera.js +15 -3
  5. package/lib/module/Shared/EIDReader/constants/eidConstants.js +65 -0
  6. package/lib/module/Shared/EIDReader/data/country.js +21 -44
  7. package/lib/module/Shared/EIDReader/data/countryInterface.js +1 -0
  8. package/lib/module/Shared/EIDReader/data/countryRegistry.js +65 -0
  9. package/lib/module/Shared/EIDReader/data/isoCountry.js +5 -1
  10. package/lib/module/Shared/EIDReader/data/unicodeCountry.js +5 -1
  11. package/lib/module/Shared/EIDReader/defaultFileSystem.js +4 -4
  12. package/lib/module/Shared/EIDReader/eidService.js +52 -51
  13. package/lib/module/Shared/EIDReader/lds/cvcaFile.js +2 -2
  14. package/lib/module/Shared/EIDReader/tlv/tlvCore.js +161 -0
  15. package/lib/module/Shared/EIDReader/tlv/tlvInputStream.js +4 -4
  16. package/lib/module/Shared/EIDReader/tlv/tlvOutputState.js +4 -4
  17. package/lib/module/Shared/EIDReader/tlv/tlvOutputStream.js +13 -11
  18. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/index.js +0 -2
  19. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/scanCodes.js +2 -0
  20. package/lib/typescript/src/Shared/Components/QrCodeScannerCamera.d.ts.map +1 -1
  21. package/lib/typescript/src/Shared/EIDReader/constants/eidConstants.d.ts +58 -0
  22. package/lib/typescript/src/Shared/EIDReader/constants/eidConstants.d.ts.map +1 -0
  23. package/lib/typescript/src/Shared/EIDReader/data/country.d.ts +4 -5
  24. package/lib/typescript/src/Shared/EIDReader/data/country.d.ts.map +1 -1
  25. package/lib/typescript/src/Shared/EIDReader/data/countryInterface.d.ts +21 -0
  26. package/lib/typescript/src/Shared/EIDReader/data/countryInterface.d.ts.map +1 -0
  27. package/lib/typescript/src/Shared/EIDReader/data/countryRegistry.d.ts +14 -0
  28. package/lib/typescript/src/Shared/EIDReader/data/countryRegistry.d.ts.map +1 -0
  29. package/lib/typescript/src/Shared/EIDReader/data/isoCountry.d.ts.map +1 -1
  30. package/lib/typescript/src/Shared/EIDReader/data/unicodeCountry.d.ts.map +1 -1
  31. package/lib/typescript/src/Shared/EIDReader/eidService.d.ts.map +1 -1
  32. package/lib/typescript/src/Shared/EIDReader/tlv/tlvCore.d.ts +22 -0
  33. package/lib/typescript/src/Shared/EIDReader/tlv/tlvCore.d.ts.map +1 -0
  34. package/lib/typescript/src/Shared/EIDReader/tlv/tlvOutputStream.d.ts +2 -2
  35. package/lib/typescript/src/Shared/EIDReader/tlv/tlvOutputStream.d.ts.map +1 -1
  36. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/index.d.ts +0 -2
  37. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/index.d.ts.map +1 -1
  38. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/scanCodes.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/Shared/Components/QrCodeScannerCamera.tsx +15 -2
  41. package/src/Shared/EIDReader/constants/eidConstants.ts +67 -0
  42. package/src/Shared/EIDReader/data/country.ts +16 -47
  43. package/src/Shared/EIDReader/data/countryInterface.ts +21 -0
  44. package/src/Shared/EIDReader/data/countryRegistry.ts +73 -0
  45. package/src/Shared/EIDReader/data/isoCountry.ts +4 -0
  46. package/src/Shared/EIDReader/data/unicodeCountry.ts +4 -0
  47. package/src/Shared/EIDReader/defaultFileSystem.ts +4 -4
  48. package/src/Shared/EIDReader/eidService.ts +58 -53
  49. package/src/Shared/EIDReader/lds/cvcaFile.ts +2 -2
  50. package/src/Shared/EIDReader/tlv/tlvCore.ts +170 -0
  51. package/src/Shared/EIDReader/tlv/tlvInputStream.ts +4 -4
  52. package/src/Shared/EIDReader/tlv/tlvOutputState.ts +4 -4
  53. package/src/Shared/EIDReader/tlv/tlvOutputStream.ts +13 -12
  54. package/src/Shared/VisionCameraPlugins/BarcodeScanner/index.ts +0 -4
  55. package/src/Shared/VisionCameraPlugins/BarcodeScanner/scanCodes.ts +2 -0
  56. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/components/BarcodeCamera.js +0 -66
  57. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/components/BarcodeCamera.d.ts +0 -13
  58. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/components/BarcodeCamera.d.ts.map +0 -1
  59. package/src/Shared/VisionCameraPlugins/BarcodeScanner/components/BarcodeCamera.tsx +0 -85
@@ -18,7 +18,6 @@ Pod::Spec.new do |s|
18
18
 
19
19
  # ML Kit dependencies
20
20
  s.dependency "MLKitTextRecognition", "7.0.0"
21
- s.dependency "MLKitBarcodeScanning", "8.0.0"
22
21
  s.dependency "MLKitFaceDetection", "8.0.0"
23
22
 
24
23
  # Camera dependency
@@ -0,0 +1,9 @@
1
+ #ifndef BarcodeScannerFrameProcessorPlugin_Bridging_Header_h
2
+ #define BarcodeScannerFrameProcessorPlugin_Bridging_Header_h
3
+
4
+ #if VISION_CAMERA_ENABLE_FRAME_PROCESSORS
5
+ #import <VisionCamera/FrameProcessorPlugin.h>
6
+ #import <VisionCamera/Frame.h>
7
+ #endif
8
+
9
+ #endif /* BarcodeScannerFrameProcessorPlugin_Bridging_Header_h */
@@ -1,172 +1,188 @@
1
1
  import Foundation
2
- import VisionCamera
3
2
  import Vision
3
+ import VisionCamera
4
4
 
5
5
  @objc(BarcodeScannerFrameProcessorPlugin)
6
6
  public class BarcodeScannerFrameProcessorPlugin: FrameProcessorPlugin {
7
7
 
8
- public override func callback(_ frame: Frame, withArguments arguments: [AnyHashable: Any]?) -> Any? {
9
- guard let imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer) else {
10
- return []
11
- }
8
+ public override init(proxy: VisionCameraProxyHolder, options: [AnyHashable: Any]! = [:]) {
9
+ super.init(proxy: proxy, options: options)
10
+ print(
11
+ "BarcodeScannerFrameProcessorPlugin: Initialized with options: \(String(describing: options))"
12
+ )
13
+ }
14
+
15
+ public override func callback(_ frame: Frame, withArguments arguments: [AnyHashable: Any]?)
16
+ -> Any?
17
+ {
18
+ print("BarcodeScannerFrameProcessorPlugin: callback called")
19
+
20
+ // Get the pixel buffer from the frame
21
+ guard let imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer) else {
22
+ print("BarcodeScannerFrameProcessorPlugin: Could not get pixel buffer from frame")
23
+ return []
24
+ }
12
25
 
13
- let visionImage = VNImageRequestHandler(cvPixelBuffer: imageBuffer, orientation: .up, options: [:])
14
-
15
- // Configure barcode types
16
- var symbologies: [VNBarcodeSymbology] = [
17
- .aztec, .code128, .code39, .code93, .dataMatrix,
18
- .ean13, .ean8, .i2of5, .pdf417, .qr, .upce, .codabar
19
- ]
20
-
21
- // Filter by specified barcode types if provided
22
- if let arguments = arguments,
23
- let barcodeTypes = arguments["barcodeTypes"] as? [String] {
24
- symbologies = barcodeTypes.compactMap { type in
25
- switch type {
26
- case "aztec":
27
- return .aztec
28
- case "codabar":
29
- return .codabar
30
- case "code-128":
31
- return .code128
32
- case "code-39":
33
- return .code39
34
- case "code-93":
35
- return .code93
36
- case "data-matrix":
37
- return .dataMatrix
38
- case "ean-13":
39
- return .ean13
40
- case "ean-8":
41
- return .ean8
42
- case "itf":
43
- return .i2of5
44
- case "pdf-417":
45
- return .pdf417
46
- case "qr":
47
- return .qr
48
- case "upc-e":
49
- return .upce
50
- default:
51
- return nil
52
- }
53
- }
26
+ // Parse barcode types from arguments (default to QR codes)
27
+ var symbologies: [VNBarcodeSymbology] = [.qr]
28
+
29
+ if let arguments = arguments,
30
+ let barcodeTypes = arguments["barcodeTypes"] as? [String]
31
+ {
32
+ symbologies = barcodeTypes.compactMap { type in
33
+ switch type {
34
+ case "aztec": return .aztec
35
+ case "codabar": return .codabar
36
+ case "code-128": return .code128
37
+ case "code-39": return .code39
38
+ case "code-93": return .code93
39
+ case "data-matrix": return .dataMatrix
40
+ case "ean-13": return .ean13
41
+ case "ean-8": return .ean8
42
+ case "itf": return .i2of5
43
+ case "pdf-417": return .pdf417
44
+ case "qr": return .qr
45
+ case "upc-a": return .ean13 // UPC-A is subset of EAN-13
46
+ case "upc-e": return .upce
47
+ default: return nil
54
48
  }
49
+ }
50
+ }
55
51
 
56
- let request = VNDetectBarcodesRequest { [weak self] request, error in
57
- // This callback runs asynchronously
58
- }
59
- request.symbologies = symbologies
52
+ // Use semaphore to make async Vision calls synchronous for frame processor
53
+ let semaphore = DispatchSemaphore(value: 0)
54
+ var detectedBarcodes: [VNBarcodeObservation] = []
55
+ var visionError: Error? = nil
60
56
 
61
- var detectedBarcodes: [VNBarcodeObservation] = []
57
+ // Create Vision request handler
58
+ let handler = VNImageRequestHandler(cvPixelBuffer: imageBuffer, options: [:])
62
59
 
63
- do {
64
- try visionImage.perform([request])
65
- detectedBarcodes = request.results as? [VNBarcodeObservation] ?? []
66
- } catch {
67
- return []
68
- }
60
+ // Create barcode detection request
61
+ let request = VNDetectBarcodesRequest { (request, error) in
62
+ defer { semaphore.signal() }
69
63
 
70
- let result = detectedBarcodes.map { barcode -> [String: Any] in
71
- var barcodeDict: [String: Any] = [:]
72
-
73
- // Add barcode value
74
- barcodeDict["value"] = barcode.payloadStringValue
75
-
76
- // Add barcode type
77
- let type: String
78
- switch barcode.symbology {
79
- case .aztec:
80
- type = "aztec"
81
- case .codabar:
82
- type = "codabar"
83
- case .code128:
84
- type = "code-128"
85
- case .code39:
86
- type = "code-39"
87
- case .code93:
88
- type = "code-93"
89
- case .dataMatrix:
90
- type = "data-matrix"
91
- case .ean13:
92
- type = "ean-13"
93
- case .ean8:
94
- type = "ean-8"
95
- case .i2of5, .i2of5Checksum, .itf14:
96
- type = "itf"
97
- case .pdf417:
98
- type = "pdf-417"
99
- case .qr:
100
- type = "qr"
101
- case .upce:
102
- type = "upc-e"
103
- default:
104
- type = "unknown"
105
- }
106
- barcodeDict["type"] = type
107
-
108
- // Convert bounding box to our format
109
- let boundingBox = barcode.boundingBox
110
- let imageSize = CGSize(width: CVPixelBufferGetWidth(imageBuffer), height: CVPixelBufferGetHeight(imageBuffer))
111
-
112
- // Vision framework uses normalized coordinates (0-1), convert to pixel coordinates
113
- let origin = CGPoint(
114
- x: boundingBox.origin.x * imageSize.width,
115
- y: (1 - boundingBox.origin.y - boundingBox.size.height) * imageSize.height // Flip Y coordinate
116
- )
117
- let size = CGSize(
118
- width: boundingBox.size.width * imageSize.width,
119
- height: boundingBox.size.height * imageSize.height
120
- )
121
-
122
- barcodeDict["boundingBox"] = [
123
- "origin": [
124
- "x": origin.x,
125
- "y": origin.y
126
- ],
127
- "size": [
128
- "width": size.width,
129
- "height": size.height
130
- ]
131
- ]
132
-
133
- // Convert corner points to our format
134
- let topLeft = CGPoint(
135
- x: barcode.topLeft.x * imageSize.width,
136
- y: (1 - barcode.topLeft.y) * imageSize.height
137
- )
138
- let topRight = CGPoint(
139
- x: barcode.topRight.x * imageSize.width,
140
- y: (1 - barcode.topRight.y) * imageSize.height
141
- )
142
- let bottomLeft = CGPoint(
143
- x: barcode.bottomLeft.x * imageSize.width,
144
- y: (1 - barcode.bottomLeft.y) * imageSize.height
145
- )
146
- let bottomRight = CGPoint(
147
- x: barcode.bottomRight.x * imageSize.width,
148
- y: (1 - barcode.bottomRight.y) * imageSize.height
149
- )
150
-
151
- barcodeDict["cornerPoints"] = [
152
- ["x": topLeft.x, "y": topLeft.y],
153
- ["x": topRight.x, "y": topRight.y],
154
- ["x": bottomRight.x, "y": bottomRight.y],
155
- ["x": bottomLeft.x, "y": bottomLeft.y]
156
- ]
157
-
158
- // Add native data
159
- var nativeDict: [String: Any] = [:]
160
-
161
- if let descriptor = barcode.barcodeDescriptor {
162
- nativeDict["descriptor"] = descriptor
163
- }
164
-
165
- barcodeDict["native"] = nativeDict
166
-
167
- return barcodeDict
168
- }
64
+ if let error = error {
65
+ print("BarcodeScannerFrameProcessorPlugin: Vision error: \(error.localizedDescription)")
66
+ visionError = error
67
+ return
68
+ }
169
69
 
170
- return result
70
+ detectedBarcodes = request.results as? [VNBarcodeObservation] ?? []
71
+ print("BarcodeScannerFrameProcessorPlugin: Detected \(detectedBarcodes.count) barcodes")
171
72
  }
73
+
74
+ // Set symbologies
75
+ request.symbologies = symbologies
76
+
77
+ // Perform the request
78
+ do {
79
+ try handler.perform([request])
80
+ } catch {
81
+ print(
82
+ "BarcodeScannerFrameProcessorPlugin: Error performing Vision request: \(error.localizedDescription)"
83
+ )
84
+ return []
85
+ }
86
+
87
+ // Wait for completion with timeout
88
+ let waitResult = semaphore.wait(timeout: .now() + 0.1) // 100ms timeout
89
+ if waitResult == .timedOut {
90
+ print("BarcodeScannerFrameProcessorPlugin: Vision request timed out")
91
+ return []
92
+ }
93
+
94
+ // Check for errors
95
+ if let error = visionError {
96
+ print(
97
+ "BarcodeScannerFrameProcessorPlugin: Vision processing failed: \(error.localizedDescription)"
98
+ )
99
+ return []
100
+ }
101
+
102
+ // Convert results to pixel coordinates at iOS level
103
+ let result = detectedBarcodes.compactMap { barcode -> [String: Any]? in
104
+ guard let barcodeValue = barcode.payloadStringValue, !barcodeValue.isEmpty else {
105
+ return nil
106
+ }
107
+
108
+ print("BarcodeScannerFrameProcessorPlugin: Processing barcode: \(barcodeValue)")
109
+
110
+ var map: [String: Any] = [:]
111
+
112
+ // Main value that TypeScript interface expects
113
+ map["value"] = barcodeValue
114
+
115
+ // Convert from normalized (0-1) coordinates to pixel coordinates
116
+ let frameWidth = frame.width
117
+ let frameHeight = frame.height
118
+ let boundingBox = barcode.boundingBox
119
+
120
+ // Convert from normalized (0-1) with bottom-left origin to pixel coordinates with top-left origin
121
+ let left = boundingBox.origin.x * CGFloat(frameWidth)
122
+ let bottom = boundingBox.origin.y * CGFloat(frameHeight)
123
+ let width = boundingBox.size.width * CGFloat(frameWidth)
124
+ let height = boundingBox.size.height * CGFloat(frameHeight)
125
+ let top = CGFloat(frameHeight) - bottom - height // Flip Y coordinate from bottom-left to top-left
126
+
127
+ // Create bounding box in pixel coordinates with top-left origin
128
+ map["boundingBox"] = [
129
+ "origin": [
130
+ "x": Int(left),
131
+ "y": Int(top),
132
+ ],
133
+ "size": [
134
+ "width": Int(width),
135
+ "height": Int(height),
136
+ ],
137
+ ]
138
+
139
+ // Convert corner points to pixel coordinates with top-left origin
140
+ let cornerPoints = [
141
+ [
142
+ "x": Int(barcode.topLeft.x * CGFloat(frameWidth)),
143
+ "y": Int((1.0 - barcode.topLeft.y) * CGFloat(frameHeight)),
144
+ ],
145
+ [
146
+ "x": Int(barcode.topRight.x * CGFloat(frameWidth)),
147
+ "y": Int((1.0 - barcode.topRight.y) * CGFloat(frameHeight)),
148
+ ],
149
+ [
150
+ "x": Int(barcode.bottomRight.x * CGFloat(frameWidth)),
151
+ "y": Int((1.0 - barcode.bottomRight.y) * CGFloat(frameHeight)),
152
+ ],
153
+ [
154
+ "x": Int(barcode.bottomLeft.x * CGFloat(frameWidth)),
155
+ "y": Int((1.0 - barcode.bottomLeft.y) * CGFloat(frameHeight)),
156
+ ],
157
+ ]
158
+ map["cornerPoints"] = cornerPoints
159
+
160
+ // Map barcode symbology to TypeScript BarcodeType strings
161
+ let typeString: String
162
+ switch barcode.symbology {
163
+ case .aztec: typeString = "aztec"
164
+ case .codabar: typeString = "codabar"
165
+ case .code128: typeString = "code-128"
166
+ case .code39: typeString = "code-39"
167
+ case .code93: typeString = "code-93"
168
+ case .dataMatrix: typeString = "data-matrix"
169
+ case .ean13: typeString = "ean-13"
170
+ case .ean8: typeString = "ean-8"
171
+ case .i2of5, .i2of5Checksum, .itf14: typeString = "itf"
172
+ case .pdf417: typeString = "pdf-417"
173
+ case .qr: typeString = "qr"
174
+ case .upce: typeString = "upc-e"
175
+ default: typeString = "unknown"
176
+ }
177
+ map["type"] = typeString
178
+
179
+ print(
180
+ "BarcodeScannerFrameProcessorPlugin: Converted barcode - value: \(barcodeValue), type: \(typeString), boundingBox: \(map["boundingBox"] ?? "nil")"
181
+ )
182
+ return map
183
+ }
184
+
185
+ print("BarcodeScannerFrameProcessorPlugin: Returning \(result.count) processed barcodes")
186
+ return result
187
+ }
172
188
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  import React, { useEffect } from 'react';
4
- import { View, StyleSheet, ActivityIndicator, Text as TextView, Text, Linking } from 'react-native';
4
+ import { View, StyleSheet, ActivityIndicator, Text as TextView, Text, Linking, Platform } from 'react-native';
5
5
  import { Camera, useCameraDevice, useCameraFormat, useCameraPermission, useFrameProcessor } from 'react-native-vision-camera';
6
6
  import { useRunOnJS, useSharedValue } from 'react-native-worklets-core';
7
7
  import { useKeepAwake } from "../Libs/native-keep-awake.utils.js";
@@ -71,8 +71,20 @@ const QrCodeScannerCamera = ({
71
71
  return false;
72
72
  };
73
73
  const handleQrCode = useRunOnJS((code, width, height, orientation) => {
74
- if (isInScanningFrame(code, width, height, orientation) && code.value) {
75
- onQrCodeScanned(code.value);
74
+ // TODO: Fix iOS coordinates - iOS coordinate system conversion may be incorrect
75
+ // causing frame checking to fail. Need to verify coordinate normalization
76
+ // between iOS Vision framework and React Native coordinate systems.
77
+
78
+ // On iOS, skip frame checking and scan any QR code found
79
+ if (Platform.OS === 'ios') {
80
+ if (code.value) {
81
+ onQrCodeScanned(code.value);
82
+ }
83
+ } else {
84
+ // On Android, continue with frame checking
85
+ if (isInScanningFrame(code, width, height, orientation) && code.value) {
86
+ onQrCodeScanned(code.value);
87
+ }
76
88
  }
77
89
  }, [onQrCodeScanned]);
78
90
  const frameProcessor = useFrameProcessor(frame => {
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Constants used throughout the EID Reader module.
5
+ * This file helps avoid circular dependencies by centralizing shared constants.
6
+ */
7
+
8
+ export const EID_CONSTANTS = {
9
+ // Transceive lengths
10
+ EXTENDED_MAX_TRANSCEIVE_LENGTH: 65536,
11
+ NORMAL_MAX_TRANSCEIVE_LENGTH: 256,
12
+ DEFAULT_MAX_BLOCKSIZE: 223,
13
+ // File identifiers
14
+ EF_CARD_ACCESS: 0x011c,
15
+ EF_CARD_SECURITY: 0x011d,
16
+ EF_DG1: 0x0101,
17
+ EF_DG2: 0x0102,
18
+ EF_DG3: 0x0103,
19
+ EF_DG4: 0x0104,
20
+ EF_DG5: 0x0105,
21
+ EF_DG6: 0x0106,
22
+ EF_DG7: 0x0107,
23
+ EF_DG8: 0x0108,
24
+ EF_DG9: 0x0109,
25
+ EF_DG10: 0x010a,
26
+ EF_DG11: 0x010b,
27
+ EF_DG12: 0x010c,
28
+ EF_DG13: 0x010d,
29
+ EF_DG14: 0x010e,
30
+ EF_DG15: 0x010f,
31
+ EF_DG16: 0x0110,
32
+ EF_SOD: 0x011d,
33
+ EF_COM: 0x011e,
34
+ EF_CVCA: 0x011c,
35
+ // Short file identifiers
36
+ SFI_CARD_ACCESS: 0x1c,
37
+ SFI_CARD_SECURITY: 0x1d,
38
+ SFI_DG1: 0x01,
39
+ SFI_DG2: 0x02,
40
+ SFI_DG3: 0x03,
41
+ SFI_DG4: 0x04,
42
+ SFI_DG5: 0x05,
43
+ SFI_DG6: 0x06,
44
+ SFI_DG7: 0x07,
45
+ SFI_DG8: 0x08,
46
+ SFI_DG9: 0x09,
47
+ SFI_DG10: 0x0a,
48
+ SFI_DG11: 0x0b,
49
+ SFI_DG12: 0x0c,
50
+ SFI_DG13: 0x0d,
51
+ SFI_DG14: 0x0e,
52
+ SFI_DG15: 0x0f,
53
+ SFI_DG16: 0x10,
54
+ SFI_COM: 0x1e,
55
+ SFI_SOD: 0x1d,
56
+ SFI_CVCA: 0x1c,
57
+ // PACE key references
58
+ NO_PACE_KEY_REFERENCE: 0x00,
59
+ MRZ_PACE_KEY_REFERENCE: 0x01,
60
+ CAN_PACE_KEY_REFERENCE: 0x02,
61
+ PIN_PACE_KEY_REFERENCE: 0x03,
62
+ PUK_PACE_KEY_REFERENCE: 0x04,
63
+ // Applet AID
64
+ APPLET_AID: new Uint8Array([0xa0, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01])
65
+ };
@@ -1,25 +1,20 @@
1
1
  "use strict";
2
2
 
3
- import { ISOCountry } from "./isoCountry.js";
4
- import { UnicodeCountry } from "./unicodeCountry.js";
5
3
  export class Country {
6
- static SUB_CLASSES = [ISOCountry, UnicodeCountry];
7
4
  static getInstance(code) {
5
+ // Note: This will be dynamically resolved at runtime
6
+ const {
7
+ CountryRegistry
8
+ } = require('./countryRegistry');
8
9
  if (typeof code === 'number') {
9
- const values = Country.values();
10
- for (const country of values) {
11
- if (country.valueOf() === code) {
12
- return country;
13
- }
14
- }
15
- throw new Error('Illegal country code ' + code.toString(16));
10
+ return CountryRegistry.fromNumericCode(code);
16
11
  } else if (typeof code === 'string') {
17
12
  code = code.trim();
18
13
  switch (code.length) {
19
14
  case 2:
20
- return Country.fromAlpha2(code);
15
+ return CountryRegistry.fromAlpha2(code);
21
16
  case 3:
22
- return Country.fromAlpha3(code);
17
+ return CountryRegistry.fromAlpha3(code);
23
18
  default:
24
19
  throw new Error('Illegal country code ' + code);
25
20
  }
@@ -28,39 +23,21 @@ export class Country {
28
23
  }
29
24
  }
30
25
  static values() {
31
- const result = [];
32
- for (const subClass of Country.SUB_CLASSES) {
33
- if (Country.isAssignable(subClass)) {
34
- try {
35
- const method = subClass.values;
36
- const subClassValues = method.call(null);
37
- result.push(...subClassValues);
38
- } catch (e) {
39
- console.debug(`Exception: ${e}`);
40
- }
41
- }
42
- }
43
- return result;
44
- }
45
- static fromAlpha2(code) {
46
- const values = Country.values();
47
- for (const country of values) {
48
- if (country.toAlpha2Code() === code) {
49
- return country;
50
- }
51
- }
52
- throw new Error('Unknown country code ' + code);
26
+ const {
27
+ CountryRegistry
28
+ } = require('./countryRegistry');
29
+ return CountryRegistry.values();
53
30
  }
54
- static fromAlpha3(code) {
55
- const values = Country.values();
56
- for (const country of values) {
57
- if (country.toAlpha3Code() === code) {
58
- return country;
59
- }
60
- }
61
- throw new Error('Unknown country code ' + code);
31
+ static fromAlpha2(alpha2Code) {
32
+ const {
33
+ CountryRegistry
34
+ } = require('./countryRegistry');
35
+ return CountryRegistry.fromAlpha2(alpha2Code);
62
36
  }
63
- static isAssignable(subClass) {
64
- return subClass.prototype instanceof Country;
37
+ static fromAlpha3(alpha3Code) {
38
+ const {
39
+ CountryRegistry
40
+ } = require('./countryRegistry');
41
+ return CountryRegistry.fromAlpha3(alpha3Code);
65
42
  }
66
43
  }
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Registry for country implementations to avoid circular dependencies.
5
+ */
6
+ export class CountryRegistry {
7
+ static countryTypes = [];
8
+ static register(countryType) {
9
+ if (!CountryRegistry.countryTypes.includes(countryType)) {
10
+ CountryRegistry.countryTypes.push(countryType);
11
+ }
12
+ }
13
+ static getRegisteredTypes() {
14
+ return [...CountryRegistry.countryTypes];
15
+ }
16
+ static values() {
17
+ const result = [];
18
+ for (const countryType of CountryRegistry.countryTypes) {
19
+ try {
20
+ const values = countryType.values?.();
21
+ if (Array.isArray(values)) {
22
+ result.push(...values);
23
+ }
24
+ } catch (e) {
25
+ console.debug(`Exception getting values from ${countryType.name}: ${e}`);
26
+ }
27
+ }
28
+ return result;
29
+ }
30
+ static fromAlpha2(alpha2Code) {
31
+ for (const countryType of CountryRegistry.countryTypes) {
32
+ try {
33
+ const country = countryType.fromAlpha2?.(alpha2Code);
34
+ if (country) {
35
+ return country;
36
+ }
37
+ } catch (e) {
38
+ // Continue to next type
39
+ }
40
+ }
41
+ throw new Error(`Unknown country code: ${alpha2Code}`);
42
+ }
43
+ static fromAlpha3(alpha3Code) {
44
+ for (const countryType of CountryRegistry.countryTypes) {
45
+ try {
46
+ const country = countryType.fromAlpha3?.(alpha3Code);
47
+ if (country) {
48
+ return country;
49
+ }
50
+ } catch (e) {
51
+ // Continue to next type
52
+ }
53
+ }
54
+ throw new Error(`Unknown country code: ${alpha3Code}`);
55
+ }
56
+ static fromNumericCode(numericCode) {
57
+ const values = CountryRegistry.values();
58
+ for (const country of values) {
59
+ if (country.valueOf() === numericCode) {
60
+ return country;
61
+ }
62
+ }
63
+ throw new Error(`Unknown country code: ${numericCode.toString(16)}`);
64
+ }
65
+ }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  import { Country } from "./country.js";
4
+ import { CountryRegistry } from "./countryRegistry.js";
4
5
  export class ISOCountry extends Country {
5
6
  static AD = new ISOCountry(32, 'AD', 'AND', 'Andorra', 'Andorran');
6
7
  static AE = new ISOCountry(1924, 'AE', 'ARE', 'United Arab Emirates', 'Emirati, Emirian');
@@ -280,4 +281,7 @@ export class ISOCountry extends Country {
280
281
  toAlpha3Code() {
281
282
  return this.alpha3Code;
282
283
  }
283
- }
284
+ }
285
+
286
+ // Register this country type with the registry
287
+ CountryRegistry.register(ISOCountry);
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  import { Country } from "./country.js";
4
+ import { CountryRegistry } from "./countryRegistry.js";
4
5
  export class UnicodeCountry extends Country {
5
6
  static AD = new UnicodeCountry(32, 'AD', 'AND', 'Andorra', 'Andorran');
6
7
  static AE = new UnicodeCountry(1924, 'AE', 'ARE', 'United Arab Emirates', 'Emirati, Emirian');
@@ -275,4 +276,7 @@ export class UnicodeCountry extends Country {
275
276
  toAlpha3Code() {
276
277
  return this.alpha3Code;
277
278
  }
278
- }
279
+ }
280
+
281
+ // Register this country type with the registry
282
+ CountryRegistry.register(UnicodeCountry);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import { EIDService } from "./eidService.js";
3
+ import { EID_CONSTANTS } from "./constants/eidConstants.js";
4
4
  import { ByteArrayInputStream } from "./java/byteArrayInputStream.js";
5
5
  import { DefaultFileInfo } from "./defaultFileInfo.js";
6
6
  import { ISO7816_SW } from "./smartcards/iso7816.js";
@@ -19,7 +19,7 @@ export class DefaultFileSystem {
19
19
  this.isSelected = false;
20
20
  this.isSFIEnabled = isSFIEnabled;
21
21
  this.fidToSFI = fidToSFI;
22
- this.maxReadBinaryLength = EIDService.EXTENDED_MAX_TRANSCEIVE_LENGTH;
22
+ this.maxReadBinaryLength = EID_CONSTANTS.EXTENDED_MAX_TRANSCEIVE_LENGTH;
23
23
  }
24
24
  setWrapper(wrapper) {
25
25
  this.oldWrapper = this.wrapper;
@@ -90,9 +90,9 @@ export class DefaultFileSystem {
90
90
  return result;
91
91
  } catch (error) {
92
92
  const sw = error.getSW();
93
- if ((sw & ISO7816_SW.WRONG_LENGTH) === ISO7816_SW.WRONG_LENGTH && this.maxReadBinaryLength > EIDService.DEFAULT_MAX_BLOCKSIZE) {
93
+ if ((sw & ISO7816_SW.WRONG_LENGTH) === ISO7816_SW.WRONG_LENGTH && this.maxReadBinaryLength > EID_CONSTANTS.DEFAULT_MAX_BLOCKSIZE) {
94
94
  this.wrapper = this.oldWrapper;
95
- this.maxReadBinaryLength = EIDService.DEFAULT_MAX_BLOCKSIZE;
95
+ this.maxReadBinaryLength = EID_CONSTANTS.DEFAULT_MAX_BLOCKSIZE;
96
96
  return new Uint8Array(0);
97
97
  }
98
98
  throw new Error(`Read binary failed on file ${fileInfo == null ? this.selectedFID.toString(16) : fileInfo}`);