Compare commits

..
Author SHA1 Message Date
Evan Bacon 754fb08327 Merge branch 'master' into @evanbacon/e2e-tests 2021-12-14 21:13:34 -07:00
Evan Bacon 05fe7bf107 Update package.json 2021-11-30 13:34:25 -07:00
Evan Bacon fa107895b6 Update detox.config.js 2021-11-29 17:18:39 -07:00
Evan Bacon d31b0273cf [WIP][NO-MERGE] 2021-11-29 17:01:02 -07:00
Evan Bacon 2f358c25e8 Try new monorepo imports 2021-11-29 16:30:21 -07:00
Evan Bacon d2eb511e1d Update e2e.yml 2021-11-29 14:38:53 -07:00
Evan Bacon f62a941bc6 Update e2e.yml 2021-11-29 14:38:30 -07:00
Evan Bacon d784d14486 Update app.json 2021-11-29 11:44:27 -07:00
Evan Bacon 7b0d0225f9 Update yarn.lock 2021-11-29 11:43:49 -07:00
Evan Bacon c1d25701ca Merge branch 'master' into @evanbacon/e2e-tests 2021-11-29 11:43:10 -07:00
Evan Bacon 5359120dbd Improved CI 2021-07-03 18:43:11 -06:00
Evan Bacon ed6b3a0ec0 Update detox.config.js 2021-07-03 18:30:03 -06:00
Evan Bacon efd3284272 remove webrtc and google chrome 2021-07-03 18:19:46 -06:00
Evan Bacon 46bc48726c Update App-e2e.ts 2021-07-03 18:00:57 -06:00
Evan Bacon ff47e492e4 Update App-e2e.ts 2021-07-03 17:40:47 -06:00
Evan Bacon be969274b9 Update app.json 2021-07-03 17:21:36 -06:00
Evan Bacon 359c1cfcb5 added missing resize mode 2021-07-03 17:15:17 -06:00
Evan Bacon 6c3fc5dff7 Update e2e.yml 2021-07-03 17:12:56 -06:00
Evan Bacon 99d3927680 Update e2e.yml 2021-07-03 17:06:40 -06:00
Evan Bacon 55482dae5f Create .ruby-version 2021-07-03 17:04:15 -06:00
Evan Bacon 395599abfa Added e2e tests 2021-07-03 16:59:15 -06:00
169 changed files with 2635 additions and 5060 deletions

No files matched your search

-1
View File
@@ -1 +0,0 @@
/* @EvanBacon
-81
View File
@@ -1,81 +0,0 @@
name: "\U0001F41B Expo Config Plugin Bug Report"
description: Report a reproducible bug with one of the Expo Config Plugins.
labels: bug
body:
- type: markdown
attributes:
value: >-
Thanks for taking the time to file a bug report! Please fill out this
form as completely as possible.
- type: markdown
attributes:
value: >-
If you leave out sections there is a high likelihood your issue will be
closed. If you have a question, not a bug report, please post it on our
[forums](https://forums.expo.dev/) instead.
- type: textarea
attributes:
label: Summary
description: Describe the issue in 1 or 2 sentences
placeholder: >-
Clearly describe what the expected behavior is vs. what is actually
happening. This should be as short as possible, while still
communicating all the necessary information. If your summary is just 'X
library/method isn't working', then you need to continue debugging
yourself and provide more information.
validations:
required: true
- type: dropdown
attributes:
label: Config Plugin
options:
- '@config-plugins/android-jsc-intl'
- '@config-plugins/detox'
- '@config-plugins/ffmpeg-kit-react-native'
- '@config-plugins/ios-stickers'
- '@config-plugins/react-native-adjust'
- '@config-plugins/react-native-ble-plx'
- '@config-plugins/react-native-blob-util'
- '@config-plugins/react-native-callkeep'
- '@config-plugins/react-native-dynamic-app-icon'
- '@config-plugins/react-native-google-cast'
- '@config-plugins/react-native-pdf'
- '@config-plugins/react-native-quick-actions'
- '@config-plugins/react-native-webrtc'
validations:
required: true
- type: dropdown
attributes:
label: What platform(s) does this occur on?
multiple: true
options:
- Android
- iOS
validations:
required: true
- type: input
attributes:
label: SDK Version
description: What version of the Expo SDK are you using?
- type: textarea
attributes:
label: Reproducible demo
description: >-
This should include as little code as possible, do not simply link your
entire project. If a reproducible demo is not provided, it is very
likely your issue will be closed. Read [here more
guidance](https://stackoverflow.com/help/mcve).
validations:
required: true
- type: markdown
attributes:
value: >-
Please make sure contributors can run your code and follow the steps
your provided in order to reproduce the bug.
- type: markdown
attributes:
value: >-
**Realize that it is up to you to debug your code and be as certain as
possible that the bug is with Expo, not with your own app.** [Here's an
excellent guide to debugging you can
follow](https://gist.github.com/brentvatne/5ac00cba0c70b7a06b89a56787d6bc4a).
-44
View File
@@ -1,44 +0,0 @@
---
blank_issues_enabled: false
contact_links:
- name: "\U0001F914 Question about an Expo Config Plugin"
about: >-
If you have a question about an Expo Config Plugin, please ask it on the
forums, discord, Twitter, or Stack Overflow.
url: 'https://forums.expo.io/'
- about: E2E tests and automation for mobile
name: "\U0001F4E6 detox issues"
url: 'https://github.com/wix/Detox/issues'
- about: FFmpeg Kit for React Native
name: "\U0001F4E6 ffmpeg-kit-react-native issues"
url: 'https://github.com/tanersener/ffmpeg-kit/issues'
- about: Adjust React Native SDK
name: "\U0001F4E6 react-native-adjust issues"
url: 'https://github.com/adjust/react_native_sdk/issues'
- about: React Native Bluetooth Low Energy library
name: "\U0001F4E6 react-native-ble-plx issues"
url: 'https://github.com/Polidea/react-native-ble-plx/issues'
- about: >-
A module provides upload, download, and files access API. Supports file
stream read/write for process large files.
name: "\U0001F4E6 react-native-blob-util issues"
url: 'https://github.com/RonRadtke/react-native-blob-util/issues'
- about: iOS 10 CallKit and Android ConnectionService Framework For React Native
name: "\U0001F4E6 react-native-callkeep issues"
url: 'https://github.com/react-native-webrtc/react-native-callkeep/issues'
- about: Programmatically change the app icon in React Native.
name: "\U0001F4E6 react-native-dynamic-app-icon issues"
url: 'https://github.com/idearockers/react-native-dynamic-app-icon/issues'
- about: React Native wrapper for the Google Cast SDK for iOS and Android
name: "\U0001F4E6 react-native-google-cast issues"
url: >-
https://github.com/react-native-google-cast/react-native-google-cast/issues
- about: 'A react native PDF view component, support ios and android platform'
name: "\U0001F4E6 react-native-pdf issues"
url: 'https://github.com/wonday/react-native-pdf/issues'
- about: A react-native interface for Touch 3D home screen quick actions
name: "\U0001F4E6 react-native-quick-actions issues"
url: 'https://github.com/jordanbyron/react-native-quick-actions/issues'
- about: WebRTC for React Native
name: "\U0001F4E6 react-native-webrtc issues"
url: 'https://github.com/react-native-webrtc/react-native-webrtc/issues'
-22
View File
@@ -1,22 +0,0 @@
name: "⭐️ Config Plugin Request"
description: "Suggest an idea for a new Expo Config Plugin."
labels: enhancement
body:
- type: markdown
attributes:
value: "This repo is used for publishing out-of-tree plugins that should eventually be upstreamed in a particular package. If the plugin is a utility or used to improve some particular workflow i.e. updates version numbers, than it's probably better suited for a personal repo or utility package."
- type: input
attributes:
label: Library
description: What package does this Config Plugin configure.
placeholder: URL to a React Native package.
validations:
required: true
- type: textarea
attributes:
label: Summary
description: Add some info on why this integration is important.
- type: textarea
attributes:
label: Any existing examples?
placeholder: Have you already created a local plugin for the requested library?
-24
View File
@@ -1,24 +0,0 @@
<!--
🚨 We use semantic release (a bot publishes everything automatically)
🚨 so please use conventional commit style for the PR title:
🚨 https://www.conventionalcommits.org/en/v1.0.0/
🚨 Example: feat(detox): add new step
-->
# Why
<!--
Please describe the motivation for this PR, and link to relevant GitHub issues, forums posts, or feature requests.
-->
# How
<!--
How did you build this feature or fix this bug and why?
-->
# Test Plan
<!--
Please describe how you tested this change and how a reviewer could reproduce your test, especially if this PR does not include automated tests! If possible, please also provide terminal output and/or screenshots demonstrating your test/reproduction.
-->
+155
View File
@@ -0,0 +1,155 @@
name: E2E Test
on:
workflow_dispatch: {}
push:
branches: [master]
paths:
- .github/workflows/ios.yml
- apps/app/**
- packages/**
- yarn.lock
pull_request:
paths:
- .github/workflows/ios.yml
- apps/app/**
- packages/**
- yarn.lock
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
cancel-in-progress: true
jobs:
ios:
runs-on: macos-latest
steps:
- name: 👀 Checkout
uses: actions/checkout@v2
with:
submodules: true
- name: 🍺 Install required tools
run: |
brew tap wix/brew
brew install applesimutils
brew install watchman
echo "$(pwd)/bin" >> $GITHUB_PATH
- name: 💎 Setup Ruby and install gems
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: ♻️ Restore workspace node modules
uses: actions/cache@v2
id: node-modules-cache
with:
path: |
# See "workspaces" → "packages" in the root package.json for the source of truth of
# which node_modules are affected by the root yarn.lock
node_modules
apps/*/node_modules
packages/*/node_modules
key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}
- name: 🧶 Install node modules in root dir
run: yarn install --frozen-lockfile
- name: ♻️ Restore apps/app/ios/Pods from cache
uses: actions/cache@v2
id: pods-cache
with:
path: "apps/app/ios/Pods"
key: ${{ runner.os }}-app-pods-${{ hashFiles('apps/app/ios/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-app-pods-
- run: yarn global add expo-cli
- name: 🔨 Prebuild
run: expo prebuild -p ios
working-directory: apps/app
- name: 🕵️ Debug CocoaPods lockfiles
run: git diff Podfile.lock Pods/Manifest.lock
working-directory: apps/app/ios
continue-on-error: true
- name: ⚛️ Display React Native config
run: yarn react-native config
working-directory: apps/app
- name: 🌳 Display pod environment
run: pod env
working-directory: apps/app/ios
- name: 🥥 Install pods in apps/app/ios
run: pod install
if: steps.pods-cache.outputs.cache-hit != 'true' || hashFiles('apps/app/ios/Podfile.lock') != hashFiles('apps/app/ios/Pods/Manifest.lock')
working-directory: apps/app/ios
- name: Clean Detox
run: yarn detox:clean
working-directory: apps/app
- name: Build iOS project for Detox
run: yarn build:ios-release
working-directory: apps/app
timeout-minutes: 30
- name: Run tests
run: yarn test:ios-release
working-directory: apps/app
- name: Store images of build failures
if: always()
uses: actions/upload-artifact@v2
with:
name: app-artifacts
path: apps/app/artifacts
android:
runs-on: macos-latest
steps:
- name: 👀 Checkout
uses: actions/checkout@v2
with:
submodules: true
- name: 🍺 Install required tools
run: |
brew install watchman
echo "$(pwd)/bin" >> $GITHUB_PATH
- name: ♻️ Restore workspace node modules
uses: actions/cache@v2
id: node-modules-cache
with:
path: |
# See "workspaces" → "packages" in the root package.json for the source of truth of
# which node_modules are affected by the root yarn.lock
node_modules
apps/*/node_modules
packages/*/node_modules
key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}
- name: 🧶 Install node modules in root dir
run: yarn install --frozen-lockfile
- uses: actions/cache@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-v20210625-${{ hashFiles('android/*.gradle*') }}
restore-keys: |
${{ runner.os }}-gradle-v20210625
- run: yarn global add expo-cli
- name: 🔨 Prebuild
run: expo prebuild -p android
working-directory: apps/app
- name: ⚛️ Display React Native config
run: yarn react-native config
working-directory: apps/app
- name: Clean Detox
run: yarn detox:clean
working-directory: apps/app
- name: Build Android project for Detox
run: yarn build:android-release
working-directory: apps/app
timeout-minutes: 35
env:
GRADLE_OPTS: "-Dorg.gradle.internal.http.connectionTimeout=180000 -Dorg.gradle.internal.http.socketTimeout=180000 -Dorg.gradle.internal.network.retry.max.attempts=18 -Dorg.gradle.internal.network.retry.initial.backOff=2000"
- name: Run tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
avd-name: app
script: yarn test:android-release
working-directory: ./apps/app
- name: Store images of build failures
if: always()
uses: actions/upload-artifact@v2
with:
name: app-artifacts
path: apps/app/artifacts
+1 -1
View File
@@ -2,7 +2,7 @@ name: Check Markdown links
on:
workflow_dispatch: {}
push:
branches: [main]
branches: [master]
paths:
- .github/workflows/lint-md.yml
- "**.md"
-37
View File
@@ -1,37 +0,0 @@
name: Release
# https://github.com/bent10/monorepo-starter/blob/main/docs/recipes/release-automation.md
on:
push:
branches:
- main
jobs:
release:
name: Releasing
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/cache@v2
with:
path: "**/node_modules"
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
- run: yarn install --frozen-lockfile --check-files
- run: yarn lerna run prepare --stream
# If the dry run fails then it will prevent us from automatically breaking the repo.
- name: Semantic release (dry run)
run: npx multi-semantic-release --dry-run --ignore-private-packages
env:
GITHUB_TOKEN: ${{ github.token }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Semantic release
# use `--ignore-packages` to ignore packages on bumping process
# npx multi-semantic-release --ignore-packages=packages/a/**,packages/b/**
run: npx multi-semantic-release --ignore-private-packages
env:
GITHUB_TOKEN: ${{ github.token }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+1 -2
View File
@@ -1,7 +1,7 @@
name: Test Packages
on:
push:
branches: [main]
branches: [master]
pull_request:
types: [opened, synchronize]
@@ -37,7 +37,6 @@ jobs:
# Manually add packages here
detox,
ffmpeg-kit-react-native,
ios-stickers,
react-native-ble-plx,
react-native-blob-util,
react-native-google-cast,
+1 -5
View File
@@ -51,8 +51,4 @@ xcuserdata
# VSCode
.history/
# Ignore build folders
packages/*/build/**
packages/*/plugin/build/**
packages/@*/*/build/**
# packages/*/build/
-62
View File
@@ -1,62 +0,0 @@
// From @byCedric https://github.com/expo/expo-github-action/blob/main/.releaserc.js
const rules = [
{ type: "feat", release: "minor", title: "Features" },
{ type: "fix", release: "patch", title: "Bug Fixes" },
{ type: "test", release: "patch", title: "Tests" },
{ type: "ci", release: "patch", title: "Continuous Integration" },
{ type: "refactor", release: "patch", title: "Code Refactoring" },
{ type: "chore", release: "patch", title: "Other chores" },
{ type: "docs", release: "patch", title: "Documentation changes" },
];
// Simple mapping to order the commit groups
const sortMap = Object.fromEntries(
rules.map((rule, index) => [rule.title, index])
);
module.exports = {
branches: ["main"],
tagFormat: "${version}",
repositoryUrl: "https://github.com/expo/config-plugins.git",
plugins: [
[
"@semantic-release/commit-analyzer",
{
preset: "conventionalcommits",
releaseRules: [
{ breaking: true, release: "major" },
{ revert: true, release: "patch" },
].concat(
rules.map(({ type, release, breaking }) => ({
type,
release,
breaking,
}))
),
},
],
[
"@semantic-release/release-notes-generator",
{
preset: "conventionalcommits",
presetConfig: {
types: rules.map(({ type, title }) => ({ type, section: title })),
},
writerOpts: {
commitGroupsSort: (a, z) => sortMap[a.title] - sortMap[z.title],
},
},
],
"@semantic-release/changelog",
"@semantic-release/npm",
[
"@semantic-release/git",
{
message: "chore: ${nextRelease.version}\n\n${nextRelease.notes}",
assets: ["package.json", "CHANGELOG.md", "build/*"],
},
],
"@semantic-release/github",
],
};
+1
View File
@@ -0,0 +1 @@
2.7.0
-15
View File
@@ -1,15 +0,0 @@
# Contributing to Expo Config Plugins
## Submitting a pull request
To submit a pull request:
1. Fork the [repository](https://github.com/expo/config-plugins) and create a feature branch. (Existing contributors can create feature branches without forking. Prefix the branch name with `@your-github-username/`.)
2. Use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) including in the PR tile.
3. Fill out the entire PR template. Ensure your code is tested locally and has continuous tests in CI.
4. Make sure all tests pass on GitHub Actions.
5. Wait for a review and adjust the code if necessary.
## Publishing a release
All publishing should be handled automatically whenever code is merged to `main`.
+2 -3
View File
@@ -1,9 +1,8 @@
// export { default } from './src/react-native-quick-actions/App';
// export { default } from './src/react-native-pdf/App';
// export { default } from './src/react-native-dynamic-app-icon/App';
// export { default } from './src/react-native-google-cast/App';
// export { default } from './src/detox/App';
export { default } from './src/detox/App';
// export { default } from './src/react-native-ble-plx/App';
export { default } from './src/react-native-webrtc/App';
// export { default } from './src/react-native-webrtc/App';
// export { default } from './src/android-jsc-intl/App';
// export { default } from './src/ffmpeg-kit-react-native/App';
-66
View File
@@ -1,66 +0,0 @@
### @expo/app [1.0.1](https://github.com/expo/config-plugins/compare/@expo/[email protected]...@expo/[email protected]) (2022-03-15)
### Bug Fixes
* **ci:** use correct internal versions ([ab8076a](https://github.com/expo/config-plugins/commit/ab8076adf51e9ba0439eba60b153d729a0996b8d))
### Dependencies
* **@config-plugins/android-jsc-intl:** upgraded to 1.0.1
* **@config-plugins/detox:** upgraded to 1.0.1
* **@config-plugins/react-native-adjust:** upgraded to 1.0.0
* **@config-plugins/react-native-ble-plx:** upgraded to 1.0.0
* **@config-plugins/react-native-blob-util:** upgraded to 1.0.1
* **@config-plugins/react-native-branch:** upgraded to 1.0.0
* **@config-plugins/react-native-callkeep:** upgraded to 1.0.0
* **@config-plugins/react-native-dynamic-app-icon:** upgraded to 1.0.0
* **@config-plugins/react-native-google-cast:** upgraded to 1.0.0
* **@config-plugins/react-native-pdf:** upgraded to 1.0.0
* **@config-plugins/react-native-quick-actions:** upgraded to 1.0.0
* **@config-plugins/react-native-webrtc:** upgraded to 1.0.0
## @expo/app 1.0.0 (2022-03-15)
### Features
* create react-native-branch plugin ([0b06baa](https://github.com/expo/config-plugins/commit/0b06baa2b486c5e02d433a4ac785960934f403b9))
### Bug Fixes
* respect old config from expo-branch ([d0e0186](https://github.com/expo/config-plugins/commit/d0e018601c09c0e92191a4eb2998ab0e6fa1c6ec))
### Other chores
* added start-metro script ([4a7d707](https://github.com/expo/config-plugins/commit/4a7d707b200a3e499d9d71caf49ad4fc1d0a89e0))
* update script ([dcf61a9](https://github.com/expo/config-plugins/commit/dcf61a9b9542851095954d84c9054c97c5400dc9))
* upgrade to latest react-native-branch ([df98474](https://github.com/expo/config-plugins/commit/df98474d79ed139b42ddd698d13100160c656c26))
### Documentation changes
* add android-jsc-intl example ([d96c0b2](https://github.com/expo/config-plugins/commit/d96c0b2888da3808d7c4e2dd7993129711ba717d))
### Dependencies
* **@config-plugins/android-jsc-intl:** upgraded to 1.0.0
* **@config-plugins/detox:** upgraded to 1.0.0
* **@config-plugins/ffmpeg-kit-react-native:** upgraded to 1.0.0
* **@config-plugins/ios-stickers:** upgraded to 1.0.0
* **@config-plugins/react-native-adjust:** upgraded to 1.0.0
* **@config-plugins/react-native-ble-plx:** upgraded to 1.0.0
* **@config-plugins/react-native-blob-util:** upgraded to 1.0.0
* **@config-plugins/react-native-branch:** upgraded to 1.0.0
* **@config-plugins/react-native-callkeep:** upgraded to 1.0.0
* **@config-plugins/react-native-dynamic-app-icon:** upgraded to 1.0.0
* **@config-plugins/react-native-google-cast:** upgraded to 1.0.0
* **@config-plugins/react-native-pdf:** upgraded to 1.0.0
* **@config-plugins/react-native-quick-actions:** upgraded to 1.0.0
* **@config-plugins/react-native-webrtc:** upgraded to 1.0.0
+6 -70
View File
@@ -13,89 +13,25 @@
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": ["**/*"],
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true,
"bundleIdentifier": "dev.bacon.app",
"config": {
"branch": {
"apiKey": "key_live_f9f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8"
}
}
"bundleIdentifier": "com.bacon.app"
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#FFFFFF"
},
"config": {
"branch": {
"apiKey": "key_live_f9f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8"
}
},
"package": "com.bacon.app"
},
"web": {
"favicon": "./assets/favicon.png"
},
"plugins": [
[
"@config-plugins/react-native-dynamic-app-icon",
[
"./assets/icons/spring.png",
"./assets/icons/summer.png",
"./assets/icons/autumn.png",
"./assets/icons/fall.png",
"./assets/icons/solstice.png"
]
],
[
"@config-plugins/react-native-quick-actions",
[
{
"title": "Take Photo",
"type": "photo",
"iconType": "UIApplicationShortcutIconTypeCapturePhoto"
}
]
],
[
"@config-plugins/ffmpeg-kit-react-native",
{
"package": "min"
}
],
"@config-plugins/detox",
"@config-plugins/react-native-adjust",
"@config-plugins/react-native-branch",
"@config-plugins/react-native-google-cast",
"@config-plugins/react-native-ble-plx",
"@config-plugins/react-native-webrtc",
"@config-plugins/react-native-callkeep",
"@config-plugins/react-native-blob-util",
"@config-plugins/react-native-pdf",
"@config-plugins/android-jsc-intl",
[
"@config-plugins/ios-stickers",
{
"name": "Stickers",
"icon": "./assets/imessage-icon.png",
"columns": 4,
"stickers": [
"./assets/stickers/annoyed.png",
"./assets/stickers/cuddle.png",
"./assets/stickers/crazy.png",
"./assets/stickers/cant.png",
"./assets/stickers/donno.png",
"./assets/stickers/cozzy.png",
"./assets/stickers/dork.png",
"./assets/stickers/focus.png",
"./assets/stickers/avocool.png",
"./assets/stickers/coder-girl.png",
"./assets/stickers/teapot.png"
]
}
]
"@config-plugins/detox"
]
}
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
const iosName = "app";
const emulator = "Pixel_3a_API_30";
const simulator = "iPhone 13 Pro";
const emulator = process.env.CI ? "app" : "Pixel_3a_API_30";
const simulator = "iPhone 11";
const derivedDataPath = "ios/build";
const sdk = "iphonesimulator";
+7 -14
View File
@@ -1,4 +1,4 @@
import { by, device, element, expect } from "detox";
import { device } from "detox";
import * as path from "path";
import { createCapture } from "../lib";
@@ -6,7 +6,10 @@ import { createCapture } from "../lib";
const projectRoot = path.resolve(__dirname, "../../");
// https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html
const languages = ["en-US", "nl-NL", "zh-CN"];
const languages = [
"en-US",
// "nl-NL", "zh-CN"
];
for (const locale of languages) {
const { captureAsync, resetAppAsync } = createCapture({
@@ -21,18 +24,8 @@ for (const locale of languages) {
await device.reloadReactNative();
});
it("should have welcome screen", async () => {
await expect(element(by.id("welcome"))).toBeVisible();
await captureAsync();
});
xit("should show hello screen after tap", async () => {
await element(by.id("hello_button")).tap();
await captureAsync();
});
xit("should show world screen after tap", async () => {
await element(by.id("world_button")).tap();
it("should load app", async () => {
// await expect(element(by.id("welcome"))).toBeVisible();
await captureAsync();
});
});
+16 -6
View File
@@ -4,10 +4,19 @@ import * as path from "path";
import { setStatusBar } from "./setStatusBar";
export function getOutputDir(projectRoot: string, locale: string) {
return path.resolve(
projectRoot,
`meta/screenshots/${device.getPlatform()}/${locale}/`
);
const store = device.getPlatform() === "ios" ? "apple" : "google";
return path.resolve(projectRoot, `merch/${store}/preview/${locale}/`);
}
function resolveName(str: string) {
if (str && device.getPlatform() === "ios" && typeof str === "string") {
// Convert a name like: `E9EA2214-6B88-4223-9872-8232168088FB {"type":"iPhone 12 Pro Max"}`
// to `iPhone 12 Pro Max`
// Name is important for screenshot sorting
const match = str.match(/"type"\s?:\s?"(.*)"}/i)?.[1];
return match || str;
}
return str;
}
export async function takeScreenshotAsync({
@@ -27,8 +36,9 @@ export async function takeScreenshotAsync({
if (index == null) {
index = fs.readdirSync(outputDir).length;
}
const deviceName = resolveName(device.name);
const name = `APP_${device.name}_${index}`.toUpperCase();
const name = `APP_${deviceName}-${index}`;
const imgPath = path.resolve(outputDir, `${name}.png`);
const imagePath = await device.takeScreenshot(name);
await fs.promises.copyFile(imagePath, imgPath);
@@ -58,7 +68,7 @@ export function createCapture({
clearAsync,
async resetAppAsync() {
// Clear old screen shots
await clearAsync();
// await clearAsync();
// configure status bars
setStatusBar();
+1
View File
@@ -1,3 +1,4 @@
import "react-native-gesture-handler";
import { registerRootComponent } from "expo";
import Constants from "expo-constants";
+15 -35
View File
@@ -3,6 +3,7 @@
"main": "./index.js",
"version": "1.0.0",
"scripts": {
"detox:clean": "detox clean-framework-cache && detox build-framework-cache",
"build:ios": "detox build -c ios.sim.debug",
"test:ios": "detox test -c ios.sim.debug",
"e2e:ios": "npm run build:ios && npm run test:ios",
@@ -13,7 +14,7 @@
"test:android": "detox test -c android.emu.debug",
"e2e:android": "npm run build:android && npm run test:android",
"build:android-release": "detox build -c android.emu.release",
"test:android-release": "detox test -c android.emu.release",
"test:android-release": "detox test -c android.emu.release --headless",
"e2e:android-release": "npm run build:android-release && npm run test:android-release",
"clean:android": "pushd android && ./gradlew clean && popd",
"start": "expo start --dev-client",
@@ -21,48 +22,27 @@
"android": "expo run:android"
},
"dependencies": {
"@config-plugins/android-jsc-intl": "*",
"@config-plugins/detox": "*",
"@config-plugins/ffmpeg-kit-react-native": "*",
"@config-plugins/ios-stickers": "*",
"@config-plugins/react-native-adjust": "*",
"@config-plugins/react-native-ble-plx": "*",
"@config-plugins/react-native-blob-util": "*",
"@config-plugins/react-native-branch": "*",
"@config-plugins/react-native-callkeep": "*",
"@config-plugins/react-native-dynamic-app-icon": "*",
"@config-plugins/react-native-google-cast": "*",
"@config-plugins/react-native-pdf": "*",
"@config-plugins/react-native-quick-actions": "*",
"@config-plugins/react-native-webrtc": "*",
"expo": "^44.0.0",
"expo-localization": "~12.0.0",
"expo-splash-screen": "~0.14.0",
"expo-status-bar": "~1.2.0",
"expo-updates": "~0.11.2",
"fbjs": "^0.8.18",
"@config-plugins/detox": "^1.0.0",
"expo": "^43.0.0",
"expo-localization": "~11.0.0",
"expo-splash-screen": "~0.13.5",
"expo-status-bar": "~1.1.0",
"expo-updates": "~0.10.13",
"ffmpeg-kit-react-native": "^4.5.0",
"i18n-js": "^3.8.0",
"luxon": "^1.27.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-adjust": "^4.29.5",
"react-native-blob-util": "^0.13.17",
"react-native-callkeep": "^4.2.0",
"react-native-branch": "^5.3.0",
"react-native-dynamic-app-icon": "^1.1.0",
"react-native-google-cast": "^4.1.2",
"react-native-pdf": "^6.4.0",
"react-native-quick-actions": "^0.3.13",
"react-native-reanimated": "~2.2.0",
"react-native-safe-area-context": "3.3.2",
"react-native-web": "0.17.1",
"react-native-webrtc": "^1.89.3"
"react-native-screens": "~3.8.0",
"react-dom": "17.0.1",
"react-native-gesture-handler": "~1.10.2",
"react-native-web": "0.17.1"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@babel/plugin-syntax-jsx": "^7.16.0",
"@expo/metro-config": "~0.3.7",
"@expo/metro-config": "~0.3.0",
"@expo/xcpretty": "^4.1.0",
"@types/jest": "^26.0.19",
"@types/luxon": "^1.27.1",
@@ -70,7 +50,7 @@
"@types/react-native": "~0.64.12",
"babel-jest": "~25.2.6",
"detox": "^19.1.0",
"jest": "^26.6.3",
"jest": "^26.5.0",
"jest-circus": "^26.5.2",
"ts-jest": "^26.4.4",
"typescript": "~4.3.5"
-27
View File
@@ -1,27 +0,0 @@
import React from "react";
import { SafeAreaView, Text, StyleSheet } from "react-native";
import { Adjust, AdjustConfig } from "react-native-adjust";
export default function App() {
React.useEffect(() => {
const adjustConfig = new AdjustConfig(
"APP_TOKEN",
AdjustConfig.EnvironmentSandbox
);
Adjust.create(adjustConfig);
}, []);
return (
<SafeAreaView style={styles.container}>
<Text>Adjust SDK</Text>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
});
+1 -18
View File
@@ -1,13 +1,9 @@
{
"name": "@config-plugins/repo",
"version": "1.0.0",
"private": true,
"scripts": {
"postinstall": "expo-yarn-workspaces check-workspace-dependencies",
"gen": "ts-node ./scripts/generate-plugin.ts",
"update-issue-template": "ts-node ./scripts/gh-issues-config.ts",
"start": "lerna run build --parallel -- --watch",
"prepare": "lerna run prepare --parallel"
"start": "lerna run build --parallel -- --watch"
},
"workspaces": [
"apps/*",
@@ -15,21 +11,8 @@
],
"devDependencies": {
"@expo/package-manager": "^0.0.43",
"@semantic-release/changelog": "^6.0.1",
"@semantic-release/commit-analyzer": "^9.0.2",
"@semantic-release/error": "^3.0.0",
"@semantic-release/exec": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@semantic-release/github": "^8.0.2",
"@semantic-release/npm": "^9.0.1",
"@semantic-release/release-notes-generator": "^10.0.3",
"conventional-changelog-conventionalcommits": "^4.6.3",
"multi-semantic-release": "^2.11.1",
"semantic-release": "^19.0.2",
"@types/js-yaml": "^4.0.5",
"@types/prompts": "^2.0.13",
"expo-yarn-workspaces": "^1.5.1",
"js-yaml": "^4.1.0",
"lerna": "3.4.1",
"prettier": "^2.2.1",
"prompts": "^2.4.1",
-43
View File
@@ -1,43 +0,0 @@
### @config-plugins/android-jsc-intl [1.0.3](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-22)
### Other chores
* git ignore build folders ([#59](https://github.com/expo/config-plugins/issues/59)) ([d6050be](https://github.com/expo/config-plugins/commit/d6050beb2a5c68dc59287c27ec388c2002ec7904))
### @config-plugins/android-jsc-intl [1.0.2](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-16)
### Continuous Integration
* fix versions [skip ci] ([#53](https://github.com/expo/config-plugins/issues/53)) ([5de4ae3](https://github.com/expo/config-plugins/commit/5de4ae3e6182c32b7aa24d70ccd23a11663bb089))
### @config-plugins/android-jsc-intl [1.0.1](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-15)
### Bug Fixes
* **ci:** use correct internal versions ([ab8076a](https://github.com/expo/config-plugins/commit/ab8076adf51e9ba0439eba60b153d729a0996b8d))
## @config-plugins/android-jsc-intl 1.0.0 (2022-03-15)
### Features
* Intl support for android via withAndroidJscIntl ([eb6642c](https://github.com/expo/config-plugins/commit/eb6642c0e7b37d6d9baf196ec40cc520f559e665))
### Bug Fixes
* remove createPluginOnce ([68cf1c0](https://github.com/expo/config-plugins/commit/68cf1c07b2c48249cbbd0732668ea95455636a0b))
* run expo prepare ([8d364ed](https://github.com/expo/config-plugins/commit/8d364ed99ea4b0e0e3af73dbcc780819bf55d6c2))
### Other chores
* upgrade @expo/config-plugins ([#49](https://github.com/expo/config-plugins/issues/49)) ([119e31e](https://github.com/expo/config-plugins/commit/119e31edf110409272ace750f02d651124e1a22d))
### Documentation changes
* clarify readme ([b524633](https://github.com/expo/config-plugins/commit/b5246338cb37ae41d138bc6253703b0d438fc3e3))
+1 -1
View File
@@ -6,7 +6,7 @@ Adding this plugin lets you use `Intl` in your Android app, without using Hermes
## Expo installation
> Tested against Expo SDK 44
> Tested against Expo SDK 43
This package cannot be used in the "Expo Go" app because [it requires custom native code](https://docs.expo.io/workflow/customizing/).
+3 -8
View File
@@ -1,15 +1,10 @@
{
"name": "@config-plugins/android-jsc-intl",
"version": "1.0.3",
"version": "0.0.1",
"description": "Config plugin for android-jsc-intl package",
"main": "build/withAndroidJscIntl.js",
"types": "build/withAndroidJscIntl.d.ts",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/expo/config-plugins.git",
"directory": "packages/android-jsc-intl"
},
"scripts": {
"build": "expo-module build",
"clean": "expo-module clean",
@@ -31,9 +26,9 @@
"preset": "expo-module-scripts"
},
"dependencies": {
"@expo/config-plugins": "^4.1.0"
"@expo/config-plugins": "^4.0.7"
},
"devDependencies": {
"expo-module-scripts": "^2.0.0"
}
}
}
-15
View File
@@ -1,15 +0,0 @@
### @config-plugins/detox [1.2.2](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-16)
### Bug Fixes
* **detox:** use improved xml generation ([#47](https://github.com/expo/config-plugins/issues/47)) ([6324eb0](https://github.com/expo/config-plugins/commit/6324eb041b3b4eb2318c0a1ea0297e3b7bf28f7c))
### @config-plugins/detox [1.2.1](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-16)
### Continuous Integration
* fix versions [skip ci] ([#53](https://github.com/expo/config-plugins/issues/53)) ([5de4ae3](https://github.com/expo/config-plugins/commit/5de4ae3e6182c32b7aa24d70ccd23a11663bb089))
### @config-plugins/detox 1.2.0
+3 -27
View File
@@ -8,15 +8,14 @@ Ensure you use versions that work together!
| `expo` | `detox` | `@config-plugins/detox` |
| ------ | ------- | ----------------------- |
| 44.0.0 | 19.1.0 | ^1.1.0 |
| 43.0.0 | 19.1.0 | ~1.0.0 |
| 40.0.0 | 18.6.2 | ~0.0.0 |
| 43.0.0 | 19.1.0 | 1.0.0 |
| 40.0.0 | 18.6.2 | 0.0.0 |
Most notably, the minimum required Kotlin version changed from `1.3.50` in SDK 40 to `1.4.21` in SDK 43. Failure to use the correct versioning could result in Android build errors like `Execution failed for task ':react-native-screens:compileDebugKotlin'.` or `Execution failed for task ':expo:compileDebugKotlin'.`.
### Add the package to your npm dependencies
> Tested against Expo SDK 44
> Tested against Expo SDK 43
```
yarn add detox @config-plugins/detox
@@ -53,29 +52,6 @@ Detox is an end-to-end (e2e) testing library for iOS and Android. You can use it
- Generate the native code `expo prebuild`
- Run `yarn detox init -r jest`
## API
The plugin provides props for extra customization. Every time you change the props or plugins, you'll need to rebuild (and `prebuild`) the native app. If no extra properties are added, defaults will be used.
- `skipProguard` (_boolean_): Disable adding proguard minification to the `app/build.gradle`. Defaults to `false`.
- `subdomains` (_string[] | '\*'_): Hostnames to add to the network security config. Pass `'*'` to allow all domains. Defaults to `['10.0.2.2', 'localhost']`.
`app.config.js`
```ts
export default {
plugins: [
[
"@config-plugins/detox",
{
skipProguard: false,
subdomains: ["10.0.2.2", "localhost"],
},
],
],
};
```
## FAQ
If the following commands fail, you can get better debug info by running a subset command:
+17
View File
@@ -0,0 +1,17 @@
import { ConfigPlugin } from "@expo/config-plugins";
declare const _default: ConfigPlugin<void | {
/**
* Disable adding proguard minification to the `app/build.gradle`.
*
* @default false
*/
skipProguard?: boolean | undefined;
/**
* Subdomains to add to the network security config.
* Pass `['10.0.3.2', 'localhost']` to use Genymotion emulators instead of Google emulators.
*
* @default ['10.0.2.2', 'localhost'] // (Google emulators)
*/
subdomains?: string[] | undefined;
}>;
export default _default;
+42
View File
@@ -0,0 +1,42 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const config_plugins_1 = require("@expo/config-plugins");
const withDetoxProjectGradle_1 = __importDefault(require("./withDetoxProjectGradle"));
const withDetoxTestAppGradle_1 = __importDefault(require("./withDetoxTestAppGradle"));
const withDetoxTestClass_1 = require("./withDetoxTestClass");
const withKotlinGradle_1 = __importDefault(require("./withKotlinGradle"));
const withNetworkSecurityConfig_1 = require("./withNetworkSecurityConfig");
const withProguardGradle_1 = __importDefault(require("./withProguardGradle"));
const withDetox = (config, { skipProguard, subdomains } = {}) => {
return config_plugins_1.withPlugins(config, [
// 3.
withDetoxProjectGradle_1.default,
// 3.
withDetoxTestAppGradle_1.default,
// 4.
[
withKotlinGradle_1.default,
// Minimum version of Kotlin required to work with expo packages in SDK 43
"1.4.21",
],
// 5.
withDetoxTestClass_1.withDetoxTestClass,
// 6.
[withNetworkSecurityConfig_1.withNetworkSecurityConfigManifest, { subdomains }],
// 7.
!skipProguard && withProguardGradle_1.default,
].filter(Boolean));
};
let pkg = {
name: "detox",
// UNVERSIONED...
};
try {
const detoxPkg = require("detox/package.json");
pkg = detoxPkg;
}
catch (_a) { }
exports.default = config_plugins_1.createRunOncePlugin(withDetox, pkg.name, pkg.version);
+9
View File
@@ -0,0 +1,9 @@
import { ConfigPlugin } from "@expo/config-plugins";
import { MergeResults } from "@expo/config-plugins/build/utils/generateCode";
/**
* [Step 3](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#3-add-the-native-detox-dependency) Add detox to the project build.gradle.
* @param config
*/
declare const withDetoxProjectGradle: ConfigPlugin;
export declare function addDetoxImport(src: string): MergeResults;
export default withDetoxProjectGradle;
+59
View File
@@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.addDetoxImport = void 0;
const config_plugins_1 = require("@expo/config-plugins");
const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
// Because we need the package to be added AFTER the React and Google maven packages, we create a new allprojects.
// It's ok to have multiple allprojects.repositories, so we create a new one since it's cheaper than tokenizing
// the existing block to find the correct place to insert our camera maven.
const gradleMaven = [
`def detoxMavenPath = new File(["node", "--print", "require.resolve('detox/package.json')"].execute(null, rootDir).text.trim(), "../Detox-android")`,
`allprojects { repositories { maven { url(detoxMavenPath) } } }`,
].join("\n");
/**
* [Step 3](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#3-add-the-native-detox-dependency) Add detox to the project build.gradle.
* @param config
*/
const withDetoxProjectGradle = (config) => {
return config_plugins_1.withProjectBuildGradle(config, (config) => {
if (config.modResults.language === "groovy") {
config.modResults.contents = addDetoxImport(config.modResults.contents).contents;
}
else {
throw new Error("Cannot add Detox maven gradle because the project build.gradle is not groovy");
}
return config;
});
};
function addDetoxImport(src) {
return appendContents({
tag: "detox-import",
src,
newSrc: gradleMaven,
comment: "//",
});
}
exports.addDetoxImport = addDetoxImport;
// Fork of config-plugins mergeContents, but appends the contents to the end of the file.
function appendContents({ src, newSrc, tag, comment, }) {
const header = generateCode_1.createGeneratedHeaderComment(newSrc, tag, comment);
if (!src.includes(header)) {
// Ensure the old generated contents are removed.
const sanitizedTarget = generateCode_1.removeGeneratedContents(src, tag);
const contentsToAdd = [
// @something
header,
// contents
newSrc,
// @end
`${comment} @generated end ${tag}`,
].join("\n");
return {
contents: sanitizedTarget !== null && sanitizedTarget !== void 0 ? sanitizedTarget : src + contentsToAdd,
didMerge: true,
didClear: !!sanitizedTarget,
};
}
return { contents: src, didClear: false, didMerge: false };
}
exports.default = withDetoxProjectGradle;
+12
View File
@@ -0,0 +1,12 @@
import { ConfigPlugin } from "@expo/config-plugins";
/**
* [Step 3](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#3-add-the-native-detox-dependency). Add the Native Detox dependency.
*
* 1. Add `androidTestImplementation` to the app/build.gradle
* 2. Add `testInstrumentationRunner` to the app/build.gradle
* @param config
*/
declare const withDetoxTestAppGradle: ConfigPlugin;
export declare function setGradleAndroidTestImplementation(buildGradle: string): string;
export declare function addDetoxDefaultConfigBlock(buildGradle: string): string;
export default withDetoxTestAppGradle;
+44
View File
@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.addDetoxDefaultConfigBlock = exports.setGradleAndroidTestImplementation = void 0;
const config_plugins_1 = require("@expo/config-plugins");
/**
* [Step 3](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#3-add-the-native-detox-dependency). Add the Native Detox dependency.
*
* 1. Add `androidTestImplementation` to the app/build.gradle
* 2. Add `testInstrumentationRunner` to the app/build.gradle
* @param config
*/
const withDetoxTestAppGradle = (config) => {
return config_plugins_1.withAppBuildGradle(config, (config) => {
if (config.modResults.language === "groovy") {
config.modResults.contents = setGradleAndroidTestImplementation(config.modResults.contents);
config.modResults.contents = addDetoxDefaultConfigBlock(config.modResults.contents);
}
else {
throw new Error("Cannot add Detox maven gradle because the project build.gradle is not groovy");
}
return config;
});
};
function setGradleAndroidTestImplementation(buildGradle) {
const pattern = /androidTestImplementation\(\'com.wix:detox:\+\'\)/g;
if (buildGradle.match(pattern)) {
return buildGradle;
}
return buildGradle.replace(/dependencies\s?{/, `dependencies {
androidTestImplementation('com.wix:detox:+')`);
}
exports.setGradleAndroidTestImplementation = setGradleAndroidTestImplementation;
function addDetoxDefaultConfigBlock(buildGradle) {
const pattern = /detox-plugin-default-config/g;
if (buildGradle.match(pattern)) {
return buildGradle;
}
return buildGradle.replace(/defaultConfig\s?{/, `defaultConfig {
// detox-plugin-default-config
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'`);
}
exports.addDetoxDefaultConfigBlock = addDetoxDefaultConfigBlock;
exports.default = withDetoxTestAppGradle;
+5
View File
@@ -0,0 +1,5 @@
import { ConfigPlugin } from "@expo/config-plugins";
/**
* [Step 5](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#5-create-a-detox-test-class). Create `DetoxTest.java`
*/
export declare const withDetoxTestClass: ConfigPlugin;
+88
View File
@@ -0,0 +1,88 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.withDetoxTestClass = void 0;
const config_plugins_1 = require("@expo/config-plugins");
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const assert_1 = __importDefault(require("assert"));
/**
* Copied from the [official template file](https://github.com/wix/Detox/blob/master/examples/demo-react-native/android/app/src/androidTest/java/com/example/DetoxTest.java).
*
* @param androidPackage
*/
function getTemplateFile(androidPackage) {
// This shouldn't change in standard Expo apps.
// Replace 'MainActivity' with the value of android:name entry in
// <activity> in AndroidManifest.xml
const mainApplicationClassName = "MainActivity";
return `package ${androidPackage};
import com.wix.detox.Detox;
import com.wix.detox.config.DetoxConfig;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class DetoxTest {
@Rule
public ActivityTestRule<${mainApplicationClassName}> mActivityRule = new ActivityTestRule<>(${mainApplicationClassName}.class, false, false);
@Test
public void runDetoxTests() {
DetoxConfig detoxConfig = new DetoxConfig();
detoxConfig.idlePolicyConfig.masterTimeoutSec = 90;
detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60;
detoxConfig.rnContextLoadTimeoutSec = (${androidPackage}.BuildConfig.DEBUG ? 180 : 60);
Detox.runTests(mActivityRule, detoxConfig);
}
}
`;
}
/**
* [Step 5](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#5-create-a-detox-test-class). Create `DetoxTest.java`
*/
const withDetoxTestClass = (config) => {
return config_plugins_1.withDangerousMod(config, [
"android",
async (config) => {
var _a;
const packageName = (_a = config.android) === null || _a === void 0 ? void 0 : _a.package;
assert_1.default(packageName, "android.package must be defined");
const folder = path.join(config.modRequest.platformProjectRoot, `app/src/androidTest/java/${packageName.split(".").join("/")}`);
fs.mkdirSync(folder, { recursive: true });
fs.writeFileSync(path.join(folder, "DetoxTest.java"), getTemplateFile(packageName), { encoding: "utf8" });
return config;
},
]);
};
exports.withDetoxTestClass = withDetoxTestClass;
+11
View File
@@ -0,0 +1,11 @@
import { ConfigPlugin } from "@expo/config-plugins";
/**
* [Step 4](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#4-add-kotlin). Add Kotlin.
*
* Lifted from [unimodules-test-core](https://github.com/expo/expo/blob/master/packages/unimodules-test-core/app.plugin.js).
*
* @param config Expo config
* @param version Kotlin version to use
*/
declare const withKotlinGradle: ConfigPlugin<string>;
export default withKotlinGradle;
+43
View File
@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const config_plugins_1 = require("@expo/config-plugins");
const kotlinClassPath = "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion";
/**
* [Step 4](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#4-add-kotlin). Add Kotlin.
*
* Lifted from [unimodules-test-core](https://github.com/expo/expo/blob/master/packages/unimodules-test-core/app.plugin.js).
*
* @param config Expo config
* @param version Kotlin version to use
*/
const withKotlinGradle = (config, version) => {
return config_plugins_1.withProjectBuildGradle(config, (config) => {
console.log(`[config-plugins/detox] Setting Kotlin version to: ${version}. This could lead to Android build issues.`);
if (config.modResults.language === "groovy") {
config.modResults.contents = setKotlinVersion(config.modResults.contents, version);
config.modResults.contents = setKotlinClassPath(config.modResults.contents);
}
else {
throw new Error("Cannot setup kotlin because the build.gradle is not groovy");
}
return config;
});
};
function setKotlinVersion(buildGradle, version) {
const pattern = /kotlinVersion\s?=\s?(["'])(?:(?=(\\?))\2.)*?\1/g;
const replacement = `kotlinVersion = "${version}"`;
if (buildGradle.match(pattern)) {
// Select kotlinVersion = '***' and replace the contents between the quotes.
return buildGradle.replace(pattern, replacement);
}
return buildGradle.replace(/ext\s?{/, `ext {
${replacement}`);
}
function setKotlinClassPath(buildGradle) {
if (buildGradle.includes(kotlinClassPath)) {
return buildGradle;
}
return buildGradle.replace(/dependencies\s?{/, `dependencies {
classpath "${kotlinClassPath}"`);
}
exports.default = withKotlinGradle;
+8
View File
@@ -0,0 +1,8 @@
import { ConfigPlugin } from "@expo/config-plugins";
export declare function getTemplateFile(subdomains: string[]): string;
/**
* [Step 6](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#6-enable-clear-text-unencrypted-traffic-for-detox). Link the `network_security_config.xml` file to the `AndroidManifest.xml`.
*/
export declare const withNetworkSecurityConfigManifest: ConfigPlugin<{
subdomains: string[];
} | void>;
+76
View File
@@ -0,0 +1,76 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.withNetworkSecurityConfigManifest = exports.getTemplateFile = void 0;
const config_plugins_1 = require("@expo/config-plugins");
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const assert_1 = __importDefault(require("assert"));
function getTemplateFile(subdomains) {
return `<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
${subdomains
.map((subdomain) => `<domain includeSubdomains="true">${subdomain}</domain>`)
.join("")}
</domain-config>
</network-security-config>
`;
}
exports.getTemplateFile = getTemplateFile;
/**
* Create `network_security_config.xml` resource file.
*/
const withNetworkSecurityConfigFile = (config, { subdomains }) => {
return config_plugins_1.withDangerousMod(config, [
"android",
async (config) => {
var _a;
const packageName = (_a = config.android) === null || _a === void 0 ? void 0 : _a.package;
assert_1.default(packageName, "android.package must be defined");
const folder = path.join(config.modRequest.platformProjectRoot, `app/src/main/res/xml`);
fs.mkdirSync(folder, { recursive: true });
fs.writeFileSync(path.join(folder, "network_security_config.xml"), getTemplateFile(subdomains), { encoding: "utf8" });
return config;
},
]);
};
/**
* [Step 6](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#6-enable-clear-text-unencrypted-traffic-for-detox). Link the `network_security_config.xml` file to the `AndroidManifest.xml`.
*/
const withNetworkSecurityConfigManifest = (config, props) => {
if (!props || !props.subdomains) {
// (*) 10.0.2.2 for Google emulators, 10.0.3.2 for Genymotion emulators.
// https://developer.android.com/training/articles/security-config
props = { subdomains: ["10.0.2.2", "localhost"] };
}
config = withNetworkSecurityConfigFile(config, props);
return config_plugins_1.withAndroidManifest(config, (config) => {
const application = config_plugins_1.AndroidConfig.Manifest.getMainApplicationOrThrow(config.modResults);
application.$["android:networkSecurityConfig"] =
"@xml/network_security_config";
return config;
});
};
exports.withNetworkSecurityConfigManifest = withNetworkSecurityConfigManifest;
+11
View File
@@ -0,0 +1,11 @@
import { ConfigPlugin } from "@expo/config-plugins";
/**
* [Step 7](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#7-proguard-minification-obfuscation). Add Proguard (Minification, Obfuscation) to the app/build.gradle.
*
* 1. Add `androidTestImplementation` to the app/build.gradle
* 2. Add `testInstrumentationRunner` to the app/build.gradle
* @param config
*/
declare const withProguardGradle: ConfigPlugin;
export declare function addDetoxProguardRules(buildGradle: string): string;
export default withProguardGradle;
+35
View File
@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.addDetoxProguardRules = void 0;
const config_plugins_1 = require("@expo/config-plugins");
/**
* [Step 7](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#7-proguard-minification-obfuscation). Add Proguard (Minification, Obfuscation) to the app/build.gradle.
*
* 1. Add `androidTestImplementation` to the app/build.gradle
* 2. Add `testInstrumentationRunner` to the app/build.gradle
* @param config
*/
const withProguardGradle = (config) => {
return config_plugins_1.withAppBuildGradle(config, (config) => {
if (config.modResults.language === "groovy") {
config.modResults.contents = addDetoxProguardRules(config.modResults.contents);
}
else {
throw new Error("Cannot add Detox maven gradle because the project build.gradle is not groovy");
}
return config;
});
};
function addDetoxProguardRules(buildGradle) {
const pattern = /detox\/proguard\-rules\-app\.pro/g;
if (buildGradle.match(pattern)) {
return buildGradle;
}
return buildGradle.replace(/proguardFiles getDefaultProguardFile\("proguard-android.txt"\),\s?"proguard-rules.pro"/, `proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
// Detox-specific additions to pro-guard
def detoxProguardRulesPath = new File(["node", "--print", "require.resolve('detox/package.json')"].execute(null, rootDir).text.trim(), "../android/detox/proguard-rules-app.pro")
proguardFile(detoxProguardRulesPath)
`);
}
exports.addDetoxProguardRules = addDetoxProguardRules;
exports.default = withProguardGradle;
+3 -9
View File
@@ -1,15 +1,10 @@
{
"name": "@config-plugins/detox",
"version": "1.2.2",
"version": "1.1.0",
"description": "Config plugin to auto configure detox on prebuild",
"main": "build/withDetox.js",
"types": "build/withDetox.d.ts",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/expo/config-plugins.git",
"directory": "packages/detox"
},
"files": [
"build",
"app.plugin.js"
@@ -30,10 +25,9 @@
"e2e"
],
"dependencies": {
"@expo/config-plugins": "^4.1.0"
"@expo/config-plugins": "^4.0.7"
},
"devDependencies": {
"expo-module-scripts": "^2.0.0"
},
"upstreamPackage": "detox"
}
}
@@ -1,39 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`getTemplateFile returns domain-config when subdomains is an array 1`] = `
"<?xml version=\\"1.0\\" encoding=\\"utf-8\\"?>
<network-security-config>
<domain-config cleartextTrafficPermitted=\\"true\\">
<domain includeSubdomains=\\"true\\">localhost</domain>
</domain-config>
</network-security-config>"
`;
exports[`getTemplateFile returns only base-config when subdomains is '*' 1`] = `
"<?xml version=\\"1.0\\" encoding=\\"utf-8\\"?>
<network-security-config>
<base-config cleartextTrafficPermitted=\\"true\\" />
</network-security-config>"
`;
exports[`withNetworkSecurityConfigManifest doesn't modify config if subdomains is an empty array 1`] = `
Object {
"name": "foo",
"slug": "bar",
}
`;
exports[`withNetworkSecurityConfigManifest modifies config if subdomains is not empty 1`] = `
Object {
"mods": Object {
"android": Object {
"dangerous": [Function],
"manifest": [Function],
},
},
"name": "foo",
"slug": "bar",
}
`;
@@ -1,38 +0,0 @@
import {
getTemplateFile,
withNetworkSecurityConfigManifest,
} from "../withNetworkSecurityConfig";
describe(getTemplateFile, () => {
it(`returns only base-config when subdomains is '*'`, () => {
const content = getTemplateFile("*");
expect(content).toMatchSnapshot();
expect(content).toMatch(/base\-config/);
expect(content).not.toMatch(/domain\-config/);
});
it(`returns domain-config when subdomains is an array`, () => {
const content = getTemplateFile(["localhost"]);
expect(content).toMatchSnapshot();
expect(content).toMatch(/domain\-config/);
expect(content).toMatch(/localhost/);
});
});
const exp = { name: "foo", slug: "bar" };
describe(withNetworkSecurityConfigManifest, () => {
it(`doesn't modify config if subdomains is an empty array`, () => {
const applied = withNetworkSecurityConfigManifest(exp, {
subdomains: [],
});
expect(applied).toMatchSnapshot();
expect(applied).toStrictEqual(exp);
});
it(`modifies config if subdomains is not empty`, () => {
const applied = withNetworkSecurityConfigManifest(exp, {
subdomains: ["10.0.2.2"],
});
expect(applied).toMatchSnapshot();
expect(applied).toHaveProperty("mods.android");
});
});
+2 -3
View File
@@ -8,7 +8,7 @@ import withDetoxProjectGradle from "./withDetoxProjectGradle";
import withDetoxTestAppGradle from "./withDetoxTestAppGradle";
import { withDetoxTestClass } from "./withDetoxTestClass";
import withKotlinGradle from "./withKotlinGradle";
import { withNetworkSecurityConfigManifest, SubdomainsType } from "./withNetworkSecurityConfig";
import { withNetworkSecurityConfigManifest } from "./withNetworkSecurityConfig";
import withProguardGradle from "./withProguardGradle";
const withDetox: ConfigPlugin<{
@@ -21,11 +21,10 @@ const withDetox: ConfigPlugin<{
/**
* Subdomains to add to the network security config.
* Pass `['10.0.3.2', 'localhost']` to use Genymotion emulators instead of Google emulators.
* Pass `*` to allow all domains.
*
* @default ['10.0.2.2', 'localhost'] // (Google emulators)
*/
subdomains?: SubdomainsType;
subdomains?: string[];
} | void> = (config, { skipProguard, subdomains } = {}) => {
return withPlugins(
config,
+18 -42
View File
@@ -8,44 +8,28 @@ import * as path from "path";
import * as fs from "fs";
import assert from "assert";
export type SubdomainsType = string[] | "*";
function getTemplateConfigContent(subdomains: SubdomainsType) {
if (subdomains === "*") {
// allow all domains
return '<base-config cleartextTrafficPermitted="true" />';
}
return `
<domain-config cleartextTrafficPermitted="true">
${subdomains
.map(
(subdomain) =>
`<domain includeSubdomains="true">${subdomain}</domain>`
)
.join("")}
</domain-config>
`;
}
export function getTemplateFile(subdomains: SubdomainsType): string {
const content = getTemplateConfigContent(subdomains);
/**
* May not have new lines or spaces in the beginning.
* Otherwise build fails with:
* "AAPT: error: XML or text declaration not at start of entity"
*/
export function getTemplateFile(subdomains: string[]): string {
return `<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
${content}
</network-security-config>`;
<domain-config cleartextTrafficPermitted="true">
${subdomains
.map(
(subdomain) =>
`<domain includeSubdomains="true">${subdomain}</domain>`
)
.join("")}
</domain-config>
</network-security-config>
`;
}
/**
* Create `network_security_config.xml` resource file.
*/
const withNetworkSecurityConfigFile: ConfigPlugin<{
subdomains: SubdomainsType;
}> = (config, { subdomains }) => {
const withNetworkSecurityConfigFile: ConfigPlugin<{ subdomains: string[] }> = (
config,
{ subdomains }
) => {
return withDangerousMod(config, [
"android",
async (config) => {
@@ -69,22 +53,14 @@ const withNetworkSecurityConfigFile: ConfigPlugin<{
/**
* [Step 6](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#6-enable-clear-text-unencrypted-traffic-for-detox). Link the `network_security_config.xml` file to the `AndroidManifest.xml`.
*/
export const withNetworkSecurityConfigManifest: ConfigPlugin<
{
subdomains: SubdomainsType;
} | void
> = (config, props) => {
export const withNetworkSecurityConfigManifest: ConfigPlugin<{
subdomains: string[];
} | void> = (config, props) => {
if (!props || !props.subdomains) {
// (*) 10.0.2.2 for Google emulators, 10.0.3.2 for Genymotion emulators.
// https://developer.android.com/training/articles/security-config
props = { subdomains: ["10.0.2.2", "localhost"] };
}
if (typeof props.subdomains === "object" && !props.subdomains.length) {
// if subdomains is an empty array, skip network config mod
return config;
}
config = withNetworkSecurityConfigFile(config, props);
return withAndroidManifest(config, (config) => {
const application = AndroidConfig.Manifest.getMainApplicationOrThrow(
@@ -1,20 +0,0 @@
### @config-plugins/ffmpeg-kit-react-native [1.0.2](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-22)
### Other chores
* **ffmpeg-kit-react-native:** update plugin to use `AndroidConfig.Version.withBuildScriptExtMinimumVersion` ([#60](https://github.com/expo/config-plugins/issues/60)) ([c3a375b](https://github.com/expo/config-plugins/commit/c3a375b292d6405be7b3277d10ab4f8dbb006047))
### @config-plugins/ffmpeg-kit-react-native [1.0.1](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-16)
### Continuous Integration
* fix versions [skip ci] ([#53](https://github.com/expo/config-plugins/issues/53)) ([5de4ae3](https://github.com/expo/config-plugins/commit/5de4ae3e6182c32b7aa24d70ccd23a11663bb089))
## @config-plugins/ffmpeg-kit-react-native 1.0.0 (2022-03-15)
### Other chores
* upgrade @expo/config-plugins ([#49](https://github.com/expo/config-plugins/issues/49)) ([119e31e](https://github.com/expo/config-plugins/commit/119e31edf110409272ace750f02d651124e1a22d))
+1 -1
View File
@@ -4,7 +4,7 @@ Config plugin to auto configure ffmpeg-kit-react-native when the native code is
## Expo installation
> Tested against Expo SDK 44. Most packages worked on iOS. Not all packages have been tested on Android.
> Tested against Expo SDK 43. Only the `min` package appeared to work on Android. Most packages worked on iOS.
> 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).
+3
View File
@@ -0,0 +1,3 @@
import { ConfigPlugin } from "@expo/config-plugins";
export declare const withAndroidFFMPEGPackage: ConfigPlugin<string | undefined>;
export declare function addPackageName(src: string, packageName?: string): string;
@@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.addPackageName = exports.withAndroidFFMPEGPackage = void 0;
const config_plugins_1 = require("@expo/config-plugins");
const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
const withAndroidFFMPEGPackage = (config, packageName) => {
return config_plugins_1.withProjectBuildGradle(config, (config) => {
if (config.modResults.language === "groovy") {
config.modResults.contents = addPackageName(config.modResults.contents, packageName);
}
else {
throw new Error("Cannot add camera maven gradle because the build.gradle is not groovy");
}
return config;
});
};
exports.withAndroidFFMPEGPackage = withAndroidFFMPEGPackage;
function addPackageName(src, packageName) {
const tag = "ffmpeg-kit-react-native-package";
const gradleMaven = packageName
? `ext { ffmpegKitPackage = "${packageName}" }`
: "";
return appendContents({
tag,
src,
newSrc: gradleMaven,
comment: "//",
}).contents;
}
exports.addPackageName = addPackageName;
// Fork of config-plugins mergeContents, but appends the contents to the end of the file.
function appendContents({ src, newSrc, tag, comment, }) {
const header = generateCode_1.createGeneratedHeaderComment(newSrc, tag, comment);
if (!src.includes(header)) {
// Ensure the old generated contents are removed.
let sanitizedTarget = generateCode_1.removeGeneratedContents(src, tag);
if (sanitizedTarget)
sanitizedTarget += "\n";
const contentsToAdd = [
// @something
header,
// contents
newSrc,
// @end
`${comment} @generated end ${tag}`,
].join("\n");
return {
contents: (sanitizedTarget !== null && sanitizedTarget !== void 0 ? sanitizedTarget : src) + contentsToAdd,
didMerge: true,
didClear: !!sanitizedTarget,
};
}
return { contents: src, didClear: false, didMerge: false };
}
@@ -0,0 +1,10 @@
import { ConfigPlugin } from "@expo/config-plugins";
/** Sets a numeric version for a value in the project.gradle buildscript.ext object to be at least the provided props.minVersion, if the existing value is greater then no change will be made. */
export declare const withBuildScriptExtMinimumVersion: ConfigPlugin<{
name: string;
minVersion: number;
}>;
export declare function setMinBuildScriptExtVersion(buildGradle: string, { name, minVersion }: {
name: string;
minVersion: number;
}): string;
@@ -0,0 +1,31 @@
"use strict";
// Copied from https://github.com/expo/expo-cli/blob/main/packages/config-plugins/src/android/Version.ts
Object.defineProperty(exports, "__esModule", { value: true });
exports.setMinBuildScriptExtVersion = exports.withBuildScriptExtMinimumVersion = void 0;
const config_plugins_1 = require("@expo/config-plugins");
/** Sets a numeric version for a value in the project.gradle buildscript.ext object to be at least the provided props.minVersion, if the existing value is greater then no change will be made. */
const withBuildScriptExtMinimumVersion = (config, props) => {
return config_plugins_1.withProjectBuildGradle(config, (config) => {
if (config.modResults.language === "groovy") {
config.modResults.contents = setMinBuildScriptExtVersion(config.modResults.contents, props);
}
else {
config_plugins_1.WarningAggregator.addWarningAndroid("withBuildScriptExtVersion", `Cannot automatically configure project build.gradle if it's not groovy`);
}
return config;
});
};
exports.withBuildScriptExtMinimumVersion = withBuildScriptExtMinimumVersion;
function setMinBuildScriptExtVersion(buildGradle, { name, minVersion }) {
var _a;
const regex = new RegExp(`(${name}\\s?=\\s?)(\\d+(?:\\.\\d+)?)`);
const currentVersion = (_a = buildGradle.match(regex)) === null || _a === void 0 ? void 0 : _a[2];
if (!currentVersion) {
config_plugins_1.WarningAggregator.addWarningAndroid("withBuildScriptExtVersion", `Cannot set minimum buildscript.ext.${name} version because the property "${name}" cannot be found or does not have a numeric value.`);
// TODO: Maybe just add the property...
return buildGradle;
}
const currentVersionNum = Number(currentVersion);
return buildGradle.replace(regex, `$1${Math.max(minVersion, currentVersionNum)}`);
}
exports.setMinBuildScriptExtVersion = setMinBuildScriptExtVersion;
+5
View File
@@ -0,0 +1,5 @@
import { ConfigPlugin } from "@expo/config-plugins";
export declare const withPodfilePropertiesPackage: ConfigPlugin<string>;
/** Dangerously adds the custom import to the CocoaPods. */
export declare const withCocoaPodsImport: ConfigPlugin;
export declare function addCocoaPodsImport(src: string): string;
@@ -0,0 +1,47 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addCocoaPodsImport = exports.withCocoaPodsImport = exports.withPodfilePropertiesPackage = void 0;
const config_plugins_1 = require("@expo/config-plugins");
const ios_plugins_1 = require("@expo/config-plugins/build/plugins/ios-plugins");
const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
const fs_1 = require("fs");
const path_1 = __importDefault(require("path"));
const withPodfilePropertiesPackage = (config, packageName) => {
return ios_plugins_1.withPodfileProperties(config, (config) => {
// @ts-ignore: wrong type
config.modResults["ffmpeg-kit-react-native.subspecs"] = [
packageName,
].filter(Boolean);
return config;
});
};
exports.withPodfilePropertiesPackage = withPodfilePropertiesPackage;
/** Dangerously adds the custom import to the CocoaPods. */
const withCocoaPodsImport = (c) => {
return config_plugins_1.withDangerousMod(c, [
"ios",
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
async (config) => {
const file = path_1.default.join(config.modRequest.platformProjectRoot, "Podfile");
const contents = await fs_1.promises.readFile(file, "utf8");
await fs_1.promises.writeFile(file, addCocoaPodsImport(contents), "utf-8");
return config;
},
]);
};
exports.withCocoaPodsImport = withCocoaPodsImport;
function addCocoaPodsImport(src) {
return generateCode_1.mergeContents({
tag: `ffmpeg-kit-react-native-import`,
src,
newSrc: ` pod 'ffmpeg-kit-react-native', :subspecs => podfile_properties['ffmpeg-kit-react-native.subspecs'] || [], :podspec => File.join(File.dirname(\`node --print "require.resolve('ffmpeg-kit-react-native/package.json')"\`), "ffmpeg-kit-react-native.podspec")`,
anchor: /use_native_modules/,
// We can't go after the use_native_modules block because it might have parameters, causing it to be multi-line (see react-native template).
offset: 0,
comment: "#",
}).contents;
}
exports.addCocoaPodsImport = addCocoaPodsImport;
+11
View File
@@ -0,0 +1,11 @@
declare type Package = "min" | "min-gpl" | "https" | "https-gpl" | "audio" | "video" | "full" | "full-gpl";
export declare type Props = {
package?: Package;
ios?: {
package?: Package;
};
android?: {
package?: Package;
};
};
export {};
+43
View File
@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const config_plugins_1 = require("@expo/config-plugins");
const withAndroidFFMPEGPackage_1 = require("./withAndroidFFMPEGPackage");
const withBuildScriptExtMinimumVersion_1 = require("./withBuildScriptExtMinimumVersion");
const withCocoaPodsImport_1 = require("./withCocoaPodsImport");
const withIosDeploymentTarget_1 = require("./withIosDeploymentTarget");
let pkg = {
name: "ffmpeg-kit-react-native",
};
try {
pkg = require("ffmpeg-kit-react-native/package.json");
}
catch (_a) {
// empty catch block
}
const withFFMPEG = (config, _props) => {
var _a, _b;
const props = _props || {};
const iosPackage = ((_a = props.ios) === null || _a === void 0 ? void 0 : _a.package) || props.package;
const androidPackage = ((_b = props.android) === null || _b === void 0 ? void 0 : _b.package) || props.package;
return config_plugins_1.withPlugins(config, [
// iOS
[withCocoaPodsImport_1.withPodfilePropertiesPackage, iosPackage],
[
withIosDeploymentTarget_1.withIosDeploymentTarget,
// https://github.com/tanersener/ffmpeg-kit/tree/main/react-native#211-package-names
{ deploymentTarget: "12.1" },
],
withCocoaPodsImport_1.withCocoaPodsImport,
// Android
// Set min SDK Version to 24.
[
withBuildScriptExtMinimumVersion_1.withBuildScriptExtMinimumVersion,
{
name: "minSdkVersion",
minVersion: 24,
},
],
[withAndroidFFMPEGPackage_1.withAndroidFFMPEGPackage, androidPackage],
]);
};
module.exports = config_plugins_1.createRunOncePlugin(withFFMPEG, pkg.name, pkg.version);
+8
View File
@@ -0,0 +1,8 @@
import { ConfigPlugin, XcodeProject } from "@expo/config-plugins";
declare type IosDeploymentTargetConfigPlugin = ConfigPlugin<{
deploymentTarget: string;
}>;
export declare const withIosDeploymentTarget: IosDeploymentTargetConfigPlugin;
export declare function updateDeploymentTargetPodfile(contents: string, deploymentTarget: string): string;
export declare function updateDeploymentTargetXcodeProject(project: XcodeProject, deploymentTarget: string): XcodeProject;
export {};
@@ -0,0 +1,60 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateDeploymentTargetXcodeProject = exports.updateDeploymentTargetPodfile = exports.withIosDeploymentTarget = void 0;
const config_plugins_1 = require("@expo/config-plugins");
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const semver_1 = __importDefault(require("semver"));
const withIosDeploymentTarget = (config, props) => {
config = withIosDeploymentTargetPodfile(config, props);
config = withIosDeploymentTargetXcodeProject(config, props);
return config;
};
exports.withIosDeploymentTarget = withIosDeploymentTarget;
const withIosDeploymentTargetPodfile = (config, props) => {
return config_plugins_1.withDangerousMod(config, [
"ios",
async (config) => {
const podfile = path_1.default.join(config.modRequest.platformProjectRoot, "Podfile");
let contents = await fs_1.default.promises.readFile(podfile, "utf8");
contents = updateDeploymentTargetPodfile(contents, props.deploymentTarget);
await fs_1.default.promises.writeFile(podfile, contents);
return config;
},
]);
};
function updateDeploymentTargetPodfile(contents, deploymentTarget) {
return contents.replace(/^(\s*platform :ios, ['"])([\d.]+)(['"])/gm, (match, prefix, version, suffix) => {
if (semver_1.default.lt(toSemVer(version), toSemVer(deploymentTarget))) {
return `${prefix}${deploymentTarget}${suffix}`;
}
return match;
});
}
exports.updateDeploymentTargetPodfile = updateDeploymentTargetPodfile;
const withIosDeploymentTargetXcodeProject = (config, props) => {
return config_plugins_1.withXcodeProject(config, (config) => {
config.modResults = updateDeploymentTargetXcodeProject(config.modResults, props.deploymentTarget);
return config;
});
};
function updateDeploymentTargetXcodeProject(project, deploymentTarget) {
const configurations = project.pbxXCBuildConfigurationSection();
// @ts-ignore
for (const { buildSettings } of Object.values(configurations !== null && configurations !== void 0 ? configurations : {})) {
const currDeploymentTarget = buildSettings === null || buildSettings === void 0 ? void 0 : buildSettings.IPHONEOS_DEPLOYMENT_TARGET;
if (currDeploymentTarget &&
semver_1.default.lt(toSemVer(currDeploymentTarget), toSemVer(deploymentTarget))) {
buildSettings.IPHONEOS_DEPLOYMENT_TARGET = deploymentTarget;
}
}
return project;
}
exports.updateDeploymentTargetXcodeProject = updateDeploymentTargetXcodeProject;
function toSemVer(version) {
var _a;
return (_a = semver_1.default.coerce(version)) !== null && _a !== void 0 ? _a : new semver_1.default.SemVer("0.0.0");
}
@@ -1,15 +1,10 @@
{
"name": "@config-plugins/ffmpeg-kit-react-native",
"version": "1.0.2",
"version": "0.0.0",
"description": "Config plugin to auto configure FFMPEG on prebuild",
"main": "build/withFFMPEG.js",
"types": "build/withFFMPEG.d.ts",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/expo/config-plugins.git",
"directory": "packages/ffmpeg-kit-react-native"
},
"files": [
"build",
"app.plugin.js"
@@ -32,12 +27,11 @@
"preset": "expo-module-scripts"
},
"dependencies": {
"@expo/config-plugins": "^4.1.0",
"@expo/config-plugins": "^4.0.7",
"semver": "^7.3.5"
},
"devDependencies": {
"@types/semver": "^7.3.9",
"expo-module-scripts": "^2.0.0"
},
"upstreamPackage": "ffmpeg-kit-react-native"
}
}
@@ -0,0 +1,89 @@
import { WarningAggregator } from "@expo/config-plugins";
import { setMinBuildScriptExtVersion } from "../withBuildScriptExtMinimumVersion";
const EXAMPLE_PROJECT_BUILD_GRADLE = `
buildscript {
ext {
buildToolsVersion = "29.0.3"
minSdkVersion = 21
compileSdkVersion = 30
targetSdkVersion = 30
oddFormat = 30.2
}
repositories {
}
dependencies {
}
}
allprojects {
repositories {
mavenLocal()
maven {
// Android JSC is installed from npm
url(new File(["node", "--print", "require.resolve('jsc-android/package.json')"].execute(null, rootDir).text.trim(), "../dist"))
}
}
}
`;
describe(setMinBuildScriptExtVersion, () => {
beforeEach(() => {
// @ts-ignore: jest
// eslint-disable-next-line import/namespace
WarningAggregator.addWarningAndroid = jest.fn();
});
it(`sets the minSdkVersion in build.gradle if minSdkVersion is given`, () => {
expect(
setMinBuildScriptExtVersion(EXAMPLE_PROJECT_BUILD_GRADLE, {
name: "minSdkVersion",
minVersion: 22,
})
).toMatch(/minSdkVersion = 22/);
expect(WarningAggregator.addWarningAndroid).not.toHaveBeenCalled();
});
it(`sets the oddFormat in build.gradle if oddFormat is given`, () => {
expect(
setMinBuildScriptExtVersion(EXAMPLE_PROJECT_BUILD_GRADLE, {
name: "oddFormat",
minVersion: 30.3,
})
).toMatch(/oddFormat = 30\.3/);
expect(WarningAggregator.addWarningAndroid).not.toHaveBeenCalled();
});
it(`does not change the compileSdkVersion in build.gradle if compileSdkVersion is lower than the existing value`, () => {
expect(
setMinBuildScriptExtVersion(EXAMPLE_PROJECT_BUILD_GRADLE, {
name: "compileSdkVersion",
minVersion: 12,
})
).toBe(EXAMPLE_PROJECT_BUILD_GRADLE);
expect(WarningAggregator.addWarningAndroid).not.toHaveBeenCalled();
});
it(`warns when it cannot find the requested value`, () => {
expect(
setMinBuildScriptExtVersion(EXAMPLE_PROJECT_BUILD_GRADLE, {
name: "foobar",
minVersion: 12,
})
).toBe(EXAMPLE_PROJECT_BUILD_GRADLE);
expect(WarningAggregator.addWarningAndroid).toBeCalledWith(
"withBuildScriptExtVersion",
'Cannot set minimum buildscript.ext.foobar version because the property "foobar" cannot be found or does not have a numeric value.'
);
});
it(`does warns when targeting a property with a string value`, () => {
expect(
setMinBuildScriptExtVersion(EXAMPLE_PROJECT_BUILD_GRADLE, {
name: "buildToolsVersion",
minVersion: 12,
})
).toBe(EXAMPLE_PROJECT_BUILD_GRADLE);
expect(WarningAggregator.addWarningAndroid).toBeCalledWith(
"withBuildScriptExtVersion",
'Cannot set minimum buildscript.ext.buildToolsVersion version because the property "buildToolsVersion" cannot be found or does not have a numeric value.'
);
});
});
@@ -0,0 +1,50 @@
// Copied from https://github.com/expo/expo-cli/blob/main/packages/config-plugins/src/android/Version.ts
import {
ConfigPlugin,
WarningAggregator,
withProjectBuildGradle,
} from "@expo/config-plugins";
/** Sets a numeric version for a value in the project.gradle buildscript.ext object to be at least the provided props.minVersion, if the existing value is greater then no change will be made. */
export const withBuildScriptExtMinimumVersion: ConfigPlugin<{
name: string;
minVersion: number;
}> = (config, props) => {
return withProjectBuildGradle(config, (config) => {
if (config.modResults.language === "groovy") {
config.modResults.contents = setMinBuildScriptExtVersion(
config.modResults.contents,
props
);
} else {
WarningAggregator.addWarningAndroid(
"withBuildScriptExtVersion",
`Cannot automatically configure project build.gradle if it's not groovy`
);
}
return config;
});
};
export function setMinBuildScriptExtVersion(
buildGradle: string,
{ name, minVersion }: { name: string; minVersion: number }
) {
const regex = new RegExp(`(${name}\\s?=\\s?)(\\d+(?:\\.\\d+)?)`);
const currentVersion = buildGradle.match(regex)?.[2];
if (!currentVersion) {
WarningAggregator.addWarningAndroid(
"withBuildScriptExtVersion",
`Cannot set minimum buildscript.ext.${name} version because the property "${name}" cannot be found or does not have a numeric value.`
);
// TODO: Maybe just add the property...
return buildGradle;
}
const currentVersionNum = Number(currentVersion);
return buildGradle.replace(
regex,
`$1${Math.max(minVersion, currentVersionNum)}`
);
}
@@ -1,11 +1,11 @@
import {
AndroidConfig,
ConfigPlugin,
createRunOncePlugin,
withPlugins,
} from "@expo/config-plugins";
import { withAndroidFFMPEGPackage } from "./withAndroidFFMPEGPackage";
import { withBuildScriptExtMinimumVersion } from "./withBuildScriptExtMinimumVersion";
import {
withCocoaPodsImport,
withPodfilePropertiesPackage,
@@ -56,7 +56,7 @@ const withFFMPEG: ConfigPlugin<void | Props> = (config, _props) => {
// Set min SDK Version to 24.
[
AndroidConfig.Version.withBuildScriptExtMinimumVersion,
withBuildScriptExtMinimumVersion,
{
name: "minSdkVersion",
minVersion: 24,
-25
View File
@@ -1,25 +0,0 @@
### @config-plugins/ios-stickers [1.0.2](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-22)
### Other chores
* git ignore build folders ([#59](https://github.com/expo/config-plugins/issues/59)) ([d6050be](https://github.com/expo/config-plugins/commit/d6050beb2a5c68dc59287c27ec388c2002ec7904))
### @config-plugins/ios-stickers [1.0.1](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-16)
### Continuous Integration
* fix versions [skip ci] ([#53](https://github.com/expo/config-plugins/issues/53)) ([5de4ae3](https://github.com/expo/config-plugins/commit/5de4ae3e6182c32b7aa24d70ccd23a11663bb089))
### Documentation changes
* **ios-stickers:** add doc block ([#55](https://github.com/expo/config-plugins/issues/55)) ([c904bc6](https://github.com/expo/config-plugins/commit/c904bc6a5f410645696a0356b5c188b94f80c231))
## @config-plugins/ios-stickers 1.0.0 (2022-03-15)
### Other chores
* upgrade @expo/config-plugins ([#49](https://github.com/expo/config-plugins/issues/49)) ([119e31e](https://github.com/expo/config-plugins/commit/119e31edf110409272ace750f02d651124e1a22d))
+1 -1
View File
@@ -4,7 +4,7 @@ Config plugin to auto configure iOS iMessage stickers
## Install
> Tested against Expo SDK 44
> Tested against Expo SDK 43
```
yarn add @config-plugins/ios-stickers
-58
View File
@@ -1,58 +0,0 @@
{
"title": "@config-plugins/ios-stickers options",
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/Props",
"definitions": {
"Props": {
"type": "object",
"properties": {
"stickers": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/Sticker"
}
]
}
},
"icon": {
"type": "string"
},
"name": {
"type": "string"
},
"columns": {
"type": "number",
"enum": [
2,
3,
4
]
}
},
"additionalProperties": false
},
"Sticker": {
"type": "object",
"properties": {
"image": {
"type": "string"
},
"name": {
"type": "string"
},
"accessibilityLabel": {
"type": "string"
}
},
"required": [
"image"
],
"additionalProperties": false
}
}
}
-1
View File
@@ -1,5 +1,4 @@
import { ConfigPlugin } from "@expo/config-plugins";
/** Dangerously applies sticker assets to the iOS project. */
export declare const withStickerAssets: ConfigPlugin<{
icon?: string;
size: string;
+1 -1
View File
@@ -44,7 +44,6 @@ function createSticker({ stickerpackPath, name, imageBuffer, extension, accessib
name: stickerName,
};
}
/** Dangerously applies sticker assets to the iOS project. */
const withStickerAssets = (config, { stickers, icon, size }) => {
// Default to using the app icon
if (!icon) {
@@ -96,6 +95,7 @@ const withStickerAssets = (config, { stickers, icon, size }) => {
projectRoot: config.modRequest.projectRoot,
cacheType: "ios-stickers",
}, {
resizeMode: "contain",
src,
});
// let results;
+1 -6
View File
@@ -4,8 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizeStickersProps = void 0;
const schema_utils_1 = require("schema-utils");
const options_json_1 = __importDefault(require("./options.json"));
const withStickerAssets_1 = require("./withStickerAssets");
const withStickerInfoPlist_1 = require("./withStickerInfoPlist");
const withStickerXcodeTarget_1 = require("./withStickerXcodeTarget");
@@ -31,10 +29,7 @@ function normalizeStickersProps(props = []) {
});
}
exports.normalizeStickersProps = normalizeStickersProps;
const withStickerPack = (config, options = {}) => {
// Perform option validation.
schema_utils_1.validate(options_json_1.default, options);
const { stickers, icon, name, columns = 3 } = options;
const withStickerPack = (config, { stickers, icon, name, columns = 3 } = {}) => {
const size = sizeColumnMap[columns] || "regular";
if (!size) {
throw new Error(`Column size "${columns}" is invalid. Expected one of: ${Object.keys(sizeColumnMap).join(", ")}`);
-1
View File
@@ -1 +0,0 @@
module.exports = require('expo-module-scripts/jest-preset-plugin');
+5 -8
View File
@@ -1,15 +1,10 @@
{
"name": "@config-plugins/ios-stickers",
"version": "1.0.2",
"version": "0.0.4",
"description": "Config plugin to auto configure iOS iMessage stickers",
"main": "build/withStickerPack.js",
"types": "build/withStickerPack.d.ts",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/expo/config-plugins.git",
"directory": "packages/ios-stickers"
},
"scripts": {
"build": "expo-module build",
"clean": "expo-module clean",
@@ -23,10 +18,12 @@
"react",
"expo"
],
"jest": {
"preset": "expo-module-scripts"
},
"dependencies": {
"@expo/config-plugins": "^4.1.0",
"@expo/config-plugins": "^4.0.7",
"@expo/image-utils": "^0.3.17",
"schema-utils": "^4.0.0",
"xcode": "^3.0.1"
},
"devDependencies": {
@@ -1,32 +0,0 @@
import withStickerPack from "../withStickerPack";
const exp = { name: "foo", slug: "bar" };
describe(withStickerPack, () => {
it("should not throw when options are valid", () => {
expect(() =>
withStickerPack(exp, {
name: "test",
stickers: [{ image: "test.png" }],
columns: 2,
icon: "test.png",
})
).not.toThrow();
});
it("should not throw when no options are provided", () => {
expect(() => withStickerPack(exp, {})).not.toThrow();
});
it("should throw if columns is not a number", () => {
expect(() => {
withStickerPack(exp, {
stickers: [],
icon: "",
name: "",
columns: "3",
} as any);
}).toThrowErrorMatchingInlineSnapshot(`
"Invalid options object. @config-plugins/ios-stickers has been initialized using an options object that does not match the API schema.
- options.columns should be one of these:
2 | 3 | 4"
`);
});
});
-58
View File
@@ -1,58 +0,0 @@
{
"title": "@config-plugins/ios-stickers options",
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/Props",
"definitions": {
"Props": {
"type": "object",
"properties": {
"stickers": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/Sticker"
}
]
}
},
"icon": {
"type": "string"
},
"name": {
"type": "string"
},
"columns": {
"type": "number",
"enum": [
2,
3,
4
]
}
},
"additionalProperties": false
},
"Sticker": {
"type": "object",
"properties": {
"image": {
"type": "string"
},
"name": {
"type": "string"
},
"accessibilityLabel": {
"type": "string"
}
},
"required": [
"image"
],
"additionalProperties": false
}
}
}
@@ -68,7 +68,6 @@ function createSticker({
};
}
/** Dangerously applies sticker assets to the iOS project. */
export const withStickerAssets: ConfigPlugin<{
icon?: string;
size: string;
@@ -174,6 +173,7 @@ export const withStickerAssets: ConfigPlugin<{
cacheType: "ios-stickers",
},
{
resizeMode: "contain",
src,
} as any
);
+5 -8
View File
@@ -1,6 +1,5 @@
import { ConfigPlugin } from "@expo/config-plugins";
import { validate } from "schema-utils";
import schema from "./options.json";
import { Props, Sticker, withStickerAssets } from "./withStickerAssets";
import { withStickersPlist } from "./withStickerInfoPlist";
import { withStickerXcodeTarget } from "./withStickerXcodeTarget";
@@ -31,12 +30,10 @@ export function normalizeStickersProps(
});
}
const withStickerPack: ConfigPlugin<Props> = (config, options = {}) => {
// Perform option validation.
validate(schema as any, options);
const { stickers, icon, name, columns = 3 } = options;
const withStickerPack: ConfigPlugin<Props> = (
config,
{ stickers, icon, name, columns = 3 } = {}
) => {
const size = sizeColumnMap[columns] || "regular";
if (!size) {
throw new Error(
+1 -2
View File
@@ -1,8 +1,7 @@
{
"extends": "expo-module-scripts/tsconfig.plugin",
"compilerOptions": {
"outDir": "./build",
"resolveJsonModule": true
"outDir": "./build"
},
"include": ["./src"],
"exclude": ["**/__mocks__/*", "**/__tests__/*"]
@@ -1,2 +0,0 @@
// @generated by expo-module-scripts
module.exports = require('expo-module-scripts/eslintrc.base.js');
-13
View File
@@ -1,13 +0,0 @@
### @config-plugins/react-native-adjust [1.0.1](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-16)
### Continuous Integration
* fix versions [skip ci] ([#53](https://github.com/expo/config-plugins/issues/53)) ([5de4ae3](https://github.com/expo/config-plugins/commit/5de4ae3e6182c32b7aa24d70ccd23a11663bb089))
## @config-plugins/react-native-adjust 1.0.0 (2022-03-15)
### Other chores
* upgrade @expo/config-plugins ([#49](https://github.com/expo/config-plugins/issues/49)) ([119e31e](https://github.com/expo/config-plugins/commit/119e31edf110409272ace750f02d651124e1a22d))
-42
View File
@@ -1,42 +0,0 @@
# @config-plugins/react-native-adjust
Expo Config Plugin to auto configure [`react-native-adjust`](https://www.npmjs.com/package/react-native-adjust) when the native code is generated (`expo prebuild`).
## Expo installation
> Tested against Expo SDK 44
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 react-native-adjust @config-plugins/react-native-adjust
```
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
{
"expo": {
"plugins": ["@config-plugins/react-native-adjust"]
}
}
```
If you are targeting Android 12 and above (API level 31), you need to add it in the options of the plugin:
```json
{
"expo": {
"plugins": [
"@config-plugins/react-native-adjust",
{ "targetAndroid12": true }
]
}
}
```
This will add the [appropriate permission](https://github.com/adjust/react_native_sdk#add-permission-to-gather-google-advertising-id) for you.
Next, rebuild your app as described in the ["Adding custom native code"](https://docs.expo.io/workflow/customizing/) guide.
@@ -1 +0,0 @@
module.exports = require("./build/withReactNativeAdjust");
-40
View File
@@ -1,40 +0,0 @@
{
"name": "@config-plugins/react-native-adjust",
"version": "1.0.1",
"description": "Config plugin to auto configure Adjust SDK on prebuild",
"main": "build/withReactNativeAdjust.js",
"types": "build/withReactNativeAdjust.d.ts",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/expo/config-plugins.git",
"directory": "packages/react-native-adjust"
},
"scripts": {
"build": "expo-module build",
"clean": "expo-module clean",
"lint": "expo-module lint",
"test": "expo-module test",
"prepare": "expo-module prepare",
"prepublishOnly": "expo-module prepublishOnly",
"expo-module": "expo-module"
},
"keywords": [
"react",
"expo",
"config-plugins",
"prebuild",
"react-native-adjust",
"expo-44"
],
"jest": {
"preset": "expo-module-scripts"
},
"dependencies": {
"@expo/config-plugins": "^4.1.0"
},
"devDependencies": {
"expo-module-scripts": "^2.0.0"
},
"upstreamPackage": "react-native-adjust"
}
@@ -1,124 +0,0 @@
import {
AndroidConfig,
createRunOncePlugin,
IOSConfig,
withXcodeProject,
withAppBuildGradle,
ConfigPlugin,
} from "@expo/config-plugins";
import { mergeContents } from "@expo/config-plugins/build/utils/generateCode";
const withXcodeLinkBinaryWithLibraries: ConfigPlugin<{
library: string;
status?: string;
}> = (config, { library, status }) => {
return withXcodeProject(config, (config) => {
const options = status === "optional" ? { weak: true } : {};
const target = IOSConfig.XcodeUtils.getApplicationNativeTarget({
project: config.modResults,
projectName: config.modRequest.projectName!,
});
config.modResults.addFramework(library, {
target: target.uuid,
...options,
});
return config;
});
};
const addAndroidPackagingOptions = (src: string) => {
return mergeContents({
tag: "react-native-play-services-analytics",
src,
newSrc: `
implementation 'com.google.android.gms:play-services-analytics:18.0.0'
implementation 'com.android.installreferrer:installreferrer:2.2'
`,
anchor: /dependencies(?:\s+)?\{/,
// Inside the dependencies block.
offset: 1,
comment: "//",
});
};
const withGradle: ConfigPlugin = (config) => {
return withAppBuildGradle(config, (config) => {
if (config.modResults.language === "groovy") {
config.modResults.contents = addAndroidPackagingOptions(
config.modResults.contents
).contents;
} else {
throw new Error(
"Cannot add Play Services maven gradle because the project build.gradle is not groovy"
);
}
return config;
});
};
/**
* Apply react-native-adjust configuration for Expo SDK +44 projects.
*/
const withAdjustPlugin: ConfigPlugin<void | { targetAndroid12?: boolean }> = (
config,
_props
) => {
const props = _props || {};
config = withXcodeLinkBinaryWithLibraries(config, {
library: "iAd.framework",
status: "optional",
});
config = withXcodeLinkBinaryWithLibraries(config, {
library: "AdServices.framework",
status: "optional",
});
config = withXcodeLinkBinaryWithLibraries(config, {
library: "AdSupport.framework",
status: "optional",
});
config = withXcodeLinkBinaryWithLibraries(config, {
library: "StoreKit.framework",
status: "optional",
});
config = withXcodeLinkBinaryWithLibraries(config, {
library: "AppTrackingTransparency.framework",
status: "optional",
});
if (props.targetAndroid12) {
config = AndroidConfig.Version.withBuildScriptExtMinimumVersion(config, {
name: "compileSdkVersion",
minVersion: 31,
});
config = AndroidConfig.Permissions.withPermissions(config, [
"com.google.android.gms.permission.AD_ID",
]);
}
config = withGradle(config);
// Return the modified config.
return config;
};
const pkg = {
// Prevent this plugin from being run more than once.
// This pattern enables users to safely migrate off of this
// out-of-tree `@config-plugins/react-native-adjust` to a future
// upstream plugin in `react-native-adjust`
name: "react-native-adjust",
// Indicates that this plugin is dangerously linked to a module,
// and might not work with the latest version of that module.
version: "UNVERSIONED",
};
export default createRunOncePlugin(withAdjustPlugin, pkg.name, pkg.version);
@@ -1,8 +0,0 @@
{
"extends": "expo-module-scripts/tsconfig.plugin",
"compilerOptions": {
"outDir": "./build"
},
"include": ["./src"],
"exclude": ["**/__mocks__/*", "**/__tests__/*"]
}
@@ -1,13 +0,0 @@
### @config-plugins/react-native-ble-plx [1.0.1](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-16)
### Continuous Integration
* fix versions [skip ci] ([#53](https://github.com/expo/config-plugins/issues/53)) ([5de4ae3](https://github.com/expo/config-plugins/commit/5de4ae3e6182c32b7aa24d70ccd23a11663bb089))
## @config-plugins/react-native-ble-plx 1.0.0 (2022-03-15)
### Other chores
* upgrade @expo/config-plugins ([#49](https://github.com/expo/config-plugins/issues/49)) ([119e31e](https://github.com/expo/config-plugins/commit/119e31edf110409272ace750f02d651124e1a22d))
+1 -1
View File
@@ -4,7 +4,7 @@ Config plugin to auto configure `react-native-ble-plx` when the native code is g
## Expo installation
> Tested against Expo SDK 44
> Tested against Expo SDK 43
> 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).
+10
View File
@@ -0,0 +1,10 @@
import { ConfigPlugin } from "@expo/config-plugins";
import { BackgroundMode } from "./withBLEBackgroundModes";
export { BackgroundMode };
declare const _default: ConfigPlugin<void | {
isBackgroundEnabled?: boolean | undefined;
modes?: BackgroundMode[] | undefined;
bluetoothAlwaysPermission?: string | false | undefined;
bluetoothPeripheralPermission?: string | false | undefined;
}>;
export default _default;
+29
View File
@@ -0,0 +1,29 @@
"use strict";
/* eslint-disable flowtype/no-types-missing-file-annotation */
Object.defineProperty(exports, "__esModule", { value: true });
exports.BackgroundMode = void 0;
const config_plugins_1 = require("@expo/config-plugins");
const withBLEAndroidManifest_1 = require("./withBLEAndroidManifest");
const withBLEBackgroundModes_1 = require("./withBLEBackgroundModes");
Object.defineProperty(exports, "BackgroundMode", { enumerable: true, get: function () { return withBLEBackgroundModes_1.BackgroundMode; } });
const withBluetoothPermissions_1 = require("./withBluetoothPermissions");
const pkg = { name: "react-native-ble-plx", version: "UNVERSIONED" }; //require('react-native-ble-plx/package.json')
/**
* Apply BLE configuration for Expo SDK 42 projects.
*/
const withBLE = (config, props = {}) => {
var _a;
const _props = props || {};
const isBackgroundEnabled = (_a = _props.isBackgroundEnabled) !== null && _a !== void 0 ? _a : false;
// iOS
config = withBluetoothPermissions_1.withBluetoothPermissions(config, _props);
config = withBLEBackgroundModes_1.withBLEBackgroundModes(config, _props.modes || []);
// Android
config = config_plugins_1.AndroidConfig.Permissions.withPermissions(config, [
"android.permission.BLUETOOTH",
"android.permission.BLUETOOTH_ADMIN",
]);
config = withBLEAndroidManifest_1.withBLEAndroidManifest(config, { isBackgroundEnabled });
return config;
};
exports.default = config_plugins_1.createRunOncePlugin(withBLE, pkg.name, pkg.version);
+17
View File
@@ -0,0 +1,17 @@
import { ConfigPlugin, AndroidConfig } from "@expo/config-plugins";
declare type InnerManifest = AndroidConfig.Manifest.AndroidManifest['manifest'];
declare type ManifestPermission = InnerManifest["permission"];
declare type AndroidManifest = {
manifest: InnerManifest & {
permission?: ManifestPermission;
"uses-permission"?: InnerManifest["uses-permission"];
"uses-permission-sdk-23"?: InnerManifest["uses-permission"];
"uses-feature"?: InnerManifest["uses-feature"];
};
};
export declare const withBLEAndroidManifest: ConfigPlugin<{
isBackgroundEnabled: boolean;
}>;
export declare function addFineControlPermissionToManifest(androidManifest: AndroidManifest): AndroidManifest;
export declare function addBLEHardwareFeatureToManifest(androidManifest: AndroidConfig.Manifest.AndroidManifest): AndroidConfig.Manifest.AndroidManifest;
export {};
+49
View File
@@ -0,0 +1,49 @@
"use strict";
/* eslint-disable flowtype/no-types-missing-file-annotation */
Object.defineProperty(exports, "__esModule", { value: true });
exports.addBLEHardwareFeatureToManifest = exports.addFineControlPermissionToManifest = exports.withBLEAndroidManifest = void 0;
const config_plugins_1 = require("@expo/config-plugins");
const withBLEAndroidManifest = (config, { isBackgroundEnabled }) => {
return config_plugins_1.withAndroidManifest(config, (config) => {
config.modResults = addFineControlPermissionToManifest(config.modResults);
if (isBackgroundEnabled) {
config.modResults = addBLEHardwareFeatureToManifest(config.modResults);
}
return config;
});
};
exports.withBLEAndroidManifest = withBLEAndroidManifest;
function addFineControlPermissionToManifest(androidManifest) {
var _a;
// Add `<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>` to the AndroidManifest.xml
if (!Array.isArray(androidManifest.manifest["uses-permission-sdk-23"])) {
androidManifest.manifest["uses-permission-sdk-23"] = [];
}
if (!androidManifest.manifest["uses-permission-sdk-23"].find((item) => item.$["android:name"] === "android.permission.ACCESS_FINE_LOCATION")) {
(_a = androidManifest.manifest["uses-permission-sdk-23"]) === null || _a === void 0 ? void 0 : _a.push({
$: {
"android:name": "android.permission.ACCESS_FINE_LOCATION",
},
});
}
return androidManifest;
}
exports.addFineControlPermissionToManifest = addFineControlPermissionToManifest;
// Add this line if your application always requires BLE. More info can be found on: https://developer.android.com/guide/topics/connectivity/bluetooth-le.html#permissions
function addBLEHardwareFeatureToManifest(androidManifest) {
var _a;
// Add `<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>` to the AndroidManifest.xml
if (!Array.isArray(androidManifest.manifest["uses-feature"])) {
androidManifest.manifest["uses-feature"] = [];
}
if (!androidManifest.manifest["uses-feature"].find((item) => item.$["android:name"] === "android.hardware.bluetooth_le")) {
(_a = androidManifest.manifest["uses-feature"]) === null || _a === void 0 ? void 0 : _a.push({
$: {
"android:name": "android.hardware.bluetooth_le",
"android:required": "true",
},
});
}
return androidManifest;
}
exports.addBLEHardwareFeatureToManifest = addBLEHardwareFeatureToManifest;
+9
View File
@@ -0,0 +1,9 @@
import { ConfigPlugin } from '@expo/config-plugins';
export declare enum BackgroundMode {
Central = "central",
Peripheral = "peripheral"
}
/**
* Append `UIBackgroundModes` to the `Info.plist`.
*/
export declare const withBLEBackgroundModes: ConfigPlugin<BackgroundMode[]>;
+40
View File
@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.withBLEBackgroundModes = exports.BackgroundMode = void 0;
/* eslint-disable flowtype/no-types-missing-file-annotation */
const config_plugins_1 = require("@expo/config-plugins");
var BackgroundMode;
(function (BackgroundMode) {
BackgroundMode["Central"] = "central";
BackgroundMode["Peripheral"] = "peripheral";
})(BackgroundMode = exports.BackgroundMode || (exports.BackgroundMode = {}));
function ensureKey(arr, key) {
if (!arr.find(mode => mode === key)) {
arr.push(key);
}
return arr;
}
const centralKey = 'bluetooth-central';
const peripheralKey = 'bluetooth-peripheral';
/**
* Append `UIBackgroundModes` to the `Info.plist`.
*/
const withBLEBackgroundModes = (c, modes) => {
return config_plugins_1.withInfoPlist(c, config => {
if (!Array.isArray(config.modResults.UIBackgroundModes)) {
config.modResults.UIBackgroundModes = [];
}
if (modes.includes(BackgroundMode.Central)) {
config.modResults.UIBackgroundModes = ensureKey(config.modResults.UIBackgroundModes, centralKey);
}
if (modes.includes(BackgroundMode.Peripheral)) {
config.modResults.UIBackgroundModes = ensureKey(config.modResults.UIBackgroundModes, peripheralKey);
}
// Prevent empty array
if (!config.modResults.UIBackgroundModes.length) {
delete config.modResults.UIBackgroundModes;
}
return config;
});
};
exports.withBLEBackgroundModes = withBLEBackgroundModes;
+5
View File
@@ -0,0 +1,5 @@
import { ConfigPlugin } from "@expo/config-plugins";
export declare const withBluetoothPermissions: ConfigPlugin<{
bluetoothAlwaysPermission?: string | false;
bluetoothPeripheralPermission?: string | false;
}>;
+25
View File
@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.withBluetoothPermissions = void 0;
/* eslint-disable flowtype/no-types-missing-file-annotation */
const config_plugins_1 = require("@expo/config-plugins");
const BLUETOOTH_ALWAYS = "Allow $(PRODUCT_NAME) to connect to bluetooth devices";
const BLUETOOTH_PERIPHERAL_USAGE = "Allow $(PRODUCT_NAME) to connect to bluetooth devices";
const withBluetoothPermissions = (c, { bluetoothAlwaysPermission, bluetoothPeripheralPermission } = {}) => {
return config_plugins_1.withInfoPlist(c, (config) => {
if (bluetoothAlwaysPermission !== false) {
config.modResults.NSBluetoothAlwaysUsageDescription =
bluetoothAlwaysPermission ||
config.modResults.NSBluetoothAlwaysUsageDescription ||
BLUETOOTH_ALWAYS;
}
if (bluetoothPeripheralPermission !== false) {
config.modResults.NSBluetoothPeripheralUsageDescription =
bluetoothPeripheralPermission ||
config.modResults.NSBluetoothPeripheralUsageDescription ||
BLUETOOTH_PERIPHERAL_USAGE;
}
return config;
});
};
exports.withBluetoothPermissions = withBluetoothPermissions;
+3 -9
View File
@@ -1,15 +1,10 @@
{
"name": "@config-plugins/react-native-ble-plx",
"version": "1.0.1",
"version": "0.0.2",
"description": "Config plugin to auto configure react-native-ble-plx on prebuild",
"main": "build/withBLE.js",
"types": "build/withBLE.d.ts",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/expo/config-plugins.git",
"directory": "packages/react-native-ble-plx"
},
"files": [
"build",
"app.plugin.js"
@@ -31,10 +26,9 @@
"preset": "expo-module-scripts"
},
"dependencies": {
"@expo/config-plugins": "^4.1.0"
"@expo/config-plugins": "^4.0.7"
},
"devDependencies": {
"expo-module-scripts": "^2.0.0"
},
"upstreamPackage": "react-native-ble-plx"
}
}
@@ -1,20 +0,0 @@
### @config-plugins/react-native-blob-util [1.0.2](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-16)
### Continuous Integration
* fix versions [skip ci] ([#53](https://github.com/expo/config-plugins/issues/53)) ([5de4ae3](https://github.com/expo/config-plugins/commit/5de4ae3e6182c32b7aa24d70ccd23a11663bb089))
### @config-plugins/react-native-blob-util [1.0.1](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-15)
### Bug Fixes
* **ci:** use correct internal versions ([ab8076a](https://github.com/expo/config-plugins/commit/ab8076adf51e9ba0439eba60b153d729a0996b8d))
## @config-plugins/react-native-blob-util 1.0.0 (2022-03-15)
### Other chores
* upgrade @expo/config-plugins ([#49](https://github.com/expo/config-plugins/issues/49)) ([119e31e](https://github.com/expo/config-plugins/commit/119e31edf110409272ace750f02d651124e1a22d))
+1 -1
View File
@@ -4,7 +4,7 @@ Config plugin to auto configure [`react-native-blob-util`][lib] when the native
### Add the package to your npm dependencies
> Tested against Expo SDK 44
> Tested against Expo SDK 43
```
yarn add react-native-blob-util @config-plugins/react-native-blob-util
+4
View File
@@ -0,0 +1,4 @@
import { AndroidConfig, ConfigPlugin } from "@expo/config-plugins";
export declare function appendDownloadCompleteAction(androidManifest: AndroidConfig.Manifest.AndroidManifest): AndroidConfig.Manifest.AndroidManifest;
declare const _default: ConfigPlugin<void>;
export default _default;
+59
View File
@@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.appendDownloadCompleteAction = void 0;
const config_plugins_1 = require("@expo/config-plugins");
let pkg = {
name: "react-native-blob-util",
};
try {
pkg = require("react-native-blob-util/package.json");
}
catch (_a) {
// empty catch block
}
function appendDownloadCompleteAction(androidManifest) {
var _a, _b;
if (!Array.isArray(androidManifest.manifest.application)) {
return androidManifest;
}
for (const application of androidManifest.manifest.application) {
for (const activity of application.activity || []) {
if (((_a = activity === null || activity === void 0 ? void 0 : activity.$) === null || _a === void 0 ? void 0 : _a["android:launchMode"]) === "singleTask") {
for (const intentFilter of activity["intent-filter"] || []) {
const isLauncher = (_b = intentFilter.category) === null || _b === void 0 ? void 0 : _b.some((action) => action.$["android:name"] === "android.intent.category.LAUNCHER");
if (!isLauncher)
continue;
intentFilter.action = intentFilter.action || [];
const hasDownloadCompleteAction = intentFilter.action.some((action) => action.$["android:name"] ===
"android.intent.action.DOWNLOAD_COMPLETE");
if (!hasDownloadCompleteAction) {
intentFilter.action.push({
$: {
"android:name": "android.intent.action.DOWNLOAD_COMPLETE",
},
});
return androidManifest;
}
}
break;
}
}
}
return androidManifest;
}
exports.appendDownloadCompleteAction = appendDownloadCompleteAction;
const withReactNativeBlobUtil = (config) => {
config = config_plugins_1.AndroidConfig.Permissions.withPermissions(config, [
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.DOWNLOAD_WITHOUT_NOTIFICATION",
// Wifi-only mode.
"android.permission.ACCESS_NETWORK_STATE",
]);
config = config_plugins_1.withAndroidManifest(config, (config) => {
config.modResults = appendDownloadCompleteAction(config.modResults);
return config;
});
return config;
};
exports.default = config_plugins_1.createRunOncePlugin(withReactNativeBlobUtil, pkg.name, pkg.version);
+3 -9
View File
@@ -1,15 +1,10 @@
{
"name": "@config-plugins/react-native-blob-util",
"version": "1.0.2",
"version": "0.0.0",
"description": "Config plugin to auto configure react-native-blob-util on prebuild",
"main": "build/withReactNativeBlobUtil.js",
"types": "build/withReactNativeBlobUtil.d.ts",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/expo/config-plugins.git",
"directory": "packages/react-native-blob-util"
},
"files": [
"build",
"app.plugin.js"
@@ -32,10 +27,9 @@
"preset": "expo-module-scripts"
},
"dependencies": {
"@expo/config-plugins": "^4.1.0"
"@expo/config-plugins": "^4.0.7"
},
"devDependencies": {
"expo-module-scripts": "^2.0.0"
},
"upstreamPackage": "react-native-blob-util"
}
}
@@ -1,2 +0,0 @@
// @generated by expo-module-scripts
module.exports = require('expo-module-scripts/eslintrc.base.js');
Loaded 100 of 169 files, more files were not shown because too many files have changed in this diff. Show more