├── .eslintrc.json ├── .github └── workflows │ └── npm_publish.yml ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── package.json ├── src ├── art │ ├── CircularProgressBar │ │ └── index.ts │ └── EmojiAnimation │ │ └── index.ts ├── biometrics │ └── index.ts ├── chart │ └── index.ts ├── color │ └── index.ts ├── copy │ └── index.ts ├── guid │ └── index.ts ├── html-to-text │ ├── index.ts │ └── util.ts ├── maps │ └── index.ts ├── pdf │ └── index.ts ├── service-call-offline │ └── index.ts ├── service-call │ └── index.ts └── table │ └── index.ts ├── test ├── copy.js └── guid.js ├── tsconfig.json ├── typedoc.js └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "commonjs": true, 4 | "es6": true, 5 | "node": true 6 | }, 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/eslint-recommended" 10 | ], 11 | "globals": { 12 | "Atomics": "readonly", 13 | "SharedArrayBuffer": "readonly" 14 | }, 15 | "parser": "@typescript-eslint/parser", 16 | "parserOptions": { 17 | "ecmaVersion": 2018 18 | }, 19 | "plugins": [ 20 | "@typescript-eslint" 21 | ], 22 | "rules": { 23 | "indent": [ 24 | 2, 25 | "warn", 26 | "space" 27 | ], 28 | "linebreak-style": [ 29 | "error", 30 | "unix" 31 | ], 32 | "quotes": [ 33 | "warn", 34 | "single" 35 | ], 36 | "semi": [ 37 | "error", 38 | "always" 39 | ], 40 | "no-unused-vars": "warn" 41 | } 42 | } -------------------------------------------------------------------------------- /.github/workflows/npm_publish.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Publish NPM 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | jobs: 8 | publish: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@main 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 14 15 | registry-url: https://registry.npmjs.org/ 16 | - name: Install Dependencies 17 | run: yarn 18 | - name: Compile Project 19 | run: yarn run build 20 | - name: Run Tests 21 | run: yarn run test 22 | - name: Generate Docs 23 | run: yarn run docs 24 | - name: Deploy Using gh-pages 25 | run: | 26 | git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git 27 | npx gh-pages -d docs -u "github-actions-bot " 28 | env: 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | - name: Publish Package 31 | run: yarn publish 32 | env: 33 | NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | npm-debug.log 3 | node_modules/ 4 | yarn-* 5 | tsconfig.ts* 6 | dist 7 | lib 8 | docs -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | createdoc.sh 2 | node_modules 3 | src 4 | doc 5 | docs 6 | .github 7 | typedoc.js 8 | tsconfig.* 9 | test -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | 4 | ## 11.3.0 (2020-06-08) 5 | 6 | ### Miscellaneous 7 | 8 | - feat: Implement network.getIpAddress util [[c545e7a](https://github.com/smartface/sf-extension-utils/commit/c545e7a7ec76be6f1c5c16a564a0438abfce2671)] 9 | - Merge pull request [#65](https://github.com/smartface/sf-extension-utils/issues/65) from smartface/feature/polyfill-promise-series [[542d632](https://github.com/smartface/sf-extension-utils/commit/542d632c48cb7d98b002e682505d18dde3d0d46b)] 10 | - feature(polyfill): Add promise.series [[06dcc1b](https://github.com/smartface/sf-extension-utils/commit/06dcc1b4b96c6e72225b1e4571a3b7d631becb74)] 11 | - v11.2.3 [[41a804c](https://github.com/smartface/sf-extension-utils/commit/41a804c98e8e5d652067eea2c8df85110064daca)] 12 | - v11.2.2 [[cec6b81](https://github.com/smartface/sf-extension-utils/commit/cec6b8183ec022c72504cbd25fa9e8e162427f6f)] 13 | - docs: Add googleplayservices documentation [[1faf081](https://github.com/smartface/sf-extension-utils/commit/1faf0819a4cf8137119c6e388ac037acb834bb79)] 14 | - fix: Fix for iOS11 [[240f579](https://github.com/smartface/sf-extension-utils/commit/240f5796fdae97045751efdd95e5955d48475f39)] 15 | - Merge pull request [#61](https://github.com/smartface/sf-extension-utils/issues/61) from smartface/dependabot/npm_and_yarn/acorn-7.1.1 [[e7c7ca5](https://github.com/smartface/sf-extension-utils/commit/e7c7ca568d527360e393504e9e6612fd7c48a74d)] 16 | - build(deps): bump acorn from 7.1.0 to 7.1.1 [[2b9e740](https://github.com/smartface/sf-extension-utils/commit/2b9e74087fce11c42903d337ee254302c9a76b83)] 17 | 18 | 19 | 20 | ## 11.2.1 (2020-04-09) 21 | 22 | ### Miscellaneous 23 | 24 | - Merge pull request [#64](https://github.com/smartface/sf-extension-utils/issues/64) from smartface/bugfifx/getcombinedstyle-guid [[f556d39](https://github.com/smartface/sf-extension-utils/commit/f556d39012e1e0eed10e302d191b1e98960190fe)] 25 | - fix(getCombinedStyle): remove guid and add proper name for dummy component [[3946144](https://github.com/smartface/sf-extension-utils/commit/394614414cbef066cebd59343e1f069d55e40245)] 26 | - bump: 11.2.0 [[9750ea6](https://github.com/smartface/sf-extension-utils/commit/9750ea6341231e80dd7d6eb8b31f5da22634d675)] 27 | - Merge pull request [#63](https://github.com/smartface/sf-extension-utils/issues/63) from smartface/bugfix/AND-3841 [[141d5f2](https://github.com/smartface/sf-extension-utils/commit/141d5f23721e54b934e70d844999983a442ce3a1)] 28 | - [AND-3841] Add GooglePlayServices class [[e7374d6](https://github.com/smartface/sf-extension-utils/commit/e7374d698b8d246a6062c97f01a4b2e8f5b10521)] 29 | - Merge pull request [#60](https://github.com/smartface/sf-extension-utils/issues/60) from smartface/fix/workaround-renault [[80db903](https://github.com/smartface/sf-extension-utils/commit/80db903d789b5c90dedca2f109402b72564bbd4a)] 30 | - fix: Support callback for location util [[eeae740](https://github.com/smartface/sf-extension-utils/commit/eeae740bda033e5f56ef877b0d605f22b7c1528f)] 31 | - Merge pull request [#59](https://github.com/smartface/sf-extension-utils/issues/59) from smartface/fix/workaround-renault [[39e6bb4](https://github.com/smartface/sf-extension-utils/commit/39e6bb4f625773b6cb6f0c4a590818a22ea46f04)] 32 | - fix: Fix for renault [[b5a8b5a](https://github.com/smartface/sf-extension-utils/commit/b5a8b5aabaead9c28469b561e41a54773d8c6b92)] 33 | - Merge pull request [#58](https://github.com/smartface/sf-extension-utils/issues/58) from smartface/feature/array-move-polyfill [[04117a7](https://github.com/smartface/sf-extension-utils/commit/04117a750c8703d9715c0b0361e0a559b1fbaac5)] 34 | - feature(base/polyfill): Add Array.move as property [[b04dbe1](https://github.com/smartface/sf-extension-utils/commit/b04dbe1913f3311f9eb04441d6624bb8916a7cac)] 35 | 36 | 37 | 38 | ## 11.1.0 (2020-01-21) 39 | 40 | ### Miscellaneous 41 | 42 | - Merge pull request [#57](https://github.com/smartface/sf-extension-utils/issues/57) from smartface/art [[474d8a7](https://github.com/smartface/sf-extension-utils/commit/474d8a70b3b877cdd3e35c6ff8a2937ba76120b0)] 43 | - Merge branch 'master' into art [[fa2e53a](https://github.com/smartface/sf-extension-utils/commit/fa2e53aff2ae0a86708fda49c2e0acb5731e2329)] 44 | - docs: Add documentation for CircularProgressBar [[c133b75](https://github.com/smartface/sf-extension-utils/commit/c133b75a09ae58f8c73726ee23f3ff187ecc7309)] 45 | - docs: Upgrade jsdoc module [[25df7b8](https://github.com/smartface/sf-extension-utils/commit/25df7b81aa0edea5eaec50a337c1f9a71d2b49f3)] 46 | - Update package.json [[68c7e2b](https://github.com/smartface/sf-extension-utils/commit/68c7e2bafb625f862aa09857e223ff1fd1a07102)] 47 | - fix: Require of CircularProgressBar [[0bd779b](https://github.com/smartface/sf-extension-utils/commit/0bd779baa0188609338aead232f02dfc80e89a08)] 48 | - feat: Add art util [[ed69f48](https://github.com/smartface/sf-extension-utils/commit/ed69f48008ff179d2db2164e6f9cd7f1b0114e04)] 49 | 50 | 51 | 52 | ## 11.0.0 (2020-01-02) 53 | 54 | ### Miscellaneous 55 | 56 | - v11.0.0 [[6afa066](https://github.com/smartface/sf-extension-utils/commit/6afa06675cefff2c45bd5710eb106e2bf2951941)] 57 | - Revert [[afe9aa8](https://github.com/smartface/sf-extension-utils/commit/afe9aa87cad26435e1b2a34bedd679f1c2e09454)] 58 | - fix: Permission management on location util [[9bddf26](https://github.com/smartface/sf-extension-utils/commit/9bddf266d9160dbee57b9d4b7c05b3e40413c3df)] 59 | - fix: Make permission util work again [[372e7f9](https://github.com/smartface/sf-extension-utils/commit/372e7f93f4afabb1758060d0c827443738e51457)] 60 | 61 | 62 | 63 | ## 10.0.3 (2019-12-27) 64 | 65 | ### Miscellaneous 66 | 67 | - Merge pull request [#55](https://github.com/smartface/sf-extension-utils/issues/55) from smartface/fix/GridView [[ef8aba2](https://github.com/smartface/sf-extension-utils/commit/ef8aba2d329568f652d9941ef844dc3025b12e97)] 68 | - fix(layoutManager): Fix crash on GridView when using getCombinedStyle [[cab4d3c](https://github.com/smartface/sf-extension-utils/commit/cab4d3c5cb7cdd2f51beb634c955a20fbe78d7e2)] 69 | - docs: Add CHANGELOG.md [[57ae563](https://github.com/smartface/sf-extension-utils/commit/57ae563a1a9c5f6f0056d0aec4cc31892c243869)] 70 | 71 | 72 | 73 | ## 10.0.2 (2019-12-20) 74 | 75 | ### Miscellaneous 76 | 77 | - chore: v10.0.2 [[c9d1e17](https://github.com/smartface/sf-extension-utils/commit/c9d1e17764a9d863615cb86aeeaaca82ce8f56df)] 78 | - fix: Assign pageProps to page [[697095b](https://github.com/smartface/sf-extension-utils/commit/697095b048c224221b5cda0ecf36164e43c99c66)] 79 | - chore: v10.0.1 [[2f3ea08](https://github.com/smartface/sf-extension-utils/commit/2f3ea08e4e128492b73b56ceaea657dc71d188ba)] 80 | - fix: Assign pageProps to page [[9f8955a](https://github.com/smartface/sf-extension-utils/commit/9f8955a037c663cabe0ca14637c20819628c1750)] 81 | - Merge pull request [#54](https://github.com/smartface/sf-extension-utils/issues/54) from smartface/biometricLogin-doc [[63b563f](https://github.com/smartface/sf-extension-utils/commit/63b563f13c0a1d31a10fbedc94d2e8cc3d8021c5)] 82 | - Fix bug on biometricLogin, renew docs [[d52bcad](https://github.com/smartface/sf-extension-utils/commit/d52bcade0a4ad814e41248dcae6db1b12ce25cc5)] 83 | 84 | 85 | 86 | ## 10.0.0 (2019-12-11) 87 | 88 | ### Miscellaneous 89 | 90 | - fix: handle request body when content type is x-www-form-urlencoded [[800351b](https://github.com/smartface/sf-extension-utils/commit/800351bf955d93f06f9e6fbf8134148d1990098d)] 91 | - Merge pull request [#53](https://github.com/smartface/sf-extension-utils/issues/53) from smartface/biometricLogin-doc [[1ede78f](https://github.com/smartface/sf-extension-utils/commit/1ede78fc7eec5d66dbc6bec01a30406eb3ceb408)] 92 | - Added a caution for data removal [[2a439a5](https://github.com/smartface/sf-extension-utils/commit/2a439a57d7cc098c209642ca5adfdb5c50a75fe5)] 93 | - Changed some fingerprint keywors to biometric [[c578ca4](https://github.com/smartface/sf-extension-utils/commit/c578ca48f339896602b99c87da63237438905949)] 94 | - Renamed fingerprint to biometricLogin and bumped to 10.0.0 [[a82c34e](https://github.com/smartface/sf-extension-utils/commit/a82c34e699f19714b86946e68b1aa4f241ce768c)] 95 | - Update back-close.md [[4f58063](https://github.com/smartface/sf-extension-utils/commit/4f58063ff05fe78253b5537086c26bf58f39c847)] 96 | - fix: Dismiss item color of Android [[3b1421f](https://github.com/smartface/sf-extension-utils/commit/3b1421f1fd3de6fec8d5d5e4a3edbab101ddf8cf)] 97 | - Merge pull request [#52](https://github.com/smartface/sf-extension-utils/issues/52) from smartface/bugfix/back-close [[86c2d76](https://github.com/smartface/sf-extension-utils/commit/86c2d7687dacdc5dda51fe569a49452a085d65a8)] 98 | - Update back-close.js [[cab1269](https://github.com/smartface/sf-extension-utils/commit/cab1269e2e5e54d90bcaa3752dd9641499b5e530)] 99 | - docs: fix typo [[8cf58e6](https://github.com/smartface/sf-extension-utils/commit/8cf58e61e2423feac37c6003e475f9f83a0f5bf1)] 100 | 101 | 102 | 103 | ## 9.0.3 (2019-11-22) 104 | 105 | ### Miscellaneous 106 | 107 | - v9.0.3 [[78230e3](https://github.com/smartface/sf-extension-utils/commit/78230e3daf052ded09b791e494b25e7bc6e0137f)] 108 | - docs: Fix buildExtender documentation [[9335ca8](https://github.com/smartface/sf-extension-utils/commit/9335ca8bf6df29d07e94fcfa5fa2571d7dd8119d)] 109 | - Merge pull request [#51](https://github.com/smartface/sf-extension-utils/issues/51) from smartface/offline [[d1f878a](https://github.com/smartface/sf-extension-utils/commit/d1f878a97748a6a1e9741f48cf8a1ce2ff62e8f9)] 110 | - Revert "fix: Unstable onShow/onHide events on Android" [[9a3adde](https://github.com/smartface/sf-extension-utils/commit/9a3adde77d2343bac4978bb5010eae52f1f035a5)] 111 | - Merge branch 'master' into offline [[13aa83d](https://github.com/smartface/sf-extension-utils/commit/13aa83d06b4656c4fa8d52f3daac57445a3df753)] 112 | - fix: Unstable onShow/onHide events on Android [[b88b76b](https://github.com/smartface/sf-extension-utils/commit/b88b76b6334020318e289c658418a6e96f625d19)] 113 | - perf: Improve offline database [[064cfe9](https://github.com/smartface/sf-extension-utils/commit/064cfe9170dad0263957f663ca0ec33167fc759c)] 114 | - perf: Improve offline database [[6f77f37](https://github.com/smartface/sf-extension-utils/commit/6f77f3734e634f2383714d50c901cc99d5aa6c7e)] 115 | - perf: Improve offline database [[d67063b](https://github.com/smartface/sf-extension-utils/commit/d67063b773bd6ddb9b272cd336c9abd88ad3945c)] 116 | 117 | 118 | 119 | ## 9.0.2 (2019-11-05) 120 | 121 | ### Miscellaneous 122 | 123 | - Merge pull request [#50](https://github.com/smartface/sf-extension-utils/issues/50) from smartface/bugfix/AND-3774 [[bf6417d](https://github.com/smartface/sf-extension-utils/commit/bf6417ded304353731bdf6557f7f9ca0163073c1)] 124 | - chore: v9.0.2 [[4fc840a](https://github.com/smartface/sf-extension-utils/commit/4fc840a19b83227d2542906b9902ae960535b123)] 125 | - fix : [AND-3774] override whole content of getPageIntance method [[f708ca4](https://github.com/smartface/sf-extension-utils/commit/f708ca4684e036b2788ad4383a56e3ffa5e5b91b)] 126 | 127 | 128 | 129 | ## 9.0.1 (2019-10-30) 130 | 131 | ### Miscellaneous 132 | 133 | - Merge pull request [#46](https://github.com/smartface/sf-extension-utils/issues/46) from smartface/hotfix-iOS-NSUrl [[66c2527](https://github.com/smartface/sf-extension-utils/commit/66c252794c75fac1fa19d3cab5dea478cdf00cb7)] 134 | - Merge pull request [#49](https://github.com/smartface/sf-extension-utils/issues/49) from smartface/dependabot/npm_and_yarn/handlebars-4.5.1 [[79ee97e](https://github.com/smartface/sf-extension-utils/commit/79ee97ec941a0127b1529c76b92a3830a8c020c8)] 135 | - Merge pull request [#48](https://github.com/smartface/sf-extension-utils/issues/48) from smartface/dependabot/npm_and_yarn/lodash-4.17.15 [[0e2ed36](https://github.com/smartface/sf-extension-utils/commit/0e2ed368d1d82a7259e1842c49fe4bcb43543f1a)] 136 | - Merge pull request [#47](https://github.com/smartface/sf-extension-utils/issues/47) from smartface/dependabot/npm_and_yarn/mixin-deep-1.3.2 [[63faaef](https://github.com/smartface/sf-extension-utils/commit/63faaefb1e8fff6e689828712843dcce644c8284)] 137 | - chore: v9.0.1 [[6f1ab88](https://github.com/smartface/sf-extension-utils/commit/6f1ab8899ac6e5be98d01c088b3da59a42d9c2bb)] 138 | - build(deps): bump handlebars from 4.0.12 to 4.5.1 [[8043534](https://github.com/smartface/sf-extension-utils/commit/80435340d50e27694b80fb9a5e855ba50000c7c9)] 139 | - build(deps): bump lodash from 4.17.11 to 4.17.15 [[9734c02](https://github.com/smartface/sf-extension-utils/commit/9734c023d1c4e625f4fa45692213848b4055d1cf)] 140 | - build(deps): bump mixin-deep from 1.3.1 to 1.3.2 [[9db8450](https://github.com/smartface/sf-extension-utils/commit/9db8450877ca184b6d3d53ccc91d3137f2853e53)] 141 | - Fixed issue causing error on nsurl [[265b50f](https://github.com/smartface/sf-extension-utils/commit/265b50f3efd5b4ecfaa0f437760e428cbee4618a)] 142 | - Merge pull request [#45](https://github.com/smartface/sf-extension-utils/issues/45) from smartface/bugfix/AND-3769 [[f1b0b79](https://github.com/smartface/sf-extension-utils/commit/f1b0b79e82ccd796f3298aaef58735859407be05)] 143 | - [AND-3769] get the DIRETCTION at initial time [[fd23a8e](https://github.com/smartface/sf-extension-utils/commit/fd23a8e4cfa9303a503224741578400b51398da4)] 144 | 145 | 146 | 147 | ## 9.0.0 (2019-10-18) 148 | 149 | ### Miscellaneous 150 | 151 | - Merge pull request [#44](https://github.com/smartface/sf-extension-utils/issues/44) from smartface/story/COR-1988 [[9504460](https://github.com/smartface/sf-extension-utils/commit/950446085883110892e3b470375bd80804b9c85d)] 152 | - v9.0.0 [[380d73e](https://github.com/smartface/sf-extension-utils/commit/380d73e4081f874576a161bccbfcfcf7f4df4683)] 153 | - [COR-1988] Update userAgent usage for android 10 [[a56aebc](https://github.com/smartface/sf-extension-utils/commit/a56aebc0059823915a945f616759f4c1ce2eb117)] 154 | 155 | 156 | 157 | ## 8.1.0 (2019-10-09) 158 | 159 | ### Miscellaneous 160 | 161 | - Merge pull request [#43](https://github.com/smartface/sf-extension-utils/issues/43) from smartface/story/AND-3725 [[bb7aa54](https://github.com/smartface/sf-extension-utils/commit/bb7aa54b7367d96eb8b6d6cb82ef51033016dcaa)] 162 | - v8.1.0 [[5bb09ff](https://github.com/smartface/sf-extension-utils/commit/5bb09ff650f3300fee4899e36546881c7d5aa7d6)] 163 | - feat: Add RTLTabBarController & RTLSwipeView [[982936e](https://github.com/smartface/sf-extension-utils/commit/982936ebbac6deebeb4b2e417579639cef2e38cf)] 164 | - [AND-3725] resolve conflicts [[061ed97](https://github.com/smartface/sf-extension-utils/commit/061ed9717fddaf4def110562fa3b8ce4cf5601f5)] 165 | - [AND-3725] Add the component to README & controll gravity case of tabbarcontroller [[847019a](https://github.com/smartface/sf-extension-utils/commit/847019a815d0859ace5517b830f61518cef92ac3)] 166 | - [AND-3725] minor fixes [[ce912a6](https://github.com/smartface/sf-extension-utils/commit/ce912a6215957a566b5766e02bf846a7c2955567)] 167 | - [AND-3725] rtltabbarcontroller & rtlswipeview analys is written [[06c9b3f](https://github.com/smartface/sf-extension-utils/commit/06c9b3ffe501cc0b3dbf6a5fb97f955b74ddd95e)] 168 | - RTL check for SwipeView [[377d4a0](https://github.com/smartface/sf-extension-utils/commit/377d4a0320d0c76df68acd89c96e079fddd25cba)] 169 | - [AND-3725] RTL supported Swipeview & TabbarControllers are imp [[99ffd53](https://github.com/smartface/sf-extension-utils/commit/99ffd53c29fa5f90c49310916c39ec2c7a9969ff)] 170 | 171 | 172 | 173 | ## 8.0.0 (2019-09-15) 174 | 175 | ### Miscellaneous 176 | 177 | - Merge pull request [#42](https://github.com/smartface/sf-extension-utils/issues/42) from smartface/story/COR-1980 [[ec5b0d1](https://github.com/smartface/sf-extension-utils/commit/ec5b0d16af98bfc3ae977398ca9ff9254d9b6ebe)] 178 | - Merge branch 'master' into fingerprint [[9c5da7e](https://github.com/smartface/sf-extension-utils/commit/9c5da7e4300b8491ee206248fa30ed9ebe3b63fa)] 179 | - docs: Add missing utils to README.md [[d33c9d0](https://github.com/smartface/sf-extension-utils/commit/d33c9d0b34311a4b7b219c3a03b6fe182192add2)] 180 | - docs: Add CONTRIBUTING.md [[99eebaa](https://github.com/smartface/sf-extension-utils/commit/99eebaa7dc162f69f1e6f5992770ad5e97f47a68)] 181 | - docs: Fix rootdetection docs [[c574f21](https://github.com/smartface/sf-extension-utils/commit/c574f21a4c01b45171c56aa966ba27b0b90542e4)] 182 | - refactor: Move security related utils under security folder [[e543caa](https://github.com/smartface/sf-extension-utils/commit/e543caaca7dd2bac510827102e19c9acab06e22e)] 183 | - fix: Add extra checks [[7216f9c](https://github.com/smartface/sf-extension-utils/commit/7216f9c3f3195bbf1c91b6909cb060924ddd83ba)] 184 | - fix: Handle timeout value when using static request method [[c2c7f76](https://github.com/smartface/sf-extension-utils/commit/c2c7f76f810a78a2208cd648ae7ed288acf35743)] 185 | - Merge branch 'master' into fingerprint [[0885b85](https://github.com/smartface/sf-extension-utils/commit/0885b8589e5208fff9c9d849d5a06b60121eb955)] 186 | - Merge branch 'master' into fingerprint [[fef3e86](https://github.com/smartface/sf-extension-utils/commit/fef3e86f6146695a9ca7b9ed07b7236d1d77bd9a)] 187 | - Revert "Added autoLogin flag to the fingerprint" [[64b5fb5](https://github.com/smartface/sf-extension-utils/commit/64b5fb56e6d0bd681cf508be0643ee3a569a7a29)] 188 | - Added autoLogin flag to the fingerprint [[b36d75e](https://github.com/smartface/sf-extension-utils/commit/b36d75e9c50f22df1eb2b76cc6976d7ad2d63e4b)] 189 | - obtain apiKey with google doc [[3e59e58](https://github.com/smartface/sf-extension-utils/commit/3e59e58165eb810cee4e802fc9c1ac80fba48fd2)] 190 | - analysis improved [[9f0160d](https://github.com/smartface/sf-extension-utils/commit/9f0160dd48957c4282c2b6e2beeb759e37634971)] 191 | - all methods are exposed [[3b55efe](https://github.com/smartface/sf-extension-utils/commit/3b55efe35abf15f3c1a05272e78016b0156e1a4d)] 192 | - [COR-1980] googlesafety net module's analysis improved [[eb58f29](https://github.com/smartface/sf-extension-utils/commit/eb58f2970be66188c27cc716d27236b9eeb276fd)] 193 | - [COR-1980] make singleton instaead of static [[2ed2e8a](https://github.com/smartface/sf-extension-utils/commit/2ed2e8aed5192147c1cf2e58bc4a506a83bc9d19)] 194 | - [COR-1980] rootdetection methods are added for android [[b5118c8](https://github.com/smartface/sf-extension-utils/commit/b5118c85bc0d2e907ed40a73757140c2470ef282)] 195 | - Added iOS [[8bcab08](https://github.com/smartface/sf-extension-utils/commit/8bcab0847a13885fcf173e3483304ca5914301a9)] 196 | - [COR-1980] google safety net helper class analysis written [[5090b41](https://github.com/smartface/sf-extension-utils/commit/5090b413c29018e55532587a262fcec05025b7af)] 197 | - [COR-1980] root detection analysis added [[8c3b6b1](https://github.com/smartface/sf-extension-utils/commit/8c3b6b1fdcb2f571036c522cfa4782f37c0f2245)] 198 | - Merge branch 'master' into fingerprint [[eb36c1b](https://github.com/smartface/sf-extension-utils/commit/eb36c1b2c4203a3353616377f5092ce4132ab97c)] 199 | - docs: Update docs [[38689d3](https://github.com/smartface/sf-extension-utils/commit/38689d35ad21352cdc7274cd9839774c41ec43c1)] 200 | - feat: Remove pageName of buildExtender and add getPageClass instead [[b5f7820](https://github.com/smartface/sf-extension-utils/commit/b5f782058f44cf1528475339beb5bdb5b28e1259)] 201 | - Merge remote-tracking branch 'origin/master' into fingerprint [[195f4e7](https://github.com/smartface/sf-extension-utils/commit/195f4e7197eca6d8827681e0547955490a5ccf05)] 202 | - changed arrow function to normal function [[73afe1d](https://github.com/smartface/sf-extension-utils/commit/73afe1d64afbebd765794dc9b9a2738dcad046d4)] 203 | - style(fingerprint): Converted one promise to one-line and converted a function to arrow function [[9747819](https://github.com/smartface/sf-extension-utils/commit/974781999e22cc1371bce783b1ed6d4ea7a7ce4a)] 204 | - fix(fingerprint-save-user): Fixed a problem that makes user unable to save credentials [[83b8133](https://github.com/smartface/sf-extension-utils/commit/83b8133fcb98287d4988e3bba788e500776e19a2)] 205 | - Merged with development [[b7c68be](https://github.com/smartface/sf-extension-utils/commit/b7c68be8648749d9a1ae0eb36033f3844de8c77a)] 206 | - fix(fingerprint-update-no): Fixed a case that clicking no to update stored credentials causing the a [[aad05a0](https://github.com/smartface/sf-extension-utils/commit/aad05a0c7b0f32826e0d3a0685e6a70e7968d9ef)] 207 | - fix(fingerprint-update): Moved update stored credential prompt BEFORE loginHandler [[a99891e](https://github.com/smartface/sf-extension-utils/commit/a99891eb7f7b7dbe5ffed98a2000e6af3d47931d)] 208 | - chore(fingerprint): Removed forgotten console log [[5604d26](https://github.com/smartface/sf-extension-utils/commit/5604d264a63439db8bd01f5fcd84e82a47eb868d)] 209 | - fix(fingerprint): Updated docs and added System.fingerprintAvailable check [[f4c1f5a](https://github.com/smartface/sf-extension-utils/commit/f4c1f5a718cd952e4159dfce75d20096c64300c6)] 210 | - Merge pull request [#39](https://github.com/smartface/sf-extension-utils/issues/39) from smartface/bugfix/fingerprint-not-trigger [[c179eb4](https://github.com/smartface/sf-extension-utils/commit/c179eb47660838b7c613ebbe90479beb43cb3f1a)] 211 | - fixed fingerprint not triggering on second logins [[65d50ee](https://github.com/smartface/sf-extension-utils/commit/65d50eefd568962b386b30fc9b05408af07a347e)] 212 | - fix: Fix conflict [[97d4d8d](https://github.com/smartface/sf-extension-utils/commit/97d4d8d3b113139a24e13ad35f962957423ddc5f)] 213 | - Fix conflict [[bbbb895](https://github.com/smartface/sf-extension-utils/commit/bbbb8950a65fc61c00d0a82412be2acde02c7a7c)] 214 | - fix: Fix conflict [[d1f6a13](https://github.com/smartface/sf-extension-utils/commit/d1f6a13f5775ba979cd7f701a3eabae505eba2d2)] 215 | - fix: Fix conflict [[5f6994a](https://github.com/smartface/sf-extension-utils/commit/5f6994a9159c24ad9a19821b6f2d6a68f76b769b)] 216 | - updated with master [[0524bb5](https://github.com/smartface/sf-extension-utils/commit/0524bb5e307f8e20782be4e74e521057f7d30265)] 217 | - Merge pull request [#33](https://github.com/smartface/sf-extension-utils/issues/33) from smartface/fingerprint-securedata [[bbbae3b](https://github.com/smartface/sf-extension-utils/commit/bbbae3b8f3f1c37c53471fd2bc819c3499cb4060)] 218 | - changed variable to SecureData [[0e9aa14](https://github.com/smartface/sf-extension-utils/commit/0e9aa14cb2c47fc46b68ecd9da33dbb86888c150)] 219 | - made the requested changes, converted to cascal case [[a087f30](https://github.com/smartface/sf-extension-utils/commit/a087f30536e92a19876717f5637f6ee6be650bbd)] 220 | - made securedata objects static [[f91c4e8](https://github.com/smartface/sf-extension-utils/commit/f91c4e8802890500434efdb0d1337e7d3dc4f65f)] 221 | - Fix 'checking if faceID is enabled or not' [[a585466](https://github.com/smartface/sf-extension-utils/commit/a5854667a98b2d9062b777d863052d2736321721)] 222 | - added log for reading username on load [[c4f2cc3](https://github.com/smartface/sf-extension-utils/commit/c4f2cc3fe24a8c4d1fec1efa61d5f5e1e74ebe04)] 223 | - updated v7.0.0 [[dcbad90](https://github.com/smartface/sf-extension-utils/commit/dcbad90e261423f69d4a383e5e5005264d409479)] 224 | - new fingerprint lib [[de77219](https://github.com/smartface/sf-extension-utils/commit/de77219df1fda1508542a1d259531b51bad36574)] 225 | 226 | 227 | 228 | ## 7.2.0 (2019-07-29) 229 | 230 | ### Miscellaneous 231 | 232 | - v7.2.0 [[4e289cb](https://github.com/smartface/sf-extension-utils/commit/4e289cb80f2eec4e4f6e90ae8319160fabbbe78d)] 233 | - Add beforeShow event [[bfbb751](https://github.com/smartface/sf-extension-utils/commit/bfbb7511201c918971be2b6ebb8c8e0e02f3088e)] 234 | - change url according to AND9, also working in ios [[86fd17e](https://github.com/smartface/sf-extension-utils/commit/86fd17eea97f25ce1a570b7759f74ce0681ac928)] 235 | - fix: Handle empty bodies of service response [[cad46d1](https://github.com/smartface/sf-extension-utils/commit/cad46d15524ea59751d3c7ed23b079545b671643)] 236 | - Merge pull request [#41](https://github.com/smartface/sf-extension-utils/issues/41) from smartface/polyfill-padStart [[e428baf](https://github.com/smartface/sf-extension-utils/commit/e428baf7d0577805676f54917cfcf37d72738fb6)] 237 | - Merge branch 'master' into polyfill-padStart [[b444e98](https://github.com/smartface/sf-extension-utils/commit/b444e98c910c7bb206349c5ddf648dcdd6a57192)] 238 | - Merge pull request [#40](https://github.com/smartface/sf-extension-utils/issues/40) from smartface/polyfill-stackTrace [[5666b6f](https://github.com/smartface/sf-extension-utils/commit/5666b6ff6bf7105fbc9d939ae1fcbbe708716d60)] 239 | - feat(polyfill-padStart): Added a polyfill for String.prototype.padStart [[09259f4](https://github.com/smartface/sf-extension-utils/commit/09259f42027b427f4abe2dbb7f7412596c0119d3)] 240 | - Fix unhandling errors [[c705d1f](https://github.com/smartface/sf-extension-utils/commit/c705d1f08fdccb8b61f75457901c7f7b8f88b1e2)] 241 | - feat(polyfill-stacktrace): Added a polyfill for devices not showing stacktrace properly [[1b32deb](https://github.com/smartface/sf-extension-utils/commit/1b32debc2adac58860c1a61b83d3add6d3c9547a)] 242 | 243 | 244 | 245 | ## 7.0.0 (2019-06-20) 246 | 247 | ### Miscellaneous 248 | 249 | - Merge pull request [#36](https://github.com/smartface/sf-extension-utils/issues/36) from smartface/bug/AND-3668 [[a649aeb](https://github.com/smartface/sf-extension-utils/commit/a649aeba29e7aa2c2c3aae92ed3f1f4f5cbfe30d)] 250 | - 7.0.0 [[32689d3](https://github.com/smartface/sf-extension-utils/commit/32689d3158029014579b9defff58d0e9071120ae)] 251 | - Merge branch 'master' into bug/AND-3668 [[a13f4f7](https://github.com/smartface/sf-extension-utils/commit/a13f4f7471cb99bad5e589f572df31f128a07b88)] 252 | - Merge branch 'pdf' [[822b8fc](https://github.com/smartface/sf-extension-utils/commit/822b8fc69838f42a36826f294cdd2e29ddbeed37)] 253 | - docs: Add documentation for pdf util [[3a2fc6d](https://github.com/smartface/sf-extension-utils/commit/3a2fc6d2f63224e9b2a85d9dcf450af922ac72d0)] 254 | - style: Beautify code [[31d441c](https://github.com/smartface/sf-extension-utils/commit/31d441c0c5f1c7db48ebcdee46465dd90fc20c75)] 255 | - perf(permission): Change array of permissions to one permission [[e0d4d96](https://github.com/smartface/sf-extension-utils/commit/e0d4d96b62eb97650e34b0d81d003a7ee1914e9e)] 256 | - docs(permission.js) fix bad naming [[c0298ee](https://github.com/smartface/sf-extension-utils/commit/c0298ee4b0c69e63710061ca528d3b46832b33fc)] 257 | - Merge branch 'master' into bug/AND-3668 [[a3e8a02](https://github.com/smartface/sf-extension-utils/commit/a3e8a02b83c2b02c2a19900ea8f9746aadd7c93b)] 258 | - build: v6.4.2 [[ed433f4](https://github.com/smartface/sf-extension-utils/commit/ed433f407dcb18cb89ba25d966294f7410068744)] 259 | - docs(permission.js): change example for callback refactor(callback): change permission's callback [[23ad4b4](https://github.com/smartface/sf-extension-utils/commit/23ad4b47ba831ca6d3e30a4e4a615cc352641d56)] 260 | - Merge branch 'master' into pdf [[9c4cd9a](https://github.com/smartface/sf-extension-utils/commit/9c4cd9ae9bc41f906dd131cf784f5f62e0af704c)] 261 | - 6.4.1 [[53e2a56](https://github.com/smartface/sf-extension-utils/commit/53e2a5633a8da997afe7969b9776b2febe491b26)] 262 | - perf(Network): Add extra check for network.isConnected to improve performance [[ceafae0](https://github.com/smartface/sf-extension-utils/commit/ceafae0d32a49302e8f1388c07b55bde24e0cfa1)] 263 | - Merge pull request [#35](https://github.com/smartface/sf-extension-utils/issues/35) from smartface/bug/COR-1966 [[8bbddb8](https://github.com/smartface/sf-extension-utils/commit/8bbddb87351c255340f0ac18d3eca9d5cb21338c)] 264 | - fix: Fix rendering when pdf has more than 1 pages [[0bc672d](https://github.com/smartface/sf-extension-utils/commit/0bc672d0be88401a148b351e2db4075958016530)] 265 | - feat: Implement pdf renderer for both platforms [[0cac98a](https://github.com/smartface/sf-extension-utils/commit/0cac98aa797f9a1594d279e7eac31430207578ae)] 266 | 267 | 268 | 269 | ## 6.4.0 (2019-06-11) 270 | 271 | ### Miscellaneous 272 | 273 | - 6.4.0 [[c00b9df](https://github.com/smartface/sf-extension-utils/commit/c00b9dfbdc6630f02e80b240f13505430d73b0f7)] 274 | - feat(Network): Add internet connectivity check [[871aea8](https://github.com/smartface/sf-extension-utils/commit/871aea82669c9cdaf4937cccdf418c89e5cb16c5)] 275 | - network connectivity added [[2250c89](https://github.com/smartface/sf-extension-utils/commit/2250c894b4b029562f7b3dd2870454e964319085)] 276 | 277 | 278 | 279 | ## 6.3.0 (2019-04-25) 280 | 281 | ### Miscellaneous 282 | 283 | - build: v6.3.0 [[ec0ea4b](https://github.com/smartface/sf-extension-utils/commit/ec0ea4b37f397ea7a278c06845459e6c9cfbc5d9)] 284 | - docs(settings.js): Add example for openApplicationSettings [[b79abc7](https://github.com/smartface/sf-extension-utils/commit/b79abc7a6ef42092b3d8133e2e05b57ea35a1929)] 285 | - feat(settings.js): Implement settings util [[4f523f4](https://github.com/smartface/sf-extension-utils/commit/4f523f4b3f9a97b9c3ddc40d962097bfc3b7a9b6)] 286 | - Merge pull request [#34](https://github.com/smartface/sf-extension-utils/issues/34) from oyilmaztekin/fix-gitignore [[45d302a](https://github.com/smartface/sf-extension-utils/commit/45d302a4b30a801643f6e9bcc87428677e8fb748)] 287 | - added node_modules in .gitignore [[f1365ab](https://github.com/smartface/sf-extension-utils/commit/f1365ab49cc77bfd714e5968426a9fff00a57134)] 288 | 289 | 290 | 291 | ## 6.2.1 (2019-03-29) 292 | 293 | ### Miscellaneous 294 | 295 | - v6.2.1 [[7dab0ee](https://github.com/smartface/sf-extension-utils/commit/7dab0ee598b2b5998dcc6d84be6ef1b035c179e0)] 296 | - Add mutex support to db for service-call-offline [[f0ace91](https://github.com/smartface/sf-extension-utils/commit/f0ace9179751467004271e86c6057c8c23915014)] 297 | 298 | 299 | 300 | ## 6.2.0 (2019-03-14) 301 | 302 | ### Miscellaneous 303 | 304 | - v6.2.0 [[f6196cc](https://github.com/smartface/sf-extension-utils/commit/f6196ccc5ad535927b2b0766dd33bec8286b48cf)] 305 | - Add encryptionFunction & decryptionFunction options for initialization of servoce-call-offline [[7310f38](https://github.com/smartface/sf-extension-utils/commit/7310f380dc9cfd079ff32766b2992c3ad165e648)] 306 | 307 | 308 | 309 | ## 6.1.1 (2019-03-13) 310 | 311 | ### Miscellaneous 312 | 313 | - Merge pull request [#32](https://github.com/smartface/sf-extension-utils/issues/32) from smartface/navigate-cookie [[e7680b9](https://github.com/smartface/sf-extension-utils/commit/e7680b9fcd950e84fa6d141310bc58f31a654c5b)] 314 | - Fixed custom navigate [[cf7b0fd](https://github.com/smartface/sf-extension-utils/commit/cf7b0fd77eb77631b3110906f8593891aec0742d)] 315 | - 6.1.1 [[d2f69e1](https://github.com/smartface/sf-extension-utils/commit/d2f69e1c1776c81018719328f7f023b8594a83ce)] 316 | 317 | 318 | 319 | ## 6.1.0 (2019-03-06) 320 | 321 | ### Miscellaneous 322 | 323 | - Merge pull request [#31](https://github.com/smartface/sf-extension-utils/issues/31) from smartface/location [[d1c1960](https://github.com/smartface/sf-extension-utils/commit/d1c19602cf2e6f4b0e73668283e8a1cf46299e2e)] 324 | - v6.1.0 [[d37df63](https://github.com/smartface/sf-extension-utils/commit/d37df63e65bf990a383cd1c5eec1a902c5c897e6)] 325 | - Update location docs [[b0e5d93](https://github.com/smartface/sf-extension-utils/commit/b0e5d93366b948d62a7876370e0d0c0451a69e25)] 326 | - Return location denied reason for all negative cases [[9e1f683](https://github.com/smartface/sf-extension-utils/commit/9e1f6839fb1f408acb6a07f4cb111a954b4c3739)] 327 | - Beautify goBack.js [[b7f6c85](https://github.com/smartface/sf-extension-utils/commit/b7f6c853737d4666d9519dc8ca13ea062c36ba5d)] 328 | - Fix location issues on Android when device location is disabled [[c18b8af](https://github.com/smartface/sf-extension-utils/commit/c18b8afc5d2f59f43486e9ef8253964008739f4d)] 329 | 330 | 331 | 332 | ## 6.0.1 (2019-03-01) 333 | 334 | ### Miscellaneous 335 | 336 | - v6.0.1 [[21d4a3d](https://github.com/smartface/sf-extension-utils/commit/21d4a3d26e9e110f67d3a258f26e098185d1e193)] 337 | - SUPDEV-1902 - Implement closing query results [[0c8d2ee](https://github.com/smartface/sf-extension-utils/commit/0c8d2eeebdba110de27e4ea343df71ffa5d3afdd)] 338 | 339 | 340 | 341 | ## 6.0.0 (2019-02-27) 342 | 343 | ### Miscellaneous 344 | 345 | - v6.0.0 [[50487d4](https://github.com/smartface/sf-extension-utils/commit/50487d49438efdfb3ef328ab82a44ac614b25bd0)] 346 | - Add offline documentation [[05c3206](https://github.com/smartface/sf-extension-utils/commit/05c3206920a505c7953a2a7d274bc3b997c5fccd)] 347 | - Merge branch 'master' into offline [[18a85ce](https://github.com/smartface/sf-extension-utils/commit/18a85ceeb89c446fb00ecb731c791c0e732ec873)] 348 | - Improve logs [[df6c8d4](https://github.com/smartface/sf-extension-utils/commit/df6c8d47045a9e8404a6463d756d825b9db6359c)] 349 | - Make db operations sync [[c45c851](https://github.com/smartface/sf-extension-utils/commit/c45c8510a5607f68e47d613caabf390fca074870)] 350 | - Fix closeOfflineDatabase [[3e0bd20](https://github.com/smartface/sf-extension-utils/commit/3e0bd20b2f4facae32af82a3e64fe24f9b30824d)] 351 | - Expose closeOfflineDatabase method for offline service call [[399b1fb](https://github.com/smartface/sf-extension-utils/commit/399b1fbfba087d7b58c26a009be24c3d7ece9788)] 352 | - Delete unnecessary stuff [[e73602d](https://github.com/smartface/sf-extension-utils/commit/e73602d02365d5faaf3fc152946977f1f5ebddd0)] 353 | - Enable encryption [[b48ec76](https://github.com/smartface/sf-extension-utils/commit/b48ec76169c0030e7c0a27de3ae0dad4c18fba81)] 354 | - Fix location util for Android [[9ded64a](https://github.com/smartface/sf-extension-utils/commit/9ded64a23f798b55540aee1f05599aeac03b2237)] 355 | - Update documentation [[e5ad528](https://github.com/smartface/sf-extension-utils/commit/e5ad52882c5c86fe96c0133344b1f5b05d242224)] 356 | - Support backward with location util [[97370bd](https://github.com/smartface/sf-extension-utils/commit/97370bdfaa1535069e7d43d02dc1f0e2b698d1dd)] 357 | - Fix promise statement [[2b96ee2](https://github.com/smartface/sf-extension-utils/commit/2b96ee212ca6a26827f97df7a1eac10c76ce0daf)] 358 | - Implement new location util [[52652e7](https://github.com/smartface/sf-extension-utils/commit/52652e7551bf19f03dc70b2df3c6c7c1a3cfe789)] 359 | - Implement clearOfflineDatabase instead of destroyOfflineDatabase [[5a8d413](https://github.com/smartface/sf-extension-utils/commit/5a8d4134809b0164fee83e6ee3feab92763c8662)] 360 | - Implement destroyOfflineDatabase [[966bc7a](https://github.com/smartface/sf-extension-utils/commit/966bc7a796a7255dd7752062d04dd235e6c034c2)] 361 | - Use promise with OfflineRequestServiceCall.offlineRequestHandler [[e53615e](https://github.com/smartface/sf-extension-utils/commit/e53615eae649219397b72112c969f540ff146596)] 362 | - Fix escaping single quotes when saving responses to db [[b5bc46f](https://github.com/smartface/sf-extension-utils/commit/b5bc46fc3f9bf5a2a0ab81db13e03882f348bcd3)] 363 | - Merge branch 'master' into offline [[ad9b105](https://github.com/smartface/sf-extension-utils/commit/ad9b105b7bad2ec2c2431a22739d1eb1a374a906)] 364 | - Implement serveFrom option for OfflineResponseServiceCall [[bed805c](https://github.com/smartface/sf-extension-utils/commit/bed805c9d18c5f90aae7f818de524bba8b34310f)] 365 | - changes for clean and handling of offline service calls [[68557d3](https://github.com/smartface/sf-extension-utils/commit/68557d33afa2c90b16e166b9dc3bf26a19434f71)] 366 | - Fix Promise.resolve statement [[fb7f73c](https://github.com/smartface/sf-extension-utils/commit/fb7f73c3241f760038b686e8794a41eaacce65fc)] 367 | - minor fixes on service-call-offline [[d0ab0f0](https://github.com/smartface/sf-extension-utils/commit/d0ab0f0323f7a643147d4cb2c3cd43c305ad2f80)] 368 | - Merge branch 'master' into offline [[2fed76d](https://github.com/smartface/sf-extension-utils/commit/2fed76d9c10d8b11b284aeb1e8ad9b64ee713d1c)] 369 | - offline service-call support [[51e4ef1](https://github.com/smartface/sf-extension-utils/commit/51e4ef1d37fc8f4f2bcfc1226bccf22f364a4413)] 370 | 371 | 372 | 373 | ## 5.5.5 (2019-02-25) 374 | 375 | ### Miscellaneous 376 | 377 | - Merge pull request [#30](https://github.com/smartface/sf-extension-utils/issues/30) from smartface/goBack-fixes [[20b0c2b](https://github.com/smartface/sf-extension-utils/commit/20b0c2b1f702b0d70a0b08cb4ae0a00c98c51099)] 378 | - updated to 5.5.5 and fixed a bottomtabbar router issue [[d4beca6](https://github.com/smartface/sf-extension-utils/commit/d4beca606b43427e53ac40e313731b15550a73c6)] 379 | - Merge pull request [#29](https://github.com/smartface/sf-extension-utils/issues/29) from smartface/goBack-fixes [[eab0835](https://github.com/smartface/sf-extension-utils/commit/eab08352cfa6f30bd0d731f66ed4b6fa108927d5)] 380 | - handles android back button actions ( not on bottomtabbar for now) [[9218e30](https://github.com/smartface/sf-extension-utils/commit/9218e30cd8b41139378516edb03bef1fd31be591)] 381 | 382 | 383 | 384 | ## 5.5.4 (2019-02-18) 385 | 386 | ### Miscellaneous 387 | 388 | - Merge pull request [#28](https://github.com/smartface/sf-extension-utils/issues/28) from smartface/getCombinedStyle-copy-remove [[f1f2822](https://github.com/smartface/sf-extension-utils/commit/f1f28226646efa78b91c96e8d555154679964fb9)] 389 | - v5.5.4 [[ae44f1f](https://github.com/smartface/sf-extension-utils/commit/ae44f1f3c844a89bcc029c1d415423c491b824ff)] 390 | - removed copy util from getCombinedStyle, because of nativeObject on iOS [[be82403](https://github.com/smartface/sf-extension-utils/commit/be82403650a4feaf2e7d06d1b8e9270c8a4f0d19)] 391 | 392 | 393 | 394 | ## 5.5.3 (2019-02-14) 395 | 396 | ### Miscellaneous 397 | 398 | - Adapt location util for changes in @smartface/native [[e990971](https://github.com/smartface/sf-extension-utils/commit/e990971325198e456e47a2fbc38a7bc806f8cdd6)] 399 | - v5.5.3 [[ad6c31f](https://github.com/smartface/sf-extension-utils/commit/ad6c31f4f994bc1aa4ff5daa61ab4db3ec6d7245)] 400 | 401 | 402 | 403 | ## 5.5.2 (2019-02-06) 404 | 405 | ### Miscellaneous 406 | 407 | - v5.5.2 [[3fb7f8c](https://github.com/smartface/sf-extension-utils/commit/3fb7f8cfb4005ce04035cadadc3a1a3430d571a6)] 408 | - Fix navigation util for Android [[65e1d27](https://github.com/smartface/sf-extension-utils/commit/65e1d272c063dfaebb8aade98cf3086005bced22)] 409 | 410 | 411 | 412 | ## 5.5.1 (2019-02-06) 413 | 414 | ### Miscellaneous 415 | 416 | - v5.5.1 [[8f6f720](https://github.com/smartface/sf-extension-utils/commit/8f6f7202af0418e8e69430b46a4d4a486e9f29bc)] 417 | - Fix navigation util for Android [[d38158e](https://github.com/smartface/sf-extension-utils/commit/d38158ea20d9af4bf381df42d8fa123c3b7cd99b)] 418 | 419 | 420 | 421 | ## 5.5.0 (2019-02-06) 422 | 423 | ### Miscellaneous 424 | 425 | - Merge pull request [#26](https://github.com/smartface/sf-extension-utils/issues/26) from smartface/fingerprintForce [[ea4a429](https://github.com/smartface/sf-extension-utils/commit/ea4a42935fdc2c8184ae34cbce583f206346f3b3)] 426 | - updated v5.5.0 [[5fa706d](https://github.com/smartface/sf-extension-utils/commit/5fa706da33b86a139205cea4b8ae22e179fb3edd)] 427 | - service-call: better handling for response contentType; ability to get the full response instead of just the body [[eecfad4](https://github.com/smartface/sf-extension-utils/commit/eecfad4322fbefabdb242020645611efee03aebf)] 428 | - extendEvent returns value [[ce95a69](https://github.com/smartface/sf-extension-utils/commit/ce95a696ff3ab4739894f9bb07cdfa546aa1115b)] 429 | - Merge branch 'master' into fingerprintForce [[e934f0c](https://github.com/smartface/sf-extension-utils/commit/e934f0cb9c59c28018a7f2813d7407eda0a85ca1)] 430 | - updated readme [[a2011f3](https://github.com/smartface/sf-extension-utils/commit/a2011f312e379b735be08bb5a1f02d086398b09a)] 431 | - added force option on fingerprint utility to recreate elements [[5c83e72](https://github.com/smartface/sf-extension-utils/commit/5c83e7237648c38078a3691c75f7d2932e81bcf3)] 432 | 433 | 434 | 435 | ## 5.4.0 (2019-01-14) 436 | 437 | ### Miscellaneous 438 | 439 | - updated v5.4.0 [[7b9b893](https://github.com/smartface/sf-extension-utils/commit/7b9b8936c46f6fa7758581c18c134a791ae518ee)] 440 | - new utils for router [[4b52218](https://github.com/smartface/sf-extension-utils/commit/4b52218698b3949e64e1f66e72b21ba54b064a54)] 441 | 442 | 443 | 444 | ## 5.3.1 (2019-01-08) 445 | 446 | ### Miscellaneous 447 | 448 | - updated to version 5.3.1 [[3a9cfdd](https://github.com/smartface/sf-extension-utils/commit/3a9cfddb1d249ac3ab997a91a05668bc3ee7fc4a)] 449 | - handling different formants of iOS & Android evalJS responses [[16bcfd7](https://github.com/smartface/sf-extension-utils/commit/16bcfd7160896a4206caf1c90f61b8e4ec7fffc9)] 450 | - change to v5.3.0 [[20315a2](https://github.com/smartface/sf-extension-utils/commit/20315a263371add546a9a2a50ebf029e7bb8235e)] 451 | - Merge branch 'master' of github.com:smartface/sf-extension-utils [[7746d98](https://github.com/smartface/sf-extension-utils/commit/7746d981208a5f4d31401b3d825f7a269eed0039)] 452 | - Merge pull request [#23](https://github.com/smartface/sf-extension-utils/issues/23) from smartface/new-console-log [[39b9c3c](https://github.com/smartface/sf-extension-utils/commit/39b9c3cf28828aeb83dee8fdd4c5d45f09ca2068)] 453 | - v5.2.0 [[0de9c2a](https://github.com/smartface/sf-extension-utils/commit/0de9c2ac9f7b2058ecf4312be8981c512d11e94b)] 454 | - Adjust console.log statements [[50897ca](https://github.com/smartface/sf-extension-utils/commit/50897ca7a1c98450edb69c028d87732f66ce2307)] 455 | 456 | 457 | 458 | ## 5.2.0 (2019-01-06) 459 | 460 | ### Miscellaneous 461 | 462 | - change to v5.2.0 [[7b757cf](https://github.com/smartface/sf-extension-utils/commit/7b757cf5cbdc56eb6265b5703f4c257080bb5200)] 463 | - added skip options for webviewbridge [[962b7cf](https://github.com/smartface/sf-extension-utils/commit/962b7cf99b6749ed765944b12b9fec062480b80c)] 464 | 465 | 466 | 467 | ## 5.1.1 (2018-12-18) 468 | 469 | ### Miscellaneous 470 | 471 | - updated v5.1.1 [[0d597fc](https://github.com/smartface/sf-extension-utils/commit/0d597fcf915f2a982e93c97b121f356f341332bf)] 472 | - if elevation change is 0, no need to animate [[6d5f7fd](https://github.com/smartface/sf-extension-utils/commit/6d5f7fdcdcf902fa5b9e7f7ddc7700c762441f79)] 473 | 474 | 475 | 476 | ## 5.1.0 (2018-12-17) 477 | 478 | ### Miscellaneous 479 | 480 | - fix for small docs in touch [[59cc1b5](https://github.com/smartface/sf-extension-utils/commit/59cc1b5c0edf63490e2407b21503ad0767f5d929)] 481 | - fixes in touch docs [[1b0f682](https://github.com/smartface/sf-extension-utils/commit/1b0f682eec27a7ce0a1ecc77d4a84a01146e1831)] 482 | - changes in docs [[8489ad6](https://github.com/smartface/sf-extension-utils/commit/8489ad6c671a6b572fa9fcc983f5fbb39c82c2ba)] 483 | - fixes in touch docs [[5f3e055](https://github.com/smartface/sf-extension-utils/commit/5f3e055773f5d9128fef59bcc97471096a24d3dc)] 484 | - added setting & getting touch effects defaults [[fc76bdb](https://github.com/smartface/sf-extension-utils/commit/fc76bdb576b434d85c523ce49db6d22827d557cb)] 485 | - Merge pull request [#21](https://github.com/smartface/sf-extension-utils/issues/21) from smartface/touchRippleDelay [[9f701ac](https://github.com/smartface/sf-extension-utils/commit/9f701ac6e9954e269052e13e38295a3bf7854588)] 486 | - changed ripple duration to 100 MS and made it default [[5366067](https://github.com/smartface/sf-extension-utils/commit/5366067ffc983186e9a15133f2ad9bc28e2c13d7)] 487 | 488 | 489 | 490 | ## 5.0.0 (2018-12-14) 491 | 492 | ### Miscellaneous 493 | 494 | - Merge pull request [#19](https://github.com/smartface/sf-extension-utils/issues/19) from smartface/navigation [[89fc8d1](https://github.com/smartface/sf-extension-utils/commit/89fc8d11397c77062a3d7cb7efa6b2c4333c93c2)] 495 | - Merge pull request [#20](https://github.com/smartface/sf-extension-utils/issues/20) from smartface/rippleEffectTouch [[1bd9dba](https://github.com/smartface/sf-extension-utils/commit/1bd9dbad3c723b2fe330b6572ab9bcdbeee3b2e5)] 496 | - updated to v5 for touch effects incompatibility with older runtimes [[5580872](https://github.com/smartface/sf-extension-utils/commit/5580872f456692e0604ed84003d8792d95a5890a)] 497 | - fix for minor typoo in touch.js [[3ccd639](https://github.com/smartface/sf-extension-utils/commit/3ccd639b57667e0b029eac4e6bfc4303e1096885)] 498 | - applied several changes on touch effects [[15fb055](https://github.com/smartface/sf-extension-utils/commit/15fb055223f9d48db98330c06a533b460fcfff21)] 499 | - touch def changed [[8802161](https://github.com/smartface/sf-extension-utils/commit/8802161df49471ba0ea9ccaed9e857454a45be88)] 500 | - ios guide [[f382df6](https://github.com/smartface/sf-extension-utils/commit/f382df61d3892b19e88279160a611e49d2fd1344)] 501 | - added analysis for iOS [[fb44a04](https://github.com/smartface/sf-extension-utils/commit/fb44a04f6c9cb7e1bfad2b8e75c1e9ccace262d4)] 502 | - Fixed conflict [[6e0625d](https://github.com/smartface/sf-extension-utils/commit/6e0625d5ec5615ea61c05da88ed7d1880327b5f1)] 503 | - Merge branch 'ios-fade' into rippleEffectTouch [[595295e](https://github.com/smartface/sf-extension-utils/commit/595295e49babe9a9a420399e9318b8baecced618)] 504 | - ripple effect is given default [[000f735](https://github.com/smartface/sf-extension-utils/commit/000f735bd594eef3f6bd50c16be39e5b85113da8)] 505 | - ripple effect became default [[63f3a07](https://github.com/smartface/sf-extension-utils/commit/63f3a07961d888d02d672684740ee7bf9b0e22d8)] 506 | - Change default for iOS [[a93964f](https://github.com/smartface/sf-extension-utils/commit/a93964fc8e9a8496bc67b26fab7c844ace4ee416)] 507 | - Chande frame to bounds [[d30f5c9](https://github.com/smartface/sf-extension-utils/commit/d30f5c91dd9be4b49279d5c075eb1586501e9ed0)] 508 | - resolve feedbacks [[bf8e1ea](https://github.com/smartface/sf-extension-utils/commit/bf8e1eadbd4418b8848e45e8ed5dbd0f0ada73f6)] 509 | - Revert "ripple options are added to doc" [[fe33446](https://github.com/smartface/sf-extension-utils/commit/fe33446f3af5925e4b546ea5b7bc03eb040ada30)] 510 | - ripple options are added to doc [[cd34fcf](https://github.com/smartface/sf-extension-utils/commit/cd34fcf5a872db85d2798ded60902400923ac72c)] 511 | - ripple effect added to touch as optional [[8ece311](https://github.com/smartface/sf-extension-utils/commit/8ece311fa6eefe517e86746786662b68db673c37)] 512 | - adapted it to promises [[6771944](https://github.com/smartface/sf-extension-utils/commit/6771944f66a51cf7cc029fd880b8166a4126846f)] 513 | - added transport type on android, fixed typos and location changed [[dce1b90](https://github.com/smartface/sf-extension-utils/commit/dce1b908ef07047719ad04ad9339a805984e1bdf)] 514 | - changed type to object [[853b293](https://github.com/smartface/sf-extension-utils/commit/853b293ea0ebb402bc3f86d94c8e4e4d698d5965)] 515 | - changed location as destination [[9cec093](https://github.com/smartface/sf-extension-utils/commit/9cec093cf0ec76026008f7f30124f87e810fafaa)] 516 | - added requirements to doc [[087607c](https://github.com/smartface/sf-extension-utils/commit/087607cc3465959985390c3c626566482b497a72)] 517 | - fixed a typo [[a34cb87](https://github.com/smartface/sf-extension-utils/commit/a34cb87182b5d94aa372dd5cadb84539f3a01487)] 518 | - updated docs [[d680625](https://github.com/smartface/sf-extension-utils/commit/d680625eda254d2773478b1b356dec0964363357)] 519 | - fixed author [[6e50283](https://github.com/smartface/sf-extension-utils/commit/6e50283d0db9ac9a65a8f48accce430e7994e9c6)] 520 | - added yandex navigator and updated docs [[c46b3b1](https://github.com/smartface/sf-extension-utils/commit/c46b3b1d5e1a4450e4b096d43f6d9e8ffe00a06e)] 521 | - Add navigation util [[a8938c8](https://github.com/smartface/sf-extension-utils/commit/a8938c807f888da0bacad10f3d4eb685ec06db65)] 522 | 523 | 524 | 525 | ## 4.6.2 (2018-11-24) 526 | 527 | ### Miscellaneous 528 | 529 | - update v4.6.2 [[449f0e5](https://github.com/smartface/sf-extension-utils/commit/449f0e5dbb114198e424af320f04df95b9866b3b)] 530 | - fix for a case in service-call for a request with missing headers [[ce6e559](https://github.com/smartface/sf-extension-utils/commit/ce6e5599f67454d849a4d64b3f50a15fbb4b9437)] 531 | 532 | 533 | 534 | ## 4.6.1 (2018-11-17) 535 | 536 | ### Miscellaneous 537 | 538 | - updating v4.6.1 [[46767eb](https://github.com/smartface/sf-extension-utils/commit/46767ebc5e5a2f8e83254ffaac7ee46ddb55aab6)] 539 | - fixing some cases for alert function [[31e02ff](https://github.com/smartface/sf-extension-utils/commit/31e02ff9f939e3fb7a07515321d79dfc002eb71f)] 540 | 541 | 542 | 543 | ## 4.6.0 (2018-11-12) 544 | 545 | ### Miscellaneous 546 | 547 | - added baseUrl property to service-call [[6adc1cc](https://github.com/smartface/sf-extension-utils/commit/6adc1ccaa551653c38831560073c2dd80118dd1b)] 548 | 549 | 550 | 551 | ## 4.5.0 (2018-10-09) 552 | 553 | ### Miscellaneous 554 | 555 | - Merge pull request [#18](https://github.com/smartface/sf-extension-utils/issues/18) from smartface/POLYFILL [[d48043d](https://github.com/smartface/sf-extension-utils/commit/d48043ddef9911914fe8cd872d4a96b241ba2a9e)] 556 | - updated to v4.5.0 [[2597734](https://github.com/smartface/sf-extension-utils/commit/2597734ad2b70eac7d675e368832c7a2185e294d)] 557 | - Add polyfill for Promise.finally [[c7065c9](https://github.com/smartface/sf-extension-utils/commit/c7065c98c665bfb4da1d47486d94dbaf1708b7bb)] 558 | - fix a typo in alert documentation [[6711aad](https://github.com/smartface/sf-extension-utils/commit/6711aaddfb208b305b1b9baf7a71d76f5052a5f0)] 559 | 560 | 561 | 562 | ## 4.4.1 (2018-09-06) 563 | 564 | ### Miscellaneous 565 | 566 | - Merge pull request [#17](https://github.com/smartface/sf-extension-utils/issues/17) from smartface/wvb-ios-cookie [[0fa77c6](https://github.com/smartface/sf-extension-utils/commit/0fa77c64c677fd8539ce8726f8b9b43aba4427fa)] 567 | - updated version to 4.4.1 [[a6b0a6c](https://github.com/smartface/sf-extension-utils/commit/a6b0a6cf426934518bbaa6bd7d99fe7515a12b09)] 568 | - Fixed iOS not handling cookies properly [[14a84b2](https://github.com/smartface/sf-extension-utils/commit/14a84b2b9878afd2f573997f9b8d8b1c99f67275)] 569 | - Improved readability and done requested changes [[5fbea2b](https://github.com/smartface/sf-extension-utils/commit/5fbea2b45db0830ca020bea1ecb4e320ad69e650)] 570 | 571 | 572 | 573 | ## 4.4.0 (2018-08-31) 574 | 575 | ### Miscellaneous 576 | 577 | - Merge pull request [#16](https://github.com/smartface/sf-extension-utils/issues/16) from smartface/touchPatch [[b0acb4a](https://github.com/smartface/sf-extension-utils/commit/b0acb4a015b7d5e66520e6f4ee10acfa0df4323d)] 578 | - v4.4.0 [[3c6edae](https://github.com/smartface/sf-extension-utils/commit/3c6edaecae0db4c28b018c9f1c602749da0e8146)] 579 | - implemented handleTouch function and updated docs [[b75cc62](https://github.com/smartface/sf-extension-utils/commit/b75cc628593559292558ba3fe573f491eb317c1b)] 580 | - fix a typo in webviewbridge [[7162fe5](https://github.com/smartface/sf-extension-utils/commit/7162fe54f92f8e69f2d4759196421a6c563e388a)] 581 | 582 | 583 | 584 | ## 4.3.0 (2018-08-19) 585 | 586 | ### Miscellaneous 587 | 588 | - updated to 4.3.0 [[620e280](https://github.com/smartface/sf-extension-utils/commit/620e280809949f45d71fd6d15ffb978d232c66bc)] 589 | - Merge branch 'master' into async [[f4da131](https://github.com/smartface/sf-extension-utils/commit/f4da1311853827868dbc0005d1e58dde9a0539c0)] 590 | - service-call uses async [[cf89b08](https://github.com/smartface/sf-extension-utils/commit/cf89b083f0ffb3e02373f81b6bbc0e6d465a0759)] 591 | 592 | 593 | 594 | ## 4.2.0 (2018-08-19) 595 | 596 | ### Miscellaneous 597 | 598 | - updated version [[66281e3](https://github.com/smartface/sf-extension-utils/commit/66281e3e09444e794ecf5520ca40d37c9418feb9)] 599 | - added extendEvent [[9fe8ad1](https://github.com/smartface/sf-extension-utils/commit/9fe8ad17df7703d29c380dc6fd5bd69e8987717c)] 600 | - fix in serviceCall lib [[23a61cd](https://github.com/smartface/sf-extension-utils/commit/23a61cdd9616c9f8083af3db7ac87932b6252b55)] 601 | - fixed ~ sign in asnyc docs [[fd53ae2](https://github.com/smartface/sf-extension-utils/commit/fd53ae299483002115fe443c1386ee7711eb8ac2)] 602 | - fixed require values in async docs [[b41b6f6](https://github.com/smartface/sf-extension-utils/commit/b41b6f6f7583788d013795928445e607e9bdc29c)] 603 | - updated async doc [[57f30f9](https://github.com/smartface/sf-extension-utils/commit/57f30f9dd20f28cc44a087f53ea0a7648bc0f4c8)] 604 | - updated async docs [[b51dbe2](https://github.com/smartface/sf-extension-utils/commit/b51dbe23470f2e34ecad35ecca6a85691276529c)] 605 | - async module added [[aceaa3d](https://github.com/smartface/sf-extension-utils/commit/aceaa3d6af9fec9b0b89b61fdfd1b657bee19fa5)] 606 | 607 | 608 | 609 | ## 4.1.1 (2018-08-15) 610 | 611 | ### Miscellaneous 612 | 613 | - updated v4.1.1 [[009748c](https://github.com/smartface/sf-extension-utils/commit/009748c4252e116179950fe07bfb56e226ece155)] 614 | - fixed alpha value with touch [[7842ff5](https://github.com/smartface/sf-extension-utils/commit/7842ff55280d07d3429124eb9c13aef24156e7f7)] 615 | 616 | 617 | 618 | ## 4.1.0 (2018-08-15) 619 | 620 | ### Miscellaneous 621 | 622 | - updated version 4.1.0 [[2b546af](https://github.com/smartface/sf-extension-utils/commit/2b546af74d49be3ab80762c7026a0323412afb31)] 623 | - fixed touch effect color setting with alpha and added caching [[6d46c70](https://github.com/smartface/sf-extension-utils/commit/6d46c70353246a0d51e93bb2f695d0257e2d19b2)] 624 | - default touch effect functions made public [[63b3551](https://github.com/smartface/sf-extension-utils/commit/63b35511f891d2c58e6c071638bd45752155ac88)] 625 | - fixed commid docs [[8c4acc6](https://github.com/smartface/sf-extension-utils/commit/8c4acc6803d7275d263bf8ab1abb2a94aa835716)] 626 | - fixed color doc [[a38761a](https://github.com/smartface/sf-extension-utils/commit/a38761a00afbed80f11eab3ef7b605072d994623)] 627 | - fix in README sample code [[e90d19d](https://github.com/smartface/sf-extension-utils/commit/e90d19d4e5c96aabbe20cf780a0c37ae9b157776)] 628 | - fix in README sample code [[34469b9](https://github.com/smartface/sf-extension-utils/commit/34469b9b2a990a3e1d1aefe3b4dac775728dbe42)] 629 | - updated README for v4 [[5123a90](https://github.com/smartface/sf-extension-utils/commit/5123a90559ae89bd2f44d012b99c7d22e3176597)] 630 | 631 | 632 | 633 | ## 4.0.0 (2018-07-31) 634 | 635 | ### Miscellaneous 636 | 637 | - fixed typo in docs [[04d06de](https://github.com/smartface/sf-extension-utils/commit/04d06de9533e5fa7559b70ad136a97d9b3fb4c0a)] 638 | - Merge branch 'master' of github.com:smartface/sf-extension-utils [[ef4b585](https://github.com/smartface/sf-extension-utils/commit/ef4b58589b4b96a4a4dd9421a6be23ade01ba647)] 639 | - fixed documentation paths [[46db876](https://github.com/smartface/sf-extension-utils/commit/46db8765a92dcff56be0e37883c76f46efe08784)] 640 | - v4 initial version [[a58b94b](https://github.com/smartface/sf-extension-utils/commit/a58b94b6b6658e858fa2c1170de00dc20e425621)] 641 | - Update location.md [[8008ec8](https://github.com/smartface/sf-extension-utils/commit/8008ec891351208c6fb15e9984441bd166f81ae2)] 642 | - added update credentials method to fingerprint lib [[081ff2c](https://github.com/smartface/sf-extension-utils/commit/081ff2c0ea8f2f79cd9047f94d928185c2690915)] 643 | - fix for webviewbridge documentation [[e346179](https://github.com/smartface/sf-extension-utils/commit/e346179a634d09544ea5bb84e59dca6118e2b091)] 644 | - fix for baseURL casing [[500e0a9](https://github.com/smartface/sf-extension-utils/commit/500e0a9df0f4b750aac355539ac49ac903ef996d)] 645 | - fix for changedURL event handling [[9b1fbf4](https://github.com/smartface/sf-extension-utils/commit/9b1fbf441c32617deeb901344c405f7ee08cac5f)] 646 | - wvb now handling return value of the events [[af3c93b](https://github.com/smartface/sf-extension-utils/commit/af3c93bddf231a134992c41147b1c824f75dfbed)] 647 | - updated wvb & fixed customNavigate [[888a451](https://github.com/smartface/sf-extension-utils/commit/888a45144d593c02001750b9979dad96f2a091d6)] 648 | - updated wvb doc [[9e589eb](https://github.com/smartface/sf-extension-utils/commit/9e589eb543a18c090e34cb242196625ef1a573af)] 649 | - added custom navigate feature for webview [[e812e8d](https://github.com/smartface/sf-extension-utils/commit/e812e8daddfb765f790198936dc8641a95cc8168)] 650 | - RAU incompatible update asks before opening the url [[9cb8035](https://github.com/smartface/sf-extension-utils/commit/9cb80356b103edbf01b67135b0ec30e875bb489c)] 651 | - updated rau doc [[74e7d71](https://github.com/smartface/sf-extension-utils/commit/74e7d71bfc90f9f1899022afd04768afdef222f2)] 652 | - fixed jsdoc tags in rau [[d6de37f](https://github.com/smartface/sf-extension-utils/commit/d6de37ff13b313b55fa4df1765af958635f4af16)] 653 | - updated documentation generation [[2978c97](https://github.com/smartface/sf-extension-utils/commit/2978c97ee7c360e01f744630aee1d5c65c4232e1)] 654 | - added onBeforeRestart event to RAU [[ac91d49](https://github.com/smartface/sf-extension-utils/commit/ac91d493768c2ecafb5b462835c3b8dcdf0c5c77)] 655 | - Merge pull request [#10](https://github.com/smartface/sf-extension-utils/issues/10) from muhammedyalcin/master [[0331e3d](https://github.com/smartface/sf-extension-utils/commit/0331e3dddc9fda7fcfd702ad89c1d37ba18ccf67)] 656 | - updated @smartface/native version [[588b2a1](https://github.com/smartface/sf-extension-utils/commit/588b2a1796a095f4a0a766389e237b822f3e606c)] 657 | - if the READ_PHONE_STATE permission is not granted, it continues to check [[5b65877](https://github.com/smartface/sf-extension-utils/commit/5b658771d8e392db6680287f1c3462ca05f94832)] 658 | - backward compatiblity for @smartface/native version while getting location [[71bb18f](https://github.com/smartface/sf-extension-utils/commit/71bb18f4a148d8ae1b56003f7c9e7b5fc4009a2b)] 659 | - location and speechtotest issues fixed [[2b47f7b](https://github.com/smartface/sf-extension-utils/commit/2b47f7b41ccb6e3c9a7042d319ce57a0edb4afbd)] 660 | - Rau checkupdate needs permission check otherwise crashes [[4dec602](https://github.com/smartface/sf-extension-utils/commit/4dec602f9099bf4c499e5bbabad6cad5811e6141)] 661 | - Merge pull request [#9](https://github.com/smartface/sf-extension-utils/issues/9) from THaliloglu/rauChanges [[7cbfd3b](https://github.com/smartface/sf-extension-utils/commit/7cbfd3bc0263869a30a4b9a4a088849cdd4370d4)] 662 | - added RAU user documentation & new release [[5ef1e6e](https://github.com/smartface/sf-extension-utils/commit/5ef1e6ea7246e51fbb68c09994b67fab965edff4)] 663 | - new property is added. [[de0b98d](https://github.com/smartface/sf-extension-utils/commit/de0b98d355637f76567a57584682f55a6cb7fc60)] 664 | - Updated license value in package.json [[cfaf12e](https://github.com/smartface/sf-extension-utils/commit/cfaf12e929646e4c44ac03613a0cca86ca9f3627)] 665 | - updated readme [[05c3b7e](https://github.com/smartface/sf-extension-utils/commit/05c3b7e94834ecc25675efaa904cb5c964166003)] 666 | - added example to touch [[b573b4f](https://github.com/smartface/sf-extension-utils/commit/b573b4f340c1165c6cd2c00b0f7225e9203c93a2)] 667 | - added textbox util doc [[194669f](https://github.com/smartface/sf-extension-utils/commit/194669fba434812603e8b498d089aac8b05dec18)] 668 | - fixed textbox.js [[e1a97db](https://github.com/smartface/sf-extension-utils/commit/e1a97dbce7e16dfdbf45811a4deb67a7dbf0e571)] 669 | - exposed setMaxtLenth [[c403bc5](https://github.com/smartface/sf-extension-utils/commit/c403bc5f83bcabbf057a4f3dd1392c77355c91ce)] 670 | - added textbox.js [[44bdec1](https://github.com/smartface/sf-extension-utils/commit/44bdec1340dfcff91a12930b6c922a0c6b953a2e)] 671 | - increased version [[fe71696](https://github.com/smartface/sf-extension-utils/commit/fe716960fcfe1b2723a3bed0ae1d0779ffdd5758)] 672 | - fix for color function return values doc [[baf44ce](https://github.com/smartface/sf-extension-utils/commit/baf44ce3c96bfac1d388e76c5980c2807208e3f7)] 673 | - fix for tinycolor return value doc [[8cef3ea](https://github.com/smartface/sf-extension-utils/commit/8cef3eaac40ee9bd341f38789a3aff8cadd62c3d)] 674 | - added & updated docs [[5d09b29](https://github.com/smartface/sf-extension-utils/commit/5d09b292c5ae6d7f80c8df6ed0702a0cf5555e56)] 675 | - fixed android touch handling [[40c920d](https://github.com/smartface/sf-extension-utils/commit/40c920d15fdcef880dbc36026a3870e9a7360081)] 676 | - fixed the need for color object in jsdocs [[9441086](https://github.com/smartface/sf-extension-utils/commit/9441086b85a947c419360d02f746bb1cb60cf0e6)] 677 | - minor fixes in touch lib [[370cb34](https://github.com/smartface/sf-extension-utils/commit/370cb349c77fbdc1b7213fe5c8b7367084fb2423)] 678 | - changed how the color interacts with tinycolor [[5b346dd](https://github.com/smartface/sf-extension-utils/commit/5b346dd0d94049f0818b411d0622244de3fd44c5)] 679 | - fixed # requirement for color in touch lib [[53da6c4](https://github.com/smartface/sf-extension-utils/commit/53da6c484900ac24c3bd48002accaaeb35f8a6ba)] 680 | - fixed # requirement for color in touch lib [[8977f3c](https://github.com/smartface/sf-extension-utils/commit/8977f3c4a3e589735cce20310d10f7224846d487)] 681 | - updated color lib functions [[57d7767](https://github.com/smartface/sf-extension-utils/commit/57d776784065189101d68e66acaf4e69b8e163aa)] 682 | - added color & touch libs [[47dcfd4](https://github.com/smartface/sf-extension-utils/commit/47dcfd4e66abc8cc5a081f4ec3c9652cc88dd47b)] 683 | - hotfix for webviewbridge [[0541453](https://github.com/smartface/sf-extension-utils/commit/054145397a32327f6cebe480c7feab5d40b01654)] 684 | - added delay to webview bridge [[a1d6964](https://github.com/smartface/sf-extension-utils/commit/a1d6964326cd976121e9c0cf9b71ddfc12d8db4e)] 685 | - added webview bridge events [[3171a17](https://github.com/smartface/sf-extension-utils/commit/3171a17b1f885b2a85211774d2a3b85e9ae991ac)] 686 | - fix for extra logging in webview bridge [[9ad1269](https://github.com/smartface/sf-extension-utils/commit/9ad1269aba43980c73a4c07f607d1eff1be1da5a)] 687 | 688 | 689 | 690 | ## 3.5.0 (2018-03-26) 691 | 692 | ### Miscellaneous 693 | 694 | - v3.5.0 with WebViewBridge [[cdedec2](https://github.com/smartface/sf-extension-utils/commit/cdedec2d1582b8420fa6de31d9b55b2a3b0a380b)] 695 | - fixed method docs ofr wvb [[7012a1d](https://github.com/smartface/sf-extension-utils/commit/7012a1d39e034a636356240548aa3ccea49e4ee6)] 696 | - fix for wvb doc for scheme [[3621ed3](https://github.com/smartface/sf-extension-utils/commit/3621ed395e835cdd874a7e13c3cf3e4ed3d02f50)] 697 | - fix for webviewbridge constructor parameters [[6c3d8c1](https://github.com/smartface/sf-extension-utils/commit/6c3d8c1772910b9a5fc5879b2a8c608d5e3dd76e)] 698 | - update of the webviewbridge doc [[080ca74](https://github.com/smartface/sf-extension-utils/commit/080ca7498fda4791272ef11c743cbb562b9116ff)] 699 | - updated docs for webViewBridge [[bd9fe73](https://github.com/smartface/sf-extension-utils/commit/bd9fe73dd4aa568182a7ecc9f348aaceee5b97fe)] 700 | - fixed WebView bridge [[9aafbe2](https://github.com/smartface/sf-extension-utils/commit/9aafbe269d7647d25500dc1ae4c3f8067fceebb3)] 701 | - updated webviewBridge with latest master [[9c82ac0](https://github.com/smartface/sf-extension-utils/commit/9c82ac09e443f646ede3d59d44ee4cb0b36e9c9e)] 702 | - fixes for webviewbridge [[e4e8b4c](https://github.com/smartface/sf-extension-utils/commit/e4e8b4c51faf68ab9737e87183cdc1ee4ab0d6c0)] 703 | - added missing exports in webviewbridge [[5bb3d18](https://github.com/smartface/sf-extension-utils/commit/5bb3d1898d36ed8895608f899b3ea99e66ab15f2)] 704 | - removed prototype from webviewbridge [[2d5f8d8](https://github.com/smartface/sf-extension-utils/commit/2d5f8d8fae93dd06873a87f714c0aa403b012404)] 705 | - renamed webviewbrdige file name fixed [[1385dca](https://github.com/smartface/sf-extension-utils/commit/1385dca42a1a79bcea29b386ad7cf25f8e33bf2b)] 706 | - added evaluateJS method [[6ad516d](https://github.com/smartface/sf-extension-utils/commit/6ad516d5ccc42b93d5b643316768687a143d3cd8)] 707 | - added webviewbridge [[bac0e3b](https://github.com/smartface/sf-extension-utils/commit/bac0e3b8756eba498705dee50b27d2593e7c8272)] 708 | 709 | 710 | 711 | ## 3.4.0 (2018-03-25) 712 | 713 | ### Miscellaneous 714 | 715 | - updated version 3.4.0 [[cbaed77](https://github.com/smartface/sf-extension-utils/commit/cbaed77b2f53e037fd0a0bc457bb3ac1cb16d90d)] 716 | - added button activity [[faa542e](https://github.com/smartface/sf-extension-utils/commit/faa542ea5b63f0cfcd69123f54d3ff6fcc2aea69)] 717 | - update readme file [[d9b1ffd](https://github.com/smartface/sf-extension-utils/commit/d9b1ffd061b21de98f5adacba23e1a44353cf41f)] 718 | 719 | 720 | 721 | ## 3.3.0 (2018-03-23) 722 | 723 | ### Miscellaneous 724 | 725 | - service-call link added [[268745b](https://github.com/smartface/sf-extension-utils/commit/268745b56e8f7e572487570b8b24a6d6c8dd143c)] 726 | - v3.3.0 to be used [[9e4eb16](https://github.com/smartface/sf-extension-utils/commit/9e4eb1623e8642ff75a4f2de94718b3d25be8eec)] 727 | - created service-call doc [[b21730d](https://github.com/smartface/sf-extension-utils/commit/b21730d9568351fd9aeeba9ec2a2739c03c5987f)] 728 | - updated doc files [[940d187](https://github.com/smartface/sf-extension-utils/commit/940d187c4c7a1ac992a86f7e982dfb957b67830b)] 729 | - updated copyright year values [[4f67d93](https://github.com/smartface/sf-extension-utils/commit/4f67d938b4b41187989886652cdcc77fb5bedc95)] 730 | - fixes for service call [[12fe059](https://github.com/smartface/sf-extension-utils/commit/12fe059ca4261f719300542f827361b79d9bce44)] 731 | - fixed copy lib call in service-call [[8b7a796](https://github.com/smartface/sf-extension-utils/commit/8b7a79635fc4422afe2a1595493000cd04fc8c1e)] 732 | - added service call files [[a7f2956](https://github.com/smartface/sf-extension-utils/commit/a7f2956edabb7ff9214f24ece5559087d41d7640)] 733 | - Merge pull request [#7](https://github.com/smartface/sf-extension-utils/issues/7) from muhammedyalcin/master [[5381ebb](https://github.com/smartface/sf-extension-utils/commit/5381ebbc1a127021e79d40c7750ddf19fec6cea6)] 734 | - Fixes [[52bde55](https://github.com/smartface/sf-extension-utils/commit/52bde5519e41ddbd27a09d93e548aa0ec77c0b00)] 735 | - Fixes [[daa2df7](https://github.com/smartface/sf-extension-utils/commit/daa2df7f97f565e6ef9adf0d6c73dfb9d56f4e5a)] 736 | - Fixes [[fe5ab8c](https://github.com/smartface/sf-extension-utils/commit/fe5ab8c828aefa0f7ebb7ad9dd0edfe83b0ca7a3)] 737 | - Fixes [[fbb749f](https://github.com/smartface/sf-extension-utils/commit/fbb749f9b320abc1cf3891d25fe6c8d77ddd4993)] 738 | - FaceID text are added [[59ae9ef](https://github.com/smartface/sf-extension-utils/commit/59ae9efa77260b0d48405ed28415aea5f268230a)] 739 | - fixed clearTimeout & clearInterval [[0d1de10](https://github.com/smartface/sf-extension-utils/commit/0d1de1013c779fb315840a7327c5ccf0325914c0)] 740 | - Merge pull request [#3](https://github.com/smartface/sf-extension-utils/issues/3) from THaliloglu/rauVersionCheck [[70816c3](https://github.com/smartface/sf-extension-utils/commit/70816c3bfb4c2c0d787da2e769e074005023de6a)] 741 | - version update [[e7aa397](https://github.com/smartface/sf-extension-utils/commit/e7aa397eddb1f1937105c28f2408d10b9b333f14)] 742 | - fix for alert was not returning an alertview [[67bdbe0](https://github.com/smartface/sf-extension-utils/commit/67bdbe03a484c14168ebc11993d06514305a6c40)] 743 | - Merge pull request [#4](https://github.com/smartface/sf-extension-utils/issues/4) from THaliloglu/statusBarFix [[2e68011](https://github.com/smartface/sf-extension-utils/commit/2e680111333fe68d074bc2f2311f7630f21c2e93)] 744 | - Something wrong with changed global.alert object. I didnt try this fix for Android side but it will fix iOS status bar problem. [[11a8e7d](https://github.com/smartface/sf-extension-utils/commit/11a8e7ded303984a24032abf0d3ed228741a3949)] 745 | - This change is added for [COR-1556] issue of Smartface JIRA. [[31557ab](https://github.com/smartface/sf-extension-utils/commit/31557ab20f14c5bf249ab7365d81a965b78b8bc5)] 746 | - c9 folder ignored [[17bd14a](https://github.com/smartface/sf-extension-utils/commit/17bd14adb0ff67f23b2104d44c080987154294a0)] 747 | - updated docs [[4108a1b](https://github.com/smartface/sf-extension-utils/commit/4108a1bfb4d0650155bcbd3e2e224015e9bfef3b)] 748 | - added event setup for fingerprint [[5d3439a](https://github.com/smartface/sf-extension-utils/commit/5d3439a3d482ac607a0672bfb195a2f09271bdd7)] 749 | - fix typoo for orientation lib [[c2a71d6](https://github.com/smartface/sf-extension-utils/commit/c2a71d695095bc17c87fcfc25bb3f2eb287eb090)] 750 | - added orientation to the list [[f97349b](https://github.com/smartface/sf-extension-utils/commit/f97349b042dbb32b32951707e385677034fbf3ac)] 751 | - fix for inline docs of orientation [[c724ae3](https://github.com/smartface/sf-extension-utils/commit/c724ae3c203bf6ef76cdec4b2bf0cc0a669d95a1)] 752 | - fix for readme to add orientation api link [[11c2a25](https://github.com/smartface/sf-extension-utils/commit/11c2a2571a17e13931d4349dfbf9e66d56871802)] 753 | - Merge branch 'master' of github.com:smartface/sf-extension-utils [[3c7ed85](https://github.com/smartface/sf-extension-utils/commit/3c7ed853552847eff640d18ad585c1969519074a)] 754 | - added orientation lib [[f519cbe](https://github.com/smartface/sf-extension-utils/commit/f519cbeaafa6c10eb9aad9981228a956560e25c4)] 755 | - restored version [[f1fdb64](https://github.com/smartface/sf-extension-utils/commit/f1fdb64dd962e8af98fa5a5343b2ae07071d0c0d)] 756 | - updated version [[50d4c73](https://github.com/smartface/sf-extension-utils/commit/50d4c73baac193509d582819a931dddbb491c85d)] 757 | - fix a parenthesis in rau lib [[45db4b2](https://github.com/smartface/sf-extension-utils/commit/45db4b246dbf16a753ee6306f594948b8b598894)] 758 | - fix for fingerprint login when not prefered [[1dd0418](https://github.com/smartface/sf-extension-utils/commit/1dd04182fbb4283a673e39bfaacbc24007cce527)] 759 | - use fingerpring no case fixed [[851998a](https://github.com/smartface/sf-extension-utils/commit/851998a87b0ba9803cd67ab33c5ef9ad4cdf2951)] 760 | - fix for rau update [[e047056](https://github.com/smartface/sf-extension-utils/commit/e04705651e0108d2371fb142a77e05ab9e6b36be)] 761 | - fix for regular login [[87527ef](https://github.com/smartface/sf-extension-utils/commit/87527efe9a4273582b4311ff86feb83e8cfb02e2)] 762 | - fix for fingerprint update credentials flow [[eea62e0](https://github.com/smartface/sf-extension-utils/commit/eea62e051a370b62134d6f1ab00b7b55a3966369)] 763 | - fix for configuration error [[4c6eb65](https://github.com/smartface/sf-extension-utils/commit/4c6eb651cdb3a8faad173865d5cc7fc17948d50a)] 764 | - fix for invalid check for autoLogin [[36a4348](https://github.com/smartface/sf-extension-utils/commit/36a4348502aaa6da1761fcf3209a71de95feedd4)] 765 | - fixed documentation regarding fingerprint lib update [[ee0d492](https://github.com/smartface/sf-extension-utils/commit/ee0d492d567a2af62dfd0c6caf3162c6ae58c55c)] 766 | - added semicolon [[2003bb2](https://github.com/smartface/sf-extension-utils/commit/2003bb277b245213f1f525c7daca7c6702a44317)] 767 | - Merge branch 'master' of github.com:smartface/sf-extension-utils [[90af73a](https://github.com/smartface/sf-extension-utils/commit/90af73a498994b685c8497dffbee1f9b4a325f4c)] 768 | - updated fingerprint lib for autoLogin, makes it incompatible [[f4f8277](https://github.com/smartface/sf-extension-utils/commit/f4f82779601e335e3d1ebd81a44896edf17544b6)] 769 | - [COR-1511] [SUPDEV-473] Fixed black background [[f215ce8](https://github.com/smartface/sf-extension-utils/commit/f215ce804b01a8c76806e628fc1c831d5c01bfc5)] 770 | 771 | 772 | 773 | ## 2.0.0 (2017-08-15) 774 | 775 | ### Miscellaneous 776 | 777 | - fix for non fingerprint supporting devices [[5e86fd8](https://github.com/smartface/sf-extension-utils/commit/5e86fd8ddae5997e305610b65e238a3a1494de39)] 778 | - fix for optional stop callback for speech recognizer [[f3780a7](https://github.com/smartface/sf-extension-utils/commit/f3780a7a4042871cd956aa3d020e555179d3319b)] 779 | - added stop option for speech recognizer [[8f081c5](https://github.com/smartface/sf-extension-utils/commit/8f081c576e3b31c55cfe2a6f68d88b2414b7085c)] 780 | - added stop option for speech recognizer [[f0b039a](https://github.com/smartface/sf-extension-utils/commit/f0b039ac49bbc5b47ac01b9068a711bde984133e)] 781 | - fix for type check in permissions [[e743988](https://github.com/smartface/sf-extension-utils/commit/e743988482fcfce7cc82b18db87663dbbcdce7cf)] 782 | - Update permission.js [[5b782df](https://github.com/smartface/sf-extension-utils/commit/5b782df600550429c12654a055979f2b20603f5e)] 783 | - added assetions [[d930e73](https://github.com/smartface/sf-extension-utils/commit/d930e73886ae6b8afec7c891c0b8d405b13fea9d)] 784 | - minor localization fix [[285029c](https://github.com/smartface/sf-extension-utils/commit/285029ca8bcdf938b76c736789823cb953cb937a)] 785 | - fixed a typo in readme.md [[7438533](https://github.com/smartface/sf-extension-utils/commit/7438533076ff8f1d5904fbaa120069d772cdcea9)] 786 | - fix for fingerprint [[6472264](https://github.com/smartface/sf-extension-utils/commit/647226487262936e92e7a82f952d72e1463d2433)] 787 | - naming change for useFingerprintLogin [[d4dcf2d](https://github.com/smartface/sf-extension-utils/commit/d4dcf2dd42e92bdcae207fb314e46a78a53c2015)] 788 | - fix path of speachtotext [[7222b8c](https://github.com/smartface/sf-extension-utils/commit/7222b8ccc496e5834de101816dc726f019d9263b)] 789 | - Merge branch 'v2' of github.com:smartface/sf-extension-utils into v2 [[4029a6f](https://github.com/smartface/sf-extension-utils/commit/4029a6ffbcc925d4613f1de0e092031a0fbf7fd2)] 790 | - fixing initial errors [[3019ad5](https://github.com/smartface/sf-extension-utils/commit/3019ad571c4d55f9ccf1b93a940736a484a37f1b)] 791 | - v2 first release [[b46586a](https://github.com/smartface/sf-extension-utils/commit/b46586a65f3f05d09f6d236b6b224cb881350904)] 792 | - added api.md file [[1da2bbe](https://github.com/smartface/sf-extension-utils/commit/1da2bbefef40646ea2d85826effb5755953f501b)] 793 | - Update speech2Text. Make version 1.1.9 [[f7c794e](https://github.com/smartface/sf-extension-utils/commit/f7c794e4a1cf057ef5e95fd75a8ce8ea23ab8b25)] 794 | - Fix speec2text make version 1.1.8 [[ca92166](https://github.com/smartface/sf-extension-utils/commit/ca921667fad69cbe72b19e940333e292d1e7f556)] 795 | - Make version 1.1.7. USE alert and permission lib inside other libs [[60b7e1c](https://github.com/smartface/sf-extension-utils/commit/60b7e1c0381c32f58cda6013bb15d534542afd03)] 796 | - Added permissions. Make version 1.1.6 [[fa4fbb9](https://github.com/smartface/sf-extension-utils/commit/fa4fbb9a8458c159483d34776e46ffa00d3ccbc8)] 797 | - Updated readme [[0416c1a](https://github.com/smartface/sf-extension-utils/commit/0416c1acb6aede38fa194d55b747d99382c69471)] 798 | - Make version 1.1.5 [[e53027d](https://github.com/smartface/sf-extension-utils/commit/e53027d017725f5c4afc9e53e85d22da0dd2602e)] 799 | - Updated rau and rau example [[de384ed](https://github.com/smartface/sf-extension-utils/commit/de384ed4b1ee2f0176062ac62efafc89f33e947c)] 800 | - Write analysis and sample page of speech2text [[ee10ae4](https://github.com/smartface/sf-extension-utils/commit/ee10ae4e50e94c3815a6bf7ebf2ac38b970a72e1)] 801 | - Write analysis of fingerprint util [[2b14610](https://github.com/smartface/sf-extension-utils/commit/2b146108532b2f669567412809a77da47461c6ca)] 802 | - Added alertutil and sample [[d7cf4cb](https://github.com/smartface/sf-extension-utils/commit/d7cf4cb5a3bf8279c1e7c9cd659e797101ca9ae2)] 803 | - Update npm ignore [[9c659c3](https://github.com/smartface/sf-extension-utils/commit/9c659c3c292c0ae79ab18a56dbeff4280405b47b)] 804 | - add speech2text. [[122f632](https://github.com/smartface/sf-extension-utils/commit/122f6325bea0c3808e152320d4b32767e29b1334)] 805 | - Added alert. Make version 1.1.4 [[e806d02](https://github.com/smartface/sf-extension-utils/commit/e806d02898a351349644d1207740c3321152abec)] 806 | - Added alert. Make version 1.1.3 [[ce94189](https://github.com/smartface/sf-extension-utils/commit/ce941892c3309e6a06dbcc8881a0cbc1778e58cf)] 807 | - Added samples make version 1.1.2 [[278ff60](https://github.com/smartface/sf-extension-utils/commit/278ff604d19ef44480edc0172a502a34d9a25a63)] 808 | - Update rau JS make version 1.1.1 [[3a687ce](https://github.com/smartface/sf-extension-utils/commit/3a687ce54b756b041172f9d8bfd63e020b9e11ec)] 809 | - Make version 1.1.0. FIX RAU [[75a64b8](https://github.com/smartface/sf-extension-utils/commit/75a64b8dfffaf19e86ddd6171206a01949d43589)] 810 | - README update [[b1c54bb](https://github.com/smartface/sf-extension-utils/commit/b1c54bbb2fe2c5e1522877821b0f97db7af66c96)] 811 | - Readme, license and code of conduct files updated [[0e9119d](https://github.com/smartface/sf-extension-utils/commit/0e9119d093fcf50ad7c5b6171129a5f082c25f4f)] 812 | - Fix RAU. Make version 1.0.9 [[3fee79f](https://github.com/smartface/sf-extension-utils/commit/3fee79f373278693f5f17268a1ade0a11bf6b6af)] 813 | - Make version 1.0.8 . Fix permission on RAU [[cbcc21b](https://github.com/smartface/sf-extension-utils/commit/cbcc21bd56a9a2132f6082b3b18559f650b4d052)] 814 | - Fixed typo. make version 1.7.0 [[9268b47](https://github.com/smartface/sf-extension-utils/commit/9268b473f0befd236d65b7180995d33caf58a62f)] 815 | - version 1.0.6 [[33b3505](https://github.com/smartface/sf-extension-utils/commit/33b3505f7ee5f3d69dd7399e988daaa2c899d3df)] 816 | - Rau fixed. Updated 1.0.5 [[9063f6e](https://github.com/smartface/sf-extension-utils/commit/9063f6e5b2cbe403acd41187622eb405e3819d8b)] 817 | - Rau fixed. Updated 1.0.4 [[750e722](https://github.com/smartface/sf-extension-utils/commit/750e722b6d1e58440aea2aa075c95950ee616532)] 818 | - Make version 1.0.3 [[aca7df9](https://github.com/smartface/sf-extension-utils/commit/aca7df955600ddc2fba8c030966922053fa1a6af)] 819 | - Removed code from permissions.js [[4ceba9f](https://github.com/smartface/sf-extension-utils/commit/4ceba9faa9de4aab4857b7a138c90d0053ba2eb7)] 820 | - Added dependency permissions.js [[f300be9](https://github.com/smartface/sf-extension-utils/commit/f300be955e3e830a53eee208a137278594785c3c)] 821 | - Updated fingerprint [[ecb7a6a](https://github.com/smartface/sf-extension-utils/commit/ecb7a6aba0f9df8d79a3bd4a5aa5716d02af6022)] 822 | - Make version 1.0.1 [[32e70f1](https://github.com/smartface/sf-extension-utils/commit/32e70f1eaad714ea6d1723fa42d91593769b0af3)] 823 | - Updated rau and fingerprint [[55bd5ac](https://github.com/smartface/sf-extension-utils/commit/55bd5ac38b3ea9cba0b4768b280b0dc9c686eba8)] 824 | - Initial commit [[3254070](https://github.com/smartface/sf-extension-utils/commit/32540700ea7d305b8df1513b88d102a5b31c6e47)] 825 | - Added npm-debug.log to gitignore and npmignore [[348dc6b](https://github.com/smartface/sf-extension-utils/commit/348dc6b8384696be408fa3e72df60bfe07beef35)] 826 | - Updated npmignore [[3405a00](https://github.com/smartface/sf-extension-utils/commit/3405a00d6f64b6cf7c22d2ce54d304247dd69720)] 827 | - Ignored npmrc file on npmignore [[55dfe4e](https://github.com/smartface/sf-extension-utils/commit/55dfe4e804ebc9b77733932789b9344475805dfb)] 828 | - ignored .npmrc [[5a08f3f](https://github.com/smartface/sf-extension-utils/commit/5a08f3f21f6ef7235222af66f0fb78fddc611f60)] 829 | - Ignore files for git and npm added [[033b34b](https://github.com/smartface/sf-extension-utils/commit/033b34b955066809ddaa537858616454ee01614b)] 830 | - Initial commit [[85c494c](https://github.com/smartface/sf-extension-utils/commit/85c494c7829ff5c406a896f70c80469ed5eee86e)] 831 | 832 | 833 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ``` 2 | ____ _ __ _ 3 | / ___| _ __ ___ __ _ _ __| |_ / _| __ _ ___ ___ (_) ___ 4 | \___ \| '_ ` _ \ / _` | '__| __| |_ / _` |/ __/ _ \ | |/ _ \ 5 | ___) | | | | | | (_| | | | |_| _| (_| | (_| __/ _ | | (_) | 6 | |____/|_| |_| |_|\__,_|_| \__|_| \__,_|\___\___| (_) |_|\___/ 7 | ----------------------------------------------------------------- 8 | ``` 9 | 10 | As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 11 | 12 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. 13 | 14 | Examples of unacceptable behavior by participants include: 15 | 16 | * The use of sexualized language or imagery 17 | * Personal attacks 18 | * Trolling or insulting/derogatory comments 19 | * Public or private harassment 20 | * Publishing other's private information, such as physical or electronic addresses, without explicit permission 21 | * Other unethical or unprofessional conduct. 22 | 23 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. 24 | 25 | This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. 26 | 27 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. 28 | 29 | *This Code of Conduct has been adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)*. 30 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to sf-extension-utils 2 | 3 | We would love for you to contribute to sf-extension-utils and help make it even 4 | better than it is today! As a contributor, here are the guidelines we would like 5 | you to follow: 6 | 7 | - [Commit Message Guidelines](#commit) 8 | 9 | ## Commit Message Guidelines 10 | 11 | We have very precise rules over how our git commit messages can be formatted. 12 | This leads to more readable messages that are easy to follow when looking through 13 | the project history. But also, we use the git commit messages to generate the change log. 14 | 15 | We strongly suggest that you use the Angular commit [message](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-guidelines) conventions. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Smartface.io 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | Within the scope of this license, all modifications to the source code, 16 | regardless of the fact that it is used commercially or not, shall be committed 17 | as a contribution back to the repository at https://github.com/smartface/sample-self-service 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Utility Extension from Smartface 2 | 3 | [![NPM](https://img.shields.io/npm/v/@smartface/extension-utils?style=flat-square)](https://www.npmjs.com/package/@smartface/extension-utils) 4 | [![Twitter: @Smartface_io](https://img.shields.io/badge/contact-@Smartface_io-blue.svg?style=flat)](https://twitter.com/smartface_io) 5 | [![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/smartface/sf-extension-utils/master/LICENSE) 6 | 7 | An extension that various utility modules for Smartface Native Framework. You can check the documentation here: https://smartface.github.io/sf-extension-utils/ 8 | 9 | ## Installation 10 | 11 | You add add utils via following command: 12 | 13 | ```shell 14 | yarn add @smartface/extension-utils 15 | ``` 16 | 17 | ## How to use 18 | 19 | Smartface Utility Extension behaves like a normal npm package. You require/import the packages and you can use your Smartface Application on stereoids! 20 | 21 | Later in any file, import it with the path: `import "@smartface/extension-utils/lib/"` Such as: 22 | 23 | - `import "@smartface/extension-utils/lib/color"` 24 | - `import "@smartface/extension-utils/lib/pdf"` 25 | 26 | ### Import their default or normal exports 27 | 28 | Some modules will only have one export, so they will be having default export. Before using any module, read their documentation for more information. 29 | Example of default import: 30 | 31 | - `import Table from "@smartface/extension-utils/lib/table"` 32 | 33 | However, some others will have different export types. You can import them like: 34 | 35 | - `import { createAttributedTexts, createAttributedStrings } from "@smartface/extension-utils/lib/html-to-text"` 36 | 37 | ### API 38 | 39 | For each module api documentation is in separate file. Please visit [Utility API Documentation](https://smartface.github.io/sf-extension-utils/). 40 | 41 | ## Release 42 | 43 | Steps to do before release: 44 | 45 | - Make sure that the version is appropiate to semver guidelines. Use e.g. `yarn version --minor` to change version. 46 | 47 | To publish a new release, create a pull request or push directly to the master with new version. The script will publish it automatically. 48 | 49 | ## Need Help? 50 | 51 | Please [submit an issue](https://github.com/smartface/sf-extension-utils/issues) on GitHub and provide information about your problem. 52 | 53 | ## Support & Documentation & Useful Links 54 | 55 | - [Guides](https://docs.smartface.io/) 56 | - [API Docs](http://ref.smartface.io/) 57 | 58 | ## Code of Conduct 59 | 60 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. 61 | Please read and follow our [Code of Conduct](./CODE_OF_CONDUCT.md). 62 | 63 | ## License 64 | 65 | This project is licensed under the terms of the MIT license. See the [LICENSE](./LICENSE) file. Within the scope of this license, all modifications to the source code, regardless of the fact that it is used commercially or not, shall be committed as a contribution back to this repository. 66 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@smartface/extension-utils", 3 | "version": "17.0.0", 4 | "description": "Utils Extension for Smartface Native Framework", 5 | "main": "lib/index.js", 6 | "repository": "https://github.com/smartface/sf-extension-utils", 7 | "scripts": { 8 | "docs": "rm -rf docs && node typedoc.js", 9 | "watch": "tsc -w", 10 | "build": "tsc", 11 | "test": "mocha" 12 | }, 13 | "keywords": [ 14 | "smartface", 15 | "extension", 16 | "utils", 17 | "javascript" 18 | ], 19 | "author": { 20 | "name": "Smartface", 21 | "email": "info@smartface.io", 22 | "url": "http://smartface.io" 23 | }, 24 | "license": "MIT", 25 | "homepage": "https://github.com/smartface/sf-extension-utils#readme", 26 | "maintainers": [ 27 | "Furkan Arabacı " 28 | ], 29 | "publishConfig": { 30 | "access": "public" 31 | }, 32 | "dependencies": { 33 | "@smartface/webviewbridge": "^5.0.3-beta.2", 34 | "apexcharts": "^3.26.3", 35 | "html-parse-stringify": "1.0.2", 36 | "mixin-deep": "^1.3.1", 37 | "query-string": "^6.10.1", 38 | "semver": "^5.7.1", 39 | "squel": "^5.13.0", 40 | "tinycolor2": "^1.4.1" 41 | }, 42 | "devDependencies": { 43 | "@smartface/contx": "^4.0.0 || ^4.0.0-rc || ^4.0.1-rc", 44 | "@smartface/native": "alpha", 45 | "@smartface/router": "^2.0.0 || ^2.0.0-rc", 46 | "@types/node": "^16.6.1", 47 | "@types/tinycolor2": "^1.4.3", 48 | "@typescript-eslint/eslint-plugin": "^4.14.0", 49 | "@typescript-eslint/parser": "^4.29.2", 50 | "chai": "^4.3.4", 51 | "eslint": "^6.8.0", 52 | "eslint-config-airbnb": "^18.0.1", 53 | "eslint-config-airbnb-base": "^14.0.0", 54 | "eslint-config-prettier": "^6.9.0", 55 | "eslint-plugin-import": "^2.20.0", 56 | "eslint-plugin-jsx-a11y": "^6.2.3", 57 | "eslint-plugin-node": "^11.0.0", 58 | "eslint-plugin-prettier": "^3.1.2", 59 | "eslint-plugin-react": "^7.18.0", 60 | "eslint-plugin-react-hooks": "^1.7.0", 61 | "gh-pages": "^3.2.3", 62 | "install-peers-cli": "^2.2.0", 63 | "jsdoc-to-markdown": "^5.0.0", 64 | "mocha": "^9.1.0", 65 | "prettier": "^1.19.1", 66 | "typedoc": "beta", 67 | "typescript": "^4.3.5" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/art/CircularProgressBar/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module CircularProgressBar 3 | * @type {Object} 4 | * @author Ozcan Ovunc 5 | * @copyright Smartface 2020 6 | */ 7 | 8 | import WebView from "@smartface/native/ui/webview"; 9 | 10 | interface CircularProgressBarOptions { 11 | /** 12 | * Should be an instance of @smartface/native/ui/webview 13 | * @see https://developer.smartface.io/docs/webview 14 | */ 15 | webView: WebView; 16 | /** 17 | * @default 4 18 | * Width of the stroke 19 | */ 20 | strokeWidth?: number; 21 | /** 22 | * @default "#555" 23 | * shorthand hexadecimal color declaration - #000 24 | */ 25 | color?: string; 26 | /** 27 | * @default 2 28 | * Duration for animation in seconds 29 | */ 30 | duration?: number; 31 | /** 32 | * @default "#eee" 33 | * Shorthand hexadecimal - #000 34 | * Color for lighter trail stroke underneath the actual progress path 35 | */ 36 | trailColor?: string; 37 | /** 38 | * @default 4 39 | * Width of the trail stroke in pixels 40 | */ 41 | trailWidth?: number; 42 | /** 43 | * @default 100 44 | * Size of the progress bar (both width & height) 45 | */ 46 | width?: number; 47 | } 48 | 49 | /** 50 | * @class 51 | * @author Ozcan Ovunc 52 | * @copyright Smartface 2020 53 | * @example 54 | * ``` 55 | * import CircularProgressBar from '@smartface/extension-utils/lib/art/CircularProgressBar'; 56 | * 57 | * const circularProgressBar = new CircularProgressBar({ 58 | * width: 130, 59 | * trailColor: "rgb(247,201,71)", 60 | * color: "rgb(55,85,147)", 61 | * webView: this.wvCircularAnimation 62 | * }); 63 | * 64 | * // Triggers the render method whenever the value is set 65 | * circularProgressBar.value = 70; 66 | * ``` 67 | */ 68 | export default class CircularProgressBar { 69 | /** 70 | * Gets/sets current shown progress from 0 to 100 71 | * Re-renders the progress bar when the value is set 72 | */ 73 | private __value = 0; 74 | private __strokeWidth = 4; 75 | private __color = "#555"; 76 | private __duration = 2; 77 | private __trailColor = "#eee"; 78 | private __trailWidth = 4; 79 | private __width = 100; 80 | private __webView: WebView; 81 | constructor(options: CircularProgressBarOptions) { 82 | if (!options.webView) { 83 | throw Error("webView parameter is required"); 84 | } 85 | this.__strokeWidth = options.strokeWidth || this.__strokeWidth; 86 | this.__duration = options.duration || this.__duration; 87 | this.__color = options.color || this.__color; 88 | this.__trailColor = options.trailColor || this.__trailColor; 89 | this.__trailWidth = options.trailWidth || this.__trailWidth; 90 | this.__width = options.width || this.__width; 91 | this.__webView = options.webView; 92 | } 93 | private static __calculateCurrentDashoffset(currentValue: number): number { 94 | const RADIUS = 54; 95 | const CIRCUMFERENCE = 2 * Math.PI * RADIUS; 96 | return CIRCUMFERENCE * (1 - currentValue / 100); 97 | } 98 | 99 | /** 100 | * Current shown progress from 0 to 100. This can be get and set. 101 | * @property {number} value 102 | */ 103 | public get value(): number { 104 | return this.__value; 105 | } 106 | 107 | /** 108 | * Current shown progress from 0 to 100. This can be get and set. 109 | * @property {number} value 110 | */ 111 | public set value(value: number) { 112 | this.__value = value; 113 | this.render(); 114 | } 115 | /** 116 | * Creates proper HTML and triggers loadHTML method of UI.WebView 117 | */ 118 | private render(): void { 119 | let htmlTemplate = ` 120 | 121 | 122 | 123 | 124 | 146 | 147 | 148 | 149 |
150 | 151 | 152 | 154 | 155 |
156 | 157 | 158 | `; 159 | 160 | htmlTemplate = htmlTemplate.replace( 161 | /{__DASHOFFSET__}/g, 162 | String(CircularProgressBar.__calculateCurrentDashoffset(this.__value)) 163 | ); 164 | htmlTemplate = htmlTemplate.replace(/{__DURATION__}/g, String(this.__duration)); 165 | htmlTemplate = htmlTemplate.replace(/{__WIDTH__}/g, String(this.__width)); 166 | htmlTemplate = htmlTemplate.replace( 167 | /{__TRAIL_WIDTH__}/g, 168 | String(this.__trailWidth) 169 | ); 170 | htmlTemplate = htmlTemplate.replace( 171 | /{__TRAIL_COLOR__}/g, 172 | this.__trailColor 173 | ); 174 | htmlTemplate = htmlTemplate.replace(/{__COLOR__}/g, this.__color); 175 | htmlTemplate = htmlTemplate.replace( 176 | /{__STROKE_WIDTH__}/g, 177 | String(this.__strokeWidth) 178 | ); 179 | 180 | this.__webView.loadHTML(htmlTemplate); 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/art/EmojiAnimation/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module EmojiAnimation 3 | * @type {Object} 4 | * @author Ali Tugrul Pinar 5 | * @copyright Smartface 2020 6 | */ 7 | 8 | import WebView from "@smartface/native/ui/webview"; 9 | 10 | const smileyBase64 = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGYAAABmCAYAAAA53+RiAAAAAXNSR0IArs4c6QAADWNJREFUeAHtXXtwVNUZ/87dTQIJS0h4mGAtD8sjwVESHoGpbUdKrSDTsWWqbUf8o7XTjop0qLQFDK4GqCOVmZZx2k7tdCrVqbYqU6WgVZn6GBAIYWxZJnFEIq8UAklIIM/d2993NrvsLvu4u/fc3Utyz8zOvffcc77znd9vz7nn/Qm6Btzmj6vG9wW0GQF/YAaRjp+YDrXH60QeQbpHJ+ERuu7hrOhCdMKvE364Uie8zsG3CXEaNZfWmK8FGtdNa4CfvR10t5/zNs2bSgP9iwIkFpFOt+mkl6nUUpBoIUF7NNLfIXfeO97pB46plK9Clm2IqT0yp0YT+n0B0u8kXZ+kInOGZQjRrJHYGdDFc3Wz6j80HM/CgDklxnt0wWS/3nsvqp4Vuk5cPeXcCUFNqAa3u0TBX7wV+47nSqGcEFN7tHoOSsU61P3fRFWVEx1SAo5/C75Lr5IQm+sqDtWnDK84QFZB8TbOudU/EFgPQu5QnA+LxYnd5HJtrJt58AOLEwqLzwox3qPzp/v1vm34D94eTvlavBH0pkvkr/RW7Ecrz1pnKTFbTywc2dHZsw4f9DUgpcDarGRJuqBeNBS2FHtGbF59w95uq1K1jJgNR6qW6EJ/BoRMsUr5nMoV9KnQxYNPzGrYZYUeyon5vT4n77Qv8CRKyWorFLabTJSerRMrtV/8SNT3q9RNKTEbfVWT+kh/EU3fGpVK2l0Wmtgf5pO459HKhmZVumqqBHmPVi/r1fWG4UYK48d55rwzBqrwVEKM1zf7fr+u74BSJaoUuwbllDAGjIUK3U0Ts8FXvd6v0x/wt3GpUOialgEMGAvGxGw+Mv7G6LouHvNV/xoDjCvNKjEU42OgdNvjlYdWCSEwgpC+y5gYNId/45CSHHAmB83ph5OHiv82o6qMi6pDSnxAI30Zo0yrtbRLTPBDj2+K4wwj4BL0Q2/l4WcNR0DAtIjh5qBsfTkf+nQwBsrC7xLiLm/FodeNRjRMDHceua0OwcO5SWwU13jh2gqEqDLaCTX0jeFhFu7RO6TEw9uwXwljyFgaiWGIGB77Go49eiMAphOGMWQsjcRJWZXJUWLS/2lEmBPGGAJoRi9NNSqdtMTwfIocujeWnhPKIAKMKWObLHhSYniSa8jOpyRDxep3mKOS2CZJJ2FVNjgd/NGQmXlMAkJOXmEmFNPUNyeapk5YYgbn6IfGdHBOkE+RKKbaJcYJgsUtMcHVLP73EsRxvBUi4HK7vuSdUf9+rMi4JSa4xCg2qPNsBQKJsL6qxMjFeIHAQSuUcGQmQEDT5sYuKryqxAidF+Q5LpsIxMM8qsQE1xL3HENLLMo/m0oOy7SwHNclRkyNXCsdVWJ4gbdDSg7+GigIEvuIpN0R9ygmWHUf6aHwvmzEDKr0LKKJIypofMGNNNI1mvK1kdQX6KZu/0U61/sJnerx0dHOPdTS06gw5dSi7KAbYw9NN4a0DVdZXl/1Ar8e2Bt6oeo6bdSttHjCQ1QOYoy6MyDmrbPb6OMua9dw2003l9AWeisP7WOcwitbvvJg+VpMhc4zCl6qcBpELy37OX5ryOMelyp41HsOf0vxUip0ldAnXXtRu6otx3bVDQs3+v79zBk5YBz+xsidXFHwmHtYAkJqSu8xJYTj31H2iCkZ8SLbVbdIDiQxcs+jwu11kwvnmCYlBOiC0u/QpMLq0KPpq5114y2OkgvkMlhisBHVdI4jBMwvuTviyfxtTYm5khepgZ11k3oOciGJkbuDI7U3eX/9yJtMSoiOrlKeSlmspWp5IS6CJQZbtqOhMPdU6B5jTkBMbJXyVMpiNVXLQztHcqHx4QZo9SjdR3+q+78x0Jp7PNV9xJyAiNh21o3VZC6YEzefOEHkj1Dd/O2ulqfp+5OfRSdSHlYhBXYNnKfW3uPE18v+DhrQ+yigD5BLuMmtFSBssWxWj8ufREXu0rAS3f5O2tXyq/Cz2Rs76xbKG3MiNviqfoAF4mmtEgwJSHYtdI2hmZ7bQEAvne72UWvf8WTBo96Nz59KE0dWkFvky5GAy/72qPdmH+ysG+cN/Zn7Qczsp7CsZo3ZzDrx1SGAHWpb8PGXB+aok+pIUoCAmM6tsgkKJDki1CIwQcMo1Ci1Mh1pZhFgTjQMN19pOpmV6MRXggBzghIjHGKUwKlOCHOCI8KcEqMOUjWSmJPgkIwaeY4UhQhofIakQnmOKAUIMCf88XeIUQCmShHMCX/8HWJUoqpAFnOCEiOPwFUgzhGhCgHmhD/+tj+DWFWGryE550AMHxbtOHshoDeBGJHd1XX2QsCm2uBUdT5W3abaDVu1mBONz7oftgjYNOPMCRoARNgyfkb1vL+RPI/FNPKNRTWYYvZT8+UGOteX2yP2x+Z/HvosCOrTDX16s68P2x3AVvPy4KJyGCDAKoDvGgFTRRiXyKPl12+im0Z/LSwO09vU1PWenN+/0H8i7J+NG17ofvt1P6GpRfOjkjty8V/091Prya8rPYc0Ko2rHpgLOEkMW4XAcoysERNLCiuCeW6a4fkywKmhd1v/SO+3/glLRAb4lWWu2F1Gi69bSTePXiLTj01oFv44vGr6pZM/i31l2bO00AHpwRIDUx3Un51/BS+0mOVZnDBjeVgx89UJD8hF5bv/t1WWooSBM3xRnFdOvLqzBstvOb1kjkv126jizvd9liyYunfMBZz8xvBNra/qOK+d5Xsr3dwxy+kbEx81nERrbzPtu/ACNbT/g/r1HsPxYgOi7ibedjGv5Nu4fpE0wX1rY+71M7+k/W0vGQtsJhTMpdRVNkxmEcESgxtpP4X0B9jTSqeJ8M4PQ8mMK5hEy8rXohQ9RE2d79KxS/vp2OUD1NF/JmV8rqomF82lKfh9oWghjc7LbHkDN06y4ZiDUDphYtioDTwtJ4aBzcTx4sFbxtwpfxy/re80tfefpkv+Nro0cIF6sDCQd6nxYsFR7rFUnFdGY1BlqXDNaKFlww1yIJMKV2X8hDVmjWgcWW5g5+7PPRXVIstGpjNNg1tmL2bh44+2T9MTlYfD2+6iKloMN2/PNAPpxHsZTdBGVEt2d76Lb8vmcjb0jMU+ihg2/8Q7ZK1WhPsFz59YRX87uZY6B1qtTi5t+dyxfP6zVfTXk49kpw8DzCX2EZpGVWXsj9bZy2idfSsijKW3BdoouXmWW0vptJSsUIr/JHvO/pbq23fg3xmwIon4MoV4Ba2x5ZEvwx//sCdscmWTmN5AF+1seZIOt7+G/ZY/xba+qrAq2brh7ex7z79AH5z/s6kmecb6MuYx7qoSw+9rj1TBWE1u7IiVj5hJC0u/h8bB17E9Iz9GXbWPxy/V08H2V8h38S25LUStdKPSxO66WQ1LYkPHJcYOx2IVYSs5V2+zxyyj0vwbYvXO+Pli/1n6qGMXqqtX0ZtvzliOqoiJjsWKSwwnWuub/QYqWlsYe+OO4pSieRhHmyev3Ecx6s5j5IBHro9fPiSvbf0njUa1PBxGI97ASHJcC4dXf2MG1WHrdQG97z9oollbnxjIfsdACx3ueE3+ODgfzDAKHckiF36yQ1mK408KcfRJBzqb7dixhk4nfl39rdQduGgghRwEYSN0Ii+hQYaEJYZVfcxXVRfQdeMDWznI37WapCbExscrG2oT6R/Vj4kNxCYF0a/5NNbfeTaJADCV2CYRk5QYtvPIJgWTxHdeZYAAY5rKhmZSYjhNPlGbTQpmkL4TJQ4CjGWqU8o5WkpiOBDbeWSTgnzvuMwRYAwZSyMSDBHDxjfZziMEthkR6oSJi0AbY2jUkKkhYjgZtnvi0rT72EhN3GQdz8QIsGEfYGfUdgwLMkwMB2aLQS7Sf8z3jjOOAGOWjrUllpwWMRyBbW0JoTl9GwbDgGOs0rVPxmKTdjCTpeuYW0yGTvAdhlyya26Rk5XGN5FwavWGZwgmhTHKNPdpV2WhhNgiKtrjDzvVWgiRK1fGJIhNZlZjWVLGVdkVNfDdYSPYJH6HCbb01iZFChkK99z64g99mjYv42VdCTEsWNrIDASew+1wNcfYxk3idFtf8UhhP2XEsDC2lckmBdl6HT8PF8c9eu48ptNPSYWNUmI4MbbzyCYFcYbw6lSJD4X3PPbFwyxGe/RG86ycmFDC0kwjrNdhFnRKyG9IXTF0z6PERgYkM8m3ZcSwMmxSkK3XofSsAUHJl9Vnon0u4vDMI4ktPJ+SaujejHqWEhNSbNBC4Da7rCEI6ZX2VdCbPOWeyBJf2vKSRMgKMaH0g6tv2KJTbpZGhfRI/yp2u9zapnhG3tKXZSxGVokJqcR20Nj8ExZ63IVSlBMdQrokvGLZKhTboQttU6z9sIRxFL7IKShB01u99wKDFdnYZWAENzR9m3iBN68ljjRNZSSuyjA5JSYyI2xYCCVohTTVkYWdbZFpY46pGR/0nQBje8iwTtT7HDzYhpjIvEtTHbAKIQ0Q4Kx71VvdMcDYggp0j9yIij2P3ukHsr9vPDLDce5tSUysnnzWPR+rHvAHsLFHx0+eFT0BJWwUqkEPqh5P6AhJPoQNfp3ww5W6IOss4uC8HBwDghMn+HCDddMabH+w0f8B1Lqzlenn1xcAAAAASUVORK5CYII=`; 11 | 12 | function getCss(emojiBoxWidth: number, emojiWidth: number): string { 13 | return ` 14 | .particle-box { 15 | width: ${emojiBoxWidth}px; 16 | right: 0; 17 | bottom: 0; 18 | top: 0; 19 | position: absolute; 20 | } 21 | 22 | div.particle { 23 | width: ${emojiBoxWidth}px; 24 | height: 80px; 25 | opacity: 1; 26 | position: absolute; 27 | bottom: 0; 28 | right: 0; 29 | display: none; 30 | } 31 | div.particle img { 32 | position: absolute; 33 | width: ${emojiWidth}px; 34 | left: 0px; 35 | right: 0px; 36 | top: 0px; 37 | margin: auto; 38 | opacity: 1; 39 | } 40 | @keyframes flowOne { 41 | 0% { 42 | opacity: 1; 43 | bottom: 0%; 44 | left: 31%; 45 | } 46 | 40% { 47 | opacity: 0.9; 48 | } 49 | 50% { 50 | opacity: 1; 51 | left: 5%; 52 | } 53 | 60% { 54 | opacity: 0.7; 55 | } 56 | 80% { 57 | bottom: 60%; 58 | } 59 | 100% { 60 | opacity: 0; 61 | bottom: 80%; 62 | left: 22%; 63 | } 64 | } 65 | @keyframes flowTwo { 66 | 0% { 67 | opacity: 0.3; 68 | bottom: 0%; 69 | left: 0%; 70 | } 71 | 40% { 72 | opacity: 0.9; 73 | } 74 | 50% { 75 | opacity: 1; 76 | left: 22%; 77 | } 78 | 60% { 79 | opacity: 0.7; 80 | } 81 | 80% { 82 | bottom: 60%; 83 | left: 5%; 84 | } 85 | 100% { 86 | opacity: 0; 87 | bottom: 80%; 88 | left: 0%; 89 | } 90 | } 91 | @keyframes flowThree { 92 | 0% { 93 | opacity: 0.6; 94 | bottom: 0%; 95 | left: 5%; 96 | } 97 | 40% { 98 | opacity: 0.9; 99 | } 100 | 50% { 101 | opacity: 1; 102 | left: 44%; 103 | } 104 | 60% { 105 | opacity: 0.7; 106 | } 107 | 80% { 108 | left: 12%; 109 | bottom: 70%; 110 | } 111 | 100% { 112 | opacity: 0; 113 | bottom: 80%; 114 | left: 0%; 115 | } 116 | } 117 | @keyframes flowFour { 118 | 0% { 119 | opacity: 0.1; 120 | bottom: 0%; 121 | left: 5%; 122 | } 123 | 40% { 124 | opacity: 0.9; 125 | left: 11%; 126 | } 127 | 50% { 128 | opacity: 1; 129 | } 130 | 60% { 131 | opacity: 0.7; 132 | } 133 | 80% { 134 | bottom: 70%; 135 | left: 19%; 136 | } 137 | 100% { 138 | opacity: 0; 139 | bottom: 80%; 140 | left: 0%; 141 | } 142 | } 143 | `; 144 | } 145 | 146 | const jsHeart = ` 147 | window.__smileyBase64 = "${smileyBase64}"; 148 | function animateEmoji(emojiIndex, timing) { 149 | // Init 150 | var rand = Math.floor(Math.random() * 100 + 1); 151 | var flows = ["flowOne", "flowTwo", "flowThree", "flowFour"]; 152 | var colors = ["colOne", "colTwo", "colThree", "colFour", "colFive", "colSix"]; 153 | // Animate Particle 154 | var emoji = window.__emojis[emojiIndex] || window.__smileyBase64; 155 | $( 156 | '
' 163 | ) 164 | .appendTo(".particle-box") 165 | .css({ 166 | animation: 167 | "" + flows[Math.floor(Math.random() * 4)] + " " + timing.toString() + "s linear" 168 | }); 169 | $(".part-" + rand).show(); 170 | // Remove Particle 171 | setTimeout(function() { 172 | $(".part-" + rand).remove(); 173 | }, timing * 1000 - 100); 174 | } 175 | 176 | window.animateEmoji = animateEmoji; 177 | `; 178 | 179 | interface EmojiAnimationOptions { 180 | /** 181 | * Should be an instance of @smartface/native/ui/webview 182 | * @see https://developer.smartface.io/docs/webview 183 | */ 184 | webView: WebView; 185 | /** 186 | * @default [] 187 | * Array of emojis will be played 188 | */ 189 | emojis?: string[]; 190 | /** 191 | * @default 100 192 | * Width of emoji box(px) 193 | */ 194 | emojiBoxWidth?: number; 195 | /** 196 | * @default 80 197 | * Width of emoji(px) 198 | */ 199 | emojiWidth?: number; 200 | /** 201 | * Toggles whether to override the webView.onError and webView.android.onConsoleMessage 202 | * @default false 203 | */ 204 | logEnabled?: boolean; 205 | } 206 | 207 | /** 208 | * @class 209 | * @author Ali Tugrul Pinar 210 | * @copyright Smartface 2020 211 | * @example 212 | * ``` 213 | * import EmojiAnimation from '@smartface/extension-utils/lib/art/EmojiAnimation'; 214 | * 215 | * const emojiAnimation = new EmojiAnimation({ 216 | * emojis: ['data:image/png;base64,eymBASDASd'] 217 | * webView: this.wvEmojiAnimation 218 | * }); 219 | * 220 | * // Play first emoji on WebView with 3 second animation 221 | * emojiAnimation.playEmoji(0, 3); 222 | * ``` 223 | * @example 224 | * EmojiAnimation with an image inside the project 225 | * ``` 226 | * const emojiAnimation = new EmojiAnimation({ 227 | * emojis: [`data:image/png;base64,${Image.createFromFile("images://smartface.png").toBlob().toBase64()}`, 'data:image/png;base64,eymBASDASd'] 228 | * webView: this.wvEmojiAnimation 229 | * }); 230 | * 231 | * // Play two emojis on WebView with 3 second animation 232 | * emojiAnimation.playEmoji(0, 3); 233 | * emojiAnimation.playEmoji(1, 3); 234 | * ``` 235 | * @example 236 | * Or do it with forEach 237 | * ``` 238 | * const emojiAnimation = new EmojiAnimation({ 239 | * emojis: [`data:image/png;base64,${Image.createFromFile("images://smartface.png").toBlob().toBase64()}`, 'data:image/png;base64,eymBASDASd'] 240 | * webView: this.wvEmojiAnimation 241 | * }); 242 | * 243 | * // Play first emoji on WebView with 3 second animation 244 | * // Or use it with forEach. 245 | * emojiAnimation.emojis.forEach((_, index) => emojiAnimation.playEmoji(index, 3)); 246 | * ``` 247 | */ 248 | export default class EmojiAnimation { 249 | private __webView: WebView; 250 | private __emojis: string[] = []; 251 | private __emojiBoxWidth = 100; 252 | private __emojiWidth = 80; 253 | private __logEnabled = false; 254 | constructor(options: EmojiAnimationOptions) { 255 | this.emojis = options.emojis || this.__emojis; // Array of emojis will be played 256 | this.__emojiBoxWidth = options.emojiBoxWidth || this.__emojiBoxWidth; // Width of emoji box(px) 257 | this.__emojiWidth = options.emojiWidth || this.__emojiWidth; // Width of emoji(px) 258 | this.__webView = options.webView; 259 | this.__logEnabled = options.logEnabled || this.__logEnabled; 260 | if (!this.__webView) { 261 | throw new Error("webView parameter is required"); 262 | } 263 | this.initWebView(); 264 | this.loadHTML(); 265 | } 266 | 267 | private initWebView() { 268 | if (this.__logEnabled) { 269 | this.__webView.onError = (e) => console.error(e); 270 | this.__webView.android.onConsoleMessage = (e) => { 271 | console.error("Webview Console: ", e.message, e); 272 | return true; 273 | }; 274 | } 275 | this.__webView.touchEnabled = false; 276 | this.__webView.scrollBarEnabled = false; 277 | this.__webView.onShow = () => {}; 278 | } 279 | 280 | private loadHTML() { 281 | let emojisAsString = "[]"; 282 | try { 283 | emojisAsString = JSON.stringify(this.emojis); 284 | } catch (e) { 285 | /* Handle stringify error and behave like nothing has happened */ 286 | } 287 | this.__webView.loadHTML(` 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 |
297 | 298 | 299 | `); 300 | } 301 | /** 302 | * Play given index that emoji on WebView 303 | */ 304 | playEmoji(emojiIndex: number, timing: number): void { 305 | const script = `window.animateEmoji(${emojiIndex}, ${timing});`; 306 | this.__webView.evaluateJS(script, (e) => {}); 307 | } 308 | /** 309 | * To change emoji values, call the constructor(create new instance) again. 310 | */ 311 | get emojis(): string[] { 312 | return this.__emojis; 313 | } 314 | private set emojis(value: string[]) { 315 | this.__emojis = value; 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /src/biometrics/index.ts: -------------------------------------------------------------------------------- 1 | import Hardware from "@smartface/native/device/hardware"; 2 | import System from "@smartface/native/device/system"; 3 | import Data from "@smartface/native/global/data"; 4 | import AlertView from "@smartface/native/ui/alertview"; 5 | 6 | enum DataVariables { 7 | BIOMETRIC_ENABLED = "UTIL_BIOMETRIC_ENABLED", 8 | BIOMETRIC_ACTIVATION_ASKED = "UTIL_BIOMETRIC_ACTIVATION_ASKED", 9 | } 10 | 11 | const faceIDNotWorkingDevices = ["huawei"]; 12 | 13 | type PromptUsage = { 14 | title: string; 15 | message: string; 16 | positiveActionText: string; 17 | negativeActionText: string; 18 | }; 19 | 20 | type Validate = 21 | | { 22 | promptUsage: true; 23 | checkPromptAsked?: boolean; 24 | title: string; 25 | message: string; 26 | cancelButtonText: string; 27 | promptOpts: PromptUsage; 28 | } 29 | | { 30 | promptUsage: false; 31 | checkPromptAsked?: boolean; 32 | title: string; 33 | message: string; 34 | cancelButtonText: string; 35 | }; 36 | 37 | class Biometrics { 38 | private __biometricEnabled: boolean; 39 | private __biometricPromptAsked: boolean; 40 | private __isBiometricValidationActive = false; 41 | constructor() { 42 | this.__biometricEnabled = !!Data.getBooleanVariable( 43 | DataVariables.BIOMETRIC_ENABLED 44 | ); 45 | 46 | this.__biometricPromptAsked = !!Data.getBooleanVariable( 47 | DataVariables.BIOMETRIC_ACTIVATION_ASKED 48 | ); 49 | } 50 | 51 | get hasSupport(): boolean { 52 | return System.biometricsAvailable; 53 | } 54 | 55 | get enabled(): boolean { 56 | return this.__biometricEnabled; 57 | } 58 | 59 | set enabled(value: boolean) { 60 | this.__biometricEnabled = value; 61 | Data.setBooleanVariable(DataVariables.BIOMETRIC_ENABLED, value); 62 | } 63 | 64 | get promptAsked(): boolean { 65 | return this.__biometricPromptAsked; 66 | } 67 | 68 | set promptAsked(value: boolean) { 69 | this.__biometricPromptAsked = value; 70 | Data.setBooleanVariable(DataVariables.BIOMETRIC_ACTIVATION_ASKED, value); 71 | } 72 | 73 | private promptUsage(opts: PromptUsage) { 74 | const { title, message, negativeActionText, positiveActionText } = opts; 75 | return new Promise((resolve, reject) => { 76 | global.alert({ 77 | title, 78 | message, 79 | buttons: [ 80 | { 81 | text: positiveActionText, 82 | type: AlertView.Android.ButtonType.POSITIVE, 83 | onClick: async () => { 84 | try { 85 | this.enabled = true; 86 | resolve(); 87 | } catch (err) { 88 | this.enabled = false; 89 | resolve(); 90 | } finally { 91 | this.promptAsked = true; 92 | } 93 | }, 94 | }, 95 | { 96 | text: negativeActionText, 97 | type: AlertView.Android.ButtonType.NEGATIVE, 98 | onClick: () => { 99 | this.enabled = false; 100 | this.promptAsked = true; 101 | reject(); 102 | }, 103 | }, 104 | ], 105 | }); 106 | }); 107 | } 108 | 109 | validate(opts: Validate, showAlert = true) { 110 | const { title, message, checkPromptAsked, cancelButtonText } = opts; 111 | return new Promise(async (resolve, reject) => { 112 | if (this.__isBiometricValidationActive) { 113 | return reject({ 114 | ...Error("Biometic prompt is already active"), 115 | deactivatePrompt: true, 116 | }); 117 | } 118 | 119 | if (checkPromptAsked) { 120 | if (!this.__biometricPromptAsked && opts.promptUsage) { 121 | try { 122 | await this.promptUsage(opts.promptOpts); 123 | } catch (err) { 124 | reject(Error("Biometric is disabled")); 125 | } 126 | } 127 | } else { 128 | if (opts.promptUsage) { 129 | try { 130 | await this.promptUsage(opts.promptOpts); 131 | } catch (err) { 132 | reject(Error("Biometric is disabled")); 133 | } 134 | } 135 | } 136 | 137 | this.__isBiometricValidationActive = true; 138 | if (!this.__biometricEnabled) { 139 | return reject(Error("Biometric is disabled")); 140 | } 141 | if (!this.hasSupport) { 142 | if (!showAlert) { 143 | return reject(Error("Won't show use fingerprint alert")); 144 | } 145 | if ( 146 | faceIDNotWorkingDevices.some((device) => 147 | Hardware.brandName.toLowerCase().includes(device.toLowerCase()) 148 | ) 149 | ) { 150 | return reject(`${Hardware.brandName} alert redirection is disabled`); 151 | } 152 | return reject(); 153 | } else { 154 | System.validateBiometric({ 155 | android: { 156 | title, 157 | cancelButtonText, 158 | }, 159 | message, 160 | onSuccess: () => resolve(), 161 | onError: (e, err) => reject(Error("Unable to scan")), 162 | }); 163 | } 164 | }) 165 | .then(() => (this.__isBiometricValidationActive = false)) 166 | .catch((err = Error()) => { 167 | this.__isBiometricValidationActive = !!err.deactivatePrompt; 168 | throw err.message; 169 | }); 170 | } 171 | } 172 | 173 | export default Biometrics; 174 | -------------------------------------------------------------------------------- /src/chart/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module Chart 3 | * @type {Object} 4 | * @author Berk Baski 5 | * @copyright Smartface 2021 6 | */ 7 | 8 | // TODO - Update from path to the new package path 9 | import WebViewBridge from "@smartface/webviewbridge"; 10 | import { ApexOptions } from "apexcharts"; 11 | 12 | /** It allows passing custom data into the chart */ 13 | type BarOptions = { 14 | [key: string]: any; 15 | }; 16 | 17 | interface ChartOptions { 18 | /** Browser to display ApexCharts charts and listen to events */ 19 | webViewBridge?: WebViewBridge; 20 | 21 | /** Required options for render to chart. More info {@link https://github.com/apexcharts/apexcharts.js|ApexCharts.js} */ 22 | apexOptions?: ApexOptions & { barOptions?: BarOptions }; 23 | 24 | /** Optional css options for html */ 25 | customCss?: string; 26 | } 27 | 28 | /** 29 | * It allows creating charts using the ApexCharts. It communicates between the events of the ApexCharts and the Smartface using WebViewBridge 30 | * @example 31 | * ``` 32 | *const wvb = new WebViewBridge({ 33 | * webView: this.webView1 34 | *}); 35 | * 36 | * wvb.on('markerClick', function (event) { 37 | * console.log('Clicked to a marker on Smartface'); 38 | * }); 39 | * 40 | * const chart = new Chart({ 41 | * webViewBridge: wvb, 42 | * apexOptions: { 43 | * barOptions: { 44 | * percent: 0.75 45 | * }, 46 | * series: [{ 47 | * name: "Desktops", 48 | * data: [10, 41, 35, 51, 49, 62, 69, 91, 148] 49 | * }], 50 | * chart: { 51 | * height: 350, 52 | * type: 'line', 53 | * zoom: { 54 | * enabled: false 55 | * }, 56 | * events: { 57 | * markerClick: () => { 58 | * //@ts-ignore 59 | * window.boubleEvent("EVENT_CHART_EVENTS_markerClick"); 60 | * } 61 | * } 62 | * }, 63 | * dataLabels: { 64 | * enabled: false, 65 | * formatter: function (val, opt) { 66 | * return val / opt?.w?.config?.percent; 67 | * } 68 | * }, 69 | * stroke: { 70 | * curve: 'straight' 71 | * }, 72 | * title: { 73 | * text: 'Product Trends by Month', 74 | * align: 'left' 75 | * }, 76 | * grid: { 77 | * row: { 78 | * colors: ['#f3f3f3', 'transparent'], 79 | * opacity: 0.5 80 | * }, 81 | * }, 82 | * xaxis: { 83 | * categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'], 84 | * } 85 | * } 86 | * }); 87 | * chart.render(); 88 | * ``` 89 | */ 90 | export default class Chart implements ChartOptions { 91 | webViewBridge; 92 | apexOptions; 93 | customCss; 94 | constructor(options: ChartOptions) { 95 | if (!options.webViewBridge) { 96 | throw new Error("webViewBridge parameter is required"); 97 | } 98 | this.webViewBridge = options.webViewBridge; 99 | this.apexOptions = options.apexOptions; 100 | this.customCss = options.customCss; 101 | } 102 | 103 | /** 104 | * It converts chart options to string for render to WebView 105 | */ 106 | convertObjectToString(obj: any): string { 107 | if (obj instanceof Array) return JSON.stringify(obj); 108 | if (typeof obj === "string") return `'${obj}'`; 109 | if (typeof obj === "function") return obj.toString(); 110 | if (typeof obj === "object") 111 | return `{${Object.keys(obj) 112 | .map((prop) => `${prop}:${this.convertObjectToString(obj[prop])}`) 113 | .join(",")}}`; 114 | return obj; 115 | } 116 | 117 | /** 118 | * It renders the given chart options to the WebViewBridge browser 119 | */ 120 | render(): void { 121 | const styles = this.customCss ? `` : ""; 122 | const html = ` 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 |
132 | 133 | 138 | ${styles} 139 | 140 | 141 | `; 142 | this.webViewBridge.webView.loadHTML(html); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/color/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Smartface Color Util module 3 | * @module color 4 | * @type {object} 5 | * @author Alper Ozisik 6 | * @copyright Smartface 2018 7 | * @see {@link https://www.npmjs.com/package/tinycolor2|tinycolor2} 8 | * @example 9 | * ``` 10 | * import Color = require('@smartface/native/ui/color'); 11 | * import colorUtil from '@smartface/extension-utils/lib/color'; 12 | * colorUtil.rgb(Color.RED); //#ff0000 13 | * colorUtil.rgb(Color.BLUE).tinycolor.darken().toHexString(); //'#0000cc' 14 | * ``` 15 | */ 16 | import Color from '@smartface/native/ui/color'; 17 | import TinyColor from "tinycolor2"; 18 | 19 | /** 20 | * Returns 6 digit hexadecimal string from Color object. Does not start with # character 21 | */ 22 | export function rgb(color: Color): string { 23 | //@ts-ignore 24 | const r = pad0(Color.red(color).toString(16)); 25 | //@ts-ignore 26 | const g = pad0(Color.green(color).toString(16)); 27 | //@ts-ignore 28 | const b = pad0(Color.blue(color).toString(16)); 29 | return r + g + b; 30 | } 31 | 32 | /** 33 | * Returns 8 digit hexadecimal string from Color object. Does not start with # character 34 | * @public 35 | * @static 36 | * @method 37 | * @params {UI.Color} color - Smartface Color Object, without gradient 38 | * @returns {string} Hexadecimal RGBA representation of the color 39 | */ 40 | export function rgba(color: Color): string { 41 | //@ts-ignore 42 | const a = pad0(Color.alpha(color).toString(16)); 43 | return rgb(color) + a; 44 | } 45 | 46 | /** 47 | * Returns 8 digit hexadecimal string from Color object. Does not start with # character 48 | * @public 49 | * @static 50 | * @method 51 | * @params {UI.Color} color - Smartface Color Object, without gradient 52 | * @returns {string} Hexadecimal ARGB representation of the color 53 | */ 54 | export function argb(color: Color): string { 55 | //@ts-ignore 56 | const a = pad0(Color.alpha(color).toString(16)); 57 | return a + rgb(color); 58 | } 59 | 60 | 61 | /** 62 | * Creates a tinycolor object from UI.Color 63 | * @method 64 | * @public 65 | * @static 66 | * @params {UI.Color} color - Smartface Color Object, without gradient 67 | * @returns {tinycolor} 68 | * @see {@link https://github.com/bgrins/TinyColor|TinyColor} 69 | */ 70 | export function tinycolor(color: Color): InstanceType { 71 | const a = Number(Color.alpha(color)) / 2.55; 72 | const r = Number(Color.red(color)); 73 | const g = Number(Color.green(color)); 74 | const b = Number(Color.blue(color)); 75 | return TinyColor({ a, r, g, b }); 76 | } 77 | 78 | function pad0(value: string): string { 79 | if (value.length < 2) 80 | return "0" + value; 81 | else return value; 82 | } 83 | 84 | export default { 85 | rgb, 86 | rgba, 87 | argb, 88 | tinycolor 89 | } -------------------------------------------------------------------------------- /src/copy/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Smartface Copy helper module 3 | * @module copy 4 | * @type {function} 5 | * @author Alper Ozisik 6 | * @copyright Smartface 2018 7 | */ 8 | 9 | /** 10 | * Creates a deep high-performing copy of a variable 11 | * @public 12 | * @function copy 13 | * @params {*} source 14 | * @params {*} [destination] 15 | * @returns {*} copy of the source 16 | * @example 17 | * ``` 18 | * import copy from '@smartface/extension-utils/lib/copy'; 19 | * const src = {nested: {x: 4}}; //deep nested object 20 | * const cpy = copy(src); 21 | * 22 | * console.log(src === cpy); //false 23 | * console.log(src.nested === cpy.nested); //false 24 | * ``` 25 | * @example 26 | * ``` 27 | * import copy from '@smartface/extension-utils/lib/copy'; 28 | * const src = {nested: {x: 4}}; //deep nested object 29 | * const cpy; 30 | * //targeting 31 | * copy(src, cpy); 32 | * ``` 33 | */ 34 | 35 | export default function(source: any, destination?: any): any { 36 | let stackSource: any = []; 37 | let stackDest: any = []; 38 | 39 | if (destination) { 40 | // Empty the destination object 41 | if (Array.isArray(destination)) { 42 | destination.length = 0; 43 | } 44 | 45 | stackSource.push(source); 46 | stackDest.push(destination); 47 | return copyRecurse(source, destination); 48 | } 49 | 50 | return copyElement(source); 51 | 52 | function copyRecurse(source: any, destination: any) { 53 | var key; 54 | if (Array.isArray(source)) { 55 | for (var i = 0, ii = source.length; i < ii; i++) { 56 | destination.push(copyElement(source[i])); 57 | } 58 | } else if (isBlankObject(source)) { 59 | // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty 60 | for (key in source) { 61 | destination[key] = copyElement(source[key]); 62 | } 63 | } else if (source && typeof source.hasOwnProperty === "function") { 64 | // Slow path, which must rely on hasOwnProperty 65 | for (key in source) { 66 | if (source.hasOwnProperty(key)) { 67 | destination[key] = copyElement(source[key]); 68 | } 69 | } 70 | } else { 71 | // Slowest path --- hasOwnProperty can't be called as a method 72 | for (key in source) { 73 | //@ts-ignore 74 | if (hasOwnProperty.call(source, key)) { 75 | destination[key] = copyElement(source[key]); 76 | } 77 | } 78 | } 79 | // setHashKey(destination, h); 80 | return destination; 81 | } 82 | 83 | function copyElement(source: any): any { 84 | // Simple values 85 | if (!isObject(source)) { 86 | return source; 87 | } 88 | 89 | // Already copied values 90 | var index = stackSource.indexOf(source); 91 | if (index !== -1) { 92 | return stackDest[index]; 93 | } 94 | 95 | // if (isWindow(source) || isScope(source)) { 96 | // throw ngMinErr('cpws', 97 | // 'Can\'t copy! Making copies of Window or Scope instances is not supported.'); 98 | // } 99 | 100 | var needsRecurse = false; 101 | var destination = copyType(source); 102 | 103 | if (destination === undefined) { 104 | destination = Array.isArray(source) 105 | ? [] 106 | : Object.create(getPrototypeOf(source)); 107 | needsRecurse = true; 108 | } 109 | 110 | stackSource.push(source); 111 | stackDest.push(destination); 112 | 113 | return needsRecurse ? copyRecurse(source, destination) : destination; 114 | } 115 | 116 | function copyType(source: any): any { 117 | //@ts-ignore 118 | switch (toString.call(source)) { 119 | case "[object Int8Array]": 120 | case "[object Int16Array]": 121 | case "[object Int32Array]": 122 | case "[object Float32Array]": 123 | case "[object Float64Array]": 124 | case "[object Uint8Array]": 125 | case "[object Uint8ClampedArray]": 126 | case "[object Uint16Array]": 127 | case "[object Uint32Array]": 128 | return new source.constructor( 129 | copyElement(source.buffer), 130 | source.byteOffset, 131 | source.length 132 | ); 133 | 134 | case "[object ArrayBuffer]": 135 | // Support: IE10 136 | if (!source.slice) { 137 | // If we're in this case we know the environment supports ArrayBuffer 138 | /* eslint-disable no-undef */ 139 | var copied = new ArrayBuffer(source.byteLength); 140 | new Uint8Array(copied).set(new Uint8Array(source)); 141 | /* eslint-enable */ 142 | return copied; 143 | } 144 | return source.slice(0); 145 | 146 | case "[object Boolean]": 147 | case "[object Number]": 148 | case "[object String]": 149 | case "[object Date]": 150 | return new source.constructor(source.valueOf()); 151 | 152 | case "[object RegExp]": 153 | var re = new RegExp( 154 | source.source, 155 | source.toString().match(/[^/]*$/)[0] 156 | ); 157 | re.lastIndex = source.lastIndex; 158 | return re; 159 | 160 | case "[object Blob]": 161 | return new source.constructor([source], { 162 | type: source.type, 163 | }); 164 | } 165 | 166 | if (isFunction(source.cloneNode)) { 167 | return source.cloneNode(true); 168 | } 169 | } 170 | } 171 | 172 | function isFunction(value: any): boolean { 173 | return typeof value === "function"; 174 | } 175 | 176 | function isObject(value: any): boolean { 177 | return value !== null && typeof value === "object"; 178 | } 179 | 180 | function getPrototypeOf(value: any): any { 181 | return value.__proto__ || value.constructor.prototype; 182 | } 183 | function isBlankObject(value: any) { 184 | return value !== null && typeof value === "object" && !getPrototypeOf(value); 185 | } 186 | -------------------------------------------------------------------------------- /src/guid/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Smartface guid util 3 | * @module guid 4 | * @type {function} 5 | * @author Alper Ozisik 6 | * @copyright Smartface 2019 7 | */ 8 | 9 | /** 10 | * Creates a UUID v4 string 11 | * @method 12 | * @public 13 | * @returns {string} Random generated uuid v4 string 14 | * @example 15 | * ``` 16 | * import guid from '@smartface/extension-utils/lib/guid'; 17 | * var newItem = { id: guid() }; 18 | * ``` 19 | */ 20 | export default function(): string { 21 | return `${s4()}${s4()}-${s4()}-${s4()}-${s4()}-${s4()}${s4()}${s4()}`; 22 | } 23 | 24 | function s4() { 25 | return Math.floor((1 + Math.random()) * 0x10000) 26 | .toString(16) 27 | .substring(1); 28 | }; -------------------------------------------------------------------------------- /src/html-to-text/index.ts: -------------------------------------------------------------------------------- 1 | //@ts-nocheck 2 | 3 | /** 4 | * Smartface html-to-text util 5 | * @module html-to-text 6 | * @type {Class} 7 | * @author Furkan Arabacı 8 | * @author Ali Tuğrul Pınar 9 | * @copyright Smartface 2021 10 | */ 11 | 12 | import HTML from 'html-parse-stringify'; 13 | import AttributedString from "@smartface/native/ui/attributedstring"; 14 | import propFactory from "@smartface/contx/lib/smartface/sfCorePropFactory"; 15 | 16 | import * as util from './util'; 17 | 18 | let lastTextNode: any = null; 19 | 20 | type ArgumentTypes = F extends (...args: infer A) => any 21 | ? A 22 | : never; 23 | 24 | /** 25 | * This method automatically maps necessary attributedstring variables. Use this if you don't have Dark theme support or you want the attributedstrings as is. 26 | * Consider reading this documentation before passing an html: https://github.com/smartface/@smartface/extension-utils/blob/master/doc/html-to-text.md 27 | * @example 28 | * ``` 29 | import TextView from '@smartface/native/ui/textview'; 30 | import { createAttributedStrings } from "sf-extenstion-utils/lib/html-to-text"); 31 | import AttributedString from "@smartface/native/ui/attributedstring"; 32 | import propFactory from "@smartface/contx/lib/smartface/sfCorePropFactory"; 33 | 34 | const textView = new TextView(); 35 | const htmlSource = "Your attributed Strings
second
Third
"; 36 | const attributedStrings = createAttributedTexts(htmlSource); 37 | textView.attributedText = attributedStrings; 38 | ``` 39 | * @param {string} htmlSource - Your html content to work with. The limitations and rules are specified in the document of this module. 40 | * @returns {Array.} 41 | */ 42 | export function createAttributedTexts(htmlSource: string): AttributedString[] { 43 | const spannedHtmlSource = `${htmlSource}`; 44 | const ast = HTML.parse(spannedHtmlSource.replace(/
/gim, "\n")); 45 | const tree = getParsedTree(ast[0]); 46 | lastTextNode = null; 47 | const attributedStringsFromTree = getAttributedStringsFromTree(tree); 48 | return attributedStringsFromTree.map( 49 | (s) => new AttributedString(propFactory(s)) 50 | ); 51 | } 52 | 53 | /** 54 | * This method returns half-baked attributedstring value. Use this method if you support dark theme to change foregroundColor or if you want to tweak other properties. 55 | * Consider reading this documentation before passing an html: https://github.com/smartface/@smartface/extension-utils/blob/master/doc/html-to-text.md 56 | * @example 57 | * ``` 58 | import TextView from '@smartface/native/ui/textview'; 59 | import { createAttributedStrings } from "sf-extenstion-utils/lib/html-to-text"); 60 | 61 | const textView = new TextView(); 62 | const htmlSource = "Your attributed Strings
second
Third
"; 63 | textView.attributedText = attributedStrings.map(s => new AttributedString(propFactory(s))); 64 | ``` 65 | * @param {string} htmlSource - Your html content to work with. The limitations and rules are specified in the document of this module. 66 | * @returns {Array.} 67 | */ 68 | export function createAttributedStrings( 69 | htmlSource: string 70 | ): ArgumentTypes[0] { 71 | const spannedHtmlSource = `${htmlSource}`; 72 | const ast = HTML.parse(spannedHtmlSource.replace(/
/gim, '\n')); 73 | const tree = getParsedTree(ast[0]); 74 | lastTextNode = null; 75 | return getAttributedStringsFromTree(tree); 76 | } 77 | 78 | 79 | function getParsedTree(ast: any, parent?: any) { 80 | const res = { children: [] }; 81 | if (!ast) return res; 82 | 83 | res.style = Object.assign( 84 | {}, 85 | parent && parent.style ? parent.style : {}, 86 | ast.attrs && ast.attrs.style ? getParsedStyleObject(ast.attrs.style) : {} 87 | ); 88 | 89 | if (ast.attrs) { 90 | if (ast.attrs.color) res.style.color = ast.attrs.color; 91 | if (ast.attrs.face) res.style['font-family'] = ast.attrs.face; 92 | if (ast.attrs.size) res.style['font-size'] = ast.attrs.size; 93 | if (ast.attrs.href) res.style['href'] = ast.attrs.href; 94 | } 95 | 96 | if (ast.type === 'text') { 97 | res.value = ast.content; 98 | lastTextNode = res; 99 | } else if (ast.type === 'tag') { 100 | if (ast.name === 'br' || ast.name === 'div') 101 | lastTextNode && (lastTextNode.value += '\n'); 102 | else if (ast.name === 'u') res.style['text-decoration-line'] = 'underline'; 103 | else if (ast.name === 'b') res.style['font-weight'] = 'bold'; 104 | else if (ast.name === 'i') res.style['font-style'] = 'italic'; 105 | else if (ast.name === 'strong') res.style['font-weight'] = 'bold'; 106 | else if (ast.name === 's' || ast.name === 'strike') { 107 | res.style.strike = true; 108 | ast.attrs.style.color && 109 | (res.style.strikethroughColor = ast.attrs.style.color); 110 | } 111 | } 112 | if (ast.voidElement === false) { 113 | ast.children.forEach((c) => res.children.push(getParsedTree(c, res))); 114 | } 115 | return res; 116 | } 117 | 118 | function getParsedStyleObject(style: any) { 119 | const res = {}; 120 | const styles = style.split(';'); 121 | styles.forEach((item: any) => { 122 | const oneStyle = item.trim().split(': '); 123 | oneStyle.length === 2 && ((res as any)[oneStyle[0]] = oneStyle[1]); 124 | }); 125 | return res; 126 | } 127 | 128 | function getAttributedStringsFromTree(tree: any, resStrings?: AttributedString[]): AttributedString[] { 129 | resStrings = resStrings || []; 130 | 131 | let obj = { font: {} }; 132 | 133 | if (tree.value) { 134 | if (tree.style['font-family']) { 135 | const parsedFamily = tree.style['font-family'].split(/_|-/); 136 | parsedFamily.length === 3 && parsedFamily.shift(); 137 | parsedFamily[0] && 138 | Object.assign(obj, { 139 | font: { 140 | family: parsedFamily[0], 141 | }, 142 | }); 143 | if (parsedFamily[1]) { 144 | obj.font.style = parsedFamily[1]; 145 | obj.font.bold = /bold/i.test(obj.font.style); 146 | obj.font.italic = /italic/i.test(obj.font.style); 147 | } 148 | } 149 | tree.style['href'] && (obj.link = tree.style['href']); 150 | tree.style['font-size'] && 151 | (obj.font.size = Math.floor(parseFloat(tree.style['font-size']))); 152 | tree.style['font-weight'] && 153 | (obj.font.bold = tree.style['font-weight'] === 'bold'); 154 | tree.style['font-style'] && 155 | (obj.font.italic = tree.style['font-style'] == 'italic'); 156 | 157 | tree.style['background-color'] && 158 | (obj.backgroundColor = tree.style['background-color']); 159 | tree.style['color'] && (obj.foregroundColor = tree.style['color']); 160 | 161 | tree.style['text-decoration-line'] && 162 | tree.style['text-decoration-line'].indexOf('underline') !== -1 && 163 | (obj.underline = true); 164 | tree.style['text-decoration-color'] && 165 | (obj.underlineColor = tree.style['text-decoration-color']); 166 | 167 | if ( 168 | tree.style.strike || 169 | (tree.style['text-decoration-line'] && 170 | tree.style['text-decoration-line'].indexOf('line-through') !== -1) 171 | ) { 172 | obj.strikethrough = true; 173 | tree.style['text-decoration-color'] && 174 | (obj.strikethroughColor = tree.style['text-decoration-color']); 175 | tree.style.strikethroughColor && 176 | (obj.strikethroughColor = tree.style.strikethroughColor); 177 | } 178 | 179 | obj.string = tree.value; 180 | Object.keys(obj.font).length === 0 && delete obj.font; 181 | util.updateTextDecorationColors(obj); 182 | obj = util.clearProps(obj); 183 | if ( 184 | resStrings.length && 185 | util.isEqualProps(resStrings[resStrings.length - 1], obj) 186 | ) { 187 | resStrings[resStrings.length - 1].string += obj.string; 188 | } else { 189 | resStrings.push(obj); 190 | } 191 | } 192 | tree.children.forEach((t) => { 193 | getAttributedStringsFromTree(t, resStrings); 194 | }); 195 | 196 | return resStrings; 197 | } 198 | -------------------------------------------------------------------------------- /src/html-to-text/util.ts: -------------------------------------------------------------------------------- 1 | //@ts-nocheck 2 | import AttributedString from "@smartface/native/global/attributedstring"; 3 | 4 | export function isEqualProps(a: AttributedString, b: AttributedString) { 5 | return ( 6 | a.underline === b.underline && 7 | a.backgroundColor === b.backgroundColor && 8 | a.foregroundColor === b.foregroundColor && 9 | a.link === b.link && 10 | isEqualFontProps(a.font, b.font) && 11 | (a.ios && b.ios 12 | ? a.ios.underlineColor === b.ios.underlineColor && 13 | a.ios.strikethroughColor === b.ios.strikethroughColor 14 | : !a.ios && !b.ios) 15 | ); 16 | } 17 | 18 | export function isEqualFontProps(a: AttributedString['font'], b: AttributedString['font']) { 19 | if (a && b) { 20 | return ( 21 | a.bold === b.bold && 22 | a.italic === b.italic && 23 | a.style === b.style && 24 | a.family === b.family && 25 | a.size === b.size 26 | ); 27 | } else if (!a && !b) return true; 28 | return false; 29 | } 30 | 31 | export function clearProps(t: AttributedString) { 32 | delete t.value; 33 | t.backgroundColor === "transparent" && delete t.backgroundColor; 34 | t.underline && 35 | t.underlineColor && 36 | (t.ios = { underlineColor: t.underlineColor }); 37 | t.strikethroughColor && 38 | (t.ios = Object.assign(t.ios || {}, { 39 | strikethroughColor: t.strikethroughColor, 40 | })); 41 | delete t.underlineColor; 42 | delete t.strikethroughColor; 43 | return t; 44 | } 45 | 46 | export function updateTextDecorationColors(t) { 47 | if (t.underline && !t.underlineColor) { 48 | t.underlineColor = t.foregroundColor || "#000000"; 49 | } 50 | if (t.strikethrough && !t.strikethroughColor) { 51 | t.strikethroughColor = t.foregroundColor || "#000000"; 52 | } 53 | } 54 | 55 | export function isPlainAttributedText(t) { 56 | return ( 57 | !t.backgroundColor && 58 | !t.foregroundColor && 59 | !t.underline && 60 | !t.ios && 61 | !t.font 62 | ); 63 | } -------------------------------------------------------------------------------- /src/maps/index.ts: -------------------------------------------------------------------------------- 1 | import Linking from "@smartface/native/global/linking"; 2 | import System from "@smartface/native/device/system"; 3 | import Menu from "@smartface/native/ui/menu"; 4 | import MenuItem from "@smartface/native/ui/menuitem"; 5 | import Page from "@smartface/native/ui/page"; 6 | 7 | type Location = { 8 | latitude: number; 9 | longitude: number; 10 | }; 11 | 12 | type NavigationOptions = { 13 | /** 14 | * @iOS 15 | */ 16 | mapType?: keyof typeof MapTypes; 17 | name?: string; 18 | location: Location; 19 | transportType: TransportTypes; 20 | /** 21 | * @android 22 | */ 23 | chooserTitle?: string; 24 | cancelText?: string; 25 | }; 26 | 27 | export enum MapTypes { 28 | APPLE_MAPS = "APPLE_MAPS", 29 | GOOGLE_MAPS = "GOOGLE_MAPS", 30 | YANDEX_MAPS = "YANDEX_MAPS", 31 | YANDEX_NAVIGATION = "YANDEX_NAVIGATION", 32 | } 33 | 34 | type MapBody = { 35 | NAME: string; 36 | SCHEME: string; 37 | URL: string; 38 | SUCCESS_TEXT: string; 39 | FAILURE_TEXT: string; 40 | }; 41 | 42 | type MapOptions = { 43 | page: Page; 44 | location: Location; 45 | name: string; 46 | transportType?: keyof typeof TransportTypes; 47 | locationName: string; 48 | isNavigation: boolean; 49 | mapType: MapTypes | keyof typeof MapTypes; 50 | chooserTitle?: string; 51 | cancelText?: string; 52 | }; 53 | 54 | const MapList: Record = { 55 | APPLE_MAPS: { 56 | NAME: "Apple Maps", 57 | URL: "http://maps.apple.com", 58 | SCHEME: "", 59 | SUCCESS_TEXT: "Apple Maps opened", 60 | FAILURE_TEXT: "Apple Maps couldn't be opened", 61 | }, 62 | GOOGLE_MAPS: { 63 | NAME: "Google Maps", 64 | SCHEME: "comgooglemaps://", 65 | URL: "https://www.google.com/maps/search/", 66 | SUCCESS_TEXT: "Google Maps opened", 67 | FAILURE_TEXT: "Google Maps couldn't be opened", 68 | }, 69 | YANDEX_MAPS: { 70 | NAME: "Yandex Maps", 71 | SCHEME: "yandexmaps://", 72 | URL: "yandexmaps://", 73 | SUCCESS_TEXT: "Yandex Maps opened", 74 | FAILURE_TEXT: "Yandex Maps couldn't be opened", 75 | }, 76 | YANDEX_NAVIGATION: { 77 | NAME: "Yandex Navigation", 78 | SCHEME: "yandexnavi://", 79 | URL: "yandexnavi://", 80 | SUCCESS_TEXT: "Yandex Nagivation opened", 81 | FAILURE_TEXT: "Yandex Nagivation couldn't be opened", 82 | }, 83 | }; 84 | 85 | export enum TransportTypes { 86 | DRIVING = "d", 87 | WALKING = "w", 88 | CYCLING = "b", 89 | } 90 | 91 | type MenuStrings = { 92 | chooserTitle?: string; 93 | cancelText?: string; 94 | }; 95 | 96 | export function showMapsMenu(options: { mapOptions: MapOptions & MenuStrings; page: Page }): Promise { 97 | const { mapOptions, page } = options; 98 | return System.OS === System.OSType.IOS ? showMenuForIOS(mapOptions, page) : showMenuForAndroid(mapOptions); 99 | } 100 | 101 | export function showNavigationMenu(options: { navigationOptions: NavigationOptions & MenuStrings; page: Page }): Promise { 102 | const { navigationOptions, page } = options; 103 | return System.OS === System.OSType.IOS ? showMenuForIOS(navigationOptions, page, true) : showMenuForAndroid(navigationOptions, true); 104 | } 105 | 106 | function showMenuForIOS(options: NavigationOptions | MapOptions, page: Page, isNavigation = false) { 107 | return new Promise((resolve, reject) => { 108 | const menu = new Menu(); 109 | const menuItems: MenuItem[] = []; 110 | 111 | const mapsOnSelected = (mapType: MapTypes) => { 112 | const mapOptions = getMapOptions({ 113 | locationName: options.name || "", 114 | location: options.location, 115 | mapType, 116 | isNavigation, 117 | transportType: options.transportType, 118 | }); 119 | if (!mapOptions) { 120 | return; 121 | } 122 | Linking.openURL({ 123 | uriScheme: mapOptions.scheme, 124 | data: mapOptions.data, 125 | onSuccess: () => resolve(mapOptions.successText), 126 | onFailure: () => reject(mapOptions.errorText), 127 | }); 128 | }; 129 | 130 | const appleMapsMenuItem = new MenuItem({ 131 | title: MapList.APPLE_MAPS.NAME, 132 | onSelected: () => mapsOnSelected(MapTypes.APPLE_MAPS), 133 | }); 134 | const googleMapsMenuItem = new MenuItem({ 135 | title: MapList.GOOGLE_MAPS.NAME, 136 | onSelected: () => mapsOnSelected(MapTypes.GOOGLE_MAPS), 137 | }); 138 | const yandexMapsMenuItem = new MenuItem({ 139 | title: MapList.YANDEX_MAPS.NAME, 140 | onSelected: () => mapsOnSelected(MapTypes.YANDEX_MAPS), 141 | }); 142 | const cancelMenuItem = new MenuItem({ 143 | title: options?.cancelText || "Cancel", 144 | ios: { 145 | style: MenuItem.ios.Style.CANCEL, 146 | }, 147 | }); 148 | 149 | const googleMapsAvailable = Linking.canOpenURL(MapList.GOOGLE_MAPS.SCHEME); 150 | const yandexMapsAvailable = Linking.canOpenURL(MapList.YANDEX_MAPS.SCHEME); 151 | 152 | // Google Maps 153 | if (googleMapsAvailable) { 154 | menuItems.push(googleMapsMenuItem); 155 | } 156 | // Yandex Maps 157 | if (yandexMapsAvailable) { 158 | menuItems.push(yandexMapsMenuItem); 159 | } 160 | if (googleMapsAvailable || yandexMapsAvailable) { 161 | menuItems.push(appleMapsMenuItem); 162 | menuItems.push(cancelMenuItem); 163 | } 164 | menu.items = menuItems; 165 | menuItems.length ? menu.show(page) : mapsOnSelected(MapTypes.APPLE_MAPS); 166 | }); 167 | } 168 | 169 | function showMenuForAndroid(options: MapOptions | NavigationOptions, isNavigation = false) { 170 | return new Promise((resolve, reject) => { 171 | const { latitude, longitude } = options.location; 172 | const locationName = options.name || ""; 173 | const transportType = options?.transportType; 174 | const uriScheme = isNavigation ? `geo:${latitude},${longitude}?q=${latitude},${longitude}&mode=${transportType}` : `geo:${latitude},${longitude}?q=${encodeURIComponent(locationName)}`; 175 | Linking.openURL({ 176 | uriScheme, 177 | chooserTitle: options?.chooserTitle || "Choose Maps App", 178 | onSuccess: (e) => resolve(e), 179 | onFailure: (e) => reject(e), 180 | shouldShowChooser: true, 181 | }); 182 | }); 183 | } 184 | 185 | type NewMapOptions = { 186 | locationName: string; 187 | location: { 188 | latitude: number; 189 | longitude: number; 190 | }; 191 | mapType: MapTypes; 192 | isNavigation?: boolean; 193 | transportType?: keyof typeof TransportTypes | TransportTypes; 194 | }; 195 | 196 | /** 197 | * @param {Object} options Options of will open map 198 | * @param {String} options.locationName 199 | * @param {Boolean} options.isNavigation 200 | * @param {TransportTypes} options.transportType 201 | * @param {MapTypes} options.mapType 202 | * @param {Object} options.location 203 | * @param {Number} options.location.latitude 204 | * @param {Number} options.location.longitude 205 | * @returns 206 | */ 207 | function getMapOptions(options: NewMapOptions) { 208 | const { 209 | locationName, 210 | isNavigation, 211 | transportType, 212 | mapType, 213 | location: { latitude, longitude }, 214 | } = options; 215 | const isDriving = transportType === TransportTypes.DRIVING; 216 | return [ 217 | { 218 | type: MapTypes.APPLE_MAPS, 219 | data: isNavigation 220 | ? { 221 | daddr: `${latitude},${longitude}`, 222 | dirflg: isDriving ? TransportTypes.DRIVING : TransportTypes.WALKING, 223 | } 224 | : { 225 | ll: `${latitude},${longitude}`, 226 | q: encodeURIComponent(locationName), 227 | }, 228 | scheme: MapList.APPLE_MAPS.URL, 229 | errorText: MapList.APPLE_MAPS.FAILURE_TEXT, 230 | successText: MapList.APPLE_MAPS.SUCCESS_TEXT, 231 | }, 232 | { 233 | type: MapTypes.GOOGLE_MAPS, 234 | data: isNavigation 235 | ? { 236 | api: "1", 237 | travelmode: isDriving ? "driving" : "walking", 238 | dir_action: "navigate", 239 | destination: `${latitude},${longitude}`, 240 | } 241 | : { 242 | api: "1", 243 | query: `${latitude},${longitude}`, 244 | q: encodeURIComponent(locationName), 245 | }, 246 | scheme: isNavigation ? "https://www.google.com/maps/dir/" : MapList.GOOGLE_MAPS.URL, 247 | errorText: MapList.GOOGLE_MAPS.FAILURE_TEXT, 248 | successText: MapList.GOOGLE_MAPS.SUCCESS_TEXT, 249 | }, 250 | { 251 | type: MapTypes.YANDEX_MAPS, 252 | data: isNavigation ? {} : { ll: `${latitude},${longitude}`, text: encodeURIComponent(locationName) }, 253 | scheme: isNavigation ? `${MapList.YANDEX_NAVIGATION.SCHEME}build_route_on_map?lat_to=${latitude}&lon_to=${longitude}` : MapList.YANDEX_MAPS.SCHEME, 254 | errorText: isNavigation ? MapList.YANDEX_NAVIGATION.FAILURE_TEXT : MapList.YANDEX_MAPS.FAILURE_TEXT, 255 | successText: isNavigation ? MapList.YANDEX_NAVIGATION.SUCCESS_TEXT : MapList.YANDEX_MAPS.SUCCESS_TEXT, 256 | }, 257 | ].find((m) => m.type === mapType); 258 | } 259 | -------------------------------------------------------------------------------- /src/pdf/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module pdf 3 | * @type {Object} 4 | * @author Ozcan Ovunc 5 | * @copyright Smartface 2019 6 | */ 7 | 8 | import WebView from '@smartface/native/ui/webview'; 9 | import Screen from '@smartface/native/device/screen'; 10 | 11 | const htmlTemplate = ` 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 58 | 59 | 60 | 61 | `; 62 | 63 | /** 64 | * @function 65 | * Renders base64 string as pdf file in a WebView 66 | * @example 67 | * ``` 68 | * import pdf from '@smartface/extension-utils/lib/pdf'; 69 | * pdf.render({ 70 | * webView: webView, 71 | * base64pdf: 'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' + 72 | * 'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' + 73 | * 'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' + 74 | * 'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' + 75 | * 'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' + 76 | * 'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' + 77 | * 'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' + 78 | * 'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' + 79 | * 'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' + 80 | * 'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' + 81 | * 'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' + 82 | * 'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' + 83 | * 'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G', 84 | * zoomEnabled: true 85 | * }); 86 | * ``` 87 | */ 88 | export function render(options: { 89 | customWidth?: number; 90 | webView: WebView; 91 | base64pdf: string; 92 | zoomEnabled?: boolean; 93 | }): void { 94 | const base64pdfParam = options.base64pdf.replace(/\n/g, ''); 95 | const html = htmlTemplate 96 | .replace( 97 | '__CUSTOM_WIDTH__', 98 | String((options.customWidth || Screen.width) - 10) 99 | ) 100 | .replace('$maximumScale', options.zoomEnabled ? '6.0' : '1.0') 101 | .replace('$userScalable', options.zoomEnabled ? '1.0' : 'no') 102 | .replace('$BASE64PDF', base64pdfParam); 103 | options.webView.zoomEnabled = options.zoomEnabled || true; 104 | options.webView.loadHTML(html); 105 | } 106 | 107 | export default { 108 | render, 109 | }; 110 | -------------------------------------------------------------------------------- /src/service-call-offline/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Smartface Service-Call-Offline module. 3 | * This module provides classes to be instead of ServiceCall class for some offline capability. 4 | * 5 | * @module service-call-offline 6 | * @type {object} 7 | * @deprecated USE AXIOS OR XMLHTTPREQUEST INSTEAD! 8 | * @copyright Smartface 2019 9 | */ 10 | 11 | import System from "@smartface/native/device/system"; 12 | import Data from "@smartface/native/global/data"; 13 | import Network from "@smartface/native/device/network"; 14 | import guid from "../guid"; 15 | import copy from "../copy"; 16 | import ServiceCall from "../service-call"; 17 | 18 | const TABLE_NAMES = Object.freeze({ 19 | CACHED_REQUESTS: "SF_EXTENSION_UTILS_OFFLINE_ALL_CACHED_REQUESTS", 20 | PENDING_REQUESTS: "SF_EXTENSION_UTILS_OFFLINE_ALL_PENDING_REQUESTS", 21 | }); 22 | 23 | const sameReturner = (e: any) => e; 24 | let encryptFunction; 25 | let decryptFunction; 26 | let isConfigured = false; 27 | 28 | async function isOnline(): Promise { 29 | const isOnline = Network.connectionType === Network.ConnectionType.NONE; 30 | return isOnline ? Promise.resolve() : Promise.reject(); 31 | } 32 | 33 | interface OfflineRequestOptions { 34 | offlineRequestHandler?(e: T): Promise; 35 | } 36 | 37 | export const closeOfflineDatabase = sameReturner; 38 | 39 | export class OfflineRequestServiceCall extends ServiceCall { 40 | offlineRequestHandler: OfflineRequestOptions["offlineRequestHandler"]; 41 | /** 42 | * Creates an OfflineRequestServiceCall helper class 43 | * If there's no network connection, saves the request to perform later when 44 | * network connection is available 45 | * @augments ServiceCall 46 | * @param {function} offlineRequestHandler - Gets request options to be modified 47 | * when network connection is available and returns a promise 48 | * @example 49 | * ``` 50 | * import { OfflineRequestServiceCall } from '@smartface/extension-utils/lib/service-call-offline'; 51 | * sc = new OfflineRequestServiceCall({ 52 | * baseUrl: "http://smartface.io", 53 | * logEnabled: true, 54 | * offlineRequestHandler: requestOptions => { 55 | * return new Promise((resolve, reject) => { 56 | * amce.createRequestOptions(amceOptions) 57 | * .then(({ headers }) => { 58 | * resolve(Object.assign({}, requestOptions, headers)); 59 | * }); 60 | * }); 61 | * } 62 | * }); 63 | * ``` 64 | */ 65 | constructor(options: OfflineRequestOptions & ConstructorParameters["0"]) { 66 | if (!isConfigured) { 67 | throw Error("First you need to configure"); 68 | } 69 | super(options); 70 | this.offlineRequestHandler = options.offlineRequestHandler || ((e: any) => Promise.resolve(e)); 71 | 72 | //@ts-ignore 73 | const notifier = new Network.createNotifier(); 74 | const networkListener = async () => { 75 | try { 76 | await isOnline(); 77 | this.sendAll(); 78 | this.clearJobs(); 79 | } finally { 80 | } 81 | networkListener(); 82 | notifier.subscribe(networkListener); 83 | }; 84 | } 85 | 86 | async request(endpointPath: string, options: Parameters[1]): Promise { 87 | const requestOptions = this.createRequestOptions(endpointPath, options); 88 | try { 89 | await isOnline(); 90 | return super.request(endpointPath, options); 91 | } catch (e) { 92 | const requestID = guid(); 93 | saveToTable({ 94 | tableID: TABLE_NAMES.PENDING_REQUESTS, 95 | requestID, 96 | data: JSON.stringify(requestOptions), 97 | }); 98 | return Promise.resolve(null); 99 | } 100 | } 101 | 102 | /** 103 | * Perform all pending requests in DB 104 | * @static 105 | * @method 106 | * @returns {Promise} 107 | */ 108 | async sendAll(): Promise { 109 | return Promise.resolve().then(() => { 110 | const allPendingRequestsString = Data.getStringVariable(TABLE_NAMES.PENDING_REQUESTS); 111 | const allPendingRequests = allPendingRequestsString ? JSON.parse(allPendingRequestsString) : []; 112 | return Promise.all( 113 | allPendingRequests.map((requestID: string) => { 114 | const requestOptions = Data.getStringVariable(requestID); 115 | const requestOptionsAsJSON = JSON.parse(requestOptions); 116 | const requestHandlerPromise = this.offlineRequestHandler ? this.offlineRequestHandler(copy(requestOptionsAsJSON)) : Promise.resolve(); 117 | return requestHandlerPromise.then((o: any) => this.request(this.baseUrl, requestOptionsAsJSON)); 118 | }) 119 | ); 120 | }); 121 | } 122 | 123 | private clearJobs(): Promise { 124 | return new Promise((resolve) => { 125 | const allPendingRequestsString = Data.getStringVariable(TABLE_NAMES.PENDING_REQUESTS); 126 | const allPendingRequests = allPendingRequestsString ? JSON.parse(allPendingRequestsString) : []; 127 | allPendingRequests.forEach((requestID: string) => { 128 | Data.removeVariable(requestID); 129 | }); 130 | }); 131 | } 132 | } 133 | 134 | export class OfflineResponseServiceCall extends ServiceCall { 135 | private _requestCleaner: OfflineRequestOptions["offlineRequestHandler"]; 136 | /** 137 | * Creates an OfflineResponseServiceCall helper class 138 | * Response is served from DB then request is made to update the DB 139 | * 140 | * @augments ServiceCall 141 | * @param {function} requestCleaner - Returns modified request options 142 | * @example 143 | * ``` 144 | * import { OfflineResponseServiceCall } from '@smartface/extension-utils/lib/service-call-offline'; 145 | * sc = sc || new OfflineResponseServiceCall({ 146 | * baseUrl: "http://smartface.io", 147 | * logEnabled: true, 148 | * requestCleaner: requestOptions => { 149 | * delete requestOptions.headers; 150 | * return requestOptions; 151 | * } 152 | * }); 153 | * ``` 154 | */ 155 | constructor(options: { 156 | baseUrl: string; 157 | logEnabled?: boolean; 158 | requestCleaner: OfflineRequestOptions["offlineRequestHandler"]; 159 | encryptionFunction: (e: any) => any; 160 | decryptionFunction: (e: any) => any; 161 | }) { 162 | if (!isConfigured) { 163 | throw Error("First you need to configure"); 164 | } 165 | super(options); 166 | this._requestCleaner = options.requestCleaner || ((e: any) => Promise.resolve(e)); 167 | } 168 | 169 | request(endpointPath: string, options?: Parameters[1]): Promise { 170 | //@ts-ignore 171 | const requestOptions = this.createRequestOptions(endpointPath, options); 172 | const cleanedRequestOptions = this._requestCleaner ? this._requestCleaner(copy(requestOptions)) : requestOptions; 173 | const cleanedRequestOptionsAsString = JSON.stringify(cleanedRequestOptions); 174 | 175 | let offlineRequest = () => { 176 | return new Promise((resolve, reject) => { 177 | let cachedResponse = Data.getStringVariable(cleanedRequestOptionsAsString); 178 | cachedResponse ? resolve(JSON.parse(cachedResponse)) : reject("No records found"); 179 | }); 180 | }; 181 | 182 | let onlineRequest = () => { 183 | return this.request(endpointPath, options).then((response) => { 184 | saveToTable({ 185 | tableID: TABLE_NAMES.CACHED_REQUESTS, 186 | requestID: cleanedRequestOptionsAsString, 187 | data: JSON.stringify(response), 188 | }); 189 | return response; 190 | }); 191 | }; 192 | 193 | return new Promise((resolve, reject) => { 194 | return offlineRequest() 195 | .then((e) => { 196 | onlineRequest(); // Make sure cache is up to date 197 | resolve(e); 198 | }) 199 | .catch((e) => { 200 | onlineRequest() 201 | .then(resolve) 202 | .catch(reject); 203 | }); 204 | }); 205 | } 206 | } 207 | 208 | const errorHandler = (err: any) => { 209 | if (err instanceof Error) 210 | return { 211 | //@ts-ignore 212 | title: err.type || "Application Error", 213 | message: System.OS === System.OSType.ANDROID ? err.stack : err.message + "\n\n*" + err.stack, 214 | }; 215 | else return err; 216 | }; 217 | 218 | export function clearOfflineDatabase(): Promise { 219 | return new Promise((resolve, reject) => { 220 | try { 221 | const allCachedRequestsString = Data.getStringVariable(TABLE_NAMES.CACHED_REQUESTS); 222 | const allPendingRequestsString = Data.getStringVariable(TABLE_NAMES.PENDING_REQUESTS); 223 | const allCachedRequests = allCachedRequestsString ? JSON.parse(allCachedRequestsString) : []; 224 | const allPendingRequests = allPendingRequestsString ? JSON.parse(allPendingRequestsString) : []; 225 | allCachedRequests.forEach((r: string) => Data.removeVariable(r)); 226 | allPendingRequests.forEach((r: string) => Data.removeVariable(r)); 227 | resolve(); 228 | } catch (e) { 229 | reject(e); 230 | } 231 | }); 232 | } 233 | 234 | function saveToTable(opts: { tableID: string; requestID: string; data: string }): Promise { 235 | return new Promise((resolve, reject) => { 236 | try { 237 | const allRequestsString = Data.getStringVariable(opts.tableID); 238 | const allRequests = allRequestsString ? JSON.parse(allRequestsString) : []; 239 | allRequests.push(opts.requestID); 240 | const allRequestsStringified = JSON.stringify(allRequests); 241 | Data.setStringVariable(opts.tableID, allRequestsStringified); 242 | Data.setStringVariable(opts.requestID, opts.data); 243 | resolve(); 244 | console.info("[SC_OFFLINE] Successfully saved ", opts.requestID, opts.data); 245 | } catch (ex) { 246 | console.error("[SC_OFFLINE] Failed to save ", opts.requestID, opts.data, errorHandler(ex)); 247 | reject(ex); 248 | } 249 | }); 250 | } 251 | -------------------------------------------------------------------------------- /src/service-call/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Smartface Service-Call helper module 3 | * @module service-call 4 | * @type {object} 5 | * @deprecated USE AXIOS OR XMLHTTPREQUEST INSTEAD! 6 | * @copyright Smartface 2021 7 | */ 8 | 9 | import Http from "@smartface/native/net/http"; 10 | import mixinDeep from "mixin-deep"; 11 | import copy from "../copy"; 12 | import queryString from "query-string"; 13 | 14 | const reHTTPUrl = /^http(s?):\/\//i; 15 | const reParseBodyAsText = /(?:application\/(?:x-csh|json|javascript|rtf|xml)|text\/.*|.*\/.*(:?\+xml|xml\+).*)/i; 16 | const reJSON = /^application\/json/i; 17 | 18 | const METHODS_WITHOUT_BODY = ["GET", "HEAD"]; 19 | const BASE_HEADERS = Object.freeze({ 20 | "Content-Type": "application/json", 21 | Accept: "application/json", 22 | //@ts-ignore 23 | "Accept-Language": global.Device.language || "en", 24 | "Cache-Control": "no-cache", 25 | }); 26 | 27 | const DEFAULT_TIMEOUT = 60000; 28 | 29 | interface IRequestOptions { 30 | /** 31 | * HTTP method of this request 32 | */ 33 | method: string; 34 | /** 35 | * Request payload body. This object will be automatically stringified 36 | */ 37 | body?: { [key: string]: any } | string; 38 | /** 39 | * Query string string object. Combines with the url 40 | */ 41 | q?: string; 42 | /** 43 | * Alias for options.q 44 | */ 45 | query?: string; 46 | /** 47 | * Request specific headers. In conflict with configuration, those values are used 48 | */ 49 | headers?: { [key: string]: any } | string; 50 | /** 51 | * Request specific log option 52 | */ 53 | logEnabled?: boolean; 54 | /** 55 | * Basic authentication user. Must be used with options.password 56 | */ 57 | user?: string; 58 | /** 59 | * Basic authentication password. Must be used with options.user 60 | */ 61 | password?: string; 62 | /** 63 | * Resolved promise contains full response including `headers`, `body` and `status` 64 | */ 65 | fullResponse?: boolean; 66 | url?: string; 67 | } 68 | 69 | interface IServiceCallParameters { 70 | baseUrl: string; 71 | timeout?: number; 72 | logEnabled?: boolean; 73 | headers?: { [key: string]: string }; 74 | sslPinning?: Http["ios"]["sslPinning"]; 75 | } 76 | /** 77 | * Helper class for calling JSON based restful services. 78 | * @public 79 | */ 80 | export default class ServiceCall { 81 | protected _http: Http; 82 | /** 83 | * Base URL for this service-call library uses. This can be get and set 84 | * @property {string} baseUrl 85 | */ 86 | private _baseUrl = ""; 87 | /** 88 | * Log enabled for service-call. This can be get and set 89 | * @property {boolean} logEnabled 90 | */ 91 | private _logEnabled = false; 92 | /** 93 | * Creates a ServiceCall helper class with common configuration to be used across multiple service calls. 94 | * @param {object} options - Cofiguration of service call helper object (required) 95 | * @param {string} options.baseUrl - Base URL of all future service calls (required) 96 | * @param {number} [options.timeout = 60000] - Timeout value for service calls. If not provided it uses the default timeout value from @smartface/native http 97 | * @param {boolean} [options.logEnabled = false] - Logs the service requests & responses to console 98 | * @param {object} [options.headers] - Sets the default headers for this configuration 99 | * @example 100 | *``` 101 | * // services/serviceConfig.ts 102 | * import ServiceCall from '@smartface/extension-utils/lib/service-call'; 103 | * export const sc = new ServiceCall({ 104 | * baseUrl: "http://api.myBaseUrl.com", 105 | * logEnabled: true, 106 | * headers: { 107 | * apiVersion: "1.0" 108 | * } 109 | * }); 110 | * 111 | * // services/user.ts 112 | * import { sc } from 'services/serviceConfig"'; 113 | * 114 | * function login(userName, password) { 115 | * return new Promise((resolve, reject) => { 116 | * sc.request(`/auth/login?emine=3`, { 117 | * method: "POST", 118 | * body: { 119 | * userName, 120 | * password 121 | * } 122 | * }).then(response => { 123 | * sc.setHeader("Authorization", "Bearer " + response.token); 124 | * resolve(response); 125 | * }).catch(err => { 126 | * reject(err); 127 | * }); 128 | * }); 129 | * } 130 | * 131 | * 132 | * // pages/pgLogin.ts 133 | * import userService from 'services/user'; 134 | * 135 | * this.btnLogin.onPress = () => { 136 | * userService.login(this.tbUserName.text, this.tbPassword.text).then(()=> { 137 | * this.router.push("dashboard"); 138 | * }).catch(()=> { 139 | * alert("Cannot login"); 140 | * }); 141 | * }; 142 | * ``` 143 | */ 144 | constructor(options: IServiceCallParameters) { 145 | this.baseUrl = options.baseUrl; 146 | this.logEnabled = !!options.logEnabled; 147 | const httpOptions: Partial = { 148 | timeout: options.timeout || DEFAULT_TIMEOUT, // Default timeout 149 | ios: { 150 | sslPinning: options.sslPinning || [], 151 | }, 152 | headers: options.headers || BASE_HEADERS, 153 | }; 154 | this._http = new Http(httpOptions); 155 | } 156 | 157 | /** 158 | * Sets headers for this configuration. Either sets one by each call or sets them in bulk 159 | * @method 160 | * @param {string} key - Header name to set 161 | * @param {string} value - Value to set of the key. If value is not a string, key is removed from header 162 | * @example 163 | * ``` 164 | * //After login 165 | * sc.setHeader("Authorization", "Basic 12345"); 166 | * ``` 167 | * @example 168 | * ``` 169 | * //After logout 170 | * sc.setHeader("Authorization"); 171 | * ``` 172 | * @example 173 | * ``` 174 | * // set multiple headers at once 175 | * sc.setHeader({ 176 | * environment: "test", 177 | * apiVersion: "1.2" //replaces the existing 178 | * }); 179 | * ``` 180 | */ 181 | setHeader(key: string | Record, value?: string): void { 182 | if (typeof key === "object") { 183 | for (let k in key) { 184 | let v = key[k]; 185 | this.setHeader(k, v); 186 | } 187 | } else if (typeof key === "string") { 188 | if (value) { 189 | this._http.headers[key] = String(value); 190 | } else { 191 | delete this._http.headers[key]; 192 | } 193 | } else { 194 | throw Error("key must be string or object"); 195 | } 196 | } 197 | 198 | /** 199 | * Gets a copy of headers used 200 | * @method 201 | * @returns {object} headers 202 | */ 203 | getHeaders(): Record { 204 | return this._http.headers; 205 | } 206 | 207 | /** 208 | * Base URL for this service-call library uses. This can be get and set 209 | * @property {string} baseUrl 210 | */ 211 | get baseUrl(): string { 212 | return this._baseUrl; 213 | } 214 | 215 | set baseUrl(value: string) { 216 | this._baseUrl = value; 217 | } 218 | 219 | /** 220 | * Log enabled for service-call. This can be get and set 221 | * @property {boolean} logEnabled 222 | */ 223 | get logEnabled(): boolean { 224 | return this._logEnabled; 225 | } 226 | 227 | set logEnabled(value: boolean) { 228 | this._logEnabled = value; 229 | } 230 | 231 | /** 232 | * creates a request options object for http request 233 | * @method 234 | * @example 235 | * ``` 236 | * const reqOps = sc.createRequestOptions(`/auth/login`, { 237 | * method: "POST", 238 | * body: { 239 | * userName, 240 | * password 241 | * }, 242 | * headers: { 243 | * "Content-Type": "application/json" 244 | * } 245 | * }); 246 | * sc.request(reqOps).then((result) => { 247 | * //logic 248 | * }).catch((err) => { 249 | * //logic 250 | * }); 251 | * ``` 252 | */ 253 | createRequestOptions(endpointPath: string, options: IRequestOptions): IRequestOptions { 254 | const url = `${this._baseUrl}${endpointPath}`; 255 | if (!reHTTPUrl.test(url)) { 256 | throw Error(`URL is not valid for http(s) request: ${url}`); 257 | } 258 | return { 259 | url, 260 | logEnabled: !!this.logEnabled, 261 | headers: this.getHeaders(), 262 | ...options, 263 | }; 264 | } 265 | 266 | /** 267 | * Performs a service call and returns a promise to handle 268 | * @method 269 | * @example 270 | * ``` 271 | * const reqOps = sc.createRequestOptions(`/auth/login`, { 272 | * method: "POST", 273 | * body: { 274 | * userName, 275 | * password 276 | * }, 277 | * headers: { 278 | * "Content-Type": "application/json" 279 | * } 280 | * }); 281 | * sc.request(reqOps).then((result) => { 282 | * //logic 283 | * }).catch((err) => { 284 | * //logic 285 | * }); 286 | * ``` 287 | */ 288 | request(endpointPath: string, options: IRequestOptions): Promise { 289 | const url = `${this._baseUrl}${endpointPath}`; 290 | if (!reHTTPUrl.test(url)) { 291 | throw Error(`URL is not valid for http(s) request: ${url}`); 292 | } 293 | const requestOptions = { 294 | url, 295 | logEnabled: !!this.logEnabled, 296 | ...options, 297 | }; 298 | 299 | // this.createRequestOptions(endpointPath, Object.assign({}, options)); 300 | let { fullResponse = false } = requestOptions; 301 | let query = requestOptions.q || requestOptions.query; 302 | requestOptions.url = String(requestOptions.url); 303 | if (query) { 304 | let urlParts = requestOptions.url.split("?"); 305 | let q = Object.assign(queryString.parse(urlParts[1]), query); 306 | let qString = queryString.stringify(q); 307 | urlParts[1] = qString; 308 | requestOptions.url = urlParts.join("?"); 309 | } 310 | 311 | return new Promise((resolve, reject) => { 312 | let copiedOptions = mixinDeep( 313 | { 314 | onLoad: (response: any) => { 315 | try { 316 | response.logEnabled = !!this.logEnabled; 317 | ServiceCall.bodyParser(requestOptions.url || "", response); 318 | if (response.body && response.body.success === false) { 319 | reject(fullResponse ? response : response.body); 320 | } else { 321 | resolve(fullResponse ? response : response.body); 322 | } 323 | } catch (ex) { 324 | reject(ex); 325 | } 326 | }, 327 | onError: (e: any) => { 328 | e.logEnabled = !!this.logEnabled; 329 | ServiceCall.bodyParser(requestOptions.url || "", e); 330 | e.requestUrl = requestOptions.url; 331 | 332 | reject(e); 333 | }, 334 | headers: {}, 335 | }, 336 | requestOptions 337 | ); 338 | 339 | if (METHODS_WITHOUT_BODY.indexOf(copiedOptions.method) !== -1) { 340 | if (copiedOptions.body) { 341 | delete copiedOptions.body; 342 | } 343 | if (copiedOptions.headers && copiedOptions.headers["Content-Type"]) delete copiedOptions.headers["Content-Type"]; 344 | if (copiedOptions.logEnabled) { 345 | console.log("request: ", copiedOptions.url, " ", copiedOptions); 346 | } 347 | } else { 348 | if (copiedOptions.logEnabled) { 349 | console.log("request: ", copiedOptions.url, " ", copiedOptions); 350 | } 351 | if (copiedOptions.body && typeof copiedOptions.body === "object") { 352 | if (copiedOptions.headers["Content-Type"].startsWith("application/json")) { 353 | copiedOptions.body = JSON.stringify(copiedOptions.body); 354 | } else if (copiedOptions.headers["Content-Type"].includes("x-www-form-urlencoded")) { 355 | copiedOptions.body = ServiceCall.convertObjectToFormData(copiedOptions.body); 356 | } 357 | } 358 | } 359 | this._http.request(copiedOptions); 360 | }); 361 | } 362 | 363 | /** 364 | * Default values of headers 365 | * @static 366 | * @readonly 367 | * @property {object} header object 368 | */ 369 | static readonly BASE_HEADERS = BASE_HEADERS; 370 | 371 | static bodyParser(requestUrl: string, response: any) { 372 | const contentType = (response.headers && ServiceCall.getContentType(response.headers)) || ""; 373 | reJSON.lastIndex = reParseBodyAsText.lastIndex = 0; 374 | if (reParseBodyAsText.test(contentType)) response.body = response.body.toString(); 375 | response.body = response.body || "{}"; 376 | 377 | if (reJSON.test(contentType)) { 378 | try { 379 | response.body = JSON.parse(response.body); 380 | response.logEnabled && console.log("Request url ", requestUrl, " Response body ", response.body); 381 | } catch (ex) { 382 | response.logEnabled && console.log("Request url ", requestUrl, " Response is not a JSON\nResponse Body ", response.body); 383 | } 384 | } 385 | if (response.logEnabled && typeof response.body === "string") console.log("Request url ", requestUrl, " Response body (non-json) ", response.body); 386 | } 387 | 388 | static convertObjectToFormData(body: { [key: string]: any }) { 389 | let formData = ""; 390 | let bodyKeys = Object.keys(body); 391 | bodyKeys.forEach((key, index) => { 392 | let isLastItem = bodyKeys.length - 1 === index; 393 | formData += key; 394 | formData += "="; 395 | formData += body[key]; 396 | if (!isLastItem) { 397 | formData += "&"; 398 | } 399 | }); 400 | return formData; 401 | } 402 | 403 | static getContentType(headers: Record = {}) { 404 | let contentType = headers["Content-Type"]; 405 | if (!contentType) { 406 | for (let h in headers) { 407 | if (h.toLowerCase() === "content-type") { 408 | contentType = headers[h]; 409 | break; 410 | } 411 | } 412 | } 413 | return contentType; 414 | } 415 | } 416 | -------------------------------------------------------------------------------- /src/table/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module Table 3 | * @type {object} 4 | * @author Berk Baski 5 | * @copyright Smartface 2021 6 | */ 7 | 8 | import WebView from "@smartface/native/ui/webview"; 9 | 10 | /** CSS properties available within this component */ 11 | const Styles = { 12 | width: "width", 13 | height: "height", 14 | margin: "margin", 15 | marginLeft: "margin-left", 16 | marginRight: "margin-right", 17 | marginBottom: "margin-bottom", 18 | marginTop: "margin-top", 19 | padding: "padding", 20 | paddingLeft: "padding-left", 21 | paddingRight: "padding-right", 22 | paddingBottom: "padding-bottom", 23 | paddingTop: "padding-top", 24 | color: "color", 25 | background: "background", 26 | backgroundColor: "background-color", 27 | fontSize: "font-size", 28 | fontWeight: "font-weight", 29 | fontFamily: "font-family", 30 | border: "border", 31 | borderLeft: "border-left", 32 | borderRight: "border-right", 33 | borderBottom: "border-bottom", 34 | borderTop: "border-top", 35 | alignItems: "align-items", 36 | justifyContent: "justify-content", 37 | diplay: "display", 38 | position: "position", 39 | left: "left", 40 | right: "right", 41 | bottom: "bottom", 42 | top: "top", 43 | zIndex: "z-index", 44 | }; 45 | Object.freeze(Styles); 46 | 47 | /** 48 | * Custom props of elements 49 | */ 50 | type AttributeOptions = { 51 | /** Key and Value of the prop */ 52 | [key: string]: any; 53 | }; 54 | 55 | /** Properties of columns in the row */ 56 | type ColumnOptions = { 57 | /** Value of column */ 58 | key: string; 59 | 60 | /** Class of column */ 61 | columnClass?: string; 62 | 63 | /** Inline style of column */ 64 | columnStyles?: typeof Styles; 65 | 66 | /** Attributes of column */ 67 | columnAttributes?: AttributeOptions; 68 | }; 69 | 70 | /** Properties of rows in the table */ 71 | type RowOptions = { 72 | /** Inline style of row */ 73 | rowStyles?: Partial; 74 | 75 | /** Class of row */ 76 | rowClass?: string; 77 | 78 | /** Attributes of row */ 79 | rowAttributes?: AttributeOptions; 80 | 81 | /** Columns in the row */ 82 | columns?: ColumnOptions[]; 83 | }; 84 | 85 | /** Options for creating a table */ 86 | type TableOptions = { 87 | /** **link** elements to add to the header of the page */ 88 | styleLinks?: string[]; 89 | 90 | /** External styles to add to the page's **style** element */ 91 | externalStyles?: string; 92 | 93 | /** Class of table */ 94 | tableClass?: string; 95 | 96 | /** Inline style of table */ 97 | tableStyles?: Partial; 98 | 99 | /** Attributes of table */ 100 | tableAttributes?: AttributeOptions; 101 | 102 | /** Rows in the table */ 103 | rows?: RowOptions[]; 104 | }; 105 | 106 | interface TableInitOptions { 107 | /** **WebView** or **WebViewBridge** component to show after rendering given table options */ 108 | webView: WebView; 109 | 110 | /** Options of table */ 111 | tableOptions: TableOptions; 112 | } 113 | 114 | /** 115 | * It's creating a table in **WebView** or **WebViewBridge** using given values and style parameters 116 | * @public 117 | * @class 118 | * @param {object} options options - Base options object 119 | * @param {WebView} webView The browser for creating a table 120 | * @param {TableOptions} tableOptions The options for creating a table 121 | * @example 122 | * ``` 123 | * const headerColumns = ['First name', 'Last name']; 124 | * const bodyColumns = [ 125 | * { first: 'Shmi', last: 'Skywalker' }, 126 | * { first: 'Anakin', last: 'Skywalker' }, 127 | * { first: 'Luke', last: 'Skywalker' }, 128 | * { first: 'Leia', last: 'Organa' }, 129 | * { first: 'Han', last: 'Solo' } 130 | * ]; 131 | * 132 | * const table = new Table({ 133 | * webView: this.webView1, 134 | * tableOptions: { 135 | * rows: [ 136 | * { 137 | * rowStyles: { 138 | * color: '#fff', 139 | * fontWeight: 'bold', 140 | * backgroundColor: '#000' 141 | * }, 142 | * columns: headerColumns.map(key => ({ key })) 143 | * }, 144 | * ...bodyColumns.map(column => ({ 145 | * rowStyles: { 146 | * padding: '10px 0', 147 | * borderBottom: '1px solid #000' 148 | * }, 149 | * columns: [ 150 | * { key: column.first }, 151 | * { key: column.last } 152 | * ] 153 | * })) 154 | * ] 155 | * } 156 | * }); 157 | * table.render(); 158 | * ``` 159 | */ 160 | export default class Table implements TableInitOptions { 161 | /** Web equivalent of CSS properties */ 162 | styleTypes: Readonly = Styles; 163 | webView: WebView; 164 | tableOptions: TableOptions; 165 | 166 | /** 167 | * It's creating a table in **WebView** or **WebViewBridge** using given values and style parameters 168 | * @public 169 | * @class 170 | * @param {object} options options - Base options object 171 | * @param {WebView} webView The browser for create a table 172 | * @param {TableOptions} tableOptions The options for create a table 173 | * @example 174 | * ``` 175 | * const headerColumns = ['First name', 'Last name']; 176 | * const bodyColumns = [ 177 | * { first: 'Shmi', last: 'Skywalker' }, 178 | * { first: 'Anakin', last: 'Skywalker' }, 179 | * { first: 'Luke', last: 'Skywalker' }, 180 | * { first: 'Leia', last: 'Organa' }, 181 | * { first: 'Han', last: 'Solo' } 182 | * ]; 183 | * 184 | * const table = new Table({ 185 | * webView: this.webView1, 186 | * tableOptions: { 187 | * rows: [ 188 | * { 189 | * rowStyles: { 190 | * color: '#fff', 191 | * fontWeight: 'bold', 192 | * backgroundColor: '#000' 193 | * }, 194 | * columns: headerColumns.map(key => ({ key })) 195 | * }, 196 | * ...bodyColumns.map(column => ({ 197 | * rowStyles: { 198 | * padding: '10px 0', 199 | * borderBottom: '1px solid #000' 200 | * }, 201 | * columns: [ 202 | * { key: column.first }, 203 | * { key: column.last } 204 | * ] 205 | * })) 206 | * ] 207 | * } 208 | * }); 209 | * table.render(); 210 | * ``` 211 | */ 212 | constructor(options: TableInitOptions) { 213 | this.webView = options.webView || new WebView(); 214 | this.tableOptions = options.tableOptions || {}; 215 | 216 | if (!this.webView) { 217 | throw new Error("webView parameter is required"); 218 | } 219 | 220 | if (!this.tableOptions.styleLinks) { 221 | this.tableOptions.styleLinks = []; 222 | } 223 | 224 | if (!this.tableOptions.rows) { 225 | this.tableOptions.rows = []; 226 | } 227 | } 228 | 229 | /** 230 | * It renders the table chart options to the WebView or WebViewBridge browser 231 | * @method 232 | * @public 233 | */ 234 | render(): void { 235 | const html = this.generateHtml(); 236 | this.webView.loadHTML(html); 237 | } 238 | /** 239 | * It returns the generated html string 240 | * @method 241 | * @public 242 | */ 243 | generateHtml(): string { 244 | const styles = ` 245 | 285 | `; 286 | const html = ` 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | ${this.tableOptions?.styleLinks?.map((link) => link).join("\n")} 295 | 296 | 297 | 302 | ${this.getTableRows(this.tableOptions?.rows || [])} 303 |
304 | ${styles} 305 | 306 | `; 307 | return html; 308 | } 309 | 310 | private parseAttributes(attributes: any) { 311 | return Object.keys(attributes || {}) 312 | .map((key) => `${key}="${attributes[key]}"`) 313 | .join(" "); 314 | } 315 | 316 | private parseClasses(classes: string) { 317 | return `class="${classes || ""}"`; 318 | } 319 | 320 | private parseStyles(styles: any) { 321 | return `style="${Object.keys(styles || {}) 322 | .map((key) => `${(this.styleTypes as any)[key]}:${styles[key]};`) 323 | .join("")}"`; 324 | } 325 | 326 | private getTableRows(rows: any[]) { 327 | return rows 328 | .map( 329 | (row) => 330 | ` 335 | ${this.getRowColumns(row.columns)} 336 | ` 337 | ) 338 | .join(""); 339 | } 340 | 341 | private getRowColumns(columns: any[]) { 342 | return columns 343 | .map( 344 | (column) => 345 | ` 350 | ${column.key} 351 | ` 352 | ) 353 | .join(""); 354 | } 355 | } 356 | -------------------------------------------------------------------------------- /test/copy.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const copy = require("../lib/copy").default; 3 | 4 | 5 | const languages = ['TR', 'US', 'UK', 'NZ', 'AU']; 6 | 7 | const person = { 8 | name: 'testName', 9 | car: undefined, 10 | address: { 11 | city: 'istanbul', 12 | doorNumber: 1, 13 | }, 14 | languages, 15 | created: new Date() 16 | }; 17 | 18 | const testObject = { 19 | name: "first", 20 | surname: "last", 21 | getFullName: function(){ return this.name + this.surname}, 22 | regex: /\d+/, 23 | multiDimArray: [ 24 | [1, null, "value"], 25 | [2, NaN, "heyyy"], 26 | [3] 27 | ] 28 | } 29 | 30 | 31 | 32 | describe("Person Object not Mutated Test", function() { 33 | const newObject = copy(person); 34 | 35 | it('should make a deep copy of the object', function() { 36 | expect(newObject !== person).to.be.equal(true); 37 | expect(newObject).to.be.not.equal(person); 38 | }) 39 | 40 | it('should have same object values', function() { 41 | expect(newObject).to.deep.equal(person); 42 | }) 43 | it('should copy single dimentional array', function() { 44 | expect(newObject.languages).to.be.an("array"); 45 | }) 46 | }); 47 | 48 | 49 | describe("Person Object Mutation Test", function() { 50 | const newObject = copy(person); 51 | 52 | it("shouldn't mutate copied object either at first level", function() { 53 | newObject.name = "NewName"; 54 | newObject.car = "defined"; 55 | newObject.created = "date"; 56 | expect(newObject.name).to.not.equal(person.name); 57 | expect(newObject.car).to.not.equal(person.car); 58 | expect(newObject.created).to.not.equal(person.created); 59 | }) 60 | 61 | it("shouldn't mutate copied object either for deeper values", function() { 62 | newObject.address.city = "bursa"; 63 | newObject.address.doorNumber = 5; 64 | expect(newObject.address.city).to.not.equal(person.address.city); 65 | expect(newObject.address.doorNumber).to.not.equal(person.address.doorNumber); 66 | }) 67 | }); 68 | 69 | describe("testObject not Mutated Test", function() { 70 | const newObject = copy(testObject); 71 | 72 | it('should make a deep copy of the object', function() { 73 | expect(newObject !== testObject).to.be.equal(true); 74 | expect(newObject).to.be.not.equal(testObject); 75 | }) 76 | 77 | it('should have same object values', function() { 78 | expect(newObject).to.deep.equal(testObject); 79 | }) 80 | 81 | it('should copy function correctly', function() { 82 | expect(newObject.getFullName()).to.be.equal(newObject.name + newObject.surname); 83 | }) 84 | 85 | it('should copy regex correctly', function() { 86 | expect(newObject.regex.test(100)).to.be.equal(true); 87 | }) 88 | it('should copy multi dimentional array', function() { 89 | expect(newObject.multiDimArray).to.be.an("array"); 90 | expect(newObject.multiDimArray.length).to.be.equal(3); 91 | expect(newObject.multiDimArray[0].length).to.be.equal(3); 92 | }) 93 | }); 94 | 95 | 96 | describe("testObject Mutation Test", function() { 97 | const newObject = copy(testObject); 98 | 99 | it("shouldn't mutate copied object either at first level", function() { 100 | newObject.name = "NewName"; 101 | newObject.surname = "newSurname"; 102 | newObject.regex= "date"; 103 | expect(newObject.name).to.not.equal(testObject.name); 104 | expect(newObject.surname).to.not.equal(testObject.surname); 105 | expect(newObject.regex).to.not.equal(testObject.regex); 106 | }) 107 | 108 | it("shouldn't mutate copied object either for deeper values", function() { 109 | newObject.multiDimArray[0].push("new Value"); 110 | expect(newObject.multiDimArray).to.not.equal(testObject.multiDimArray); 111 | }) 112 | }); -------------------------------------------------------------------------------- /test/guid.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const guid = require("../lib/guid").default; 3 | 4 | const guidRegex = /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/i; 5 | 6 | describe("guid assertion", function() { 7 | it('Is guid string', function() { 8 | expect(guid()).to.be.string; 9 | }) 10 | }); 11 | 12 | describe("guid positive cases", function() { 13 | const guidArray = new Array(5).fill().map(() => guid()); 14 | 15 | guidArray.forEach((guid, index) => { 16 | it(`${index}: ${guid}`, function() { 17 | expect(guidRegex.test(guid)).to.be.equal(true); 18 | }); 19 | }); 20 | }); 21 | 22 | describe("guid negative cases", function() { 23 | const guidArray = [`3${guid()}5`]; 24 | guidArray.push(undefined); 25 | guidArray.push("1"); 26 | guidArray.push(NaN); 27 | guidArray.push("3-3-3-3-3"); 28 | 29 | guidArray.forEach((guid, index) => { 30 | it(`${index}: ${guid}`, function() { 31 | expect(guidRegex.test(guid)).to.be.equal(false); 32 | }); 33 | }); 34 | }); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "incremental": true, 4 | "target": "es5", 5 | "moduleResolution": "node", 6 | "module": "commonjs", 7 | "lib": ["es6"], 8 | "checkJs": true, 9 | "declaration": true, 10 | "sourceMap": true, 11 | "outDir": "lib", 12 | "rootDir": "src", 13 | "downlevelIteration": true, 14 | "strict": true, 15 | "baseUrl": "src", 16 | "allowSyntheticDefaultImports": true, 17 | "esModuleInterop": true, 18 | "resolveJsonModule": true, 19 | "skipLibCheck": true, 20 | "forceConsistentCasingInFileNames": true, 21 | "noImplicitAny": false, 22 | "strictBindCallApply": true 23 | }, 24 | "include": [ 25 | "src" 26 | ], 27 | "exclude": [ 28 | "node_modules", 29 | "lib" 30 | ], 31 | } 32 | -------------------------------------------------------------------------------- /typedoc.js: -------------------------------------------------------------------------------- 1 | const TypeDoc = require("typedoc"); 2 | const fs = require('fs'); 3 | const path = require('path'); 4 | 5 | const OUTPUT_DIR = 'docs'; 6 | const BASE_PATH = 'src'; 7 | 8 | function flatten(lists) { 9 | return lists.reduce((a, b) => a.concat(b), []); 10 | } 11 | 12 | function getDirectories(srcpath) { 13 | return fs.readdirSync(srcpath) 14 | .map(file => path.join(srcpath, file)) 15 | .filter(path => fs.statSync(path).isDirectory()); 16 | } 17 | 18 | function getDirectoriesRecursive(srcpath) { 19 | return [srcpath, ...flatten(getDirectories(srcpath).map(getDirectoriesRecursive))]; 20 | } 21 | 22 | function getModuleNamesWithPath(basePath) { 23 | const directories = getDirectoriesRecursive(basePath); 24 | return directories; 25 | } 26 | 27 | async function main() { 28 | const app = new TypeDoc.Application(); 29 | app.converter.on(TypeDoc.Converter.EVENT_RESOLVE_BEGIN, (context) => { 30 | // Some extra sanity checks would be good here. 31 | // context is of type Context, which typedoc <0.22 doesn't publicly export 32 | context.project?.children?.forEach(submodule => { 33 | const oldDefault = submodule?.children?.find((reflection) => reflection.name === "default" && reflection.kind === 128); 34 | oldDefault?.children?.forEach((child) => { 35 | submodule.children.push(child) 36 | child.parent = submodule; 37 | }); 38 | if (oldDefault) { 39 | oldDefault.children = undefined; 40 | context.project.removeReflection(oldDefault); 41 | } 42 | }); 43 | }); 44 | app.options.addReader(new TypeDoc.TSConfigReader()); 45 | const fileNames = getModuleNamesWithPath(BASE_PATH); 46 | app.bootstrap({ 47 | entryPoints: fileNames, 48 | sort: ["source-order", "visibility"], 49 | excludePrivate: true, 50 | excludeNotDocumented: false, 51 | excludeInternal: true, 52 | pretty: true, 53 | categorizeByGroup: true, 54 | emit: true 55 | }); 56 | 57 | const project = app.convert(); 58 | 59 | // Project may not have converted correctly 60 | if (project) { 61 | // Rendered docs 62 | await app.generateDocs(project, OUTPUT_DIR); 63 | } 64 | } 65 | 66 | main().catch(console.error); --------------------------------------------------------------------------------