mirror of
https://github.com/danielsogl/awesome-cordova-plugins.git
synced 2026-02-04 00:06:19 +08:00
Compare commits
619 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8695220ea | ||
|
|
364b30af59 | ||
|
|
860d79828d | ||
|
|
9057dc2c93 | ||
|
|
5223dc7dd5 | ||
|
|
bb77620d0d | ||
|
|
b280ef4c55 | ||
|
|
8e79890251 | ||
|
|
f4a4bb9e55 | ||
|
|
d108776981 | ||
|
|
8a65cc943a | ||
|
|
d2e4d3e5ce | ||
|
|
3440dca70f | ||
|
|
499cc5c075 | ||
|
|
f2961fb4bb | ||
|
|
48082eeaef | ||
|
|
4c56d227a8 | ||
|
|
2fd4885fb1 | ||
|
|
7d756394dd | ||
|
|
f4b03bcce4 | ||
|
|
01bfa5cc5e | ||
|
|
996bf00e85 | ||
|
|
30360fe29d | ||
|
|
88bf517697 | ||
|
|
e6ac206b8d | ||
|
|
00ef998ee5 | ||
|
|
f81e181588 | ||
|
|
08332b7c02 | ||
|
|
86cca49236 | ||
|
|
2718bccccc | ||
|
|
042e36de08 | ||
|
|
ec933011e6 | ||
|
|
2312665792 | ||
|
|
eae8c1000c | ||
|
|
509bd72dde | ||
|
|
fe38903e4b | ||
|
|
1ebf447240 | ||
|
|
4788104931 | ||
|
|
fdd38b97b6 | ||
|
|
409a985142 | ||
|
|
8534061b2f | ||
|
|
275741faed | ||
|
|
4c5d70eacd | ||
|
|
0b43c69993 | ||
|
|
fb5d47bff2 | ||
|
|
7033a1822e | ||
|
|
a840a03e33 | ||
|
|
fb540f7774 | ||
|
|
cb4d5b5064 | ||
|
|
265b4ba02f | ||
|
|
5fc13abb10 | ||
|
|
b7a4e44308 | ||
|
|
a1fb93707f | ||
|
|
a575233f23 | ||
|
|
66f2e155f0 | ||
|
|
5f16fcd292 | ||
|
|
fc6d1d0c7f | ||
|
|
acec6cfb18 | ||
|
|
f5d94d824d | ||
|
|
70d4fcd30e | ||
|
|
5cea6141c4 | ||
|
|
cb543b9841 | ||
|
|
3f172cc2b8 | ||
|
|
98b463b0d3 | ||
|
|
8940301e87 | ||
|
|
493405426c | ||
|
|
fcec2d16b3 | ||
|
|
d9ded4d164 | ||
|
|
141f0e6e41 | ||
|
|
199380c0c3 | ||
|
|
a46e308ea8 | ||
|
|
fb0ee819be | ||
|
|
1b6506f53a | ||
|
|
d539eb4f62 | ||
|
|
cfcd8d16a6 | ||
|
|
6bc1b932c8 | ||
|
|
650615e883 | ||
|
|
8b3b2a4b27 | ||
|
|
2b347fe889 | ||
|
|
8032429faa | ||
|
|
4cb97eeec4 | ||
|
|
1d878c6902 | ||
|
|
e65ce4a879 | ||
|
|
bfa4f62e2b | ||
|
|
1af96d1369 | ||
|
|
dcce3489f4 | ||
|
|
3a5c790a56 | ||
|
|
73493e222f | ||
|
|
26447d22ea | ||
|
|
a55bb60d70 | ||
|
|
4d1e0e6949 | ||
|
|
189570d255 | ||
|
|
64ca73e5cc | ||
|
|
4337515961 | ||
|
|
c0d4a2ee34 | ||
|
|
1f7e6a5d02 | ||
|
|
fd81a5e5b7 | ||
|
|
f3b8e34091 | ||
|
|
5cc91bc79a | ||
|
|
e37a7221b1 | ||
|
|
016023a7bb | ||
|
|
852df98647 | ||
|
|
7696706080 | ||
|
|
2c0aa4f124 | ||
|
|
8bcbc955e0 | ||
|
|
3bb6b59112 | ||
|
|
f6e77db7b0 | ||
|
|
acc587aca2 | ||
|
|
c77bdf17c1 | ||
|
|
0c9bf3bf49 | ||
|
|
f54b9e0797 | ||
|
|
7e08680d31 | ||
|
|
de83edb99b | ||
|
|
fac94485a0 | ||
|
|
9c9ed3518f | ||
|
|
a0779de633 | ||
|
|
50408b08c6 | ||
|
|
767391a4b4 | ||
|
|
a2f5acb48c | ||
|
|
3a3e9338e7 | ||
|
|
8badd2943a | ||
|
|
9a46ab1a6d | ||
|
|
952a5c8e11 | ||
|
|
2a995d94ec | ||
|
|
941d394da9 | ||
|
|
cc1f25c38c | ||
|
|
7aa08109ce | ||
|
|
8ce541ff9a | ||
|
|
75190f5166 | ||
|
|
c697139089 | ||
|
|
717f6864f3 | ||
|
|
e9fa3ee6f2 | ||
|
|
28ce962677 | ||
|
|
f576c5f11e | ||
|
|
f488a75e26 | ||
|
|
55fb503d81 | ||
|
|
afe95a6752 | ||
|
|
2ca8bda8f7 | ||
|
|
2b684fadb1 | ||
|
|
7f2da56a28 | ||
|
|
4a546bd11a | ||
|
|
a0f5254988 | ||
|
|
8521b32306 | ||
|
|
d52278b2d1 | ||
|
|
2fadb6b0e1 | ||
|
|
ad11ed21ac | ||
|
|
5857b9654c | ||
|
|
92d5764e01 | ||
|
|
a4db080786 | ||
|
|
54ac2bfdf5 | ||
|
|
9274083b24 | ||
|
|
d04396e631 | ||
|
|
c4b4584d2d | ||
|
|
1fc09098fe | ||
|
|
b217bdb62a | ||
|
|
1b60247807 | ||
|
|
b75f40c76e | ||
|
|
09ca1a1843 | ||
|
|
6cbb226ed2 | ||
|
|
ed80933b6c | ||
|
|
300d7c229c | ||
|
|
43442ac4ea | ||
|
|
12f2782fef | ||
|
|
a586734b92 | ||
|
|
f58183260d | ||
|
|
a3c49fd17a | ||
|
|
6ee94b93ba | ||
|
|
a0ec1252e0 | ||
|
|
dfb0aa3d5d | ||
|
|
312c126cc8 | ||
|
|
b79c8b1ea0 | ||
|
|
49e81cc414 | ||
|
|
2942ebfae4 | ||
|
|
4ae35cba9a | ||
|
|
bb7b516c50 | ||
|
|
c0b092b242 | ||
|
|
a2fe674a3f | ||
|
|
f12da1f4f5 | ||
|
|
0e7bec3633 | ||
|
|
7588eaf9fd | ||
|
|
c5a9d0d258 | ||
|
|
18e4a9cda6 | ||
|
|
26f63c744d | ||
|
|
1cb4c989f9 | ||
|
|
c80d081c92 | ||
|
|
3e0a7395ca | ||
|
|
4c6dc71cbe | ||
|
|
81a10280cc | ||
|
|
56e4a7827f | ||
|
|
c4fe2b7203 | ||
|
|
0dc320bbd2 | ||
|
|
b4201e1b52 | ||
|
|
9a4bef34bb | ||
|
|
2bc8bdc49c | ||
|
|
e363d98bd8 | ||
|
|
980447673b | ||
|
|
7afed90b56 | ||
|
|
0634e64b58 | ||
|
|
a42e7b8258 | ||
|
|
5b5c6e61ac | ||
|
|
79037743b8 | ||
|
|
ed36dc492d | ||
|
|
1f31954cb3 | ||
|
|
4601ea3e01 | ||
|
|
45c64b0394 | ||
|
|
591c290dbd | ||
|
|
66b9d1a011 | ||
|
|
25ef7c98bc | ||
|
|
19ddf3fb93 | ||
|
|
20a3791a88 | ||
|
|
9800271352 | ||
|
|
e288a5d757 | ||
|
|
ab7c7fa491 | ||
|
|
9e306e7de1 | ||
|
|
92e0cb2385 | ||
|
|
0800f4a414 | ||
|
|
e47774b771 | ||
|
|
c0ce17b170 | ||
|
|
c518c8114d | ||
|
|
21dc1f9a56 | ||
|
|
7ea51fcf06 | ||
|
|
c063652800 | ||
|
|
9024ea516a | ||
|
|
e92b7aeb74 | ||
|
|
dc51c3e1e8 | ||
|
|
4859387925 | ||
|
|
10787c8056 | ||
|
|
f874185a35 | ||
|
|
00e34877f3 | ||
|
|
4de49c37dd | ||
|
|
bd4b2e2bb4 | ||
|
|
aa138c4cfe | ||
|
|
4e60c631ae | ||
|
|
767d3b3dd4 | ||
|
|
39be27566b | ||
|
|
029f82f1fd | ||
|
|
6a19509ded | ||
|
|
c75aeb9c39 | ||
|
|
dcd95582d2 | ||
|
|
354af9fe6f | ||
|
|
49d7ca7375 | ||
|
|
8d91856103 | ||
|
|
5221c8cf41 | ||
|
|
d827db27b0 | ||
|
|
b9e46730e3 | ||
|
|
fcda5ffcab | ||
|
|
6fde61d69c | ||
|
|
c8ff885023 | ||
|
|
06654afae3 | ||
|
|
e1a25af0b5 | ||
|
|
419b68217e | ||
|
|
cd97375e63 | ||
|
|
b0dea6dc58 | ||
|
|
7e090cc6f2 | ||
|
|
c2029f7927 | ||
|
|
5b1bdc37e0 | ||
|
|
e3e8c85087 | ||
|
|
03c01c687e | ||
|
|
c0684cb3d8 | ||
|
|
9a85a5cd62 | ||
|
|
7ae2ad4e3e | ||
|
|
c5ae6362d7 | ||
|
|
8b53c04dc5 | ||
|
|
64230319a2 | ||
|
|
3d8cdde7eb | ||
|
|
e1b7aca3a9 | ||
|
|
9bdb2fac9d | ||
|
|
41c6bcafe6 | ||
|
|
d55d1d6f7f | ||
|
|
aed25a6642 | ||
|
|
daf04566a1 | ||
|
|
4cb2aee62b | ||
|
|
63124f35fd | ||
|
|
632dec28ae | ||
|
|
50e05349ec | ||
|
|
fd27136de7 | ||
|
|
2833da472a | ||
|
|
c5ceba1aae | ||
|
|
e1a490357d | ||
|
|
959a9135e4 | ||
|
|
fc0a238229 | ||
|
|
eeb68f1706 | ||
|
|
bceb428690 | ||
|
|
242240c711 | ||
|
|
e9911aa4ad | ||
|
|
04798c7354 | ||
|
|
3aedde55d8 | ||
|
|
92140cd2db | ||
|
|
184986f06b | ||
|
|
2ce2725b2a | ||
|
|
3d8455ae35 | ||
|
|
bf7ba9bd01 | ||
|
|
0883240f60 | ||
|
|
b6f340ae82 | ||
|
|
0612aef725 | ||
|
|
4bf7ba6085 | ||
|
|
707d40bd83 | ||
|
|
b4e0764d71 | ||
|
|
c1d7ce13dd | ||
|
|
999853eb32 | ||
|
|
dfd6714331 | ||
|
|
898c68bb5e | ||
|
|
674e80ee61 | ||
|
|
7e817a0223 | ||
|
|
2efc5b2e2c | ||
|
|
3f65ce1c7e | ||
|
|
2d49671282 | ||
|
|
a9dbb23b23 | ||
|
|
9250d49970 | ||
|
|
2397ef9d60 | ||
|
|
dbd8b4c080 | ||
|
|
1ba6f97082 | ||
|
|
c2f45616ac | ||
|
|
603d6943ef | ||
|
|
3226f76ef9 | ||
|
|
34ecd29d9f | ||
|
|
874be0bb04 | ||
|
|
9e6705df7f | ||
|
|
7c46d8c2fc | ||
|
|
651a40f784 | ||
|
|
f420d2b830 | ||
|
|
e374b52c59 | ||
|
|
7d3ddf89ae | ||
|
|
19b3e8f521 | ||
|
|
c14ea31a8a | ||
|
|
707ce1cad9 | ||
|
|
d33bcb0220 | ||
|
|
5df3de7dc0 | ||
|
|
d499a4db8d | ||
|
|
e2b25deff6 | ||
|
|
c3de8dfaba | ||
|
|
448e064012 | ||
|
|
8e405cc3d3 | ||
|
|
6ef854f4f1 | ||
|
|
ea3150e99a | ||
|
|
3edd62e56c | ||
|
|
7483c3554c | ||
|
|
06634dc5f4 | ||
|
|
8879ffb789 | ||
|
|
649dca1ef4 | ||
|
|
165c3cc211 | ||
|
|
b63102a5fa | ||
|
|
df7ec0146c | ||
|
|
20878516b4 | ||
|
|
b166cc51ea | ||
|
|
31e4058257 | ||
|
|
543fa64b35 | ||
|
|
dcac00e7ad | ||
|
|
006570483d | ||
|
|
b7594e201b | ||
|
|
1396b61215 | ||
|
|
b9e9aa184e | ||
|
|
4f8779a969 | ||
|
|
7145afa24f | ||
|
|
66316d29fe | ||
|
|
7dcd6b27a0 | ||
|
|
b98393462d | ||
|
|
f9011c89c8 | ||
|
|
4b4b2c45a0 | ||
|
|
43bfeb487a | ||
|
|
accfba8a40 | ||
|
|
dc4183da07 | ||
|
|
b61b33987f | ||
|
|
39b4b85631 | ||
|
|
669dd02285 | ||
|
|
a3bd19769f | ||
|
|
ff3ef094e0 | ||
|
|
2933d40cdc | ||
|
|
874ae88ff4 | ||
|
|
a02ca715e9 | ||
|
|
336b3ff89b | ||
|
|
2aa73b5546 | ||
|
|
99cebcba0b | ||
|
|
6c99ec8033 | ||
|
|
a167bd85aa | ||
|
|
487acd603b | ||
|
|
fb4d2640c1 | ||
|
|
4468b520ad | ||
|
|
1a2dc3ee73 | ||
|
|
220e22b659 | ||
|
|
00a1674fd6 | ||
|
|
2b14bd979e | ||
|
|
ac78a1540c | ||
|
|
bdd1755f8b | ||
|
|
3ed39c06ed | ||
|
|
89a5ca7ec5 | ||
|
|
0422521db6 | ||
|
|
8d57df3e64 | ||
|
|
fcd6d26727 | ||
|
|
f95003cbe1 | ||
|
|
8e5f2e5ab3 | ||
|
|
307477da78 | ||
|
|
f691883a29 | ||
|
|
0d5d4f30a9 | ||
|
|
1457a1698b | ||
|
|
fbf7463724 | ||
|
|
bfd46eed16 | ||
|
|
cbeb4139d9 | ||
|
|
3eff280127 | ||
|
|
457d47cc16 | ||
|
|
8116ddd139 | ||
|
|
358474dcfd | ||
|
|
d6d9b54991 | ||
|
|
93ff513bd8 | ||
|
|
d3af51915e | ||
|
|
276c88dea1 | ||
|
|
653f5a2969 | ||
|
|
e661f2ece9 | ||
|
|
15cd285ec6 | ||
|
|
95b92623a6 | ||
|
|
a6bcc9affd | ||
|
|
c0d8c99e8d | ||
|
|
7aa5e00453 | ||
|
|
59fd0cc50d | ||
|
|
c433317051 | ||
|
|
f223ed4fa1 | ||
|
|
7160953683 | ||
|
|
4c55212b8d | ||
|
|
38a1dd1187 | ||
|
|
fe9655ed84 | ||
|
|
41c034cc19 | ||
|
|
89631a9fa6 | ||
|
|
04db233b33 | ||
|
|
10d222dcea | ||
|
|
640da1b618 | ||
|
|
aecb0f9460 | ||
|
|
d077c48205 | ||
|
|
49d27e816c | ||
|
|
3699fa9b50 | ||
|
|
ab4f1f5bbe | ||
|
|
51006a76a0 | ||
|
|
8bab32173a | ||
|
|
3ef9593704 | ||
|
|
ffae843c0f | ||
|
|
7cff234c26 | ||
|
|
039c6d40af | ||
|
|
33e4392b63 | ||
|
|
9acbb9fcd6 | ||
|
|
c1e1c5cb79 | ||
|
|
46b1a7385c | ||
|
|
0c7cfeeeb8 | ||
|
|
737ad518c8 | ||
|
|
89ed51cc49 | ||
|
|
26a8df9b7c | ||
|
|
84db491ead | ||
|
|
d5011fb105 | ||
|
|
c9d41ebd8a | ||
|
|
60a7190eda | ||
|
|
261106131e | ||
|
|
4803912350 | ||
|
|
9feefe8454 | ||
|
|
81df665189 | ||
|
|
f2c8edecc4 | ||
|
|
6c18a8bc4f | ||
|
|
ca7f872a3c | ||
|
|
2c04ae5985 | ||
|
|
a7830693af | ||
|
|
2e47de2ee3 | ||
|
|
384d1ea71e | ||
|
|
f7e76c5f83 | ||
|
|
d2d1f4889e | ||
|
|
b60d5d4851 | ||
|
|
0c4aeddd1b | ||
|
|
667de5ba26 | ||
|
|
2dc7ee8916 | ||
|
|
2c2c1e482c | ||
|
|
7c419b48ad | ||
|
|
0b9717636c | ||
|
|
10ac9ff9de | ||
|
|
90d75af9d1 | ||
|
|
3b3f942ed5 | ||
|
|
9601a64227 | ||
|
|
22fd49b5d3 | ||
|
|
890129bfda | ||
|
|
6a9a871758 | ||
|
|
ac467c50ac | ||
|
|
267149b16f | ||
|
|
7047920a2a | ||
|
|
8f8aeb6e6a | ||
|
|
f75243e10b | ||
|
|
0f5ae4726d | ||
|
|
5462a2358c | ||
|
|
9c75e53702 | ||
|
|
2213673055 | ||
|
|
c8d25a1fc5 | ||
|
|
bd345818f8 | ||
|
|
110fb7e8e1 | ||
|
|
c0d776cdd2 | ||
|
|
89140c1502 | ||
|
|
8f19719d2a | ||
|
|
999aca1b8d | ||
|
|
1ad4cc1375 | ||
|
|
38b6501612 | ||
|
|
fe87b68ccc | ||
|
|
9e923fa8da | ||
|
|
5e9c92a773 | ||
|
|
5ac940d2bf | ||
|
|
e47a3e1522 | ||
|
|
1a1c665b18 | ||
|
|
f2728f26fe | ||
|
|
2f560d619a | ||
|
|
342b9dace5 | ||
|
|
07557e95ec | ||
|
|
b7be1bf9dd | ||
|
|
b01c2ee1fb | ||
|
|
bea5eaea1a | ||
|
|
97b80b533b | ||
|
|
6ea43ef5e4 | ||
|
|
f9c49dcd3f | ||
|
|
db70bbd765 | ||
|
|
81287c9edf | ||
|
|
6398dcf479 | ||
|
|
0a758f85e6 | ||
|
|
23e0977954 | ||
|
|
95c8566d76 | ||
|
|
7d5e7aaa7d | ||
|
|
406ad12232 | ||
|
|
aff44e9fde | ||
|
|
ed515f7017 | ||
|
|
f3ef2a877d | ||
|
|
f7afd1f066 | ||
|
|
74a65b039f | ||
|
|
37f16ba5da | ||
|
|
8beb1774b8 | ||
|
|
6662234894 | ||
|
|
db32d2d520 | ||
|
|
aa90626116 | ||
|
|
5516165fb6 | ||
|
|
48714d72d6 | ||
|
|
e0b0687004 | ||
|
|
885d09d0ab | ||
|
|
0b3d299a96 | ||
|
|
f34b6e6664 | ||
|
|
3fbd475ed2 | ||
|
|
3b43bd76fd | ||
|
|
d3c2859d38 | ||
|
|
fbaacfb572 | ||
|
|
f348f95e56 | ||
|
|
f13b31f074 | ||
|
|
88fda657f4 | ||
|
|
0dfbb386ff | ||
|
|
213d77ffda | ||
|
|
d55fd2a109 | ||
|
|
b36a1f9df6 | ||
|
|
fa08b99bbc | ||
|
|
f414e0e081 | ||
|
|
86b637e85a | ||
|
|
3b440c6df8 | ||
|
|
ad1848899d | ||
|
|
242cd4b124 | ||
|
|
abee240df5 | ||
|
|
6d8b406471 | ||
|
|
29646d8da0 | ||
|
|
9f70bf5727 | ||
|
|
f21b63be47 | ||
|
|
7a1ff64bf2 | ||
|
|
c13a53ad45 | ||
|
|
9e3f1cc0c6 | ||
|
|
4ce15c6cd7 | ||
|
|
c63895db19 | ||
|
|
3aea3900bc | ||
|
|
d96c230b2e | ||
|
|
bb6342b72a | ||
|
|
d56826f12d | ||
|
|
b09eb06cb0 | ||
|
|
fd87e968f0 | ||
|
|
e12c90f890 | ||
|
|
f70eaea71e | ||
|
|
29d668ca2f | ||
|
|
c0737feb41 | ||
|
|
c4e8c2efbc | ||
|
|
83680aad96 | ||
|
|
cc9a980dc3 | ||
|
|
3750cad793 | ||
|
|
4aca04a62e | ||
|
|
3ced31ed2a | ||
|
|
48b0f16ed9 | ||
|
|
97a73ca369 | ||
|
|
bf0eaf75b9 | ||
|
|
0b08ce4395 | ||
|
|
70f01fe528 | ||
|
|
b5e04cca20 | ||
|
|
c15b78bab2 | ||
|
|
d7829e4012 | ||
|
|
28e95ea66e | ||
|
|
9711061889 | ||
|
|
a7c1dea6a1 | ||
|
|
12235cef2e | ||
|
|
3a84aeec21 | ||
|
|
acfaeac64b | ||
|
|
d35e790b1e | ||
|
|
1e401682f6 | ||
|
|
1d7ee313a0 | ||
|
|
a1c4d48f54 | ||
|
|
9e2e902b18 | ||
|
|
c99340d504 | ||
|
|
9f19e2ba07 | ||
|
|
b9d9f0bd54 | ||
|
|
a6d5d51489 | ||
|
|
1c95039c02 | ||
|
|
92aff84e54 | ||
|
|
821d8222fa | ||
|
|
85d685b38f | ||
|
|
13308403cb | ||
|
|
b60df6cf7e | ||
|
|
dcf5102c57 | ||
|
|
0cc1a2b2ff | ||
|
|
fc9dcc8e64 | ||
|
|
228c0bb9f3 | ||
|
|
1c35991548 | ||
|
|
a26457b30a | ||
|
|
542e7d24f0 | ||
|
|
2f5f34c2c5 | ||
|
|
2a3f015f07 | ||
|
|
11a1cc2ff5 | ||
|
|
6416395727 | ||
|
|
75675ea19f | ||
|
|
c22ac6d681 | ||
|
|
0f9c21ab42 |
@@ -1,15 +1,15 @@
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
insert_final_newline = false
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = false
|
||||
31
.github/workflows/nodejs.yml
vendored
Normal file
31
.github/workflows/nodejs.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Node CI
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Test
|
||||
run: npm run test
|
||||
- name: Readmes
|
||||
run: npm run readmes
|
||||
env:
|
||||
CI: true
|
||||
38
.github/workflows/npmpublish.yml
vendored
Normal file
38
.github/workflows/npmpublish.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: Node.js Package
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Test
|
||||
run: npm run test
|
||||
- name: Readmes
|
||||
run: npm run readmes
|
||||
|
||||
publish-npm:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12
|
||||
registry-url: https://registry.npmjs.org/
|
||||
- run: npm ci
|
||||
- run: npm run shipit
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -4,5 +4,9 @@ node_modules/
|
||||
.tmp
|
||||
aot/
|
||||
scripts/ionic-native-bower
|
||||
scripts/docs-json/*.json
|
||||
dist/
|
||||
src/@ionic-native/plugins/**/ngx
|
||||
*.d.ts
|
||||
injectable-classes.json
|
||||
|
||||
|
||||
2351
CHANGELOG.md
2351
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@@ -88,8 +88,6 @@ It's just a stub. The `return` is only there to keep the TypeScript type-checker
|
||||
|
||||
By default, the `@Cordova` decorator wraps the plugin callbacks in a Promise that resolves when the success callback is called and rejects when the error callback is called. It also ensures that Cordova and the underlying plugin are available, and prints helpful diagnostics if they aren't.
|
||||
|
||||
You'll also notice that `getCurrentPosition` is a static method. That's because the plugin class is just a utility class to call the underlying Cordova plugin methods, it's not an instance and has no state.
|
||||
|
||||
Next, let's look at the `watchPosition` method.
|
||||
|
||||
```
|
||||
@@ -194,7 +192,7 @@ Checks if the plugin and property exist before getting/setting the property's va
|
||||
|
||||
Example:
|
||||
```ts
|
||||
@CordovaProperty
|
||||
@CordovaProperty()
|
||||
someProperty: string;
|
||||
```
|
||||
|
||||
|
||||
46
LICENSE
46
LICENSE
@@ -1,23 +1,23 @@
|
||||
Copyright 2015-present Drifty Co.
|
||||
http://drifty.com/
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Copyright 2015-present Drifty Co.
|
||||
http://drifty.com/
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
81
README.md
81
README.md
@@ -11,7 +11,7 @@ Ionic Native wraps plugin callbacks in a Promise or Observable, providing a comm
|
||||
Run following command to install Ionic Native in your project.
|
||||
|
||||
```bash
|
||||
npm install @ionic-native/core
|
||||
npm install @ionic-native/core --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.
|
||||
@@ -22,11 +22,13 @@ For the full Ionic Native documentation, please visit [https://ionicframework.co
|
||||
|
||||
### Basic Usage
|
||||
|
||||
To use a plugin, import and add the plugin provider to your `@NgModule`, and then inject it where you wish to use it.
|
||||
#### 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.
|
||||
Make sure to import the injectable class from the `/ngx` directory as shown in the following examples:
|
||||
|
||||
```typescript
|
||||
// app.module.ts
|
||||
import { Camera } from '@ionic-native/camera';
|
||||
import { Camera } from '@ionic-native/camera/ngx';
|
||||
|
||||
...
|
||||
|
||||
@@ -44,7 +46,7 @@ export class AppModule { }
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { Geolocation } from '@ionic-native/geolocation';
|
||||
import { Geolocation } from '@ionic-native/geolocation/ngx';
|
||||
import { Platform } from 'ionic-angular';
|
||||
|
||||
@Component({ ... })
|
||||
@@ -74,16 +76,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:
|
||||
|
||||
First import the `Camera` class in your `src/app/app.module.ts` file:
|
||||
|
||||
```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:
|
||||
@@ -109,8 +166,11 @@ Here's the full example:
|
||||
```typescript
|
||||
import { ErrorHandler, NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { Camera } from '@ionic-native/camera';
|
||||
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
|
||||
import { IonicApp, IonicModule, IonicErrorHandler } 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 { MyApp } from './app.component';
|
||||
@@ -146,9 +206,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:
|
||||
|
||||
## 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
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ jobs:
|
||||
build:
|
||||
working_directory: ~/ionic-native/
|
||||
docker:
|
||||
- image: node:8
|
||||
- image: node:12
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
key: node_modules_{{ checksum "package.json" }}
|
||||
- run:
|
||||
name: Install node modules
|
||||
command: npm i
|
||||
command: npm ci
|
||||
- save_cache:
|
||||
key: node_modules_{{ checksum "package.json" }}
|
||||
paths:
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- run: bash ./scripts/git/config.sh
|
||||
- run:
|
||||
name: Build Ionic Native
|
||||
command: npm run build:core && ./node_modules/.bin/tsc
|
||||
command: npm run build
|
||||
- run:
|
||||
name: Generate README files to ensure docs are valid
|
||||
command: npm run readmes
|
||||
|
||||
@@ -32,9 +32,7 @@ gulp.task('lint', () => {
|
||||
|
||||
gulp.task('plugin:create', () => {
|
||||
if (flags.n && flags.n !== '') {
|
||||
const src = flags.m
|
||||
? './scripts/templates/wrap-min.tmpl'
|
||||
: './scripts/templates/wrap.tmpl',
|
||||
const src = flags.m ? './scripts/templates/wrap-min.tmpl' : './scripts/templates/wrap.tmpl',
|
||||
pluginName = flags.n,
|
||||
spaced = pluginName.replace(/(?!^)([A-Z])/g, ' $1'),
|
||||
kebabCase = _.kebabCase(pluginName);
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
23853
package-lock.json
generated
23853
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
117
package.json
117
package.json
@@ -1,63 +1,80 @@
|
||||
{
|
||||
"name": "ionic-native",
|
||||
"version": "4.12.2",
|
||||
"version": "5.17.1",
|
||||
"description": "Native plugin wrappers for Cordova and Ionic with TypeScript, ES6+, Promise and Observable support",
|
||||
"homepage": "https://ionicframework.com/",
|
||||
"author": "Ionic Team <hi@ionic.io> (https://ionic.io)",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@angular/compiler": "^5.2.11",
|
||||
"@angular/compiler-cli": "^5.2.11",
|
||||
"@angular/core": "^5.2.11",
|
||||
"@types/cordova": "0.0.34",
|
||||
"@types/jasmine": "^2.8.8",
|
||||
"@types/node": "8.10.20",
|
||||
"canonical-path": "0.0.2",
|
||||
"child-process-promise": "2.2.1",
|
||||
"conventional-changelog-cli": "^2.0.5",
|
||||
"cz-conventional-changelog": "^2.1.0",
|
||||
"dgeni": "0.4.7",
|
||||
"dgeni-packages": "0.16.10",
|
||||
"fs-extra": "2.0.0",
|
||||
"fs-extra-promise": "0.4.1",
|
||||
"gulp": "3.9.1",
|
||||
"gulp-rename": "^1.4.0",
|
||||
"gulp-replace": "^1.0.0",
|
||||
"gulp-tslint": "6.1.2",
|
||||
"jasmine-core": "^3.2.1",
|
||||
"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.10",
|
||||
"minimist": "1.2.0",
|
||||
"node-html-encoder": "0.0.2",
|
||||
"q": "^1.5.1",
|
||||
"queue": "^4.5.0",
|
||||
"rimraf": "^2.6.2",
|
||||
"rxjs": "^5.5.12",
|
||||
"semver": "^5.5.1",
|
||||
"tslint": "3.15.1",
|
||||
"tslint-ionic-rules": "0.0.8",
|
||||
"typescript": "~2.4.2",
|
||||
"zone.js": "^0.8.26"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "npm run test:watch",
|
||||
"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",
|
||||
"build": "npm run clean && npm run lint && npm run build:core && npm run build:modules",
|
||||
"build:core": "ngc -p scripts/build/tsconfig-core.json",
|
||||
"build:modules": "node scripts/build/build.js",
|
||||
"clean": "rimraf dist .tmp",
|
||||
"shipit": "npm run build && gulp readmes && npm run npmpub",
|
||||
"npmpub": "node scripts/build/publish.js",
|
||||
"readmes": "gulp readmes",
|
||||
"docs-json": "ts-node -P scripts/tsconfig.json scripts/docs-json",
|
||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
|
||||
"postchangelog": "git commit -am \"chore(): update changelog\"",
|
||||
"test": "karma start karma.conf.js --single-run",
|
||||
"test:watch": "karma start karma.conf.js",
|
||||
"readmes": "gulp readmes"
|
||||
"shipit": "npm run build && npm run readmes && npm run npmpub"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/common": "^8.2.14",
|
||||
"@angular/compiler": "^8.2.14",
|
||||
"@angular/compiler-cli": "^8.2.14",
|
||||
"@angular/core": "^8.2.14",
|
||||
"@types/cordova": "0.0.34",
|
||||
"@types/fs-extra": "^8.0.1",
|
||||
"@types/jest": "^24.0.23",
|
||||
"@types/lodash": "^4.14.149",
|
||||
"@types/node": "^12.12.14",
|
||||
"@types/rimraf": "^2.0.3",
|
||||
"@types/webpack": "^4.41.0",
|
||||
"ajv": "^6.10.2",
|
||||
"async-promise-queue": "^1.0.5",
|
||||
"conventional-changelog-cli": "^2.0.28",
|
||||
"cz-conventional-changelog": "^3.0.2",
|
||||
"dgeni": "^0.4.12",
|
||||
"dgeni-packages": "0.16.10",
|
||||
"fs-extra": "^8.1.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-rename": "^1.4.0",
|
||||
"gulp-replace": "^1.0.0",
|
||||
"gulp-tslint": "^8.1.4",
|
||||
"jest": "^24.9.0",
|
||||
"lodash": "^4.17.15",
|
||||
"minimist": "1.2.0",
|
||||
"natives": "^1.1.6",
|
||||
"rimraf": "^3.0.0",
|
||||
"rxjs": "^6.5.3",
|
||||
"ts-jest": "^24.2.0",
|
||||
"ts-node": "^8.5.2",
|
||||
"tslint": "^5.20.1",
|
||||
"tslint-ionic-rules": "0.0.21",
|
||||
"typedoc": "^0.15.3",
|
||||
"typescript": "~3.5.3",
|
||||
"uglifyjs-webpack-plugin": "^2.2.0",
|
||||
"unminified-webpack-plugin": "^2.0.0",
|
||||
"webpack": "^4.41.2",
|
||||
"winston": "^3.2.1",
|
||||
"zone.js": "^0.9.1"
|
||||
},
|
||||
"jest": {
|
||||
"transform": {
|
||||
"^.+\\.tsx?$": "ts-jest"
|
||||
},
|
||||
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(js?|ts?)$",
|
||||
"moduleFileExtensions": [
|
||||
"ts",
|
||||
"tsx",
|
||||
"js",
|
||||
"jsx",
|
||||
"json"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
'use strict';
|
||||
// Node module dependencies
|
||||
const fs = require('fs-extra-promise').useFs(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.mkdirpAsync(PLUGIN_BUILD_DIR) // create tmp build dir
|
||||
.then(() => fs.mkdirpAsync(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.writeJsonAsync(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.writeJsonAsync(
|
||||
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!');
|
||||
}
|
||||
});
|
||||
@@ -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
126
scripts/build/helpers.ts
Normal 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
105
scripts/build/ngx.ts
Normal 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'))
|
||||
);
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
'use strict';
|
||||
// Node module dependencies
|
||||
const fs = require('fs-extra-promise').useFs(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!');
|
||||
}
|
||||
});
|
||||
2
scripts/build/remove-tslib-helpers.js
Normal file
2
scripts/build/remove-tslib-helpers.js
Normal 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, '');
|
||||
59
scripts/build/transformers/extract-injectables.ts
Normal file
59
scripts/build/transformers/extract-injectables.ts
Normal 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);
|
||||
}
|
||||
74
scripts/build/transformers/imports.ts
Normal file
74
scripts/build/transformers/imports.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
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));
|
||||
|
||||
const methodElements = methods.map(m => ts.createIdentifier(m));
|
||||
const methodNames = methodElements.map((el) => el.escapedText);
|
||||
|
||||
importStatement.importClause.namedBindings.elements = [
|
||||
ts.createIdentifier('IonicNativePlugin'),
|
||||
...methodElements,
|
||||
...importStatement.importClause.namedBindings.elements.filter(
|
||||
el => keep.indexOf(el.name.text) !== -1 && methodNames.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);
|
||||
};
|
||||
};
|
||||
}
|
||||
37
scripts/build/transformers/members.ts
Normal file
37
scripts/build/transformers/members.ts
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
49
scripts/build/transformers/methods.ts
Normal file
49
scripts/build/transformers/methods.ts
Normal 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')
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
80
scripts/build/transformers/plugin-class.ts
Normal file
80
scripts/build/transformers/plugin-class.ts
Normal 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;
|
||||
};
|
||||
};
|
||||
}
|
||||
67
scripts/build/transformers/properties.ts
Normal file
67
scripts/build/transformers/properties.ts
Normal 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];
|
||||
}
|
||||
51
scripts/build/transpile.ts
Normal file
51
scripts/build/transpile.ts
Normal 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;
|
||||
}
|
||||
|
||||
@@ -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": []
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
101
scripts/docs-json/index.ts
Normal file
101
scripts/docs-json/index.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import * as fs from 'fs-extra';
|
||||
import { Application } from 'typedoc';
|
||||
import { basename, dirname, resolve } from 'path';
|
||||
import { runInNewContext } from 'vm';
|
||||
|
||||
interface Plugin {
|
||||
packageName: string;
|
||||
displayName: string;
|
||||
description: string;
|
||||
platforms: string[];
|
||||
usage: string;
|
||||
repo: string;
|
||||
installVariables: string[];
|
||||
cordovaPlugin: {
|
||||
name: string;
|
||||
};
|
||||
}
|
||||
|
||||
const rootDir = resolve(__dirname, '../..');
|
||||
const typedocTmp = resolve(__dirname, 'typedoc.tmp.json');
|
||||
const pluginsDir = resolve(rootDir, 'src/@ionic-native/plugins');
|
||||
const typedoc = new Application({
|
||||
mode: 'modules',
|
||||
tsconfig: resolve(rootDir, 'tsconfig.json'),
|
||||
ignoreCompilerErrors: true
|
||||
});
|
||||
|
||||
run(pluginsDir);
|
||||
|
||||
async function run(pluginsDir: string) {
|
||||
const typedocData = await generateTypedoc(pluginsDir);
|
||||
const modules = typedocData.children.filter(isModule);
|
||||
const plugins = modules.filter(hasPlugin).map(processPlugin);
|
||||
await fs.outputJson(resolve(__dirname, 'plugins.json'), plugins, {
|
||||
spaces: 2
|
||||
});
|
||||
}
|
||||
|
||||
async function generateTypedoc(root: string, outputPath = typedocTmp) {
|
||||
const pluginDirs = await fs.readdir(root);
|
||||
const paths = pluginDirs.map(dir => resolve(root, dir, 'index.ts'));
|
||||
typedoc.generateJson(paths, outputPath);
|
||||
return fs.readJson(outputPath);
|
||||
}
|
||||
|
||||
function processPlugin(pluginModule): Plugin {
|
||||
const pluginClass = pluginModule.children.find(isPlugin);
|
||||
const decorator = getPluginDecorator(pluginClass);
|
||||
const packageName = `@ionic-native/${basename(dirname(pluginModule.originalName))}`;
|
||||
const displayName = getTag(pluginClass, 'name');
|
||||
const usage = getTag(pluginClass, 'usage');
|
||||
const description = getTag(pluginClass, 'description');
|
||||
return {
|
||||
packageName,
|
||||
displayName,
|
||||
description,
|
||||
usage,
|
||||
platforms: decorator.platforms,
|
||||
repo: decorator.repo,
|
||||
installVariables: decorator.installVariables,
|
||||
cordovaPlugin: {
|
||||
name: decorator.plugin
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Typedoc only gives us the Plugin decorator internals
|
||||
* as a string. So, rather than try to parse that with a RegExp,
|
||||
* we evaluate it using Node's vm module.
|
||||
*/
|
||||
const getPluginDecorator = (child: any) => {
|
||||
if (isPlugin(child)) {
|
||||
const decorator = child.decorators.find(d => d.name === 'Plugin');
|
||||
return runInNewContext(`(${decorator.arguments.config})`);
|
||||
}
|
||||
};
|
||||
|
||||
const getTag = (child: any, tagName: string): string => {
|
||||
if (hasTags(child)) {
|
||||
const tag = child.comment.tags.find(t => t.tag === tagName);
|
||||
if (tag) {
|
||||
return tag.text;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const isModule = (child: any): boolean =>
|
||||
child.kind === 1;
|
||||
|
||||
const isClass = (child: any): boolean =>
|
||||
child.kind === 128;
|
||||
|
||||
const isPlugin = (child: any): boolean =>
|
||||
isClass(child) && hasTags(child) && Array.isArray(child.decorators) && child.decorators.some(d => d.name === 'Plugin');
|
||||
|
||||
const hasPlugin = (child: any): boolean =>
|
||||
child.children.some(isPlugin);
|
||||
|
||||
const hasTags = (child: any): boolean =>
|
||||
child.comment && Array.isArray(child.comment.tags);
|
||||
3
scripts/docs-json/readme.md
Normal file
3
scripts/docs-json/readme.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# docs-json
|
||||
|
||||
This script reads and generates [typedoc](https://github.com/TypeStrong/typedoc) data for each of the plugins in `src/@ionic-native/plugins`. That data is then formatted and output as `plugins.json` in this directory.
|
||||
@@ -2,5 +2,5 @@
|
||||
"sitePath": "../ionic-site",
|
||||
"v2DocsDir": "docs/native",
|
||||
"docsDest": "../ionic-site/content/docs/native",
|
||||
"pluginDir": "dist/@ionic-native"
|
||||
"pluginDir": "dist/@ionic-native/plugins"
|
||||
}
|
||||
@@ -50,9 +50,9 @@ module.exports = currentVersion => {
|
||||
|
||||
// Don't run unwanted processors since we are not using the normal file reading processor
|
||||
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 = [
|
||||
'./src/@ionic-native/plugins/**/*.ts'
|
||||
];
|
||||
@@ -40,7 +40,6 @@ module.exports = currentVersion => {
|
||||
computePathsProcessor.pathTemplates = [{
|
||||
docTypes: ['class'],
|
||||
getOutputPath: doc => doc.originalModule.replace(config.pluginDir + '/', '')
|
||||
.replace('/plugins', '')
|
||||
.replace(/\/index$/, '/README.md')
|
||||
}];
|
||||
|
||||
@@ -50,15 +49,15 @@ module.exports = currentVersion => {
|
||||
.config(function(readFilesProcessor, readTypeScriptModules) {
|
||||
// Don't run unwanted processors since we are not using the normal file reading processor
|
||||
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'];
|
||||
})
|
||||
|
||||
// Configure file writing
|
||||
.config(function(writeFilesProcessor) {
|
||||
writeFilesProcessor.outputFolder = './dist/';
|
||||
writeFilesProcessor.outputFolder = './dist/@ionic-native/';
|
||||
})
|
||||
|
||||
// Configure rendering
|
||||
@@ -10,7 +10,7 @@ module.exports = function readmes(renderDocsProcessor) {
|
||||
docs = docs.filter(doc => (!!doc.name && !!doc.outputPath) || doc.docType === 'index-page');
|
||||
|
||||
docs.forEach(doc => {
|
||||
doc.outputPath = doc.outputPath.replace('src/', '');
|
||||
doc.outputPath = doc.outputPath.replace('src/@ionic-native/', '');
|
||||
});
|
||||
|
||||
return docs;
|
||||
@@ -187,7 +187,7 @@ docType: "<$ doc.docType $>"
|
||||
<ol class="installation">
|
||||
<li>Install the Cordova and Ionic Native plugins:<br>
|
||||
<pre><code class="nohighlight">$ <@ if prop.install @><$ prop.install | replace('<', '<').replace('>', '>') $><@ else @>ionic cordova plugin add <$ prop.plugin $><@ endif @>
|
||||
$ npm install --save @ionic-native/<$ doc.npmId $>
|
||||
$ npm install @ionic-native/<$ doc.npmId $>
|
||||
</code></pre>
|
||||
</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>
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
```
|
||||
$ <@ 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 $>
|
||||
```
|
||||
|
||||
## [Usage Documentation](https://ionicframework.com/docs/native/<$ doc.fileInfo.relativePath|replace('/home/ubuntu/ionic-native/', '')|replace('//','/')|replace('index.ts','')|replace('src/@ionic-native/plugins/','') $>)
|
||||
@@ -1,39 +1,34 @@
|
||||
"use strict";
|
||||
const config = require('../config.json'),
|
||||
'use strict';
|
||||
const config = require('./config.json'),
|
||||
projectPackage = require('../../package.json'),
|
||||
path = require('path'),
|
||||
fs = require('fs-extra-promise').useFs(require('fs-extra')),
|
||||
fs = require('fs-extra'),
|
||||
Dgeni = require('dgeni');
|
||||
|
||||
module.exports = gulp => {
|
||||
gulp.task('docs', [], () => {
|
||||
|
||||
gulp.task('docs', () => {
|
||||
try {
|
||||
|
||||
const ionicPackage = require('./dgeni-config')(projectPackage.version),
|
||||
const ionicPackage = require('./dgeni/dgeni-config')(projectPackage.version),
|
||||
dgeni = new Dgeni([ionicPackage]);
|
||||
|
||||
return dgeni.generate().then(docs => console.log(docs.length + ' docs generated'));
|
||||
|
||||
} catch (err) {
|
||||
console.log(err.stack);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
gulp.task('readmes', [], function() {
|
||||
|
||||
fs.copySync(path.resolve(__dirname, '..', '..', 'README.md'), path.resolve(__dirname, '..', '..', config.pluginDir, 'core', 'README.md'));
|
||||
gulp.task('readmes', () => {
|
||||
fs.copySync(
|
||||
path.resolve(__dirname, '..', '..', 'README.md'),
|
||||
path.resolve(__dirname, '..', '..', config.pluginDir, 'core', 'README.md')
|
||||
);
|
||||
|
||||
try {
|
||||
|
||||
const ionicPackage = require('./dgeni-readmes-config')(projectPackage.version),
|
||||
const ionicPackage = require('./dgeni/dgeni-readmes-config')(projectPackage.version),
|
||||
dgeni = new Dgeni([ionicPackage]);
|
||||
return dgeni.generate().then(docs => console.log(docs.length + ' README files generated'));
|
||||
|
||||
} catch (err) {
|
||||
console.log(err.stack);
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
@@ -34,4 +34,4 @@ function run {
|
||||
|
||||
}
|
||||
|
||||
source $(dirname $0)/../utils.inc.sh
|
||||
source $(dirname $0)/utils.inc.sh
|
||||
|
||||
@@ -47,4 +47,4 @@ function run {
|
||||
fi
|
||||
}
|
||||
|
||||
source $(dirname $0)/../utils.inc.sh
|
||||
source $(dirname $0)/utils.inc.sh
|
||||
|
||||
@@ -31,7 +31,7 @@ function run {
|
||||
|
||||
# git push origin master || :
|
||||
|
||||
echo "-- Updated docs for $VERSION_NAME succesfully!"
|
||||
echo "-- Updated docs for $VERSION_NAME successfully!"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
3
scripts/utils.inc.sh → scripts/docs/utils.inc.sh
Executable file → Normal file
3
scripts/utils.inc.sh → scripts/docs/utils.inc.sh
Executable file → Normal file
@@ -1,5 +1,4 @@
|
||||
# bash utils from angularjs
|
||||
|
||||
# This file provides:
|
||||
# - a default control flow
|
||||
# * initializes the environment
|
||||
@@ -36,7 +35,6 @@
|
||||
# Special arguments that are always available:
|
||||
# - "--action=.*": This parameter will be used to dispatch to a function with that name when the
|
||||
# script is started
|
||||
|
||||
# - "--verbose=true": This will set the `-x` flag in bash so that all calls will be logged
|
||||
#
|
||||
# Utility functions:
|
||||
@@ -46,7 +44,6 @@
|
||||
# - getVar
|
||||
# - serVar
|
||||
# - isFunction
|
||||
|
||||
# always stop on errors
|
||||
set -e
|
||||
|
||||
11
scripts/logger.ts
Normal file
11
scripts/logger.ts
Normal 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 })]
|
||||
});
|
||||
97
scripts/tasks/build-es5.ts
Normal file
97
scripts/tasks/build-es5.ts
Normal 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();
|
||||
46
scripts/tasks/build-esm.ts
Normal file
46
scripts/tasks/build-esm.ts
Normal 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');
|
||||
});
|
||||
13
scripts/tasks/build-ngx.ts
Normal file
13
scripts/tasks/build-ngx.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import {
|
||||
cleanupNgx,
|
||||
generateDeclarationFiles,
|
||||
modifyMetadata,
|
||||
transpileNgx,
|
||||
transpileNgxCore
|
||||
} from '../build/ngx';
|
||||
|
||||
transpileNgxCore();
|
||||
transpileNgx();
|
||||
generateDeclarationFiles();
|
||||
modifyMetadata();
|
||||
cleanupNgx();
|
||||
109
scripts/tasks/publish.ts
Normal file
109
scripts/tasks/publish.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
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';
|
||||
|
||||
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 MIN_CORE_VERSION = '^5.1.0';
|
||||
const RXJS_VERSION = '^5.5.0 || ^6.5.0';
|
||||
|
||||
const PLUGIN_PEER_DEPENDENCIES = {
|
||||
'@ionic-native/core': MIN_CORE_VERSION,
|
||||
rxjs: RXJS_VERSION
|
||||
};
|
||||
|
||||
function getPackageJsonContent(name: string, 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();
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Plugin, Cordova, CordovaProperty, CordovaInstance, InstanceProperty, IonicNativePlugin } from '@ionic-native/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/**
|
||||
* @name {{ Plugin_Name }}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Plugin, Cordova, CordovaProperty, CordovaInstance, InstanceProperty, IonicNativePlugin } from '@ionic-native/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/**
|
||||
* @name {{ Plugin_Name }}
|
||||
|
||||
12
scripts/tsconfig.json
Normal file
12
scripts/tsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": false,
|
||||
"lib": ["es6"]
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
@@ -1,25 +1,26 @@
|
||||
export function checkReady() {
|
||||
const DEVICE_READY_TIMEOUT = 5000;
|
||||
if (typeof process === 'undefined') {
|
||||
const win: any = typeof window !== 'undefined' ? window : {};
|
||||
const DEVICE_READY_TIMEOUT = 5000;
|
||||
|
||||
// To help developers using cordova, we listen for the device ready event and
|
||||
// log an error if it didn't fire in a reasonable amount of time. Generally,
|
||||
// when this happens, developers should remove and reinstall plugins, since
|
||||
// an inconsistent plugin is often the culprit.
|
||||
const before = Date.now();
|
||||
// To help developers using cordova, we listen for the device ready event and
|
||||
// log an error if it didn't fire in a reasonable amount of time. Generally,
|
||||
// when this happens, developers should remove and reinstall plugins, since
|
||||
// an inconsistent plugin is often the culprit.
|
||||
const before = Date.now();
|
||||
|
||||
let didFireReady = false;
|
||||
document.addEventListener('deviceready', () => {
|
||||
console.log(
|
||||
`Ionic Native: deviceready event fired after ${Date.now() - before} ms`
|
||||
);
|
||||
didFireReady = true;
|
||||
});
|
||||
let didFireReady = false;
|
||||
win.document.addEventListener('deviceready', () => {
|
||||
console.log(`Ionic Native: deviceready event fired after ${Date.now() - before} ms`);
|
||||
didFireReady = true;
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
if (!didFireReady && !!window.cordova) {
|
||||
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.`
|
||||
);
|
||||
}
|
||||
}, DEVICE_READY_TIMEOUT);
|
||||
setTimeout(() => {
|
||||
if (!didFireReady && win.cordova) {
|
||||
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.`
|
||||
);
|
||||
}
|
||||
}, DEVICE_READY_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(<any>plugin.pingSync()).toEqual(ERR_PLUGIN_NOT_INSTALLED);
|
||||
|
||||
plugin.ping().catch(e => {
|
||||
expect(e).toEqual(ERR_PLUGIN_NOT_INSTALLED.error);
|
||||
delete window.cordova;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw cordova_not_available error', (done: Function) => {
|
||||
delete window.testPlugin;
|
||||
|
||||
expect(<any>plugin.pingSync()).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');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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: function(...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: function(...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 function(cls: any) {
|
||||
// Add these fields to the class
|
||||
for (let prop in config) {
|
||||
cls[prop] = config[prop];
|
||||
}
|
||||
|
||||
cls['installed'] = function(printWarning?: boolean) {
|
||||
return !!getPlugin(config.pluginRef);
|
||||
};
|
||||
|
||||
cls['getPlugin'] = function() {
|
||||
return getPlugin(config.pluginRef);
|
||||
};
|
||||
|
||||
cls['checkInstall'] = function() {
|
||||
return checkAvailability(cls) === true;
|
||||
};
|
||||
|
||||
cls['getPluginName'] = function() {
|
||||
return config.pluginName;
|
||||
};
|
||||
|
||||
cls['getPluginRef'] = function() {
|
||||
return config.pluginRef;
|
||||
};
|
||||
|
||||
cls['getPluginInstallName'] = function() {
|
||||
return config.plugin;
|
||||
};
|
||||
|
||||
cls['getPluginRepo'] = function() {
|
||||
return config.repo;
|
||||
};
|
||||
|
||||
cls['getSupportedPlatforms'] = function() {
|
||||
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: function(...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: function(...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: function() {
|
||||
return this._objectInstance[key];
|
||||
},
|
||||
set: function(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: function(...args: any[]) {
|
||||
return overrideFunction(this, methodName, opts);
|
||||
},
|
||||
enumerable: true
|
||||
};
|
||||
};
|
||||
}
|
||||
100
src/@ionic-native/core/decorators/common.spec.ts
Normal file
100
src/@ionic-native/core/decorators/common.spec.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
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');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,179 +1,49 @@
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { fromEvent } from 'rxjs/observable/fromEvent';
|
||||
import { fromEvent, Observable } from 'rxjs';
|
||||
|
||||
import { checkReady } from './bootstrap';
|
||||
import { CordovaOptions } from './decorators';
|
||||
import { cordovaWarn, getPlugin, getPromise, pluginWarn } from './util';
|
||||
import { CordovaOptions } from './interfaces';
|
||||
|
||||
checkReady();
|
||||
|
||||
// declare const window;
|
||||
// declare var Promise;
|
||||
declare const window: any;
|
||||
|
||||
export const ERR_CORDOVA_NOT_AVAILABLE = { error: 'cordova_not_available' };
|
||||
export const ERR_PLUGIN_NOT_INSTALLED = { error: 'plugin_not_installed' };
|
||||
|
||||
/**
|
||||
* 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')
|
||||
);
|
||||
}
|
||||
|
||||
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
|
||||
) {
|
||||
let 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();
|
||||
export function getPromise<T>(callback: (resolve: Function, reject?: Function) => any): Promise<T> {
|
||||
const tryNativePromise = () => {
|
||||
if (Promise) {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
callback(resolve, reject);
|
||||
});
|
||||
} else {
|
||||
setSuccessIndex();
|
||||
setErrorIndex();
|
||||
console.error(
|
||||
'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
|
||||
args.push(resolve);
|
||||
args.push(reject);
|
||||
};
|
||||
|
||||
if (typeof window !== 'undefined' && window.angular) {
|
||||
const doc = window.document;
|
||||
const injector = window.angular
|
||||
.element(doc.querySelector('[ng-app]') || doc.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,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
function wrapPromise(
|
||||
pluginObj: any,
|
||||
methodName: string,
|
||||
args: any[],
|
||||
opts: any = {}
|
||||
opts: CordovaOptions = {}
|
||||
) {
|
||||
let pluginResult: any, rej: Function;
|
||||
const p = getPromise((resolve: Function, reject: Function) => {
|
||||
@@ -187,14 +57,7 @@ function wrapPromise(
|
||||
(...args: any[]) => reject(args)
|
||||
);
|
||||
} else {
|
||||
pluginResult = callCordovaPlugin(
|
||||
pluginObj,
|
||||
methodName,
|
||||
args,
|
||||
opts,
|
||||
resolve,
|
||||
reject
|
||||
);
|
||||
pluginResult = callCordovaPlugin(pluginObj, methodName, args, opts, resolve, reject);
|
||||
}
|
||||
rej = reject;
|
||||
});
|
||||
@@ -208,12 +71,7 @@ function wrapPromise(
|
||||
return p;
|
||||
}
|
||||
|
||||
function wrapOtherPromise(
|
||||
pluginObj: any,
|
||||
methodName: string,
|
||||
args: any[],
|
||||
opts: any = {}
|
||||
) {
|
||||
function wrapOtherPromise(pluginObj: any, methodName: string, args: any[], opts: any = {}) {
|
||||
return getPromise((resolve: Function, reject: Function) => {
|
||||
const pluginResult = callCordovaPlugin(pluginObj, methodName, args, opts);
|
||||
if (pluginResult) {
|
||||
@@ -228,12 +86,7 @@ function wrapOtherPromise(
|
||||
});
|
||||
}
|
||||
|
||||
function wrapObservable(
|
||||
pluginObj: any,
|
||||
methodName: string,
|
||||
args: any[],
|
||||
opts: any = {}
|
||||
) {
|
||||
function wrapObservable(pluginObj: any, methodName: string, args: any[], opts: any = {}) {
|
||||
return new Observable(observer => {
|
||||
let pluginResult;
|
||||
|
||||
@@ -288,7 +141,157 @@ function wrapObservable(
|
||||
});
|
||||
}
|
||||
|
||||
function callInstance(
|
||||
/**
|
||||
* Wrap the event with an observable
|
||||
* @private
|
||||
* @param event event name
|
||||
* @param element The element to attach the event listener to
|
||||
* @returns {Observable}
|
||||
*/
|
||||
function wrapEventObservable(event: string, element: any): Observable<any> {
|
||||
element = (typeof window !== 'undefined' && element) ? get(window, element) : element || (typeof window !== 'undefined' ? 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 (typeof window === 'undefined' || !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,
|
||||
methodName: string,
|
||||
args: any[],
|
||||
@@ -299,67 +302,81 @@ function callInstance(
|
||||
args = setIndex(args, opts, resolve, reject);
|
||||
|
||||
if (instanceAvailability(pluginObj, methodName)) {
|
||||
return pluginObj._objectInstance[methodName].apply(
|
||||
pluginObj._objectInstance,
|
||||
args
|
||||
return pluginObj._objectInstance[methodName].apply(pluginObj._objectInstance, args);
|
||||
}
|
||||
}
|
||||
|
||||
export function getPlugin(pluginRef: string): any {
|
||||
if (typeof window !== 'undefined') {
|
||||
return get(window, pluginRef);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function get(element: Element | Window, path: string) {
|
||||
const paths: string[] = path.split('.');
|
||||
let obj: any = element;
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
if (!obj) {
|
||||
return null;
|
||||
}
|
||||
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}'`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the event with an observable
|
||||
* @private
|
||||
* @param event even name
|
||||
* @param element The element to attach the event listener to
|
||||
* @returns {Observable}
|
||||
* @param pluginName
|
||||
* @param method
|
||||
*/
|
||||
export function wrapEventObservable(
|
||||
event: string,
|
||||
element: any = window
|
||||
): Observable<any> {
|
||||
return fromEvent(element, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Certain plugins expect the user to override methods in the plugin. For example,
|
||||
* window.cordova.plugins.backgroundMode.onactivate = function() { ... }.
|
||||
*
|
||||
* Unfortunately, this is brittle and would be better wrapped as an Observable. overrideFunction
|
||||
* does just this.
|
||||
* @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] = () => {});
|
||||
export function cordovaWarn(pluginName: string, method?: string): void {
|
||||
if (typeof process === 'undefined') {
|
||||
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 {
|
||||
observer.error(availabilityCheck);
|
||||
observer.complete();
|
||||
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
|
||||
*/
|
||||
export const wrap = function(
|
||||
pluginObj: any,
|
||||
methodName: string,
|
||||
opts: CordovaOptions = {}
|
||||
) {
|
||||
export const wrap = (pluginObj: any, methodName: string, opts: CordovaOptions = {}): WrapFn => {
|
||||
return (...args: any[]) => {
|
||||
if (opts.sync) {
|
||||
// Sync doesn't wrap the plugin with a promise or observable, it returns the result as-is
|
||||
@@ -379,11 +396,7 @@ export const wrap = function(
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export function wrapInstance(
|
||||
pluginObj: any,
|
||||
methodName: string,
|
||||
opts: any = {}
|
||||
) {
|
||||
export function wrapInstance(pluginObj: any, methodName: string, opts: any = {}): Function {
|
||||
return (...args: any[]) => {
|
||||
if (opts.sync) {
|
||||
return callInstance(pluginObj, methodName, args, opts);
|
||||
@@ -413,7 +426,6 @@ export function wrapInstance(
|
||||
|
||||
if (pluginResult && pluginResult.error) {
|
||||
observer.error(pluginResult.error);
|
||||
observer.complete();
|
||||
}
|
||||
|
||||
return () => {
|
||||
@@ -452,16 +464,9 @@ export function wrapInstance(
|
||||
(...args: any[]) => reject(args)
|
||||
);
|
||||
} else {
|
||||
result = callInstance(
|
||||
pluginObj,
|
||||
methodName,
|
||||
args,
|
||||
opts,
|
||||
resolve,
|
||||
reject
|
||||
);
|
||||
result = callInstance(pluginObj, methodName, args, opts, resolve, reject);
|
||||
}
|
||||
if (result && !!result.then) {
|
||||
if (result && result.then) {
|
||||
result.then(resolve, reject);
|
||||
} else {
|
||||
reject();
|
||||
@@ -480,14 +485,7 @@ export function wrapInstance(
|
||||
(...args: any[]) => reject(args)
|
||||
);
|
||||
} else {
|
||||
pluginResult = callInstance(
|
||||
pluginObj,
|
||||
methodName,
|
||||
args,
|
||||
opts,
|
||||
resolve,
|
||||
reject
|
||||
);
|
||||
pluginResult = callInstance(pluginObj, methodName, args, opts, resolve, reject);
|
||||
}
|
||||
rej = reject;
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
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);
|
||||
}
|
||||
12
src/@ionic-native/core/decorators/cordova-instance.ts
Normal file
12
src/@ionic-native/core/decorators/cordova-instance.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
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);
|
||||
}
|
||||
14
src/@ionic-native/core/decorators/cordova-property.ts
Normal file
14
src/@ionic-native/core/decorators/cordova-property.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
11
src/@ionic-native/core/decorators/cordova.ts
Normal file
11
src/@ionic-native/core/decorators/cordova.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
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);
|
||||
}
|
||||
12
src/@ionic-native/core/decorators/instance-property.ts
Normal file
12
src/@ionic-native/core/decorators/instance-property.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
107
src/@ionic-native/core/decorators/interfaces.ts
Normal file
107
src/@ionic-native/core/decorators/interfaces.ts
Normal 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;
|
||||
@@ -1,4 +1,14 @@
|
||||
export * from './plugin';
|
||||
export * from './decorators';
|
||||
export * from './util';
|
||||
export * from './ionic-native-plugin';
|
||||
import { checkReady } from './bootstrap';
|
||||
|
||||
export { IonicNativePlugin } 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();
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
@@ -1,3 +1,6 @@
|
||||
import { checkAvailability } from './decorators/common';
|
||||
import { get } from './util';
|
||||
|
||||
export class IonicNativePlugin {
|
||||
static pluginName: string;
|
||||
|
||||
@@ -16,39 +19,44 @@ export class IonicNativePlugin {
|
||||
* @return {boolean}
|
||||
*/
|
||||
static installed(): boolean {
|
||||
return false;
|
||||
return checkAvailability(this.pluginRef) === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the original plugin object
|
||||
*/
|
||||
static getPlugin(): any {}
|
||||
static getPlugin(): any {
|
||||
if (typeof window !== 'undefined') {
|
||||
return get(window, this.pluginRef);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin's name
|
||||
*/
|
||||
static getPluginName(): string {
|
||||
return;
|
||||
return this.pluginName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin's reference
|
||||
*/
|
||||
static getPluginRef(): string {
|
||||
return;
|
||||
return this.pluginRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin's install name
|
||||
*/
|
||||
static getPluginInstallName(): string {
|
||||
return;
|
||||
return this.plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin's supported platforms
|
||||
*/
|
||||
static getSupportedPlatforms(): string[] {
|
||||
return;
|
||||
return this.platforms || [];
|
||||
}
|
||||
}
|
||||
|
||||
27
src/@ionic-native/core/ng1.ts
Normal file
27
src/@ionic-native/core/ng1.ts
Normal 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 (typeof window !== 'undefined' && 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,25 +3,25 @@ declare const window: any;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export const get = (element: Element | Window, path: string): any => {
|
||||
export function get(element: Element | Window, path: string) {
|
||||
const paths: string[] = path.split('.');
|
||||
let obj: any = element;
|
||||
for (let i: number = 0; i < paths.length; i++) {
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
if (!obj) {
|
||||
return null;
|
||||
}
|
||||
obj = obj[paths[i]];
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export const getPromise = (callback: Function): Promise<any> => {
|
||||
export function getPromise(callback: Function = () => {}): Promise<any> {
|
||||
const tryNativePromise = () => {
|
||||
if (window.Promise) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof Promise === 'function' || (typeof window !== 'undefined' && window.Promise)) {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
callback(resolve, reject);
|
||||
});
|
||||
} else {
|
||||
@@ -32,66 +32,4 @@ export const getPromise = (callback: Function): Promise<any> => {
|
||||
};
|
||||
|
||||
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'
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ declare const AbbyyRtrSdk: any;
|
||||
* default setting will be used.
|
||||
*/
|
||||
export interface TextCaptureOptions {
|
||||
|
||||
/**
|
||||
* The name of the license file. This file must be located in the
|
||||
* www/rtr_assets/ directory in your project.
|
||||
@@ -21,12 +20,12 @@ export interface TextCaptureOptions {
|
||||
* for example: ["English", "French", "German"]. Empty array
|
||||
* disables language selection.
|
||||
*/
|
||||
selectableRecognitionLanguages?: Array<string>;
|
||||
selectableRecognitionLanguages?: string[];
|
||||
|
||||
/**
|
||||
* Recognition language selected by default.
|
||||
*/
|
||||
recognitionLanguages?: Array<string>;
|
||||
recognitionLanguages?: string[];
|
||||
|
||||
/**
|
||||
* Width and height of the recognition area, separated by a
|
||||
@@ -57,6 +56,11 @@ export interface TextCaptureOptions {
|
||||
* the latest recognition result.
|
||||
*/
|
||||
isStopButtonVisible?: boolean;
|
||||
|
||||
/**
|
||||
* Specify the orientation, possible values 'landscape' or 'portrait'.
|
||||
*/
|
||||
orientation?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +68,6 @@ export interface TextCaptureOptions {
|
||||
* The callback you implement should parse this object and show results to user.
|
||||
*/
|
||||
export interface TextCaptureResult {
|
||||
|
||||
/**
|
||||
* An array of objects representing recognized lines of text.
|
||||
* These objects have the following keys:
|
||||
@@ -75,7 +78,7 @@ export interface TextCaptureResult {
|
||||
* · rect (string): position and size of the bounding rectangle,
|
||||
* a string of 4 integers separated with whitespaces ("x y width height").
|
||||
*/
|
||||
textLines: Array<{ text: string, quadrangle: string, rect?: string }>;
|
||||
textLines: { text: string; quadrangle: string; rect?: string }[];
|
||||
|
||||
/**
|
||||
* Additional information. This object has the following keys:
|
||||
@@ -91,10 +94,10 @@ export interface TextCaptureResult {
|
||||
* the array contains language identifiers (["English", "French", "German"]).
|
||||
*/
|
||||
resultInfo: {
|
||||
stabilityStatus: string,
|
||||
userAction: string,
|
||||
frameSize: string,
|
||||
recognitionLanguages: Array<string>
|
||||
stabilityStatus: string;
|
||||
userAction: string;
|
||||
frameSize: string;
|
||||
recognitionLanguages: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -114,7 +117,6 @@ export interface TextCaptureResult {
|
||||
* keys: you must specify either one of them, but not both at the same time.
|
||||
*/
|
||||
export interface DataCaptureOptions {
|
||||
|
||||
/**
|
||||
* The predefined data capture profile to use, for example: "MRZ".
|
||||
* Note: For the list of supported documents, see Specifications — Data
|
||||
@@ -134,10 +136,10 @@ export interface DataCaptureOptions {
|
||||
* the regular expression that should be matched when capturing a field.
|
||||
*/
|
||||
customDataCaptureScenario?: {
|
||||
name: string,
|
||||
description: string,
|
||||
recognitionLanguages: Array<string>,
|
||||
fields: Array<{ regEx: string }>
|
||||
name: string;
|
||||
description: string;
|
||||
recognitionLanguages: string[];
|
||||
fields: { regEx: string }[];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -175,6 +177,11 @@ export interface DataCaptureOptions {
|
||||
* the latest recognition result.
|
||||
*/
|
||||
isStopButtonVisible?: boolean;
|
||||
|
||||
/**
|
||||
* Specify the orientation, possible values 'landscape' or 'portrait'.
|
||||
*/
|
||||
orientation?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,7 +189,6 @@ export interface DataCaptureOptions {
|
||||
* implement should parse this object and show results to user.
|
||||
*/
|
||||
export interface DataCaptureResult {
|
||||
|
||||
/**
|
||||
* The data scheme which was applied during data capture.
|
||||
* The value is an object which has two keys:
|
||||
@@ -195,8 +201,8 @@ export interface DataCaptureResult {
|
||||
* present in the result.
|
||||
*/
|
||||
dataScheme?: {
|
||||
id: string,
|
||||
name: string
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -222,15 +228,15 @@ export interface DataCaptureResult {
|
||||
* of 4 integers separated with whitespaces ("x y width height").
|
||||
*/
|
||||
dataFields: {
|
||||
id: string,
|
||||
name: string,
|
||||
text: string,
|
||||
quadrangle: string,
|
||||
id: string;
|
||||
name: string;
|
||||
text: string;
|
||||
quadrangle: string;
|
||||
components: {
|
||||
text: string,
|
||||
quadrangle: string,
|
||||
rect: string
|
||||
}
|
||||
text: string;
|
||||
quadrangle: string;
|
||||
rect: string;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -245,9 +251,9 @@ export interface DataCaptureResult {
|
||||
* with 2 integers separated with a whitespace ("720 1280").
|
||||
*/
|
||||
resultInfo: {
|
||||
stabilityStatus: string,
|
||||
userAction: string,
|
||||
frameSize: string
|
||||
stabilityStatus: string;
|
||||
userAction: string;
|
||||
frameSize: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -268,7 +274,7 @@ export interface DataCaptureResult {
|
||||
*
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { AbbyyRTR } from '@ionic-native/abbyy-rtr';
|
||||
* import { AbbyyRTR } from '@ionic-native/abbyy-rtr/ngx';
|
||||
*
|
||||
*
|
||||
* constructor(private abbyyRTR: AbbyyRTR) { }
|
||||
@@ -297,7 +303,6 @@ export interface DataCaptureResult {
|
||||
})
|
||||
@Injectable()
|
||||
export class AbbyyRTR extends IonicNativePlugin {
|
||||
|
||||
/**
|
||||
* Opens a modal dialog with controls for the Text Capture scenario.
|
||||
* @param {TextCaptureOptions} options
|
||||
|
||||
@@ -62,7 +62,7 @@ export interface ActionSheetOptions {
|
||||
*
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { ActionSheet, ActionSheetOptions } from '@ionic-native/action-sheet';
|
||||
* import { ActionSheet, ActionSheetOptions } from '@ionic-native/action-sheet/ngx';
|
||||
*
|
||||
* constructor(private actionSheet: ActionSheet) { }
|
||||
*
|
||||
@@ -79,7 +79,7 @@ export interface ActionSheetOptions {
|
||||
* addDestructiveButtonWithLabel: 'Delete',
|
||||
* androidTheme: this.actionSheet.ANDROID_THEMES.THEME_HOLO_DARK,
|
||||
* destructiveButtonLast: true
|
||||
* };
|
||||
* }
|
||||
*
|
||||
* this.actionSheet.show(options).then((buttonIndex: number) => {
|
||||
* console.log('Button pressed: ' + buttonIndex);
|
||||
|
||||
461
src/@ionic-native/plugins/adjust/index.ts
Normal file
461
src/@ionic-native/plugins/adjust/index.ts
Normal file
@@ -0,0 +1,461 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
|
||||
export class AdjustEvent {
|
||||
private eventToken: string;
|
||||
private revenue: number;
|
||||
private currency: string;
|
||||
private transactionId: string;
|
||||
private callbackId: string;
|
||||
private callbackParameters: string[] = [];
|
||||
private partnerParameters: string[] = [];
|
||||
|
||||
constructor(eventToken: string) {
|
||||
this.eventToken = eventToken;
|
||||
}
|
||||
|
||||
setRevenue(revenue: number, currency: string): void {
|
||||
this.revenue = revenue;
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
addCallbackParameter(key: string, value: string): void {
|
||||
this.callbackParameters.push(key);
|
||||
this.callbackParameters.push(value);
|
||||
}
|
||||
|
||||
addPartnerParameter(key: string, value: string): void {
|
||||
this.partnerParameters.push(key);
|
||||
this.partnerParameters.push(value);
|
||||
}
|
||||
|
||||
setTransactionId(transactionId: string) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
setCallbackId(callbackId: string) {
|
||||
this.callbackId = callbackId;
|
||||
}
|
||||
}
|
||||
|
||||
export class AdjustConfig {
|
||||
private appToken: string;
|
||||
private environment: AdjustEnvironment;
|
||||
private sdkPrefix: string;
|
||||
private delayStart = 0.0;
|
||||
private logLevel: AdjustLogLevel = null;
|
||||
private defaultTracker: string = null;
|
||||
private sendInBackground: boolean = null;
|
||||
private shouldLaunchDeeplink: boolean = null;
|
||||
private eventBufferingEnabled: boolean = null;
|
||||
private userAgent: string = null;
|
||||
private isDeviceKnown: boolean = null;
|
||||
private secretId: number = null;
|
||||
private info1: number = null;
|
||||
private info2: number = null;
|
||||
private info3: number = null;
|
||||
private info4: number = null;
|
||||
private processName: string = null; // Android only
|
||||
|
||||
private attributionCallback: (attribution: AdjustAttribution) => void = null;
|
||||
private eventTrackingSucceededCallback: (event: AdjustEventSuccess) => void = null;
|
||||
private eventTrackingFailedCallback: (event: AdjustEventFailure) => void = null;
|
||||
private sessionTrackingSucceededCallback: (session: AdjustSessionSuccess) => void = null;
|
||||
private sessionTrackingFailedCallback: (session: AdjustSessionFailure) => void = null;
|
||||
private deferredDeeplinkCallback: (uri: string) => void = null;
|
||||
|
||||
constructor(appToken: string, environment: AdjustEnvironment) {
|
||||
this.appToken = appToken;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
setAppSecret(secretId: number, info1: number, info2: number, info3: number, info4: number): void {
|
||||
this.secretId = secretId;
|
||||
this.info1 = info1;
|
||||
this.info2 = info2;
|
||||
this.info3 = info3;
|
||||
this.info4 = info4;
|
||||
}
|
||||
|
||||
setDelayStart(delayStart: number) {
|
||||
this.delayStart = delayStart;
|
||||
}
|
||||
|
||||
setLogLevel(logLevel: AdjustLogLevel) {
|
||||
this.logLevel = logLevel;
|
||||
}
|
||||
|
||||
setDefaultTracker(defaultTracker: string) {
|
||||
this.defaultTracker = defaultTracker;
|
||||
}
|
||||
|
||||
setSendInBackground(sendInBackground: boolean) {
|
||||
this.sendInBackground = sendInBackground;
|
||||
}
|
||||
|
||||
setShouldLaunchDeeplink(shouldLaunchDeeplink: boolean) {
|
||||
this.shouldLaunchDeeplink = shouldLaunchDeeplink;
|
||||
}
|
||||
|
||||
setEventBufferingEnabled(eventBufferingEnabled: boolean) {
|
||||
this.eventBufferingEnabled = eventBufferingEnabled;
|
||||
}
|
||||
|
||||
setUserAgent(userAgent: string) {
|
||||
this.userAgent = userAgent;
|
||||
}
|
||||
|
||||
setDeviceKnown(isDeviceKnown: boolean) {
|
||||
this.isDeviceKnown = isDeviceKnown;
|
||||
}
|
||||
|
||||
setProcessName(processName: string) {
|
||||
this.processName = processName;
|
||||
}
|
||||
|
||||
setAttributionCallbackListener(attributionCallback: (attribution: AdjustAttribution) => void) {
|
||||
this.attributionCallback = attributionCallback;
|
||||
}
|
||||
|
||||
setEventTrackingSucceededCallbackListener(
|
||||
eventTrackingSucceededCallback: (event: AdjustEventSuccess) => void
|
||||
) {
|
||||
this.eventTrackingSucceededCallback = eventTrackingSucceededCallback;
|
||||
}
|
||||
|
||||
setEventTrackingFailedCallbackListener(
|
||||
eventTrackingFailedCallback: (event: AdjustEventFailure) => void
|
||||
) {
|
||||
this.eventTrackingFailedCallback = eventTrackingFailedCallback;
|
||||
}
|
||||
|
||||
setSessionTrackingSucceededCallbackListener(
|
||||
sessionTrackingSucceededCallback: (session: AdjustSessionSuccess) => void
|
||||
) {
|
||||
this.sessionTrackingSucceededCallback = sessionTrackingSucceededCallback;
|
||||
}
|
||||
|
||||
setSessionTrackingFailedCallbackListener(
|
||||
sessionTrackingFailedCallback: (session: AdjustSessionFailure) => void
|
||||
) {
|
||||
this.sessionTrackingFailedCallback = sessionTrackingFailedCallback;
|
||||
}
|
||||
|
||||
setDeferredDeeplinkCallbackListener(deferredDeeplinkCallback: (uri: string) => void) {
|
||||
this.deferredDeeplinkCallback = deferredDeeplinkCallback;
|
||||
}
|
||||
|
||||
private getAttributionCallback() {
|
||||
return this.attributionCallback;
|
||||
}
|
||||
|
||||
private getEventTrackingSucceededCallback() {
|
||||
return this.eventTrackingSucceededCallback;
|
||||
}
|
||||
|
||||
private getEventTrackingFailedCallback() {
|
||||
return this.eventTrackingFailedCallback;
|
||||
}
|
||||
|
||||
private getSessionTrackingSucceededCallback() {
|
||||
return this.sessionTrackingSucceededCallback;
|
||||
}
|
||||
|
||||
private getSessionTrackingFailedCallback() {
|
||||
return this.sessionTrackingFailedCallback;
|
||||
}
|
||||
|
||||
private getDeferredDeeplinkCallback() {
|
||||
return this.deferredDeeplinkCallback;
|
||||
}
|
||||
|
||||
private hasAttributionListener() {
|
||||
return this.attributionCallback !== null;
|
||||
}
|
||||
|
||||
private hasEventTrackingSucceededListener() {
|
||||
return this.eventTrackingSucceededCallback !== null;
|
||||
}
|
||||
|
||||
private hasEventTrackingFailedListener() {
|
||||
return this.eventTrackingFailedCallback !== null;
|
||||
}
|
||||
|
||||
private hasSessionTrackingSucceededListener() {
|
||||
return this.sessionTrackingSucceededCallback !== null;
|
||||
}
|
||||
|
||||
private hasSessionTrackingFailedListener() {
|
||||
return this.sessionTrackingFailedCallback !== null;
|
||||
}
|
||||
|
||||
private hasDeferredDeeplinkCallbackListener() {
|
||||
return this.deferredDeeplinkCallback !== null;
|
||||
}
|
||||
}
|
||||
|
||||
export interface AdjustAttribution {
|
||||
trackerToken: string;
|
||||
trackerName: string;
|
||||
network: string;
|
||||
campaign: string;
|
||||
adgroup: string;
|
||||
creative: string;
|
||||
clickLabel: string;
|
||||
adid: string;
|
||||
}
|
||||
|
||||
export interface AdjustSessionSuccess {
|
||||
message: string;
|
||||
timestamp: string;
|
||||
adid: string;
|
||||
jsonResponse: string;
|
||||
}
|
||||
|
||||
export interface AdjustSessionFailure {
|
||||
message: string;
|
||||
timestamp: string;
|
||||
adid: string;
|
||||
willRetry: boolean;
|
||||
jsonResponse: string;
|
||||
}
|
||||
|
||||
export interface AdjustEventSuccess {
|
||||
message: string;
|
||||
timestamp: string;
|
||||
adid: string;
|
||||
eventToken: string;
|
||||
callbackId: string;
|
||||
jsonResponse: string;
|
||||
}
|
||||
|
||||
export interface AdjustEventFailure {
|
||||
message: string;
|
||||
timestamp: string;
|
||||
adid: string;
|
||||
eventToken: string;
|
||||
willRetry: boolean;
|
||||
callbackId: string;
|
||||
jsonResponse: string;
|
||||
}
|
||||
|
||||
export enum AdjustEnvironment {
|
||||
Sandbox = 'sandbox',
|
||||
Production = 'production'
|
||||
}
|
||||
|
||||
export enum AdjustLogLevel {
|
||||
Verbose = 'VERBOSE',
|
||||
Debug = 'DEBUG',
|
||||
Info = 'INFO',
|
||||
Warn = 'WARN',
|
||||
Error = 'ERROR',
|
||||
Assert = 'ASSERT',
|
||||
Suppress = 'SUPPRESS'
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Adjust
|
||||
* @description
|
||||
* This is the Ionic Cordova SDK of Adjust™. You can read more about Adjust™ at adjust.com.
|
||||
*
|
||||
* Requires Cordova plugin: `com.adjust.sdk`. For more info, please see the [Adjust Cordova SDK](https://github.com/adjust/cordova_sdk)
|
||||
*
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { Adjust, AdjustConfig, AdjustEnvironment } from '@ionic-native/adjust/ngx';
|
||||
*
|
||||
* constructor(private adjust: Adjust) { }
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* const config = new AdjustConfig('APP-TOKEN-HERE', AdjustEnvironment.Sandbox);
|
||||
* config.logLevel = AdjustLogLevel.Verbose;
|
||||
* // Set other config properties.
|
||||
* adjust.create(config);
|
||||
*
|
||||
* ```
|
||||
* @interfaces
|
||||
* AdjustAttribution
|
||||
* AdjustSessionSuccess
|
||||
* AdjustSessionFailure
|
||||
* AdjustEventSuccess
|
||||
* AdjustEventFailure
|
||||
* @classes
|
||||
* AdjustEvent
|
||||
* AdjustConfig
|
||||
* @enums
|
||||
* AdjustEnvironment
|
||||
* AdjustLogLevel
|
||||
*/
|
||||
@Plugin({
|
||||
pluginName: 'Adjust',
|
||||
plugin: 'com.adjust.sdk',
|
||||
pluginRef: 'Adjust',
|
||||
repo: 'https://github.com/adjust/cordova_sdk',
|
||||
platforms: ['Android', 'iOS']
|
||||
})
|
||||
@Injectable()
|
||||
export class Adjust extends IonicNativePlugin {
|
||||
/**
|
||||
* This method initializes Adjust SDK
|
||||
* @param {AdjustConig} config Adjust config object used as starting options
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
create(config: AdjustConfig): void {}
|
||||
|
||||
/**
|
||||
* This method tracks an event
|
||||
* @param {AdjustEvent} event Adjust event object to be tracked
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
trackEvent(event: AdjustEvent): void {}
|
||||
|
||||
/**
|
||||
* This method sets offline mode on or off
|
||||
* @param {boolean} enabled set to true for offline mode on
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
setOfflineMode(enabled: boolean): void {}
|
||||
|
||||
/**
|
||||
* By making this call, the Adjust SDK will try to find if there is any new attribution info inside of the deep link and if any, it will be sent to the Adjust backend.
|
||||
* @param {string} url URL of the deeplink
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
appWillOpenUrl(url: string): void {}
|
||||
|
||||
/**
|
||||
* You can disable/enable the Adjust SDK from tracking by invoking this method
|
||||
* @param {boolean} enabled set to false to disable SDK
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
setEnabled(enabled: boolean): void {}
|
||||
|
||||
/**
|
||||
* To send us the push notification token, add the following call to Adjust whenever you get your token in the app or when it gets updated.
|
||||
* Push tokens are used for Audience Builder and client callbacks, and they are required for the upcoming uninstall tracking feature.
|
||||
* @param {string} pushToken push token value
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
setPushToken(pushToken: string): void {}
|
||||
|
||||
/**
|
||||
* Check if the Adjust SDK is currently enabled by calling this function
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
@Cordova()
|
||||
isEnabled(): Promise<boolean> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* In accordance with article 17 of the EU's General Data Protection Regulation (GDPR), you can notify Adjust when a user has exercised their right to be forgotten.
|
||||
* Calling the following method will instruct the Adjust SDK to communicate the user's choice to be forgotten to the Adjust backend
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
gdprForgetMe(): void {}
|
||||
|
||||
/**
|
||||
* Function used to get Google AdId
|
||||
* @return {Promise<string>} Returns a promise with google AdId value
|
||||
*/
|
||||
@Cordova()
|
||||
getGoogleAdId(): Promise<string> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If you need to obtain the Amazon Advertising ID, you can make a call to this function.
|
||||
* @return {Promise<string>} Returns a promise with anazib adv. ID
|
||||
*/
|
||||
@Cordova()
|
||||
getAmazonAdId(): Promise<string> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* To obtain the IDFA, call this function
|
||||
* @return {Promise<string>} Returns a promise with IDFA string value
|
||||
*/
|
||||
@Cordova()
|
||||
getIdfa(): Promise<string> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* For every device with your app installed on it, the Adjust backend generates a unique Adjust device identifier (adid).
|
||||
* In order to obtain this identifier, call this function
|
||||
* @return {Promise<string>} Returns a promise with adid value
|
||||
*/
|
||||
@Cordova()
|
||||
getAdid(): Promise<string> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If you want to access information about a user's current attribution whenever you need it, you can make a call to this function
|
||||
* @return {Promise<AdjustAttribution>} Returns a promise with AdjustAttribution object
|
||||
*/
|
||||
@Cordova()
|
||||
getAttribution(): Promise<AdjustAttribution> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the information about version of the SDK used
|
||||
* @return {Promise<string>} Returns a promise with sdk version information
|
||||
*/
|
||||
@Cordova()
|
||||
getSdkVersion(): Promise<string> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to add session callback parameters
|
||||
* @param key key
|
||||
* @param value value
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
addSessionCallbackParameter(key: string, value: string): void {}
|
||||
|
||||
/**
|
||||
* Remove a specific session callback parameter by passing the desiring key to this method
|
||||
* @param key key
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
removeSessionCallbackParameter(key: string): void {}
|
||||
|
||||
/**
|
||||
* If all keys and values from the session callback parameters have to be removed, call this method
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
resetSessionCallbackParameters(): void {}
|
||||
|
||||
/**
|
||||
* Method used to add session partner parameters
|
||||
* @param key key
|
||||
* @param value value
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
addSessionPartnerParameter(key: string, value: string): void {}
|
||||
|
||||
/**
|
||||
* Remove a specific session partner parameter by passing the desiring key to this method
|
||||
* @param key key
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
removeSessionPartnerParameter(key: string): void {}
|
||||
|
||||
/**
|
||||
* If all keys and values from the session partner parameters have to be removed, call this method
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
resetSessionPartnerParameters(): void {}
|
||||
|
||||
/**
|
||||
* This method call will make the Adjust SDK send the initial install session and any events created, if they were not sent after delay start was set and it's delay expired.
|
||||
*/
|
||||
@Cordova({ sync: true })
|
||||
sendFirstPackages(): void {}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { fromEvent } from 'rxjs/observable/fromEvent';
|
||||
import { Observable, fromEvent } from 'rxjs';
|
||||
|
||||
export interface AdMobFreeBannerConfig {
|
||||
/**
|
||||
@@ -68,12 +67,12 @@ export interface AdMobFreeRewardVideoConfig {
|
||||
* @name AdMob Free
|
||||
* @description
|
||||
* A free, no ad-sharing version of Google AdMob plugin for Cordova.
|
||||
*
|
||||
*
|
||||
* Requires Cordova plugin: `cordova-plugin-admob-free`. For more info, please see the [AdMob Free plugin docs](https://github.com/ratson/cordova-plugin-admob-free).
|
||||
*
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { AdMobFree, AdMobFreeBannerConfig } from '@ionic-native/admob-free';
|
||||
* import { AdMobFree, AdMobFreeBannerConfig } from '@ionic-native/admob-free/ngx';
|
||||
*
|
||||
*
|
||||
* constructor(private admobFree: AdMobFree) { }
|
||||
@@ -179,7 +178,7 @@ export class AdMobFree extends IonicNativePlugin {
|
||||
plugin: 'cordova-plugin-admob-free',
|
||||
pluginRef: 'admob.banner'
|
||||
})
|
||||
export class AdMobFreeBanner {
|
||||
export class AdMobFreeBanner extends IonicNativePlugin {
|
||||
/**
|
||||
* Update config
|
||||
* @param options
|
||||
@@ -235,7 +234,7 @@ export class AdMobFreeBanner {
|
||||
plugin: 'cordova-plugin-admob-free',
|
||||
pluginRef: 'admob.interstitial'
|
||||
})
|
||||
export class AdMobFreeInterstitial {
|
||||
export class AdMobFreeInterstitial extends IonicNativePlugin {
|
||||
/**
|
||||
* Update config
|
||||
* @param options
|
||||
@@ -282,7 +281,7 @@ export class AdMobFreeInterstitial {
|
||||
plugin: 'cordova-plugin-admob-free',
|
||||
pluginRef: 'admob.rewardvideo'
|
||||
})
|
||||
export class AdMobFreeRewardVideo {
|
||||
export class AdMobFreeRewardVideo extends IonicNativePlugin {
|
||||
/**
|
||||
* Update config
|
||||
* @param {AdMobFreeRewardVideoConfig} options Admob reward config
|
||||
|
||||
94
src/@ionic-native/plugins/admob-plus/index.ts
Normal file
94
src/@ionic-native/plugins/admob-plus/index.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
import { Observable, fromEvent } from 'rxjs';
|
||||
|
||||
export type AdUnitIDOption = string | {
|
||||
android: string;
|
||||
ios: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* @name AdMob Plus
|
||||
* @description
|
||||
* AdMob Plus is the successor of cordova-plugin-admob-free, which provides a cleaner API and build with modern tools.
|
||||
*/
|
||||
@Plugin({
|
||||
plugin: 'cordova-admob-plus',
|
||||
pluginName: 'AdMob',
|
||||
pluginRef: 'admob.banner',
|
||||
repo: 'https://github.com/admob-plus/admob-plus',
|
||||
platforms: ['Android', 'iOS']
|
||||
})
|
||||
export class Banner {
|
||||
@Cordova({ otherPromise: true })
|
||||
hide(): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@Cordova({ otherPromise: true })
|
||||
show(opts: { id?: AdUnitIDOption }): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@Plugin({
|
||||
plugin: 'cordova-admob-plus',
|
||||
pluginName: 'AdMob',
|
||||
pluginRef: 'admob.interstitial',
|
||||
})
|
||||
export class Interstitial {
|
||||
@Cordova({ otherPromise: true })
|
||||
load(opts: { id?: AdUnitIDOption }): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@Cordova({ otherPromise: true })
|
||||
show(): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@Plugin({
|
||||
plugin: 'cordova-admob-plus',
|
||||
pluginName: 'AdMob',
|
||||
pluginRef: 'admob.rewardVideo',
|
||||
})
|
||||
export class RewardVideo {
|
||||
@Cordova({ otherPromise: true })
|
||||
load(opts: { id?: AdUnitIDOption }): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@Cordova({ otherPromise: true })
|
||||
show(): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@Plugin({
|
||||
platforms: ['Android', 'iOS'],
|
||||
plugin: 'cordova-admob-plus',
|
||||
pluginName: 'AdMob',
|
||||
pluginRef: 'admob',
|
||||
repo: 'https://github.com/admob-plus/admob-plus',
|
||||
})
|
||||
@Injectable()
|
||||
export class AdMob extends IonicNativePlugin {
|
||||
banner = new Banner();
|
||||
interstitial = new Interstitial();
|
||||
rewardVideo = new RewardVideo();
|
||||
|
||||
@Cordova({ otherPromise: true })
|
||||
setAppMuted(value: boolean): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@Cordova({ otherPromise: true })
|
||||
setAppVolume(value: number): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
on(event: string): Observable<any> {
|
||||
return fromEvent(document, event);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export type AdSize =
|
||||
| '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).
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { AdMobPro } from '@ionic-native/admob-pro';
|
||||
* import { Platform } from 'ionic-angular';
|
||||
* import { AdMobPro } from '@ionic-native/admob-pro/ngx';
|
||||
* import { Platform } from '@ionic/angular';
|
||||
*
|
||||
* constructor(private admob: AdMobPro, private platform: Platform ) { }
|
||||
*
|
||||
@@ -275,7 +275,7 @@ export class AdMobPro extends IonicNativePlugin {
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'onAdFailLoad',
|
||||
element: document
|
||||
element: 'document'
|
||||
})
|
||||
onAdFailLoad(): Observable<any> {
|
||||
return;
|
||||
@@ -288,7 +288,7 @@ export class AdMobPro extends IonicNativePlugin {
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'onAdLoaded',
|
||||
element: document
|
||||
element: 'document'
|
||||
})
|
||||
onAdLoaded(): Observable<any> {
|
||||
return;
|
||||
@@ -301,7 +301,7 @@ export class AdMobPro extends IonicNativePlugin {
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'onAdPresent',
|
||||
element: document
|
||||
element: 'document'
|
||||
})
|
||||
onAdPresent(): Observable<any> {
|
||||
return;
|
||||
@@ -314,7 +314,7 @@ export class AdMobPro extends IonicNativePlugin {
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'onAdLeaveApp',
|
||||
element: document
|
||||
element: 'document'
|
||||
})
|
||||
onAdLeaveApp(): Observable<any> {
|
||||
return;
|
||||
@@ -327,7 +327,7 @@ export class AdMobPro extends IonicNativePlugin {
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'onAdDismiss',
|
||||
element: document
|
||||
element: 'document'
|
||||
})
|
||||
onAdDismiss(): Observable<any> {
|
||||
return;
|
||||
|
||||
456
src/@ionic-native/plugins/admob/index.ts
Normal file
456
src/@ionic-native/plugins/admob/index.ts
Normal file
@@ -0,0 +1,456 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Cordova, CordovaProperty, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface AdmobOptions {
|
||||
/**
|
||||
* Your publisher id code from your AdMob account
|
||||
*/
|
||||
publisherId: string;
|
||||
|
||||
/**
|
||||
* (Optional) Your interstitial id code from your AdMob account. Defaults to publisherId
|
||||
*/
|
||||
interstitialAdId?: string;
|
||||
|
||||
/**
|
||||
* (Optional) Your rewarded id code from your AdMob account. Defaults to publisherId
|
||||
*/
|
||||
rewardedAdId?: string;
|
||||
|
||||
/**
|
||||
* (Optional) Your tappx id for iOS apps. If Admob is configured, it is also used to backfill your lost inventory when there are no Admob ads available
|
||||
*/
|
||||
tappxIdiOS?: string;
|
||||
|
||||
/**
|
||||
* (Optional) Your tappx id for Android apps. Admob is configured, it is also used to backfill your lost inventory when there are no Admob ads available
|
||||
*/
|
||||
tappxIdAndroid?: string;
|
||||
|
||||
/**
|
||||
* (Optional) If any of tappxId is present, it tells the percentage of traffic diverted to tappx. Defaults to 0.5 (50% of the traffic will be requested to Tappx)
|
||||
*/
|
||||
tappxShare?: number;
|
||||
|
||||
/**
|
||||
* (Optional) Indicates whether to put banner ads at top when set to true or at bottom when set to false. Defaults to false
|
||||
*/
|
||||
bannerAtTop?: boolean;
|
||||
|
||||
/**
|
||||
* (Optional) Indicates the size of banner ads
|
||||
*/
|
||||
adSize?: string;
|
||||
|
||||
/**
|
||||
* (Optional) Allow banner overlap webview. Default false
|
||||
*/
|
||||
overlap?: boolean;
|
||||
|
||||
/**
|
||||
* (Optional) Set to true to avoid ios7 status bar overlap. Default false
|
||||
*/
|
||||
offsetStatusBar?: boolean;
|
||||
|
||||
/**
|
||||
* (Optional) Set to true to receive test ads (do not test with real ads as your account may be banned). Defaults to false
|
||||
*/
|
||||
isTesting?: boolean;
|
||||
|
||||
/**
|
||||
* (Options) A JSON object with additional {key: value} pairs
|
||||
*/
|
||||
adExtras?: any;
|
||||
|
||||
/**
|
||||
* (Optional) Auto show banner ads when available (onAdLoaded event is called). Defaults to true
|
||||
*/
|
||||
autoShowBanner?: boolean;
|
||||
|
||||
/**
|
||||
* (Optional) Auto show interstitial asd when available (onAdLoaded event is called). Defaults to true
|
||||
*/
|
||||
autoShowInterstitial?: boolean;
|
||||
|
||||
/**
|
||||
* (Optional) Auto show rewarded ads when available (onAdLoaded event is called). Defaults to true
|
||||
*/
|
||||
autoShowRewarded?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Admob
|
||||
* @description
|
||||
* Most complete Admob plugin with support for [Tappx](http://www.tappx.com/?h=dec334d63287772de859bdb4e977fce6) ads.
|
||||
* Monetize your apps and games with AdMob ads, using latest Google AdMob SDK. With this plugin you can show AdMob ads easily!
|
||||
*
|
||||
* **Supports:**
|
||||
* - Banner ads (top and bottom)
|
||||
* - Interstitial ads
|
||||
* - Rewarded ads
|
||||
* - [Tappx](http://www.tappx.com/?h=dec334d63287772de859bdb4e977fce6) ads
|
||||
*
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { Admob, AdmobOptions } from '@ionic-native/admob/ngx';
|
||||
*
|
||||
*
|
||||
* constructor(private admob: Admob) {
|
||||
* // Admob options config
|
||||
* const admobOptions: AdmobOptions = {
|
||||
* publisherId: 'XXX-XXXX-XXXX',
|
||||
* interstitialAdId: 'XXX-XXXX-XXXX',
|
||||
* rewardedAdId: 'XXX-XXXX-XXXX',
|
||||
* isTesting: true,
|
||||
* autoShowBanner: false,
|
||||
* autoShowInterstitial: false,
|
||||
* autoShowRewarded: false,
|
||||
* adSize: this.admob.AD_SIZE.BANNER
|
||||
* };
|
||||
*
|
||||
* // Set admob options
|
||||
* this.admob.setOptions(admobOptions)
|
||||
* .then(() => console.log('Admob options have been successfully set'))
|
||||
* .catch(err => console.error('Error setting admob options:', err));
|
||||
* }
|
||||
*
|
||||
*
|
||||
*
|
||||
* // (Optionally) Load banner ad, in order to have it ready to show
|
||||
* this.admob.createBannerView()
|
||||
* .then(() => console.log('Banner ad loaded'))
|
||||
* .catch(err => console.error('Error loading banner ad:', err));
|
||||
*
|
||||
*
|
||||
* // Show banner ad (createBannerView must be called before and onAdLoaded() event raised)
|
||||
* this.admob.onAdLoaded().subscribe((ad) => {
|
||||
* if (ad.adType === this.admob.AD_TYPE.BANNER) {
|
||||
* this.admob.showBannerAd()
|
||||
* .then(() => console.log('Banner ad shown'))
|
||||
* .catch(err => console.error('Error showing banner ad:', err));
|
||||
* }
|
||||
* });
|
||||
*
|
||||
*
|
||||
* // Hide banner ad, but do not destroy it, so it can be shown later on
|
||||
* // See destroyBannerView in order to hide and destroy banner ad
|
||||
* this.admob.showBannerAd(false)
|
||||
* .then(() => console.log('Banner ad hidden'))
|
||||
* .catch(err => console.error('Error hiding banner ad:', err));
|
||||
*
|
||||
*
|
||||
*
|
||||
* // Request an interstitial ad, in order to be shown later on
|
||||
* // It is possible to autoshow it via options parameter, see docs
|
||||
* this.admob.requestInterstitialAd()
|
||||
* .then(() => console.log('Interstitial ad loaded'))
|
||||
* .catch(err => console.error('Error loading interstitial ad:', err));
|
||||
*
|
||||
*
|
||||
* // Show an interstitial ad (requestInterstitialAd must be called before)
|
||||
* this.admob.onAdLoaded().subscribe((ad) => {
|
||||
* if (ad.adType === this.admob.AD_TYPE.INTERSTITIAL) {
|
||||
* this.admob.showInterstitialAd()
|
||||
* .then(() => console.log('Interstitial ad shown'))
|
||||
* .catch(err => console.error('Error showing interstitial ad:', err));
|
||||
* }
|
||||
* });
|
||||
*
|
||||
*
|
||||
* // Request a rewarded ad
|
||||
* this.admob.requestRewardedAd()
|
||||
* .then(() => console.log('Rewarded ad loaded'))
|
||||
* .catch(err => console.error('Error loading rewarded ad:', err));
|
||||
*
|
||||
*
|
||||
* // Show rewarded ad (requestRewardedAd must be called before)
|
||||
* this.admob.onAdLoaded().subscribe((ad) => {
|
||||
* if (ad.adType === this.admob.AD_TYPE.REWARDED) {
|
||||
* this.admob.showRewardedAd()
|
||||
* .then(() => console.log('Rewarded ad shown'))
|
||||
* .catch(err => console.error('Error showing rewarded ad:', err));
|
||||
* }
|
||||
* });
|
||||
*
|
||||
*
|
||||
* // Hide and destroy banner or interstitial ad
|
||||
* this.admob.destroyBannerView()
|
||||
* .then(() => console.log('Banner or interstitial ad destroyed'))
|
||||
* .catch(err => console.error('Error destroying banner or interstitial ad:', err));
|
||||
*
|
||||
*
|
||||
*
|
||||
* // On Ad loaded event
|
||||
* this.admob.onAdLoaded().subscribe((ad) => {
|
||||
* if (ad.adType === this.admob.AD_TYPE.BANNER) {
|
||||
* console.log('Banner ad is loaded');
|
||||
* this.admob.showBannerAd();
|
||||
* } else if (ad.adType === this.admob.AD_TYPE.INTERSTITIAL) {
|
||||
* console.log('Interstitial ad is loaded');
|
||||
* this.admob.showInterstitialAd();
|
||||
* } else if (ad.adType === this.admob.AD_TYPE.REWARDED) {
|
||||
* console.log('Rewarded ad is loaded');
|
||||
* this.admob.showRewardedAd();
|
||||
* }
|
||||
* });
|
||||
*
|
||||
*
|
||||
*
|
||||
* // On ad failed to load
|
||||
* this.admob.onAdFailedToLoad().subscribe(err => console.log('Error loading ad:', err));
|
||||
*
|
||||
*
|
||||
*
|
||||
* // On interstitial ad opened
|
||||
* this.admob.onAdOpened().subscribe(() => console.log('Interstitial ad opened'));
|
||||
*
|
||||
*
|
||||
*
|
||||
* // On interstitial ad closed
|
||||
* this.admob.onAdClosed().subscribe(() => console.log('Interstitial ad closed'));
|
||||
*
|
||||
*
|
||||
*
|
||||
* // On ad clicked and left application
|
||||
* this.admob.onAdLeftApplication().subscribe(() => console.log('Ad lefted application'));
|
||||
*
|
||||
*
|
||||
*
|
||||
* // On user ad rewarded
|
||||
* this.admob.onRewardedAd().subscribe(() => console.log('The user has been rewarded'));
|
||||
*
|
||||
*
|
||||
*
|
||||
* // On rewarded ad video started
|
||||
* this.admob.onRewardedAdVideoStarted().subscribe(() => console.log('Rewarded ad vieo started'));
|
||||
*
|
||||
*
|
||||
*
|
||||
* // On rewarded ad video completed
|
||||
* this.admob.onRewardedAdVideoCompleted().subscribe(() => console.log('Rewarded ad video completed'));
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
@Plugin({
|
||||
pluginName: 'Admob',
|
||||
plugin: 'cordova-admob',
|
||||
pluginRef: 'admob',
|
||||
repo: 'https://github.com/appfeel/admob-google-cordova',
|
||||
platforms: ['Android', 'iOS']
|
||||
})
|
||||
@Injectable()
|
||||
export class Admob extends IonicNativePlugin {
|
||||
/**
|
||||
* This enum represents AdMob's supported ad sizes.
|
||||
* Use one of these constants as adSize option when calling createBannerView
|
||||
* @readonly
|
||||
*/
|
||||
@CordovaProperty()
|
||||
readonly AD_SIZE: {
|
||||
BANNER: string;
|
||||
IAB_MRECT: string;
|
||||
IAB_BANNER: string;
|
||||
IAB_LEADERBOARD: string;
|
||||
SMART_BANNER: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* This enum represents AdMob's supported ad types
|
||||
* @readonly
|
||||
*/
|
||||
@CordovaProperty()
|
||||
readonly AD_TYPE: {
|
||||
BANNER: string;
|
||||
INTERSTITIAL: string;
|
||||
REWARDED: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the options to start displaying ads.
|
||||
* Although it is not required to call this method, as options can be specified in other methods, it is highly recommended
|
||||
* @param options {AdmobOptions} Some param to configure something
|
||||
* @return {Promise<any>} Returns a promise that resolves when the options are set
|
||||
*/
|
||||
@Cordova()
|
||||
setOptions(options: AdmobOptions): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new banner ad view. Call this method in order to be able to start showing banners
|
||||
* @param options {AdmobOptions} (Optional) Setup options
|
||||
* @return {Promise<any>} Returns a promise that resolves when the banner view is created
|
||||
*/
|
||||
@Cordova()
|
||||
createBannerView(options?: AdmobOptions): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show banner ads. You must call createBannerView first, otherwise it will result in failure callback and no ads will be shown
|
||||
* @param show {boolean} (Optional) Indicates whether to show or hide banner ads. Defaults to `true`
|
||||
* @return {Promise<any>} Returns a promise that resolves when the banner shown or hidden
|
||||
*/
|
||||
@Cordova()
|
||||
showBannerAd(show?: boolean): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide and destroy banner view. Call this method when you want to destroy banner view.
|
||||
* It is not necessary to call this method when the app closed, as it will be automatically called by the plugin
|
||||
*/
|
||||
@Cordova()
|
||||
destroyBannerView() {}
|
||||
|
||||
/**
|
||||
* Request an interstitial ad
|
||||
* If `options.autoShowInterstitial` is set to `true` (default), the ad will automatically be displayed.
|
||||
* Otherwise you need to subscribe to `onAdLoaded()` event and call `showInterstitialAd()` after it will be raised specifying that an interstitial ad is available.
|
||||
* If you already called `requestInterstitialAd()` but the interstitial has never been shown, the successive calls to `requestInterstitialAd()` will result in the ad being inmediately available (the one that was obtained on the first call)
|
||||
* @param options {AdmobOptions} (Optional) Setup options
|
||||
* @return {Promise<any>} Returns a promise that resolves when the interstitial ad is loaded
|
||||
*/
|
||||
@Cordova()
|
||||
requestInterstitialAd(options?: AdmobOptions): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an interstitial ad. Call it after `requestInterstitialAd()` and `onAdLoaded()` event raised.
|
||||
* @return {Promise<any>} Returns a promise that resolves when the interstitial ad is shown
|
||||
*/
|
||||
@Cordova()
|
||||
showInterstitialAd(): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request an rewarded ad
|
||||
* If `options.autoShowRewarded` is set to `true` (default), the ad will automatically be displayed.
|
||||
* Otherwise you need to subscribe to `onAdLoaded()` enent and call `showRewardedAd()` after it will be raised specifying that a rewarded ad is available.
|
||||
* If you already called `requestRewardedAd()` but the rewarded has never been shown, the successive calls to `requestRewardedAd()` will result in the ad being inmediately available (the one that was obtained on the first call)
|
||||
* @param options {AdmobOptions} (Optional) Setup options
|
||||
* @return {Promise<any>} Returns a promise that resolves when the rewarded ad is loaded
|
||||
*/
|
||||
@Cordova()
|
||||
requestRewardedAd(options?: AdmobOptions): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a rewarded ad
|
||||
* @return {Promise<any>} Returns a promise that resolves when the rewarded ad is shown
|
||||
*/
|
||||
@Cordova()
|
||||
showRewardedAd(): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an ad is received
|
||||
* @returns {Observable<any>} Returns an observable when an ad is received
|
||||
*/
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'appfeel.cordova.admob.onAdLoaded',
|
||||
element: document
|
||||
})
|
||||
onAdLoaded(): Observable<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an ad request failed
|
||||
* @returns {Observable<any>} Returns an observable when an ad request is failed
|
||||
*/
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'appfeel.cordova.admob.onAdFailedToLoad',
|
||||
element: document
|
||||
})
|
||||
onAdFailedToLoad(): Observable<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an ad opens an overlay that covers the screen.
|
||||
* Please note that onPause cordova event is raised when an interstitial is shown
|
||||
* @returns {Observable<any>} Returns an observable when an ad is opened
|
||||
*/
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'appfeel.cordova.admob.onAdOpened',
|
||||
element: document
|
||||
})
|
||||
onAdOpened(): Observable<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user is about to return to the application after clicking on an ad.
|
||||
* Please note that onResume cordova event is raised when an interstitial is closed
|
||||
* @returns {Observable<any>} Returns an observable when an ad is closed
|
||||
*/
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'appfeel.cordova.admob.onAdClosed',
|
||||
element: document
|
||||
})
|
||||
onAdClosed(): Observable<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user leaves the application after clicking an ad (e.g., to go to the browser)
|
||||
* @returns {Observable<any>} Returns an observable when an ad leaves the application
|
||||
*/
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'appfeel.cordova.admob.onAdLeftApplication',
|
||||
element: document
|
||||
})
|
||||
onAdLeftApplication(): Observable<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user has been rewarded by an ad
|
||||
* @returns {Observable<any>} Returns an observable when the user rewards an ad
|
||||
*/
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'appfeel.cordova.admob.onRewardedAd',
|
||||
element: document
|
||||
})
|
||||
onRewardedAd(): Observable<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the video of a rewarded ad started
|
||||
* @returns {Observable<any>} Returns an observable when the video is started
|
||||
*/
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'appfeel.cordova.admob.onRewardedAdVideoStarted',
|
||||
element: document
|
||||
})
|
||||
onRewardedAdVideoStarted(): Observable<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the video of a rewarded ad has completed
|
||||
* @returns {Observable<any>} Returns an observable when the video is completed
|
||||
*/
|
||||
@Cordova({
|
||||
eventObservable: true,
|
||||
event: 'appfeel.cordova.admob.onRewardedAdVideoCompleted',
|
||||
element: document
|
||||
})
|
||||
onRewardedAdVideoCompleted(): Observable<any> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -10,12 +10,12 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
*
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { AES256 } from '@ionic-native/aes-256';
|
||||
* import { AES256 } from '@ionic-native/aes-256/ngx';
|
||||
*
|
||||
* private secureKey: string;
|
||||
* private secureIV: string;
|
||||
*
|
||||
* constructor(private aes256: AES256) {
|
||||
*
|
||||
* constructor(private aes256: AES256) {
|
||||
* this.generateSecureKeyAndIV(); // To generate the random secureKey and secureIV
|
||||
* }
|
||||
*
|
||||
@@ -34,16 +34,16 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
* .then(res => console.log('Decrypted Data : ',res))
|
||||
* .catch((error: any) => console.error(error));
|
||||
*
|
||||
*
|
||||
*
|
||||
* * this.aes256.generateSecureKey('random password 12345')
|
||||
* .then(res => console.log('Secure Key : ',res))
|
||||
* .catch((error: any) => console.error(error));
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* * this.aes256.generateSecureIV('random password 12345')
|
||||
* .then(res => console.log('Secure IV : ',res))
|
||||
* .catch((error: any) => console.error(error));
|
||||
*
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
@Plugin({
|
||||
@@ -56,7 +56,6 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
})
|
||||
@Injectable()
|
||||
export class AES256 extends IonicNativePlugin {
|
||||
|
||||
/**
|
||||
* This function used to perform the aes256 encryption
|
||||
* @param {string} secureKey A 32 bytes string, which will used as input key for AES256 encryption.
|
||||
|
||||
@@ -10,12 +10,12 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
*
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { Alipay } from '@ionic-native/alipay';
|
||||
* import { Alipay } from '@ionic-native/alipay/ngx';
|
||||
*
|
||||
* constructor(private alipay: Alipay) {
|
||||
*
|
||||
* //alipayOrder is a string that has been generated and signed by the server side.
|
||||
* this.alipay.pay(alipayOrder)
|
||||
* this.alipay.pay(alipayOrder, success, error)
|
||||
* .then(result => {
|
||||
* console.log(result); // Success
|
||||
* })
|
||||
@@ -30,7 +30,7 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
@Plugin({
|
||||
pluginName: 'Alipay',
|
||||
plugin: 'cordova-plugin-gubnoi-alipay',
|
||||
pluginRef: 'Alipay',
|
||||
pluginRef: 'cordova.plugins.alipay',
|
||||
repo: 'https://github.com/jing-zhou/cordova-plugin-alipay',
|
||||
install: 'ionic cordova plugin add cordova-plugin-gubnoi-alipay --variable APP_ID=your_app_id',
|
||||
installVariables: ['APP_ID'],
|
||||
@@ -44,7 +44,7 @@ export class Alipay extends IonicNativePlugin {
|
||||
* @returns {Promise<any>} Returns a Promise that resolves with the success return, or rejects with an error.
|
||||
*/
|
||||
@Cordova()
|
||||
pay(order: string): Promise<any> {
|
||||
pay(order: string, success?: (res?: any) => void, error?: (err?: any) => void): Promise<any> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
248
src/@ionic-native/plugins/analytics-firebase/index.ts
Normal file
248
src/@ionic-native/plugins/analytics-firebase/index.ts
Normal file
@@ -0,0 +1,248 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Cordova, CordovaProperty, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
|
||||
/**
|
||||
* @name Analytics Firebase
|
||||
* @description
|
||||
* Google Analytics Firebase plugin for Ionic Native apps.
|
||||
*
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { AnalyticsFirebase } from '@ionic-native/analytics-firebase';
|
||||
*
|
||||
*
|
||||
* constructor(private analyticsFirebase: AnalyticsFirebase) { }
|
||||
*
|
||||
* // Track an event with default events and params
|
||||
* const eventParams = {};
|
||||
* eventParams[this.analyticsFirebase.DEFAULT_PARAMS.LEVEL] = 29;
|
||||
* this.analyticsFirebase.logEvent(this.analyticsFirebase.DEFAULT_EVENTS.LEVEL_UP, eventParams)
|
||||
* .then(() => console.log('Event successfully tracked'))
|
||||
* .catch(err => console.log('Error tracking event:', err));
|
||||
*
|
||||
* // Track an event with custom events and params
|
||||
* const eventParams = {};
|
||||
* eventParams['my-prop'] = 29;
|
||||
* this.analyticsFirebase.logEvent('my-event', eventParams)
|
||||
* .then(() => console.log('Event successfully tracked'))
|
||||
* .catch(err => console.log('Error tracking event:', err));
|
||||
*
|
||||
*
|
||||
* // Reset analytics data
|
||||
* this.analyticsFirebase.resetAnalyticsData()
|
||||
* .then(() => console.log('Analytics data have been reset'))
|
||||
* .catch(err => console.log('Error resetting analytics data:', err));
|
||||
*
|
||||
*
|
||||
* // Track a screen view
|
||||
* this.analyticsFirebase.setCurrentScreen('Home')
|
||||
* .then(() => console.log('View successfully tracked'))
|
||||
* .catch(err => console.log('Error tracking view:', err));
|
||||
*
|
||||
*
|
||||
* // Set user id
|
||||
* this.analyticsFirebase.setUserId('USER-ID')
|
||||
* .then(() => console.log('User id successfully set'))
|
||||
* .catch(err => console.log('Error setting user id:', err));
|
||||
*
|
||||
*
|
||||
* // Set user property from default properties
|
||||
* this.analyticsFirebase.setUserProperty('KEY', 'VALUE')
|
||||
* .then(() => console.log('User property successfully set'))
|
||||
* .catch(err => console.log('Error setting user property:', err));
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
@Plugin({
|
||||
pluginName: 'AnalyticsFirebase',
|
||||
plugin: 'cordova-plugin-analytics',
|
||||
pluginRef: 'analytics',
|
||||
repo: 'https://github.com/appfeel/analytics-google',
|
||||
platforms: ['Android', 'iOS']
|
||||
})
|
||||
@Injectable()
|
||||
export class AnalyticsFirebase extends IonicNativePlugin {
|
||||
/**
|
||||
* This enum represents AnalyticsFirebase default events.
|
||||
* Use one of these default events or a custom event
|
||||
* @readonly
|
||||
*/
|
||||
@CordovaProperty()
|
||||
readonly DEFAULT_EVENTS: {
|
||||
ADD_PAYMENT_INFO: string;
|
||||
ADD_TO_CART: string;
|
||||
ADD_TO_WISHLIST: string;
|
||||
APP_OPEN: string;
|
||||
BEGIN_CHECKOUT: string;
|
||||
CAMPAIGN_DETAILS: string;
|
||||
CHECKOUT_PROGRESS: string;
|
||||
EARN_VIRTUAL_CURRENCY: string;
|
||||
ECOMMERCE_PURCHASE: string;
|
||||
GENERATE_LEAD: string;
|
||||
JOIN_GROUP: string;
|
||||
LEVEL_END: string;
|
||||
LEVEL_START: string;
|
||||
LEVEL_UP: string;
|
||||
LOGIN: string;
|
||||
POST_SCORE: string;
|
||||
PRESENT_OFFER: string;
|
||||
PURCHASE_REFUND: string;
|
||||
REMOVE_FROM_CART: string;
|
||||
SEARCH: string;
|
||||
SELECT_CONTENT: string;
|
||||
SET_CHECKOUT_OPTION: string;
|
||||
SHARE: string;
|
||||
SIGN_UP: string;
|
||||
SPEND_VIRTUAL_CURRENCY: string;
|
||||
TUTORIAL_BEGIN: string;
|
||||
TUTORIAL_COMPLETE: string;
|
||||
UNLOCK_ACHIEVEMENT: string;
|
||||
VIEW_ITEM: string;
|
||||
VIEW_ITEM_LIST: string;
|
||||
VIEW_SEARCH_RESULTS: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* This enum represents AnalyticsFirebase default params.
|
||||
* Use one of these default params or a custom param
|
||||
* @readonly
|
||||
*/
|
||||
@CordovaProperty()
|
||||
readonly DEFAULT_PARAMS: {
|
||||
ACHIEVEMENT_ID: string;
|
||||
ACLID: string;
|
||||
AFFILIATION: string;
|
||||
CAMPAIGN: string;
|
||||
CHARACTER: string;
|
||||
CHECKOUT_OPTION: string;
|
||||
CHECKOUT_STEP: string;
|
||||
CONTENT: string;
|
||||
CONTENT_TYPE: string;
|
||||
COUPON: string;
|
||||
CP1: string;
|
||||
CREATIVE_NAME: string;
|
||||
CREATIVE_SLOT: string;
|
||||
CURRENCY: string;
|
||||
DESTINATION: string;
|
||||
END_DATE: string;
|
||||
FLIGHT_NUMBER: string;
|
||||
GROUP_ID: string;
|
||||
INDEX: string;
|
||||
ITEM_BRAND: string;
|
||||
ITEM_CATEGORY: string;
|
||||
ITEM_ID: string;
|
||||
ITEM_LIST: string;
|
||||
ITEM_LOCATION_ID: string;
|
||||
ITEM_NAME: string;
|
||||
ITEM_VARIANT: string;
|
||||
LEVEL: string;
|
||||
LEVEL_NAME: string;
|
||||
LOCATION: string;
|
||||
MEDIUM: string;
|
||||
METHOD: string;
|
||||
NUMBER_OF_NIGHTS: string;
|
||||
NUMBER_OF_PASSENGERS: string;
|
||||
NUMBER_OF_ROOMS: string;
|
||||
ORIGIN: string;
|
||||
PRICE: string;
|
||||
QUANTITY: string;
|
||||
SCORE: string;
|
||||
SEARCH_TERM: string;
|
||||
SHIPPING: string;
|
||||
SOURCE: string;
|
||||
START_DATE: string;
|
||||
SUCCESS: string;
|
||||
TAX: string;
|
||||
TERM: string;
|
||||
TRANSACTION_ID: string;
|
||||
TRAVEL_CLASS: string;
|
||||
VALUE: string;
|
||||
VIRTUAL_CURRENCY_NAME: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Logs an app event. The event can have up to 25 parameters.
|
||||
* Events with the same name must have the same parameters.
|
||||
* Up to 500 event names are supported.
|
||||
* Using predefined [FirebaseAnalytics.Event](https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics.Event.html) and/or [FirebaseAnalytics.Param](https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics.Param.html) is recommended for optimal reporting.
|
||||
*
|
||||
* @param eventName {string} The event name
|
||||
* @param eventParams {object} (Optional) The event params
|
||||
* @return {Promise<any>} Returns a promise that resolves when the event is logged
|
||||
*/
|
||||
@Cordova()
|
||||
logEvent(eventName: string, eventParams?: object): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all analytics data for this app from the device and resets the app instance id
|
||||
* @return {Promise<any>} Returns a promise that resolves when the analytics data is cleared
|
||||
*/
|
||||
@Cordova()
|
||||
resetAnalyticsData(): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether analytics collection is enabled for this app on this device. This setting is persisted across app sessions. By default it is enabled
|
||||
* @param screenName {boolean} The value of the collection
|
||||
* @return {Promise<any>} Returns a promise that resolves when the collection is enabled/disabled
|
||||
*/
|
||||
@Cordova()
|
||||
setAnalyticsCollectionEnabled(enabled: boolean): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current screen name, which specifies the current visual context in your app.
|
||||
* This helps identify the areas in your app where users spend their time and how they interact with your app
|
||||
* @param screenName {string} The screen name
|
||||
* @return {Promise<any>} Returns a promise that resolves when the current screen is setted
|
||||
*/
|
||||
@Cordova()
|
||||
setCurrentScreen(screenName: string): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum engagement time required before starting a session. The default value is 10000 (10 seconds)
|
||||
* @param screenName {number} The duration in milliseconds
|
||||
* @return {Promise<any>} Returns a promise that resolves when the minimum session duration is set
|
||||
*/
|
||||
@Cordova()
|
||||
setMinimumSessionDuration(milliseconds: number): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the duration of inactivity that terminates the current session. The default value is 1800000 (30 minutes)
|
||||
* @param screenName {number} The duration in milliseconds
|
||||
* @return {Promise<any>} Returns a promise that resolves when the session timeout duration is set
|
||||
*/
|
||||
@Cordova()
|
||||
setSessionTimeoutDuration(milliseconds: number): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user ID property. This feature must be used in accordance with Google's Privacy Policy
|
||||
* @param userId {string} The user id
|
||||
* @return {Promise<any>} Returns a promise that resolves when the user id is setted
|
||||
*/
|
||||
@Cordova()
|
||||
setUserId(userId: string): Promise<any> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a user property to a given value. Up to 25 user property names are supported. Once set, user property values persist throughout the app lifecycle and across sessions
|
||||
* @param userPropertyName {string} The user property name
|
||||
* @param userPropertyValue {string} The user property value
|
||||
* @return {Promise<any>} Returns a promise that resolves when the user property setted
|
||||
*/
|
||||
@Cordova()
|
||||
setUserProperty(userPropertyName: string, userPropertyValue: string): Promise<any> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/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';
|
||||
|
||||
@@ -158,7 +158,7 @@ export interface AndroidExoPlayerControllerConfig {
|
||||
*
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { AndroidExoPlayer } from '@ionic-native/android-exoplayer';
|
||||
* import { AndroidExoPlayer } from '@ionic-native/android-exoplayer/ngx';
|
||||
*
|
||||
* constructor(private androidExoPlayer: AndroidExoPlayer) { }
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { AndroidFingerprintAuth } from '@ionic-native/android-fingerprint-auth';
|
||||
* import { AndroidFingerprintAuth } from '@ionic-native/android-fingerprint-auth/ngx';
|
||||
*
|
||||
* constructor(private androidFingerprintAuth: AndroidFingerprintAuth) { }
|
||||
*
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Cordova, Plugin, IonicNativePlugin } from '@ionic-native/core';
|
||||
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
/** 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.
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { AndroidFullScreen } from '@ionic-native/android-full-screen';
|
||||
* import { AndroidFullScreen } from '@ionic-native/android-full-screen/ngx';
|
||||
*
|
||||
* constructor(private androidFullScreen: AndroidFullScreen) { }
|
||||
*
|
||||
@@ -62,63 +62,81 @@ export class AndroidFullScreen extends IonicNativePlugin {
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
@Cordova()
|
||||
isSupported(): Promise<void> { return; }
|
||||
isSupported(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is immersive mode supported?
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
@Cordova()
|
||||
isImmersiveModeSupported(): Promise<void> { return; }
|
||||
isImmersiveModeSupported(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the screen in immersive mode.
|
||||
* @return {Promise<number>}
|
||||
*/
|
||||
@Cordova()
|
||||
immersiveWidth(): Promise<number> { return; }
|
||||
immersiveWidth(): Promise<number> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of the screen in immersive mode.
|
||||
* @return {Promise<number>}
|
||||
*/
|
||||
@Cordova()
|
||||
immersiveHeight(): Promise<number> { return; }
|
||||
immersiveHeight(): Promise<number> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide system UI until user interacts.
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
@Cordova()
|
||||
leanMode(): Promise<void> { return; }
|
||||
leanMode(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show system UI.
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
@Cordova()
|
||||
showSystemUI(): Promise<void> { return; }
|
||||
showSystemUI(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend your app underneath the status bar (Android 4.4+ only).
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
@Cordova()
|
||||
showUnderStatusBar(): Promise<void> { return; }
|
||||
showUnderStatusBar(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend your app underneath the system UI (Android 4.4+ only).
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
@Cordova()
|
||||
showUnderSystemUI(): Promise<void> { return; }
|
||||
showUnderSystemUI(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide system UI and keep it hidden (Android 4.4+ only).
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
@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).
|
||||
@@ -127,5 +145,7 @@ export class AndroidFullScreen extends IonicNativePlugin {
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
@Cordova()
|
||||
setSystemUiVisibility(visibility: AndroidSystemUiFlags): Promise<void> { return; }
|
||||
setSystemUiVisibility(visibility: AndroidSystemUiFlags): Promise<void> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
*
|
||||
* @usage
|
||||
* ```
|
||||
* import { AndroidPermissions } from '@ionic-native/android-permissions';
|
||||
* import { AndroidPermissions } from '@ionic-native/android-permissions/ngx';
|
||||
*
|
||||
*
|
||||
* constructor(private androidPermissions: AndroidPermissions) { }
|
||||
@@ -204,26 +204,26 @@ export class AndroidPermissions extends IonicNativePlugin {
|
||||
/**
|
||||
* Check permission
|
||||
* @param {string} permission The name of the permission
|
||||
* @return {Promise<any>} Returns a promise
|
||||
* @return {Promise<AndroidPermissionResponse>} Returns a promise
|
||||
*/
|
||||
@Cordova()
|
||||
checkPermission(permission: string): Promise<any> {
|
||||
checkPermission(permission: string): Promise<AndroidPermissionResponse> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request permission
|
||||
* @param {string} permission The name of the permission to request
|
||||
* @return {Promise<any>}
|
||||
* @return {Promise<AndroidPermissionResponse>}
|
||||
*/
|
||||
@Cordova()
|
||||
requestPermission(permission: string): Promise<any> {
|
||||
requestPermission(permission: string): Promise<AndroidPermissionResponse> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request permissions
|
||||
* @param {Array<string>} permissions An array with permissions
|
||||
* @param {string[]} permissions An array with permissions
|
||||
* @return {Promise<any>} Returns a promise
|
||||
*/
|
||||
@Cordova()
|
||||
@@ -234,10 +234,14 @@ export class AndroidPermissions extends IonicNativePlugin {
|
||||
/**
|
||||
* This function still works now, will not support in the future.
|
||||
* @param {string} permission The name of the permission
|
||||
* @return {Promise<any>} Returns a promise
|
||||
* @return {Promise<AndroidPermissionResponse>} Returns a promise
|
||||
*/
|
||||
@Cordova()
|
||||
hasPermission(permission: string): Promise<any> {
|
||||
hasPermission(permission: string): Promise<AndroidPermissionResponse> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
export interface AndroidPermissionResponse {
|
||||
hasPermission: boolean;
|
||||
}
|
||||
|
||||
51
src/@ionic-native/plugins/anyline/index.ts
Normal file
51
src/@ionic-native/plugins/anyline/index.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
|
||||
export interface AnylineOptions {
|
||||
// Valid License Key
|
||||
licenseKey: string;
|
||||
|
||||
// Scanning options
|
||||
config: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Anyline
|
||||
* @description
|
||||
* Anyline provides an easy-to-use SDK for applications to enable Optical Character Recognition (OCR) on mobile devices.
|
||||
*
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { Anyline } from '@ionic-native/anyline/ngx';
|
||||
*
|
||||
*
|
||||
* constructor(private anyline: Anyline) { }
|
||||
*
|
||||
* ...
|
||||
*
|
||||
*
|
||||
* this.anyline.scan(options)
|
||||
* .then((res: any) => console.log(res))
|
||||
* .catch((error: any) => console.error(error));
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
@Plugin({
|
||||
pluginName: 'Anyline',
|
||||
plugin: 'io-anyline-cordova',
|
||||
pluginRef: 'Anyline',
|
||||
repo: 'https://github.com/Anyline/anyline-ocr-cordova-module',
|
||||
platforms: ['Android', 'iOS']
|
||||
})
|
||||
@Injectable()
|
||||
export class Anyline extends IonicNativePlugin {
|
||||
/**
|
||||
* Scan
|
||||
* @param options {AnylineOptions} Scanning options
|
||||
* @return {Promise<any>} Returns a promise that resolves when Code is captured
|
||||
*/
|
||||
@Cordova()
|
||||
scan(options: AnylineOptions): Promise<any> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Cordova, Plugin, IonicNativePlugin } from '@ionic-native/core';
|
||||
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';
|
||||
|
||||
/**
|
||||
* @name App Availability
|
||||
@@ -10,7 +10,7 @@ import { Cordova, Plugin, IonicNativePlugin } from '@ionic-native/core';
|
||||
*
|
||||
* @usage
|
||||
* ```typescript
|
||||
* import { AppAvailability } from '@ionic-native/app-availability';
|
||||
* import { AppAvailability } from '@ionic-native/app-availability/ngx';
|
||||
* import { Platform } from 'ionic-angular';
|
||||
*
|
||||
* constructor(private appAvailability: AppAvailability, private platform: Platform) { }
|
||||
@@ -48,6 +48,8 @@ export class AppAvailability extends IonicNativePlugin {
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
@Cordova()
|
||||
check(app: string): Promise<boolean> { return; }
|
||||
check(app: string): Promise<boolean> {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user