From 82fb93c20f109ae1d66998191125575fc23ed477 Mon Sep 17 00:00:00 2001 From: Bernhard Pfeifer Date: Wed, 28 Aug 2024 00:03:21 +0200 Subject: [PATCH] refactor: merge squareetlabs, fix definitions --- android/build.gradle | 2 +- .../capacitor/Subscriptions.java | 134 +- .../capacitor/SubscriptionsPlugin.java | 14 +- dist/docs.json | 14 +- dist/esm/definitions.d.ts | 2 +- dist/esm/definitions.js.map | 2 +- example/package-lock.json | 1308 +++++++++++++++++ ios/Plugin/Subscriptions.swift | 236 +-- ios/Plugin/SubscriptionsPlugin.swift | 85 +- package-lock.json | 175 ++- package.json | 3 + src/definitions.ts | 10 +- 12 files changed, 1663 insertions(+), 322 deletions(-) create mode 100644 example/package-lock.json diff --git a/android/build.gradle b/android/build.gradle index 2282b45..8f9de2b 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -13,7 +13,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.2.1' + classpath 'com.android.tools.build:gradle:8.2.2' // classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/android/src/main/java/com/capacitor_subscriptions/capacitor/Subscriptions.java b/android/src/main/java/com/capacitor_subscriptions/capacitor/Subscriptions.java index 4e792f8..4a1a00a 100644 --- a/android/src/main/java/com/capacitor_subscriptions/capacitor/Subscriptions.java +++ b/android/src/main/java/com/capacitor_subscriptions/capacitor/Subscriptions.java @@ -1,58 +1,45 @@ -package com.capicitor_subscriptions.capacitor; +package com.squareetlabs.capacitor.subscriptions; import android.app.Activity; import android.util.Log; -import com.android.billingclient.api.AcknowledgePurchaseParams; -import com.android.billingclient.api.AcknowledgePurchaseResponseListener; import com.android.billingclient.api.BillingClient; import com.android.billingclient.api.BillingClientStateListener; import com.android.billingclient.api.BillingFlowParams; import com.android.billingclient.api.BillingResult; import com.android.billingclient.api.ProductDetails; -import com.android.billingclient.api.ProductDetailsResponseListener; import com.android.billingclient.api.Purchase; import com.android.billingclient.api.PurchaseHistoryRecord; -import com.android.billingclient.api.PurchaseHistoryResponseListener; -import com.android.billingclient.api.PurchasesUpdatedListener; import com.android.billingclient.api.QueryProductDetailsParams; import com.android.billingclient.api.QueryPurchaseHistoryParams; import com.android.billingclient.api.QueryPurchasesParams; -import com.getcapacitor.App; import com.getcapacitor.JSObject; +import com.getcapacitor.Logger; import com.getcapacitor.PluginCall; -import com.google.android.gms.ads.identifier.AdvertisingIdClient; import android.content.Context; -import android.util.Pair; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import org.json.JSONException; -import org.json.JSONObject; +import androidx.annotation.NonNull; import java.io.BufferedReader; -import java.io.DataOutputStream; import java.io.InputStreamReader; -import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; -import java.util.Date; import java.util.List; +import java.util.Locale; +import java.util.Objects; public class Subscriptions { - private Activity activity = null; - public Context context = null; - private SubscriptionsPlugin plugin; - private BillingClient billingClient; + private final Activity activity; + public Context context; + private final BillingClient billingClient; private int billingClientIsConnected = 0; private String googleVerifyEndpoint = ""; @@ -60,17 +47,17 @@ public class Subscriptions { public Subscriptions(SubscriptionsPlugin plugin, BillingClient billingClient) { - this.plugin = plugin; this.billingClient = billingClient; this.billingClient.startConnection(new BillingClientStateListener() { @Override - public void onBillingSetupFinished(BillingResult billingResult) { - if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { + public void onBillingSetupFinished(@NonNull BillingResult billingResult) { + if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { billingClientIsConnected = 1; } else { billingClientIsConnected = billingResult.getResponseCode(); } } + @Override public void onBillingServiceDisconnected() { // Try to restart the connection on the next request to @@ -98,7 +85,7 @@ public void getProductDetails(String productIdentifier, PluginCall call) { JSObject response = new JSObject(); - if(billingClientIsConnected == 1) { + if (billingClientIsConnected == 1) { QueryProductDetailsParams.Product productToFind = QueryProductDetailsParams.Product.newBuilder() .setProductId(productIdentifier) @@ -126,21 +113,19 @@ public void getProductDetails(String productIdentifier, PluginCall call) { List subscriptionOfferDetails = productDetails.getSubscriptionOfferDetails(); - String price = subscriptionOfferDetails.get(0).getPricingPhases().getPricingPhaseList().get(0).getFormattedPrice(); -// String currency = subscriptionOfferDetails.get(0).getPricingPhases().getPricingPhaseList().get(0).getPriceCurrencyCode(); + String price = Objects.requireNonNull(subscriptionOfferDetails).get(0).getPricingPhases().getPricingPhaseList().get(0).getFormattedPrice(); JSObject data = new JSObject(); data.put("productIdentifier", productId); data.put("displayName", title); data.put("description", desc); data.put("price", price); -// data.put("currency", currency); response.put("responseCode", 0); response.put("responseMessage", "Successfully found the product details for given productIdentifier"); response.put("data", data); - } catch(Exception e) { + } catch (Exception e) { Log.e("Err", e.toString()); response.put("responseCode", 1); response.put("responseMessage", "Could not find a product matching the given productIdentifier"); @@ -149,8 +134,8 @@ public void getProductDetails(String productIdentifier, PluginCall call) { call.resolve(response); } ); - - } else if(billingClientIsConnected == 2) { + + } else if (billingClientIsConnected == 2) { response.put("responseCode", 500); response.put("responseMessage", "Android: BillingClient failed to initialise"); @@ -172,7 +157,7 @@ public void getLatestTransaction(String productIdentifier, PluginCall call) { JSObject response = new JSObject(); - if(billingClientIsConnected == 1) { + if (billingClientIsConnected == 1) { QueryPurchaseHistoryParams queryPurchaseHistoryParams = QueryPurchaseHistoryParams.newBuilder() @@ -199,26 +184,24 @@ public void getLatestTransaction(String productIdentifier, PluginCall call) { JSObject data = new JSObject(); String expiryDate = getExpiryDateFromGoogle(productIdentifier, currentPurchaseHistoryRecord.get("purchaseToken").toString()); - if(expiryDate != null) { + if (expiryDate != null) { data.put("expiryDate", expiryDate); } - - String dateFormat = "dd-MM-yyyy hh:mm"; - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat); Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(Long.parseLong((currentPurchaseHistoryRecord.get("purchaseTime").toString()))); - + String orderId = currentPurchaseHistoryRecord.optString("orderId", ""); // Usamos optString para obtener un valor por defecto si la clave no existe data.put("productIdentifier", currentPurchaseHistoryRecord.get("productId")); - data.put("originalId", currentPurchaseHistoryRecord.get("orderId")); - data.put("transactionId", currentPurchaseHistoryRecord.get("orderId")); + data.put("originalId", orderId); + data.put("transactionId", orderId); + data.put("developerPayload",currentPurchaseHistoryRecord.optString("developerPayload", "")); // Usamos optString para obtener un valor por defecto si la clave no existe + data.put("purchaseToken", currentPurchaseHistoryRecord.get("purchaseToken").toString()); response.put("responseCode", 0); response.put("responseMessage", "Successfully found the latest transaction matching given productIdentifier"); response.put("data", data); } } catch (Exception e) { - e.printStackTrace(); - // This should never really be caught, but compile a response saying an unknown error occurred anyway. + Logger.error(e.getMessage()); } i++; @@ -244,7 +227,7 @@ public void getCurrentEntitlements(PluginCall call) { JSObject response = new JSObject(); - if(billingClientIsConnected == 1) { + if (billingClientIsConnected == 1) { QueryPurchasesParams queryPurchasesParams = QueryPurchasesParams.newBuilder() @@ -257,34 +240,32 @@ public void getCurrentEntitlements(PluginCall call) { try { - Integer amountOfPurchases = purchaseList.size(); + int amountOfPurchases = purchaseList.size(); - if(amountOfPurchases > 0 ) { + if (amountOfPurchases > 0) { - ArrayList entitlements = new ArrayList(); - for(int i = 0; i < purchaseList.size(); i++) { + ArrayList entitlements = new ArrayList<>(); + for (int i = 0; i < purchaseList.size(); i++) { Purchase currentPurchase = purchaseList.get(i); - // if(currentPurchase.isAutoRenewing()) { - - String expiryDate = this.getExpiryDateFromGoogle(currentPurchase.getProducts().get(0), currentPurchase.getPurchaseToken()); - String orderId = currentPurchase.getOrderId(); - - String dateFormat = "dd-MM-yyyy hh:mm"; - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat); - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(Long.parseLong((String.valueOf(currentPurchase.getPurchaseTime())))); - - entitlements.add( - new JSObject() - .put("productIdentifier", currentPurchase.getProducts().get(0)) - .put("expiryDate", expiryDate) - .put("originalStartDate", simpleDateFormat.format(calendar.getTime())) - .put("originalId", orderId) - .put("transactionId", orderId) - ); - // } + String expiryDate = this.getExpiryDateFromGoogle(currentPurchase.getProducts().get(0), currentPurchase.getPurchaseToken()); + String orderId = currentPurchase.getOrderId(); + + String dateFormat = "dd-MM-yyyy hh:mm"; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat, Locale.getDefault()); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(Long.parseLong((String.valueOf(currentPurchase.getPurchaseTime())))); + + entitlements.add( + new JSObject() + .put("productIdentifier", currentPurchase.getProducts().get(0)) + .put("expiryDate", expiryDate) + .put("originalStartDate", simpleDateFormat.format(calendar.getTime())) + .put("originalId", orderId) + .put("transactionId", orderId) + .put("purchaseToken", currentPurchase.getPurchaseToken()) + ); } response.put("responseCode", 0); @@ -301,7 +282,7 @@ public void getCurrentEntitlements(PluginCall call) { call.resolve(response); - } catch(Exception e) { + } catch (Exception e) { Log.e("Error", e.toString()); response.put("responseCode", 2); response.put("responseMessage", e.toString()); @@ -320,7 +301,7 @@ public void purchaseProduct(String productIdentifier, PluginCall call) { JSObject response = new JSObject(); - if(billingClientIsConnected == 1) { + if (billingClientIsConnected == 1) { QueryProductDetailsParams.Product productToFind = QueryProductDetailsParams.Product.newBuilder() .setProductId(productIdentifier) @@ -343,18 +324,19 @@ public void purchaseProduct(String productIdentifier, PluginCall call) { List.of( BillingFlowParams.ProductDetailsParams.newBuilder() .setProductDetails(productDetails) - .setOfferToken(productDetails.getSubscriptionOfferDetails().get(0).getOfferToken()) + .setOfferToken(Objects.requireNonNull(productDetails.getSubscriptionOfferDetails()).get(0).getOfferToken()) .build() ) ) .build(); BillingResult result = billingClient.launchBillingFlow(this.activity, billingFlowParams); + Log.i("RESULT", result.toString()); response.put("responseCode", 0); response.put("responseMessage", "Successfully opened native popover"); } catch (Exception e) { - e.printStackTrace(); + Logger.error(e.getMessage()); response.put("responseCode", 1); response.put("responseMessage", "Failed to open native popover"); } @@ -377,10 +359,10 @@ private String getExpiryDateFromGoogle(String productIdentifier, String purchase // Try to receive response from server try (BufferedReader br = new BufferedReader( - new InputStreamReader(con.getInputStream(), "utf-8"))) { + new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))) { StringBuilder googleResponse = new StringBuilder(); - String responseLine = null; + String responseLine; while ((responseLine = br.readLine()) != null) { googleResponse.append(responseLine.trim()); Log.i("Response Line", responseLine); @@ -390,11 +372,11 @@ private String getExpiryDateFromGoogle(String productIdentifier, String purchase if (con.getResponseCode() == 200) { JSObject postResponseJSON = new JSObject(googleResponse.toString()); - JSObject googleResponseJSON = new JSObject(postResponseJSON.get("googleResponce").toString()); // <-- note the typo in response object from server + JSObject googleResponseJSON = new JSObject(postResponseJSON.get("googleResponse").toString()); // <-- note the typo in response object from server JSObject payloadJSON = new JSObject(googleResponseJSON.get("payload").toString()); String dateFormat = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z '('z')'"; - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat, Locale.getDefault()); Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(Long.parseLong((payloadJSON.get("expiryTimeMillis").toString()))); @@ -406,15 +388,15 @@ private String getExpiryDateFromGoogle(String productIdentifier, String purchase return null; } } catch (Exception e) { - e.printStackTrace(); + Logger.error(e.getMessage()); } } catch (Exception e) { - e.printStackTrace(); + Logger.error(e.getMessage()); } // If the method manages to each this far before already returning, just return null // because something went wrong return null; } -} +} \ No newline at end of file diff --git a/android/src/main/java/com/capacitor_subscriptions/capacitor/SubscriptionsPlugin.java b/android/src/main/java/com/capacitor_subscriptions/capacitor/SubscriptionsPlugin.java index 6bc959b..8ad6512 100644 --- a/android/src/main/java/com/capacitor_subscriptions/capacitor/SubscriptionsPlugin.java +++ b/android/src/main/java/com/capacitor_subscriptions/capacitor/SubscriptionsPlugin.java @@ -1,4 +1,4 @@ -package com.capicitor_subscriptions.capacitor; +package com.squareetlabs.capacitor.subscriptions; import android.content.Intent; import android.net.Uri; @@ -6,19 +6,14 @@ import com.android.billingclient.api.AcknowledgePurchaseParams; import com.android.billingclient.api.BillingClient; -import com.android.billingclient.api.BillingClientStateListener; -import com.android.billingclient.api.BillingResult; import com.android.billingclient.api.Purchase; import com.android.billingclient.api.PurchasesUpdatedListener; import com.getcapacitor.JSObject; import com.getcapacitor.Plugin; import com.getcapacitor.PluginCall; import com.getcapacitor.PluginMethod; -import com.getcapacitor.PluginResult; import com.getcapacitor.annotation.CapacitorPlugin; -import org.json.JSONObject; - @CapacitorPlugin(name = "Subscriptions") public class SubscriptionsPlugin extends Plugin { @@ -33,7 +28,7 @@ public SubscriptionsPlugin () { // This listener is fired upon completing the billing flow, it is vital to call the acknowledgePurchase // method on the billingClient, with the purchase token otherwise Google will automatically cancel the subscription // shortly after the purchase - private PurchasesUpdatedListener purchasesUpdatedListener = (billingResult, purchases) -> { + private final PurchasesUpdatedListener purchasesUpdatedListener = (billingResult, purchases) -> { JSObject response = new JSObject(); @@ -51,7 +46,7 @@ public SubscriptionsPlugin () { Log.i("Purchase ack", currentPurchase.getOriginalJson()); billingResult1.getResponseCode(); - response.put("successful", true); + response.put("successful", billingResult1.getResponseCode()); // WARNING: Changed the notifyListeners method from protected to public in order to get the method call to work // This may be a security issue in the future - in order to fix it, it may be best to move this listener + the billingClient @@ -169,5 +164,4 @@ public void manageSubscriptions(PluginCall call) { getActivity().startActivity(browserIntent); } -} - +} \ No newline at end of file diff --git a/dist/docs.json b/dist/docs.json index 61c9d40..7d6f437 100644 --- a/dist/docs.json +++ b/dist/docs.json @@ -125,7 +125,7 @@ }, { "name": "addListener", - "signature": "(eventName: 'ANDROID-PURCHASE-RESPONSE', listenerFunc: (response: AndroidPurchasedTrigger) => void) => Promise & PluginListenerHandle", + "signature": "(eventName: 'ANDROID-PURCHASE-RESPONSE', listenerFunc: (response: AndroidPurchasedTrigger) => void) => Promise", "parameters": [ { "name": "eventName", @@ -138,7 +138,7 @@ "type": "(response: AndroidPurchasedTrigger) => void" } ], - "returns": "Promise & PluginListenerHandle", + "returns": "Promise", "tags": [], "docs": "", "complexTypes": [ @@ -417,7 +417,15 @@ "docs": "", "tags": [], "methods": [], - "properties": [] + "properties": [ + { + "name": "remove", + "tags": [], + "docs": "", + "complexTypes": [], + "type": "() => Promise" + } + ] }, { "name": "AndroidPurchasedTrigger", diff --git a/dist/esm/definitions.d.ts b/dist/esm/definitions.d.ts index 6aaa935..c068427 100644 --- a/dist/esm/definitions.d.ts +++ b/dist/esm/definitions.d.ts @@ -31,7 +31,7 @@ export interface SubscriptionsPlugin { googleVerifyEndpoint: string; bid: string; }): void; - addListener(eventName: 'ANDROID-PURCHASE-RESPONSE', listenerFunc: (response: AndroidPurchasedTrigger) => void): Promise & PluginListenerHandle; + addListener(eventName: 'ANDROID-PURCHASE-RESPONSE', listenerFunc: (response: AndroidPurchasedTrigger) => void): Promise; } export interface Product { productIdentifier: string; diff --git a/dist/esm/definitions.js.map b/dist/esm/definitions.js.map index 2d55125..51845e2 100644 --- a/dist/esm/definitions.js.map +++ b/dist/esm/definitions.js.map @@ -1 +1 @@ -{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import { PluginListenerHandle } from \"@capacitor/core\";\n\nexport interface SubscriptionsPlugin {\n /**\n * A test method which just returns what is passed in\n */\n echo(options: { value: string }): Promise<{ value: string }>;\n\n /**\n * Receives a product ID and returns the product details\n * @param options.productId The product ID to lookup\n */\n getProductDetails(options: { productIdentifier: string }): Promise< ProductDetailsResponse >;\n\n /**\n * Receives the product ID which the user wants to purchase and returns the transaction ID\n * @param options.productId contains the productIdentifier\n */\n purchaseProduct(options: { productIdentifier: string }): Promise< PurchaseProductResponse >;\n\n \n getCurrentEntitlements(): Promise< CurrentEntitlementsResponse >;\n \n getLatestTransaction(options: {productIdentifier: string}): Promise< LatestTransactionResponse >;\n\n manageSubscriptions(): any;\n\n setGoogleVerificationDetails(options: { googleVerifyEndpoint: string, bid: string }): void;\n\n addListener(\n eventName: 'ANDROID-PURCHASE-RESPONSE',\n listenerFunc: (response: AndroidPurchasedTrigger) => void,\n ): Promise & PluginListenerHandle;\n\n}\n\n// Response data types\n\nexport interface Product {\n productIdentifier: string;\n price: string;\n displayName: string;\n description: string;\n}\n\nexport interface Transaction {\n productIdentifier: string;\n expiryDate: string;\n originalId: string;\n transactionId: string;\n originalStartDate: string;\n isTrial?: boolean;\n}\n\n// latestTransactions interface and types\n\nexport interface LatestTransactionResponse {\n\tresponseCode: LatestTransactionResponseCode,\n\tresponseMessage: LatestTransactionResponseMessage,\n\tdata?: Transaction\n}\n\nexport type LatestTransactionResponseCode = -1 | 0 | 1 | 2 | 3\nexport type LatestTransactionResponseMessage =\n\"Incompatible with web\" |\n\"Successfully found the latest transaction matching given productIdentifier\" |\n\"Could not find a product matching the given productIdentifier\" |\n\"No transaction for given productIdentifier, or it could not be verified\" |\n\"Unknown problem trying to retrieve latest transaction\"\n\n// currentEntitlements interface and types\n\nexport interface CurrentEntitlementsResponse {\n\tresponseCode: CurrentEntitlementsResponseCode,\n\tresponseMessage: CurrentEntitlementsResponseMessage,\n\tdata?: Transaction[]\n}\n\nexport type CurrentEntitlementsResponseCode = -1 | 0 | 1 | 2\nexport type CurrentEntitlementsResponseMessage =\n\"Incompatible with web\" |\n\"Successfully found all entitlements across all product types\" |\n\"No entitlements were found\" |\n\"Unknown problem trying to retrieve entitlements\"\n\n// purchaseProduct interface and types\n\nexport interface PurchaseProductResponse {\n\tresponseCode: PurchaseProductIOSResponseCode | PurchaseProductAndroidResponseCode\n\tresponseMessage: PurchaseProductIOSResponseMessage | PurchaseProductAndroidResponseMessage\n receiptString?: string\n currency?: string\n productId?: string\n productPrice?: number\n transactionPrice?: number\n}\n\nexport type PurchaseProductIOSResponseCode = -1 | 0 | 1 | 2 | 3 | 4 | 5\nexport type PurchaseProductIOSResponseMessage =\n\"Incompatible with web\" | \n\"Successfully purchased product\" |\n\"Could not find a product matching the given productIdentifier\" |\n\"Product seems to have been purchased but the transaction failed verification\" |\n\"User closed the native popover before purchasing\" |\n\"Product request made but is currently pending - likely due to parental restrictions\" |\n\"An unknown error occurred whilst in the purchasing process\"\n\nexport type PurchaseProductAndroidResponseCode = -1 | 0 | 1\nexport type PurchaseProductAndroidResponseMessage =\n\"Incompatible with web\" |\n\"Successfully opened native popover\" |\n\"Failed to open native popover\"\n\nexport interface ProductDetailsResponse {\n\tresponseCode: ProductDetailsResponseCode\n\tresponseMessage: ProductDetailsResponseMessage\n\tdata?: Product\n}\n\nexport type ProductDetailsResponseCode = -1 | 0 | 1\nexport type ProductDetailsResponseMessage = \n\"Incompatible with web\" |\n\"Successfully found the product details for given productIdentifier\" |\n\"Could not find a product matching the given productIdentifier\"\n\nexport interface AndroidPurchasedTrigger {\n fired: boolean;\n}\n"]} \ No newline at end of file +{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import { PluginListenerHandle } from \"@capacitor/core\";\n\nexport interface SubscriptionsPlugin {\n /**\n * A test method which just returns what is passed in\n */\n echo(options: { value: string }): Promise<{ value: string }>;\n\n /**\n * Receives a product ID and returns the product details\n * @param options.productId The product ID to lookup\n */\n getProductDetails(options: { productIdentifier: string }): Promise< ProductDetailsResponse >;\n\n /**\n * Receives the product ID which the user wants to purchase and returns the transaction ID\n * @param options.productId contains the productIdentifier\n */\n purchaseProduct(options: { productIdentifier: string }): Promise< PurchaseProductResponse >;\n\n\n getCurrentEntitlements(): Promise< CurrentEntitlementsResponse >;\n\n getLatestTransaction(options: {productIdentifier: string}): Promise< LatestTransactionResponse >;\n\n manageSubscriptions(): any;\n\n setGoogleVerificationDetails(options: { googleVerifyEndpoint: string, bid: string }): void;\n\n addListener(\n eventName: 'ANDROID-PURCHASE-RESPONSE',\n listenerFunc: (response: AndroidPurchasedTrigger) => void,\n ): Promise;\n\n}\n\n// Response data types\n\nexport interface Product {\n productIdentifier: string;\n price: string;\n displayName: string;\n description: string;\n}\n\nexport interface Transaction {\n productIdentifier: string;\n expiryDate: string;\n originalId: string;\n transactionId: string;\n originalStartDate: string;\n isTrial?: boolean;\n}\n\n// latestTransactions interface and types\n\nexport interface LatestTransactionResponse {\n\tresponseCode: LatestTransactionResponseCode,\n\tresponseMessage: LatestTransactionResponseMessage,\n\tdata?: Transaction\n}\n\nexport type LatestTransactionResponseCode = -1 | 0 | 1 | 2 | 3\nexport type LatestTransactionResponseMessage =\n\"Incompatible with web\" |\n\"Successfully found the latest transaction matching given productIdentifier\" |\n\"Could not find a product matching the given productIdentifier\" |\n\"No transaction for given productIdentifier, or it could not be verified\" |\n\"Unknown problem trying to retrieve latest transaction\"\n\n// currentEntitlements interface and types\n\nexport interface CurrentEntitlementsResponse {\n\tresponseCode: CurrentEntitlementsResponseCode,\n\tresponseMessage: CurrentEntitlementsResponseMessage,\n\tdata?: Transaction[]\n}\n\nexport type CurrentEntitlementsResponseCode = -1 | 0 | 1 | 2\nexport type CurrentEntitlementsResponseMessage =\n\"Incompatible with web\" |\n\"Successfully found all entitlements across all product types\" |\n\"No entitlements were found\" |\n\"Unknown problem trying to retrieve entitlements\"\n\n// purchaseProduct interface and types\n\nexport interface PurchaseProductResponse {\n\tresponseCode: PurchaseProductIOSResponseCode | PurchaseProductAndroidResponseCode\n\tresponseMessage: PurchaseProductIOSResponseMessage | PurchaseProductAndroidResponseMessage\n receiptString?: string\n currency?: string\n productId?: string\n productPrice?: number\n transactionPrice?: number\n}\n\nexport type PurchaseProductIOSResponseCode = -1 | 0 | 1 | 2 | 3 | 4 | 5\nexport type PurchaseProductIOSResponseMessage =\n\"Incompatible with web\" |\n\"Successfully purchased product\" |\n\"Could not find a product matching the given productIdentifier\" |\n\"Product seems to have been purchased but the transaction failed verification\" |\n\"User closed the native popover before purchasing\" |\n\"Product request made but is currently pending - likely due to parental restrictions\" |\n\"An unknown error occurred whilst in the purchasing process\"\n\nexport type PurchaseProductAndroidResponseCode = -1 | 0 | 1\nexport type PurchaseProductAndroidResponseMessage =\n\"Incompatible with web\" |\n\"Successfully opened native popover\" |\n\"Failed to open native popover\"\n\nexport interface ProductDetailsResponse {\n\tresponseCode: ProductDetailsResponseCode\n\tresponseMessage: ProductDetailsResponseMessage\n\tdata?: Product\n}\n\nexport type ProductDetailsResponseCode = -1 | 0 | 1\nexport type ProductDetailsResponseMessage =\n\"Incompatible with web\" |\n\"Successfully found the product details for given productIdentifier\" |\n\"Could not find a product matching the given productIdentifier\"\n\nexport interface AndroidPurchasedTrigger {\n fired: boolean;\n}\n"]} \ No newline at end of file diff --git a/example/package-lock.json b/example/package-lock.json new file mode 100644 index 0000000..fa80822 --- /dev/null +++ b/example/package-lock.json @@ -0,0 +1,1308 @@ +{ + "name": "capacitor-app", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "capacitor-app", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@capacitor/camera": "latest", + "@capacitor/core": "latest", + "@capacitor/splash-screen": "latest", + "capacitor-subscriptions": "file:.." + }, + "devDependencies": { + "@capacitor/cli": "latest" + } + }, + "..": { + "version": "1.0.4", + "license": "none", + "devDependencies": { + "@capacitor/android": "^6.0.0", + "@capacitor/core": "^6.0.0", + "@capacitor/docgen": "^0.2.1", + "@capacitor/ios": "^6.0.0", + "@ionic/eslint-config": "^0.3.0", + "@ionic/prettier-config": "^4.0.0", + "@ionic/swiftlint-config": "^1.1.2", + "eslint": "^8.52.0", + "prettier": "~3.0.3", + "prettier-plugin-java": "~2.3.1", + "rimraf": "^5.0.5", + "rollup": "^4.2.0", + "swiftlint": "^1.0.2", + "typescript": "~5.2.2" + }, + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/camera": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/camera/-/camera-6.0.2.tgz", + "integrity": "sha512-bC2xxCcNTyfKYuLNLbGIyLlK9fok2MDhF4v8s01jusYAxoBI7LaKWQMQoGBA1MY/Ec6x/2pjIr+7k89Kmdr74g==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/cli": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-6.1.2.tgz", + "integrity": "sha512-HKCNGE0RP8U7aiEF2vg5wTivJROS8BVfu8a3yYJb1mRQvzv+czpmtHNsTWS/WukvwoxUjyjRmsNQSAACHfMTmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/cli-framework-output": "^2.2.5", + "@ionic/utils-fs": "^3.1.6", + "@ionic/utils-process": "^2.1.11", + "@ionic/utils-subprocess": "2.1.11", + "@ionic/utils-terminal": "^2.3.3", + "commander": "^9.3.0", + "debug": "^4.3.4", + "env-paths": "^2.2.0", + "kleur": "^4.1.4", + "native-run": "^2.0.0", + "open": "^8.4.0", + "plist": "^3.0.5", + "prompts": "^2.4.2", + "rimraf": "^4.4.1", + "semver": "^7.3.7", + "tar": "^6.1.11", + "tslib": "^2.4.0", + "xml2js": "^0.5.0" + }, + "bin": { + "cap": "bin/capacitor", + "capacitor": "bin/capacitor" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@capacitor/core": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-6.1.2.tgz", + "integrity": "sha512-xFy1/4qLFLp5WCIzIhtwUuVNNoz36+V7/BzHmLqgVJcvotc4MMjswW/TshnPQaLLujEOaLkA4h8ZJ0uoK3ImGg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@capacitor/splash-screen": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/splash-screen/-/splash-screen-6.0.2.tgz", + "integrity": "sha512-WC0KYZ+ev15up03xs4fTnoTKwBVUSxXsKKQr/8XAncvi/nAG8qrpanW8OlavSC5zF5e1IZZDLsI2GSv0SkZ7VQ==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@ionic/cli-framework-output": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.8.tgz", + "integrity": "sha512-TshtaFQsovB4NWRBydbNFawql6yul7d5bMiW1WYYf17hd99V6xdDdk3vtF51bw6sLkxON3bDQpWsnUc9/hVo3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-array": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.5.tgz", + "integrity": "sha512-HD72a71IQVBmQckDwmA8RxNVMTbxnaLbgFOl+dO5tbvW9CkkSFCv41h6fUuNsSEVgngfkn0i98HDuZC8mk+lTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-fs": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.7.tgz", + "integrity": "sha512-2EknRvMVfhnyhL1VhFkSLa5gOcycK91VnjfrTB0kbqkTFCOXyXgVLI5whzq7SLrgD9t1aqos3lMMQyVzaQ5gVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^8.0.0", + "debug": "^4.0.0", + "fs-extra": "^9.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-object": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.6.tgz", + "integrity": "sha512-vCl7sl6JjBHFw99CuAqHljYJpcE88YaH2ZW4ELiC/Zwxl5tiwn4kbdP/gxi2OT3MQb1vOtgAmSNRtusvgxI8ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-process": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.12.tgz", + "integrity": "sha512-Jqkgyq7zBs/v/J3YvKtQQiIcxfJyplPgECMWgdO0E1fKrrH8EF0QGHNJ9mJCn6PYe2UtHNS8JJf5G21e09DfYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-object": "2.1.6", + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-stream": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.5.tgz", + "integrity": "sha512-hkm46uHvEC05X/8PHgdJi4l4zv9VQDELZTM+Kz69odtO9zZYfnt8DkfXHJqJ+PxmtiE5mk/ehJWLnn/XAczTUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-2.1.11.tgz", + "integrity": "sha512-6zCDixNmZCbMCy5np8klSxOZF85kuDyzZSTTQKQP90ZtYNCcPYmuFSzaqDwApJT4r5L3MY3JrqK1gLkc6xiUPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-array": "2.1.5", + "@ionic/utils-fs": "3.1.6", + "@ionic/utils-process": "2.1.10", + "@ionic/utils-stream": "3.1.5", + "@ionic/utils-terminal": "2.3.3", + "cross-spawn": "^7.0.3", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-fs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.6.tgz", + "integrity": "sha512-eikrNkK89CfGPmexjTfSWl4EYqsPSBh0Ka7by4F0PLc1hJZYtJxUZV3X4r5ecA8ikjicUmcbU7zJmAjmqutG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^8.0.0", + "debug": "^4.0.0", + "fs-extra": "^9.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-object": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.5.tgz", + "integrity": "sha512-XnYNSwfewUqxq+yjER1hxTKggftpNjFLJH0s37jcrNDwbzmbpFTQTVAp4ikNK4rd9DOebX/jbeZb8jfD86IYxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-process": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.10.tgz", + "integrity": "sha512-mZ7JEowcuGQK+SKsJXi0liYTcXd2bNMR3nE0CyTROpMECUpJeAvvaBaPGZf5ERQUPeWBVuwqAqjUmIdxhz5bxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-object": "2.1.5", + "@ionic/utils-terminal": "2.3.3", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-terminal": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.3.tgz", + "integrity": "sha512-RnuSfNZ5fLEyX3R5mtcMY97cGD1A0NVBbarsSQ6yMMfRJ5YHU7hHVyUfvZeClbqkBC/pAqI/rYJuXKCT9YeMCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/slice-ansi": "^4.0.0", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "tslib": "^2.0.1", + "untildify": "^4.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-terminal": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.5.tgz", + "integrity": "sha512-3cKScz9Jx2/Pr9ijj1OzGlBDfcmx7OMVBt4+P1uRR0SSW4cm1/y3Mo4OY3lfkuaYifMNBW8Wz6lQHbs1bihr7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/slice-ansi": "^4.0.0", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "tslib": "^2.0.1", + "untildify": "^4.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@types/fs-extra": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", + "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bplist-parser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", + "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/capacitor-subscriptions": { + "resolved": "..", + "link": true + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/elementtree": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", + "integrity": "sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "sax": "1.1.4" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/native-run": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/native-run/-/native-run-2.0.1.tgz", + "integrity": "sha512-XfG1FBZLM50J10xH9361whJRC9SHZ0Bub4iNRhhI61C8Jv0e1ud19muex6sNKB51ibQNUJNuYn25MuYET/rE6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-fs": "^3.1.7", + "@ionic/utils-terminal": "^2.3.4", + "bplist-parser": "^0.3.2", + "debug": "^4.3.4", + "elementtree": "^0.1.7", + "ini": "^4.1.1", + "plist": "^3.1.0", + "split2": "^4.2.0", + "through2": "^4.0.2", + "tslib": "^2.6.2", + "yauzl": "^2.10.0" + }, + "bin": { + "native-run": "bin/native-run" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/rimraf": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", + "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", + "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==", + "dev": true, + "license": "ISC" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/ios/Plugin/Subscriptions.swift b/ios/Plugin/Subscriptions.swift index cf829f9..7b933e4 100644 --- a/ios/Plugin/Subscriptions.swift +++ b/ios/Plugin/Subscriptions.swift @@ -4,7 +4,7 @@ import Capacitor import UIKit @objc public class Subscriptions: NSObject { - + override init() { super.init(); if #available(iOS 15.0.0, *) { @@ -14,7 +14,7 @@ import UIKit // Fallback on earlier versions }; } - + // When the subscription renews at the end of the month, a transaction will // be queued for when the app is next opened. This listener handles any transactions // within the queue and finishes verified purchases to clear the queue and prevent @@ -25,35 +25,35 @@ import UIKit //Iterate through any transactions that don't come from a direct call to `purchase()`. for await verification in Transaction.updates { - + guard let transaction: Transaction = self.checkVerified(verification) as? Transaction else { print("checkVerified failed"); return - + }; - + await transaction.finish(); print("Transaction finished and removed from paymentQueue - Transactions.updates"); } - + } } - + @available(iOS 15.0.0, *) private func finishTransactions() -> Task { return Task.detached { //Iterate through any transactions that don't come from a direct call to `purchase()`. for await verification in Transaction.unfinished { - + guard let transaction: Transaction = self.checkVerified(verification) as? Transaction else { print("checkVerified failed"); return - + }; - + await transaction.finish(); print("Transaction finished and removed from paymentQueue - transactions.unfinished"); } @@ -69,7 +69,7 @@ import UIKit "responseMessage": "Could not find a product matching the given productIdentifier" ] }; - + let displayName = product.displayName; let description = product.description; let price = product.displayPrice; @@ -78,54 +78,17 @@ import UIKit "responseCode": 0, "responseMessage": "Successfully found the product details for given productIdentifier", "data": [ + "productIdentifier": productIdentifier, "displayName": displayName, "description": description, - "price": price, - "productIdentifier": productIdentifier + "price": price ] ]; } -// func validateReceipt(receipt: String) { -// // let requestDictionary = ["receipt-data": receipt] -// // guard JSONSerialization.isValidJSONObject(requestDictionary), -// // let requestData = try? JSONSerialization.data(withJSONObject: requestDictionary) else { -// // print("FAULT 1") -// // return -// // } -// let requestData: [String: Any] = [ -// "receipt-data": receipt, -// "password": "8006fc83269046d499d16a3111d6dbba" // Only needed for subscriptions -// ] -// -// guard let httpBody = try? JSONSerialization.data(withJSONObject: requestData, options: []) else { -// print("Invalid JSON") -// return -// } -// -// let storeURL = URL(string: "https://sandbox.itunes.apple.com/verifyReceipt")! -// var request = URLRequest(url: storeURL) -// request.httpMethod = "POST" -// request.httpBody = httpBody -// request.setValue("application/json", forHTTPHeaderField: "Content-Type") -// -// let task = URLSession.shared.dataTask(with: request) { data, response, error in -// guard error == nil, let data = data else { -// print("FAULT 2") -// return -// } -// -// if let jsonResponse = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { -// print(jsonResponse) -// // Handle the response -// } -// } -// task.resume() -// } - @available(iOS 15.0.0, *) @objc public func purchaseProduct(_ productIdentifier: String) async -> PluginCallResultData { - + do { guard let product: Product = await getProduct(productIdentifier) as? Product else { @@ -146,54 +109,12 @@ import UIKit "responseMessage": "Product seems to have been purchased but the transaction failed verification" ]; }; - - await transaction.finish(); - - // make sure we load the complete transaction history - // otherwise it can be possible that the receipt is not updated - // and stays empty - // let paymentQueue = SKPaymentQueue.default() - // paymentQueue.restoreCompletedTransactions() - refreshReceipt(); - - if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL, - FileManager.default.fileExists(atPath: appStoreReceiptURL.path) { - - do { - let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped) - - - let receiptString = receiptData.base64EncodedString(options: []) - print("Receipt String: ", receiptString) - - var responseDict: [String: Any] = [ - "responseCode": 0, - "responseMessage": "Successfully purchased product", - "receiptString": receiptString, - "productId": transaction.productID, - "productPrice": product.price, - ] - - if let price: Decimal = transaction.price { - responseDict["transactionPrice"] = price - } - - if #available(iOS 16.0, *) { - if let currency: Locale.Currency = transaction.currency { - responseDict["currency"] = String(describing: currency) - } - } - - return responseDict - - } - catch { print("Couldn't read receipt data with error: " + error.localizedDescription) } - } + await transaction.finish(); return [ "responseCode": 0, "responseMessage": "Successfully purchased product" - ] + ]; case .userCancelled: @@ -215,9 +136,9 @@ import UIKit "responseCode": 5, "responseMessage": "An unknown error occurred whilst in the purchasing process", ] - + } - + } catch { print(error.localizedDescription); return [ @@ -227,62 +148,56 @@ import UIKit } } - + @available(iOS 15.0.0, *) @objc public func getCurrentEntitlements() async -> PluginCallResultData { do { - + var transactionDictionary = [String: [String: Any]](); - -// Loop through each verification result in currentEntitlements, verify the transaction -// then add it to the transactionDictionary if verified. - var index = 0 + + // Loop through each verification result in currentEntitlements, verify the transaction + // then add it to the transactionDictionary if verified. for await verification in Transaction.currentEntitlements { - + let transaction: Transaction? = checkVerified(verification) as? Transaction if(transaction != nil) { - transactionDictionary[String(index)] = [ + transactionDictionary[String(transaction!.id)] = [ "productIdentifier": transaction!.productID, "originalStartDate": transaction!.originalPurchaseDate, "originalId": transaction!.originalID, "transactionId": transaction!.id, - "expiryDate": transaction!.expirationDate + "expiryDate": transaction!.expirationDate!, + "purchaseToken": "" ] - index += 1 + } - + } - -// If we have one or more entitlements in transactionDictionary -// we want the response to include it in the data property + + // If we have one or more entitlements in transactionDictionary + // we want the response to include it in the data property if(transactionDictionary.count > 0) { - + let response = [ "responseCode": 0, "responseMessage": "Successfully found all entitlements across all product types", "data": transactionDictionary ] as [String : Any] - + return response; - -// Otherwise - no entitlements were found + + // Otherwise - no entitlements were found } else { return [ "responseCode": 1, "responseMessage": "No entitlements were found", ] } - - } catch { - print(error.localizedDescription) - return [ - "responseCode": 2, - "responseMessage": "Unknown problem trying to retrieve entitlements" - ] + } - + } @@ -297,7 +212,7 @@ import UIKit ] }; - + guard let transaction: Transaction = checkVerified(await product.latestTransaction) as? Transaction else { // The user hasn't purchased this product. return [ @@ -305,11 +220,13 @@ import UIKit "responseMessage": "No transaction for given productIdentifier, or it could not be verified" ] } - + print("expiration" + String(decoding: formatDate(transaction.expirationDate)!, as: UTF8.self)) - print("transaction.expirationDate", transaction.expirationDate) + print("transaction.expirationDate", transaction.expirationDate!) print("transaction.originalID", transaction.originalID); - + + var receiptString = ""; + if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL, FileManager.default.fileExists(atPath: appStoreReceiptURL.path) { @@ -319,7 +236,7 @@ import UIKit print("Receipt Data: ", receiptData) - let receiptString = receiptData.base64EncodedString(options: [Data.Base64EncodingOptions.endLineWithCarriageReturn]) + receiptString = receiptData.base64EncodedString(options: [Data.Base64EncodingOptions.endLineWithCarriageReturn]) print("Receipt String: ", receiptString) @@ -328,7 +245,7 @@ import UIKit catch { print("Couldn't read receipt data with error: " + error.localizedDescription) } } - + return [ "responseCode": 0, "responseMessage": "Latest transaction found", @@ -337,55 +254,50 @@ import UIKit "originalStartDate": transaction.originalPurchaseDate, "originalId": transaction.originalID, "transactionId": transaction.id, - "expiryDate": transaction.expirationDate + "expiryDate": transaction.expirationDate!, + "purchaseToken": receiptString ] ]; - - } catch { - print("Error:" + error.localizedDescription); - return [ - "responseCode": 3, - "responseMessage": "Unknown problem trying to retrieve latest transaction" - ] + } } @available(iOS 15.0.0, *) @objc public func manageSubscriptions() async { - + let manageTransactions: UIWindowScene await UIApplication.shared.open(URL(string: "https://apps.apple.com/account/subscriptions")!) - + } - + @available(iOS 15.0.0, *) @objc private func formatDate(_ date: Date?) -> Data? { - + let df = DateFormatter(); df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" return df.string(for: date)?.data(using: String.Encoding.utf8)!; - + } - + @available(iOS 15.0.0, *) @objc private func updateTrialDate(_ bid: String, _ formattedDate: Data?) { - + let keyChainUpdateParams: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrAccount as String: bid ] - + let keyChainUpdateValue: [String: Any] = [ - kSecValueData as String: formattedDate + kSecValueData as String: formattedDate! ]; - + let updateStatusCode = SecItemUpdate(keyChainUpdateParams as CFDictionary, keyChainUpdateValue as CFDictionary); let updateStatusMessage = SecCopyErrorMessageString(updateStatusCode, nil); - + print("updateStatusCode in SecItemUpdate", updateStatusCode); - print("updateStatusMessage in SecItemUpdate", updateStatusMessage); - + print("updateStatusMessage in SecItemUpdate", updateStatusMessage!); + } @available(iOS 15.0.0, *) @@ -418,26 +330,4 @@ import UIKit } - @objc private func refreshReceipt() { - let request = SKReceiptRefreshRequest() - request.delegate = self - request.start() - } - -} - -extension Subscriptions: SKRequestDelegate { - public func requestDidFinish(_ request: SKRequest) { - if request is SKReceiptRefreshRequest { - print("Receipt refresh request finished successfully.") - // Handle successful receipt refresh here - } - } - - public func request(_ request: SKRequest, didFailWithError error: Error) { - if request is SKReceiptRefreshRequest { - print("Receipt refresh request failed with error: \(error.localizedDescription)") - // Handle receipt refresh failure here - } - } -} +} \ No newline at end of file diff --git a/ios/Plugin/SubscriptionsPlugin.swift b/ios/Plugin/SubscriptionsPlugin.swift index 78287c3..c809a21 100644 --- a/ios/Plugin/SubscriptionsPlugin.swift +++ b/ios/Plugin/SubscriptionsPlugin.swift @@ -14,90 +14,77 @@ public class SubscriptionsPlugin: CAPPlugin { @objc func echo(_ call: CAPPluginCall) { let value = call.getString("value") ?? "" - + call.resolve([ "value": value ]) } - + @available(iOS 15.0.0, *) @objc func getProductDetails(_ call: CAPPluginCall) { - - guard let productIdentifier = call.getString("productIdentifier") as? String else { - call.reject("Must provide a productID") - return; + guard let productIdentifier = call.getString("productIdentifier") else { + call.reject("Must provide a productID") + return } - async { - - let response = await implementation.getProductDetails(productIdentifier); - call.resolve(response); - + Task { + do { + let response = await implementation.getProductDetails(productIdentifier) + call.resolve(response) + } } } @available(iOS 15.0.0, *) @objc func purchaseProduct(_ call: CAPPluginCall) { - - guard let productIdentifier = call.getString("productIdentifier") as? String else { - call.reject("Must provide a productID") - return; + guard let productIdentifier = call.getString("productIdentifier") else { + call.reject("Must provide a productID") + return } - async { - - let response = await implementation.purchaseProduct(productIdentifier); - call.resolve(response); - + Task { + do { + let response = await implementation.purchaseProduct(productIdentifier) + call.resolve(response) + } } - } @available(iOS 15.0.0, *) @objc func getCurrentEntitlements(_ call: CAPPluginCall) { - - async { - - let response = await implementation.getCurrentEntitlements(); - call.resolve(response); - + Task { + do { + let response = await implementation.getCurrentEntitlements() + call.resolve(response) + } } - } + @available(iOS 15.0.0, *) @objc func getLatestTransaction(_ call: CAPPluginCall) { - - guard let productIdentifier = call.getString("productIdentifier") as? String else { - call.reject("Must provide a productID") - return; + guard let productIdentifier = call.getString("productIdentifier") else { + call.reject("Must provide a productID") + return; } - - async { - - let response = await implementation.getLatestTransaction(productIdentifier); - call.resolve(response); + Task { + do { + let response = await implementation.getLatestTransaction(productIdentifier) + call.resolve(response) + } } - } @available(iOS 15.0.0, *) @objc func manageSubscriptions(_ call: CAPPluginCall) { - - async { - + Task { do { - await implementation.manageSubscriptions(); + await implementation.manageSubscriptions() call.resolve(["Success": "Opened"]) - } catch { - print(error.localizedDescription); - call.reject(error.localizedDescription) } - } - } - -} + +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e271541..aa113ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "capacitor-subscriptions", "version": "1.0.4", "license": "none", + "dependencies": { + "@rollup/rollup-linux-arm64-gnu": "^4.21.1" + }, "devDependencies": { "@capacitor/android": "^6.0.0", "@capacitor/core": "^6.0.0", @@ -676,6 +679,34 @@ "node": ">=14" } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.2.0.tgz", + "integrity": "sha512-8PlggAxGxavr+pkCNeV1TM2wTb2o+cUWDg9M1cm9nR27Dsn287uZtSLYXoQqQcmq+sYfF7lHfd3sWJJinH9GmA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.2.0.tgz", + "integrity": "sha512-+71T85hbMFrJI+zKQULNmSYBeIhru55PYoF/u75MyeN2FcxE4HSPw20319b+FcZ4lWx2Nx/Ql9tN+hoaD3GH/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.2.0", "cpu": [ @@ -688,6 +719,130 @@ "darwin" ] }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.2.0.tgz", + "integrity": "sha512-BXcXvnLaea1Xz900omrGJhxHFJfH9jZ0CpJuVsbjjhpniJ6qiLXz3xA8Lekaa4MuhFcJd4f0r+Ky1G4VFbYhWw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.2.0.tgz", + "integrity": "sha512-f4K3MKw9Y4AKi4ANGnmPIglr+S+8tO858YrGVuqAHXxJdVghBmz9CPU9kDpOnGvT4g4vg5uNyIFpOOFvffXyMA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.1.tgz", + "integrity": "sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.2.0.tgz", + "integrity": "sha512-Jp1NxBJpGLuxRU2ihrQk4IZ+ia5nffobG6sOFUPW5PMYkF0kQtxEbeDuCa69Xif211vUOcxlOnf5IOEIpTEySA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.2.0.tgz", + "integrity": "sha512-3p3iRtQmv2aXw+vtKNyZMLOQ+LSRsqArXjKAh2Oj9cqwfIRe7OXvdkOzWfZOIp1F/x5KJzVAxGxnniF4cMbnsQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.2.0.tgz", + "integrity": "sha512-atih7IF/reUZe4LBLC5Izd44hth2tfDIG8LaPp4/cQXdHh9jabcZEvIeRPrpDq0i/Uu487Qu5gl5KwyAnWajnw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.2.0.tgz", + "integrity": "sha512-vYxF3tKJeUE4ceYzpNe2p84RXk/fGK30I8frpRfv/MyPStej/mRlojztkN7Jtd1014HHVeq/tYaMBz/3IxkxZw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.2.0.tgz", + "integrity": "sha512-1LZJ6zpl93SaPQvas618bMFarVwufWTaczH4ESAbFcwiC4OtznA6Ym+hFPyIGaJaGEB8uMWWac0uXGPXOg5FGA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.2.0.tgz", + "integrity": "sha512-dgQfFdHCNg08nM5zBmqxqc9vrm0DVzhWotpavbPa0j4//MAOKZEB75yGAfzQE9fUJ+4pvM1239Y4IhL8f6sSog==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@types/fs-extra": { "version": "8.1.4", "dev": true, @@ -2567,9 +2722,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -3004,6 +3159,20 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.2.0.tgz", + "integrity": "sha512-bNsTYQBgp4H7w6cT7FZhesxpcUPahsSIy4NgdZjH1ZwEoZHxi4XKglj+CsSEkhsKi+x6toVvMylhjRKhEMYfnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/run-parallel": { "version": "1.2.0", "dev": true, diff --git a/package.json b/package.json index 039f1b0..58500b5 100644 --- a/package.json +++ b/package.json @@ -74,5 +74,8 @@ "android": { "src": "android" } + }, + "dependencies": { + "@rollup/rollup-linux-arm64-gnu": "^4.21.1" } } diff --git a/src/definitions.ts b/src/definitions.ts index fbb671e..db5069c 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -18,9 +18,9 @@ export interface SubscriptionsPlugin { */ purchaseProduct(options: { productIdentifier: string }): Promise< PurchaseProductResponse >; - + getCurrentEntitlements(): Promise< CurrentEntitlementsResponse >; - + getLatestTransaction(options: {productIdentifier: string}): Promise< LatestTransactionResponse >; manageSubscriptions(): any; @@ -30,7 +30,7 @@ export interface SubscriptionsPlugin { addListener( eventName: 'ANDROID-PURCHASE-RESPONSE', listenerFunc: (response: AndroidPurchasedTrigger) => void, - ): Promise & PluginListenerHandle; + ): Promise; } @@ -97,7 +97,7 @@ export interface PurchaseProductResponse { export type PurchaseProductIOSResponseCode = -1 | 0 | 1 | 2 | 3 | 4 | 5 export type PurchaseProductIOSResponseMessage = -"Incompatible with web" | +"Incompatible with web" | "Successfully purchased product" | "Could not find a product matching the given productIdentifier" | "Product seems to have been purchased but the transaction failed verification" | @@ -118,7 +118,7 @@ export interface ProductDetailsResponse { } export type ProductDetailsResponseCode = -1 | 0 | 1 -export type ProductDetailsResponseMessage = +export type ProductDetailsResponseMessage = "Incompatible with web" | "Successfully found the product details for given productIdentifier" | "Could not find a product matching the given productIdentifier"