@smileid/usesmileid_vision_document 12.0.1 → 12.1.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.
- package/CHANGELOG.md +11 -0
- package/README.md +33 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -34
- package/ios/UseSmileIDVisionDocumentExpo.podspec +2 -5
- package/ios/UseSmileIDVisionDocumentModule/ResizingFrameStorage.swift +1 -1
- package/ios/UseSmileIDVisionDocumentModule/UseSmileIDVisionDocumentKameraAnalysisTick.swift +80 -0
- package/ios/UseSmileIDVisionDocumentModule/UseSmileIDVisionDocumentModule.swift +9 -14
- package/package.json +13 -14
- package/plugin/build/index.d.ts +11 -2
- package/plugin/build/index.js +1 -107
- package/plugin/build/lib/deployment_target.d.ts +5 -0
- package/plugin/build/lib/deployment_target.js +1 -0
- package/plugin/build/lib/podfile.d.ts +17 -0
- package/plugin/build/lib/podfile.js +187 -117
- package/plugin/build/lib/signature_dedup.d.ts +14 -0
- package/plugin/build/lib/signature_dedup.js +2 -0
- package/plugin/build/lib/spm.d.ts +22 -1
- package/plugin/build/lib/spm.js +1 -196
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/ios/UseSmileIDVisionDocumentModule/UseSmileIDVisionDocumentFrameProcessorPlugin.swift +0 -149
- package/plugin/build/index.js.map +0 -1
- package/plugin/build/lib/podfile.js.map +0 -1
- package/plugin/build/lib/spm.js.map +0 -1
- package/plugin/src/index.ts +0 -88
- package/plugin/src/lib/podfile.ts +0 -209
- package/plugin/src/lib/spm.ts +0 -314
- package/plugin/tsconfig.json +0 -19
- package/src/__tests__/use_smile_id_vision_document.test.ts +0 -79
- package/src/index.ts +0 -42
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
Full release notes: [Smile ID docs](https://docs.usesmileid.com/developer-resources/sdks/mobile/release-notes/react-native-expo).
|
|
2
|
+
|
|
3
|
+
## 12.1.0
|
|
4
|
+
|
|
5
|
+
See the repository CHANGELOG for the 12.1.0 release notes.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## 12.0.2
|
|
9
|
+
|
|
10
|
+
See the repository CHANGELOG for the 12.0.2 release notes.
|
|
11
|
+
|
|
1
12
|
## 12.0.1
|
|
2
13
|
|
|
3
14
|
See the repository CHANGELOG for the 12.0.1 release notes.
|
package/README.md
CHANGED
|
@@ -17,14 +17,46 @@ No ML logic is reimplemented in this package — it's a pure passthrough.
|
|
|
17
17
|
## Installation
|
|
18
18
|
|
|
19
19
|
```sh
|
|
20
|
-
pnpm add @smileid/usesmileid_vision_document
|
|
20
|
+
pnpm add @smileid/usesmileid_vision_document react-native-vision-camera@^4
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
This package's pod depends on VisionCamera: without it `pod install` fails
|
|
24
|
+
with `Unable to find a specification for VisionCamera depended upon by
|
|
25
|
+
UseSmileIDVisionDocumentExpo`. Pin v4 — the SDK is built against the v4
|
|
26
|
+
API, and a bare `expo install react-native-vision-camera` resolves a v5.
|
|
27
|
+
|
|
23
28
|
The Smile ID native SDK is declared as an SPM dependency in
|
|
24
29
|
`expo-module.config.json`. Expo Modules autolinking surfaces it to
|
|
25
30
|
the iOS target — partners do not need to add anything to their
|
|
26
31
|
`Podfile` beyond the standard `use_expo_modules!` invocation.
|
|
27
32
|
|
|
33
|
+
## Config plugin options
|
|
34
|
+
|
|
35
|
+
| Option | Values | Default |
|
|
36
|
+
| ------------------------- | ------------------------ | -------- |
|
|
37
|
+
| `iosSignatureAggregation` | `"keep"` \| `"disabled"` | `"keep"` |
|
|
38
|
+
|
|
39
|
+
Several targets have to reference the same signed Smile ID XCFramework, and an
|
|
40
|
+
iOS release archive collects framework signatures into one directory keyed by
|
|
41
|
+
filename — so `"keep"` adds a build phase that leaves exactly one staged copy of
|
|
42
|
+
each signature while the archive is assembled.
|
|
43
|
+
|
|
44
|
+
`"disabled"` instead turns off Xcode's signature aggregation for the app target.
|
|
45
|
+
Reach for it only if an Xcode version we have not seen still fails to archive:
|
|
46
|
+
it drops the recorded signatures of every framework in the archive, including
|
|
47
|
+
your own and other vendors'.
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"plugins": [
|
|
52
|
+
[
|
|
53
|
+
"@smileid/usesmileid_vision_document",
|
|
54
|
+
{ "iosSignatureAggregation": "disabled" }
|
|
55
|
+
]
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
28
60
|
## Usage
|
|
29
61
|
|
|
30
62
|
```ts
|
package/dist/index.d.ts
CHANGED
|
@@ -18,9 +18,10 @@ import type { DocumentConfig, DocumentScanResult } from "@smileid/usesmileid_bri
|
|
|
18
18
|
* contract.
|
|
19
19
|
*/
|
|
20
20
|
/**
|
|
21
|
-
* Must match the Swift Expo Module's `Name("UseSmileIDVisionDocument")`
|
|
22
|
-
*
|
|
23
|
-
*
|
|
21
|
+
* Must match the Swift Expo Module's `Name("UseSmileIDVisionDocument")` — drift is a runtime
|
|
22
|
+
* "module not found" error, not a compile error.
|
|
23
|
+
*
|
|
24
|
+
* `frameProcessorPluginName` is inert; kept only for API compatibility.
|
|
24
25
|
*/
|
|
25
26
|
export declare const UseSmileIDVisionDocumentIdentifiers: {
|
|
26
27
|
readonly nativeModuleName: "UseSmileIDVisionDocument";
|
|
@@ -28,4 +29,3 @@ export declare const UseSmileIDVisionDocumentIdentifiers: {
|
|
|
28
29
|
};
|
|
29
30
|
export declare const useSmileIDVisionDocument: import("@smileid/usesmileid_platform_interface").DocumentAnalyzer;
|
|
30
31
|
export type { DocumentConfig, DocumentScanResult };
|
|
31
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,34 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
/**
|
|
3
|
-
* Apple Vision document analyzer (iOS-only).
|
|
4
|
-
*
|
|
5
|
-
* Thin shim around the existing native session
|
|
6
|
-
* `UseSmileID.UseSmileIDDocumentSession(DocumentDetectorAnalyzer())` shipped
|
|
7
|
-
* in the `UseSmileIDVisionDocument` Swift Package. The native side runs the
|
|
8
|
-
* entire pipeline (analyzer + validator + transitioner + state machine);
|
|
9
|
-
* this TS layer routes calls and validates wire payloads at the channel
|
|
10
|
-
* boundary.
|
|
11
|
-
*
|
|
12
|
-
* The canonical wiring lives in [useSmileIDAnalyzerExecutor] in
|
|
13
|
-
* `usesmileid_platform_interface`.
|
|
14
|
-
*
|
|
15
|
-
* Lifecycle: `configure()` → per-frame analysis via the native frame
|
|
16
|
-
* processor plugin → `reset()`? → `close()`. See
|
|
17
|
-
* `usesmileid_platform_interface` `DocumentAnalyzer` for the canonical
|
|
18
|
-
* contract.
|
|
19
|
-
*/
|
|
20
|
-
/**
|
|
21
|
-
* Must match the Swift Expo Module's `Name("UseSmileIDVisionDocument")` and
|
|
22
|
-
* its VisionCamera frame-processor-plugin registration — drift is a runtime
|
|
23
|
-
* "module/plugin not found" error, not a compile error.
|
|
24
|
-
*/
|
|
25
|
-
export const UseSmileIDVisionDocumentIdentifiers = {
|
|
26
|
-
nativeModuleName: "UseSmileIDVisionDocument",
|
|
27
|
-
frameProcessorPluginName: "UseSmileIDVisionDocumentFrameProcessor",
|
|
28
|
-
};
|
|
29
|
-
export const useSmileIDVisionDocument = useSmileIDAnalyzerExecutor({
|
|
30
|
-
nativeModuleName: UseSmileIDVisionDocumentIdentifiers.nativeModuleName,
|
|
31
|
-
frameProcessorPluginName: UseSmileIDVisionDocumentIdentifiers.frameProcessorPluginName,
|
|
32
|
-
kind: "document",
|
|
33
|
-
});
|
|
34
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";import{useSmileIDAnalyzerExecutor as e}from"@smileid/usesmileid_platform_interface";export const UseSmileIDVisionDocumentIdentifiers={nativeModuleName:"UseSmileIDVisionDocument",frameProcessorPluginName:"UseSmileIDVisionDocumentFrameProcessor"},useSmileIDVisionDocument=e({nativeModuleName:UseSmileIDVisionDocumentIdentifiers.nativeModuleName,frameProcessorPluginName:UseSmileIDVisionDocumentIdentifiers.frameProcessorPluginName,kind:"document"});
|
|
@@ -20,11 +20,8 @@ Pod::Spec.new do |s|
|
|
|
20
20
|
s.static_framework = true
|
|
21
21
|
|
|
22
22
|
s.dependency 'ExpoModulesCore'
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
# Frame processors additionally require react-native-worklets-core in the
|
|
26
|
-
# consuming app (already declared as an SDK peer dependency).
|
|
27
|
-
s.dependency 'VisionCamera'
|
|
23
|
+
# kamera native core (pre-release pod); analyzeKameraFrame takes frames from its KameraFrameHub.
|
|
24
|
+
s.dependency 'kamera-rn'
|
|
28
25
|
|
|
29
26
|
# The Smile ID native deps (`UseSmileIDVisionDocument` / `UseSmileIDBridge`)
|
|
30
27
|
# are SPM-only — declared in `expo-module.config.json` under
|
|
@@ -34,7 +34,7 @@ final class ResizingFrameStorage: FrameStorage {
|
|
|
34
34
|
private let livenessQuality: CGFloat
|
|
35
35
|
private let documentQuality: CGFloat
|
|
36
36
|
private let writer: Writer
|
|
37
|
-
// The
|
|
37
|
+
// The analysis tick calls `setCropRegion` on the module's async-function
|
|
38
38
|
// thread; `persist` reads the value on that same serialised scan path before
|
|
39
39
|
// handing it (by value) to the background encode task. The Swift value is a
|
|
40
40
|
// `Sendable` struct captured by value into `Writer.enqueue`, so no background
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import CoreMedia
|
|
2
|
+
import Kamera
|
|
3
|
+
import CoreImage
|
|
4
|
+
import UIKit
|
|
5
|
+
import UseSmileIDBridge
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
private extension CGImagePropertyOrientation {
|
|
9
|
+
/// Kamera rotation + mirror metadata → the preview's view of the frame. The rotation already
|
|
10
|
+
/// follows the locked interface axis, so no further fold onto the viewport is needed.
|
|
11
|
+
init(rotationDegrees: Int, isMirrored: Bool) {
|
|
12
|
+
let normalised = ((rotationDegrees % 360) + 360) % 360
|
|
13
|
+
switch (normalised, isMirrored) {
|
|
14
|
+
case (90, false): self = .right
|
|
15
|
+
case (90, true): self = .leftMirrored
|
|
16
|
+
case (180, false): self = .down
|
|
17
|
+
case (180, true): self = .downMirrored
|
|
18
|
+
case (270, false): self = .left
|
|
19
|
+
case (270, true): self = .rightMirrored
|
|
20
|
+
case (_, true): self = .upMirrored
|
|
21
|
+
default: self = .up
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Scans the latest `KameraFrameHub` frame; no pending frame returns the `no_frame` wire error.
|
|
27
|
+
enum UseSmileIDVisionDocumentKameraTick {
|
|
28
|
+
/// Reused across ticks — per-tick creation recompiles the GPU pipeline.
|
|
29
|
+
private static let ciContext = CIContext(options: [.useSoftwareRenderer: false])
|
|
30
|
+
|
|
31
|
+
static func analyze(arguments: [String: Any?]?) -> Any {
|
|
32
|
+
guard let frame = KameraFrameHub.take() else {
|
|
33
|
+
return ["error": "no_frame"]
|
|
34
|
+
}
|
|
35
|
+
guard let concrete = frame as? CVPixelBufferKameraFrame else {
|
|
36
|
+
frame.close()
|
|
37
|
+
return ["error": "frame_conversion_failed"]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let orientedImage = CIImage(cvPixelBuffer: concrete.pixelBuffer)
|
|
41
|
+
.oriented(CGImagePropertyOrientation(
|
|
42
|
+
rotationDegrees: frame.rotationDegrees,
|
|
43
|
+
isMirrored: frame.isMirrored
|
|
44
|
+
))
|
|
45
|
+
let cgImage = ciContext.createCGImage(orientedImage, from: orientedImage.extent)
|
|
46
|
+
frame.close()
|
|
47
|
+
guard let cgImage else {
|
|
48
|
+
return ["error": "frame_conversion_failed"]
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let rotation = (arguments?["rotation"] as? NSNumber)?.intValue ?? 0
|
|
52
|
+
|
|
53
|
+
// Crop the saved capture to the guide rectangle the user framed.
|
|
54
|
+
UseSmileIDVisionDocumentSessionHolder.shared.setCropRegion(kameraCropRegionFrom(arguments))
|
|
55
|
+
|
|
56
|
+
guard let result = UseSmileIDVisionDocumentSessionHolder.shared.scanAndDrain(
|
|
57
|
+
image: UIImage(cgImage: cgImage),
|
|
58
|
+
rotation: rotation
|
|
59
|
+
) else {
|
|
60
|
+
return ["error": "session_not_configured"]
|
|
61
|
+
}
|
|
62
|
+
return result
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/// Crop region from the flat crop args; nil when `cropWidth <= 0` means no region.
|
|
67
|
+
private func kameraCropRegionFrom(_ arguments: [String: Any?]?) -> ViewportCropRegion? {
|
|
68
|
+
guard let width = (arguments?["cropWidth"] as? NSNumber)?.floatValue, width > 0 else {
|
|
69
|
+
return nil
|
|
70
|
+
}
|
|
71
|
+
return ViewportCropRegion(
|
|
72
|
+
left: (arguments?["cropLeft"] as? NSNumber)?.floatValue ?? 0,
|
|
73
|
+
top: (arguments?["cropTop"] as? NSNumber)?.floatValue ?? 0,
|
|
74
|
+
width: width,
|
|
75
|
+
height: (arguments?["cropHeight"] as? NSNumber)?.floatValue ?? 0,
|
|
76
|
+
viewportWidthPx: (arguments?["cropViewportWidth"] as? NSNumber)?.intValue ?? 0,
|
|
77
|
+
viewportHeightPx: (arguments?["cropViewportHeight"] as? NSNumber)?.intValue ?? 0,
|
|
78
|
+
contentScale: .crop
|
|
79
|
+
)
|
|
80
|
+
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import ExpoModulesCore
|
|
2
|
-
import UIKit
|
|
3
2
|
import UseSmileIDBridge
|
|
4
3
|
import UseSmileIDVisionDocument
|
|
5
|
-
import VisionCamera
|
|
6
4
|
|
|
7
5
|
/// Expo Module bridging the native `UseSmileIDDocumentSession` (from the
|
|
8
6
|
/// `UseSmileIDVisionDocument` Swift Package) to JS. No ML logic here — it
|
|
@@ -12,10 +10,6 @@ import VisionCamera
|
|
|
12
10
|
public class UseSmileIDVisionDocumentModule: Module {
|
|
13
11
|
private lazy var analyzer: DocumentDetectorAnalyzer = DocumentDetectorAnalyzer.Factory().newInstance()!
|
|
14
12
|
|
|
15
|
-
/// Prevents double-registration of the frame processor plugin when
|
|
16
|
-
/// Expo Go / dev-client fast-refreshes the JS bundle and `OnCreate`
|
|
17
|
-
/// runs again in the same native process.
|
|
18
|
-
private static var isFrameProcessorRegistered = false
|
|
19
13
|
|
|
20
14
|
private var session: UseSmileIDDocumentSession?
|
|
21
15
|
|
|
@@ -23,13 +17,6 @@ public class UseSmileIDVisionDocumentModule: Module {
|
|
|
23
17
|
Name("UseSmileIDVisionDocument")
|
|
24
18
|
|
|
25
19
|
OnCreate {
|
|
26
|
-
// Guard prevents double-registration on dev-client fast-refresh reloads.
|
|
27
|
-
if !Self.isFrameProcessorRegistered {
|
|
28
|
-
FrameProcessorPluginRegistry.addFrameProcessorPlugin("UseSmileIDVisionDocumentFrameProcessor") { proxy, options in
|
|
29
|
-
UseSmileIDVisionDocumentFrameProcessorPlugin(proxy: proxy, options: options)
|
|
30
|
-
}
|
|
31
|
-
Self.isFrameProcessorRegistered = true
|
|
32
|
-
}
|
|
33
20
|
}
|
|
34
21
|
|
|
35
22
|
AsyncFunction("configure") { (config: [String: Any?]) in
|
|
@@ -64,6 +51,11 @@ public class UseSmileIDVisionDocumentModule: Module {
|
|
|
64
51
|
UseSmileIDVisionDocumentSessionHolder.shared.setStorage(storage)
|
|
65
52
|
}
|
|
66
53
|
|
|
54
|
+
AsyncFunction("analyzeKameraFrame") { (arguments: [String: Any?]?) -> Any in
|
|
55
|
+
// Runs on this module's async queue, so only one scan is in flight at a time.
|
|
56
|
+
UseSmileIDVisionDocumentKameraTick.analyze(arguments: arguments)
|
|
57
|
+
}
|
|
58
|
+
|
|
67
59
|
AsyncFunction("reset") {
|
|
68
60
|
UseSmileIDVisionDocumentSessionHolder.shared.reset()
|
|
69
61
|
}
|
|
@@ -121,7 +113,9 @@ private extension Dictionary where Key == String, Value == Any? {
|
|
|
121
113
|
timeout: (self["timeout"] as? NSNumber)?.intValue ?? 15_000,
|
|
122
114
|
iouThreshold: (self["iouThreshold"] as? NSNumber)?.floatValue ?? 0.85,
|
|
123
115
|
timeRequired: (self["timeRequired"] as? NSNumber)?.intValue ?? 1_000,
|
|
124
|
-
|
|
116
|
+
// Coverage is measured against the full analysis frame, which is wider than the preview;
|
|
117
|
+
// a guide-filling document covers only ~0.2 of it, so the floor must sit below that.
|
|
118
|
+
minCoverageThreshold: (self["minCoverageThreshold"] as? NSNumber)?.floatValue ?? 0.12,
|
|
125
119
|
maxCoverageThreshold: (self["maxCoverageThreshold"] as? NSNumber)?.floatValue ?? 0.78,
|
|
126
120
|
centerToleranceX: (self["centerToleranceX"] as? NSNumber)?.floatValue ?? 0.05,
|
|
127
121
|
centerToleranceY: (self["centerToleranceY"] as? NSNumber)?.floatValue ?? 0.05
|
|
@@ -214,3 +208,4 @@ extension UseSmileIDBridge.UseSmileIDScanState {
|
|
|
214
208
|
return map
|
|
215
209
|
}
|
|
216
210
|
}
|
|
211
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smileid/usesmileid_vision_document",
|
|
3
|
-
"version": "12.0
|
|
3
|
+
"version": "12.1.0",
|
|
4
4
|
"description": "Apple Vision document detection implementation for the UseSmileID React Native (Expo) SDK.",
|
|
5
5
|
"homepage": "https://usesmileid.com",
|
|
6
6
|
"repository": {
|
|
@@ -36,11 +36,9 @@
|
|
|
36
36
|
},
|
|
37
37
|
"files": [
|
|
38
38
|
"dist",
|
|
39
|
-
"
|
|
40
|
-
"ios",
|
|
39
|
+
"ios/UseSmileIDVisionDocumentExpo.podspec",
|
|
40
|
+
"ios/UseSmileIDVisionDocumentModule",
|
|
41
41
|
"plugin/build",
|
|
42
|
-
"plugin/src",
|
|
43
|
-
"plugin/tsconfig.json",
|
|
44
42
|
"app.plugin.js",
|
|
45
43
|
"expo-module.config.json",
|
|
46
44
|
"README.md",
|
|
@@ -48,8 +46,8 @@
|
|
|
48
46
|
"CHANGELOG.md"
|
|
49
47
|
],
|
|
50
48
|
"dependencies": {
|
|
51
|
-
"@smileid/
|
|
52
|
-
"@smileid/
|
|
49
|
+
"@smileid/usesmileid_platform_interface": "12.1.0",
|
|
50
|
+
"@smileid/usesmileid_bridge": "12.1.0"
|
|
53
51
|
},
|
|
54
52
|
"peerDependencies": {
|
|
55
53
|
"expo": ">=56.0.0",
|
|
@@ -57,22 +55,23 @@
|
|
|
57
55
|
"react-native": ">=0.83.0"
|
|
58
56
|
},
|
|
59
57
|
"devDependencies": {
|
|
60
|
-
"@
|
|
61
|
-
"
|
|
62
|
-
"expo-modules-core": "^
|
|
63
|
-
"react-native": "^0.
|
|
64
|
-
"typescript": "^6.0.3"
|
|
58
|
+
"@types/node": "^26.4.1",
|
|
59
|
+
"expo": "~57.0.20",
|
|
60
|
+
"expo-modules-core": "^57.0.16",
|
|
61
|
+
"react-native": "^0.86.3",
|
|
62
|
+
"typescript": "^6.0.3",
|
|
63
|
+
"xcode": "^3.0.1"
|
|
65
64
|
},
|
|
66
65
|
"publishConfig": {
|
|
67
66
|
"access": "public"
|
|
68
67
|
},
|
|
69
68
|
"scripts": {
|
|
70
|
-
"build": "pnpm run build:lib && pnpm run build:plugin",
|
|
69
|
+
"build": "pnpm run build:lib && pnpm run build:plugin && node ../Scripts/copy-assets.mjs",
|
|
71
70
|
"build:lib": "tsc -p tsconfig.json",
|
|
72
71
|
"build:plugin": "tsc -p plugin/tsconfig.json",
|
|
73
72
|
"typecheck": "tsc -b && tsc -p plugin/tsconfig.json --noEmit",
|
|
74
73
|
"test": "vitest run",
|
|
75
74
|
"test:watch": "vitest",
|
|
76
|
-
"clean": "rm -rf dist plugin/build .turbo coverage"
|
|
75
|
+
"clean": "rm -rf dist plugin/build .turbo coverage tsconfig.tsbuildinfo"
|
|
77
76
|
}
|
|
78
77
|
}
|
package/plugin/build/index.d.ts
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
import { ConfigPlugin } from "
|
|
2
|
-
|
|
1
|
+
import { ConfigPlugin } from "expo/config-plugins";
|
|
2
|
+
export interface VisionDocumentOptions {
|
|
3
|
+
/**
|
|
4
|
+
* `"disabled"` stops Xcode recording XCFramework signatures in iOS archives
|
|
5
|
+
* instead of keeping one staged copy per framework — an escape hatch that
|
|
6
|
+
* drops the records for every framework, Smile ID's and yours alike.
|
|
7
|
+
*/
|
|
8
|
+
iosSignatureAggregation?: "keep" | "disabled";
|
|
9
|
+
}
|
|
10
|
+
export declare const SPM_PRODUCTS: readonly ["UseSmileIDVisionDocument"];
|
|
11
|
+
declare const withVisionDocumentSpm: ConfigPlugin<VisionDocumentOptions | void>;
|
|
3
12
|
export default withVisionDocumentSpm;
|
package/plugin/build/index.js
CHANGED
|
@@ -1,107 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Expo config plugin that wires the Smile Identity Swift Package
|
|
3
|
-
// (`https://github.com/smileidentity/ios-spm`) into both:
|
|
4
|
-
// 1. The consuming app's Xcode project — so the .xcframeworks ship
|
|
5
|
-
// and embed in the final .app bundle.
|
|
6
|
-
// 2. The autogenerated Pods.xcodeproj at `pod install` time — so
|
|
7
|
-
// the Expo Module bridge (`UseSmileIDVisionDocumentExpo`) compiles
|
|
8
|
-
// with `import UseSmileIDVisionDocument` / `import UseSmileIDBridge`.
|
|
9
|
-
//
|
|
10
|
-
// Why a plugin: `expo-modules-autolinking@55.0.x`'s
|
|
11
|
-
// `RawModuleConfigApple` schema has no `dependencies` field, so the
|
|
12
|
-
// `apple.dependencies` block in `expo-module.config.json` is silently
|
|
13
|
-
// ignored. Without this plugin, neither the bridge nor the host app
|
|
14
|
-
// know about the SPM package.
|
|
15
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
-
if (k2 === undefined) k2 = k;
|
|
17
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
-
}
|
|
21
|
-
Object.defineProperty(o, k2, desc);
|
|
22
|
-
}) : (function(o, m, k, k2) {
|
|
23
|
-
if (k2 === undefined) k2 = k;
|
|
24
|
-
o[k2] = m[k];
|
|
25
|
-
}));
|
|
26
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
-
}) : function(o, v) {
|
|
29
|
-
o["default"] = v;
|
|
30
|
-
});
|
|
31
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
-
var ownKeys = function(o) {
|
|
33
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
-
var ar = [];
|
|
35
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
-
return ar;
|
|
37
|
-
};
|
|
38
|
-
return ownKeys(o);
|
|
39
|
-
};
|
|
40
|
-
return function (mod) {
|
|
41
|
-
if (mod && mod.__esModule) return mod;
|
|
42
|
-
var result = {};
|
|
43
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
-
__setModuleDefault(result, mod);
|
|
45
|
-
return result;
|
|
46
|
-
};
|
|
47
|
-
})();
|
|
48
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
-
const config_plugins_1 = require("@expo/config-plugins");
|
|
50
|
-
const fs = __importStar(require("fs"));
|
|
51
|
-
const path = __importStar(require("path"));
|
|
52
|
-
const podfile_1 = require("./lib/podfile");
|
|
53
|
-
const spm_1 = require("./lib/spm");
|
|
54
|
-
// Pinned to the exact `12.0.0` release tag — `from: 12.0.0`
|
|
55
|
-
// would not resolve because `ios-spm` publishes pre-release tags (e.g.
|
|
56
|
-
// `12.0.0`), and SPM excludes pre-release tags from open-ended
|
|
57
|
-
// major-version requirements.
|
|
58
|
-
const SMILE_ID_PACKAGE = {
|
|
59
|
-
url: "https://github.com/smileidentity/ios-spm",
|
|
60
|
-
requirement: {
|
|
61
|
-
kind: "exactVersion",
|
|
62
|
-
version: "12.0.1-SNAPSHOT.20260729180601.30478033861",
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
const POD_TARGET = "UseSmileIDVisionDocumentExpo";
|
|
66
|
-
const SPM_PRODUCTS = ["UseSmileIDVisionDocument", "UseSmileIDBridge"];
|
|
67
|
-
const PODFILE_MARKER = "usesmileid_vision_document";
|
|
68
|
-
const withVisionDocumentSpm = (config) => {
|
|
69
|
-
// 1. Add the package + products to the host app's Xcode project so
|
|
70
|
-
// Xcode resolves the binary xcframeworks and embeds them in the
|
|
71
|
-
// .app at link time.
|
|
72
|
-
config = (0, config_plugins_1.withXcodeProject)(config, (config) => {
|
|
73
|
-
const appTarget = config.modRequest.projectName;
|
|
74
|
-
if (!appTarget) {
|
|
75
|
-
throw new Error("[usesmileid_vision_document] Unable to resolve host app native target name from Expo config.");
|
|
76
|
-
}
|
|
77
|
-
(0, spm_1.linkSpmPackage)(config.modResults, SMILE_ID_PACKAGE, {
|
|
78
|
-
targetName: appTarget,
|
|
79
|
-
products: [...SPM_PRODUCTS],
|
|
80
|
-
});
|
|
81
|
-
return config;
|
|
82
|
-
});
|
|
83
|
-
// 2. Inject a Ruby block into the Podfile's post_install hook that
|
|
84
|
-
// re-applies the same wiring to Pods.xcodeproj when CocoaPods
|
|
85
|
-
// materializes it. The bridge pod target needs the products
|
|
86
|
-
// visible at compile time; the host-app step alone isn't enough.
|
|
87
|
-
config = (0, config_plugins_1.withDangerousMod)(config, [
|
|
88
|
-
"ios",
|
|
89
|
-
(config) => {
|
|
90
|
-
const podfilePath = path.join(config.modRequest.platformProjectRoot, "Podfile");
|
|
91
|
-
const original = fs.readFileSync(podfilePath, "utf-8");
|
|
92
|
-
const next = (0, podfile_1.injectPodfileSpmBlock)(original, {
|
|
93
|
-
marker: PODFILE_MARKER,
|
|
94
|
-
package: SMILE_ID_PACKAGE,
|
|
95
|
-
podTarget: POD_TARGET,
|
|
96
|
-
products: [...SPM_PRODUCTS],
|
|
97
|
-
});
|
|
98
|
-
if (next !== original) {
|
|
99
|
-
fs.writeFileSync(podfilePath, next);
|
|
100
|
-
}
|
|
101
|
-
return config;
|
|
102
|
-
},
|
|
103
|
-
]);
|
|
104
|
-
return config;
|
|
105
|
-
};
|
|
106
|
-
exports.default = withVisionDocumentSpm;
|
|
107
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(i,r,t,e){e===void 0&&(e=t);var o=Object.getOwnPropertyDescriptor(r,t);(!o||("get"in o?!r.__esModule:o.writable||o.configurable))&&(o={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(i,e,o)}):(function(i,r,t,e){e===void 0&&(e=t),i[e]=r[t]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(i,r){Object.defineProperty(i,"default",{enumerable:!0,value:r})}):function(i,r){i.default=r}),__importStar=this&&this.__importStar||(function(){var i=function(r){return i=Object.getOwnPropertyNames||function(t){var e=[];for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[e.length]=o);return e},i(r)};return function(r){if(r&&r.__esModule)return r;var t={};if(r!=null)for(var e=i(r),o=0;o<e.length;o++)e[o]!=="default"&&__createBinding(t,r,e[o]);return __setModuleDefault(t,r),t}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.SPM_PRODUCTS=void 0;const config_plugins_1=require("expo/config-plugins"),fs=__importStar(require("fs")),path=__importStar(require("path")),deployment_target_1=require("./lib/deployment_target"),podfile_1=require("./lib/podfile"),signature_dedup_1=require("./lib/signature_dedup"),spm_1=require("./lib/spm"),IOS_DEPLOYMENT_TARGET="16.4",SMILE_ID_PACKAGE={url:"https://github.com/smileidentity/ios-spm",requirement:{kind:"exactVersion",version:"12.1.0"}},POD_TARGET="UseSmileIDVisionDocumentExpo";exports.SPM_PRODUCTS=["UseSmileIDVisionDocument"];const PODFILE_MARKER="usesmileid_vision_document",BRIDGE_POD_TARGET="UseSmileIDBridgeExpo",BRIDGE_SPM_PRODUCTS=["UseSmileIDBridge"],BRIDGE_PODFILE_MARKER="usesmileid_bridge",withVisionDocumentSpm=(i,r)=>(i=(0,deployment_target_1.withIosDeploymentTargetFloor)(i,IOS_DEPLOYMENT_TARGET),i=(0,config_plugins_1.withXcodeProject)(i,t=>{const e=t.modRequest.projectName;if(!e)throw new Error("[usesmileid_vision_document] Unable to resolve host app native target name from Expo config.");return(0,spm_1.linkSpmPackage)(t.modResults,SMILE_ID_PACKAGE,{targetName:e,products:[...exports.SPM_PRODUCTS]}),r?.iosSignatureAggregation==="disabled"?(0,signature_dedup_1.disableSignatureAggregation)(t.modResults,e):(0,signature_dedup_1.ensureSignatureDedupPhase)(t.modResults,e),t}),i=(0,config_plugins_1.withDangerousMod)(i,["ios",t=>{const e=path.join(t.modRequest.platformProjectRoot,"Podfile"),o=fs.readFileSync(e,"utf-8");let n=(0,podfile_1.injectPodfileSpmBlock)(o,{marker:PODFILE_MARKER,package:SMILE_ID_PACKAGE,podTarget:POD_TARGET,products:[...exports.SPM_PRODUCTS]});return n=(0,podfile_1.injectPodfileSpmBlock)(n,{marker:BRIDGE_PODFILE_MARKER,package:SMILE_ID_PACKAGE,podTarget:BRIDGE_POD_TARGET,products:[...BRIDGE_SPM_PRODUCTS],required:!0}),n=(0,podfile_1.injectPodfileKameraLinkBlock)(n),n=(0,podfile_1.injectPodfileSignatureDedupBlock)(n),n!==o&&fs.writeFileSync(e,n),t}]),i);exports.default=withVisionDocumentSpm;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ConfigPlugin } from "expo/config-plugins";
|
|
2
|
+
/** Sets `ios.deploymentTarget` to `minimum` unless the project already asks for a higher one. */
|
|
3
|
+
export declare const withIosDeploymentTargetFloor: ConfigPlugin<string>;
|
|
4
|
+
/** Pure form of the edit the plugin makes to the Podfile properties. */
|
|
5
|
+
export declare function raiseDeploymentTarget(properties: Readonly<Record<string, string>>, minimum: string): Record<string, string>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.withIosDeploymentTargetFloor=void 0,exports.raiseDeploymentTarget=raiseDeploymentTarget;const config_plugins_1=require("expo/config-plugins"),withIosDeploymentTargetFloor=(e,t)=>(0,config_plugins_1.withPodfileProperties)(e,r=>(r.modResults=raiseDeploymentTarget(r.modResults,t),r));exports.withIosDeploymentTargetFloor=withIosDeploymentTargetFloor;function raiseDeploymentTarget(e,t){const r=e["ios.deploymentTarget"];return r!==void 0&&compareVersions(r,t)>=0?{...e}:{...e,"ios.deploymentTarget":t}}function compareVersions(e,t){const r=e.split("."),n=t.split(".");for(let o=0;o<Math.max(r.length,n.length);o++){const s=toNumber(r[o]??"0")-toNumber(n[o]??"0");if(s!==0)return s}return 0}function toNumber(e){const t=Number.parseInt(e,10);return Number.isNaN(t)?0:t}
|
|
@@ -7,6 +7,8 @@ export interface PodfileLinkOptions {
|
|
|
7
7
|
podTarget: string;
|
|
8
8
|
/** SPM library product names to link to the pod target. */
|
|
9
9
|
products: string[];
|
|
10
|
+
/** Fail `pod install` when the target is absent — a warning there reads as success. */
|
|
11
|
+
required?: boolean;
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
12
14
|
* Idempotently injects an SPM-linking Ruby block into the Podfile's
|
|
@@ -15,3 +17,18 @@ export interface PodfileLinkOptions {
|
|
|
15
17
|
* product changes flow through cleanly on the next prebuild).
|
|
16
18
|
*/
|
|
17
19
|
export declare function injectPodfileSpmBlock(podfile: string, options: PodfileLinkOptions): string;
|
|
20
|
+
/**
|
|
21
|
+
* Links kamera-spm's products into the `kamera-rn` (and `kamera-testing`) pod
|
|
22
|
+
* targets with the helper `@smileid/kamera` ships. The SDK's own binaries link
|
|
23
|
+
* `Kamera.framework` dynamically and ios-spm declares kamera-spm for the app, so
|
|
24
|
+
* the kamera pod must take Kamera from that same package instead of vendoring a
|
|
25
|
+
* second copy; the helper pins kamera-spm at the installed `@smileid/kamera`
|
|
26
|
+
* version, so the pin can never drift from the JS side. Idempotent per marker.
|
|
27
|
+
*/
|
|
28
|
+
export declare function injectPodfileKameraLinkBlock(podfile: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Adds the archive signature-dedup phase to the app target of the user's own
|
|
31
|
+
* project — the path for apps whose `ios/` is hand-maintained, where no config
|
|
32
|
+
* plugin runs. Guarded by phase name, so an app on both paths gets one.
|
|
33
|
+
*/
|
|
34
|
+
export declare function injectPodfileSignatureDedupBlock(podfile: string): string;
|