@smileid/usesmileid_vision_face 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.
@@ -1,96 +0,0 @@
1
- import CoreMedia
2
- import CoreImage
3
- import UIKit
4
- import VisionCamera
5
-
6
- /// VisionCamera frame processor plugin that feeds camera frames directly
7
- /// into the active `UseSmileIDFaceSession` without crossing the JS thread.
8
- ///
9
- /// Registered programmatically via `FrameProcessorPluginRegistry` (avoids ObjC bridging-header
10
- /// constraint); the `OnCreate` guard prevents double-registration on fast-refresh reloads.
11
- /// All session ops are serialised through `UseSmileIDVisionFaceSessionHolder.operationQueue`.
12
- /// `CIContext` is created once per instance — per-frame creation causes GPU pipeline re-compilation.
13
- @objc(UseSmileIDVisionFaceFrameProcessorPlugin)
14
- public class UseSmileIDVisionFaceFrameProcessorPlugin: FrameProcessorPlugin {
15
-
16
- /// GPU-backed context reused across frames (CPU fallback if Metal unavailable).
17
- private let ciContext = CIContext(options: [.useSoftwareRenderer: false])
18
-
19
- @objc public override init(proxy: VisionCameraProxyHolder, options: [AnyHashable: Any]? = nil) {
20
- super.init(proxy: proxy, options: options)
21
- }
22
-
23
- public override func callback(_ frame: Frame, withArguments arguments: [AnyHashable: Any]?) -> Any? {
24
- guard frame.isValid else {
25
- return ["error": "frame_conversion_failed"]
26
- }
27
-
28
- guard let pixelBuffer = CMSampleBufferGetImageBuffer(frame.buffer) else {
29
- return ["error": "frame_conversion_failed"]
30
- }
31
-
32
- // Bake rotation physically into pixels (CIImage.oriented) rather than
33
- // tagging UIImage with an orientation flag: some consumers honour the flag
34
- // (UIKit draw) but others ignore it (raw CGImage ops), so physical pixels are safer.
35
- // The front camera's mirror is preserved — the analyzer's head-pose
36
- // convention is calibrated on mirrored pixels; un-mirroring flips
37
- // Vision's yaw sign and inverts the ESS head-turn gates.
38
- let orientationFlag = frame.isMirrored
39
- ? frame.orientation.oppositeRotationPreservingMirror()
40
- : frame.orientation
41
- let orientedImage = CIImage(cvPixelBuffer: pixelBuffer)
42
- .oriented(CGImagePropertyOrientation(orientationFlag))
43
-
44
- guard let cgImage = ciContext.createCGImage(orientedImage, from: orientedImage.extent) else {
45
- return ["error": "frame_conversion_failed"]
46
- }
47
-
48
- let rotation = (arguments?["rotation"] as? NSNumber)?.intValue ?? 0
49
- let uiImage = UIImage(cgImage: cgImage)
50
-
51
- guard let result = UseSmileIDVisionFaceSessionHolder.shared.scanAndDrain(
52
- image: uiImage,
53
- rotation: rotation
54
- ) else {
55
- return ["error": "session_not_configured"]
56
- }
57
-
58
- return result
59
- }
60
- }
61
-
62
-
63
- private extension UIImage.Orientation {
64
- /// Rotation-only flag that uprights a MIRRORED buffer while keeping its
65
- /// mirror — flipH ∘ transpose is the opposite 90°, so quarter-turns swap.
66
- /// Device-verified: `.right` ⇒ upright mirrored; raw `.left` ⇒ upside down.
67
- func oppositeRotationPreservingMirror() -> UIImage.Orientation {
68
- switch self {
69
- case .left: return .right
70
- case .right: return .left
71
- case .leftMirrored: return .rightMirrored
72
- case .rightMirrored: return .leftMirrored
73
- default: return self
74
- }
75
- }
76
- }
77
-
78
-
79
- private extension CGImagePropertyOrientation {
80
- /// Case-for-case translation from `UIImage.Orientation` — the two
81
- /// enums share semantics but not raw values, so a direct cast would
82
- /// silently produce the wrong transform.
83
- init(_ uiOrientation: UIImage.Orientation) {
84
- switch uiOrientation {
85
- case .up: self = .up
86
- case .upMirrored: self = .upMirrored
87
- case .down: self = .down
88
- case .downMirrored: self = .downMirrored
89
- case .left: self = .left
90
- case .leftMirrored: self = .leftMirrored
91
- case .right: self = .right
92
- case .rightMirrored: self = .rightMirrored
93
- @unknown default: self = .up
94
- }
95
- }
96
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,iEAAiE;AACjE,0DAA0D;AAC1D,qEAAqE;AACrE,2CAA2C;AAC3C,mEAAmE;AACnE,oEAAoE;AACpE,uEAAuE;AACvE,EAAE;AACF,oDAAoD;AACpD,oEAAoE;AACpE,sEAAsE;AACtE,oEAAoE;AACpE,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE9B,yDAI8B;AAC9B,uCAAyB;AACzB,2CAA6B;AAE7B,2CAAsD;AACtD,mCAAuD;AAEvD,4DAA4D;AAC5D,uEAAuE;AACvE,+DAA+D;AAC/D,8BAA8B;AAC9B,MAAM,gBAAgB,GAAe;IACnC,GAAG,EAAE,0CAA0C;IAC/C,WAAW,EAAE;QACX,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,4CAA4C;KACtD;CACF,CAAC;AAEF,MAAM,UAAU,GAAG,0BAA0B,CAAC;AAC9C,sEAAsE;AACtE,qEAAqE;AACrE,sEAAsE;AACtE,+DAA+D;AAC/D,uDAAuD;AACvD,yEAAyE;AACzE,qEAAqE;AACrE,kEAAkE;AAClE,MAAM,YAAY,GAAG,CAAC,sBAAsB,EAAE,kBAAkB,CAAU,CAAC;AAC3E,MAAM,cAAc,GAAG,wBAAwB,CAAC;AAEhD,MAAM,iBAAiB,GAAiB,CAAC,MAAM,EAAE,EAAE;IACjD,mEAAmE;IACnE,mEAAmE;IACnE,wBAAwB;IACxB,MAAM,GAAG,IAAA,iCAAgB,EAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;QAC3C,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC;QAChD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,0FAA0F,CAC3F,CAAC;QACJ,CAAC;QACD,IAAA,oBAAc,EAAC,MAAM,CAAC,UAAU,EAAE,gBAAgB,EAAE;YAClD,UAAU,EAAE,SAAS;YACrB,QAAQ,EAAE,CAAC,GAAG,YAAY,CAAC;SAC5B,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,mEAAmE;IACnE,iEAAiE;IACjE,+DAA+D;IAC/D,oEAAoE;IACpE,MAAM,GAAG,IAAA,iCAAgB,EAAC,MAAM,EAAE;QAChC,KAAK;QACL,CAAC,MAAM,EAAE,EAAE;YACT,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAC3B,MAAM,CAAC,UAAU,CAAC,mBAAmB,EACrC,SAAS,CACV,CAAC;YACF,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACvD,MAAM,IAAI,GAAG,IAAA,+BAAqB,EAAC,QAAQ,EAAE;gBAC3C,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,gBAAgB;gBACzB,SAAS,EAAE,UAAU;gBACrB,QAAQ,EAAE,CAAC,GAAG,YAAY,CAAC;aAC5B,CAAC,CAAC;YACH,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YACtC,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,kBAAe,iBAAiB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"podfile.js","sourceRoot":"","sources":["../../src/lib/podfile.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"spm.js","sourceRoot":"","sources":["../../src/lib/spm.ts"],"names":[],"mappings":"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"}
@@ -1,96 +0,0 @@
1
- // Expo config plugin that wires the Smile Identity Swift Package
2
- // (`https://github.com/smileidentity/ios-spm`) into both:
3
- // 1. The consuming app's Xcode project — so the .xcframeworks ship
4
- // and embed in the final .app bundle.
5
- // 2. The autogenerated Pods.xcodeproj at `pod install` time — so
6
- // the Expo Module bridge (`UseSmileIDVisionFaceExpo`) compiles
7
- // with `import UseSmileIDVisionFace` / `import UseSmileIDBridge`.
8
- //
9
- // Why a plugin: `expo-modules-autolinking@55.0.x`'s
10
- // `RawModuleConfigApple` schema has no `dependencies` field, so the
11
- // `apple.dependencies` block in `expo-module.config.json` is silently
12
- // ignored. Without this plugin, neither the bridge nor the host app
13
- // know about the SPM package.
14
-
15
- import {
16
- ConfigPlugin,
17
- withDangerousMod,
18
- withXcodeProject,
19
- } from "@expo/config-plugins";
20
- import * as fs from "fs";
21
- import * as path from "path";
22
-
23
- import { injectPodfileSpmBlock } from "./lib/podfile";
24
- import { linkSpmPackage, SpmPackage } from "./lib/spm";
25
-
26
- // Pinned to the exact `12.0.0` release tag — `from: 12.0.0`
27
- // would not resolve because `ios-spm` publishes pre-release tags (e.g.
28
- // `12.0.0`), and SPM excludes pre-release tags from open-ended
29
- // major-version requirements.
30
- const SMILE_ID_PACKAGE: SpmPackage = {
31
- url: "https://github.com/smileidentity/ios-spm",
32
- requirement: {
33
- kind: "exactVersion",
34
- version: "12.0.1-SNAPSHOT.20260729180601.30478033861",
35
- },
36
- };
37
-
38
- const POD_TARGET = "UseSmileIDVisionFaceExpo";
39
- // `UseSmileIDBridge` is also listed explicitly even though the Vision
40
- // library product wraps it as a transitive target — empirically this
41
- // is what makes `import UseSmileIDBridge` resolve in the bridge under
42
- // SPM-via-CocoaPods. A cleaner config that drops the redundant
43
- // listing is plausible (the SPM Package.swift declares
44
- // `targets: ["UseSmileIDVisionFace", "UseSmileIDBridge"]` for the Vision
45
- // library product) but unverified, and the duplicate produces only a
46
- // benign "Conflicting parseable interfaces" warning at link time.
47
- const SPM_PRODUCTS = ["UseSmileIDVisionFace", "UseSmileIDBridge"] as const;
48
- const PODFILE_MARKER = "usesmileid_vision_face";
49
-
50
- const withVisionFaceSpm: ConfigPlugin = (config) => {
51
- // 1. Add the package + products to the host app's Xcode project so
52
- // Xcode resolves the binary xcframeworks and embeds them in the
53
- // .app at link time.
54
- config = withXcodeProject(config, (config) => {
55
- const appTarget = config.modRequest.projectName;
56
- if (!appTarget) {
57
- throw new Error(
58
- "[usesmileid_vision_face] Unable to resolve host app native target name from Expo config.",
59
- );
60
- }
61
- linkSpmPackage(config.modResults, SMILE_ID_PACKAGE, {
62
- targetName: appTarget,
63
- products: [...SPM_PRODUCTS],
64
- });
65
- return config;
66
- });
67
-
68
- // 2. Inject a Ruby block into the Podfile's post_install hook that
69
- // re-applies the same wiring to Pods.xcodeproj when CocoaPods
70
- // materializes it. The bridge pod target needs the products
71
- // visible at compile time; the host-app step alone isn't enough.
72
- config = withDangerousMod(config, [
73
- "ios",
74
- (config) => {
75
- const podfilePath = path.join(
76
- config.modRequest.platformProjectRoot,
77
- "Podfile",
78
- );
79
- const original = fs.readFileSync(podfilePath, "utf-8");
80
- const next = injectPodfileSpmBlock(original, {
81
- marker: PODFILE_MARKER,
82
- package: SMILE_ID_PACKAGE,
83
- podTarget: POD_TARGET,
84
- products: [...SPM_PRODUCTS],
85
- });
86
- if (next !== original) {
87
- fs.writeFileSync(podfilePath, next);
88
- }
89
- return config;
90
- },
91
- ]);
92
-
93
- return config;
94
- };
95
-
96
- export default withVisionFaceSpm;
@@ -1,209 +0,0 @@
1
- // Injects an idempotent Ruby block into the Expo-generated Podfile's
2
- // `post_install` hook. The block runs at `pod install` time and wires
3
- // the Smile ID Swift Package into the autogenerated Pods.xcodeproj
4
- // for a specific bridge pod target — Pods.xcodeproj only exists at
5
- // pod-install time, so this is the only hook that can mutate it.
6
-
7
- import type { SpmPackage, SpmRequirement } from "./spm";
8
-
9
- const BEGIN_PREFIX = "# === BEGIN smileid-spm:";
10
- const END_PREFIX = "# === END smileid-spm:";
11
-
12
- export interface PodfileLinkOptions {
13
- /** Marker key — distinct per bridge so each plugin owns its own block. */
14
- marker: string;
15
- package: SpmPackage;
16
- /** Pod target name (e.g. `UseSmileIDVisionFaceExpo`). */
17
- podTarget: string;
18
- /** SPM library product names to link to the pod target. */
19
- products: string[];
20
- }
21
-
22
- /**
23
- * Idempotently injects an SPM-linking Ruby block into the Podfile's
24
- * top-level `post_install` block. Re-running on an already-injected
25
- * Podfile rewrites the same marker block in place (so version /
26
- * product changes flow through cleanly on the next prebuild).
27
- */
28
- export function injectPodfileSpmBlock(
29
- podfile: string,
30
- options: PodfileLinkOptions,
31
- ): string {
32
- validateRubySafe(options);
33
-
34
- const block = renderBlock(options);
35
- const beginMarker = `${BEGIN_PREFIX} ${options.marker} ===`;
36
- const endMarker = `${END_PREFIX} ${options.marker} ===`;
37
-
38
- const blockRegex = new RegExp(
39
- `${escapeRegExp(beginMarker)}[\\s\\S]*?${escapeRegExp(endMarker)}`,
40
- "m",
41
- );
42
- if (blockRegex.test(podfile)) {
43
- return podfile.replace(blockRegex, block);
44
- }
45
-
46
- // Inject at the *start* of the post_install body — right after
47
- // `post_install do |installer|`. We tried matching the closing
48
- // `end` pair instead, but a second plugin running on a Podfile
49
- // already mutated by the first sees a non-flat body and the
50
- // non-greedy `end…end` match latches onto inner block ends,
51
- // nesting the second injection inside the first. Anchoring on
52
- // the opening line removes that failure mode entirely. Order
53
- // relative to `react_native_post_install` doesn't matter because
54
- // CocoaPods persists the Pods project at the end of pod install
55
- // regardless of what we explicitly save mid-block.
56
- const headerRegex = /(post_install\s+do\s*\|\s*installer\s*\|)\r?\n/;
57
- const headerMatch = podfile.match(headerRegex);
58
- if (!headerMatch || headerMatch.index === undefined) {
59
- throw new Error(
60
- "[smileid-spm] Could not locate `post_install do |installer|` in Podfile. " +
61
- "Refusing to append a top-level post_install hook because CocoaPods only honors one — adding a second " +
62
- "would silently override the React Native post-install plumbing. Restore the Expo Podfile template " +
63
- "or wire the SPM block in manually.",
64
- );
65
- }
66
- const insertAt = headerMatch.index + headerMatch[0].length;
67
- const indented =
68
- block
69
- .split("\n")
70
- .map((line) => (line.length > 0 ? ` ${line}` : line))
71
- .join("\n") + "\n";
72
- return podfile.slice(0, insertAt) + indented + podfile.slice(insertAt);
73
- }
74
-
75
- // All injected strings flow into single-quoted Ruby literals. We
76
- // reject characters that could break out of those literals so a
77
- // typo in the bridge plugin can't produce code that runs during
78
- // `pod install`. Rejected: single-quote, backslash, control chars.
79
- function validateRubySafe(options: PodfileLinkOptions): void {
80
- const fields: Array<[string, string]> = [
81
- ["marker", options.marker],
82
- ["package.url", options.package.url],
83
- ["podTarget", options.podTarget],
84
- ];
85
- for (const product of options.products) {
86
- fields.push(["products[*]", product]);
87
- }
88
- switch (options.package.requirement.kind) {
89
- case "upToNextMajorVersion":
90
- case "upToNextMinorVersion":
91
- fields.push([
92
- "requirement.minimumVersion",
93
- options.package.requirement.minimumVersion,
94
- ]);
95
- break;
96
- case "exactVersion":
97
- fields.push(["requirement.version", options.package.requirement.version]);
98
- break;
99
- case "branch":
100
- fields.push(["requirement.branch", options.package.requirement.branch]);
101
- break;
102
- }
103
- for (const [name, value] of fields) {
104
- if (/['\\\n\r\t]/.test(value)) {
105
- throw new Error(
106
- `[smileid-spm] Refusing to inject Podfile block: '${name}' contains an unsafe character (got: ${JSON.stringify(value)}).`,
107
- );
108
- }
109
- }
110
- }
111
-
112
- function renderBlock(options: PodfileLinkOptions): string {
113
- const beginMarker = `${BEGIN_PREFIX} ${options.marker} ===`;
114
- const endMarker = `${END_PREFIX} ${options.marker} ===`;
115
- const requirement = renderRequirement(options.package.requirement);
116
- const productList = options.products.map((p) => `'${p}'`).join(", ");
117
-
118
- return `${beginMarker}
119
- # Wires ${options.package.url} into Pods.xcodeproj and links its
120
- # products to the '${options.podTarget}' pod target so the Swift
121
- # bridge code can \`import\` them. Idempotent across pod installs.
122
- #
123
- # UUIDs are minted via SecureRandom rather than \`pods_project.new\`
124
- # because \`prepare_react_native_project!\` sets
125
- # \`:deterministic_uuids => false\`. With that flag off, CocoaPods
126
- # skips its predictabilize step and \`stabilize_target_uuids\` resets
127
- # \`@generated_uuids\` to a tiny leftover pool — so any post_install
128
- # call to \`pods_project.new\` restarts the sequential index near 0
129
- # and re-mints UUIDs already in use. The collision then runs through
130
- # \`add_referrer\`, which clobbers \`objects_by_uuid[uuid]\` and
131
- # leaves the rootObject (\`46EB2E00000000\`) unreachable, crashing
132
- # Xcode 26 with \`XCSwiftPackageProductDependency
133
- # _setSavedArchiveVersion:\` unrecognized selector. Random 24-char
134
- # hex IDs can't collide with the 14-char cocoapods scheme.
135
- begin
136
- pods_project = installer.pods_project
137
- spm_url = '${options.package.url}'
138
- spm_requirement = ${requirement}
139
- product_names = [${productList}]
140
- target_name = '${options.podTarget}'
141
-
142
- smileid_spm_safe_uuid = lambda do |project|
143
- loop do
144
- candidate = SecureRandom.hex(12).upcase
145
- return candidate unless project.objects_by_uuid.key?(candidate)
146
- end
147
- end
148
-
149
- pkg = pods_project.root_object.package_references.find do |r|
150
- r.respond_to?(:repositoryURL) && r.repositoryURL == spm_url
151
- end
152
- unless pkg
153
- pkg_uuid = smileid_spm_safe_uuid.call(pods_project)
154
- pkg = Xcodeproj::Project::Object::XCRemoteSwiftPackageReference.new(pods_project, pkg_uuid)
155
- pkg.initialize_defaults
156
- pkg.repositoryURL = spm_url
157
- pkg.requirement = spm_requirement
158
- pods_project.root_object.package_references << pkg
159
- end
160
-
161
- target = pods_project.targets.find { |t| t.name == target_name }
162
- if target.nil?
163
- Pod::UI.warn "[smileid-spm] Pod target #{target_name} not found; skipping SPM link."
164
- else
165
- product_names.each do |product_name|
166
- already = target.package_product_dependencies.any? do |d|
167
- d.package == pkg && d.product_name == product_name
168
- end
169
- next if already
170
-
171
- dep_uuid = smileid_spm_safe_uuid.call(pods_project)
172
- dep = Xcodeproj::Project::Object::XCSwiftPackageProductDependency.new(pods_project, dep_uuid)
173
- dep.initialize_defaults
174
- dep.package = pkg
175
- dep.product_name = product_name
176
- target.package_product_dependencies << dep
177
-
178
- bf_uuid = smileid_spm_safe_uuid.call(pods_project)
179
- bf = Xcodeproj::Project::Object::PBXBuildFile.new(pods_project, bf_uuid)
180
- bf.initialize_defaults
181
- bf.product_ref = dep
182
- target.frameworks_build_phase.files << bf
183
- end
184
- end
185
-
186
- pods_project.save
187
- rescue => e
188
- Pod::UI.warn "[smileid-spm] Failed to link SPM products for ${options.podTarget}: #{e.message}"
189
- raise
190
- end
191
- ${endMarker}`;
192
- }
193
-
194
- function renderRequirement(req: SpmRequirement): string {
195
- switch (req.kind) {
196
- case "upToNextMajorVersion":
197
- return `{ kind: 'upToNextMajorVersion', minimumVersion: '${req.minimumVersion}' }`;
198
- case "upToNextMinorVersion":
199
- return `{ kind: 'upToNextMinorVersion', minimumVersion: '${req.minimumVersion}' }`;
200
- case "exactVersion":
201
- return `{ kind: 'exactVersion', version: '${req.version}' }`;
202
- case "branch":
203
- return `{ kind: 'branch', branch: '${req.branch}' }`;
204
- }
205
- }
206
-
207
- function escapeRegExp(s: string): string {
208
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
209
- }