@breeztech/breez-sdk-spark-react-native 0.15.1 → 0.16.1-dev1
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/cpp/generated/breez_sdk_spark.cpp +4947 -2629
- package/cpp/generated/breez_sdk_spark.hpp +257 -110
- package/lib/commonjs/generated/breez_sdk_spark-ffi.js.map +1 -1
- package/lib/commonjs/generated/breez_sdk_spark.js +1304 -580
- package/lib/commonjs/generated/breez_sdk_spark.js.map +1 -1
- package/lib/commonjs/passkey-prf-provider.js +300 -0
- package/lib/commonjs/passkey-prf-provider.js.map +1 -0
- package/lib/module/generated/breez_sdk_spark-ffi.js.map +1 -1
- package/lib/module/generated/breez_sdk_spark.js +1304 -580
- package/lib/module/generated/breez_sdk_spark.js.map +1 -1
- package/lib/module/passkey-prf-provider.js +293 -0
- package/lib/module/passkey-prf-provider.js.map +1 -0
- package/lib/typescript/commonjs/src/generated/breez_sdk_spark-ffi.d.ts +199 -140
- package/lib/typescript/commonjs/src/generated/breez_sdk_spark-ffi.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/generated/breez_sdk_spark.d.ts +6149 -3695
- package/lib/typescript/commonjs/src/generated/breez_sdk_spark.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/passkey-prf-provider.d.ts +135 -0
- package/lib/typescript/commonjs/src/passkey-prf-provider.d.ts.map +1 -0
- package/lib/typescript/module/src/generated/breez_sdk_spark-ffi.d.ts +199 -140
- package/lib/typescript/module/src/generated/breez_sdk_spark-ffi.d.ts.map +1 -1
- package/lib/typescript/module/src/generated/breez_sdk_spark.d.ts +6149 -3695
- package/lib/typescript/module/src/generated/breez_sdk_spark.d.ts.map +1 -1
- package/lib/typescript/module/src/passkey-prf-provider.d.ts +135 -0
- package/lib/typescript/module/src/passkey-prf-provider.d.ts.map +1 -0
- package/package.json +17 -5
- package/scripts/post-ubrn.js +227 -0
- package/src/generated/breez_sdk_spark-ffi.ts +366 -198
- package/src/generated/breez_sdk_spark.ts +12343 -7056
- package/src/passkey-prf-provider.ts +372 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { PasskeyClient as SdkPasskeyClient, PasskeyProviderOptions, type PasskeyConfig, type PrfProvider } from './generated/breez_sdk_spark';
|
|
2
|
+
/**
|
|
3
|
+
* A passkey credential from a register or sign-in ceremony. `credentialId`
|
|
4
|
+
* is always set; the attestation fields are populated on registration and
|
|
5
|
+
* absent on sign-in (an assertion carries no attestation). Persist
|
|
6
|
+
* `credentialId` to drive `excludeCredentials` / `allowCredentials` on later
|
|
7
|
+
* calls. Treat `aaguid` as an unverified display hint, never a trust decision.
|
|
8
|
+
* `userId` is the user handle minted by the native plugin (never host-supplied).
|
|
9
|
+
*/
|
|
10
|
+
export interface PasskeyCredential {
|
|
11
|
+
credentialId: Uint8Array;
|
|
12
|
+
userId: Uint8Array | null;
|
|
13
|
+
aaguid: Uint8Array | null;
|
|
14
|
+
backupEligible: boolean | null;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Result of {@link PasskeyProvider.checkDomainAssociation}. Switch on `kind`
|
|
18
|
+
* to handle each outcome.
|
|
19
|
+
*/
|
|
20
|
+
export type DomainAssociation = {
|
|
21
|
+
kind: 'Associated';
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'NotAssociated';
|
|
24
|
+
source: string;
|
|
25
|
+
reason: string;
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'Skipped';
|
|
28
|
+
reason: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Error thrown when a passkey operation fails, with a structured `code` for
|
|
32
|
+
* programmatic handling: `userCancelled`, `userTimedOut`, `prfNotSupported`,
|
|
33
|
+
* `noCredential`, `configuration`, `credentialAlreadyExists`, `unknown`.
|
|
34
|
+
* `userTimedOut` is the OS biometric inactivity timeout (distinct from the
|
|
35
|
+
* user dismissing the prompt), so hosts may safely auto-retry it.
|
|
36
|
+
*/
|
|
37
|
+
export declare class PasskeyPrfException extends Error {
|
|
38
|
+
readonly code: string;
|
|
39
|
+
constructor(code: string, message: string);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Built-in React Native passkey PRF provider, backed by AuthenticationServices
|
|
43
|
+
* on iOS and Credential Manager on Android. The default {@link PrfProvider};
|
|
44
|
+
* inject a configured instance through {@link PasskeyClientBuilder}. Requires
|
|
45
|
+
* iOS 18+ or Android 14+ (API 34) plus the Associated Domains entitlement
|
|
46
|
+
* (iOS) or assetlinks.json (Android) for the RP domain.
|
|
47
|
+
*/
|
|
48
|
+
export declare class PasskeyProvider {
|
|
49
|
+
/**
|
|
50
|
+
* Breez's shared `keys.breez.technology` RP. Pass as `rpId` to opt in
|
|
51
|
+
* (only valid for apps registered with Breez); apps with their own RP
|
|
52
|
+
* domain pass their own string.
|
|
53
|
+
*/
|
|
54
|
+
static readonly BREEZ_RP_ID: string;
|
|
55
|
+
/** Default `rpName` for the zero-config client when none is supplied. */
|
|
56
|
+
static readonly DEFAULT_RP_NAME: string;
|
|
57
|
+
private rpId;
|
|
58
|
+
private rpName;
|
|
59
|
+
private userName;
|
|
60
|
+
private userDisplayName;
|
|
61
|
+
constructor(options: PasskeyProviderOptions);
|
|
62
|
+
/**
|
|
63
|
+
* Derive one 32-byte seed per salt from passkey PRF, in as few OS prompts
|
|
64
|
+
* as the platform supports. `allowCredentials` restricts the assertion to
|
|
65
|
+
* specific credential IDs (mainly for reauthentication) when non-empty;
|
|
66
|
+
* `preferImmediatelyAvailableCredentials` overrides the platform default
|
|
67
|
+
* when set. Returns the seeds plus the asserted credential ID.
|
|
68
|
+
*/
|
|
69
|
+
deriveSeeds(request: {
|
|
70
|
+
salts: string[];
|
|
71
|
+
allowCredentials?: Uint8Array[];
|
|
72
|
+
preferImmediatelyAvailableCredentials?: boolean | null;
|
|
73
|
+
}): Promise<{
|
|
74
|
+
seeds: Uint8Array[];
|
|
75
|
+
credentialId?: Uint8Array;
|
|
76
|
+
}>;
|
|
77
|
+
/**
|
|
78
|
+
* Register a new PRF-capable passkey (one prompt, no seed derivation): use
|
|
79
|
+
* it to split credential creation from derivation in multi-step onboarding.
|
|
80
|
+
* `excludeCredentials` blocks re-registering a device that already holds a
|
|
81
|
+
* credential, surfaced as a `credentialAlreadyExists` failure. The returned
|
|
82
|
+
* user handle is minted fresh per call (never host-supplied).
|
|
83
|
+
*/
|
|
84
|
+
createPasskey(excludeCredentials?: Uint8Array[]): Promise<PasskeyCredential>;
|
|
85
|
+
/** Whether this device supports passkeys with the PRF extension. */
|
|
86
|
+
isSupported(): Promise<boolean>;
|
|
87
|
+
/**
|
|
88
|
+
* Verify the app is associated with the configured `rpId` for WebAuthn.
|
|
89
|
+
* Android always returns `Skipped` rather than `NotAssociated`: Credential
|
|
90
|
+
* Manager runs its own check internally against fresher data.
|
|
91
|
+
*/
|
|
92
|
+
checkDomainAssociation(): Promise<DomainAssociation>;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Builds a `PasskeyClient` backed by a caller-supplied provider. Use this
|
|
96
|
+
* for a custom PRF backend; omit the provider for the zero-config Breez-RP
|
|
97
|
+
* default and set `providerOptions` on the config to use your own RP.
|
|
98
|
+
*/
|
|
99
|
+
export declare class PasskeyClientBuilder {
|
|
100
|
+
private readonly breezApiKey?;
|
|
101
|
+
private readonly config?;
|
|
102
|
+
private provider?;
|
|
103
|
+
/**
|
|
104
|
+
* @param breezApiKey Breez relay key for authenticated (NIP-42) label
|
|
105
|
+
* storage. Omit for public relays only.
|
|
106
|
+
* @param config Passkey client config. `providerOptions` configures the
|
|
107
|
+
* default provider (ignored when a provider is injected via
|
|
108
|
+
* {@link withPrfProvider}, which owns its RP); `defaultLabel` is the
|
|
109
|
+
* label-store default.
|
|
110
|
+
*/
|
|
111
|
+
constructor(breezApiKey?: string | undefined, config?: PasskeyConfig | undefined);
|
|
112
|
+
/**
|
|
113
|
+
* Inject the provider the client derives seeds through: the built-in
|
|
114
|
+
* {@link PasskeyProvider} or any custom `PrfProvider` implementation.
|
|
115
|
+
* Supersedes the config's `providerOptions` (the injected provider owns
|
|
116
|
+
* its RP).
|
|
117
|
+
*/
|
|
118
|
+
withPrfProvider(provider: PrfProvider): this;
|
|
119
|
+
/**
|
|
120
|
+
* Construct the client. Falls back to a default {@link PasskeyProvider}
|
|
121
|
+
* on the config's `providerOptions` (default: the Breez RP) when no
|
|
122
|
+
* provider was injected.
|
|
123
|
+
*/
|
|
124
|
+
build(): SdkPasskeyClient;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Zero-config passkey client on the Breez shared RP (`keys.breez.technology`),
|
|
128
|
+
* so a Breez-registered app needs only its relay key; set `providerOptions` on
|
|
129
|
+
* the config to use your own RP. For a custom PRF backend, build the provider
|
|
130
|
+
* and inject it via {@link PasskeyClientBuilder}.
|
|
131
|
+
*/
|
|
132
|
+
export declare const PasskeyClient: {
|
|
133
|
+
new (breezApiKey?: string, config?: PasskeyConfig): SdkPasskeyClient;
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=passkey-prf-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkey-prf-provider.d.ts","sourceRoot":"","sources":["../../../../src/passkey-prf-provider.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,IAAI,gBAAgB,EACjC,sBAAsB,EACtB,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,6BAA6B,CAAC;AAwCrC;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,UAAU,CAAC;IACzB,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK1C;AA+BD;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAA2B;IAE9D,yEAAyE;IACzE,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAW;IAElD,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAAS;gBAEpB,OAAO,EAAE,sBAAsB;IAO3C;;;;;;OAMG;IACG,WAAW,CAAC,OAAO,EAAE;QACzB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,gBAAgB,CAAC,EAAE,UAAU,EAAE,CAAC;QAChC,qCAAqC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;KACxD,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QAAC,YAAY,CAAC,EAAE,UAAU,CAAA;KAAE,CAAC;IA2C/D;;;;;;OAMG;IACG,aAAa,CAAC,kBAAkB,GAAE,UAAU,EAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAgCtF,oEAAoE;IAC9D,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAQrC;;;;OAIG;IACG,sBAAsB,IAAI,OAAO,CAAC,iBAAiB,CAAC;CA6B3D;AAqBD;;;;GAIG;AACH,qBAAa,oBAAoB;IAY7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAZ1B,OAAO,CAAC,QAAQ,CAAC,CAAc;IAE/B;;;;;;;OAOG;gBAEgB,WAAW,CAAC,EAAE,MAAM,YAAA,EACpB,MAAM,CAAC,EAAE,aAAa,YAAA;IAGzC;;;;;OAKG;IACH,eAAe,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAK5C;;;;OAIG;IACH,KAAK,IAAI,gBAAgB;CAU1B;AAUD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE;IAC1B,KAAK,WAAW,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,gBAAgB,CAAC;CAGtE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@breeztech/breez-sdk-spark-react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1-dev1",
|
|
4
4
|
"description": "React Native bindings for the Breez SDK - Nodeless (Spark Implementation)",
|
|
5
5
|
"source": "./src/index.tsx",
|
|
6
6
|
"main": "./lib/commonjs/index.js",
|
|
7
|
+
"types": "./lib/typescript/commonjs/src/index.d.ts",
|
|
7
8
|
"module": "./lib/module/index.js",
|
|
8
9
|
"exports": {
|
|
9
10
|
"./app.plugin.js": "./app.plugin.js",
|
|
11
|
+
"./passkey-prf-provider": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./lib/typescript/module/src/passkey-prf-provider.d.ts",
|
|
14
|
+
"default": "./lib/module/passkey-prf-provider.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./lib/typescript/commonjs/src/passkey-prf-provider.d.ts",
|
|
18
|
+
"default": "./lib/commonjs/passkey-prf-provider.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
10
21
|
".": {
|
|
11
22
|
"import": {
|
|
12
23
|
"types": "./lib/typescript/module/src/index.d.ts",
|
|
@@ -52,11 +63,12 @@
|
|
|
52
63
|
"prepare": "bob build && yarn plugin:build",
|
|
53
64
|
"release": "release-it --only-version",
|
|
54
65
|
"typecheck": "tsc",
|
|
55
|
-
"ubrn:android": "ubrn build android --release --config ubrn.config.yaml --and-generate",
|
|
66
|
+
"ubrn:android": "ubrn build android --release --config ubrn.config.yaml --and-generate && yarn post-ubrn",
|
|
56
67
|
"ubrn:build": "yarn ubrn:ios && yarn ubrn:android",
|
|
57
68
|
"ubrn:checkout": "ubrn checkout --config ubrn.config.yaml",
|
|
58
69
|
"ubrn:clean": "rm -rfv cpp/ android/CMakeLists.txt android/src/main/java android/*.cpp ios/ src/Native* src/index.*ts* src/generated/",
|
|
59
|
-
"ubrn:ios": "ubrn build ios --release --config ubrn.config.yaml --and-generate"
|
|
70
|
+
"ubrn:ios": "ubrn build ios --release --config ubrn.config.yaml --and-generate && yarn post-ubrn",
|
|
71
|
+
"post-ubrn": "node ./scripts/post-ubrn.js"
|
|
60
72
|
},
|
|
61
73
|
"keywords": [
|
|
62
74
|
"react-native",
|
|
@@ -197,7 +209,7 @@
|
|
|
197
209
|
"version": "0.49.0"
|
|
198
210
|
},
|
|
199
211
|
"checksums": {
|
|
200
|
-
"android": "
|
|
201
|
-
"ios": "
|
|
212
|
+
"android": "221bd9a358381e424f56018a81c4e359fde5799382bacea4cff86cb9d3f19607",
|
|
213
|
+
"ios": "46fdfca17557a6a5b65785c1c65a1375e1b4b2c754c0402dda809150c6e144bd"
|
|
202
214
|
}
|
|
203
215
|
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Apply hand-edits to uniffi-bindgen-react-native-generated files after
|
|
4
|
+
* running `yarn ubrn:android`, `yarn ubrn:ios`, or `yarn ubrn:checkout`.
|
|
5
|
+
*
|
|
6
|
+
* The code generator is unaware of the built-in passkey PRF provider, so
|
|
7
|
+
* each regeneration would otherwise silently drop the few lines required
|
|
8
|
+
* to:
|
|
9
|
+
*
|
|
10
|
+
* 1. android/build.gradle
|
|
11
|
+
* - add androidx.credentials / kotlinx-coroutines dependencies
|
|
12
|
+
* (needed by the hand-written BreezSdkSparkPasskeyModule.kt and
|
|
13
|
+
* CredentialManagerPrfCore.kt)
|
|
14
|
+
* - add `src/main/kotlin` to the Android gradle sourceSets so
|
|
15
|
+
* those hand-written files (which live under
|
|
16
|
+
* `android/src/main/kotlin/...` to survive `yarn ubrn:clean`)
|
|
17
|
+
* are actually compiled
|
|
18
|
+
*
|
|
19
|
+
* 2. android/src/main/java/.../BreezSdkSparkReactNativePackage.kt
|
|
20
|
+
* - register BreezSdkSparkPasskeyModule alongside the generated
|
|
21
|
+
* UniFFI TurboModule so React Native can find it at runtime
|
|
22
|
+
*
|
|
23
|
+
* The PasskeyProvider class is exposed via a subpath export
|
|
24
|
+
* (`@breeztech/breez-sdk-spark-react-native/passkey-prf-provider`) declared
|
|
25
|
+
* in package.json `exports`, so no edit to the generated `src/index.tsx`
|
|
26
|
+
* is required.
|
|
27
|
+
*
|
|
28
|
+
* Each patch is idempotent (runs as a no-op if already applied) and
|
|
29
|
+
* errors loudly if its anchor cannot be found. If uniffi-bindgen-react-native
|
|
30
|
+
* changes its output format, this script fails fast with an actionable
|
|
31
|
+
* message instead of silently producing a broken package.
|
|
32
|
+
*
|
|
33
|
+
* Invoked automatically by the `ubrn:*` npm scripts; can also be run
|
|
34
|
+
* manually via `yarn post-ubrn`.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
'use strict';
|
|
38
|
+
|
|
39
|
+
const fs = require('fs');
|
|
40
|
+
const path = require('path');
|
|
41
|
+
|
|
42
|
+
const args = process.argv.slice(2);
|
|
43
|
+
const checkMode = args.includes('--check') || args.includes('--dry-run');
|
|
44
|
+
|
|
45
|
+
const repoRoot = path.resolve(__dirname, '..');
|
|
46
|
+
const drift = [];
|
|
47
|
+
const errors = [];
|
|
48
|
+
|
|
49
|
+
function patchFile(relPath, label, patcher) {
|
|
50
|
+
const filePath = path.join(repoRoot, relPath);
|
|
51
|
+
if (!fs.existsSync(filePath)) {
|
|
52
|
+
console.log(`[post-ubrn] ${label}: skipping, file not yet generated (${relPath})`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
let before, after;
|
|
56
|
+
try {
|
|
57
|
+
before = fs.readFileSync(filePath, 'utf8');
|
|
58
|
+
after = patcher(before, label, relPath);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
errors.push({ label, relPath, message: err.message });
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (before === after) {
|
|
64
|
+
console.log(`[post-ubrn] ${label}: already patched (${relPath})`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (checkMode) {
|
|
68
|
+
drift.push({ label, relPath });
|
|
69
|
+
console.log(`[post-ubrn] ${label}: WOULD PATCH (${relPath})`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
fs.writeFileSync(filePath, after);
|
|
73
|
+
console.log(`[post-ubrn] ${label}: patched (${relPath})`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function requireAnchor(content, anchor, label, relPath) {
|
|
77
|
+
if (!content.includes(anchor)) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
`anchor not found. The uniffi-bindgen-react-native output format may ` +
|
|
80
|
+
`have changed (check the installed version against the one this ` +
|
|
81
|
+
`script was written for). See CLAUDE.md "Generated Files Policy" ` +
|
|
82
|
+
`for how to update the patches. Expected anchor text:\n${anchor}`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// 1. android/build.gradle
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
patchFile(
|
|
92
|
+
'android/build.gradle',
|
|
93
|
+
'androidx.credentials dependencies',
|
|
94
|
+
(content, label, relPath) => {
|
|
95
|
+
if (content.includes('androidx.credentials:credentials:1.3.0')) {
|
|
96
|
+
return content;
|
|
97
|
+
}
|
|
98
|
+
const anchor = ' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"';
|
|
99
|
+
requireAnchor(content, anchor, label, relPath);
|
|
100
|
+
const injected = [
|
|
101
|
+
anchor,
|
|
102
|
+
' implementation "androidx.credentials:credentials:1.3.0"',
|
|
103
|
+
' implementation "androidx.credentials:credentials-play-services-auth:1.3.0"',
|
|
104
|
+
' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0"',
|
|
105
|
+
].join('\n');
|
|
106
|
+
return content.replace(anchor, injected);
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
patchFile(
|
|
111
|
+
'android/build.gradle',
|
|
112
|
+
'src/main/kotlin sourceSet',
|
|
113
|
+
(content, label, relPath) => {
|
|
114
|
+
if (content.includes("main.kotlin.srcDirs += 'src/main/kotlin'")) {
|
|
115
|
+
return content;
|
|
116
|
+
}
|
|
117
|
+
// The generated build.gradle already has a `sourceSets { main { ... } }`
|
|
118
|
+
// block (for the new-architecture jni dirs). Extend it by adding the
|
|
119
|
+
// hand-written kotlin source dir right after the opening `main {`.
|
|
120
|
+
const anchor = ` sourceSets {
|
|
121
|
+
main {
|
|
122
|
+
if (isNewArchitectureEnabled()) {`;
|
|
123
|
+
requireAnchor(content, anchor, label, relPath);
|
|
124
|
+
return content.replace(
|
|
125
|
+
anchor,
|
|
126
|
+
` sourceSets {
|
|
127
|
+
main {
|
|
128
|
+
main.kotlin.srcDirs += 'src/main/kotlin'
|
|
129
|
+
if (isNewArchitectureEnabled()) {`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// 2. android/src/main/java/.../BreezSdkSparkReactNativePackage.kt
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
|
|
138
|
+
const PACKAGE_KT_REL =
|
|
139
|
+
'android/src/main/java/com/breeztech/breezsdkspark/BreezSdkSparkReactNativePackage.kt';
|
|
140
|
+
|
|
141
|
+
patchFile(
|
|
142
|
+
PACKAGE_KT_REL,
|
|
143
|
+
'BreezSdkSparkPasskeyModule getModule() registration',
|
|
144
|
+
(content, label, relPath) => {
|
|
145
|
+
if (content.includes('BreezSdkSparkPasskeyModule.NAME ->')) {
|
|
146
|
+
return content;
|
|
147
|
+
}
|
|
148
|
+
const anchor = ` override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
149
|
+
return if (name == BreezSdkSparkReactNativeModule.NAME) {
|
|
150
|
+
BreezSdkSparkReactNativeModule(reactContext)
|
|
151
|
+
} else {
|
|
152
|
+
null
|
|
153
|
+
}
|
|
154
|
+
}`;
|
|
155
|
+
const replacement = ` override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
156
|
+
return when (name) {
|
|
157
|
+
BreezSdkSparkReactNativeModule.NAME -> BreezSdkSparkReactNativeModule(reactContext)
|
|
158
|
+
BreezSdkSparkPasskeyModule.NAME -> BreezSdkSparkPasskeyModule(reactContext)
|
|
159
|
+
else -> null
|
|
160
|
+
}
|
|
161
|
+
}`;
|
|
162
|
+
requireAnchor(content, anchor, label, relPath);
|
|
163
|
+
return content.replace(anchor, replacement);
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
patchFile(
|
|
168
|
+
PACKAGE_KT_REL,
|
|
169
|
+
'BreezSdkSparkPasskeyModule ReactModuleInfo registration',
|
|
170
|
+
(content, label, relPath) => {
|
|
171
|
+
if (content.includes('moduleInfos[BreezSdkSparkPasskeyModule.NAME]')) {
|
|
172
|
+
return content;
|
|
173
|
+
}
|
|
174
|
+
const anchor = ` true // isTurboModule
|
|
175
|
+
)
|
|
176
|
+
moduleInfos
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}`;
|
|
180
|
+
const replacement = ` true // isTurboModule
|
|
181
|
+
)
|
|
182
|
+
moduleInfos[BreezSdkSparkPasskeyModule.NAME] = ReactModuleInfo(
|
|
183
|
+
BreezSdkSparkPasskeyModule.NAME,
|
|
184
|
+
BreezSdkSparkPasskeyModule.NAME,
|
|
185
|
+
false, // canOverrideExistingModule
|
|
186
|
+
false, // needsEagerInit
|
|
187
|
+
false, // isCxxModule
|
|
188
|
+
false // isTurboModule (standard native module)
|
|
189
|
+
)
|
|
190
|
+
moduleInfos
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}`;
|
|
194
|
+
requireAnchor(content, anchor, label, relPath);
|
|
195
|
+
return content.replace(anchor, replacement);
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
if (errors.length > 0) {
|
|
200
|
+
console.error('');
|
|
201
|
+
console.error(`[post-ubrn] ${errors.length} patch(es) failed:`);
|
|
202
|
+
for (const { label, relPath, message } of errors) {
|
|
203
|
+
console.error(` - ${label} (${relPath})`);
|
|
204
|
+
console.error(` ${message.split('\n').join('\n ')}`);
|
|
205
|
+
}
|
|
206
|
+
process.exit(2);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (checkMode && drift.length > 0) {
|
|
210
|
+
console.error('');
|
|
211
|
+
console.error(
|
|
212
|
+
`[post-ubrn] ${drift.length} generated file(s) are out of sync with the ` +
|
|
213
|
+
`committed hand-edits:`
|
|
214
|
+
);
|
|
215
|
+
for (const { label, relPath } of drift) {
|
|
216
|
+
console.error(` - ${label} (${relPath})`);
|
|
217
|
+
}
|
|
218
|
+
console.error('');
|
|
219
|
+
console.error(
|
|
220
|
+
'Run `yarn post-ubrn` inside packages/react-native and commit the diff, ' +
|
|
221
|
+
'or revert whatever change dropped the patches. See CLAUDE.md ' +
|
|
222
|
+
'"Generated Files Policy" for context.'
|
|
223
|
+
);
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
console.log('[post-ubrn] done.');
|