From 3fb0d23b153981d7c49dc77d322088d0bd0e456a Mon Sep 17 00:00:00 2001 From: arekkubaczkowski Date: Mon, 21 Mar 2022 08:53:29 +0100 Subject: [PATCH] Create expo plugin (#113) * chore: create expo plugin * chore: add plugin params * chore: add expo docs * fix package.json path --- README.md | 32 +++++++ app.plugin.js | 1 + package.json | 1 + src/plugin/withStripeTerminal.ts | 70 +++++++++++++++ yarn.lock | 149 +++++++++++++++++++++++++++++-- 5 files changed, 247 insertions(+), 6 deletions(-) create mode 100644 app.plugin.js create mode 100644 src/plugin/withStripeTerminal.ts diff --git a/README.md b/README.md index 6a8ba6d9..e88d5d89 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,38 @@ Please read the [Android documentation](https://developer.android.com/about/vers - Compatible with apps targeting iOS 10 or above. +### Expo initialization + +> This package cannot be used in the "Expo Go" app because [it requires custom native code](https://docs.expo.io/workflow/customizing/). + +> First install the package with yarn, npm, or [`expo install`](https://docs.expo.io/workflow/expo-cli/#expo-install). + +```sh +expo install stripe-terminal-react-native +``` + +After installing this npm package, add the [config plugin](https://docs.expo.io/guides/config-plugins/) to the [`plugins`](https://docs.expo.io/versions/latest/config/app/#plugins) array of your `app.json` or `app.config.js`: + +```json +{ + // ... + "plugins": [ + [ + // ... + "stripe-terminal-react-native", + { + "bluetoothBackgroundMode": true, + "locationWhenInUsePermission": "Location access is required in order to accept payments.", + "bluetoothPeripheralPermission": "Bluetooth access is required in order to connect to supported bluetooth card readers.", + "bluetoothAlwaysUsagePermission": "This app uses Bluetooth to connect to supported card readers." + } + ] + ] +} +``` + +Next, rebuild your app as described in the ['Adding custom native code'](https://docs.expo.io/workflow/customizing/) guide. + ## Stripe Terminal SDK initialization To initialize Stripe Terminal SDK in your React Native app, use the `StripeTerminalProvider` component in the root component of your application. diff --git a/app.plugin.js b/app.plugin.js new file mode 100644 index 00000000..cf406fa5 --- /dev/null +++ b/app.plugin.js @@ -0,0 +1 @@ +module.exports = require('./lib/commonjs/plugin/withStripeTerminal'); diff --git a/package.json b/package.json index 4aedc539..f854b988 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ }, "devDependencies": { "@commitlint/config-conventional": "^11.0.0", + "@expo/config-plugins": "^4.0.18", "@react-native-community/eslint-config": "^2.0.0", "@types/jest": "^27.0.2", "@types/react": "^16.9.19", diff --git a/src/plugin/withStripeTerminal.ts b/src/plugin/withStripeTerminal.ts new file mode 100644 index 00000000..f8e6e963 --- /dev/null +++ b/src/plugin/withStripeTerminal.ts @@ -0,0 +1,70 @@ +import { + ConfigPlugin, + createRunOncePlugin, + IOSConfig, + withInfoPlist, +} from '@expo/config-plugins'; + +const pkg = require('stripe-terminal-react-native/package.json'); + +type StripeTerminalPluginProps = { + bluetoothBackgroundMode?: boolean; + locationWhenInUsePermission?: string; + bluetoothPeripheralPermission?: string; + bluetoothAlwaysUsagePermission?: string; +}; + +const withStripeTerminal: ConfigPlugin = ( + config, + props +) => { + config = withStripeTerminalIos(config, props); + config = withNoopSwiftFile(config); + + return config; +}; + +/** + * Grant bluetooth and location permissions. + */ +const withStripeTerminalIos: ConfigPlugin = ( + expoConfig, + props +) => { + return withInfoPlist(expoConfig, (config) => { + if (props.bluetoothBackgroundMode) { + config.modResults.UIBackgroundModes = ['bluetooth-central']; + } + + config.modResults.NSLocationWhenInUseUsageDescription = + props.locationWhenInUsePermission || + 'Location access is required in order to accept payments.'; + + config.modResults.NSBluetoothPeripheralUsageDescription = + props.bluetoothPeripheralPermission || + 'Bluetooth access is required in order to connect to supported bluetooth card readers.'; + + config.modResults.NSBluetoothAlwaysUsageDescription = + props.bluetoothAlwaysUsagePermission || + 'This app uses Bluetooth to connect to supported card readers.'; + return config; + }); +}; + +/** + * Add a blank Swift file to the Xcode project for Swift compatibility. + */ +export const withNoopSwiftFile: ConfigPlugin = (config) => { + return IOSConfig.XcodeProjectFile.withBuildSourceFile(config, { + filePath: 'noop-file.swift', + contents: [ + '//', + '// @generated', + '// A blank Swift file must be created for native modules with Swift files to work correctly.', + '//', + '', + ].join('\n'), + }); +}; + +export default createRunOncePlugin(withStripeTerminal, pkg.name, pkg.version); diff --git a/yarn.lock b/yarn.lock index 248e754a..02c4dbf0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,6 +16,13 @@ dependencies: "@babel/highlight" "^7.16.0" +"@babel/code-frame@~7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== + dependencies: + "@babel/highlight" "^7.10.4" + "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.0", "@babel/compat-data@^7.16.4": version "7.16.4" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" @@ -1232,6 +1239,56 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@expo/config-plugins@^4.0.18": + version "4.0.18" + resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-4.0.18.tgz#80cf6a3aed83e78f714ad097d80e5a7cca48591a" + integrity sha512-tW4bnrnKhn+PPHF8wf1KAoubICAVUHW8CcagvyFqaRIzeh6yavMIOsQShxOVTbgx7LzSyymZ1nEs45yCGAiMfA== + dependencies: + "@expo/config-types" "^44.0.0" + "@expo/json-file" "8.2.34" + "@expo/plist" "0.0.17" + "@expo/sdk-runtime-versions" "^1.0.0" + "@react-native/normalize-color" "^2.0.0" + chalk "^4.1.2" + debug "^4.3.1" + find-up "~5.0.0" + fs-extra "9.0.0" + getenv "^1.0.0" + glob "7.1.6" + resolve-from "^5.0.0" + semver "^7.3.5" + slash "^3.0.0" + xcode "^3.0.1" + xml2js "0.4.23" + +"@expo/config-types@^44.0.0": + version "44.0.0" + resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-44.0.0.tgz#d3480fe2c99f9e895dae4ebba58b74ed72d03e26" + integrity sha512-d+gpdKOAhqaD5RmcMzGgKzNtvE1w+GCqpFQNSXLliYlXjj+Tv0eL8EPeAdPtvke0vowpPFwd5McXLA90dgY6Jg== + +"@expo/json-file@8.2.34": + version "8.2.34" + resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.2.34.tgz#2f24e90a677195f7a81e167115460eb2902c3130" + integrity sha512-ZxtBodAZGxdLtgKzmsC+8ViUxt1mhFW642Clu2OuG3f6PAyAFsU/SqEGag9wKFaD3x3Wt8VhL+3y5fMJmUFgPw== + dependencies: + "@babel/code-frame" "~7.10.4" + json5 "^1.0.1" + write-file-atomic "^2.3.0" + +"@expo/plist@0.0.17": + version "0.0.17" + resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.0.17.tgz#0f6c594e116f45a28f5ed20998dadb5f3429f88b" + integrity sha512-5Ul3d/YOYE6mfum0jCE25XUnkKHZ5vGlU/X2275ZmCtGrpRn1Fl8Nq+jQKSaks3NqTfxdyXROi/TgH8Zxeg2wg== + dependencies: + "@xmldom/xmldom" "~0.7.0" + base64-js "^1.2.3" + xmlbuilder "^14.0.0" + +"@expo/sdk-runtime-versions@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz#d7ebd21b19f1c6b0395e50d78da4416941c57f7c" + integrity sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ== + "@hapi/hoek@^9.0.0": version "9.2.1" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.1.tgz#9551142a1980503752536b5050fd99f4a7f13b17" @@ -1653,6 +1710,11 @@ resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-1.0.0.tgz#c52a99d4fe01049102d47dc45d40cbde4f720ab6" integrity sha512-xUNRvNmCl3UGCPbbHvfyFMnpvLPoOjDCcp5bT9m2k+TF/ZBklEQwhPZlkrxRx2NhgFh1X3a5uL7mJ7ZR+8G7Qg== +"@react-native/normalize-color@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.0.0.tgz#da955909432474a9a0fe1cbffc66576a0447f567" + integrity sha512-Wip/xsc5lw8vsBlmY2MO/gFLp3MvuZ2baBZjDeTjjndMgM0h5sxz7AZR62RDPGgstp8Np7JzjvVqVT7tpFZqsw== + "@react-native/polyfills@2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-2.0.0.tgz#4c40b74655c83982c8cf47530ee7dc13d957b6aa" @@ -1915,6 +1977,11 @@ dependencies: eslint-visitor-keys "^1.1.0" +"@xmldom/xmldom@~0.7.0": + version "0.7.5" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.5.tgz#09fa51e356d07d0be200642b0e4f91d8e6dd408d" + integrity sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A== + JSONStream@^1.0.4: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -2380,7 +2447,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.1.2, base64-js@^1.5.1: +base64-js@^1.1.2, base64-js@^1.2.3, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -2985,7 +3052,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== @@ -3767,7 +3834,7 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -find-up@^5.0.0: +find-up@^5.0.0, find-up@~5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== @@ -3829,6 +3896,16 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +fs-extra@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.0.tgz#b6afc31036e247b2466dc99c29ae797d5d4580a3" + integrity sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^1.0.0" + fs-extra@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" @@ -3964,6 +4041,11 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= +getenv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/getenv/-/getenv-1.0.0.tgz#874f2e7544fbca53c7a4738f37de8605c3fcfc31" + integrity sha512-7yetJWqbS9sbn0vIfliPsFgoXMKn/YMF+Wuiog97x+urnSRRRZ7xB+uVkwGKzRgq9CDFfMQnE9ruL5DHv9c6Xg== + git-raw-commits@^2.0.0: version "2.0.10" resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.10.tgz#e2255ed9563b1c9c3ea6bd05806410290297bbc1" @@ -3982,6 +4064,18 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" +glob@7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^6.0.1: version "6.0.4" resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" @@ -5280,6 +5374,13 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + json5@^2.1.2, json5@^2.1.3: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" @@ -7047,7 +7148,7 @@ sanitize-filename@^1.6.1: dependencies: truncate-utf8-bytes "^1.0.0" -sax@^1.2.1: +sax@>=0.6.0, sax@^1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -7087,7 +7188,7 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.0.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4: +semver@^7.0.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -7224,7 +7325,7 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== -simple-plist@^1.0.0: +simple-plist@^1.0.0, simple-plist@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-1.3.0.tgz#f451997663eafd8ea6bad353a01caf49ef186d43" integrity sha512-uYWpeGFtZtVt2NhG4AHgpwx323zxD85x42heMJBan1qAiqqozIlaGrwrEt6kRjXWRWIXsuV1VLCvVmZan2B5dg== @@ -7903,6 +8004,11 @@ universalify@^0.1.0, universalify@^0.1.2: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" + integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== + universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" @@ -7965,6 +8071,11 @@ uuid@^3.0.1, uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +uuid@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" + integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== + v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" @@ -8189,16 +8300,42 @@ xcode@^2.0.0: simple-plist "^1.0.0" uuid "^3.3.2" +xcode@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/xcode/-/xcode-3.0.1.tgz#3efb62aac641ab2c702458f9a0302696146aa53c" + integrity sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA== + dependencies: + simple-plist "^1.1.0" + uuid "^7.0.3" + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xml2js@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-14.0.0.tgz#876b5aec4f05ffd5feb97b0a871c855d16fbeb8c" + integrity sha512-ts+B2rSe4fIckR6iquDjsKbQFK2NlUk6iG5nf14mDEyldgoc2nEKZ3jZWMPTxGQwVgToSjt6VGIho1H8/fNFTg== + xmlbuilder@^9.0.7: version "9.0.7" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"