lean-ionic-capacitor 1.0.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.
@@ -0,0 +1,17 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'LeanIonicCapacitor'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.license = package['license']
10
+ s.homepage = package['repository']['url']
11
+ s.author = package['author']
12
+ s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
+ s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
+ s.ios.deployment_target = '15.0'
15
+ s.dependency 'Capacitor'
16
+ s.swift_version = '5.1'
17
+ end
package/Package.swift ADDED
@@ -0,0 +1,30 @@
1
+ // swift-tools-version: 5.9
2
+ import PackageDescription
3
+
4
+ let package = Package(
5
+ name: "LeanIonicCapacitor",
6
+ platforms: [.iOS(.v15)],
7
+ products: [
8
+ .library(
9
+ name: "LeanIonicCapacitor",
10
+ targets: ["LEANPlugin"])
11
+ ],
12
+ dependencies: [
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0"),
14
+ .package(url: "https://github.com/leantechnologies/link-sdk-ios-distribution", from: "1.0.0")
15
+ ],
16
+ targets: [
17
+ .target(
18
+ name: "LEANPlugin",
19
+ dependencies: [
20
+ .product(name: "Capacitor", package: "capacitor-swift-pm"),
21
+ .product(name: "Cordova", package: "capacitor-swift-pm"),
22
+ .product(name: "LeanSDK", package: "link-sdk-ios-distribution")
23
+ ],
24
+ path: "ios/Sources/LEANPlugin"),
25
+ .testTarget(
26
+ name: "LEANPluginTests",
27
+ dependencies: ["LEANPlugin"],
28
+ path: "ios/Tests/LEANPluginTests")
29
+ ]
30
+ )
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # lean-ionic-capacitor
2
+
3
+ Capacitor plugin for **Lean Technologies Link**: one API for Web, Android, and iOS. Connect customers to Payments and Data with native flows, deep linking, and sandbox/production support.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install lean-ionic-capacitor
9
+ npx cap sync
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ ```typescript
15
+ import { Lean } from 'lean-ionic-capacitor';
16
+
17
+ const result = await Lean.connect({
18
+ customerId: '123',
19
+ permissions: ['accounts', 'transactions'],
20
+ sandbox: true,
21
+ appToken: 'YOUR_APP_TOKEN', // required on Web; recommended on native
22
+ successRedirectUrl: 'https://yourapp.com/success',
23
+ failRedirectUrl: 'https://yourapp.com/fail',
24
+ bankIdentifier: 'LEANMB1', // optional: skip bank list
25
+ });
26
+
27
+ // result: { status: 'SUCCESS' | 'CANCELLED' | 'ERROR', message?, bank?, ... }
28
+ ```
29
+
30
+ ## Platform overview
31
+
32
+ | Platform | Implementation |
33
+ | --------- | --------------------------------------------------- |
34
+ | Web | Lean Link Web SDK (load script in your app) |
35
+ | Android | Lean Link Android SDK via reflection |
36
+ | iOS | Lean Link iOS SDK (Swift Package) |
37
+
38
+ ## Setup by platform
39
+
40
+ ### Web
41
+
42
+ Load the Lean script once (e.g. in `index.html`):
43
+
44
+ ```html
45
+ <script src="https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js"></script>
46
+ ```
47
+
48
+ Pass `appToken` (and optionally `accessToken`) in `connect()`.
49
+
50
+ ### Android
51
+
52
+ The plugin uses the Lean SDK at runtime. Your app must add:
53
+
54
+ 1. **Repositories:** `maven { url 'https://jitpack.io' }` (project or settings)
55
+ 2. **Dependencies:** `implementation "me.leantech:link-sdk-android:3.0.2"` (app module)
56
+
57
+ Pass `appToken` in `connect()`.
58
+
59
+ ### iOS
60
+
61
+ Add the Lean iOS SDK in Xcode: **File → Add Package Dependencies** →
62
+ `https://github.com/leantechnologies/link-sdk-ios-distribution`
63
+
64
+ Set `appToken` via `Lean.manager.setup(appToken, sandbox, version)` in app init, or pass it in `connect()`.
65
+
66
+ ## API
67
+
68
+ ### `Lean.connect(options)`
69
+
70
+ Connects a customer to Lean. Returns `Promise<LeanConnectResult>`.
71
+
72
+ #### Options
73
+
74
+ | Option | Type | Required | Description |
75
+ | ---------------------- | ---------- | ------------- | ------------------------------------------------------------------------ |
76
+ | `customerId` | `string` | Yes | Your Lean customer identifier. |
77
+ | `permissions` | `string[]` | Yes | `'identity'`, `'accounts'`, `'transactions'`, `'balance'`, `'payments'`. |
78
+ | `sandbox` | `boolean` | No | Use sandbox (default `true`). |
79
+ | `appToken` | `string` | Web / Android | Lean app token. |
80
+ | `accessToken` | `string` | No | Customer-scoped token for token exchange. |
81
+ | `successRedirectUrl` | `string` | No | Redirect URL on success (Open Finance). |
82
+ | `failRedirectUrl` | `string` | No | Redirect URL on failure (Open Finance). |
83
+ | `bankIdentifier` | `string` | No | Pre-select a bank (skip bank list). |
84
+ | `paymentDestinationId` | `string` | No | Payment destination (defaults to your CMA account). |
85
+
86
+ #### Result
87
+
88
+ ```ts
89
+ interface LeanConnectResult {
90
+ status: 'SUCCESS' | 'CANCELLED' | 'ERROR';
91
+ message?: string | null;
92
+ last_api_response?: string | null;
93
+ exit_point?: string | null;
94
+ secondary_status?: string | null;
95
+ bank?: { bank_identifier?: string; is_supported?: boolean } | null;
96
+ }
97
+ ```
98
+
99
+ ## Deep linking and token exchange
100
+
101
+ - **Deep linking:** Set `successRedirectUrl` and `failRedirectUrl` so Lean redirects back to your app.
102
+ - **Token exchange:** Issue a customer-scoped `accessToken` on your backend and pass it (with `appToken`) in `connect()`; the plugin forwards them to the Lean SDK.
103
+
104
+ ## Troubleshooting
105
+
106
+ **Android: "Lean SDK not found"**
107
+ Add JitPack and `implementation "me.leantech:link-sdk-android:3.0.2"` in your **app’s** `build.gradle`, then `npx cap sync android` and rebuild.
108
+
109
+ ## Development
110
+
111
+ - **Verify (all platforms):** `npm run verify`
112
+ - **Check (plugin + example app):** `npm run check`
113
+ - **Web only:** `npm run check:web`
114
+ - **iOS only:** `npm run check:ios`
115
+
116
+ See [VERIFY.md](VERIFY.md) for detailed steps. Before release: run `npm run lint`, then see [PRODUCTION.md](PRODUCTION.md). [CHANGELOG.md](CHANGELOG.md) lists version history.
117
+
118
+ ## License
119
+
120
+ MIT
@@ -0,0 +1,66 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
4
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
5
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
6
+ }
7
+
8
+ buildscript {
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+ dependencies {
14
+ classpath 'com.android.tools.build:gradle:8.13.0'
15
+ classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22'
16
+ }
17
+ }
18
+
19
+ apply plugin: 'com.android.library'
20
+ apply plugin: 'kotlin-android'
21
+
22
+ android {
23
+ namespace = "com.codecraft_studio.lean"
24
+ compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
25
+ defaultConfig {
26
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
27
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
28
+ versionCode 1
29
+ versionName "1.0"
30
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
31
+ }
32
+ buildTypes {
33
+ release {
34
+ minifyEnabled false
35
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
36
+ }
37
+ }
38
+ lintOptions {
39
+ abortOnError = false
40
+ }
41
+ compileOptions {
42
+ sourceCompatibility JavaVersion.VERSION_21
43
+ targetCompatibility JavaVersion.VERSION_21
44
+ }
45
+ kotlinOptions {
46
+ jvmTarget = '21'
47
+ }
48
+ }
49
+
50
+ repositories {
51
+ google()
52
+ mavenCentral()
53
+ maven { url 'https://jitpack.io' }
54
+ }
55
+
56
+ dependencies {
57
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
58
+ implementation project(':capacitor-android')
59
+ implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
60
+ testImplementation "junit:junit:$junitVersion"
61
+ androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
62
+ androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
63
+ // Lean SDK is loaded at runtime via reflection when the host app adds it.
64
+ // Host app must add: implementation "me.leantech:link-sdk-android:3.0.2" and maven { url 'https://jitpack.io' }
65
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.22"
66
+ }
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,214 @@
1
+ package com.codecraft_studio.lean
2
+
3
+ import android.app.Activity
4
+ import com.getcapacitor.JSObject
5
+ import com.getcapacitor.Plugin
6
+ import com.getcapacitor.PluginCall
7
+ import com.getcapacitor.PluginMethod
8
+ import com.getcapacitor.annotation.CapacitorPlugin
9
+ import org.json.JSONArray
10
+ import java.lang.reflect.Proxy
11
+
12
+ /**
13
+ * Capacitor plugin bridging to Lean Link Android SDK via reflection.
14
+ * The host app must add: implementation "me.leantech:link-sdk-android:3.0.2"
15
+ * and JitPack: maven { url 'https://jitpack.io' }
16
+ */
17
+ @CapacitorPlugin(name = "Lean")
18
+ class LEANPlugin : Plugin() {
19
+
20
+ private var leanInstance: Any? = null
21
+ private var cachedAppToken: String? = null
22
+ private var cachedSandbox: Boolean? = null
23
+
24
+ private val leanClassNames = listOf("me.leantech.lean.Lean", "me.leantech.Lean")
25
+
26
+ private fun findLeanClass(): Class<*>? {
27
+ for (name in leanClassNames) {
28
+ try {
29
+ return Class.forName(name)
30
+ } catch (_: ClassNotFoundException) { }
31
+ }
32
+ return null
33
+ }
34
+
35
+ private fun getLean(appToken: String?, sandbox: Boolean): Any? {
36
+ if (leanInstance != null && appToken != null && appToken == cachedAppToken && sandbox == cachedSandbox) {
37
+ return leanInstance
38
+ }
39
+ if (appToken.isNullOrBlank()) return null
40
+ val leanClass = findLeanClass()
41
+ ?: return null
42
+ try {
43
+ val builderClass = leanClass.declaredClasses.find { it.simpleName == "Builder" }
44
+ ?: return null
45
+ val builderCtor = builderClass.getConstructor()
46
+ val buildMethod = builderClass.getMethod("build")
47
+ val setAppToken = builderClass.getMethod("setAppToken", String::class.java)
48
+ val setVersion = builderClass.getMethod("setVersion", String::class.java)
49
+ val setCountry = builderClass.getMethod("setCountry", String::class.java)
50
+ val setLanguage = builderClass.getMethod("setLanguage", String::class.java)
51
+ val setSandboxMode = builderClass.getMethod("setSandboxMode")
52
+
53
+ var builder = builderCtor.newInstance()
54
+ builder = setAppToken.invoke(builder, appToken)
55
+ builder = setVersion.invoke(builder, "latest")
56
+ builder = setCountry.invoke(builder, "ae")
57
+ builder = setLanguage.invoke(builder, "en")
58
+ if (sandbox) builder = setSandboxMode.invoke(builder)
59
+ leanInstance = buildMethod.invoke(builder)
60
+ cachedAppToken = appToken
61
+ cachedSandbox = sandbox
62
+ return leanInstance
63
+ } catch (e: Exception) {
64
+ return null
65
+ }
66
+ }
67
+
68
+ private fun mapPermissions(leanClass: Class<*>, arr: JSONArray?): List<Any> {
69
+ val list = mutableListOf<Any>()
70
+ arr ?: return list
71
+ val permissionsClass = leanClass.declaredClasses.find { it.simpleName == "UserPermissions" }
72
+ ?: return list
73
+ val identity = permissionsClass.enumConstants?.find { it.toString() == "IDENTITY" }
74
+ val accounts = permissionsClass.enumConstants?.find { it.toString() == "ACCOUNTS" }
75
+ val transactions = permissionsClass.enumConstants?.find { it.toString() == "TRANSACTIONS" }
76
+ val balance = permissionsClass.enumConstants?.find { it.toString() == "BALANCE" }
77
+ val payments = permissionsClass.enumConstants?.find { it.toString() == "PAYMENTS" }
78
+ for (i in 0 until arr.length()) {
79
+ when (arr.optString(i, "").lowercase()) {
80
+ "identity" -> if (identity != null) list.add(identity)
81
+ "accounts" -> if (accounts != null) list.add(accounts)
82
+ "transactions" -> if (transactions != null) list.add(transactions)
83
+ "balance" -> if (balance != null) list.add(balance)
84
+ "payments" -> if (payments != null) list.add(payments)
85
+ else -> {}
86
+ }
87
+ }
88
+ return list
89
+ }
90
+
91
+ private fun responseToJS(response: Any?): JSObject {
92
+ val o = JSObject()
93
+ if (response == null) return o
94
+ try {
95
+ val status = response.javaClass.getMethod("getStatus").invoke(response)?.toString() ?: "ERROR"
96
+ val message = response.javaClass.getMethod("getMessage").invoke(response)?.toString()
97
+ val lastApiResponse = response.javaClass.getMethod("getLastApiResponse").invoke(response)?.toString()
98
+ val exitPoint = response.javaClass.getMethod("getExitPoint").invoke(response)?.toString()
99
+ val secondaryStatus = response.javaClass.getMethod("getSecondaryStatus").invoke(response)?.toString()
100
+ o.put("status", status)
101
+ o.put("message", message)
102
+ o.put("last_api_response", lastApiResponse)
103
+ o.put("exit_point", exitPoint)
104
+ o.put("secondary_status", secondaryStatus)
105
+ try {
106
+ val bank = response.javaClass.getMethod("getBank").invoke(response)
107
+ if (bank != null) {
108
+ val bankObj = JSObject()
109
+ val getBankId = bank.javaClass.methods.find { it.name == "getBankIdentifier" }
110
+ val getSupported = bank.javaClass.methods.find { it.name == "getIsSupported" || it.name == "isSupported" }
111
+ bankObj.put("bank_identifier", getBankId?.invoke(bank)?.toString())
112
+ bankObj.put("is_supported", getSupported?.invoke(bank) as? Boolean ?: true)
113
+ o.put("bank", bankObj)
114
+ }
115
+ } catch (_: Exception) { }
116
+ } catch (_: Exception) {
117
+ o.put("status", "ERROR")
118
+ o.put("message", "Failed to serialize response")
119
+ }
120
+ return o
121
+ }
122
+
123
+ @PluginMethod
124
+ fun connect(call: PluginCall) {
125
+ val customerId = call.getString("customerId")
126
+ val appToken = call.getString("appToken")
127
+ val sandbox = call.getBoolean("sandbox") ?: true
128
+ val permissionsArr = call.getArray("permissions") ?: JSONArray()
129
+ val bankIdentifier = call.getString("bankIdentifier")
130
+ val paymentDestinationId = call.getString("paymentDestinationId")
131
+ val successRedirectUrl = call.getString("successRedirectUrl")
132
+ val failRedirectUrl = call.getString("failRedirectUrl")
133
+
134
+ if (customerId.isNullOrBlank()) {
135
+ call.reject("customerId is required")
136
+ return
137
+ }
138
+
139
+ val leanClass = findLeanClass()
140
+ if (leanClass == null) {
141
+ call.reject(
142
+ "Lean SDK not found. Add to your app's build.gradle: implementation \"me.leantech:link-sdk-android:3.0.2\" " +
143
+ "and maven { url 'https://jitpack.io' } in repositories."
144
+ )
145
+ return
146
+ }
147
+
148
+ val lean = getLean(appToken, sandbox)
149
+ if (lean == null) {
150
+ call.reject("appToken is required for Android. Pass appToken in connect options.")
151
+ return
152
+ }
153
+
154
+ val activity: Activity? = getActivity()
155
+ if (activity == null) {
156
+ call.reject("Activity not available")
157
+ return
158
+ }
159
+
160
+ val permissions = mapPermissions(leanClass, permissionsArr)
161
+ val listenerInterface = leanClass.declaredClasses.find { it.simpleName == "Listener" }
162
+ ?: run {
163
+ call.reject("Lean SDK Listener not found")
164
+ return
165
+ }
166
+ val responseClass = leanClass.declaredClasses.find { it.simpleName == "Response" }
167
+ ?: run {
168
+ call.reject("Lean SDK Response not found")
169
+ return
170
+ }
171
+
172
+ val proxyListener = Proxy.newProxyInstance(
173
+ listenerInterface.classLoader,
174
+ arrayOf(listenerInterface)
175
+ ) { _, method, args ->
176
+ if (method.name == "onResponse" && args != null && args.isNotEmpty()) {
177
+ call.resolve(responseToJS(args[0]))
178
+ }
179
+ null
180
+ }
181
+
182
+ activity.runOnUiThread {
183
+ try {
184
+ val connectMethod = lean.javaClass.methods.find { m ->
185
+ m.name == "connect" && m.parameterCount >= 5
186
+ } ?: run {
187
+ call.reject("Lean connect method not found")
188
+ return@runOnUiThread
189
+ }
190
+ // Lean.connect(activity, customerId, bankIdentifier, paymentDestinationId, permissions,
191
+ // customization, accessTo, accessFrom, failRedirectUrl, successRedirectUrl, accountType,
192
+ // endUserId, accessToken, showConsentExplanation, destinationAlias, destinationAvatar,
193
+ // customerMetadata, leanListener)
194
+ val args = arrayOf(
195
+ activity,
196
+ customerId,
197
+ bankIdentifier,
198
+ paymentDestinationId,
199
+ ArrayList(permissions),
200
+ null, null, null,
201
+ failRedirectUrl,
202
+ successRedirectUrl,
203
+ null, null, null, null, null, null, null,
204
+ proxyListener
205
+ )
206
+ val paramCount = connectMethod.parameterTypes.size
207
+ val toPass = if (args.size == paramCount) args else args.take(paramCount).toTypedArray()
208
+ connectMethod.invoke(lean, *toPass)
209
+ } catch (e: Exception) {
210
+ call.reject("Lean connect failed: ${e.message}", e)
211
+ }
212
+ }
213
+ }
214
+ }
File without changes
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Result returned from Lean.connect() (and native redirect flows).
3
+ * Matches Lean Link SDK response shape across Web, Android, and iOS.
4
+ */
5
+ export interface LeanConnectResult {
6
+ status: 'SUCCESS' | 'CANCELLED' | 'ERROR';
7
+ message?: string | null;
8
+ last_api_response?: string | null;
9
+ exit_point?: string | null;
10
+ secondary_status?: string | null;
11
+ bank?: {
12
+ bank_identifier?: string;
13
+ is_supported?: boolean;
14
+ } | null;
15
+ }
16
+ /**
17
+ * Options for connecting a customer via Lean Link (Web / Android / iOS).
18
+ */
19
+ export interface LeanConnectOptions {
20
+ /** Your Lean customer identifier. */
21
+ customerId: string;
22
+ /** Requested scopes: 'identity' | 'accounts' | 'transactions' | 'balance' | 'payments'. */
23
+ permissions: string[];
24
+ /** Use sandbox environment. Defaults to true. */
25
+ sandbox?: boolean;
26
+ /** App token (required for Web; optional for native if configured separately). */
27
+ appToken?: string;
28
+ /** Customer-scoped access token for token exchange / backend auth (Web & native). */
29
+ accessToken?: string;
30
+ /** Deep link / redirect URL on success (Open Finance flows). */
31
+ successRedirectUrl?: string;
32
+ /** Deep link / redirect URL on failure (Open Finance flows). */
33
+ failRedirectUrl?: string;
34
+ /** Skip bank list by pre-selecting a bank identifier. */
35
+ bankIdentifier?: string;
36
+ /** Payment destination ID (optional; defaults to your CMA account). */
37
+ paymentDestinationId?: string;
38
+ }
39
+ export interface LeanPlugin {
40
+ /**
41
+ * Connect a customer to Lean (Payments + Data). Uses Web SDK on web,
42
+ * native Lean SDK on Android and iOS. Supports deep linking and
43
+ * sandbox/production via options.
44
+ * @throws if customerId is missing, permissions are invalid, or SDK is not available.
45
+ */
46
+ connect(options: LeanConnectOptions): Promise<LeanConnectResult>;
47
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Result returned from Lean.connect() (and native redirect flows).\n * Matches Lean Link SDK response shape across Web, Android, and iOS.\n */\nexport interface LeanConnectResult {\n status: 'SUCCESS' | 'CANCELLED' | 'ERROR';\n message?: string | null;\n last_api_response?: string | null;\n exit_point?: string | null;\n secondary_status?: string | null;\n bank?: {\n bank_identifier?: string;\n is_supported?: boolean;\n } | null;\n}\n\n/**\n * Options for connecting a customer via Lean Link (Web / Android / iOS).\n */\nexport interface LeanConnectOptions {\n /** Your Lean customer identifier. */\n customerId: string;\n /** Requested scopes: 'identity' | 'accounts' | 'transactions' | 'balance' | 'payments'. */\n permissions: string[];\n /** Use sandbox environment. Defaults to true. */\n sandbox?: boolean;\n /** App token (required for Web; optional for native if configured separately). */\n appToken?: string;\n /** Customer-scoped access token for token exchange / backend auth (Web & native). */\n accessToken?: string;\n /** Deep link / redirect URL on success (Open Finance flows). */\n successRedirectUrl?: string;\n /** Deep link / redirect URL on failure (Open Finance flows). */\n failRedirectUrl?: string;\n /** Skip bank list by pre-selecting a bank identifier. */\n bankIdentifier?: string;\n /** Payment destination ID (optional; defaults to your CMA account). */\n paymentDestinationId?: string;\n}\n\nexport interface LeanPlugin {\n /**\n * Connect a customer to Lean (Payments + Data). Uses Web SDK on web,\n * native Lean SDK on Android and iOS. Supports deep linking and\n * sandbox/production via options.\n * @throws if customerId is missing, permissions are invalid, or SDK is not available.\n */\n connect(options: LeanConnectOptions): Promise<LeanConnectResult>;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { LeanPlugin } from './definitions';
2
+ declare const Lean: LeanPlugin;
3
+ export * from './definitions';
4
+ export { Lean };
@@ -0,0 +1,7 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ const Lean = registerPlugin('Lean', {
3
+ web: () => import('./web').then((m) => new m.LeanWeb()),
4
+ });
5
+ export * from './definitions';
6
+ export { Lean };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,IAAI,GAAG,cAAc,CAAa,MAAM,EAAE;IAC9C,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;CACxD,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { LeanPlugin } from './definitions';\n\nconst Lean = registerPlugin<LeanPlugin>('Lean', {\n web: () => import('./web').then((m) => new m.LeanWeb()),\n});\n\nexport * from './definitions';\nexport { Lean };\n"]}
@@ -0,0 +1,30 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import type { LeanPlugin, LeanConnectOptions, LeanConnectResult } from './definitions';
3
+ declare global {
4
+ interface Window {
5
+ Lean?: {
6
+ connect(options: LeanWebConnectOptions): void;
7
+ };
8
+ }
9
+ interface LeanWebConnectOptions {
10
+ app_token?: string;
11
+ access_token?: string;
12
+ customer_id: string;
13
+ permissions: string[];
14
+ sandbox?: string | boolean;
15
+ success_redirect_url?: string;
16
+ fail_redirect_url?: string;
17
+ bank_identifier?: string;
18
+ payment_destination_id?: string;
19
+ callback?: (response: LeanConnectResult) => void;
20
+ }
21
+ }
22
+ /**
23
+ * Web implementation using Lean Link Web SDK.
24
+ * Load the loader script in your app (e.g. in index.html):
25
+ * <script src="https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js"></script>
26
+ * For Web, appToken (and optionally accessToken) should be passed in connect() or the SDK may not work.
27
+ */
28
+ export declare class LeanWeb extends WebPlugin implements LeanPlugin {
29
+ connect(options: LeanConnectOptions): Promise<LeanConnectResult>;
30
+ }
@@ -0,0 +1,46 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ /**
3
+ * Web implementation using Lean Link Web SDK.
4
+ * Load the loader script in your app (e.g. in index.html):
5
+ * <script src="https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js"></script>
6
+ * For Web, appToken (and optionally accessToken) should be passed in connect() or the SDK may not work.
7
+ */
8
+ export class LeanWeb extends WebPlugin {
9
+ async connect(options) {
10
+ var _a;
11
+ if (!((_a = options === null || options === void 0 ? void 0 : options.customerId) === null || _a === void 0 ? void 0 : _a.trim())) {
12
+ throw new Error('customerId is required');
13
+ }
14
+ if (!Array.isArray(options.permissions)) {
15
+ throw new Error('permissions must be a non-null array');
16
+ }
17
+ return new Promise((resolve, reject) => {
18
+ var _a;
19
+ if (!window.Lean) {
20
+ reject(new Error('Lean Web SDK not loaded. Add: <script src="https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js"></script>'));
21
+ return;
22
+ }
23
+ const sandbox = (_a = options.sandbox) !== null && _a !== void 0 ? _a : true;
24
+ const params = {
25
+ customer_id: options.customerId,
26
+ permissions: options.permissions,
27
+ sandbox: typeof sandbox === 'boolean' ? (sandbox ? 'true' : 'false') : String(sandbox),
28
+ callback: (response) => resolve(response),
29
+ };
30
+ if (options.appToken != null)
31
+ params.app_token = options.appToken;
32
+ if (options.accessToken != null)
33
+ params.access_token = options.accessToken;
34
+ if (options.successRedirectUrl != null)
35
+ params.success_redirect_url = options.successRedirectUrl;
36
+ if (options.failRedirectUrl != null)
37
+ params.fail_redirect_url = options.failRedirectUrl;
38
+ if (options.bankIdentifier != null)
39
+ params.bank_identifier = options.bankIdentifier;
40
+ if (options.paymentDestinationId != null)
41
+ params.payment_destination_id = options.paymentDestinationId;
42
+ window.Lean.connect(params);
43
+ });
44
+ }
45
+ }
46
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAyB5C;;;;;GAKG;AACH,MAAM,OAAO,OAAQ,SAAQ,SAAS;IACpC,KAAK,CAAC,OAAO,CAAC,OAA2B;;QACvC,IAAI,CAAC,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,0CAAE,IAAI,EAAE,CAAA,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;;YACrC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBACjB,MAAM,CACJ,IAAI,KAAK,CACP,kIAAkI,CACnI,CACF,CAAC;gBACF,OAAO;YACT,CAAC;YAED,MAAM,OAAO,GAAG,MAAA,OAAO,CAAC,OAAO,mCAAI,IAAI,CAAC;YACxC,MAAM,MAAM,GAA0B;gBACpC,WAAW,EAAE,OAAO,CAAC,UAAU;gBAC/B,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,OAAO,EAAE,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;gBACtF,QAAQ,EAAE,CAAC,QAA2B,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;aAC7D,CAAC;YACF,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI;gBAAE,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;YAClE,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI;gBAAE,MAAM,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;YAC3E,IAAI,OAAO,CAAC,kBAAkB,IAAI,IAAI;gBAAE,MAAM,CAAC,oBAAoB,GAAG,OAAO,CAAC,kBAAkB,CAAC;YACjG,IAAI,OAAO,CAAC,eAAe,IAAI,IAAI;gBAAE,MAAM,CAAC,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;YACxF,IAAI,OAAO,CAAC,cAAc,IAAI,IAAI;gBAAE,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;YACpF,IAAI,OAAO,CAAC,oBAAoB,IAAI,IAAI;gBAAE,MAAM,CAAC,sBAAsB,GAAG,OAAO,CAAC,oBAAoB,CAAC;YAEvG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type { LeanPlugin, LeanConnectOptions, LeanConnectResult } from './definitions';\n\ndeclare global {\n interface Window {\n Lean?: {\n connect(options: LeanWebConnectOptions): void;\n };\n }\n\n interface LeanWebConnectOptions {\n app_token?: string;\n access_token?: string;\n customer_id: string;\n permissions: string[];\n sandbox?: string | boolean;\n success_redirect_url?: string;\n fail_redirect_url?: string;\n bank_identifier?: string;\n payment_destination_id?: string;\n callback?: (response: LeanConnectResult) => void;\n }\n}\n\n/**\n * Web implementation using Lean Link Web SDK.\n * Load the loader script in your app (e.g. in index.html):\n * <script src=\"https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js\"></script>\n * For Web, appToken (and optionally accessToken) should be passed in connect() or the SDK may not work.\n */\nexport class LeanWeb extends WebPlugin implements LeanPlugin {\n async connect(options: LeanConnectOptions): Promise<LeanConnectResult> {\n if (!options?.customerId?.trim()) {\n throw new Error('customerId is required');\n }\n if (!Array.isArray(options.permissions)) {\n throw new Error('permissions must be a non-null array');\n }\n\n return new Promise((resolve, reject) => {\n if (!window.Lean) {\n reject(\n new Error(\n 'Lean Web SDK not loaded. Add: <script src=\"https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js\"></script>',\n ),\n );\n return;\n }\n\n const sandbox = options.sandbox ?? true;\n const params: LeanWebConnectOptions = {\n customer_id: options.customerId,\n permissions: options.permissions,\n sandbox: typeof sandbox === 'boolean' ? (sandbox ? 'true' : 'false') : String(sandbox),\n callback: (response: LeanConnectResult) => resolve(response),\n };\n if (options.appToken != null) params.app_token = options.appToken;\n if (options.accessToken != null) params.access_token = options.accessToken;\n if (options.successRedirectUrl != null) params.success_redirect_url = options.successRedirectUrl;\n if (options.failRedirectUrl != null) params.fail_redirect_url = options.failRedirectUrl;\n if (options.bankIdentifier != null) params.bank_identifier = options.bankIdentifier;\n if (options.paymentDestinationId != null) params.payment_destination_id = options.paymentDestinationId;\n\n window.Lean.connect(params);\n });\n }\n}\n"]}
@@ -0,0 +1,60 @@
1
+ 'use strict';
2
+
3
+ var core = require('@capacitor/core');
4
+
5
+ const Lean = core.registerPlugin('Lean', {
6
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.LeanWeb()),
7
+ });
8
+
9
+ /**
10
+ * Web implementation using Lean Link Web SDK.
11
+ * Load the loader script in your app (e.g. in index.html):
12
+ * <script src="https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js"></script>
13
+ * For Web, appToken (and optionally accessToken) should be passed in connect() or the SDK may not work.
14
+ */
15
+ class LeanWeb extends core.WebPlugin {
16
+ async connect(options) {
17
+ var _a;
18
+ if (!((_a = options === null || options === void 0 ? void 0 : options.customerId) === null || _a === void 0 ? void 0 : _a.trim())) {
19
+ throw new Error('customerId is required');
20
+ }
21
+ if (!Array.isArray(options.permissions)) {
22
+ throw new Error('permissions must be a non-null array');
23
+ }
24
+ return new Promise((resolve, reject) => {
25
+ var _a;
26
+ if (!window.Lean) {
27
+ reject(new Error('Lean Web SDK not loaded. Add: <script src="https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js"></script>'));
28
+ return;
29
+ }
30
+ const sandbox = (_a = options.sandbox) !== null && _a !== void 0 ? _a : true;
31
+ const params = {
32
+ customer_id: options.customerId,
33
+ permissions: options.permissions,
34
+ sandbox: typeof sandbox === 'boolean' ? (sandbox ? 'true' : 'false') : String(sandbox),
35
+ callback: (response) => resolve(response),
36
+ };
37
+ if (options.appToken != null)
38
+ params.app_token = options.appToken;
39
+ if (options.accessToken != null)
40
+ params.access_token = options.accessToken;
41
+ if (options.successRedirectUrl != null)
42
+ params.success_redirect_url = options.successRedirectUrl;
43
+ if (options.failRedirectUrl != null)
44
+ params.fail_redirect_url = options.failRedirectUrl;
45
+ if (options.bankIdentifier != null)
46
+ params.bank_identifier = options.bankIdentifier;
47
+ if (options.paymentDestinationId != null)
48
+ params.payment_destination_id = options.paymentDestinationId;
49
+ window.Lean.connect(params);
50
+ });
51
+ }
52
+ }
53
+
54
+ var web = /*#__PURE__*/Object.freeze({
55
+ __proto__: null,
56
+ LeanWeb: LeanWeb
57
+ });
58
+
59
+ exports.Lean = Lean;
60
+ //# sourceMappingURL=plugin.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Lean = registerPlugin('Lean', {\n web: () => import('./web').then((m) => new m.LeanWeb()),\n});\nexport * from './definitions';\nexport { Lean };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\n/**\n * Web implementation using Lean Link Web SDK.\n * Load the loader script in your app (e.g. in index.html):\n * <script src=\"https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js\"></script>\n * For Web, appToken (and optionally accessToken) should be passed in connect() or the SDK may not work.\n */\nexport class LeanWeb extends WebPlugin {\n async connect(options) {\n var _a;\n if (!((_a = options === null || options === void 0 ? void 0 : options.customerId) === null || _a === void 0 ? void 0 : _a.trim())) {\n throw new Error('customerId is required');\n }\n if (!Array.isArray(options.permissions)) {\n throw new Error('permissions must be a non-null array');\n }\n return new Promise((resolve, reject) => {\n var _a;\n if (!window.Lean) {\n reject(new Error('Lean Web SDK not loaded. Add: <script src=\"https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js\"></script>'));\n return;\n }\n const sandbox = (_a = options.sandbox) !== null && _a !== void 0 ? _a : true;\n const params = {\n customer_id: options.customerId,\n permissions: options.permissions,\n sandbox: typeof sandbox === 'boolean' ? (sandbox ? 'true' : 'false') : String(sandbox),\n callback: (response) => resolve(response),\n };\n if (options.appToken != null)\n params.app_token = options.appToken;\n if (options.accessToken != null)\n params.access_token = options.accessToken;\n if (options.successRedirectUrl != null)\n params.success_redirect_url = options.successRedirectUrl;\n if (options.failRedirectUrl != null)\n params.fail_redirect_url = options.failRedirectUrl;\n if (options.bankIdentifier != null)\n params.bank_identifier = options.bankIdentifier;\n if (options.paymentDestinationId != null)\n params.payment_destination_id = options.paymentDestinationId;\n window.Lean.connect(params);\n });\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,IAAI,GAAGA,mBAAc,CAAC,MAAM,EAAE;AACpC,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;AAC3D,CAAC;;ACFD;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,OAAO,SAASC,cAAS,CAAC;AACvC,IAAI,MAAM,OAAO,CAAC,OAAO,EAAE;AAC3B,QAAQ,IAAI,EAAE;AACd,QAAQ,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,UAAU,MAAM,IAAI,IAAI,EAAE,KAAK,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE;AAC3I,YAAY,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC;AACrD,QAAQ;AACR,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;AACjD,YAAY,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC;AACnE,QAAQ;AACR,QAAQ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAChD,YAAY,IAAI,EAAE;AAClB,YAAY,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;AAC9B,gBAAgB,MAAM,CAAC,IAAI,KAAK,CAAC,kIAAkI,CAAC,CAAC;AACrK,gBAAgB;AAChB,YAAY;AACZ,YAAY,MAAM,OAAO,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,MAAM,IAAI,IAAI,EAAE,KAAK,MAAM,GAAG,EAAE,GAAG,IAAI;AACxF,YAAY,MAAM,MAAM,GAAG;AAC3B,gBAAgB,WAAW,EAAE,OAAO,CAAC,UAAU;AAC/C,gBAAgB,WAAW,EAAE,OAAO,CAAC,WAAW;AAChD,gBAAgB,OAAO,EAAE,OAAO,OAAO,KAAK,SAAS,IAAI,OAAO,GAAG,MAAM,GAAG,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC;AACtG,gBAAgB,QAAQ,EAAE,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC;AACzD,aAAa;AACb,YAAY,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI;AACxC,gBAAgB,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ;AACnD,YAAY,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI;AAC3C,gBAAgB,MAAM,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW;AACzD,YAAY,IAAI,OAAO,CAAC,kBAAkB,IAAI,IAAI;AAClD,gBAAgB,MAAM,CAAC,oBAAoB,GAAG,OAAO,CAAC,kBAAkB;AACxE,YAAY,IAAI,OAAO,CAAC,eAAe,IAAI,IAAI;AAC/C,gBAAgB,MAAM,CAAC,iBAAiB,GAAG,OAAO,CAAC,eAAe;AAClE,YAAY,IAAI,OAAO,CAAC,cAAc,IAAI,IAAI;AAC9C,gBAAgB,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC,cAAc;AAC/D,YAAY,IAAI,OAAO,CAAC,oBAAoB,IAAI,IAAI;AACpD,gBAAgB,MAAM,CAAC,sBAAsB,GAAG,OAAO,CAAC,oBAAoB;AAC5E,YAAY,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;AACvC,QAAQ,CAAC,CAAC;AACV,IAAI;AACJ;;;;;;;;;"}
package/dist/plugin.js ADDED
@@ -0,0 +1,63 @@
1
+ var capacitorLEAN = (function (exports, core) {
2
+ 'use strict';
3
+
4
+ const Lean = core.registerPlugin('Lean', {
5
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.LeanWeb()),
6
+ });
7
+
8
+ /**
9
+ * Web implementation using Lean Link Web SDK.
10
+ * Load the loader script in your app (e.g. in index.html):
11
+ * <script src="https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js"></script>
12
+ * For Web, appToken (and optionally accessToken) should be passed in connect() or the SDK may not work.
13
+ */
14
+ class LeanWeb extends core.WebPlugin {
15
+ async connect(options) {
16
+ var _a;
17
+ if (!((_a = options === null || options === void 0 ? void 0 : options.customerId) === null || _a === void 0 ? void 0 : _a.trim())) {
18
+ throw new Error('customerId is required');
19
+ }
20
+ if (!Array.isArray(options.permissions)) {
21
+ throw new Error('permissions must be a non-null array');
22
+ }
23
+ return new Promise((resolve, reject) => {
24
+ var _a;
25
+ if (!window.Lean) {
26
+ reject(new Error('Lean Web SDK not loaded. Add: <script src="https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js"></script>'));
27
+ return;
28
+ }
29
+ const sandbox = (_a = options.sandbox) !== null && _a !== void 0 ? _a : true;
30
+ const params = {
31
+ customer_id: options.customerId,
32
+ permissions: options.permissions,
33
+ sandbox: typeof sandbox === 'boolean' ? (sandbox ? 'true' : 'false') : String(sandbox),
34
+ callback: (response) => resolve(response),
35
+ };
36
+ if (options.appToken != null)
37
+ params.app_token = options.appToken;
38
+ if (options.accessToken != null)
39
+ params.access_token = options.accessToken;
40
+ if (options.successRedirectUrl != null)
41
+ params.success_redirect_url = options.successRedirectUrl;
42
+ if (options.failRedirectUrl != null)
43
+ params.fail_redirect_url = options.failRedirectUrl;
44
+ if (options.bankIdentifier != null)
45
+ params.bank_identifier = options.bankIdentifier;
46
+ if (options.paymentDestinationId != null)
47
+ params.payment_destination_id = options.paymentDestinationId;
48
+ window.Lean.connect(params);
49
+ });
50
+ }
51
+ }
52
+
53
+ var web = /*#__PURE__*/Object.freeze({
54
+ __proto__: null,
55
+ LeanWeb: LeanWeb
56
+ });
57
+
58
+ exports.Lean = Lean;
59
+
60
+ return exports;
61
+
62
+ })({}, capacitorExports);
63
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Lean = registerPlugin('Lean', {\n web: () => import('./web').then((m) => new m.LeanWeb()),\n});\nexport * from './definitions';\nexport { Lean };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\n/**\n * Web implementation using Lean Link Web SDK.\n * Load the loader script in your app (e.g. in index.html):\n * <script src=\"https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js\"></script>\n * For Web, appToken (and optionally accessToken) should be passed in connect() or the SDK may not work.\n */\nexport class LeanWeb extends WebPlugin {\n async connect(options) {\n var _a;\n if (!((_a = options === null || options === void 0 ? void 0 : options.customerId) === null || _a === void 0 ? void 0 : _a.trim())) {\n throw new Error('customerId is required');\n }\n if (!Array.isArray(options.permissions)) {\n throw new Error('permissions must be a non-null array');\n }\n return new Promise((resolve, reject) => {\n var _a;\n if (!window.Lean) {\n reject(new Error('Lean Web SDK not loaded. Add: <script src=\"https://cdn.leantech.me/link/loader/prod/ae/latest/lean-link-loader.min.js\"></script>'));\n return;\n }\n const sandbox = (_a = options.sandbox) !== null && _a !== void 0 ? _a : true;\n const params = {\n customer_id: options.customerId,\n permissions: options.permissions,\n sandbox: typeof sandbox === 'boolean' ? (sandbox ? 'true' : 'false') : String(sandbox),\n callback: (response) => resolve(response),\n };\n if (options.appToken != null)\n params.app_token = options.appToken;\n if (options.accessToken != null)\n params.access_token = options.accessToken;\n if (options.successRedirectUrl != null)\n params.success_redirect_url = options.successRedirectUrl;\n if (options.failRedirectUrl != null)\n params.fail_redirect_url = options.failRedirectUrl;\n if (options.bankIdentifier != null)\n params.bank_identifier = options.bankIdentifier;\n if (options.paymentDestinationId != null)\n params.payment_destination_id = options.paymentDestinationId;\n window.Lean.connect(params);\n });\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,IAAI,GAAGA,mBAAc,CAAC,MAAM,EAAE;IACpC,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IAC3D,CAAC;;ICFD;IACA;IACA;IACA;IACA;IACA;IACO,MAAM,OAAO,SAASC,cAAS,CAAC;IACvC,IAAI,MAAM,OAAO,CAAC,OAAO,EAAE;IAC3B,QAAQ,IAAI,EAAE;IACd,QAAQ,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,UAAU,MAAM,IAAI,IAAI,EAAE,KAAK,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE;IAC3I,YAAY,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC;IACrD,QAAQ;IACR,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;IACjD,YAAY,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC;IACnE,QAAQ;IACR,QAAQ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;IAChD,YAAY,IAAI,EAAE;IAClB,YAAY,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;IAC9B,gBAAgB,MAAM,CAAC,IAAI,KAAK,CAAC,kIAAkI,CAAC,CAAC;IACrK,gBAAgB;IAChB,YAAY;IACZ,YAAY,MAAM,OAAO,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,MAAM,IAAI,IAAI,EAAE,KAAK,MAAM,GAAG,EAAE,GAAG,IAAI;IACxF,YAAY,MAAM,MAAM,GAAG;IAC3B,gBAAgB,WAAW,EAAE,OAAO,CAAC,UAAU;IAC/C,gBAAgB,WAAW,EAAE,OAAO,CAAC,WAAW;IAChD,gBAAgB,OAAO,EAAE,OAAO,OAAO,KAAK,SAAS,IAAI,OAAO,GAAG,MAAM,GAAG,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC;IACtG,gBAAgB,QAAQ,EAAE,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC;IACzD,aAAa;IACb,YAAY,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI;IACxC,gBAAgB,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ;IACnD,YAAY,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI;IAC3C,gBAAgB,MAAM,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW;IACzD,YAAY,IAAI,OAAO,CAAC,kBAAkB,IAAI,IAAI;IAClD,gBAAgB,MAAM,CAAC,oBAAoB,GAAG,OAAO,CAAC,kBAAkB;IACxE,YAAY,IAAI,OAAO,CAAC,eAAe,IAAI,IAAI;IAC/C,gBAAgB,MAAM,CAAC,iBAAiB,GAAG,OAAO,CAAC,eAAe;IAClE,YAAY,IAAI,OAAO,CAAC,cAAc,IAAI,IAAI;IAC9C,gBAAgB,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC,cAAc;IAC/D,YAAY,IAAI,OAAO,CAAC,oBAAoB,IAAI,IAAI;IACpD,gBAAgB,MAAM,CAAC,sBAAsB,GAAG,OAAO,CAAC,oBAAoB;IAC5E,YAAY,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IACvC,QAAQ,CAAC,CAAC;IACV,IAAI;IACJ;;;;;;;;;;;;;;;"}
@@ -0,0 +1,77 @@
1
+ import Foundation
2
+ import Capacitor
3
+ import LeanSDK
4
+
5
+ /// Capacitor plugin bridging to Lean Link iOS SDK.
6
+ /// Call Lean.manager.setup(appToken, sandbox) in your app's init, or pass appToken in connect options.
7
+ @objc(LeanPlugin)
8
+ public class LEANPlugin: CAPPlugin, CAPBridgedPlugin {
9
+ public let identifier = "LeanPlugin"
10
+ public let jsName = "Lean"
11
+ public let pluginMethods: [CAPPluginMethod] = [
12
+ CAPPluginMethod(name: "connect", returnType: CAPPluginReturnPromise)
13
+ ]
14
+
15
+ private static func mapPermissions(_ permissions: [String]?) -> [LeanPermission] {
16
+ guard let permissions = permissions else { return [] }
17
+ return permissions.compactMap { permission in
18
+ switch permission.lowercased() {
19
+ case "identity": return .Identity
20
+ case "accounts": return .Accounts
21
+ case "transactions": return .Transactions
22
+ case "balance": return .Balance
23
+ case "payments": return .Payments
24
+ default: return nil
25
+ }
26
+ }
27
+ }
28
+
29
+ private static func resultFrom(status: LeanStatus?) -> [String: Any] {
30
+ guard let status = status else {
31
+ return ["status": "SUCCESS", "message": "Entity connected"]
32
+ }
33
+ var out: [String: Any] = [
34
+ "status": String(describing: status.status),
35
+ "message": status.message ?? ""
36
+ ]
37
+ out["method"] = status.method
38
+ return out
39
+ }
40
+
41
+ @objc func connect(_ call: CAPPluginCall) {
42
+ guard let customerId = call.getString("customerId"), !customerId.isEmpty else {
43
+ call.reject("customerId is required")
44
+ return
45
+ }
46
+ let permissions = LEANPlugin.mapPermissions(call.getArray("permissions") as? [String])
47
+ let sandbox = call.getBool("sandbox") ?? true
48
+ let appToken = call.getString("appToken")
49
+ let bankId = call.getString("bankIdentifier")
50
+ let paymentDestinationId = call.getString("paymentDestinationId")
51
+
52
+ if let token = appToken, !token.isEmpty {
53
+ Lean.manager.setup(appToken: token, sandbox: sandbox, version: "latest")
54
+ }
55
+
56
+ guard let viewController = bridge?.viewController else {
57
+ call.reject("View controller not available")
58
+ return
59
+ }
60
+
61
+ let resolvedPermissions = permissions.isEmpty ? [LeanPermission.Identity, .Accounts, .Transactions, .Balance] : permissions
62
+ Lean.manager.connect(
63
+ presentingViewController: viewController,
64
+ customerId: customerId,
65
+ permissions: resolvedPermissions,
66
+ paymentDestinationId: paymentDestinationId,
67
+ bankId: bankId,
68
+ customization: nil,
69
+ success: { _ in
70
+ call.resolve(LEANPlugin.resultFrom(status: nil))
71
+ },
72
+ error: { status in
73
+ call.resolve(LEANPlugin.resultFrom(status: status))
74
+ }
75
+ )
76
+ }
77
+ }
@@ -0,0 +1,11 @@
1
+ import XCTest
2
+ @testable import LEANPlugin
3
+
4
+ class LEANTests: XCTestCase {
5
+ func testPluginLoads() {
6
+ // Plugin loads and exposes Lean bridge name
7
+ let plugin = LEANPlugin()
8
+ XCTAssertEqual(plugin.jsName, "Lean")
9
+ XCTAssertEqual(plugin.identifier, "LeanPlugin")
10
+ }
11
+ }
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "lean-ionic-capacitor",
3
+ "version": "1.0.0",
4
+ "description": "Capacitor plugin for integrating Lean Technologies into Ionic apps with native iOS/Android SDK support and Web SDK fallback.",
5
+ "main": "dist/plugin.cjs.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/esm/index.d.ts",
8
+ "unpkg": "dist/plugin.js",
9
+ "files": [
10
+ "android/src/main/",
11
+ "android/build.gradle",
12
+ "dist/",
13
+ "ios/Sources",
14
+ "ios/Tests",
15
+ "Package.swift",
16
+ "LeanIonicCapacitor.podspec"
17
+ ],
18
+ "author": "Muhammad Nadeem",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/imuhammadnadeem/LEAN-Ionic-Capaciotr.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/imuhammadnadeem/LEAN-Ionic-Capaciotr/issues"
26
+ },
27
+ "keywords": [
28
+ "capacitor",
29
+ "plugin",
30
+ "native"
31
+ ],
32
+ "scripts": {
33
+ "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
34
+ "verify:ios": "xcodebuild -scheme LeanIonicCapacitor -destination 'generic/platform=iOS' -configuration Debug build",
35
+ "verify:android": "cd android && ./gradlew clean build test && cd ..",
36
+ "verify:web": "npm run build",
37
+ "check": "npm run check:ios && npm run check:android && npm run check:web",
38
+ "check:ios": "xcodebuild -scheme LeanIonicCapacitor -destination 'generic/platform=iOS' -configuration Debug build",
39
+ "check:ios:simulator": "xcodebuild -scheme LeanIonicCapacitor -destination 'platform=iOS Simulator,name=iPhone 16' -configuration Debug build",
40
+ "check:android": "cd android && ./gradlew clean build test && cd ..",
41
+ "check:web": "npm run build && cd example-app && npm install && npm run build",
42
+ "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint",
43
+ "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
44
+ "eslint": "eslint . --ext ts",
45
+ "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
46
+ "swiftlint": "node-swiftlint lint ios Package.swift",
47
+ "docgen": "docgen --api LEANPlugin --output-readme README.md --output-json dist/docs.json",
48
+ "build": "npm run clean && tsc && rollup -c rollup.config.mjs",
49
+ "clean": "rimraf ./dist",
50
+ "watch": "tsc --watch",
51
+ "prepublishOnly": "npm run build"
52
+ },
53
+ "devDependencies": {
54
+ "@capacitor/android": "^8.0.0",
55
+ "@capacitor/core": "^8.0.0",
56
+ "@capacitor/docgen": "^0.3.1",
57
+ "@capacitor/ios": "^8.0.0",
58
+ "@ionic/eslint-config": "^0.4.0",
59
+ "@ionic/prettier-config": "^4.0.0",
60
+ "@ionic/swiftlint-config": "^2.0.0",
61
+ "eslint": "^8.57.1",
62
+ "prettier": "^3.6.2",
63
+ "prettier-plugin-java": "^2.7.7",
64
+ "rimraf": "^6.1.0",
65
+ "rollup": "^4.53.2",
66
+ "swiftlint": "^2.0.0",
67
+ "typescript": "^5.9.3"
68
+ },
69
+ "peerDependencies": {
70
+ "@capacitor/core": ">=8.0.0"
71
+ },
72
+ "prettier": "@ionic/prettier-config",
73
+ "swiftlint": "@ionic/swiftlint-config",
74
+ "eslintConfig": {
75
+ "extends": "@ionic/eslint-config/recommended"
76
+ },
77
+ "capacitor": {
78
+ "ios": {
79
+ "src": "ios"
80
+ },
81
+ "android": {
82
+ "src": "android"
83
+ }
84
+ }
85
+ }