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.
- package/LeanIonicCapacitor.podspec +17 -0
- package/Package.swift +30 -0
- package/README.md +120 -0
- package/android/build.gradle +66 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/kotlin/com/codecraft_studio/lean/LEANPlugin.kt +214 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/esm/definitions.d.ts +47 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +30 -0
- package/dist/esm/web.js +46 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +60 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +63 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/LEANPlugin/LEANPlugin.swift +77 -0
- package/ios/Tests/LEANPluginTests/LEANTests.swift +11 -0
- package/package.json +85 -0
|
@@ -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,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 @@
|
|
|
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 @@
|
|
|
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
|
+
}
|
package/dist/esm/web.js
ADDED
|
@@ -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
|
+
}
|