@jaeyeonee/capacitor-ios-webview 0.0.1

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 = 'CapacitorIosCustomWebView'
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,28 @@
1
+ // swift-tools-version: 5.9
2
+ import PackageDescription
3
+
4
+ let package = Package(
5
+ name: "CapacitorIosCustomWebView",
6
+ platforms: [.iOS(.v15)],
7
+ products: [
8
+ .library(
9
+ name: "CapacitorIosCustomWebView",
10
+ targets: ["CapacitorIosCustomWebView"])
11
+ ],
12
+ dependencies: [
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0")
14
+ ],
15
+ targets: [
16
+ .target(
17
+ name: "CapacitorIosCustomWebView",
18
+ dependencies: [
19
+ .product(name: "Capacitor", package: "capacitor-swift-pm"),
20
+ .product(name: "Cordova", package: "capacitor-swift-pm")
21
+ ],
22
+ path: "ios/Sources/CustomWebViewPlugin"),
23
+ .testTarget(
24
+ name: "CapacitorIosCustomWebViewTests",
25
+ dependencies: ["CapacitorIosCustomWebView"],
26
+ path: "ios/Tests/CustomWebViewPluginTests")
27
+ ]
28
+ )
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # capacitor-iosCustomWebView
2
+
3
+ capacitor iosCustomWebView
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install capacitor-iosCustomWebView
9
+ npx cap sync
10
+ ```
11
+
12
+ ## API
13
+
14
+ <docgen-index>
15
+
16
+ * [`open(...)`](#open)
17
+ * [`close()`](#close)
18
+
19
+ </docgen-index>
20
+
21
+ <docgen-api>
22
+ <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
23
+
24
+ ### open(...)
25
+
26
+ ```typescript
27
+ open(options: { url: string; closeButtonText?: string; }) => Promise<void>
28
+ ```
29
+
30
+ | Param | Type |
31
+ | ------------- | ------------------------------------------------------- |
32
+ | **`options`** | <code>{ url: string; closeButtonText?: string; }</code> |
33
+
34
+ --------------------
35
+
36
+
37
+ ### close()
38
+
39
+ ```typescript
40
+ close() => Promise<void>
41
+ ```
42
+
43
+ --------------------
44
+
45
+ </docgen-api>
package/dist/docs.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "api": {
3
+ "name": "CustomWebViewPlugin",
4
+ "slug": "customwebviewplugin",
5
+ "docs": "",
6
+ "tags": [],
7
+ "methods": [
8
+ {
9
+ "name": "open",
10
+ "signature": "(options: { url: string; closeButtonText?: string; }) => Promise<void>",
11
+ "parameters": [
12
+ {
13
+ "name": "options",
14
+ "docs": "",
15
+ "type": "{ url: string; closeButtonText?: string | undefined; }"
16
+ }
17
+ ],
18
+ "returns": "Promise<void>",
19
+ "tags": [],
20
+ "docs": "",
21
+ "complexTypes": [],
22
+ "slug": "open"
23
+ },
24
+ {
25
+ "name": "close",
26
+ "signature": "() => Promise<void>",
27
+ "parameters": [],
28
+ "returns": "Promise<void>",
29
+ "tags": [],
30
+ "docs": "",
31
+ "complexTypes": [],
32
+ "slug": "close"
33
+ }
34
+ ],
35
+ "properties": []
36
+ },
37
+ "interfaces": [],
38
+ "enums": [],
39
+ "typeAliases": [],
40
+ "pluginConfigs": []
41
+ }
@@ -0,0 +1,7 @@
1
+ export interface CustomWebViewPlugin {
2
+ open(options: {
3
+ url: string;
4
+ closeButtonText?: string;
5
+ }): Promise<void>;
6
+ close(): Promise<void>;
7
+ }
@@ -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":["export interface CustomWebViewPlugin {\n open(options: { url: string, closeButtonText?: string }): Promise<void>;\n\n close(): Promise<void>;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { CustomWebViewPlugin } from './definitions';
2
+ declare const CustomWebView: CustomWebViewPlugin;
3
+ export * from './definitions';
4
+ export { CustomWebView };
@@ -0,0 +1,7 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ const CustomWebView = registerPlugin('CustomWebView', {
3
+ web: () => import('./web').then((m) => new m.CustomWebViewWeb()),
4
+ });
5
+ export * from './definitions';
6
+ export { CustomWebView };
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,aAAa,GAAG,cAAc,CAAsB,eAAe,EAAE;IACzE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;CACjE,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { CustomWebViewPlugin } from './definitions';\n\nconst CustomWebView = registerPlugin<CustomWebViewPlugin>('CustomWebView', {\n web: () => import('./web').then((m) => new m.CustomWebViewWeb()),\n});\n\nexport * from './definitions';\nexport { CustomWebView };\n"]}
@@ -0,0 +1,8 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import type { CustomWebViewPlugin } from './definitions';
3
+ export declare class CustomWebViewWeb extends WebPlugin implements CustomWebViewPlugin {
4
+ open(options: {
5
+ url: string;
6
+ }): Promise<void>;
7
+ close(): Promise<void>;
8
+ }
@@ -0,0 +1,10 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ export class CustomWebViewWeb extends WebPlugin {
3
+ async open(options) {
4
+ console.warn('[CustomWebView] open() is not supported on web', options);
5
+ }
6
+ async close() {
7
+ console.warn('[CustomWebView] close() is not supported on web');
8
+ }
9
+ }
10
+ //# 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;AAG5C,MAAM,OAAO,gBAAiB,SAAQ,SAAS;IAC7C,KAAK,CAAC,IAAI,CAAC,OAAwB;QACjC,OAAO,CAAC,IAAI,CAAC,gDAAgD,EAAE,OAAO,CAAC,CAAC;IAC1E,CAAC;IAED,KAAK,CAAC,KAAK;QACT,OAAO,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;IAClE,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\nimport type { CustomWebViewPlugin } from './definitions';\n\nexport class CustomWebViewWeb extends WebPlugin implements CustomWebViewPlugin {\n async open(options: { url: string }): Promise<void> {\n console.warn('[CustomWebView] open() is not supported on web', options);\n }\n\n async close(): Promise<void> {\n console.warn('[CustomWebView] close() is not supported on web');\n }\n}\n"]}
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ var core = require('@capacitor/core');
4
+
5
+ const CustomWebView = core.registerPlugin('CustomWebView', {
6
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.CustomWebViewWeb()),
7
+ });
8
+
9
+ class CustomWebViewWeb extends core.WebPlugin {
10
+ async open(options) {
11
+ console.warn('[CustomWebView] open() is not supported on web', options);
12
+ }
13
+ async close() {
14
+ console.warn('[CustomWebView] close() is not supported on web');
15
+ }
16
+ }
17
+
18
+ var web = /*#__PURE__*/Object.freeze({
19
+ __proto__: null,
20
+ CustomWebViewWeb: CustomWebViewWeb
21
+ });
22
+
23
+ exports.CustomWebView = CustomWebView;
24
+ //# 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 CustomWebView = registerPlugin('CustomWebView', {\n web: () => import('./web').then((m) => new m.CustomWebViewWeb()),\n});\nexport * from './definitions';\nexport { CustomWebView };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class CustomWebViewWeb extends WebPlugin {\n async open(options) {\n console.warn('[CustomWebView] open() is not supported on web', options);\n }\n async close() {\n console.warn('[CustomWebView] close() is not supported on web');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,aAAa,GAAGA,mBAAc,CAAC,eAAe,EAAE;AACtD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;AACpE,CAAC;;ACFM,MAAM,gBAAgB,SAASC,cAAS,CAAC;AAChD,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;AACxB,QAAQ,OAAO,CAAC,IAAI,CAAC,gDAAgD,EAAE,OAAO,CAAC;AAC/E,IAAI;AACJ,IAAI,MAAM,KAAK,GAAG;AAClB,QAAQ,OAAO,CAAC,IAAI,CAAC,iDAAiD,CAAC;AACvE,IAAI;AACJ;;;;;;;;;"}
package/dist/plugin.js ADDED
@@ -0,0 +1,27 @@
1
+ var capacitorCustomWebView = (function (exports, core) {
2
+ 'use strict';
3
+
4
+ const CustomWebView = core.registerPlugin('CustomWebView', {
5
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.CustomWebViewWeb()),
6
+ });
7
+
8
+ class CustomWebViewWeb extends core.WebPlugin {
9
+ async open(options) {
10
+ console.warn('[CustomWebView] open() is not supported on web', options);
11
+ }
12
+ async close() {
13
+ console.warn('[CustomWebView] close() is not supported on web');
14
+ }
15
+ }
16
+
17
+ var web = /*#__PURE__*/Object.freeze({
18
+ __proto__: null,
19
+ CustomWebViewWeb: CustomWebViewWeb
20
+ });
21
+
22
+ exports.CustomWebView = CustomWebView;
23
+
24
+ return exports;
25
+
26
+ })({}, capacitorExports);
27
+ //# 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 CustomWebView = registerPlugin('CustomWebView', {\n web: () => import('./web').then((m) => new m.CustomWebViewWeb()),\n});\nexport * from './definitions';\nexport { CustomWebView };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class CustomWebViewWeb extends WebPlugin {\n async open(options) {\n console.warn('[CustomWebView] open() is not supported on web', options);\n }\n async close() {\n console.warn('[CustomWebView] close() is not supported on web');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,aAAa,GAAGA,mBAAc,CAAC,eAAe,EAAE;IACtD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACpE,CAAC;;ICFM,MAAM,gBAAgB,SAASC,cAAS,CAAC;IAChD,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;IACxB,QAAQ,OAAO,CAAC,IAAI,CAAC,gDAAgD,EAAE,OAAO,CAAC;IAC/E,IAAI;IACJ,IAAI,MAAM,KAAK,GAAG;IAClB,QAAQ,OAAO,CAAC,IAAI,CAAC,iDAAiD,CAAC;IACvE,IAAI;IACJ;;;;;;;;;;;;;;;"}
@@ -0,0 +1,162 @@
1
+ import UIKit
2
+ import WebKit
3
+
4
+ final class CustomWebViewController: UIViewController, UIGestureRecognizerDelegate, WKNavigationDelegate {
5
+
6
+ private let url: URL
7
+ private let closeButtonText: String
8
+ private let webView = WKWebView()
9
+ private var backButton: UIButton!
10
+
11
+ init(url: URL, closeButtonText: String? = nil) {
12
+ self.url = url
13
+ self.closeButtonText = closeButtonText ?? "Close"
14
+ super.init(nibName: nil, bundle: nil)
15
+ }
16
+
17
+ required init?(coder: NSCoder) {
18
+ fatalError()
19
+ }
20
+
21
+ override func viewDidLoad() {
22
+ super.viewDidLoad()
23
+ view.backgroundColor = .white
24
+
25
+ setupHeader()
26
+ setupWebView()
27
+ load()
28
+ }
29
+
30
+ private func setupHeader() {
31
+ let header = UIView()
32
+ header.backgroundColor = .white
33
+ header.translatesAutoresizingMaskIntoConstraints = false
34
+ view.addSubview(header)
35
+
36
+ let back = UIButton(type: .system)
37
+ back.setImage(UIImage(systemName: "chevron.left"), for: .normal)
38
+ back.addTarget(self, action: #selector(backTapped), for: .touchUpInside)
39
+ back.translatesAutoresizingMaskIntoConstraints = false
40
+ header.addSubview(back)
41
+ self.backButton = back
42
+
43
+ let close = UIButton(type: .system)
44
+ close.setTitle(closeButtonText, for: .normal)
45
+ close.addTarget(self, action: #selector(closeTapped), for: .touchUpInside)
46
+ close.translatesAutoresizingMaskIntoConstraints = false
47
+ header.addSubview(close)
48
+
49
+ NSLayoutConstraint.activate([
50
+ header.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
51
+ header.leadingAnchor.constraint(equalTo: view.leadingAnchor),
52
+ header.trailingAnchor.constraint(equalTo: view.trailingAnchor),
53
+ header.heightAnchor.constraint(equalToConstant: 48),
54
+
55
+ back.leadingAnchor.constraint(equalTo: header.leadingAnchor, constant: 8),
56
+ back.centerYAnchor.constraint(equalTo: header.centerYAnchor),
57
+ back.widthAnchor.constraint(equalToConstant: 44),
58
+ back.heightAnchor.constraint(equalToConstant: 44),
59
+
60
+ close.leadingAnchor.constraint(equalTo: back.trailingAnchor, constant: 4),
61
+ close.centerYAnchor.constraint(equalTo: header.centerYAnchor)
62
+ ])
63
+ }
64
+
65
+
66
+ private func setupWebView() {
67
+ webView.translatesAutoresizingMaskIntoConstraints = false
68
+ webView.allowsBackForwardNavigationGestures = true
69
+ webView.navigationDelegate = self
70
+ view.addSubview(webView)
71
+
72
+ NSLayoutConstraint.activate([
73
+ webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 48),
74
+ webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
75
+ webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
76
+ webView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
77
+ ])
78
+ }
79
+
80
+ private func load() {
81
+ webView.load(URLRequest(url: url))
82
+ }
83
+
84
+ @objc private func closeTapped() {
85
+ dismiss(animated: true)
86
+ }
87
+
88
+
89
+ func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
90
+ }
91
+
92
+ private var toastView: UIView?
93
+
94
+ private func showToast(_ message: String) {
95
+ toastView?.removeFromSuperview()
96
+
97
+ let label = UILabel()
98
+ label.text = message
99
+ label.textColor = .white
100
+ label.font = UIFont.preferredFont(forTextStyle: .callout)
101
+ label.textAlignment = .center
102
+ label.numberOfLines = 0
103
+
104
+ let container = UIView()
105
+ container.backgroundColor = UIColor.black.withAlphaComponent(0.7)
106
+ container.layer.cornerRadius = 10
107
+ container.clipsToBounds = true
108
+ container.alpha = 0
109
+
110
+ label.translatesAutoresizingMaskIntoConstraints = false
111
+ container.translatesAutoresizingMaskIntoConstraints = false
112
+
113
+ container.addSubview(label)
114
+ view.addSubview(container)
115
+ toastView = container
116
+
117
+ NSLayoutConstraint.activate([
118
+ label.topAnchor.constraint(equalTo: container.topAnchor, constant: 10),
119
+ label.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -10),
120
+ label.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 14),
121
+ label.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -14),
122
+
123
+ container.centerXAnchor.constraint(equalTo: view.centerXAnchor),
124
+ container.bottomAnchor.constraint(
125
+ equalTo: view.safeAreaLayoutGuide.bottomAnchor,
126
+ constant: -20
127
+ ),
128
+ container.widthAnchor.constraint(lessThanOrEqualToConstant: 320)
129
+ ])
130
+
131
+ UIView.animate(withDuration: 0.25) {
132
+ container.alpha = 1
133
+ }
134
+
135
+ DispatchQueue.main.asyncAfter(deadline: .now() + 1.8) {
136
+ UIView.animate(withDuration: 0.25, animations: {
137
+ container.alpha = 0
138
+ }) { _ in
139
+ container.removeFromSuperview()
140
+ }
141
+ }
142
+ }
143
+
144
+ private var lastBackPressedAt: Date?
145
+
146
+ @objc private func backTapped() {
147
+ if webView.canGoBack {
148
+ webView.goBack()
149
+ return
150
+ }
151
+
152
+ let now = Date()
153
+
154
+ if let last = lastBackPressedAt,
155
+ now.timeIntervalSince(last) < 2 {
156
+ dismiss(animated: true)
157
+ } else {
158
+ lastBackPressedAt = now
159
+ showToast("한 번 더 누르면 웹뷰가 종료됩니다.")
160
+ }
161
+ }
162
+ }
@@ -0,0 +1,43 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ @objc(CustomWebViewPlugin)
5
+ public class CustomWebViewPlugin: CAPPlugin, CAPBridgedPlugin {
6
+
7
+ public let identifier = "CustomWebViewPlugin"
8
+ public let jsName = "CustomWebView"
9
+
10
+ public let pluginMethods: [CAPPluginMethod] = [
11
+ CAPPluginMethod(name: "open", returnType: CAPPluginReturnPromise),
12
+ CAPPluginMethod(name: "close", returnType: CAPPluginReturnNone)
13
+ ]
14
+
15
+ private var webVC: CustomWebViewController?
16
+
17
+ @objc func open(_ call: CAPPluginCall) {
18
+ let urlString = call.getString("url") ?? ""
19
+ let closeButtonText = call.getString("closeButtonText") ?? ""
20
+ guard let url = URL(string: urlString) else {
21
+ call.reject("Invalid URL")
22
+ return
23
+ }
24
+
25
+
26
+ DispatchQueue.main.async {
27
+ let vc = CustomWebViewController(url: url, closeButtonText: closeButtonText)
28
+ vc.modalPresentationStyle = .fullScreen
29
+ self.bridge?.viewController?.present(vc, animated: true)
30
+ self.webVC = vc
31
+ }
32
+
33
+ call.resolve()
34
+ }
35
+
36
+ @objc func close(_ call: CAPPluginCall) {
37
+ DispatchQueue.main.async {
38
+ self.webVC?.dismiss(animated: true)
39
+ self.webVC = nil
40
+ }
41
+ call.resolve()
42
+ }
43
+ }
@@ -0,0 +1,15 @@
1
+ import XCTest
2
+ @testable import CustomWebViewPlugin
3
+
4
+ class CustomWebViewTests: XCTestCase {
5
+ func testEcho() {
6
+ // This is an example of a functional test case for a plugin.
7
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
8
+
9
+ let implementation = CustomWebView()
10
+ let value = "Hello, World!"
11
+ let result = implementation.echo(value)
12
+
13
+ XCTAssertEqual(value, result)
14
+ }
15
+ }
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@jaeyeonee/capacitor-ios-webview",
3
+ "version": "0.0.1",
4
+ "description": "capacitor-iosCustomWebView",
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
+ "CustomWebview.podspec"
17
+ ],
18
+ "author": "jaeyeonee",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/JaeyeoneeJ/capacitor-iosCustomWebView.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/JaeyeoneeJ/capacitor-iosCustomWebView/issues"
26
+ },
27
+ "keywords": [
28
+ "capacitor",
29
+ "plugin",
30
+ "native"
31
+ ],
32
+ "scripts": {
33
+ "verify": "npm run verify:ios && npm run verify:web",
34
+ "verify:ios": "xcodebuild -scheme CustomWebview -destination generic/platform=iOS",
35
+ "verify:web": "npm run build",
36
+ "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
37
+ "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
38
+ "eslint": "eslint . --ext ts",
39
+ "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
40
+ "swiftlint": "node-swiftlint",
41
+ "docgen": "docgen --api CustomWebViewPlugin --output-readme README.md --output-json dist/docs.json",
42
+ "build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
43
+ "clean": "rimraf ./dist",
44
+ "watch": "tsc --watch",
45
+ "prepublishOnly": "npm run build"
46
+ },
47
+ "devDependencies": {
48
+ "@capacitor/core": "^8.0.0",
49
+ "@capacitor/docgen": "^0.3.1",
50
+ "@capacitor/ios": "^8.0.0",
51
+ "@ionic/eslint-config": "^0.4.0",
52
+ "@ionic/prettier-config": "^4.0.0",
53
+ "@ionic/swiftlint-config": "^2.0.0",
54
+ "eslint": "^8.57.1",
55
+ "prettier": "^3.6.2",
56
+ "prettier-plugin-java": "^2.7.7",
57
+ "rimraf": "^6.1.0",
58
+ "rollup": "^4.53.2",
59
+ "swiftlint": "^2.0.0",
60
+ "typescript": "^5.9.3"
61
+ },
62
+ "peerDependencies": {
63
+ "@capacitor/core": ">=8.0.0"
64
+ },
65
+ "prettier": "@ionic/prettier-config",
66
+ "swiftlint": "@ionic/swiftlint-config",
67
+ "eslintConfig": {
68
+ "extends": "@ionic/eslint-config/recommended"
69
+ },
70
+ "capacitor": {
71
+ "ios": {
72
+ "src": "ios"
73
+ }
74
+ }
75
+ }