Merge remote-tracking branch 'origin/v5'

This commit is contained in:
Daniel 2019-01-23 07:54:31 +01:00
commit 898c68bb5e
313 changed files with 15065 additions and 8137 deletions

3
.gitignore vendored
View File

@ -5,4 +5,7 @@ node_modules/
aot/ aot/
scripts/ionic-native-bower scripts/ionic-native-bower
dist/ dist/
src/@ionic-native/plugins/**/ngx
*.d.ts
injectable-classes.json

View File

@ -258,29 +258,53 @@
### Bug Fixes ### Bug Fixes
* **appodeal:** removed bad imports ([7d5e7aa](https://github.com/ionic-team/ionic-native/commit/7d5e7aa))
* **file-tramsfer:** fix v5 imports for file-transfer plugin ([#2537](https://github.com/ionic-team/ionic-native/issues/2537)) ([406ad12](https://github.com/ionic-team/ionic-native/commit/406ad12))
* **healt:** add correct return type for query function ([#2565](https://github.com/ionic-team/ionic-native/issues/2565)) ([98d44e6](https://github.com/ionic-team/ionic-native/commit/98d44e6))
* **index-app-content:** add missing function ([8d57198](https://github.com/ionic-team/ionic-native/commit/8d57198))
* **index-app-content:** fix imports ([189d66c](https://github.com/ionic-team/ionic-native/commit/189d66c))
### Features
* **aes-256:** AES256 encryption and decryption plugin added ([#2562](https://github.com/ionic-team/ionic-native/issues/2562)) ([fdd6315](https://github.com/ionic-team/ionic-native/commit/fdd6315))
* **image-picker:** add DATA_URL as an option to ImagePicker ([#2325](https://github.com/ionic-team/ionic-native/issues/2325)) ([dd9ba0a](https://github.com/ionic-team/ionic-native/commit/dd9ba0a))
* **plugin:** add Sensors plugin ([#2268](https://github.com/ionic-team/ionic-native/issues/2268)) ([e61d574](https://github.com/ionic-team/ionic-native/commit/e61d574))
# [5.0.0-beta.12](https://github.com/ionic-team/ionic-native/compare/v4.8.0...v5.0.0-beta.12) (2018-06-23)
### Bug Fixes
* build errors ([f70eaea](https://github.com/ionic-team/ionic-native/commit/f70eaea))
* fix lint ([b36a1f9](https://github.com/ionic-team/ionic-native/commit/b36a1f9))
* fix more lint errors ([0b3d299](https://github.com/ionic-team/ionic-native/commit/0b3d299))
* fix rxjs 6 imports ([e0b0687](https://github.com/ionic-team/ionic-native/commit/e0b0687))
* **android-fingerprint-auth:** ensure ERRORS array is defined ([#2508](https://github.com/ionic-team/ionic-native/issues/2508)) ([714114d](https://github.com/ionic-team/ionic-native/commit/714114d)) * **android-fingerprint-auth:** ensure ERRORS array is defined ([#2508](https://github.com/ionic-team/ionic-native/issues/2508)) ([714114d](https://github.com/ionic-team/ionic-native/commit/714114d))
* **background-geolocation:** watchLocationMode returns observable ([#2547](https://github.com/ionic-team/ionic-native/issues/2547)) ([3f8a6f2](https://github.com/ionic-team/ionic-native/commit/3f8a6f2)) * **background-geolocation:** watchLocationMode returns observable ([#2547](https://github.com/ionic-team/ionic-native/issues/2547)) ([3f8a6f2](https://github.com/ionic-team/ionic-native/commit/3f8a6f2))
* **calendar:** Fixes createCalendar parameter typing ([84e0aa1](https://github.com/ionic-team/ionic-native/commit/84e0aa1)) * **calendar:** Fixes createCalendar parameter typing ([84e0aa1](https://github.com/ionic-team/ionic-native/commit/84e0aa1))
* **call-number:** fix isCallSupported function ([f49d2a9](https://github.com/ionic-team/ionic-native/commit/f49d2a9)), closes [#2428](https://github.com/ionic-team/ionic-native/issues/2428) * **call-number:** fix isCallSupported function ([f49d2a9](https://github.com/ionic-team/ionic-native/commit/f49d2a9)), closes [#2428](https://github.com/ionic-team/ionic-native/issues/2428)
* **healt:** add correct return type for query function ([#2565](https://github.com/ionic-team/ionic-native/issues/2565)) ([98d44e6](https://github.com/ionic-team/ionic-native/commit/98d44e6))
* **healths:** add missing attribute on HealthQueryOptionsAggregated ([#2550](https://github.com/ionic-team/ionic-native/issues/2550)) ([be370a4](https://github.com/ionic-team/ionic-native/commit/be370a4)) * **healths:** add missing attribute on HealthQueryOptionsAggregated ([#2550](https://github.com/ionic-team/ionic-native/issues/2550)) ([be370a4](https://github.com/ionic-team/ionic-native/commit/be370a4))
* **ibeacon:** correct Type {Region} in some params ([#2453](https://github.com/ionic-team/ionic-native/issues/2453)) ([300db62](https://github.com/ionic-team/ionic-native/commit/300db62)) * **ibeacon:** correct Type {Region} in some params ([#2453](https://github.com/ionic-team/ionic-native/issues/2453)) ([300db62](https://github.com/ionic-team/ionic-native/commit/300db62))
* **in-app-purchase-2:** fix ready method signature ([#2043](https://github.com/ionic-team/ionic-native/issues/2043)) ([a018381](https://github.com/ionic-team/ionic-native/commit/a018381)) * **in-app-purchase-2:** fix ready method signature ([#2043](https://github.com/ionic-team/ionic-native/issues/2043)) ([a018381](https://github.com/ionic-team/ionic-native/commit/a018381))
* **index-app-content:** add missing function ([8d57198](https://github.com/ionic-team/ionic-native/commit/8d57198)) * **linting:** Fixing misc linting errors that typedoc complains about ([#2476](https://github.com/ionic-team/ionic-native/issues/2476)) ([d3c2859](https://github.com/ionic-team/ionic-native/commit/d3c2859))
* **index-app-content:** fix imports ([189d66c](https://github.com/ionic-team/ionic-native/commit/189d66c)) * fix tealium jsdoc ([f34b6e6](https://github.com/ionic-team/ionic-native/commit/f34b6e6))
* **native-geocoder:** set response type to an array ([#2505](https://github.com/ionic-team/ionic-native/issues/2505)) ([defb276](https://github.com/ionic-team/ionic-native/commit/defb276)) * **native-geocoder:** set response type to an array ([#2505](https://github.com/ionic-team/ionic-native/issues/2505)) ([defb276](https://github.com/ionic-team/ionic-native/commit/defb276))
* **onesignal:** make params optional ([#2507](https://github.com/ionic-team/ionic-native/issues/2507)) ([e6db281](https://github.com/ionic-team/ionic-native/commit/e6db281)) * **onesignal:** make params optional ([#2507](https://github.com/ionic-team/ionic-native/issues/2507)) ([e6db281](https://github.com/ionic-team/ionic-native/commit/e6db281))
* **onesignal:** update OSPermissionState interface ([#2561](https://github.com/ionic-team/ionic-native/issues/2561)) ([fc088f8](https://github.com/ionic-team/ionic-native/commit/fc088f8)) * **onesignal:** update OSPermissionState interface ([#2561](https://github.com/ionic-team/ionic-native/issues/2561)) ([fc088f8](https://github.com/ionic-team/ionic-native/commit/fc088f8))
* **site:** no prepended slash ([cea1dc1](https://github.com/ionic-team/ionic-native/commit/cea1dc1)) * **site:** no prepended slash ([cea1dc1](https://github.com/ionic-team/ionic-native/commit/cea1dc1))
* **str-prnt:** rxjs 6 import ([48714d7](https://github.com/ionic-team/ionic-native/commit/48714d7))
* **stripe:** fixed casing of postal code param ([#2520](https://github.com/ionic-team/ionic-native/issues/2520)) ([d6a9ed1](https://github.com/ionic-team/ionic-native/commit/d6a9ed1)) * **stripe:** fixed casing of postal code param ([#2520](https://github.com/ionic-team/ionic-native/issues/2520)) ([d6a9ed1](https://github.com/ionic-team/ionic-native/commit/d6a9ed1))
* **themeable-browser:** allow hidden and clear cache ([a4cc7f7](https://github.com/ionic-team/ionic-native/commit/a4cc7f7)) * **themeable-browser:** allow hidden and clear cache ([a4cc7f7](https://github.com/ionic-team/ionic-native/commit/a4cc7f7))
* **v5-builder:** stop transforming "declare" classes ([#2503](https://github.com/ionic-team/ionic-native/issues/2503)) ([6662234](https://github.com/ionic-team/ionic-native/commit/6662234))
* **web-intent:** fix options param ([#2450](https://github.com/ionic-team/ionic-native/issues/2450)) ([23b760b](https://github.com/ionic-team/ionic-native/commit/23b760b)) * **web-intent:** fix options param ([#2450](https://github.com/ionic-team/ionic-native/issues/2450)) ([23b760b](https://github.com/ionic-team/ionic-native/commit/23b760b))
* **web-intent:** registerBroadcastReceiver as Observable ([#2491](https://github.com/ionic-team/ionic-native/issues/2491)) ([47f7397](https://github.com/ionic-team/ionic-native/commit/47f7397)) * **web-intent:** registerBroadcastReceiver as Observable ([#2491](https://github.com/ionic-team/ionic-native/issues/2491)) ([47f7397](https://github.com/ionic-team/ionic-native/commit/47f7397))
### Features ### Features
* **aes-256:** AES256 encryption and decryption plugin added ([#2562](https://github.com/ionic-team/ionic-native/issues/2562)) ([fdd6315](https://github.com/ionic-team/ionic-native/commit/fdd6315))
* **ble:** update wrapper to match latest plugin release ([#2548](https://github.com/ionic-team/ionic-native/issues/2548)) ([03e6afb](https://github.com/ionic-team/ionic-native/commit/03e6afb)) * **ble:** update wrapper to match latest plugin release ([#2548](https://github.com/ionic-team/ionic-native/issues/2548)) ([03e6afb](https://github.com/ionic-team/ionic-native/commit/03e6afb))
* **calldirectory:** add call directory plugin ([#2473](https://github.com/ionic-team/ionic-native/issues/2473)) ([1bfe829](https://github.com/ionic-team/ionic-native/commit/1bfe829)) * **calldirectory:** add call directory plugin ([#2473](https://github.com/ionic-team/ionic-native/issues/2473)) ([1bfe829](https://github.com/ionic-team/ionic-native/commit/1bfe829))
* **cloud-settings:** add support for cordova-plugin-cloud-settings ([#2494](https://github.com/ionic-team/ionic-native/issues/2494)) ([400dbcb](https://github.com/ionic-team/ionic-native/commit/400dbcb)) * **cloud-settings:** add support for cordova-plugin-cloud-settings ([#2494](https://github.com/ionic-team/ionic-native/issues/2494)) ([400dbcb](https://github.com/ionic-team/ionic-native/commit/400dbcb))
@ -290,12 +314,11 @@
* **firebase-config:** add firebase-config wrapper ([#2517](https://github.com/ionic-team/ionic-native/issues/2517)) ([05423ce](https://github.com/ionic-team/ionic-native/commit/05423ce)) * **firebase-config:** add firebase-config wrapper ([#2517](https://github.com/ionic-team/ionic-native/issues/2517)) ([05423ce](https://github.com/ionic-team/ionic-native/commit/05423ce))
* **firebase-messaging:** add firebase-messaging ([#2518](https://github.com/ionic-team/ionic-native/issues/2518)) ([c03b73f](https://github.com/ionic-team/ionic-native/commit/c03b73f)) * **firebase-messaging:** add firebase-messaging ([#2518](https://github.com/ionic-team/ionic-native/issues/2518)) ([c03b73f](https://github.com/ionic-team/ionic-native/commit/c03b73f))
* **hce:** add hce plugin wrapper ([#2534](https://github.com/ionic-team/ionic-native/issues/2534)) ([8460e68](https://github.com/ionic-team/ionic-native/commit/8460e68)) * **hce:** add hce plugin wrapper ([#2534](https://github.com/ionic-team/ionic-native/issues/2534)) ([8460e68](https://github.com/ionic-team/ionic-native/commit/8460e68))
* **image-picker:** add DATA_URL as an option to ImagePicker ([#2325](https://github.com/ionic-team/ionic-native/issues/2325)) ([dd9ba0a](https://github.com/ionic-team/ionic-native/commit/dd9ba0a))
* **InAppReview:** add InAppReview plugin ([#2483](https://github.com/ionic-team/ionic-native/issues/2483)) ([bfe5ae9](https://github.com/ionic-team/ionic-native/commit/bfe5ae9)) * **InAppReview:** add InAppReview plugin ([#2483](https://github.com/ionic-team/ionic-native/issues/2483)) ([bfe5ae9](https://github.com/ionic-team/ionic-native/commit/bfe5ae9))
* **ionic-webview:** plugin for cordova-plugin-ionic-webview 2.0 ([8beb177](https://github.com/ionic-team/ionic-native/commit/8beb177))
* **local-notifications:** added support for foreground option in version 0.9.0-beta.3 of cordova-plugin-local-notifications ([#2506](https://github.com/ionic-team/ionic-native/issues/2506)) ([ae6e28d](https://github.com/ionic-team/ionic-native/commit/ae6e28d)) * **local-notifications:** added support for foreground option in version 0.9.0-beta.3 of cordova-plugin-local-notifications ([#2506](https://github.com/ionic-team/ionic-native/issues/2506)) ([ae6e28d](https://github.com/ionic-team/ionic-native/commit/ae6e28d))
* **onesignal:** Added notification stacking ([#2512](https://github.com/ionic-team/ionic-native/issues/2512)) ([7c35535](https://github.com/ionic-team/ionic-native/commit/7c35535)) * **onesignal:** Added notification stacking ([#2512](https://github.com/ionic-team/ionic-native/issues/2512)) ([7c35535](https://github.com/ionic-team/ionic-native/commit/7c35535))
* **photo-library:** add maxItems to limit items-iOS ([#2554](https://github.com/ionic-team/ionic-native/issues/2554)) ([31fc892](https://github.com/ionic-team/ionic-native/commit/31fc892)) * **photo-library:** add maxItems to limit items-iOS ([#2554](https://github.com/ionic-team/ionic-native/issues/2554)) ([31fc892](https://github.com/ionic-team/ionic-native/commit/31fc892))
* **plugin:** add Sensors plugin ([#2268](https://github.com/ionic-team/ionic-native/issues/2268)) ([e61d574](https://github.com/ionic-team/ionic-native/commit/e61d574))
* **send-result:** add sendResult method for WebIntent plugin ([#2495](https://github.com/ionic-team/ionic-native/issues/2495)) ([34aeb19](https://github.com/ionic-team/ionic-native/commit/34aeb19)) * **send-result:** add sendResult method for WebIntent plugin ([#2495](https://github.com/ionic-team/ionic-native/issues/2495)) ([34aeb19](https://github.com/ionic-team/ionic-native/commit/34aeb19))
* **SiriShortcuts:** implement Siri Shortcuts plugin in Ionic ([#2542](https://github.com/ionic-team/ionic-native/issues/2542)) ([df254de](https://github.com/ionic-team/ionic-native/commit/df254de)) * **SiriShortcuts:** implement Siri Shortcuts plugin in Ionic ([#2542](https://github.com/ionic-team/ionic-native/issues/2542)) ([df254de](https://github.com/ionic-team/ionic-native/commit/df254de))
* **star-prnt:** add StarPRNT plugin ([a1e6bef](https://github.com/ionic-team/ionic-native/commit/a1e6bef)) * **star-prnt:** add StarPRNT plugin ([a1e6bef](https://github.com/ionic-team/ionic-native/commit/a1e6bef))
@ -311,9 +334,11 @@
### Bug Fixes ### Bug Fixes
* **badge:** add correct requestPermission function ([586c7e5](https://github.com/ionic-team/ionic-native/commit/586c7e5)), closes [#105](https://github.com/ionic-team/ionic-native/issues/105) [#1856](https://github.com/ionic-team/ionic-native/issues/1856) * **badge:** add correct requestPermission function ([586c7e5](https://github.com/ionic-team/ionic-native/commit/586c7e5)), closes [#105](https://github.com/ionic-team/ionic-native/issues/105) [#1856](https://github.com/ionic-team/ionic-native/issues/1856)
* **build:** fix ngx build errors ([cc9a980](https://github.com/ionic-team/ionic-native/commit/cc9a980))
* **call-log:** comments erratum ([4b9cf17](https://github.com/ionic-team/ionic-native/commit/4b9cf17)) * **call-log:** comments erratum ([4b9cf17](https://github.com/ionic-team/ionic-native/commit/4b9cf17))
* **call-log:** update getCallLog signature ([61c0ecf](https://github.com/ionic-team/ionic-native/commit/61c0ecf)) * **call-log:** update getCallLog signature ([61c0ecf](https://github.com/ionic-team/ionic-native/commit/61c0ecf))
* **contacts:** refactor wrong ContactFieldTypes ([f607a03](https://github.com/ionic-team/ionic-native/commit/f607a03)) * **contacts:** refactor wrong ContactFieldTypes ([f607a03](https://github.com/ionic-team/ionic-native/commit/f607a03))
* **core:** fix rxjs 6 build errors ([48b0f16](https://github.com/ionic-team/ionic-native/commit/48b0f16)), closes [#2439](https://github.com/ionic-team/ionic-native/issues/2439)
* **email-composer:** add missing options ([4399600](https://github.com/ionic-team/ionic-native/commit/4399600)), closes [#175](https://github.com/ionic-team/ionic-native/issues/175) * **email-composer:** add missing options ([4399600](https://github.com/ionic-team/ionic-native/commit/4399600)), closes [#175](https://github.com/ionic-team/ionic-native/issues/175)
* **facebook:** remove browserInit function ([f718432](https://github.com/ionic-team/ionic-native/commit/f718432)), closes [#1901](https://github.com/ionic-team/ionic-native/issues/1901) * **facebook:** remove browserInit function ([f718432](https://github.com/ionic-team/ionic-native/commit/f718432)), closes [#1901](https://github.com/ionic-team/ionic-native/issues/1901)
* **firebase-analytics:** add `sync` option for all methods ([42fd1f2](https://github.com/ionic-team/ionic-native/commit/42fd1f2)) * **firebase-analytics:** add `sync` option for all methods ([42fd1f2](https://github.com/ionic-team/ionic-native/commit/42fd1f2))
@ -322,6 +347,7 @@
* **image-resizer:** add missing option ([859cbfc](https://github.com/ionic-team/ionic-native/commit/859cbfc)) * **image-resizer:** add missing option ([859cbfc](https://github.com/ionic-team/ionic-native/commit/859cbfc))
* **index-app-content:** remove onItemPressed function ([270678f](https://github.com/ionic-team/ionic-native/commit/270678f)) * **index-app-content:** remove onItemPressed function ([270678f](https://github.com/ionic-team/ionic-native/commit/270678f))
* **local-notifications:** fixed linting errors ([8a26377](https://github.com/ionic-team/ionic-native/commit/8a26377)) * **local-notifications:** fixed linting errors ([8a26377](https://github.com/ionic-team/ionic-native/commit/8a26377))
* **plugins:** fix rxjs 6 build errors ([3ced31e](https://github.com/ionic-team/ionic-native/commit/3ced31e)), closes [#2439](https://github.com/ionic-team/ionic-native/issues/2439)
* **printer:** add correct npm repository ([4bf55d3](https://github.com/ionic-team/ionic-native/commit/4bf55d3)) * **printer:** add correct npm repository ([4bf55d3](https://github.com/ionic-team/ionic-native/commit/4bf55d3))
* **pro:** proper callback type and guard for plugin instantiate. [#2136](https://github.com/ionic-team/ionic-native/issues/2136) [#2127](https://github.com/ionic-team/ionic-native/issues/2127) ([61293c3](https://github.com/ionic-team/ionic-native/commit/61293c3)) * **pro:** proper callback type and guard for plugin instantiate. [#2136](https://github.com/ionic-team/ionic-native/issues/2136) [#2127](https://github.com/ionic-team/ionic-native/issues/2127) ([61293c3](https://github.com/ionic-team/ionic-native/commit/61293c3))
* **pro:** Tweak to pro plugin. [#2136](https://github.com/ionic-team/ionic-native/issues/2136) [#2127](https://github.com/ionic-team/ionic-native/issues/2127) ([c8ecee0](https://github.com/ionic-team/ionic-native/commit/c8ecee0)) * **pro:** Tweak to pro plugin. [#2136](https://github.com/ionic-team/ionic-native/issues/2136) [#2127](https://github.com/ionic-team/ionic-native/issues/2127) ([c8ecee0](https://github.com/ionic-team/ionic-native/commit/c8ecee0))

View File

@ -194,7 +194,7 @@ Checks if the plugin and property exist before getting/setting the property's va
Example: Example:
```ts ```ts
@CordovaProperty @CordovaProperty()
someProperty: string; someProperty: string;
``` ```

View File

@ -11,22 +11,26 @@ Ionic Native wraps plugin callbacks in a Promise or Observable, providing a comm
Run following command to install Ionic Native in your project. Run following command to install Ionic Native in your project.
```bash ```bash
npm install @ionic-native/core npm install @ionic-native/core@beta --save
``` ```
You also need to install the Ionic Native package for each plugin you want to add. Please see the [Ionic Native documentation](https://ionicframework.com/docs/native/) for complete instructions on how to add and use the plugins. You also need to install the Ionic Native package for each plugin you want to add. Please see the [Ionic Native documentation](https://ionicframework.com/docs/native/) for complete instructions on how to add and use the plugins.
**NOTE: to use Ionic Native v5, you must use the `@beta` tag when installing any NPM package.**
## Documentation ## Documentation
For the full Ionic Native documentation, please visit [https://ionicframework.com/docs/native/](https://ionicframework.com/docs/native/). For the full Ionic Native documentation, please visit [https://ionicframework.com/docs/native/](https://ionicframework.com/docs/native/).
### Basic Usage ### Basic Usage
#### Ionic/Angular apps
To use a plugin, import and add the plugin provider to your `@NgModule`, and then inject it where you wish to use it. To use a plugin, import and add the plugin provider to your `@NgModule`, and then inject it where you wish to use it.
Make sure to import the injectable class from the `/ngx` directory as shown in the following examples:
```typescript ```typescript
// app.module.ts // app.module.ts
import { Camera } from '@ionic-native/camera'; import { Camera } from '@ionic-native/camera/ngx';
... ...
@ -44,7 +48,7 @@ export class AppModule { }
``` ```
```typescript ```typescript
import { Geolocation } from '@ionic-native/geolocation'; import { Geolocation } from '@ionic-native/geolocation/ngx';
import { Platform } from 'ionic-angular'; import { Platform } from 'ionic-angular';
@Component({ ... }) @Component({ ... })
@ -74,16 +78,71 @@ export class MyComponent {
} }
``` ```
### Mocking and Browser Development #### ES2015+/TypeScript
These modules can work in any ES2015+/TypeScript app (including Angular/Ionic apps). To use any plugin, import the class from the appropriate package, and use it's static methods.
```js
import { Camera } from '@ionic-native/camera';
Ionic Native 3.x makes it possible to mock plugins and develop nearly the entirety of your app in the browser or in `ionic serve`. document.addEventListener('deviceready', () => {
Camera.getPicture()
.then((data) => console.log('Took a picture!', data))
.catch((e) => console.log('Error occurred while taking a picture', e));
});
```
#### AngularJS
Ionic Native generates an AngularJS module in runtime and prepares a service for each plugin. To use the plugins in your AngularJS app:
1. Download the latest bundle from the [Github releases](https://github.com/ionic-team/ionic-native/releases) page.
2. Include it in `index.html` before your app's code.
3. Inject `ionic.native` module in your app.
4. Inject any plugin you would like to use with a `$cordova` prefix.
```js
angular.module('myApp', ['ionic.native'])
.controller('MyPageController', function($cordovaCamera) {
$cordovaCamera.getPicture()
.then(
function(data) {
console.log('Took a picture!', data);
},
function(err) {
console.log('Error occurred while taking a picture', err);
}
);
});
```
#### Vanilla JS
To use Ionic Native in any other setup:
1. Download the latest bundle from the [Github releases](https://github.com/ionic-team/ionic-native/releases) page.
2. Include it in `index.html` before your app's code.
3. Access any plugin using the global `IonicNative` variable.
```js
document.addEventListener('deviceready', function() {
IonicNative.Camera.getPicture()
.then(
function(data) {
console.log('Took a picture!', data);
},
function(err) {
console.log('Error occurred while taking a picture', err);
}
);
});
```
### Mocking and Browser Development (Ionic/Angular apps only)
Ionic Native makes it possible to mock plugins and develop nearly the entirety of your app in the browser or in `ionic serve`.
To do this, you need to provide a mock implementation of the plugins you wish to use. Here's an example of mocking the `Camera` plugin to return a stock image while in development: To do this, you need to provide a mock implementation of the plugins you wish to use. Here's an example of mocking the `Camera` plugin to return a stock image while in development:
First import the `Camera` class in your `src/app/app.module.ts` file: First import the `Camera` class in your `src/app/app.module.ts` file:
```typescript ```typescript
import { Camera } from '@ionic-native/camera'; import { Camera } from '@ionic-native/camera/ngx';
``` ```
Then create a new class that extends the `Camera` class with a mock implementation: Then create a new class that extends the `Camera` class with a mock implementation:
@ -109,8 +168,11 @@ Here's the full example:
```typescript ```typescript
import { ErrorHandler, NgModule } from '@angular/core'; import { ErrorHandler, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { Camera } from '@ionic-native/camera'; import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular'; import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { Camera } from '@ionic-native/camera/ngx';
import { HomePage } from '../pages/home/home'; import { HomePage } from '../pages/home/home';
import { MyApp } from './app.component'; import { MyApp } from './app.component';
@ -146,9 +208,6 @@ Spent way too long diagnosing an issue only to realize a plugin wasn't firing or
Let us know or submit a PR! Take a look at [the Developer Guide](https://github.com/ionic-team/ionic-native/blob/master/DEVELOPER.md) for more on how to contribute. :heart: Let us know or submit a PR! Take a look at [the Developer Guide](https://github.com/ionic-team/ionic-native/blob/master/DEVELOPER.md) for more on how to contribute. :heart:
## Ionic v1 (AngularJS, Angular 1.x) support
For Ionic v1 (AngularJS, Angular 1.x) support, please use version 2 of Ionic Native. See the [2.x README](https://github.com/ionic-team/ionic-native/blob/v2.x/README.md) for usage information.
# Credits # Credits

View File

@ -33,7 +33,7 @@ jobs:
- run: bash ./scripts/git/config.sh - run: bash ./scripts/git/config.sh
- run: - run:
name: Build Ionic Native name: Build Ionic Native
command: npm run build:core && ./node_modules/.bin/tsc command: npm run build
- run: - run:
name: Generate README files to ensure docs are valid name: Generate README files to ensure docs are valid
command: npm run readmes command: npm run readmes

View File

@ -1,40 +0,0 @@
'use strict';
module.exports = config => {
const conf = {
frameworks: ['jasmine', 'karma-typescript'],
plugins: ['karma-typescript', 'karma-jasmine', 'karma-phantomjs-launcher'],
preprocessors: {
'src/**/*.ts': ['karma-typescript']
},
karmaTypescriptConfig: {
bundlerOptions: {
entrypoints: /\.spec\.ts$/,
transforms: [require('karma-typescript-es6-transform')()]
},
compilerOptions: {
lib: ['es2015', 'dom'],
paths: {
'@ionic-native/core': ['./src/@ionic-native/core']
},
baseUrl: '.'
}
},
files: [{ pattern: 'src/**/*.ts', included: true, watched: true }],
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.INFO,
autoWatch: true,
browsers: ['PhantomJS'],
singleRun: false
};
config.set(conf);
};

12473
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,40 @@
{ {
"name": "ionic-native", "name": "ionic-native",
"version": "4.20.0", "version": "5.0.0-beta.24",
"description": "Native plugin wrappers for Cordova and Ionic with TypeScript, ES6+, Promise and Observable support", "description": "Native plugin wrappers for Cordova and Ionic with TypeScript, ES6+, Promise and Observable support",
"homepage": "https://ionicframework.com/", "homepage": "https://ionicframework.com/",
"author": "Ionic Team <hi@ionic.io> (https://ionic.io)", "author": "Ionic Team <hi@ionic.io> (https://ionic.io)",
"license": "MIT", "license": "MIT",
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"build:core": "tsc -p tsconfig.core.json",
"build:esm": "ts-node -P scripts/tsconfig.json scripts/tasks/build-esm",
"build:es5": "ts-node -P scripts/tsconfig.json scripts/tasks/build-es5",
"build:ngx": "ts-node -P scripts/tsconfig.json scripts/tasks/build-ngx",
"build": "npm run build:core && npm run build:esm && npm run build:ngx && npm run build:es5",
"prebuild": "rimraf -rf dist",
"npmpub": "ts-node -P scripts/tsconfig.json scripts/tasks/publish",
"lint": "gulp lint",
"readmes": "gulp readmes",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
"postchangelog": "git commit -am \"chore(): update changelog\"",
"shipit": "npm run build && npm run readmes && npm run npmpub"
},
"devDependencies": { "devDependencies": {
"@angular/compiler": "^5.2.11", "@angular/common": "^7.2.1",
"@angular/compiler-cli": "^5.2.11", "@angular/compiler": "^7.2.1",
"@angular/core": "^5.2.11", "@angular/compiler-cli": "^7.2.1",
"@angular/core": "^7.2.1",
"@types/cordova": "0.0.34", "@types/cordova": "0.0.34",
"@types/jasmine": "2.8.9", "@types/fs-extra": "^5.0.4",
"@types/node": "8.10.20", "@types/jest": "^23.3.13",
"child-process-promise": "2.2.1", "@types/lodash": "^4.14.120",
"@types/node": "^10.12.18",
"@types/rimraf": "^2.0.2",
"@types/webpack": "^4.4.23",
"ajv": "^6.7.0",
"async-promise-queue": "^1.0.4",
"conventional-changelog-cli": "^2.0.11", "conventional-changelog-cli": "^2.0.11",
"cz-conventional-changelog": "^2.1.0", "cz-conventional-changelog": "^2.1.0",
"dgeni": "^0.4.11", "dgeni": "^0.4.11",
@ -22,40 +44,35 @@
"gulp-rename": "^1.4.0", "gulp-rename": "^1.4.0",
"gulp-replace": "^1.0.0", "gulp-replace": "^1.0.0",
"gulp-tslint": "^8.1.3", "gulp-tslint": "^8.1.3",
"jasmine-core": "2.99.1", "jest": "^23.6.0",
"karma": "^2.0.5",
"karma-cli": "^1.0.1",
"karma-jasmine": "^1.1.2",
"karma-phantomjs-launcher": "^1.0.4",
"karma-typescript": "^3.0.13",
"karma-typescript-es6-transform": "^1.0.4",
"lodash": "^4.17.11", "lodash": "^4.17.11",
"minimist": "1.2.0", "minimist": "1.2.0",
"node-html-encoder": "0.0.2", "natives": "^1.1.6",
"q": "^1.5.1",
"queue": "^4.5.1",
"rimraf": "^2.6.3", "rimraf": "^2.6.3",
"rxjs": "^5.5.12", "rxjs": "^6.3.3",
"semver": "^5.6.0", "ts-jest": "^23.10.5",
"ts-node": "^7.0.1",
"tslint": "^5.12.1", "tslint": "^5.12.1",
"tslint-ionic-rules": "0.0.21", "tslint-ionic-rules": "0.0.21",
"typescript": "~2.4.2", "typescript": "3.2.4",
"zone.js": "^0.8.28" "uglifyjs-webpack-plugin": "^2.1.1",
"unminified-webpack-plugin": "^2.0.0",
"webpack": "^4.28.4",
"winston": "^3.1.0",
"zone.js": "^0.8.26"
}, },
"scripts": { "jest": {
"start": "npm run test:watch", "transform": {
"lint": "gulp lint", "^.+\\.tsx?$": "ts-jest"
"build": "npm run clean && npm run lint && npm run build:core && npm run build:modules", },
"build:core": "ngc -p scripts/build/tsconfig-core.json", "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(js?|ts?)$",
"build:modules": "node scripts/build/build.js", "moduleFileExtensions": [
"clean": "rimraf dist .tmp", "ts",
"shipit": "npm run build && gulp readmes && npm run npmpub", "tsx",
"npmpub": "node scripts/build/publish.js", "js",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0", "jsx",
"postchangelog": "git commit -am \"chore(): update changelog\"", "json"
"test": "karma start karma.conf.js --single-run", ]
"test:watch": "karma start karma.conf.js",
"readmes": "gulp readmes"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -1,154 +0,0 @@
'use strict';
// Node module dependencies
const fs = require('fs-extra'),
queue = require('queue'),
path = require('path'),
exec = require('child_process').exec;
// Constants for the build process. Paths and JSON files templates
const ROOT = path.resolve(path.join(__dirname, '../../')), // root ionic-native directory
PLUGINS_PATH = path.resolve(ROOT, 'src/@ionic-native/plugins'), // path to plugins source files
CORE_PACKAGE_JSON = require(path.resolve(__dirname, 'core-package.json')), // core package.json
PLUGIN_PACKAGE_JSON = require(path.resolve(__dirname, 'plugin-package.json')), // plugin package.json template
PLUGIN_TS_CONFIG = require(path.resolve(__dirname, 'tsconfig-plugin.json')), // plugin tsconfig template
BUILD_TMP = path.resolve(ROOT, '.tmp'), // tmp directory path
BUILD_DIST_ROOT = path.resolve(ROOT, 'dist/@ionic-native'), // dist directory root path
BUILD_CORE_DIST = path.resolve(BUILD_DIST_ROOT, 'core'); // core dist directory path
// dependency versions
const ANGULAR_VERSION = '*',
RXJS_VERSION = '^5.5.11',
MIN_CORE_VERSION = '^4.11.0',
IONIC_NATIVE_VERSION = require(path.resolve(ROOT, 'package.json')).version;
// package dependencies
const CORE_PEER_DEPS = {
rxjs: RXJS_VERSION
};
const PLUGIN_PEER_DEPS = {
'@ionic-native/core': MIN_CORE_VERSION,
'@angular/core': ANGULAR_VERSION,
rxjs: RXJS_VERSION
};
// set peer dependencies for all plugins
PLUGIN_PACKAGE_JSON.peerDependencies = PLUGIN_PEER_DEPS;
// Create tmp/dist directories
console.log('Making new TMP directory');
fs.mkdirpSync(BUILD_TMP);
// Prepare and copy the core module's package.json
console.log('Preparing core module package.json');
CORE_PACKAGE_JSON.version = IONIC_NATIVE_VERSION;
CORE_PACKAGE_JSON.peerDependencies = CORE_PEER_DEPS;
fs.writeJsonSync(
path.resolve(BUILD_CORE_DIST, 'package.json'),
CORE_PACKAGE_JSON
);
// Fetch a list of the plugins
const PLUGINS = fs.readdirSync(PLUGINS_PATH);
// Build specific list of plugins to build from arguments, if any
let pluginsToBuild = process.argv.slice(2);
let ignoreErrors = false;
let errors = [];
const index = pluginsToBuild.indexOf('ignore-errors');
if (index > -1) {
ignoreErrors = true;
pluginsToBuild.splice(index, 1);
console.log(
'Build will continue even if errors were thrown. Errors will be printed when build finishes.'
);
}
if (!pluginsToBuild.length) {
pluginsToBuild = PLUGINS;
}
// Create a queue to process tasks
const QUEUE = queue({
concurrency: require('os').cpus().length
});
// Function to process a single plugin
const addPluginToQueue = pluginName => {
QUEUE.push(callback => {
console.log(`Building plugin: ${pluginName}`);
const PLUGIN_BUILD_DIR = path.resolve(BUILD_TMP, 'plugins', pluginName),
PLUGIN_SRC_PATH = path.resolve(PLUGINS_PATH, pluginName, 'index.ts');
let tsConfigPath;
fs.mkdirp(PLUGIN_BUILD_DIR) // create tmp build dir
.then(() => fs.mkdirp(path.resolve(BUILD_DIST_ROOT, pluginName))) // create dist dir
.then(() => {
// Write tsconfig.json
const tsConfig = JSON.parse(JSON.stringify(PLUGIN_TS_CONFIG));
tsConfig.files = [PLUGIN_SRC_PATH];
// tsConfig.compilerOptions.paths['@ionic-native/core'] = [BUILD_CORE_DIST];
tsConfigPath = path.resolve(PLUGIN_BUILD_DIR, 'tsconfig.json');
return fs.writeJson(tsConfigPath, tsConfig);
})
.then(() => {
// clone package.json
const packageJson = JSON.parse(JSON.stringify(PLUGIN_PACKAGE_JSON));
packageJson.name = `@ionic-native/${pluginName}`;
packageJson.version = IONIC_NATIVE_VERSION;
return fs.writeJson(
path.resolve(BUILD_DIST_ROOT, pluginName, 'package.json'),
packageJson
);
})
.then(() => {
// compile the plugin
exec(
`${ROOT}/node_modules/.bin/ngc -p ${tsConfigPath}`,
(err, stdout, stderr) => {
if (err) {
if (!ignoreErrors) {
// oops! something went wrong.
console.log(err);
callback(`\n\nBuilding ${pluginName} failed.`);
return;
} else {
errors.push(err);
}
}
// we're done with this plugin!
callback();
}
);
})
.catch(callback);
}); // QUEUE.push end
};
pluginsToBuild.forEach(addPluginToQueue);
QUEUE.start(err => {
if (err) {
console.log('Error building plugins.');
console.log(err);
process.stderr.write(err);
process.exit(1);
} else if (errors.length) {
errors.forEach(e => {
console.log(e.message) && console.log('\n');
process.stderr.write(err);
});
console.log('Build complete with errors');
process.exit(1);
} else {
console.log('Done processing plugins!');
}
});

View File

@ -1,14 +0,0 @@
{
"name": "@ionic-native/core",
"version": "{{VERSION}}",
"description": "Ionic Native - Native plugins for ionic apps",
"module": "index.js",
"typings": "index.d.ts",
"author": "ionic",
"license": "MIT",
"peerDependencies": {},
"repository": {
"type": "git",
"url": "https://github.com/ionic-team/ionic-native.git"
}
}

126
scripts/build/helpers.ts Normal file
View File

@ -0,0 +1,126 @@
import * as ts from 'typescript';
import * as fs from 'fs-extra';
import * as path from 'path';
import { camelCase, clone } from 'lodash';
import { Logger } from '../logger';
export const ROOT = path.resolve(__dirname, '../../');
// tslint:disable-next-line:no-var-requires
export const TS_CONFIG = clone(require(path.resolve(ROOT, 'tsconfig.json')));
export const COMPILER_OPTIONS = TS_CONFIG.compilerOptions;
export const PLUGINS_ROOT = path.join(ROOT, 'src/@ionic-native/plugins/');
export const PLUGIN_PATHS = fs.readdirSync(PLUGINS_ROOT).map(d => path.join(PLUGINS_ROOT, d, 'index.ts'));
export function getDecorator(node: ts.Node, index = 0): ts.Decorator {
if (node.decorators && node.decorators[index]) {
return node.decorators[index];
}
}
export function hasDecorator(decoratorName: string, node: ts.Node): boolean {
return node.decorators && node.decorators.length && node.decorators.findIndex(d => getDecoratorName(d) === decoratorName) > -1;
}
export function getDecoratorName(decorator: any) {
return decorator.expression.expression.text;
}
export function getRawDecoratorArgs(decorator: any): any[] {
if (decorator.expression.arguments.length === 0) return [];
return decorator.expression.arguments[0].properties;
}
export function getDecoratorArgs(decorator: any) {
const properties: any[] = getRawDecoratorArgs(decorator);
const args = {};
properties.forEach(prop => {
let val;
switch (prop.initializer.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.Identifier:
val = prop.initializer.text;
break;
case ts.SyntaxKind.ArrayLiteralExpression:
val = prop.initializer.elements.map((e: any) => e.text);
break;
case ts.SyntaxKind.TrueKeyword:
val = true;
break;
case ts.SyntaxKind.FalseKeyword:
val = false;
break;
case ts.SyntaxKind.NumericLiteral:
val = Number(prop.initializer.text);
break;
default:
Logger.debug('Unexpected property value type: ' + prop.initializer.kind);
throw new Error('Unexpected property value type << helpers.ts >>');
}
args[prop.name.text] = val;
});
return args;
}
/**
* FROM STENCIL
* Convert a js value into typescript AST
* @param val array, object, string, boolean, or number
* @returns Typescript Object Literal, Array Literal, String Literal, Boolean Literal, Numeric Literal
*/
export function convertValueToLiteral(val: any) {
if (Array.isArray(val)) {
return arrayToArrayLiteral(val);
}
if (typeof val === 'object') {
return objectToObjectLiteral(val);
}
if (typeof val === 'number') {
return ts.createNumericLiteral(String(val));
}
return ts.createLiteral(val);
}
/**
* FROM STENCIL
* Convert a js object into typescript AST
* @param obj key value object
* @returns Typescript Object Literal Expression
*/
function objectToObjectLiteral(obj: { [key: string]: any }): ts.ObjectLiteralExpression {
const newProperties: ts.ObjectLiteralElementLike[] = Object.keys(obj).map((key: string): ts.ObjectLiteralElementLike => {
return ts.createPropertyAssignment(ts.createLiteral(key), convertValueToLiteral(obj[key]) as ts.Expression);
});
return ts.createObjectLiteral(newProperties);
}
/**
* FROM STENCIL
* Convert a js array into typescript AST
* @param list array
* @returns Typescript Array Literal Expression
*/
function arrayToArrayLiteral(list: any[]): ts.ArrayLiteralExpression {
const newList: any[] = list.map(convertValueToLiteral);
return ts.createArrayLiteral(newList);
}
export function getMethodsForDecorator(decoratorName: string) {
switch (decoratorName) {
case 'CordovaProperty': return ['cordovaPropertyGet', 'cordovaPropertySet'];
case 'InstanceProperty': return ['instancePropertyGet', 'instancePropertySet'];
case 'CordovaCheck': return ['checkAvailability'];
case 'InstanceCheck': return ['instanceAvailability'];
}
return [camelCase(decoratorName)];
}

105
scripts/build/ngx.ts Normal file
View File

@ -0,0 +1,105 @@
import * as ts from 'typescript';
import * as fs from 'fs-extra';
import * as path from 'path';
import * as ngc from '@angular/compiler-cli';
import * as rimraf from 'rimraf';
import { generateDeclarations } from './transpile';
import { clone } from 'lodash';
import { EmitFlags } from '@angular/compiler-cli';
import { importsTransformer } from './transformers/imports';
import { pluginClassTransformer } from './transformers/plugin-class';
import { COMPILER_OPTIONS, PLUGIN_PATHS, ROOT } from './helpers';
export function getProgram(rootNames: string[] = createSourceFiles()) {
const options: ngc.CompilerOptions = clone(COMPILER_OPTIONS);
options.basePath = ROOT;
options.moduleResolution = ts.ModuleResolutionKind.NodeJs;
options.module = ts.ModuleKind.ES2015;
options.target = ts.ScriptTarget.ES5;
options.lib = ['dom', 'es2017'];
options.inlineSourceMap = true;
options.inlineSources = true;
delete options.baseUrl;
const host: ngc.CompilerHost = ngc.createCompilerHost({ options });
return ngc.createProgram({
rootNames,
options,
host
});
}
// hacky way to export metadata only for core package
export function transpileNgxCore() {
getProgram([path.resolve(ROOT, 'src/@ionic-native/core/index.ts')]).emit({
emitFlags: EmitFlags.Metadata,
emitCallback: ({ program, writeFile, customTransformers, cancellationToken, targetSourceFile }) =>
program.emit(targetSourceFile, writeFile, cancellationToken, true, customTransformers)
});
}
export function transpileNgx() {
getProgram().emit({
emitFlags: EmitFlags.Metadata,
customTransformers: {
beforeTs: [
importsTransformer(true),
pluginClassTransformer(true)
]
}
});
}
export function generateDeclarationFiles() {
generateDeclarations(PLUGIN_PATHS.map(p => p.replace('index.ts', 'ngx/index.ts')));
}
// remove reference to @ionic-native/core decorators
export function modifyMetadata() {
PLUGIN_PATHS.map(p => p.replace(path.join(ROOT, 'src'), path.join(ROOT, 'dist')).replace('index.ts', 'ngx/index.metadata.json'))
.forEach(p => {
const content = fs.readJSONSync(p);
let _prop;
for (const prop in content[0].metadata) {
_prop = content[0].metadata[prop];
removeIonicNativeDecorators(_prop);
if (_prop.members) {
for (const memberProp in _prop.members) {
removeIonicNativeDecorators(_prop.members[memberProp][0]);
}
}
}
fs.writeJSONSync(p, content);
});
}
function removeIonicNativeDecorators(node: any) {
if (node.decorators && node.decorators.length) {
node.decorators = node.decorators.filter((d, i) => d.expression.module !== '@ionic-native/core');
}
if (node.decorators && !node.decorators.length) delete node.decorators;
}
function createSourceFiles(): string[] {
return PLUGIN_PATHS.map((indexPath: string) => {
const ngxPath = path.resolve(indexPath.replace('index.ts', ''), 'ngx'),
newPath = path.resolve(ngxPath, 'index.ts');
// delete directory
rimraf.sync(ngxPath);
fs.mkdirpSync(ngxPath);
fs.copyFileSync(indexPath, newPath);
return newPath;
});
}
export function cleanupNgx() {
PLUGIN_PATHS.forEach((indexPath: string) =>
rimraf.sync(indexPath.replace('index.ts', 'ngx'))
);
}

View File

@ -1,14 +0,0 @@
{
"name": "@ionic-native/{{PLUGIN}}",
"version": "{{VERSION}}",
"description": "Ionic Native - Native plugins for ionic apps",
"module": "index.js",
"typings": "index.d.ts",
"author": "ionic",
"license": "MIT",
"peerDependencies": {},
"repository": {
"type": "git",
"url": "https://github.com/ionic-team/ionic-native.git"
}
}

View File

@ -1,51 +0,0 @@
'use strict';
// Node module dependencies
const fs = require('fs-extra'),
queue = require('queue'),
path = require('path'),
exec = require('child-process-promise').exec;
const ROOT = path.resolve(path.join(__dirname, '../../')),
DIST = path.resolve(ROOT, 'dist', '@ionic-native');
const FLAGS = '--access public'; // add any flags here if you want... (example: --tag alpha)
const PACKAGES = fs.readdirSync(DIST);
const failedPackages = [];
const QUEUE = queue({
concurrency: 10
});
PACKAGES.forEach(packageName => {
QUEUE.push(done => {
console.log(`Publishing @ionic-native/${packageName}`);
const packagePath = path.resolve(DIST, packageName);
exec(`npm publish ${packagePath} ${FLAGS}`)
.then(() => done())
.catch(e => {
if (
e.stderr &&
e.stderr.indexOf('previously published version') === -1
) {
failedPackages.push({
cmd: e.cmd,
stderr: e.stderr
});
}
done();
});
});
});
QUEUE.start(err => {
if (err) {
console.log('Error publishing ionic-native. ', err);
} else if (failedPackages.length > 0) {
console.log(`${failedPackages.length} packages failed to publish.`);
console.log(failedPackages);
} else {
console.log('Done publishing ionic-native!');
}
});

View File

@ -0,0 +1,2 @@
// removes the __extends method that is added automatically by typescript
module.exports = source => source.replace(/var\s__extends\s=\s\(this\s&&[\sa-z\._\(\)\|{}=:\[\]&,;?]+}\)\(\);/i, '');

View File

@ -0,0 +1,59 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import * as ts from 'typescript';
import { hasDecorator, ROOT } from '../helpers';
export interface InjectableClassEntry {
file: string;
className: string;
dirName: string;
}
const injectableClasses: InjectableClassEntry[] = [];
export const EMIT_PATH = path.resolve(ROOT, 'injectable-classes.json');
/**
* This transformer extracts all the injectable classes
* so we can use all the names later on when we compile
* an es5 bundle.
*
* Every injectable class will end up in the
* window['IonicNative'] object.
*/
export function extractInjectables() {
return (ctx: ts.TransformationContext) => {
return tsSourceFile => {
if (tsSourceFile.fileName.indexOf('src/@ionic-native/plugins') > -1) {
ts.visitEachChild(
tsSourceFile,
node => {
if (node.kind !== ts.SyntaxKind.ClassDeclaration) {
return node;
}
const isInjectable: boolean = hasDecorator('Injectable', node);
if (isInjectable) {
injectableClasses.push({
file: tsSourceFile.path,
className: (node as ts.ClassDeclaration).name.text,
dirName: tsSourceFile.path.split(/[\\\/]+/).reverse()[1]
});
}
},
ctx
);
}
return tsSourceFile;
};
};
}
export function emitInjectableClasses() {
fs.writeJSONSync(EMIT_PATH, injectableClasses);
}
export function cleanEmittedData() {
fs.unlinkSync(EMIT_PATH);
}

View File

@ -0,0 +1,69 @@
import * as ts from 'typescript';
import { getMethodsForDecorator } from '../helpers';
function transformImports(file: ts.SourceFile, ctx: ts.TransformationContext, ngcBuild?: boolean) {
// remove angular imports
if (!ngcBuild) {
file.statements = (file.statements as any).filter((s: any) => !(s.kind === ts.SyntaxKind.ImportDeclaration && s.moduleSpecifier.text === '@angular/core'));
}
// find the @ionic-native/core import statement
const importStatement = (file.statements as any).find((s: any) => {
return s.kind === ts.SyntaxKind.ImportDeclaration && s.moduleSpecifier.text === '@ionic-native/core';
});
// we're only interested in files containing @ionic-native/core import statement
if (!importStatement) return file;
const decorators: string[] = [];
const decoratorRegex: RegExp = /@([a-zA-Z]+)\(/g;
const ignored: string [] = ['Plugin', 'Component', 'Injectable'];
const keep: string [] = ['getPromise', 'checkAvailability'];
let m;
while ((m = decoratorRegex.exec(file.text)) !== null) {
if (m.index === decoratorRegex.lastIndex) {
decoratorRegex.lastIndex++;
}
if (m && m[1] && decorators.indexOf(m[1]) === -1 && ignored.indexOf(m[1]) === -1) decorators.push(m[1]);
}
if (decorators.length) {
let methods = [];
decorators.forEach(d => methods = getMethodsForDecorator(d).concat(methods));
importStatement.importClause.namedBindings.elements = [
ts.createIdentifier('IonicNativePlugin'),
...methods.map(m => ts.createIdentifier(m)),
...importStatement.importClause.namedBindings.elements.filter(el => keep.indexOf(el.name.text) !== -1)
];
if (ngcBuild) {
importStatement.importClause.namedBindings.elements = importStatement.importClause.namedBindings.elements.map(
binding => {
if (binding.escapedText) {
binding.name = {
text: binding.escapedText
};
}
return binding;
}
);
}
}
return file;
}
export function importsTransformer(ngcBuild?: boolean) {
return (ctx: ts.TransformationContext) => {
return tsSourceFile => {
return transformImports(tsSourceFile, ctx, ngcBuild);
};
};
}

View File

@ -0,0 +1,37 @@
import * as ts from 'typescript';
import { transformMethod } from './methods';
import { transformProperty } from './properties';
export function transformMembers(cls: ts.ClassDeclaration) {
const propertyIndices: number[] = [];
const members = cls.members.map((member: any, index: number) => {
// only process decorated members
if (!member.decorators || !member.decorators.length) return member;
switch (member.kind) {
case ts.SyntaxKind.MethodDeclaration:
return transformMethod(member);
case ts.SyntaxKind.PropertyDeclaration:
propertyIndices.push(index);
return member;
case ts.SyntaxKind.Constructor:
return ts.createConstructor(undefined, undefined, member.parameters, member.body);
default:
return member; // in case anything gets here by accident...
}
});
propertyIndices.forEach((i: number) => {
const [getter, setter] = transformProperty(members, i) as any;
members.push(getter, setter);
});
propertyIndices.reverse().forEach(i => members.splice(i, 1));
return members;
}

View File

@ -0,0 +1,49 @@
import * as ts from 'typescript';
import { Logger } from '../../logger';
import { convertValueToLiteral, getDecorator, getDecoratorArgs, getDecoratorName, getMethodsForDecorator } from '../helpers';
export function transformMethod(method: ts.MethodDeclaration) {
if (!method) return;
const decorator = getDecorator(method),
decoratorName = getDecoratorName(decorator),
decoratorArgs = getDecoratorArgs(decorator);
try {
return ts.createMethod(undefined, undefined, undefined, method.name, undefined, method.typeParameters, method.parameters, method.type, ts.createBlock([
ts.createReturn(
getMethodBlock(method, decoratorName, decoratorArgs)
)
]));
} catch (e) {
Logger.error('Error transforming method: ' + (method.name as any).text);
Logger.error(e.message);
}
}
function getMethodBlock(method: ts.MethodDeclaration, decoratorName: string, decoratorArgs: any): ts.Expression {
const decoratorMethod = getMethodsForDecorator(decoratorName)[0];
switch (decoratorName) {
case 'CordovaCheck':
case 'InstanceCheck':
// TODO remove function wrapper
return ts.createImmediatelyInvokedArrowFunction([ts.createIf(
ts.createBinary(
ts.createCall(ts.createIdentifier(decoratorMethod), undefined, [ts.createThis()]),
ts.SyntaxKind.EqualsEqualsEqualsToken,
ts.createTrue()
),
method.body
)]);
default:
return ts.createCall(ts.createIdentifier(decoratorMethod), undefined, [
ts.createThis(),
ts.createLiteral((method.name as any).text),
convertValueToLiteral(decoratorArgs),
ts.createIdentifier('arguments')
]);
}
}

View File

@ -0,0 +1,80 @@
import * as ts from 'typescript';
import { Logger } from '../../logger';
import {
convertValueToLiteral,
getDecorator,
getDecoratorArgs,
getDecoratorName
} from '../helpers';
import { transformMembers } from './members';
function transformClass(cls: any, ngcBuild?: boolean) {
Logger.profile('transformClass: ' + cls.name.text);
const pluginStatics = [];
const dec: any = getDecorator(cls);
if (dec) {
const pluginDecoratorArgs = getDecoratorArgs(dec);
// add plugin decorator args as static properties of the plugin's class
for (const prop in pluginDecoratorArgs) {
pluginStatics.push(
ts.createProperty(
undefined,
[ts.createToken(ts.SyntaxKind.StaticKeyword)],
ts.createIdentifier(prop),
undefined,
undefined,
convertValueToLiteral(pluginDecoratorArgs[prop])
)
);
}
}
cls = ts.createClassDeclaration(
ngcBuild && cls.decorators && cls.decorators.length
? cls.decorators.filter(d => getDecoratorName(d) === 'Injectable')
: undefined, // remove Plugin and Injectable decorators
[ts.createToken(ts.SyntaxKind.ExportKeyword)],
cls.name,
cls.typeParameters,
cls.heritageClauses,
[...transformMembers(cls), ...pluginStatics]
);
Logger.profile('transformClass: ' + cls.name.text);
return cls;
}
function transformClasses(
file: ts.SourceFile,
ctx: ts.TransformationContext,
ngcBuild?: boolean
) {
Logger.silly('Transforming file: ' + file.fileName);
return ts.visitEachChild(
file,
node => {
if (node.kind !== ts.SyntaxKind.ClassDeclaration
|| (node.modifiers && node.modifiers.find(v => v.kind === ts.SyntaxKind.DeclareKeyword))) {
return node;
}
return transformClass(node, ngcBuild);
},
ctx
);
}
export function pluginClassTransformer(
ngcBuild?: boolean
): ts.TransformerFactory<ts.SourceFile> {
return (ctx: ts.TransformationContext) => {
return tsSourceFile => {
if (tsSourceFile.fileName.indexOf('src/@ionic-native/plugins') > -1)
return transformClasses(tsSourceFile, ctx, ngcBuild);
return tsSourceFile;
};
};
}

View File

@ -0,0 +1,67 @@
import * as ts from 'typescript';
import { getDecorator, getDecoratorName } from '../helpers';
export function transformProperty(members: any[], index: number) {
const property = members[index] as ts.PropertyDeclaration,
decorator = getDecorator(property),
decoratorName = getDecoratorName(decorator);
let type: 'cordova' | 'instance';
switch (decoratorName) {
case 'CordovaProperty':
type = 'cordova';
break;
case 'InstanceProperty':
type = 'instance';
break;
default:
return property;
}
const getter = ts.createGetAccessor(
undefined,
undefined,
property.name,
undefined,
property.type,
ts.createBlock([
ts.createReturn(
ts.createCall(ts.createIdentifier(type + 'PropertyGet'), undefined, [
ts.createThis(),
ts.createLiteral((property.name as any).text)
])
)
])
);
const setter = ts.createSetAccessor(
undefined,
undefined,
property.name,
[
ts.createParameter(
undefined,
undefined,
undefined,
'value',
undefined,
property.type
)
],
ts.createBlock([
ts.createStatement(
ts.createCall(ts.createIdentifier(type + 'PropertySet'), undefined, [
ts.createThis(),
ts.createLiteral((property.name as any).text),
ts.createIdentifier('value')
])
)
])
);
return [getter, setter];
}

View File

@ -0,0 +1,51 @@
import * as ts from 'typescript';
import { pluginClassTransformer } from './transformers/plugin-class';
import { importsTransformer } from './transformers/imports';
import { clone } from 'lodash';
import { emitInjectableClasses, extractInjectables } from './transformers/extract-injectables';
import { COMPILER_OPTIONS, PLUGIN_PATHS, TS_CONFIG } from './helpers';
let host: ts.CompilerHost;
export function getCompilerHost() {
if (!host) host = ts.createCompilerHost(TS_CONFIG);
return host;
}
export function getProgram(declaration = false, pluginPaths: string[] = PLUGIN_PATHS) {
const compilerOptions: ts.CompilerOptions = clone(COMPILER_OPTIONS);
compilerOptions.declaration = declaration;
compilerOptions.moduleResolution = ts.ModuleResolutionKind.NodeJs;
compilerOptions.target = ts.ScriptTarget.ES5;
compilerOptions.module = ts.ModuleKind.ES2015;
compilerOptions.inlineSourceMap = true;
compilerOptions.inlineSources = true;
compilerOptions.lib = [
'lib.dom.d.ts',
'lib.es5.d.ts',
'lib.es2015.d.ts',
'lib.es2016.d.ts',
'lib.es2017.d.ts'
];
return ts.createProgram(pluginPaths, compilerOptions, getCompilerHost());
}
export function generateDeclarations(sourceFiles?: string[]) {
return getProgram(true, sourceFiles).emit(undefined, getCompilerHost().writeFile, undefined, true);
}
export function transpile() {
const emitResult = getProgram().emit(undefined, getCompilerHost().writeFile, undefined, false, {
before: [
extractInjectables(),
importsTransformer(),
pluginClassTransformer(),
]
});
emitInjectableClasses();
return emitResult;
}

View File

@ -1,23 +0,0 @@
{
"compilerOptions": {
"baseUrl": ".",
"declaration": true,
"stripInternal": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"module": "es2015",
"moduleResolution": "node",
"outDir": "../../../dist/@ionic-native/",
"paths": {
"@ionic-native/core": ["../../../dist/@ionic-native/core"]
},
"rootDir": "../../../src/@ionic-native/plugins/",
"target": "es5",
"skipLibCheck": true,
"lib": ["es2015", "dom"],
"sourceMap": true,
"inlineSources": true,
"noImplicitAny": true
},
"files": []
}

View File

@ -1,71 +0,0 @@
const exec = require('child-process-promise').exec;
let diff;
exec(`git branch | grep \\* | cut -d ' ' -f2`)
.then(output => {
if (output.stderr) {
return Promise.reject(output.stderr);
}
const branch = output.stdout.trim();
if (branch !== 'master') {
console.log('Merging master branch in ...');
// not on master branch
// let's test the changes that were made
return exec(`git merge origin master`);
}
})
.then(output => {
if (output && output.stderr) {
return Promise.reject(output.stderr);
}
console.log('Checking for differences ...');
return exec(`git diff --name-status origin master`);
})
.then(output => {
if (output && output.stderr) {
return Promise.reject(output.stderr);
}
diff = output.stdout;
diff = diff.replace(/A\s+/g, '');
diff = diff.match(
/src\/@ionic-native\/plugins\/([a-zA-Z0-9\-]+)\/index\.ts/g
);
if (!diff) process.exit();
console.log(
`${
diff.length
} plugins were modified. We will now build them to verify they still work.`
);
return exec('npm run build:core --silent');
})
.then(output => {
if (output && output.stderr) {
return Promise.reject(output.stderr);
}
console.log('Built core library successfully ...');
console.log('Building plugins ...');
diff = diff.map(text =>
text.replace('src/@ionic-native/plugins/', '').replace('/index.ts', '')
);
return exec(`npm run build:modules ${diff.join(' ')} --silent`);
})
.then(output => {
if (output && output.stderr) {
console.log(output.stderr);
process.exit(1);
}
console.log(output.stdout);
process.exit();
})
.catch(e => {
console.log(e.message || e);
process.exit(1);
});

View File

@ -2,5 +2,5 @@
"sitePath": "../ionic-site", "sitePath": "../ionic-site",
"v2DocsDir": "docs/native", "v2DocsDir": "docs/native",
"docsDest": "../ionic-site/content/docs/native", "docsDest": "../ionic-site/content/docs/native",
"pluginDir": "dist/@ionic-native" "pluginDir": "dist/@ionic-native/plugins"
} }

View File

@ -50,9 +50,9 @@ module.exports = currentVersion => {
// Don't run unwanted processors since we are not using the normal file reading processor // Don't run unwanted processors since we are not using the normal file reading processor
readFilesProcessor.$enabled = false; readFilesProcessor.$enabled = false;
readFilesProcessor.basePath = path.resolve(__dirname, '../..'); readFilesProcessor.basePath = path.resolve(__dirname, '../../..');
readTypeScriptModules.basePath = path.resolve(__dirname, '../..'); readTypeScriptModules.basePath = path.resolve(__dirname, '../../..');
readTypeScriptModules.sourceFiles = [ readTypeScriptModules.sourceFiles = [
'./src/@ionic-native/plugins/**/*.ts' './src/@ionic-native/plugins/**/*.ts'
]; ];

View File

@ -40,7 +40,6 @@ module.exports = currentVersion => {
computePathsProcessor.pathTemplates = [{ computePathsProcessor.pathTemplates = [{
docTypes: ['class'], docTypes: ['class'],
getOutputPath: doc => doc.originalModule.replace(config.pluginDir + '/', '') getOutputPath: doc => doc.originalModule.replace(config.pluginDir + '/', '')
.replace('/plugins', '')
.replace(/\/index$/, '/README.md') .replace(/\/index$/, '/README.md')
}]; }];
@ -50,15 +49,15 @@ module.exports = currentVersion => {
.config(function(readFilesProcessor, readTypeScriptModules) { .config(function(readFilesProcessor, readTypeScriptModules) {
// Don't run unwanted processors since we are not using the normal file reading processor // Don't run unwanted processors since we are not using the normal file reading processor
readFilesProcessor.$enabled = false; readFilesProcessor.$enabled = false;
readFilesProcessor.basePath = path.resolve(__dirname, '../..'); readFilesProcessor.basePath = path.resolve(__dirname, '../../..');
readTypeScriptModules.basePath = path.resolve(path.resolve(__dirname, '../..')); readTypeScriptModules.basePath = path.resolve(path.resolve(__dirname, '../../..'));
readTypeScriptModules.sourceFiles = ['./src/@ionic-native/plugins/**/*.ts']; readTypeScriptModules.sourceFiles = ['./src/@ionic-native/plugins/**/*.ts'];
}) })
// Configure file writing // Configure file writing
.config(function(writeFilesProcessor) { .config(function(writeFilesProcessor) {
writeFilesProcessor.outputFolder = './dist/'; writeFilesProcessor.outputFolder = './dist/@ionic-native/';
}) })
// Configure rendering // Configure rendering

View File

@ -10,7 +10,7 @@ module.exports = function readmes(renderDocsProcessor) {
docs = docs.filter(doc => (!!doc.name && !!doc.outputPath) || doc.docType === 'index-page'); docs = docs.filter(doc => (!!doc.name && !!doc.outputPath) || doc.docType === 'index-page');
docs.forEach(doc => { docs.forEach(doc => {
doc.outputPath = doc.outputPath.replace('src/', ''); doc.outputPath = doc.outputPath.replace('src/@ionic-native/', '');
}); });
return docs; return docs;

View File

@ -187,7 +187,7 @@ docType: "<$ doc.docType $>"
<ol class="installation"> <ol class="installation">
<li>Install the Cordova and Ionic Native plugins:<br> <li>Install the Cordova and Ionic Native plugins:<br>
<pre><code class="nohighlight">$ <@ if prop.install @><$ prop.install | replace('<', '&lt;').replace('>', '&gt;') $><@ else @>ionic cordova plugin add <$ prop.plugin $><@ endif @> <pre><code class="nohighlight">$ <@ if prop.install @><$ prop.install | replace('<', '&lt;').replace('>', '&gt;') $><@ else @>ionic cordova plugin add <$ prop.plugin $><@ endif @>
$ npm install --save @ionic-native/<$ doc.npmId $> $ npm install @ionic-native/<$ doc.npmId $>@beta
</code></pre> </code></pre>
</li> </li>
<li><a href="https://ionicframework.com/docs/native/#Add_Plugins_to_Your_App_Module">Add this plugin to your app's module</a></li> <li><a href="https://ionicframework.com/docs/native/#Add_Plugins_to_Your_App_Module">Add this plugin to your app's module</a></li>

View File

@ -17,7 +17,7 @@
``` ```
$ <@ if prop.install @><$ prop.install $><@ else @>ionic cordova plugin add <$ prop.plugin $><@ endif @> $ <@ if prop.install @><$ prop.install $><@ else @>ionic cordova plugin add <$ prop.plugin $><@ endif @>
$ npm install --save @ionic-native/<$ doc.npmId $> $ npm install @ionic-native/<$ doc.npmId $>@beta
``` ```
## [Usage Documentation](https://ionicframework.com/docs/native/<$ doc.fileInfo.relativePath|replace('/home/ubuntu/ionic-native/', '')|replace('//','/')|replace('index.ts','')|replace('src/@ionic-native/plugins/','') $>) ## [Usage Documentation](https://ionicframework.com/docs/native/<$ doc.fileInfo.relativePath|replace('/home/ubuntu/ionic-native/', '')|replace('//','/')|replace('index.ts','')|replace('src/@ionic-native/plugins/','') $>)

View File

@ -1,5 +1,5 @@
"use strict"; 'use strict';
const config = require('../config.json'), const config = require('./config.json'),
projectPackage = require('../../package.json'), projectPackage = require('../../package.json'),
path = require('path'), path = require('path'),
fs = require('fs-extra'), fs = require('fs-extra'),
@ -7,33 +7,36 @@ const config = require('../config.json'),
module.exports = gulp => { module.exports = gulp => {
gulp.task('docs', [], () => { gulp.task('docs', [], () => {
try { try {
const ionicPackage = require('./dgeni/dgeni-config')(
const ionicPackage = require('./dgeni-config')(projectPackage.version), projectPackage.version
),
dgeni = new Dgeni([ionicPackage]); dgeni = new Dgeni([ionicPackage]);
return dgeni.generate().then(docs => console.log(docs.length + ' docs generated')); return dgeni
.generate()
.then(docs => console.log(docs.length + ' docs generated'));
} catch (err) { } catch (err) {
console.log(err.stack); console.log(err.stack);
} }
}); });
gulp.task('readmes', [], function() { gulp.task('readmes', [], function() {
fs.copySync(
fs.copySync(path.resolve(__dirname, '..', '..', 'README.md'), path.resolve(__dirname, '..', '..', config.pluginDir, 'core', 'README.md')); path.resolve(__dirname, '..', '..', 'README.md'),
path.resolve(__dirname, '..', '..', config.pluginDir, 'core', 'README.md')
);
try { try {
const ionicPackage = require('./dgeni/dgeni-readmes-config')(
const ionicPackage = require('./dgeni-readmes-config')(projectPackage.version), projectPackage.version
),
dgeni = new Dgeni([ionicPackage]); dgeni = new Dgeni([ionicPackage]);
return dgeni.generate().then(docs => console.log(docs.length + ' README files generated')); return dgeni
.generate()
.then(docs => console.log(docs.length + ' README files generated'));
} catch (err) { } catch (err) {
console.log(err.stack); console.log(err.stack);
} }
}); });
}; };

View File

@ -31,7 +31,7 @@ function run {
# git push origin master || : # git push origin master || :
echo "-- Updated docs for $VERSION_NAME succesfully!" echo "-- Updated docs for $VERSION_NAME successfully!"
fi fi
} }

0
scripts/utils.inc.sh → scripts/docs/utils.inc.sh Executable file → Normal file
View File

11
scripts/logger.ts Normal file
View File

@ -0,0 +1,11 @@
import { createLogger, format, transports } from 'winston';
const { combine, colorize, simple } = format;
const LOG_LEVEL = 'verbose';
export const Logger = createLogger({
level: LOG_LEVEL,
format: combine(colorize(), simple()),
transports: [new transports.Console({ level: LOG_LEVEL })]
});

View File

@ -0,0 +1,97 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import * as uglifyJsPlugin from 'uglifyjs-webpack-plugin';
import * as unminifiedPlugin from 'unminified-webpack-plugin';
import * as webpack from 'webpack';
import { ROOT } from '../build/helpers';
import {
cleanEmittedData,
EMIT_PATH,
InjectableClassEntry
} from '../build/transformers/extract-injectables';
import { Logger } from '../logger';
const DIST = path.resolve(ROOT, 'dist');
const INDEX_PATH = path.resolve(DIST, 'index.js');
const INJECTABLE_CLASSES = fs
.readJSONSync(EMIT_PATH)
.map((item: InjectableClassEntry) => {
item.file =
'./' +
item.file
.split(/[\/\\]+/)
.slice(-4, -1)
.join('/');
return item;
});
const webpackConfig: webpack.Configuration = {
mode: 'production',
entry: INDEX_PATH,
devtool: 'source-map',
target: 'web',
output: {
path: DIST,
filename: 'ionic-native.min.js'
},
resolve: {
modules: ['node_modules'],
extensions: ['.js'],
alias: {
'@ionic-native/core': path.resolve(DIST, '@ionic-native/core/index.js')
}
},
module: {
rules: [
{
test: /\.js$/,
use: path.resolve(ROOT, 'scripts/build/remove-tslib-helpers.js')
}
]
},
plugins: [
new webpack.ProvidePlugin({
__extends: ['tslib', '__extends']
}),
new webpack.optimize.OccurrenceOrderPlugin(true),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new uglifyJsPlugin({
sourceMap: true
}),
new unminifiedPlugin()
]
};
function getPluginImport(entry: InjectableClassEntry) {
return `import { ${entry.className} } from '${entry.file}';`;
}
function createIndexFile() {
let fileContent = '';
fileContent += INJECTABLE_CLASSES.map(getPluginImport).join('\n');
fileContent += `\nwindow.IonicNative = {\n`;
fileContent += INJECTABLE_CLASSES.map(e => e.className).join(',\n');
fileContent += '\n};\n';
fileContent += `require('./@ionic-native/core/bootstrap').checkReady();\n`;
fileContent += `require('./@ionic-native/core/ng1').initAngular1(window.IonicNative);`;
fs.writeFileSync(INDEX_PATH, fileContent, { encoding: 'utf-8' });
}
function compile() {
Logger.profile('build-es5');
webpack(webpackConfig, (err, stats) => {
Logger.profile('build-es5');
if (err) Logger.error('Error occurred while compiling with Webpack', err);
else {
Logger.info('Compiled ES5 file with Webpack successfully.');
}
cleanEmittedData();
});
}
createIndexFile();
compile();

View File

@ -0,0 +1,46 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import { PLUGIN_PATHS, ROOT } from '../build/helpers';
import { EMIT_PATH } from '../build/transformers/extract-injectables';
import { generateDeclarations, transpile } from '../build/transpile';
generateDeclarations();
transpile();
const outDirs = PLUGIN_PATHS.map(p =>
p.replace(path.join(ROOT, 'src'), path.join(ROOT, 'dist')).replace(/[\\/]index.ts/, '')
);
const injectableClasses = fs.readJSONSync(EMIT_PATH);
outDirs.forEach(dir => {
const classes = injectableClasses.filter(
entry => entry.dirName === dir.split(/[\\/]+/).pop()
);
let jsFile: string = fs.readFileSync(path.join(dir, 'index.js'), 'utf-8'),
dtsFile: string = fs.readFileSync(path.join(dir, 'index.d.ts'), 'utf-8');
classes.forEach(entry => {
dtsFile = dtsFile.replace(
`class ${entry.className} `,
'class ' + entry.className + 'Original '
);
dtsFile += `\nexport declare const ${entry.className}: ${
entry.className
}Original;`;
jsFile = jsFile.replace(
new RegExp(`([\\s\\(])${entry.className}([\\s\\.;\\(,])`, 'g'),
'$1' + entry.className + 'Original$2'
);
jsFile = jsFile.replace(
`export { ${entry.className}Original }`,
`var ${entry.className} = new ${entry.className}Original();\nexport { ${
entry.className
} }`
);
});
fs.writeFileSync(path.join(dir, 'index.js'), jsFile, 'utf-8');
fs.writeFileSync(path.join(dir, 'index.d.ts'), dtsFile, 'utf-8');
});

View File

@ -0,0 +1,13 @@
import {
cleanupNgx,
generateDeclarationFiles,
modifyMetadata,
transpileNgx,
transpileNgxCore
} from '../build/ngx';
transpileNgxCore();
transpileNgx();
generateDeclarationFiles();
modifyMetadata();
cleanupNgx();

112
scripts/tasks/publish.ts Normal file
View File

@ -0,0 +1,112 @@
import * as Queue from 'async-promise-queue';
import { exec } from 'child_process';
import * as fs from 'fs-extra';
import { merge } from 'lodash';
import { cpus } from 'os';
import * as path from 'path';
import { PLUGIN_PATHS, ROOT } from '../build/helpers';
import { Logger } from '../logger';
// tslint:disable-next-line:no-var-requires
const MAIN_PACKAGE_JSON = require('../../package.json');
const VERSION = MAIN_PACKAGE_JSON.version;
const FLAGS = '--access public --tag beta';
const PACKAGE_JSON_BASE = {
description: 'Ionic Native - Native plugins for ionic apps',
module: 'index.js',
typings: 'index.d.ts',
author: 'ionic',
license: 'MIT',
repository: {
type: 'git',
url: 'https://github.com/ionic-team/ionic-native.git'
}
};
const DIST = path.resolve(ROOT, 'dist/@ionic-native');
const PACKAGES = [];
const RXJS_VERSION = '*';
const PLUGIN_PEER_DEPENDENCIES = {
'@ionic-native/core': VERSION, // TODO change this in production
rxjs: RXJS_VERSION
};
function getPackageJsonContent(name, peerDependencies = {}, dependencies = {}) {
return merge(PACKAGE_JSON_BASE, {
name: '@ionic-native/' + name,
dependencies,
peerDependencies,
version: VERSION
});
}
function writePackageJson(data: any, dir: string) {
const filePath = path.resolve(dir, 'package.json');
fs.writeJSONSync(filePath, data);
PACKAGES.push(dir);
}
function prepare() {
// write @ionic-native/core package.json
writePackageJson(
getPackageJsonContent('core', { rxjs: RXJS_VERSION }, { '@types/cordova': 'latest' }),
path.resolve(DIST, 'core')
);
// write plugin package.json files
PLUGIN_PATHS.forEach((pluginPath: string) => {
const pluginName = pluginPath.split(/[\/\\]+/).slice(-2)[0];
const packageJsonContents = getPackageJsonContent(
pluginName,
PLUGIN_PEER_DEPENDENCIES
);
const dir = path.resolve(DIST, 'plugins', pluginName);
writePackageJson(packageJsonContents, dir);
});
}
async function publish(ignoreErrors = false) {
Logger.profile('Publishing');
// upload 1 package per CPU thread at a time
const worker = Queue.async.asyncify((pkg: any) =>
new Promise<any>((resolve, reject) => {
exec(`npm publish ${pkg} ${FLAGS}`, (err, stdout) => {
if (stdout) {
Logger.verbose(stdout.trim());
resolve(stdout);
}
if (err) {
if (!ignoreErrors) {
if (
err.message.includes(
'You cannot publish over the previously published version'
)
) {
Logger.verbose('Ignoring duplicate version error.');
return resolve();
}
reject(err);
}
}
});
})
);
try {
await Queue(worker, PACKAGES, cpus().length);
Logger.info('Done publishing!');
} catch (e) {
Logger.error('Error publishing!');
Logger.error(e);
}
Logger.profile('Publishing');
}
prepare();
publish();

View File

@ -10,8 +10,8 @@
* *
*/ */
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Cordova, CordovaInstance, CordovaProperty, InstanceProperty, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Plugin, Cordova, CordovaProperty, CordovaInstance, InstanceProperty, IonicNativePlugin } from '@ionic-native/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs';
/** /**
* @name {{ Plugin_Name }} * @name {{ Plugin_Name }}

View File

@ -10,8 +10,8 @@
* *
*/ */
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Cordova, CordovaInstance, CordovaProperty, InstanceProperty, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Plugin, Cordova, CordovaProperty, CordovaInstance, InstanceProperty, IonicNativePlugin } from '@ionic-native/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs';
/** /**
* @name {{ Plugin_Name }} * @name {{ Plugin_Name }}

12
scripts/tsconfig.json Normal file
View File

@ -0,0 +1,12 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"moduleResolution": "node",
"noImplicitAny": false,
"lib": ["es6"]
},
"exclude": [
"node_modules"
]
}

View File

@ -16,7 +16,7 @@ export function checkReady() {
}); });
setTimeout(() => { setTimeout(() => {
if (!didFireReady && !!window.cordova) { if (!didFireReady && window.cordova) {
console.warn( console.warn(
`Ionic Native: deviceready did not fire within ${DEVICE_READY_TIMEOUT}ms. This can happen when plugins are in an inconsistent state. Try removing plugins from plugins/ and reinstalling them.` `Ionic Native: deviceready did not fire within ${DEVICE_READY_TIMEOUT}ms. This can happen when plugins are in an inconsistent state. Try removing plugins from plugins/ and reinstalling them.`
); );

View File

@ -1,251 +0,0 @@
import 'core-js';
import { Observable } from 'rxjs/Observable';
import { Cordova, CordovaCheck, CordovaInstance, CordovaProperty, InstanceProperty, Plugin } from './decorators';
import { IonicNativePlugin } from './ionic-native-plugin';
import { ERR_CORDOVA_NOT_AVAILABLE, ERR_PLUGIN_NOT_INSTALLED } from './plugin';
declare const window: any;
class TestObject {
constructor(public _objectInstance: any) {}
@InstanceProperty name: string;
@CordovaInstance({ sync: true })
pingSync(): string {
return;
}
@CordovaInstance()
ping(): Promise<any> {
return;
}
}
@Plugin({
pluginName: 'TestPlugin',
pluginRef: 'testPlugin',
repo: '',
plugin: 'cordova-plugin-my-plugin',
platforms: ['Android', 'iOS']
})
class TestPlugin extends IonicNativePlugin {
@CordovaProperty name: string;
@Cordova({ sync: true })
pingSync(): string {
return;
}
@Cordova()
ping(): Promise<string> {
return;
}
@CordovaCheck()
customPing(): Promise<string> {
return Promise.resolve('pong');
}
create(): TestObject {
return new TestObject(TestPlugin.getPlugin().create());
}
@Cordova({
destruct: true
})
destructPromise(): Promise<any> {
return;
}
@Cordova({
destruct: true,
observable: true
})
destructObservable(): Observable<any> {
return;
}
}
function definePlugin() {
(window as any).testPlugin = {
name: 'John Smith',
ping: (success: Function, error: Function) => success('pong'),
pingSync: () => 'pong',
create: function TestObject() {
this.pingSync = () => 'pong';
this.ping = (success: Function, error: Function) => success('pong');
this.name = 'John Smith';
return this;
},
destructPromise: (success: Function) => success('hello', 'world'),
destructObservable: (success: Function) => success('hello', 'world')
};
}
describe('Regular Decorators', () => {
let plugin: TestPlugin;
beforeEach(() => {
plugin = new TestPlugin();
definePlugin();
});
describe('Plugin', () => {
it('should set pluginName', () => {
expect(TestPlugin.getPluginName()).toEqual('TestPlugin');
});
it('should set pluginRef', () => {
expect(TestPlugin.getPluginRef()).toEqual('testPlugin');
});
it('should return original plugin object', () => {
expect(TestPlugin.getPlugin()).toEqual(window.testPlugin);
});
it('should return supported platforms', () => {
expect(TestPlugin.getSupportedPlatforms()).toEqual(['Android', 'iOS']);
});
});
describe('Cordova', () => {
it('should do a sync function', () => {
expect(plugin.pingSync()).toEqual('pong');
});
it('should do an async function', (done: Function) => {
plugin
.ping()
.then(res => {
expect(res).toEqual('pong');
done();
})
.catch(e => {
expect(e).toBeUndefined();
done('Method should have resolved');
});
});
it('should throw plugin_not_installed error', (done: Function) => {
delete window.testPlugin;
window.cordova = true;
expect(plugin.pingSync() as any).toEqual(ERR_PLUGIN_NOT_INSTALLED);
plugin.ping().catch(e => {
expect(e).toEqual(ERR_PLUGIN_NOT_INSTALLED.error);
delete window.cordova;
done();
});
});
xit('should throw cordova_not_available error', (done: Function) => {
delete window.testPlugin;
expect(plugin.pingSync() as any).toEqual(ERR_CORDOVA_NOT_AVAILABLE);
plugin.ping().catch(e => {
expect(e).toEqual(ERR_CORDOVA_NOT_AVAILABLE.error);
done();
});
});
});
describe('CordovaProperty', () => {
it('should return property value', () => {
expect(plugin.name).toEqual('John Smith');
});
it('should set property value', () => {
plugin.name = 'value2';
expect(plugin.name).toEqual('value2');
});
});
describe('CordovaCheck', () => {
it('should run the method when plugin exists', done => {
plugin.customPing().then(res => {
expect(res).toEqual('pong');
done();
});
});
it('shouldnt run the method when plugin doesnt exist', done => {
delete window.testPlugin;
window.cordova = true;
plugin.customPing().catch(e => {
expect(e).toEqual(ERR_PLUGIN_NOT_INSTALLED.error);
done();
});
});
});
describe('CordovaOptions', () => {
describe('destruct', () => {
it('should destruct values returned by a Promise', done => {
plugin.destructPromise().then((args: any[]) => {
expect(args).toEqual(['hello', 'world']);
done();
});
});
it('should destruct values returned by an Observable', done => {
plugin.destructObservable().subscribe((args: any[]) => {
expect(args).toEqual(['hello', 'world']);
done();
});
});
});
});
});
describe('Instance Decorators', () => {
let instance: TestObject, plugin: TestPlugin;
beforeEach(() => {
definePlugin();
plugin = new TestPlugin();
instance = plugin.create();
});
describe('Instance plugin', () => {});
describe('CordovaInstance', () => {
it('should call instance async method', done => {
instance.ping().then(r => {
expect(r).toEqual('pong');
done();
});
});
it('should call instance sync method', () => {
expect(instance.pingSync()).toEqual('pong');
});
it('shouldnt call instance method when _objectInstance is undefined', () => {
delete instance._objectInstance;
instance
.ping()
.then(r => {
expect(r).toBeUndefined();
})
.catch(e => {
expect(e).toBeUndefined();
});
});
});
describe('InstanceProperty', () => {
it('should return property value', () => {
expect(instance.name).toEqual('John Smith');
});
it('should set property value', () => {
instance.name = 'John Cena';
expect(instance.name).toEqual('John Cena');
});
});
});

View File

@ -1,326 +0,0 @@
import { Observable } from 'rxjs/Observable';
import { _throw } from 'rxjs/observable/throw';
import { checkAvailability, instanceAvailability, overrideFunction, wrap, wrapInstance } from './plugin';
import { getPlugin, getPromise } from './util';
export interface PluginConfig {
/**
* Plugin name, this should match the class name
*/
pluginName: string;
/**
* Plugin NPM package name
*/
plugin: string;
/**
* Plugin object reference
*/
pluginRef?: string;
/**
* Github repository URL
*/
repo?: string;
/**
* Custom install command
*/
install?: string;
/**
* Available installation variables
*/
installVariables?: string[];
/**
* Supported platforms
*/
platforms?: string[];
[key: string]: any;
}
export interface CordovaOptions {
destruct?: boolean;
/**
* Set to true if the wrapped method is a sync function
*/
sync?: boolean;
/**
* Callback order. Set to reverse if the success/error callbacks are the first 2 arguments that the wrapped method takes.
*/
callbackOrder?: 'reverse';
/**
* Callback style
*/
callbackStyle?: 'node' | 'object';
/**
* Set a custom index for the success callback function. This doesn't work if callbackOrder or callbackStyle are set.
*/
successIndex?: number;
/**
* Set a custom index for the error callback function. This doesn't work if callbackOrder or callbackStyle are set.
*/
errorIndex?: number;
/**
* Success function property name. This must be set if callbackStyle is set to object.
*/
successName?: string;
/**
* Error function property name. This must be set if callbackStyle is set to object.
*/
errorName?: string;
/**
* Set to true to return an observable
*/
observable?: boolean;
/**
* If observable is set to true, this can be set to a different function name that will cancel the observable.
*/
clearFunction?: string;
/**
* This can be used if clearFunction is set. Set this to true to call the clearFunction with the same arguments used in the initial function.
*/
clearWithArgs?: boolean;
/**
* Creates an observable that wraps a global event. Replaces document.addEventListener
*/
eventObservable?: boolean;
/**
* Event name, this must be set if eventObservable is set to true
*/
event?: string;
/**
* Element to attach the event listener to, this is optional, defaults to `window`
*/
element?: any;
/**
* Set to true if the wrapped method returns a promise
*/
otherPromise?: boolean;
/**
* Supported platforms
*/
platforms?: string[];
}
export interface CordovaCheckOptions {
sync?: boolean;
observable?: boolean;
}
/**
* @private
*/
export function InstanceCheck(opts: CordovaCheckOptions = {}) {
return (
pluginObj: Object,
methodName: string,
descriptor: TypedPropertyDescriptor<any>
): TypedPropertyDescriptor<any> => {
return {
value(...args: any[]): any {
if (instanceAvailability(this)) {
return descriptor.value.apply(this, args);
} else {
if (opts.sync) {
return;
} else if (opts.observable) {
return new Observable<any>(() => {});
}
return getPromise(() => {});
}
},
enumerable: true
};
};
}
/**
* Executes function only if plugin is available
* @private
*/
export function CordovaCheck(opts: CordovaCheckOptions = {}) {
return (
pluginObj: Object,
methodName: string,
descriptor: TypedPropertyDescriptor<any>
): TypedPropertyDescriptor<any> => {
return {
value(...args: any[]): any {
const check = checkAvailability(pluginObj);
if (check === true) {
return descriptor.value.apply(this, args);
} else {
if (opts.sync) {
return null;
} else if (opts.observable) {
return _throw(new Error(check && check.error));
}
return Promise.reject(check && check.error);
}
},
enumerable: true
};
};
}
/**
* @private
*
* Class decorator specifying Plugin metadata. Required for all plugins.
*
* @usage
* ```typescript
* @Plugin({
* pluginName: 'MyPlugin',
* plugin: 'cordova-plugin-myplugin',
* pluginRef: 'window.myplugin'
* })
* export class MyPlugin {
*
* // Plugin wrappers, properties, and functions go here ...
*
* }
* ```
*/
export function Plugin(config: PluginConfig): ClassDecorator {
return (cls: any) => {
// Add these fields to the class
for (const prop in config) {
cls[prop] = config[prop];
}
cls['installed'] = (printWarning?: boolean) => {
return !!getPlugin(config.pluginRef);
};
cls['getPlugin'] = () => {
return getPlugin(config.pluginRef);
};
cls['checkInstall'] = () => {
return checkAvailability(cls) === true;
};
cls['getPluginName'] = () => {
return config.pluginName;
};
cls['getPluginRef'] = () => {
return config.pluginRef;
};
cls['getPluginInstallName'] = () => {
return config.plugin;
};
cls['getPluginRepo'] = () => {
return config.repo;
};
cls['getSupportedPlatforms'] = () => {
return config.platforms;
};
return cls;
};
}
/**
* @private
*
* Wrap a stub function in a call to a Cordova plugin, checking if both Cordova
* and the required plugin are installed.
*/
export function Cordova(opts: CordovaOptions = {}) {
return (
target: Object,
methodName: string,
descriptor: TypedPropertyDescriptor<any>
) => {
return {
value(...args: any[]) {
return wrap(this, methodName, opts).apply(this, args);
},
enumerable: true
};
};
}
/**
* @private
*
* Wrap an instance method
*/
export function CordovaInstance(opts: CordovaOptions = {}) {
return (target: Object, methodName: string) => {
return {
value(...args: any[]) {
return wrapInstance(this, methodName, opts).apply(this, args);
},
enumerable: true
};
};
}
/**
* @private
*
*
* Before calling the original method, ensure Cordova and the plugin are installed.
*/
export function CordovaProperty(target: any, key: string) {
Object.defineProperty(target, key, {
enumerable: true,
get: () => {
if (checkAvailability(target, key) === true) {
return getPlugin(target.constructor.getPluginRef())[key];
} else {
return null;
}
},
set: value => {
if (checkAvailability(target, key) === true) {
getPlugin(target.constructor.getPluginRef())[key] = value;
}
}
});
}
/**
* @private
* @param target
* @param key
* @constructor
*/
export function InstanceProperty(target: any, key: string) {
Object.defineProperty(target, key, {
enumerable: true,
get() {
return this._objectInstance[key];
},
set(value) {
this._objectInstance[key] = value;
}
});
}
/**
* @private
*
* Wrap a stub function in a call to a Cordova plugin, checking if both Cordova
* and the required plugin are installed.
*/
export function CordovaFunctionOverride(opts: any = {}) {
return (
target: Object,
methodName: string,
descriptor: TypedPropertyDescriptor<any>
) => {
return {
value(...args: any[]) {
return overrideFunction(this, methodName, opts);
},
enumerable: true
};
};
}

View File

@ -0,0 +1,108 @@
import { callCordovaPlugin, wrapPromise } from './common';
declare const window: any;
class MockPlugin {
static getPluginRef(): string {
return 'mockPlugin';
}
static getPluginName(): string {
return 'MockPlugin';
}
static getPluginInstallName(): string {
return '';
}
create(): MockInstancePluginObject {
return new MockInstancePluginObject();
}
}
class MockInstancePluginObject {
_pluginInstance: MockCordovaPlugin;
constructor() {
this._pluginInstance = new MockCordovaPlugin();
}
}
class MockCordovaPlugin {
static ping = jest.fn((arg: string) => 'pong');
static pingAsync = jest.fn(
(arg: string, success: Function, error: Function) => success('pong')
);
ping = jest.fn((arg: string) => 'pong');
pingAsync = jest.fn((arg: string, success: Function, error: Function) =>
success('pong')
);
}
describe('Common decorator functions', () => {
let plugin: MockPlugin, instancePluginObject: MockInstancePluginObject;
beforeAll(() => {
window.mockPlugin = MockCordovaPlugin;
plugin = new MockPlugin();
instancePluginObject = plugin.create();
});
describe('callCordovaPlugin', () => {
test('should return value from cordova plugin', () => {
expect(callCordovaPlugin(plugin, 'ping', ['pingpong'])).toBe('pong');
});
test('original method should have been called', () => {
expect(MockCordovaPlugin.ping.mock.calls.length).toBe(1);
});
test('original method should have received args', () => {
expect(MockCordovaPlugin.ping.mock.calls[0][0]).toBe('pingpong');
});
});
describe('wrapPromise', () => {
test('should return a promise that resolves with a value', async () => {
expect(await wrapPromise(plugin, 'pingAsync', ['pingpong'])).toBe('pong');
});
test('original method should have been called', () => {
expect(MockCordovaPlugin.pingAsync.mock.calls.length).toBe(1);
});
test('original method should have received args', () => {
expect(MockCordovaPlugin.pingAsync.mock.calls[0][0]).toBe('pingpong');
expect(typeof MockCordovaPlugin.pingAsync.mock.calls[0][1]).toBe(
'function'
);
expect(typeof MockCordovaPlugin.pingAsync.mock.calls[0][2]).toBe(
'function'
);
});
});
describe('wrapObservable', () => {
test('should return an observable that emits a value', async () => {});
test('original method should have been called', () => {});
test('original method should have received args', () => {});
});
describe('wrapEventObservable', () => {
test('should return an observable that wraps an event listener', async () => {});
});
describe('callInstance', () => {
test('should call an instance method', async () => {});
test('original method should have been called', () => {
// expect(instancePluginObject._pluginInstance.ping.mock.calls.length).toBe(1);
});
test('original method should have received args', () => {
// expect(instancePluginObject._pluginInstance.ping.mock.calls[0][0]).toBe('pingpong');
});
});
});

View File

@ -1,179 +1,50 @@
import { Observable } from 'rxjs/Observable'; import { Observable, fromEvent } from 'rxjs';
import { fromEvent } from 'rxjs/observable/fromEvent';
import { checkReady } from './bootstrap'; import { CordovaOptions } from './interfaces';
import { CordovaOptions } from './decorators';
import { cordovaWarn, getPlugin, getPromise, pluginWarn } from './util';
checkReady(); declare const window: any;
// declare const window;
// declare var Promise;
export const ERR_CORDOVA_NOT_AVAILABLE = { error: 'cordova_not_available' }; export const ERR_CORDOVA_NOT_AVAILABLE = { error: 'cordova_not_available' };
export const ERR_PLUGIN_NOT_INSTALLED = { error: 'plugin_not_installed' }; export const ERR_PLUGIN_NOT_INSTALLED = { error: 'plugin_not_installed' };
/** export function getPromise<T>(
* Checks if plugin/cordova is available callback: (resolve: Function, reject?: Function) => any
* @return {boolean | { error: string } } ): Promise<T> {
* @private const tryNativePromise = () => {
*/ if (Promise) {
export function checkAvailability( return new Promise<T>((resolve, reject) => {
pluginRef: string, callback(resolve, reject);
methodName?: string, });
pluginName?: string
): boolean | { error: string };
export function checkAvailability(
pluginObj: any,
methodName?: string,
pluginName?: string
): boolean | { error: string };
export function checkAvailability(
plugin: any,
methodName?: string,
pluginName?: string
): boolean | { error: string } {
let pluginRef, pluginInstance, pluginPackage;
if (typeof plugin === 'string') {
pluginRef = plugin;
} else {
pluginRef = plugin.constructor.getPluginRef();
pluginName = plugin.constructor.getPluginName();
pluginPackage = plugin.constructor.getPluginInstallName();
}
pluginInstance = getPlugin(pluginRef);
if (
!pluginInstance ||
(!!methodName && typeof pluginInstance[methodName] === 'undefined')
) {
if (!window.cordova) {
cordovaWarn(pluginName, methodName);
return ERR_CORDOVA_NOT_AVAILABLE;
}
pluginWarn(pluginName, pluginPackage, methodName);
return ERR_PLUGIN_NOT_INSTALLED;
}
return true;
}
/**
* Checks if _objectInstance exists and has the method/property
* @private
*/
export function instanceAvailability(
pluginObj: any,
methodName?: string
): boolean {
return (
pluginObj._objectInstance &&
(!methodName ||
typeof pluginObj._objectInstance[methodName] !== 'undefined')
);
}
function setIndex(
args: any[],
opts: any = {},
resolve?: Function,
reject?: Function
): any {
// ignore resolve and reject in case sync
if (opts.sync) {
return args;
}
// If the plugin method expects myMethod(success, err, options)
if (opts.callbackOrder === 'reverse') {
// Get those arguments in the order [resolve, reject, ...restOfArgs]
args.unshift(reject);
args.unshift(resolve);
} else if (opts.callbackStyle === 'node') {
args.push((err: any, result: any) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
} else if (
opts.callbackStyle === 'object' &&
opts.successName &&
opts.errorName
) {
const obj: any = {};
obj[opts.successName] = resolve;
obj[opts.errorName] = reject;
args.push(obj);
} else if (
typeof opts.successIndex !== 'undefined' ||
typeof opts.errorIndex !== 'undefined'
) {
const setSuccessIndex = () => {
// If we've specified a success/error index
if (opts.successIndex > args.length) {
args[opts.successIndex] = resolve;
} else {
args.splice(opts.successIndex, 0, resolve);
}
};
const setErrorIndex = () => {
// We don't want that the reject cb gets spliced into the position of an optional argument that has not been defined and thus causing non expected behaviour.
if (opts.errorIndex > args.length) {
args[opts.errorIndex] = reject; // insert the reject fn at the correct specific index
} else {
args.splice(opts.errorIndex, 0, reject); // otherwise just splice it into the array
}
};
if (opts.successIndex > opts.errorIndex) {
setErrorIndex();
setSuccessIndex();
} else { } else {
setSuccessIndex(); console.error(
setErrorIndex(); 'No Promise support or polyfill found. To enable Ionic Native support, please add the es6-promise polyfill before this script, or run with a library like Angular or on a recent browser.'
);
} }
} else { };
// Otherwise, let's tack them on to the end of the argument list
// which is 90% of cases if (window.angular) {
args.push(resolve); const injector = window.angular
args.push(reject); .element(document.querySelector('[ng-app]') || document.body)
.injector();
if (injector) {
const $q = injector.get('$q');
return $q((resolve: Function, reject: Function) => {
callback(resolve, reject);
});
}
console.warn(
`Angular 1 was detected but $q couldn't be retrieved. This is usually when the app is not bootstrapped on the html or body tag. Falling back to native promises which won't trigger an automatic digest when promises resolve.`
);
} }
return args;
return tryNativePromise();
} }
function callCordovaPlugin( export function wrapPromise(
pluginObj: any, pluginObj: any,
methodName: string, methodName: string,
args: any[], args: any[],
opts: any = {}, opts: CordovaOptions = {}
resolve?: Function,
reject?: Function
) {
// Try to figure out where the success/error callbacks need to be bound
// to our promise resolve/reject handlers.
args = setIndex(args, opts, resolve, reject);
const availabilityCheck = checkAvailability(pluginObj, methodName);
if (availabilityCheck === true) {
const pluginInstance = getPlugin(pluginObj.constructor.getPluginRef());
return pluginInstance[methodName].apply(pluginInstance, args);
} else {
return availabilityCheck;
}
}
function wrapPromise(
pluginObj: any,
methodName: string,
args: any[],
opts: any = {}
) { ) {
let pluginResult: any, rej: Function; let pluginResult: any, rej: Function;
const p = getPromise((resolve: Function, reject: Function) => { const p = getPromise((resolve: Function, reject: Function) => {
@ -288,7 +159,176 @@ function wrapObservable(
}); });
} }
function callInstance( /**
* Wrap the event with an observable
* @private
* @param event even name
* @param element The element to attach the event listener to
* @returns {Observable}
*/
function wrapEventObservable(event: string, element: any): Observable<any> {
element = element ? get(window, element) : window;
return fromEvent(element, event);
}
/**
* Checks if plugin/cordova is available
* @return {boolean | { error: string } }
* @private
*/
export function checkAvailability(
pluginRef: string,
methodName?: string,
pluginName?: string
): boolean | { error: string };
export function checkAvailability(
pluginObj: any,
methodName?: string,
pluginName?: string
): boolean | { error: string };
export function checkAvailability(
plugin: any,
methodName?: string,
pluginName?: string
): boolean | { error: string } {
let pluginRef, pluginInstance, pluginPackage;
if (typeof plugin === 'string') {
pluginRef = plugin;
} else {
pluginRef = plugin.constructor.getPluginRef();
pluginName = plugin.constructor.getPluginName();
pluginPackage = plugin.constructor.getPluginInstallName();
}
pluginInstance = getPlugin(pluginRef);
if (
!pluginInstance ||
(!!methodName && typeof pluginInstance[methodName] === 'undefined')
) {
if (!window.cordova) {
cordovaWarn(pluginName, methodName);
return ERR_CORDOVA_NOT_AVAILABLE;
}
pluginWarn(pluginName, pluginPackage, methodName);
return ERR_PLUGIN_NOT_INSTALLED;
}
return true;
}
/**
* Checks if _objectInstance exists and has the method/property
* @private
*/
export function instanceAvailability(
pluginObj: any,
methodName?: string
): boolean {
return (
pluginObj._objectInstance &&
(!methodName ||
typeof pluginObj._objectInstance[methodName] !== 'undefined')
);
}
export function setIndex(
args: any[],
opts: any = {},
resolve?: Function,
reject?: Function
): any {
// ignore resolve and reject in case sync
if (opts.sync) {
return args;
}
// If the plugin method expects myMethod(success, err, options)
if (opts.callbackOrder === 'reverse') {
// Get those arguments in the order [resolve, reject, ...restOfArgs]
args.unshift(reject);
args.unshift(resolve);
} else if (opts.callbackStyle === 'node') {
args.push((err: any, result: any) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
} else if (
opts.callbackStyle === 'object' &&
opts.successName &&
opts.errorName
) {
const obj: any = {};
obj[opts.successName] = resolve;
obj[opts.errorName] = reject;
args.push(obj);
} else if (
typeof opts.successIndex !== 'undefined' ||
typeof opts.errorIndex !== 'undefined'
) {
const setSuccessIndex = () => {
// If we've specified a success/error index
if (opts.successIndex > args.length) {
args[opts.successIndex] = resolve;
} else {
args.splice(opts.successIndex, 0, resolve);
}
};
const setErrorIndex = () => {
// We don't want that the reject cb gets spliced into the position of an optional argument that has not been
// defined and thus causing non expected behavior.
if (opts.errorIndex > args.length) {
args[opts.errorIndex] = reject; // insert the reject fn at the correct specific index
} else {
args.splice(opts.errorIndex, 0, reject); // otherwise just splice it into the array
}
};
if (opts.successIndex > opts.errorIndex) {
setErrorIndex();
setSuccessIndex();
} else {
setSuccessIndex();
setErrorIndex();
}
} else {
// Otherwise, let's tack them on to the end of the argument list
// which is 90% of cases
args.push(resolve);
args.push(reject);
}
return args;
}
export function callCordovaPlugin(
pluginObj: any,
methodName: string,
args: any[],
opts: any = {},
resolve?: Function,
reject?: Function
) {
// Try to figure out where the success/error callbacks need to be bound
// to our promise resolve/reject handlers.
args = setIndex(args, opts, resolve, reject);
const availabilityCheck = checkAvailability(pluginObj, methodName);
if (availabilityCheck === true) {
const pluginInstance = getPlugin(pluginObj.constructor.getPluginRef());
return pluginInstance[methodName].apply(pluginInstance, args);
} else {
return availabilityCheck;
}
}
export function callInstance(
pluginObj: any, pluginObj: any,
methodName: string, methodName: string,
args: any[], args: any[],
@ -306,52 +346,76 @@ function callInstance(
} }
} }
/** export function getPlugin(pluginRef: string): any {
* Wrap the event with an observable return get(window, pluginRef);
* @private
* @param event even name
* @param element The element to attach the event listener to
* @returns {Observable}
*/
export function wrapEventObservable(
event: string,
element: any = window
): Observable<any> {
return fromEvent(element, event);
} }
/** export function get(element: Element | Window, path: string) {
* Certain plugins expect the user to override methods in the plugin. For example, const paths: string[] = path.split('.');
* window.cordova.plugins.backgroundMode.onactivate = function() { ... }. let obj: any = element;
* for (let i = 0; i < paths.length; i++) {
* Unfortunately, this is brittle and would be better wrapped as an Observable. overrideFunction if (!obj) {
* does just this. return null;
* @private
*/
export function overrideFunction(
pluginObj: any,
methodName: string,
args: any[],
opts: any = {}
): Observable<any> {
return new Observable(observer => {
const availabilityCheck = checkAvailability(
pluginObj,
null,
pluginObj.constructor.getPluginName()
);
if (availabilityCheck === true) {
const pluginInstance = getPlugin(pluginObj.constructor.getPluginRef());
pluginInstance[methodName] = observer.next.bind(observer);
return () => (pluginInstance[methodName] = () => {});
} else {
observer.error(availabilityCheck);
observer.complete();
} }
}); obj = obj[paths[i]];
}
return obj;
} }
export function pluginWarn(
pluginName: string,
plugin?: string,
method?: string
): void {
if (method) {
console.warn(
'Native: tried calling ' +
pluginName +
'.' +
method +
', but the ' +
pluginName +
' plugin is not installed.'
);
} else {
console.warn(
`Native: tried accessing the ${pluginName} plugin but it's not installed.`
);
}
if (plugin) {
console.warn(
`Install the ${pluginName} plugin: 'ionic cordova plugin add ${plugin}'`
);
}
}
/**
* @private
* @param pluginName
* @param method
*/
export function cordovaWarn(pluginName: string, method?: string): void {
if (method) {
console.warn(
'Native: tried calling ' +
pluginName +
'.' +
method +
', but Cordova is not available. Make sure to include cordova.js or run in a device/simulator'
);
} else {
console.warn(
'Native: tried accessing the ' +
pluginName +
' plugin but Cordova is not available. Make sure to include cordova.js or run in a device/simulator'
);
}
}
// Fixes a bug in TypeScript 2.9.2 where the ...args is being converted into args: {} and
// causing compilation issues
export type WrapFn = (...args: any[]) => any;
/** /**
* @private * @private
*/ */
@ -359,7 +423,7 @@ export const wrap = (
pluginObj: any, pluginObj: any,
methodName: string, methodName: string,
opts: CordovaOptions = {} opts: CordovaOptions = {}
) => { ): WrapFn => {
return (...args: any[]) => { return (...args: any[]) => {
if (opts.sync) { if (opts.sync) {
// Sync doesn't wrap the plugin with a promise or observable, it returns the result as-is // Sync doesn't wrap the plugin with a promise or observable, it returns the result as-is
@ -383,7 +447,7 @@ export function wrapInstance(
pluginObj: any, pluginObj: any,
methodName: string, methodName: string,
opts: any = {} opts: any = {}
) { ): Function {
return (...args: any[]) => { return (...args: any[]) => {
if (opts.sync) { if (opts.sync) {
return callInstance(pluginObj, methodName, args, opts); return callInstance(pluginObj, methodName, args, opts);
@ -413,7 +477,6 @@ export function wrapInstance(
if (pluginResult && pluginResult.error) { if (pluginResult && pluginResult.error) {
observer.error(pluginResult.error); observer.error(pluginResult.error);
observer.complete();
} }
return () => { return () => {
@ -461,7 +524,7 @@ export function wrapInstance(
reject reject
); );
} }
if (result && !!result.then) { if (result && result.then) {
result.then(resolve, reject); result.then(resolve, reject);
} else { } else {
reject(); reject();

View File

@ -0,0 +1,25 @@
import { Observable, Observer } from 'rxjs';
import { checkAvailability, getPlugin } from './common';
function overrideFunction(pluginObj: any, methodName: string): Observable<any> {
return new Observable((observer: Observer<any>) => {
const availabilityCheck = checkAvailability(pluginObj, methodName);
if (availabilityCheck === true) {
const pluginInstance = getPlugin(pluginObj.constructor.getPluginRef());
pluginInstance[methodName] = observer.next.bind(observer);
return () => (pluginInstance[methodName] = () => {});
} else {
observer.error(availabilityCheck);
observer.complete();
}
});
}
export function cordovaFunctionOverride(
pluginObj: any,
methodName: string,
args: IArguments | any[] = []
) {
return overrideFunction(pluginObj, methodName);
}

View File

@ -0,0 +1,7 @@
import { wrapInstance } from './common';
import { CordovaOptions } from './interfaces';
export function cordovaInstance(pluginObj: any, methodName: string, config: CordovaOptions, args: IArguments | any[]) {
args = Array.from(args);
return wrapInstance(pluginObj, methodName, config).apply(this, args);
}

View File

@ -0,0 +1,14 @@
import { checkAvailability, getPlugin } from './common';
export function cordovaPropertyGet(pluginObj: any, key: string) {
if (checkAvailability(pluginObj, key) === true) {
return getPlugin(pluginObj.constructor.getPluginRef())[key];
}
return null;
}
export function cordovaPropertySet(pluginObj: any, key: string, value: any) {
if (checkAvailability(pluginObj, key) === true) {
getPlugin(pluginObj.constructor.getPluginRef())[key] = value;
}
}

View File

@ -0,0 +1,6 @@
import { wrap } from './common';
import { CordovaOptions } from './interfaces';
export function cordova(pluginObj: any, methodName: string, config: CordovaOptions, args: IArguments | any[]) {
return wrap(pluginObj, methodName, config).apply(this, args);
}

View File

@ -0,0 +1,12 @@
export function instancePropertyGet(pluginObj: any, key: string) {
if (pluginObj._objectInstance && pluginObj._objectInstance[key]) {
return pluginObj._objectInstance[key];
}
return null;
}
export function instancePropertySet(pluginObj: any, key: string, value: any) {
if (pluginObj._objectInstance) {
pluginObj._objectInstance[key] = value;
}
}

View File

@ -0,0 +1,107 @@
export interface PluginConfig {
/**
* Plugin name, this should match the class name
*/
pluginName: string;
/**
* Plugin NPM package name
*/
plugin: string;
/**
* Plugin object reference
*/
pluginRef?: string;
/**
* Github repository URL
*/
repo?: string;
/**
* Custom install command
*/
install?: string;
/**
* Available installation variables
*/
installVariables?: string[];
/**
* Supported platforms
*/
platforms?: string[];
[key: string]: any;
}
export interface CordovaOptions {
destruct?: boolean;
/**
* Set to true if the wrapped method is a sync function
*/
sync?: boolean;
/**
* Callback order. Set to reverse if the success/error callbacks are the first 2 arguments that the wrapped method
* takes.
*/
callbackOrder?: 'reverse';
/**
* Callback style
*/
callbackStyle?: 'node' | 'object';
/**
* Set a custom index for the success callback function. This doesn't work if callbackOrder or callbackStyle are set.
*/
successIndex?: number;
/**
* Set a custom index for the error callback function. This doesn't work if callbackOrder or callbackStyle are set.
*/
errorIndex?: number;
/**
* Success function property name. This must be set if callbackStyle is set to object.
*/
successName?: string;
/**
* Error function property name. This must be set if callbackStyle is set to object.
*/
errorName?: string;
/**
* Set to true to return an observable
*/
observable?: boolean;
/**
* If observable is set to true, this can be set to a different function name that will cancel the observable.
*/
clearFunction?: string;
/**
* This can be used if clearFunction is set. Set this to true to call the clearFunction with the same arguments used
* in the initial function.
*/
clearWithArgs?: boolean;
/**
* Creates an observable that wraps a global event. Replaces document.addEventListener
*/
eventObservable?: boolean;
/**
* Event name, this must be set if eventObservable is set to true
*/
event?: string;
/**
* Element to attach the event listener to, this is optional, defaults to `window`
*/
element?: any;
/**
* Set to true if the wrapped method returns a promise
*/
otherPromise?: boolean;
/**
* Supported platforms
*/
platforms?: string[];
}
export declare const Plugin: (config: PluginConfig) => ClassDecorator;
export declare const Cordova: (config?: CordovaOptions) => MethodDecorator;
export declare const CordovaProperty: () => PropertyDecorator;
export declare const CordovaInstance: (config?: CordovaOptions) => MethodDecorator;
export declare const InstanceProperty: () => PropertyDecorator;
export declare const CordovaCheck: (config?: CordovaOptions) => MethodDecorator;
export declare const InstanceCheck: (config?: CordovaOptions) => MethodDecorator;
export declare const CordovaFunctionOverride: () => MethodDecorator;

View File

@ -1,4 +1,14 @@
export * from './plugin'; import { checkReady } from './bootstrap';
export * from './decorators';
export * from './util'; export { IonicNativePlugin } from './ionic-native-plugin';
export * from './ionic-native-plugin';
// Decorators
export { checkAvailability, instanceAvailability, wrap, getPromise } from './decorators/common';
export * from './decorators/cordova';
export * from './decorators/cordova-function-override';
export * from './decorators/cordova-instance';
export * from './decorators/cordova-property';
export * from './decorators/instance-property';
export * from './decorators/interfaces';
checkReady();

View File

@ -1,74 +0,0 @@
// This is to verify that new (FileTransfer.getPlugin)() works
import { CordovaInstance, Plugin } from './decorators';
import { IonicNativePlugin } from './ionic-native-plugin';
import { checkAvailability } from './plugin';
class FT {
hello(): string {
return 'world';
}
}
(window as any).FileTransfer = () => new FT();
@Plugin({
plugin: 'cordova-plugin-file-transfer',
pluginRef: 'FileTransfer',
repo: '',
pluginName: 'FileTransfer'
})
export class FileTransfer extends IonicNativePlugin {
create(): FileTransferObject {
let instance: any;
if (
checkAvailability(
FileTransfer.getPluginRef(),
null,
FileTransfer.getPluginName()
) === true
) {
instance = new (FileTransfer.getPlugin())();
}
return new FileTransferObject(instance);
}
}
export class FileTransferObject {
constructor(public _objectInstance: any) {
console.info(
'Creating a new FileTransferObject with instance: ',
_objectInstance
);
}
@CordovaInstance({ sync: true })
hello(): string {
return;
}
}
describe('Mock FileTransfer Plugin', () => {
let plugin: FileTransfer, instance: FileTransferObject;
beforeAll(() => {
plugin = new FileTransfer();
instance = plugin.create();
});
it('should create a new FileTransfer plugin instance', () => {
expect(plugin instanceof FileTransfer).toBeTruthy();
});
it('should create new FileTransferObject instance', () => {
expect(instance instanceof FileTransferObject).toBeTruthy();
});
it('FileTransferObject instance should have _objectInstance property', () => {
expect(instance._objectInstance).toBeDefined();
});
it('FileTransferObject.hello should return world', () => {
console.info('instance hello is', instance.hello());
expect(instance.hello()).toEqual('world');
});
});

View File

@ -1,3 +1,6 @@
import { checkAvailability } from './decorators/common';
import { get } from './util';
export class IonicNativePlugin { export class IonicNativePlugin {
static pluginName: string; static pluginName: string;
@ -15,40 +18,31 @@ export class IonicNativePlugin {
* Returns a boolean that indicates whether the plugin is installed * Returns a boolean that indicates whether the plugin is installed
* @return {boolean} * @return {boolean}
*/ */
static installed(): boolean { static installed(): boolean { return checkAvailability(this.pluginRef) === true; }
return false;
}
/** /**
* Returns the original plugin object * Returns the original plugin object
*/ */
static getPlugin(): any {} static getPlugin(): any { return get(window, this.pluginRef); }
/** /**
* Returns the plugin's name * Returns the plugin's name
*/ */
static getPluginName(): string { static getPluginName(): string { return this.pluginName; }
return;
}
/** /**
* Returns the plugin's reference * Returns the plugin's reference
*/ */
static getPluginRef(): string { static getPluginRef(): string { return this.pluginRef; }
return;
}
/** /**
* Returns the plugin's install name * Returns the plugin's install name
*/ */
static getPluginInstallName(): string { static getPluginInstallName(): string { return this.plugin; }
return;
}
/** /**
* Returns the plugin's supported platforms * Returns the plugin's supported platforms
*/ */
static getSupportedPlatforms(): string[] { static getSupportedPlatforms(): string[] { return this.platforms || []; }
return;
}
} }

View File

@ -0,0 +1,27 @@
declare const window: any;
/**
* Initialize the ionic.native Angular module if we're running in ng1.
* This iterates through the list of registered plugins and dynamically
* creates Angular 1 services of the form $cordovaSERVICE, ex: $cordovaStatusBar.
*/
export function initAngular1(plugins: any) {
if (window.angular) {
const ngModule = window.angular.module('ionic.native', []);
for (const name in plugins) {
const serviceName = '$cordova' + name;
const cls = plugins[name];
((serviceName, cls, name) => {
ngModule.service(serviceName, [
() => {
const funcs = window.angular.copy(cls);
funcs.__proto__['name'] = name;
return funcs;
}
]);
})(serviceName, cls, name);
}
}
}

View File

@ -3,25 +3,24 @@ declare const window: any;
/** /**
* @private * @private
*/ */
export const get = (element: Element | Window, path: string): any => { export function get(element: Element | Window, path: string) {
const paths: string[] = path.split('.'); const paths: string[] = path.split('.');
let obj: any = element; let obj: any = element;
for (let i = 0; i < paths.length; i++) { for (let i = 0; i < paths.length; i++) {
if (!obj) { if (!obj) { return null; }
return null;
}
obj = obj[paths[i]]; obj = obj[paths[i]];
} }
return obj; return obj;
}; }
/** /**
* @private * @private
*/ */
export const getPromise = (callback: Function): Promise<any> => { export function getPromise(callback: Function = () => {}): Promise<any> {
const tryNativePromise = () => { const tryNativePromise = () => {
if (window.Promise) { if (window.Promise) {
return new Promise((resolve, reject) => { return new Promise<any>((resolve, reject) => {
callback(resolve, reject); callback(resolve, reject);
}); });
} else { } else {
@ -32,66 +31,4 @@ export const getPromise = (callback: Function): Promise<any> => {
}; };
return tryNativePromise(); return tryNativePromise();
}; }
/**
* @private
* @param pluginRef
* @returns {null|*}
*/
export const getPlugin = (pluginRef: string): any => {
return get(window, pluginRef);
};
/**
* @private
*/
export const pluginWarn = (
pluginName: string,
plugin?: string,
method?: string
): void => {
if (method) {
console.warn(
'Ionic Native: tried calling ' +
pluginName +
'.' +
method +
', but the ' +
pluginName +
' plugin is not installed.'
);
} else {
console.warn(
`'Ionic Native: tried accessing the ${pluginName} plugin but it's not installed.`
);
}
if (plugin) {
console.warn(
`Install the ${pluginName} plugin: 'ionic cordova plugin add ${plugin}'`
);
}
};
/**
* @private
* @param pluginName
* @param method
*/
export const cordovaWarn = (pluginName: string, method?: string): void => {
if (method) {
console.warn(
'Ionic Native: tried calling ' +
pluginName +
'.' +
method +
', but Cordova is not available. Make sure to a) run in a real device or simulator and b) include cordova.js in your index.html'
);
} else {
console.warn(
'Native: tried accessing the ' +
pluginName +
' plugin but Cordova is not available. Make sure to a) run in a real device or simulator and b) include cordova.js in your index.html'
);
}
};

View File

@ -268,7 +268,7 @@ export interface DataCaptureResult {
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AbbyyRTR } from '@ionic-native/abbyy-rtr'; * import { AbbyyRTR } from '@ionic-native/abbyy-rtr/ngx';
* *
* *
* constructor(private abbyyRTR: AbbyyRTR) { } * constructor(private abbyyRTR: AbbyyRTR) { }

View File

@ -62,7 +62,7 @@ export interface ActionSheetOptions {
* *
* @usage * @usage
* ```typescript * ```typescript
* import { ActionSheet, ActionSheetOptions } from '@ionic-native/action-sheet'; * import { ActionSheet, ActionSheetOptions } from '@ionic-native/action-sheet/ngx';
* *
* constructor(private actionSheet: ActionSheet) { } * constructor(private actionSheet: ActionSheet) { }
* *
@ -79,7 +79,7 @@ export interface ActionSheetOptions {
* addDestructiveButtonWithLabel: 'Delete', * addDestructiveButtonWithLabel: 'Delete',
* androidTheme: this.actionSheet.ANDROID_THEMES.THEME_HOLO_DARK, * androidTheme: this.actionSheet.ANDROID_THEMES.THEME_HOLO_DARK,
* destructiveButtonLast: true * destructiveButtonLast: true
* }; * }
* *
* this.actionSheet.show(options).then((buttonIndex: number) => { * this.actionSheet.show(options).then((buttonIndex: number) => {
* console.log('Button pressed: ' + buttonIndex); * console.log('Button pressed: ' + buttonIndex);

View File

@ -263,7 +263,7 @@ export enum AdjustLogLevel {
* *
* @usage * @usage
* ```typescript * ```typescript
* import { Adjust, AdjustConfig, AdjustEnvironment } from '@ionic-native/adjust'; * import { Adjust, AdjustConfig, AdjustEnvironment } from '@ionic-native/adjust/ngx';
* *
* constructor(private adjust: Adjust) { } * constructor(private adjust: Adjust) { }
* *

View File

@ -1,7 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
import { Observable } from 'rxjs/Observable'; import { Observable, fromEvent } from 'rxjs';
import { fromEvent } from 'rxjs/observable/fromEvent';
export interface AdMobFreeBannerConfig { export interface AdMobFreeBannerConfig {
/** /**
@ -73,7 +72,7 @@ export interface AdMobFreeRewardVideoConfig {
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AdMobFree, AdMobFreeBannerConfig } from '@ionic-native/admob-free'; * import { AdMobFree, AdMobFreeBannerConfig } from '@ionic-native/admob-free/ngx';
* *
* *
* constructor(private admobFree: AdMobFree) { } * constructor(private admobFree: AdMobFree) { }
@ -179,7 +178,7 @@ export class AdMobFree extends IonicNativePlugin {
plugin: 'cordova-plugin-admob-free', plugin: 'cordova-plugin-admob-free',
pluginRef: 'admob.banner' pluginRef: 'admob.banner'
}) })
export class AdMobFreeBanner { export class AdMobFreeBanner extends IonicNativePlugin {
/** /**
* Update config * Update config
* @param options * @param options
@ -235,7 +234,7 @@ export class AdMobFreeBanner {
plugin: 'cordova-plugin-admob-free', plugin: 'cordova-plugin-admob-free',
pluginRef: 'admob.interstitial' pluginRef: 'admob.interstitial'
}) })
export class AdMobFreeInterstitial { export class AdMobFreeInterstitial extends IonicNativePlugin {
/** /**
* Update config * Update config
* @param options * @param options
@ -282,7 +281,7 @@ export class AdMobFreeInterstitial {
plugin: 'cordova-plugin-admob-free', plugin: 'cordova-plugin-admob-free',
pluginRef: 'admob.rewardvideo' pluginRef: 'admob.rewardvideo'
}) })
export class AdMobFreeRewardVideo { export class AdMobFreeRewardVideo extends IonicNativePlugin {
/** /**
* Update config * Update config
* @param {AdMobFreeRewardVideoConfig} options Admob reward config * @param {AdMobFreeRewardVideoConfig} options Admob reward config

View File

@ -1,7 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
import { Observable } from 'rxjs/Observable'; import { Observable, fromEvent } from 'rxjs';
import { fromEvent } from 'rxjs/observable/fromEvent';
export type AdUnitIDOption = string | { export type AdUnitIDOption = string | {
android: string; android: string;

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs';
export type AdSize = export type AdSize =
| 'SMART_BANNER' | 'SMART_BANNER'
@ -106,8 +106,8 @@ export interface AdExtras {
* IMPORTANT NOTICE: this plugin takes a percentage out of your earnings if you profit more than $1,000. Read more about this on the plugin's repo. For a completely free alternative, see [AdMobPro Free](../admob-free). * IMPORTANT NOTICE: this plugin takes a percentage out of your earnings if you profit more than $1,000. Read more about this on the plugin's repo. For a completely free alternative, see [AdMobPro Free](../admob-free).
* @usage * @usage
* ```typescript * ```typescript
* import { AdMobPro } from '@ionic-native/admob-pro'; * import { AdMobPro } from '@ionic-native/admob-pro/ngx';
* import { Platform } from 'ionic-angular'; * import { Platform } from '@ionic/angular';
* *
* constructor(private admob: AdMobPro, private platform: Platform ) { } * constructor(private admob: AdMobPro, private platform: Platform ) { }
* *
@ -275,7 +275,7 @@ export class AdMobPro extends IonicNativePlugin {
@Cordova({ @Cordova({
eventObservable: true, eventObservable: true,
event: 'onAdFailLoad', event: 'onAdFailLoad',
element: document element: 'document'
}) })
onAdFailLoad(): Observable<any> { onAdFailLoad(): Observable<any> {
return; return;
@ -288,7 +288,7 @@ export class AdMobPro extends IonicNativePlugin {
@Cordova({ @Cordova({
eventObservable: true, eventObservable: true,
event: 'onAdLoaded', event: 'onAdLoaded',
element: document element: 'document'
}) })
onAdLoaded(): Observable<any> { onAdLoaded(): Observable<any> {
return; return;
@ -301,7 +301,7 @@ export class AdMobPro extends IonicNativePlugin {
@Cordova({ @Cordova({
eventObservable: true, eventObservable: true,
event: 'onAdPresent', event: 'onAdPresent',
element: document element: 'document'
}) })
onAdPresent(): Observable<any> { onAdPresent(): Observable<any> {
return; return;
@ -314,7 +314,7 @@ export class AdMobPro extends IonicNativePlugin {
@Cordova({ @Cordova({
eventObservable: true, eventObservable: true,
event: 'onAdLeaveApp', event: 'onAdLeaveApp',
element: document element: 'document'
}) })
onAdLeaveApp(): Observable<any> { onAdLeaveApp(): Observable<any> {
return; return;
@ -327,7 +327,7 @@ export class AdMobPro extends IonicNativePlugin {
@Cordova({ @Cordova({
eventObservable: true, eventObservable: true,
event: 'onAdDismiss', event: 'onAdDismiss',
element: document element: 'document'
}) })
onAdDismiss(): Observable<any> { onAdDismiss(): Observable<any> {
return; return;

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Cordova, CordovaProperty, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Cordova, CordovaProperty, IonicNativePlugin, Plugin } from '@ionic-native/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs';
export interface AdmobOptions { export interface AdmobOptions {
/** /**
@ -93,7 +93,7 @@ export interface AdmobOptions {
* *
* @usage * @usage
* ```typescript * ```typescript
* import { Admob, AdmobOptions } from '@ionic-native/admob'; * import { Admob, AdmobOptions } from '@ionic-native/admob/ngx';
* *
* *
* constructor(private admob: Admob) { * constructor(private admob: Admob) {
@ -246,7 +246,7 @@ export class Admob extends IonicNativePlugin {
* Use one of these constants as adSize option when calling createBannerView * Use one of these constants as adSize option when calling createBannerView
* @readonly * @readonly
*/ */
@CordovaProperty @CordovaProperty()
readonly AD_SIZE: { readonly AD_SIZE: {
BANNER: string; BANNER: string;
IAB_MRECT: string; IAB_MRECT: string;
@ -259,7 +259,7 @@ export class Admob extends IonicNativePlugin {
* This enum represents AdMob's supported ad types * This enum represents AdMob's supported ad types
* @readonly * @readonly
*/ */
@CordovaProperty @CordovaProperty()
readonly AD_TYPE: { readonly AD_TYPE: {
BANNER: string; BANNER: string;
INTERSTITIAL: string; INTERSTITIAL: string;

View File

@ -10,7 +10,7 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AES256 } from '@ionic-native/aes-256'; * import { AES256 } from '@ionic-native/aes-256/ngx';
* *
* private secureKey: string; * private secureKey: string;
* private secureIV: string; * private secureIV: string;
@ -56,7 +56,6 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
}) })
@Injectable() @Injectable()
export class AES256 extends IonicNativePlugin { export class AES256 extends IonicNativePlugin {
/** /**
* This function used to perform the aes256 encryption * This function used to perform the aes256 encryption
* @param {string} secureKey A 32 bytes string, which will used as input key for AES256 encryption. * @param {string} secureKey A 32 bytes string, which will used as input key for AES256 encryption.

View File

@ -10,7 +10,7 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
* *
* @usage * @usage
* ```typescript * ```typescript
* import { Alipay } from '@ionic-native/alipay'; * import { Alipay } from '@ionic-native/alipay/ngx';
* *
* constructor(private alipay: Alipay) { * constructor(private alipay: Alipay) {
* *

View File

@ -67,7 +67,7 @@ export class AnalyticsFirebase extends IonicNativePlugin {
* Use one of these default events or a custom event * Use one of these default events or a custom event
* @readonly * @readonly
*/ */
@CordovaProperty @CordovaProperty()
readonly DEFAULT_EVENTS: { readonly DEFAULT_EVENTS: {
ADD_PAYMENT_INFO: string; ADD_PAYMENT_INFO: string;
ADD_TO_CART: string; ADD_TO_CART: string;
@ -107,7 +107,7 @@ export class AnalyticsFirebase extends IonicNativePlugin {
* Use one of these default params or a custom param * Use one of these default params or a custom param
* @readonly * @readonly
*/ */
@CordovaProperty @CordovaProperty()
readonly DEFAULT_PARAMS: { readonly DEFAULT_PARAMS: {
ACHIEVEMENT_ID: string; ACHIEVEMENT_ID: string;
ACLID: string; ACLID: string;

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs';
export type AndroidExoPlayerAspectRatio = 'FILL_SCREEN' | 'FIT_SCREEN'; export type AndroidExoPlayerAspectRatio = 'FILL_SCREEN' | 'FIT_SCREEN';
@ -158,7 +158,7 @@ export interface AndroidExoPlayerControllerConfig {
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AndroidExoPlayer } from '@ionic-native/android-exoplayer'; * import { AndroidExoPlayer } from '@ionic-native/android-exoplayer/ngx';
* *
* constructor(private androidExoPlayer: AndroidExoPlayer) { } * constructor(private androidExoPlayer: AndroidExoPlayer) { }
* *

View File

@ -110,7 +110,7 @@ export interface AFADeleteOptions {
* This plugin will open a native dialog fragment prompting the user to authenticate using their fingerprint. If the device has a secure lockscreen (pattern, PIN, or password), the user may opt to authenticate using that method as a backup. * This plugin will open a native dialog fragment prompting the user to authenticate using their fingerprint. If the device has a secure lockscreen (pattern, PIN, or password), the user may opt to authenticate using that method as a backup.
* @usage * @usage
* ```typescript * ```typescript
* import { AndroidFingerprintAuth } from '@ionic-native/android-fingerprint-auth'; * import { AndroidFingerprintAuth } from '@ionic-native/android-fingerprint-auth/ngx';
* *
* constructor(private androidFingerprintAuth: AndroidFingerprintAuth) { } * constructor(private androidFingerprintAuth: AndroidFingerprintAuth) { }
* *

View File

@ -3,7 +3,7 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
/** /**
* Bit flag values for setSystemUiVisibility() * Bit flag values for setSystemUiVisibility()
* @see https://developer.android.com/reference/android/view/View.html#setSystemUiVisibility(int) * @see https://developer.android.com/reference/android/view/View.html#setSystemUiVisibility(int)
*/ */
export enum AndroidSystemUiFlags { export enum AndroidSystemUiFlags {
/** View has requested the system UI (status bar) to be visible (the default). SYSTEM_UI_FLAG_VISIBLE */ /** View has requested the system UI (status bar) to be visible (the default). SYSTEM_UI_FLAG_VISIBLE */
@ -36,7 +36,7 @@ export enum AndroidSystemUiFlags {
* In Android 4.4+, however, you can now enter true full screen, fully interactive immersive mode. In this mode, your app will remain in true full screen until you choose otherwise; users can swipe down from the top of the screen to temporarily display the system UI. * In Android 4.4+, however, you can now enter true full screen, fully interactive immersive mode. In this mode, your app will remain in true full screen until you choose otherwise; users can swipe down from the top of the screen to temporarily display the system UI.
* @usage * @usage
* ```typescript * ```typescript
* import { AndroidFullScreen } from '@ionic-native/android-full-screen'; * import { AndroidFullScreen } from '@ionic-native/android-full-screen/ngx';
* *
* constructor(private androidFullScreen: AndroidFullScreen) { } * constructor(private androidFullScreen: AndroidFullScreen) { }
* *
@ -62,63 +62,81 @@ export class AndroidFullScreen extends IonicNativePlugin {
* @return {Promise<void>} * @return {Promise<void>}
*/ */
@Cordova() @Cordova()
isSupported(): Promise<void> { return; } isSupported(): Promise<void> {
return;
}
/** /**
* Is immersive mode supported? * Is immersive mode supported?
* @return {Promise<void>} * @return {Promise<void>}
*/ */
@Cordova() @Cordova()
isImmersiveModeSupported(): Promise<void> { return; } isImmersiveModeSupported(): Promise<void> {
return;
}
/** /**
* The width of the screen in immersive mode. * The width of the screen in immersive mode.
* @return {Promise<number>} * @return {Promise<number>}
*/ */
@Cordova() @Cordova()
immersiveWidth(): Promise<number> { return; } immersiveWidth(): Promise<number> {
return;
}
/** /**
* The height of the screen in immersive mode. * The height of the screen in immersive mode.
* @return {Promise<number>} * @return {Promise<number>}
*/ */
@Cordova() @Cordova()
immersiveHeight(): Promise<number> { return; } immersiveHeight(): Promise<number> {
return;
}
/** /**
* Hide system UI until user interacts. * Hide system UI until user interacts.
* @return {Promise<void>} * @return {Promise<void>}
*/ */
@Cordova() @Cordova()
leanMode(): Promise<void> { return; } leanMode(): Promise<void> {
return;
}
/** /**
* Show system UI. * Show system UI.
* @return {Promise<void>} * @return {Promise<void>}
*/ */
@Cordova() @Cordova()
showSystemUI(): Promise<void> { return; } showSystemUI(): Promise<void> {
return;
}
/** /**
* Extend your app underneath the status bar (Android 4.4+ only). * Extend your app underneath the status bar (Android 4.4+ only).
* @return {Promise<void>} * @return {Promise<void>}
*/ */
@Cordova() @Cordova()
showUnderStatusBar(): Promise<void> { return; } showUnderStatusBar(): Promise<void> {
return;
}
/** /**
* Extend your app underneath the system UI (Android 4.4+ only). * Extend your app underneath the system UI (Android 4.4+ only).
* @return {Promise<void>} * @return {Promise<void>}
*/ */
@Cordova() @Cordova()
showUnderSystemUI(): Promise<void> { return; } showUnderSystemUI(): Promise<void> {
return;
}
/** /**
* Hide system UI and keep it hidden (Android 4.4+ only). * Hide system UI and keep it hidden (Android 4.4+ only).
* @return {Promise<void>} * @return {Promise<void>}
*/ */
@Cordova() @Cordova()
immersiveMode(): Promise<void> { return; } immersiveMode(): Promise<void> {
return;
}
/** /**
* Manually set the the system UI to a custom mode. This mirrors the Android method of the same name. (Android 4.4+ only). * Manually set the the system UI to a custom mode. This mirrors the Android method of the same name. (Android 4.4+ only).
@ -127,5 +145,7 @@ export class AndroidFullScreen extends IonicNativePlugin {
* @return {Promise<void>} * @return {Promise<void>}
*/ */
@Cordova() @Cordova()
setSystemUiVisibility(visibility: AndroidSystemUiFlags): Promise<void> { return; } setSystemUiVisibility(visibility: AndroidSystemUiFlags): Promise<void> {
return;
}
} }

View File

@ -10,7 +10,7 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
* *
* @usage * @usage
* ``` * ```
* import { AndroidPermissions } from '@ionic-native/android-permissions'; * import { AndroidPermissions } from '@ionic-native/android-permissions/ngx';
* *
* *
* constructor(private androidPermissions: AndroidPermissions) { } * constructor(private androidPermissions: AndroidPermissions) { }
@ -223,7 +223,7 @@ export class AndroidPermissions extends IonicNativePlugin {
/** /**
* Request permissions * Request permissions
* @param {Array<string>} permissions An array with permissions * @param {string[]} permissions An array with permissions
* @return {Promise<any>} Returns a promise * @return {Promise<any>} Returns a promise
*/ */
@Cordova() @Cordova()

View File

@ -10,7 +10,7 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AppAvailability } from '@ionic-native/app-availability'; * import { AppAvailability } from '@ionic-native/app-availability/ngx';
* import { Platform } from 'ionic-angular'; * import { Platform } from 'ionic-angular';
* *
* constructor(private appAvailability: AppAvailability, private platform: Platform) { } * constructor(private appAvailability: AppAvailability, private platform: Platform) { }
@ -48,6 +48,8 @@ export class AppAvailability extends IonicNativePlugin {
* @returns {Promise<boolean>} * @returns {Promise<boolean>}
*/ */
@Cordova() @Cordova()
check(app: string): Promise<boolean> { return; } check(app: string): Promise<boolean> {
return;
}
} }

View File

@ -17,7 +17,7 @@ export interface StringMap {
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AppCenterAnalytics } from '@ionic-native/app-center-analytics'; * import { AppCenterAnalytics } from '@ionic-native/app-center-analytics/ngx';
* *
* *
* constructor(private appCenterAnalytics: AppCenterAnalytics) { } * constructor(private appCenterAnalytics: AppCenterAnalytics) { }

View File

@ -40,7 +40,7 @@ export interface AppCenterCrashReportDevice {
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AppCenterCrashes } from '@ionic-native/app-center-crashes'; * import { AppCenterCrashes } from '@ionic-native/app-center-crashes/ngx';
* *
* *
* constructor(private AppCenterCrashes: AppCenterCrashes) { } * constructor(private AppCenterCrashes: AppCenterCrashes) { }

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs';
/** /**
* @name App Center Push * @name App Center Push
@ -10,7 +10,7 @@ import { Observable } from 'rxjs/Observable';
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AppCenterPush } from '@ionic-native/app-center-push'; * import { AppCenterPush } from '@ionic-native/app-center-push/ngx';
* *
* *
* constructor(private appCenterPush: AppCenterPush) { } * constructor(private appCenterPush: AppCenterPush) { }

View File

@ -8,8 +8,8 @@ import { Injectable } from '@angular/core';
* *
* @usage * @usage
* ```typescript * ```typescript
* import { Platfrom } from 'ionic-angular'; * import { Platfrom } from '@ionic/angular';
* import { AppMinimize } from '@ionic-native/app-minimize'; * import { AppMinimize } from '@ionic-native/app-minimize/ngx';
* *
* *
* constructor(private platform: Platform, private appMinimize: AppMinimize) { } * constructor(private platform: Platform, private appMinimize: AppMinimize) { }
@ -37,6 +37,8 @@ export class AppMinimize extends IonicNativePlugin {
* @return {Promise<any>} * @return {Promise<any>}
*/ */
@Cordova() @Cordova()
minimize(): Promise<any> { return; } minimize(): Promise<any> {
return;
}
} }

View File

@ -1,5 +1,5 @@
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
/** /**
@ -9,7 +9,7 @@ import { Injectable } from '@angular/core';
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AppPreferences } from '@ionic-native/app-preferences'; * import { AppPreferences } from '@ionic-native/app-preferences/ngx';
* *
* constructor(private appPreferences: AppPreferences) { } * constructor(private appPreferences: AppPreferences) { }
* *
@ -25,11 +25,18 @@ import { Injectable } from '@angular/core';
plugin: 'cordova-plugin-app-preferences', plugin: 'cordova-plugin-app-preferences',
pluginRef: 'plugins.appPreferences', pluginRef: 'plugins.appPreferences',
repo: 'https://github.com/apla/me.apla.cordova.app-preferences', repo: 'https://github.com/apla/me.apla.cordova.app-preferences',
platforms: ['Android', 'BlackBerry 10', 'Browser', 'iOS', 'macOS', 'Windows 8', 'Windows Phone'] platforms: [
'Android',
'BlackBerry 10',
'Browser',
'iOS',
'macOS',
'Windows 8',
'Windows Phone'
]
}) })
@Injectable() @Injectable()
export class AppPreferences extends IonicNativePlugin { export class AppPreferences extends IonicNativePlugin {
/** /**
* Get a preference value * Get a preference value
* *
@ -40,7 +47,9 @@ export class AppPreferences extends IonicNativePlugin {
@Cordova({ @Cordova({
callbackOrder: 'reverse' callbackOrder: 'reverse'
}) })
fetch(dict: string, key?: string): Promise<any> { return; } fetch(dict: string, key?: string): Promise<any> {
return;
}
/** /**
* Set a preference value * Set a preference value
@ -67,7 +76,9 @@ export class AppPreferences extends IonicNativePlugin {
@Cordova({ @Cordova({
callbackOrder: 'reverse' callbackOrder: 'reverse'
}) })
remove(dict: string, key?: string): Promise<any> { return; } remove(dict: string, key?: string): Promise<any> {
return;
}
/** /**
* Clear preferences * Clear preferences
@ -77,7 +88,9 @@ export class AppPreferences extends IonicNativePlugin {
@Cordova({ @Cordova({
callbackOrder: 'reverse' callbackOrder: 'reverse'
}) })
clearAll(): Promise<any> { return; } clearAll(): Promise<any> {
return;
}
/** /**
* Show native preferences interface * Show native preferences interface
@ -87,7 +100,9 @@ export class AppPreferences extends IonicNativePlugin {
@Cordova({ @Cordova({
callbackOrder: 'reverse' callbackOrder: 'reverse'
}) })
show(): Promise<any> { return; } show(): Promise<any> {
return;
}
/** /**
* Show native preferences interface * Show native preferences interface
@ -98,7 +113,9 @@ export class AppPreferences extends IonicNativePlugin {
@Cordova({ @Cordova({
observable: true observable: true
}) })
watch(subscribe: boolean): Observable<any> { return; } watch(subscribe: boolean): Observable<any> {
return;
}
/** /**
* Return named configuration context * Return named configuration context
@ -111,13 +128,17 @@ export class AppPreferences extends IonicNativePlugin {
platforms: ['Android'], platforms: ['Android'],
sync: true sync: true
}) })
suite(suiteName: string): any { return; } suite(suiteName: string): any {
return;
}
@Cordova({ @Cordova({
platforms: ['iOS'], platforms: ['iOS'],
sync: true sync: true
}) })
iosSuite(suiteName: string): any { return; } iosSuite(suiteName: string): any {
return;
}
/** /**
* Return cloud synchronized configuration context * Return cloud synchronized configuration context
@ -127,7 +148,9 @@ export class AppPreferences extends IonicNativePlugin {
@Cordova({ @Cordova({
platforms: ['iOS', 'Windows', 'Windows Phone 8'] platforms: ['iOS', 'Windows', 'Windows Phone 8']
}) })
cloudSync(): Object { return; } cloudSync(): Object {
return;
}
/** /**
* Return default configuration context * Return default configuration context
@ -137,6 +160,7 @@ export class AppPreferences extends IonicNativePlugin {
@Cordova({ @Cordova({
platforms: ['iOS', 'Windows', 'Windows Phone 8'] platforms: ['iOS', 'Windows', 'Windows Phone 8']
}) })
defaults(): Object { return; } defaults(): Object {
return;
}
} }

View File

@ -134,7 +134,7 @@ export interface AppUrls {
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AppRate } from '@ionic-native/app-rate'; * import { AppRate } from '@ionic-native/app-rate/ngx';
* *
* constructor(private appRate: AppRate) { } * constructor(private appRate: AppRate) { }
* *
@ -144,7 +144,7 @@ export interface AppUrls {
* ios: '<app_id>', * ios: '<app_id>',
* android: 'market://details?id=<package_name>', * android: 'market://details?id=<package_name>',
* windows: 'ms-windows-store://review/?ProductId=<store_id>' * windows: 'ms-windows-store://review/?ProductId=<store_id>'
* }; * }
* *
* this.appRate.promptForRating(true); * this.appRate.promptForRating(true);
* *
@ -156,7 +156,7 @@ export interface AppUrls {
* android: 'market://details?id=<package_name>', * android: 'market://details?id=<package_name>',
* windows: 'ms-windows-store://review/?ProductId=<store_id>' * windows: 'ms-windows-store://review/?ProductId=<store_id>'
* } * }
* }; * }
* *
* this.appRate.promptForRating(false); * this.appRate.promptForRating(false);
* ``` * ```
@ -181,7 +181,8 @@ export class AppRate extends IonicNativePlugin {
* Configure various settings for the Rating View. * Configure various settings for the Rating View.
* See table below for options * See table below for options
*/ */
@CordovaProperty preferences: AppRatePreferences; @CordovaProperty()
preferences: AppRatePreferences;
/** /**
* Prompts the user for rating * Prompts the user for rating

View File

@ -26,7 +26,7 @@ export interface AppUpdateOptions {
* Then use the following code: * Then use the following code:
* *
* ```typescript * ```typescript
* import { AppUpdate } from '@ionic-native/app-update'; * import { AppUpdate } from '@ionic-native/app-update/ngx';
* *
* constructor(private appUpdate: AppUpdate) { * constructor(private appUpdate: AppUpdate) {
* *

View File

@ -2,7 +2,6 @@ import { Injectable } from '@angular/core';
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
/** /**
* @name App Version * @name App Version
* @description * @description
@ -12,7 +11,7 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AppVersion } from '@ionic-native/app-version'; * import { AppVersion } from '@ionic-native/app-version/ngx';
* *
* constructor(private appVersion: AppVersion) { } * constructor(private appVersion: AppVersion) { }
* *

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs';
export type IMakePayments = export type IMakePayments =
| 'This device can make payments and has a supported card' | 'This device can make payments and has a supported card'
@ -71,6 +71,7 @@ export interface IShippingMethod {
detail: string; detail: string;
amount: number; amount: number;
} }
export interface IOrderItemsAndShippingMethods { export interface IOrderItemsAndShippingMethods {
items: IOrderItem[]; items: IOrderItem[];
shippingMethods?: IShippingMethod[]; shippingMethods?: IShippingMethod[];
@ -99,7 +100,7 @@ export interface ISelectedShippingContact {
* *
* @usage * @usage
* ```typescript * ```typescript
* import { ApplePay } from '@ionic-native/apple-pay'; * import { ApplePay } from '@ionic-native/apple-pay/ngx';
* *
* *
* constructor(private applePay: ApplePay) { } * constructor(private applePay: ApplePay) { }
@ -237,7 +238,7 @@ export class ApplePay extends IonicNativePlugin {
* this.paySheetItems.shippingCost = { * this.paySheetItems.shippingCost = {
* label: 'Shipping Cost', * label: 'Shipping Cost',
* amount: shippingMethod[0].amount * amount: shippingMethod[0].amount
* }; * }
* this.applePay.updateItemsAndShippingMethods(this.paySheetItems, shippingMethods); * this.applePay.updateItemsAndShippingMethods(this.paySheetItems, shippingMethods);
* }); * });
*/ */

View File

@ -11,7 +11,7 @@ export interface CardData {
cardholderName: string; cardholderName: string;
primaryAccountNumberSuffix: string; primaryAccountNumberSuffix: string;
localizedDescription?: string; localizedDescription?: string;
paymentNetwork?: string; paymentNetwork: string;
} }
/** /**
@ -21,33 +21,25 @@ export interface CardData {
* *
* @usage * @usage
* ```typescript * ```typescript
* import { AppleWallet } from '@ionic-native/apple-wallet'; * import { AppleWallet } from '@ionic-native/apple-wallet/ngx';
* *
* *
* constructor(private appleWallet: AppleWallet) { } * constructor(private appleWallet: AppleWallet) { }
* *
*
* ... * ...
* *
* *
* // Simple call to check whether the app can add cards to Apple Pay.
* this.appleWallet.available() * this.appleWallet.available()
* .then((res) => { * .then((res) => {
* // Apple Wallet is enabled and a supported card is setup. Expect: * // res is a boolean value, either true or false
* // boolean value, true or false * console.log("Is Apple Wallet available? ", res);
* }) * })
* .catch((message) => { * .catch((message) => {
* // Error message while trying to know if device is able to add to wallet * console.error("ERROR AVAILBLE>> ", message);
* }); * });
* *
*
* ... * ...
* *
*
* // Simple call with the configuration data needed to instantiate a new PKAddPaymentPassViewController object.
* // The encryption scheme, cardholder name, and primary account suffix are required for configuration.
* // The configuration information is used for setup and display only. It should not contain any sensitive information.
*
* let data: cardData = { * let data: cardData = {
* cardholderName: 'Test User', * cardholderName: 'Test User',
* primaryAccountNumberSuffix: '1234', * primaryAccountNumberSuffix: '1234',
@ -57,32 +49,14 @@ export interface CardData {
* *
* this.appleWallet.startAddPaymentPass(data: cardData) * this.appleWallet.startAddPaymentPass(data: cardData)
* .then((res) => { * .then((res) => {
* // User proceed and successfully asked to add card to his wallet * console.log("startAddPaymentPass success response ", res);
* // Use the callback response JSON payload to complete addition process
* }) * })
* .catch((err) => { * .catch((err) => {
* // Error or user cancelled. * console.error("startAddPaymentPass ERROR response", err);
* }); * });
* *
* // You should expect the callback success response to be as follow
*
* // {
* // data: {
* // "certificateSubCA": "Base64 string represents certificateSubCA",
* // "certificateLeaf":" Base64 string represents certificateLeaf"
* // "nonce": "Base64 string represents nonce",
* // "nonceSignature": "Base64 string represents nonceSignature",
* // }
* // }
*
* // This method provides the data needed to create an add payment request.
* // Pass the certificate chain to the issuer server. The server returns an encrypted JSON file containing the card data.
* // After you receive the encrypted data, pass it to completeAddPaymentPass method
*
*
* ... * ...
* *
*
* let data: encryptedCardData = { * let data: encryptedCardData = {
* activationData: 'encoded Base64 activationData from your server', * activationData: 'encoded Base64 activationData from your server',
* encryptedPassData: 'encoded Base64 encryptedPassData from your server', * encryptedPassData: 'encoded Base64 encryptedPassData from your server',
@ -91,12 +65,10 @@ export interface CardData {
* *
* this.appleWallet.encryptedCardData(data: encryptedCardData) * this.appleWallet.encryptedCardData(data: encryptedCardData)
* .then((res) => { * .then((res) => {
* // callback success response means card has been added successfully, * console.log("completeAddCardToAppleWallet success response ", res);
* // PKAddPaymentPassViewController will be dismissed
* }) * })
* .catch((err) => { * .catch((err) => {
* // Error and can not add the card, or something wrong happend * console.error("completeAddCardToAppleWallet ERROR response", err);
* // PKAddPaymentPassViewController will be dismissed
* }); * });
* *
* ``` * ```

Some files were not shown because too many files have changed in this diff Show More