mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
47
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81737c2b99 | ||
|
|
ff1261e7dc | ||
|
|
1e659dc44e | ||
|
|
9f65442f2d | ||
|
|
c4fd80f414 | ||
|
|
e9fc092156 | ||
|
|
e8c4faaf08 | ||
|
|
fbe38bb2a3 | ||
|
|
40093d96d1 | ||
|
|
6f9ddd8f89 | ||
|
|
3ce4b80e6f | ||
|
|
a09df751eb | ||
|
|
94d4bfd7c8 | ||
|
|
a35852f976 | ||
|
|
51b98c24bd | ||
|
|
bbe5e72768 | ||
|
|
dac6d508af | ||
|
|
0def73d1a6 | ||
|
|
4fc2c8fd1f | ||
|
|
b048659ceb | ||
|
|
201b517de0 | ||
|
|
980f4b42ca | ||
|
|
621d4ee298 | ||
|
|
e8776240b4 | ||
|
|
defc0c8c21 | ||
|
|
e56bd89eff | ||
|
|
807500a63e | ||
|
|
bea4535246 | ||
|
|
699a94d938 | ||
|
|
2e10ba945f | ||
|
|
007a8e12b8 | ||
|
|
1be8c51173 | ||
|
|
9f9e1a41ca | ||
|
|
c967deaa2d | ||
|
|
55671c00e5 | ||
|
|
ce1620616c | ||
|
|
ab0d812cc6 | ||
|
|
5e2f3e018c | ||
|
|
45ae0b44d5 | ||
|
|
02b879b1e2 | ||
|
|
788dd2e681 | ||
|
|
3f8d1fa286 | ||
|
|
066128321d | ||
|
|
60a2706e97 | ||
|
|
d91a12bc8b | ||
|
|
111d013c03 | ||
|
|
7e14ec5177 |
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
const {
|
||||
publishTemplate,
|
||||
verifyPublishedTemplate,
|
||||
} = require('../publishTemplate');
|
||||
|
||||
const mockRun = jest.fn();
|
||||
const mockSleep = jest.fn();
|
||||
const mockGetNpmPackageInfo = jest.fn();
|
||||
const silence = () => {};
|
||||
|
||||
jest.mock('../utils.js', () => ({
|
||||
log: silence,
|
||||
run: mockRun,
|
||||
sleep: mockSleep,
|
||||
getNpmPackageInfo: mockGetNpmPackageInfo,
|
||||
}));
|
||||
|
||||
const getMockGithub = () => ({
|
||||
rest: {
|
||||
actions: {
|
||||
createWorkflowDispatch: jest.fn(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
describe('#publishTemplate', () => {
|
||||
beforeEach(jest.clearAllMocks);
|
||||
|
||||
it('checks commits for magic #publish-package-to-npm&latest string and sets latest', async () => {
|
||||
mockRun.mockReturnValueOnce(`
|
||||
The commit message
|
||||
|
||||
#publish-packages-to-npm&latest`);
|
||||
|
||||
const github = getMockGithub();
|
||||
await publishTemplate(github, '0.76.0', true);
|
||||
expect(github.rest.actions.createWorkflowDispatch).toHaveBeenCalledWith({
|
||||
owner: 'react-native-community',
|
||||
repo: 'template',
|
||||
workflow_id: 'release.yaml',
|
||||
ref: '0.76-stable',
|
||||
inputs: {
|
||||
dry_run: true,
|
||||
is_latest_on_npm: true,
|
||||
version: '0.76.0',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('pubished as is_latest_on_npm = false if missing magic string', async () => {
|
||||
mockRun.mockReturnValueOnce(`
|
||||
The commit message without magic
|
||||
`);
|
||||
|
||||
const github = getMockGithub();
|
||||
await publishTemplate(github, '0.76.0', false);
|
||||
expect(github.rest.actions.createWorkflowDispatch).toHaveBeenCalledWith({
|
||||
owner: 'react-native-community',
|
||||
repo: 'template',
|
||||
workflow_id: 'release.yaml',
|
||||
ref: '0.76-stable',
|
||||
inputs: {
|
||||
dry_run: false,
|
||||
is_latest_on_npm: false,
|
||||
version: '0.76.0',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#verifyPublishedTemplate', () => {
|
||||
beforeEach(jest.clearAllMocks);
|
||||
|
||||
it("waits on npm updating for version and not 'latest'", async () => {
|
||||
const NOT_LATEST = false;
|
||||
mockGetNpmPackageInfo
|
||||
// template@<version>
|
||||
.mockReturnValueOnce(Promise.reject('mock http/404'))
|
||||
.mockReturnValueOnce(Promise.resolve());
|
||||
mockSleep.mockReturnValueOnce(Promise.resolve()).mockImplementation(() => {
|
||||
throw new Error('Should not be called again!');
|
||||
});
|
||||
|
||||
const version = '0.77.0';
|
||||
await verifyPublishedTemplate(version, NOT_LATEST);
|
||||
|
||||
expect(mockGetNpmPackageInfo).toHaveBeenLastCalledWith(
|
||||
'@react-native-community/template',
|
||||
version,
|
||||
);
|
||||
});
|
||||
|
||||
it('waits on npm updating version and latest tag', async () => {
|
||||
const IS_LATEST = true;
|
||||
const version = '0.77.0';
|
||||
mockGetNpmPackageInfo
|
||||
// template@latest → unknown tag
|
||||
.mockReturnValueOnce(Promise.reject('mock http/404'))
|
||||
// template@latest != version → old tag
|
||||
.mockReturnValueOnce(Promise.resolve({version: '0.76.5'}))
|
||||
// template@latest == version → correct tag
|
||||
.mockReturnValueOnce(Promise.resolve({version}));
|
||||
mockSleep
|
||||
.mockReturnValueOnce(Promise.resolve())
|
||||
.mockReturnValueOnce(Promise.resolve())
|
||||
.mockImplementation(() => {
|
||||
throw new Error('Should not be called again!');
|
||||
});
|
||||
|
||||
await verifyPublishedTemplate(version, IS_LATEST);
|
||||
|
||||
expect(mockGetNpmPackageInfo).toHaveBeenCalledWith(
|
||||
'@react-native-community/template',
|
||||
'latest',
|
||||
);
|
||||
});
|
||||
|
||||
describe('timeouts', () => {
|
||||
let mockProcess;
|
||||
beforeEach(() => {
|
||||
mockProcess = jest.spyOn(process, 'exit').mockImplementation(code => {
|
||||
throw new Error(`process.exit(${code}) called!`);
|
||||
});
|
||||
});
|
||||
afterEach(() => mockProcess.mockRestore());
|
||||
it('will timeout if npm does not update package version after a set number of retries', async () => {
|
||||
const RETRIES = 2;
|
||||
mockGetNpmPackageInfo.mockReturnValue(Promise.reject('mock http/404'));
|
||||
mockSleep.mockReturnValue(Promise.resolve());
|
||||
await expect(() =>
|
||||
verifyPublishedTemplate('0.77.0', true, RETRIES),
|
||||
).rejects.toThrowError('process.exit(1) called!');
|
||||
expect(mockGetNpmPackageInfo).toHaveBeenCalledTimes(RETRIES);
|
||||
});
|
||||
|
||||
it('will timeout if npm does not update latest tag after a set number of retries', async () => {
|
||||
const RETRIES = 7;
|
||||
const IS_LATEST = true;
|
||||
mockGetNpmPackageInfo.mockReturnValue(
|
||||
Promise.resolve({version: '0.76.5'}),
|
||||
);
|
||||
mockSleep.mockReturnValue(Promise.resolve());
|
||||
await expect(async () => {
|
||||
await verifyPublishedTemplate('0.77.0', IS_LATEST, RETRIES);
|
||||
}).rejects.toThrowError('process.exit(1) called!');
|
||||
expect(mockGetNpmPackageInfo).toHaveBeenCalledTimes(RETRIES);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
const {run, sleep, getNpmPackageInfo, log} = require('./utils.js');
|
||||
|
||||
const TAG_AS_LATEST_REGEX = /#publish-packages-to-npm&latest/;
|
||||
|
||||
/**
|
||||
* Should this commit be `latest` on npm?
|
||||
*/
|
||||
function isLatest() {
|
||||
const commitMessage = run('git log -n1 --pretty=%B');
|
||||
return TAG_AS_LATEST_REGEX.test(commitMessage);
|
||||
}
|
||||
module.exports.isLatest = isLatest;
|
||||
|
||||
/**
|
||||
* Create a Github Action to publish the community template matching the released version
|
||||
* of React Native.
|
||||
*/
|
||||
module.exports.publishTemplate = async (github, version, dryRun = true) => {
|
||||
log(`📤 Get the ${TEMPLATE_NPM_PKG} repo to publish ${version}`);
|
||||
|
||||
const is_latest_on_npm = isLatest();
|
||||
|
||||
const majorMinor = /^v?(\d+\.\d+)/.exec(version);
|
||||
|
||||
if (!majorMinor) {
|
||||
log(`🔥 can't capture MAJOR.MINOR from '${version}', giving up.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// MAJOR.MINOR-stable
|
||||
const ref = `${majorMinor[1]}-stable`;
|
||||
|
||||
await github.rest.actions.createWorkflowDispatch({
|
||||
owner: 'react-native-community',
|
||||
repo: 'template',
|
||||
workflow_id: 'release.yaml',
|
||||
ref,
|
||||
inputs: {
|
||||
dry_run: dryRun,
|
||||
is_latest_on_npm,
|
||||
// 0.75.0-rc.0, note no 'v' prefix
|
||||
version: version.replace(/^v/, ''),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const SLEEP_S = 10;
|
||||
const MAX_RETRIES = 3 * 6; // 3 minutes
|
||||
const TEMPLATE_NPM_PKG = '@react-native-community/template';
|
||||
|
||||
/**
|
||||
* Will verify that @latest and the @<version> have been published.
|
||||
*
|
||||
* NOTE: This will infinitely query each step until successful, make sure the
|
||||
* calling job has a timeout.
|
||||
*/
|
||||
module.exports.verifyPublishedTemplate = async (
|
||||
version,
|
||||
latest = false,
|
||||
retries = MAX_RETRIES,
|
||||
) => {
|
||||
log(`🔍 Is ${TEMPLATE_NPM_PKG}@${version} on npm?`);
|
||||
|
||||
let count = retries;
|
||||
while (count-- > 0) {
|
||||
try {
|
||||
const json = await getNpmPackageInfo(
|
||||
TEMPLATE_NPM_PKG,
|
||||
latest ? 'latest' : version,
|
||||
);
|
||||
log(`🎉 Found ${TEMPLATE_NPM_PKG}@${version} on npm`);
|
||||
if (!latest) {
|
||||
return;
|
||||
}
|
||||
if (json.version === version) {
|
||||
log(`🎉 ${TEMPLATE_NPM_PKG}@latest → ${version} on npm`);
|
||||
return;
|
||||
}
|
||||
log(
|
||||
`🐌 ${TEMPLATE_NPM_PKG}@latest → ${pkg.version} on npm and not ${version} as expected, retrying...`,
|
||||
);
|
||||
} catch (e) {
|
||||
log(`Nope, fetch failed: ${e.message}`);
|
||||
}
|
||||
await sleep(SLEEP_S);
|
||||
}
|
||||
|
||||
let msg = `🚨 Timed out when trying to verify ${TEMPLATE_NPM_PKG}@${version} on npm`;
|
||||
if (latest) {
|
||||
msg += ' and latest tag points to this version.';
|
||||
}
|
||||
log(msg);
|
||||
process.exit(1);
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
const {execSync} = require('child_process');
|
||||
|
||||
function run(cmd) {
|
||||
return execSync(cmd, 'utf8').toString().trim();
|
||||
}
|
||||
module.exports.run = run;
|
||||
|
||||
async function sleep(seconds) {
|
||||
return new Promise(resolve => setTimeout(resolve, seconds * 1000));
|
||||
}
|
||||
module.exports.sleep = sleep;
|
||||
|
||||
async function getNpmPackageInfo(pkg, versionOrTag) {
|
||||
return fetch(`https://registry.npmjs.org/${pkg}/${versionOrTag}`).then(resp =>
|
||||
res.json(),
|
||||
);
|
||||
}
|
||||
module.exports.getNpmPackageInfo = getNpmPackageInfo;
|
||||
|
||||
module.exports.log = (...args) => console.log(...args);
|
||||
@@ -191,46 +191,23 @@ jobs:
|
||||
gha-npm-token: ${{ env.GHA_NPM_TOKEN }}
|
||||
- name: Publish @react-native-community/template
|
||||
id: publish-template-to-npm
|
||||
shell: bash
|
||||
run: |
|
||||
COMMIT_MSG=$(git log -n1 --pretty=%B);
|
||||
if grep -q '#publish-packages-to-npm&latest' <<< "$COMMIT_MSG"; then
|
||||
echo "TAG=latest" >> $GITHUB_OUTPUT
|
||||
IS_LATEST=true
|
||||
else
|
||||
IS_LATEST=false
|
||||
fi
|
||||
# Go from v0.75.0-rc.4 -> 0.75-stable, which is the template's branching scheme
|
||||
VERSION=$(grep -oE '\d+\.\d+' <<< "${{ github.ref_name }}" | { read version; echo "$version-stable"; })
|
||||
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
curl -L https://api.github.com/repos/react-native-community/template/actions/workflows/release.yaml/dispatches
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \
|
||||
-d "{\"ref\":\"$VERSION\",\"inputs\":{\"version\":\"${{ github.ref_name }}\",\"is_latest_on_npm\":\"$IS_LATEST\"}}"
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
|
||||
script: |
|
||||
const {publishTemplate} = require('./.github/workflow-scripts/publishTemplate.js')
|
||||
const version = "${{ github.ref_name }}"
|
||||
const isDryRun = false
|
||||
await publishTemplate(github, version, isDryRun);
|
||||
- name: Wait for template to be published
|
||||
timeout-minutes: 3
|
||||
env:
|
||||
VERSION: ${{ steps.publish-template-to-npm.outputs.VERSION }}
|
||||
TAG: ${{ steps.publish-template-to-npm.outputs.TAG }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Waiting until @react-native-community/template is published to npm"
|
||||
while true; do
|
||||
if curl -o /dev/null -s -f "https://registry.npmjs.org/@react-native-community/template/$VERSION"; then
|
||||
echo "Confirm that @react-native-community/template@$VERSION is published on npm"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
while [ "$TAG" == "latest" ]; do
|
||||
CURRENT=$(curl -s "https://registry.npmjs.org/react-native/latest" | jq -r '.version');
|
||||
if [ "$CURRENT" == "$VERSION" ]; then
|
||||
echo "Confirm that @react-native-community/template@latest == $VERSION on npm"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
|
||||
script: |
|
||||
const {verifyPublishedTemplate, isLatest} = require('./.github/workflow-scripts/publishTemplate.js')
|
||||
const version = "${{ github.ref_name }}"
|
||||
await verifyPublishedTemplate(version, isLatest());
|
||||
- name: Update rn-diff-purge to generate upgrade-support diff
|
||||
run: |
|
||||
curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \
|
||||
|
||||
@@ -5,3 +5,4 @@ ruby ">= 2.6.10"
|
||||
|
||||
gem 'cocoapods', '~> 1.13', '!= 1.15.0', '!= 1.15.1'
|
||||
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
|
||||
gem 'xcodeproj', '< 1.26.0'
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
+4
-4
@@ -49,8 +49,8 @@
|
||||
"@definitelytyped/dtslint": "^0.0.127",
|
||||
"@jest/create-cache-key-function": "^29.6.3",
|
||||
"@pkgjs/parseargs": "^0.11.0",
|
||||
"@react-native/metro-babel-transformer": "0.76.0-rc.4",
|
||||
"@react-native/metro-config": "0.76.0-rc.4",
|
||||
"@react-native/metro-babel-transformer": "0.76.2",
|
||||
"@react-native/metro-config": "0.76.2",
|
||||
"@tsconfig/node18": "1.0.1",
|
||||
"@types/react": "^18.2.6",
|
||||
"@typescript-eslint/parser": "^7.1.1",
|
||||
@@ -86,8 +86,8 @@
|
||||
"jest": "^29.6.3",
|
||||
"jest-junit": "^10.0.0",
|
||||
"jscodeshift": "^0.14.0",
|
||||
"metro-babel-register": "^0.81.0-alpha.2",
|
||||
"metro-memory-fs": "^0.81.0-alpha.2",
|
||||
"metro-babel-register": "^0.81.0",
|
||||
"metro-memory-fs": "^0.81.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"mkdirp": "^0.5.1",
|
||||
"node-fetch": "^2.2.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/assets-registry",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Asset support code for React Native.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/babel-plugin-codegen",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Babel plugin to generate native module and view manager code for React Native.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -25,7 +25,7 @@
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@react-native/codegen": "0.76.0-rc.4"
|
||||
"@react-native/codegen": "0.76.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/community-cli-plugin",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Core CLI commands for React Native",
|
||||
"keywords": [
|
||||
"react-native",
|
||||
@@ -22,19 +22,20 @@
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@react-native/dev-middleware": "0.76.0-rc.4",
|
||||
"@react-native/metro-babel-transformer": "0.76.0-rc.4",
|
||||
"@react-native/dev-middleware": "0.76.2",
|
||||
"@react-native/metro-babel-transformer": "0.76.2",
|
||||
"chalk": "^4.0.0",
|
||||
"execa": "^5.1.1",
|
||||
"invariant": "^2.2.4",
|
||||
"metro": "^0.81.0-alpha.2",
|
||||
"metro-config": "^0.81.0-alpha.2",
|
||||
"metro-core": "^0.81.0-alpha.2",
|
||||
"metro": "^0.81.0",
|
||||
"metro-config": "^0.81.0",
|
||||
"metro-core": "^0.81.0",
|
||||
"node-fetch": "^2.2.0",
|
||||
"readline": "^1.3.0"
|
||||
"readline": "^1.3.0",
|
||||
"semver": "^7.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"metro-resolver": "^0.81.0-alpha.2"
|
||||
"metro-resolver": "^0.81.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@react-native-community/cli-server-api": "*"
|
||||
|
||||
@@ -140,7 +140,7 @@ async function buildBundleWithConfig(
|
||||
args.assetCatalogDest,
|
||||
);
|
||||
} finally {
|
||||
server.end();
|
||||
await server.end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/core-cli-utils",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "React Native CLI library for Frameworks to build on",
|
||||
"license": "MIT",
|
||||
"main": "./src/index.flow.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/debugger-frontend",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Debugger frontend for React Native based on Chrome DevTools",
|
||||
"keywords": [
|
||||
"react-native",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/dev-middleware",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Dev server middleware for React Native",
|
||||
"keywords": [
|
||||
"react-native",
|
||||
@@ -23,7 +23,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@isaacs/ttlcache": "^1.4.1",
|
||||
"@react-native/debugger-frontend": "0.76.0-rc.4",
|
||||
"@react-native/debugger-frontend": "0.76.2",
|
||||
"chrome-launcher": "^0.15.2",
|
||||
"chromium-edge-launcher": "^0.2.0",
|
||||
"connect": "^3.6.5",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/eslint-config",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "ESLint config for React Native",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -22,7 +22,7 @@
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/eslint-parser": "^7.25.1",
|
||||
"@react-native/eslint-plugin": "0.76.0-rc.4",
|
||||
"@react-native/eslint-plugin": "0.76.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
||||
"@typescript-eslint/parser": "^7.1.1",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/eslint-plugin",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "ESLint rules for @react-native/eslint-config",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/eslint-plugin-specs",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "ESLint rules to validate NativeModule and Component Specs",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -27,7 +27,7 @@
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/plugin-transform-flow-strip-types": "^7.25.2",
|
||||
"@babel/preset-flow": "^7.24.7",
|
||||
"@react-native/codegen": "0.76.0-rc.4",
|
||||
"@react-native/codegen": "0.76.2",
|
||||
"make-dir": "^2.1.0",
|
||||
"pirates": "^4.0.1",
|
||||
"source-map-support": "0.5.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/gradle-plugin",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Gradle Plugin for React Native",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
+7
-4
@@ -59,15 +59,15 @@ abstract class GenerateAutolinkingNewArchitecturesFileTask : DefaultTask() {
|
||||
val cxxModuleCMakeListsPath = dep.cxxModuleCMakeListsPath
|
||||
if (libraryName != null && cmakeListsPath != null) {
|
||||
// If user provided a custom cmakeListsPath, let's honor it.
|
||||
val nativeFolderPath = cmakeListsPath.replace("CMakeLists.txt", "")
|
||||
val nativeFolderPath = sanitizeCmakeListsPath(cmakeListsPath)
|
||||
addDirectoryString +=
|
||||
"add_subdirectory($nativeFolderPath ${libraryName}_autolinked_build)"
|
||||
"add_subdirectory(\"$nativeFolderPath\" ${libraryName}_autolinked_build)"
|
||||
}
|
||||
if (cxxModuleCMakeListsPath != null) {
|
||||
// If user provided a custom cxxModuleCMakeListsPath, let's honor it.
|
||||
val nativeFolderPath = cxxModuleCMakeListsPath.replace("CMakeLists.txt", "")
|
||||
val nativeFolderPath = sanitizeCmakeListsPath(cxxModuleCMakeListsPath)
|
||||
addDirectoryString +=
|
||||
"\nadd_subdirectory($nativeFolderPath ${libraryName}_cxxmodule_autolinked_build)"
|
||||
"\nadd_subdirectory(\"$nativeFolderPath\" ${libraryName}_cxxmodule_autolinked_build)"
|
||||
}
|
||||
addDirectoryString
|
||||
}
|
||||
@@ -159,6 +159,9 @@ abstract class GenerateAutolinkingNewArchitecturesFileTask : DefaultTask() {
|
||||
const val COMPONENT_DESCRIPTOR_FILENAME = "ComponentDescriptors.h"
|
||||
const val COMPONENT_INCLUDE_PATH = "react/renderer/components"
|
||||
|
||||
internal fun sanitizeCmakeListsPath(cmakeListsPath: String): String =
|
||||
cmakeListsPath.replace("CMakeLists.txt", "").replace(" ", "\\ ")
|
||||
|
||||
// language=cmake
|
||||
val CMAKE_TEMPLATE =
|
||||
"""
|
||||
|
||||
+23
-4
@@ -11,6 +11,7 @@ import com.facebook.react.model.ModelAutolinkingConfigJson
|
||||
import com.facebook.react.model.ModelAutolinkingDependenciesJson
|
||||
import com.facebook.react.model.ModelAutolinkingDependenciesPlatformAndroidJson
|
||||
import com.facebook.react.model.ModelAutolinkingDependenciesPlatformJson
|
||||
import com.facebook.react.tasks.GenerateAutolinkingNewArchitecturesFileTask.Companion.sanitizeCmakeListsPath
|
||||
import com.facebook.react.tests.createTestTask
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Rule
|
||||
@@ -145,9 +146,9 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
# or link against a old prefab target (this is needed for React Native 0.76 on).
|
||||
set(REACTNATIVE_MERGED_SO true)
|
||||
|
||||
add_subdirectory(./a/directory/ aPackage_autolinked_build)
|
||||
add_subdirectory(./another/directory/ anotherPackage_autolinked_build)
|
||||
add_subdirectory(./another/directory/cxx/ anotherPackage_cxxmodule_autolinked_build)
|
||||
add_subdirectory("./a/directory/" aPackage_autolinked_build)
|
||||
add_subdirectory("./another/directory/with\ spaces/" anotherPackage_autolinked_build)
|
||||
add_subdirectory("./another/directory/cxx/" anotherPackage_cxxmodule_autolinked_build)
|
||||
|
||||
set(AUTOLINKED_LIBRARIES
|
||||
react_codegen_aPackage
|
||||
@@ -258,6 +259,24 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
.trimIndent())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sanitizeCmakeListsPath_withPathEndingWithFileName_removesFilename() {
|
||||
val input = "./a/directory/CMakeLists.txt"
|
||||
assertThat(sanitizeCmakeListsPath(input)).isEqualTo("./a/directory/")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sanitizeCmakeListsPath_withSpaces_removesSpaces() {
|
||||
val input = "./a/dir ectory/with spaces/"
|
||||
assertThat(sanitizeCmakeListsPath(input)).isEqualTo("./a/dir\\ ectory/with\\ spaces/")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sanitizeCmakeListsPath_withPathEndingWithFileNameAndSpaces_sanitizesIt() {
|
||||
val input = "./a/dir ectory/CMakeLists.txt"
|
||||
assertThat(sanitizeCmakeListsPath(input)).isEqualTo("./a/dir\\ ectory/")
|
||||
}
|
||||
|
||||
private val testDependencies =
|
||||
listOf(
|
||||
ModelAutolinkingDependenciesPlatformAndroidJson(
|
||||
@@ -276,7 +295,7 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
buildTypes = emptyList(),
|
||||
libraryName = "anotherPackage",
|
||||
componentDescriptors = listOf("AnotherPackageComponentDescriptor"),
|
||||
cmakeListsPath = "./another/directory/CMakeLists.txt",
|
||||
cmakeListsPath = "./another/directory/with spaces/CMakeLists.txt",
|
||||
cxxModuleCMakeListsPath = "./another/directory/cxx/CMakeLists.txt",
|
||||
cxxModuleHeaderName = "AnotherCxxModule",
|
||||
cxxModuleCMakeListsModuleName = "another_cxxModule",
|
||||
|
||||
@@ -4,3 +4,4 @@ ruby ">= 2.6.10"
|
||||
|
||||
gem 'cocoapods', '~> 1.13', '!= 1.15.0', '!= 1.15.1'
|
||||
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
|
||||
gem 'xcodeproj', '< 1.26.0'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "helloworld",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"bootstrap": "node ./cli.js bootstrap",
|
||||
@@ -13,16 +13,16 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "18.3.1",
|
||||
"react-native": "0.76.0-rc.4"
|
||||
"react-native": "0.76.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/preset-env": "^7.25.3",
|
||||
"@babel/runtime": "^7.25.0",
|
||||
"@react-native/babel-preset": "0.76.0-rc.4",
|
||||
"@react-native/core-cli-utils": "0.76.0-rc.4",
|
||||
"@react-native/eslint-config": "0.76.0-rc.4",
|
||||
"@react-native/metro-config": "0.76.0-rc.4",
|
||||
"@react-native/babel-preset": "0.76.2",
|
||||
"@react-native/core-cli-utils": "0.76.2",
|
||||
"@react-native/eslint-config": "0.76.2",
|
||||
"@react-native/metro-config": "0.76.2",
|
||||
"babel-jest": "^29.6.3",
|
||||
"chalk": "^4.1.2",
|
||||
"commander": "^12.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/hermes-inspector-msggen",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"private": true,
|
||||
"description": "Hermes Inspector Message Generator for React Native",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/metro-config",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Metro configuration for React Native.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -26,9 +26,9 @@
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@react-native/js-polyfills": "0.76.0-rc.4",
|
||||
"@react-native/metro-babel-transformer": "0.76.0-rc.4",
|
||||
"metro-config": "^0.81.0-alpha.2",
|
||||
"metro-runtime": "^0.81.0-alpha.2"
|
||||
"@react-native/js-polyfills": "0.76.2",
|
||||
"@react-native/metro-babel-transformer": "0.76.2",
|
||||
"metro-config": "^0.81.0",
|
||||
"metro-runtime": "^0.81.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/normalize-colors",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Color normalization for React Native.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/js-polyfills",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Polyfills for React Native.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/babel-preset",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Babel preset for React Native applications",
|
||||
"main": "src/index.js",
|
||||
"repository": {
|
||||
@@ -55,8 +55,8 @@
|
||||
"@babel/plugin-transform-typescript": "^7.25.2",
|
||||
"@babel/plugin-transform-unicode-regex": "^7.24.7",
|
||||
"@babel/template": "^7.25.0",
|
||||
"@react-native/babel-plugin-codegen": "0.76.0-rc.4",
|
||||
"babel-plugin-syntax-hermes-parser": "^0.23.1",
|
||||
"@react-native/babel-plugin-codegen": "0.76.2",
|
||||
"babel-plugin-syntax-hermes-parser": "^0.25.1",
|
||||
"babel-plugin-transform-flow-enums": "^0.0.2",
|
||||
"react-refresh": "^0.14.0"
|
||||
},
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ function isTSXSource(fileName) {
|
||||
const loose = true;
|
||||
|
||||
const defaultPlugins = [
|
||||
[require('babel-plugin-syntax-hermes-parser')],
|
||||
[require('babel-plugin-syntax-hermes-parser'), {parseLangTypes: 'flow'}],
|
||||
[require('babel-plugin-transform-flow-enums')],
|
||||
[require('@babel/plugin-transform-block-scoping')],
|
||||
[require('@babel/plugin-transform-class-properties'), {loose}],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/metro-babel-transformer",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Babel transformer for React Native applications.",
|
||||
"main": "src/index.js",
|
||||
"repository": {
|
||||
@@ -16,7 +16,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@react-native/babel-preset": "0.76.0-rc.4",
|
||||
"@react-native/babel-preset": "0.76.2",
|
||||
"hermes-parser": "0.23.1",
|
||||
"nullthrows": "^1.1.1"
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@react-native/bots",
|
||||
"description": "React Native Bots",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/codegen-typescript-test",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"private": true,
|
||||
"description": "TypeScript related unit test for @react-native/codegen",
|
||||
"license": "MIT",
|
||||
@@ -19,7 +19,7 @@
|
||||
"prepare": "yarn run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-native/codegen": "0.76.0-rc.4"
|
||||
"@react-native/codegen": "0.76.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/codegen",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Code generation tools for React Native",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-info",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"main": "build/index.js",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
@@ -17,10 +17,10 @@
|
||||
"directory": "packages/react-native-info"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-native-community/cli-config": "15.0.0-alpha.2",
|
||||
"@react-native-community/cli-platform-apple": "15.0.0-alpha.2",
|
||||
"@react-native-community/cli-tools": "15.0.0-alpha.2",
|
||||
"@react-native-community/cli-types": "15.0.0-alpha.2",
|
||||
"@react-native-community/cli-config": "15.0.1",
|
||||
"@react-native-community/cli-platform-apple": "15.0.1",
|
||||
"@react-native-community/cli-tools": "15.0.1",
|
||||
"@react-native-community/cli-types": "15.0.1",
|
||||
"commander": "^12.0.0",
|
||||
"fs-extra": "^11.2.0",
|
||||
"yaml": "^2.4.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/popup-menu-android",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "PopupMenu for the Android platform",
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
@@ -17,7 +17,7 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@react-native/codegen": "0.76.0-rc.4"
|
||||
"@react-native/codegen": "0.76.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^18.2.6",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/oss-library-example",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"private": true,
|
||||
"description": "Package that includes native module exapmle, native component example, targets both the old and the new architecture. It should serve as an example of a real-world OSS library.",
|
||||
"license": "MIT",
|
||||
@@ -26,8 +26,8 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@react-native/babel-preset": "0.76.0-rc.4",
|
||||
"react-native": "0.76.0-rc.4"
|
||||
"@react-native/babel-preset": "0.76.2",
|
||||
"react-native": "0.76.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@react-native/test-renderer",
|
||||
"private": true,
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "A Test rendering library for React Native",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [self createRootViewController];
|
||||
[self setRootView:rootView toRootViewController:rootViewController];
|
||||
_window.windowScene.delegate = self;
|
||||
_window.rootViewController = rootViewController;
|
||||
[_window makeKeyAndVisible];
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ Pod::Spec.new do |s|
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
|
||||
"DEFINES_MODULE" => "YES"
|
||||
}
|
||||
s.user_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\""}
|
||||
s.user_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\" \"$(PODS_ROOT)/Headers/Private/Yoga\""}
|
||||
|
||||
s.dependency "React-Core"
|
||||
s.dependency "RCT-Folly", folly_version
|
||||
|
||||
@@ -16,8 +16,8 @@ const version: $ReadOnly<{
|
||||
}> = {
|
||||
major: 0,
|
||||
minor: 76,
|
||||
patch: 0,
|
||||
prerelease: 'rc.4',
|
||||
patch: 2,
|
||||
prerelease: null,
|
||||
};
|
||||
|
||||
module.exports = {version};
|
||||
|
||||
@@ -21,13 +21,7 @@ ExceptionsManager.installConsoleErrorReporter();
|
||||
if (!global.__fbDisableExceptionsManager) {
|
||||
const handleError = (e: mixed, isFatal: boolean) => {
|
||||
try {
|
||||
// TODO(T196834299): We should really use a c++ turbomodule for this
|
||||
if (
|
||||
!global.RN$handleException ||
|
||||
!global.RN$handleException(e, isFatal)
|
||||
) {
|
||||
ExceptionsManager.handleException(e, isFatal);
|
||||
}
|
||||
ExceptionsManager.handleException(e, isFatal);
|
||||
} catch (ee) {
|
||||
console.log('Failed to print error: ', ee.message);
|
||||
throw e;
|
||||
|
||||
@@ -82,9 +82,9 @@ let warningFilter: WarningFilter = function (format) {
|
||||
return {
|
||||
finalFormat: format,
|
||||
forceDialogImmediately: false,
|
||||
suppressDialog_LEGACY: true,
|
||||
suppressDialog_LEGACY: false,
|
||||
suppressCompletely: false,
|
||||
monitorEvent: 'unknown',
|
||||
monitorEvent: 'warning_unhandled',
|
||||
monitorListVersion: 0,
|
||||
monitorSampleRate: 1,
|
||||
};
|
||||
|
||||
+169
-44
@@ -11,45 +11,29 @@
|
||||
import {
|
||||
DoesNotUseKey,
|
||||
FragmentWithProp,
|
||||
ManualConsoleError,
|
||||
ManualConsoleErrorWithStack,
|
||||
} from './__fixtures__/ReactWarningFixtures';
|
||||
import * as React from 'react';
|
||||
|
||||
const LogBoxData = require('../Data/LogBoxData');
|
||||
const TestRenderer = require('react-test-renderer');
|
||||
|
||||
const installLogBox = () => {
|
||||
const LogBox = require('../LogBox');
|
||||
const ExceptionsManager = require('../../Core/ExceptionsManager.js');
|
||||
|
||||
const installLogBox = () => {
|
||||
const LogBox = require('../LogBox').default;
|
||||
LogBox.install();
|
||||
};
|
||||
|
||||
const uninstallLogBox = () => {
|
||||
const LogBox = require('../LogBox');
|
||||
const LogBox = require('../LogBox').default;
|
||||
LogBox.uninstall();
|
||||
};
|
||||
|
||||
const BEFORE_SLASH_RE = /(?:\/[a-zA-Z]+\/)(.+?)(?:\/.+)\//;
|
||||
|
||||
const cleanPath = message => {
|
||||
return message.replace(BEFORE_SLASH_RE, '/path/to/');
|
||||
};
|
||||
|
||||
const cleanLog = logs => {
|
||||
return logs.map(log => {
|
||||
return {
|
||||
...log,
|
||||
componentStack: log.componentStack.map(stack => ({
|
||||
...stack,
|
||||
fileName: cleanPath(stack.fileName),
|
||||
})),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// TODO(T71117418): Re-enable skipped LogBox integration tests once React component
|
||||
// stack frames are the same internally and in open source.
|
||||
// eslint-disable-next-line jest/no-disabled-tests
|
||||
describe.skip('LogBox', () => {
|
||||
// TODO: we can remove all the symetric matchers once OSS lands component stack frames.
|
||||
// For now, the component stack parsing differs in ways we can't easily detect in this test.
|
||||
describe('LogBox', () => {
|
||||
const {error, warn} = console;
|
||||
const mockError = jest.fn();
|
||||
const mockWarn = jest.fn();
|
||||
@@ -57,10 +41,14 @@ describe.skip('LogBox', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
jest.restoreAllMocks();
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
mockError.mockClear();
|
||||
mockWarn.mockClear();
|
||||
|
||||
// Reset ExceptionManager patching.
|
||||
if (console._errorOriginal) {
|
||||
console._errorOriginal = null;
|
||||
}
|
||||
(console: any).error = mockError;
|
||||
(console: any).warn = mockWarn;
|
||||
});
|
||||
@@ -79,7 +67,10 @@ describe.skip('LogBox', () => {
|
||||
// so we can assert on what React logs.
|
||||
jest.spyOn(console, 'error');
|
||||
|
||||
const output = TestRenderer.create(<DoesNotUseKey />);
|
||||
let output;
|
||||
TestRenderer.act(() => {
|
||||
output = TestRenderer.create(<DoesNotUseKey />);
|
||||
});
|
||||
|
||||
// The key error should always be the highest severity.
|
||||
// In LogBox, we expect these errors to:
|
||||
@@ -88,16 +79,37 @@ describe.skip('LogBox', () => {
|
||||
// - Pass to console.error, with a "Warning" prefix so it does not pop a RedBox.
|
||||
expect(output).toBeDefined();
|
||||
expect(mockWarn).not.toBeCalled();
|
||||
expect(console.error.mock.calls[0].map(cleanPath)).toMatchSnapshot(
|
||||
'Log sent from React',
|
||||
);
|
||||
expect(cleanLog(spy.mock.calls[0])).toMatchSnapshot('Log added to LogBox');
|
||||
expect(mockError.mock.calls[0].map(cleanPath)).toMatchSnapshot(
|
||||
'Log passed to console error',
|
||||
);
|
||||
expect(console.error).toBeCalledTimes(1);
|
||||
expect(console.error.mock.calls[0]).toEqual([
|
||||
'Warning: Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.%s',
|
||||
'\n\nCheck the render method of `DoesNotUseKey`.',
|
||||
'',
|
||||
expect.stringMatching('at DoesNotUseKey'),
|
||||
]);
|
||||
expect(spy).toHaveBeenCalledWith({
|
||||
level: 'error',
|
||||
category: expect.stringContaining(
|
||||
'Warning: Each child in a list should have a unique',
|
||||
),
|
||||
componentStack: expect.anything(),
|
||||
componentStackType: 'stack',
|
||||
message: {
|
||||
content:
|
||||
'Warning: Each child in a list should have a unique "key" prop.\n\nCheck the render method of `DoesNotUseKey`. See https://reactjs.org/link/warning-keys for more information.',
|
||||
substitutions: [
|
||||
{length: 45, offset: 62},
|
||||
{length: 0, offset: 107},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
// The Warning: prefix is added due to a hack in LogBox to prevent double logging.
|
||||
expect(mockError.mock.calls[0][0].startsWith('Warning: ')).toBe(true);
|
||||
// We also interpolate the string before passing to the underlying console method.
|
||||
expect(mockError.mock.calls[0]).toEqual([
|
||||
expect.stringMatching(
|
||||
'Warning: Each child in a list should have a unique "key" prop.\n\nCheck the render method of `DoesNotUseKey`. See https://reactjs.org/link/warning-keys for more information.\n at ',
|
||||
),
|
||||
]);
|
||||
});
|
||||
|
||||
it('integrates with React and handles a fragment warning in LogBox', () => {
|
||||
@@ -108,7 +120,10 @@ describe.skip('LogBox', () => {
|
||||
// so we can assert on what React logs.
|
||||
jest.spyOn(console, 'error');
|
||||
|
||||
const output = TestRenderer.create(<FragmentWithProp />);
|
||||
let output;
|
||||
TestRenderer.act(() => {
|
||||
output = TestRenderer.create(<FragmentWithProp />);
|
||||
});
|
||||
|
||||
// The fragment warning is not as severe. For this warning we don't want to
|
||||
// pop open a dialog, so we show a collapsed error UI.
|
||||
@@ -118,15 +133,125 @@ describe.skip('LogBox', () => {
|
||||
// - Pass to console.error, with a "Warning" prefix so it does not pop a RedBox.
|
||||
expect(output).toBeDefined();
|
||||
expect(mockWarn).not.toBeCalled();
|
||||
expect(console.error.mock.calls[0].map(cleanPath)).toMatchSnapshot(
|
||||
'Log sent from React',
|
||||
);
|
||||
expect(cleanLog(spy.mock.calls[0])).toMatchSnapshot('Log added to LogBox');
|
||||
expect(mockError.mock.calls[0].map(cleanPath)).toMatchSnapshot(
|
||||
'Log passed to console error',
|
||||
);
|
||||
expect(console.error).toBeCalledTimes(1);
|
||||
expect(console.error.mock.calls[0]).toEqual([
|
||||
'Warning: Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.%s',
|
||||
'invalid',
|
||||
expect.stringMatching('at FragmentWithProp'),
|
||||
]);
|
||||
expect(spy).toHaveBeenCalledWith({
|
||||
level: 'error',
|
||||
category: expect.stringContaining('Warning: Invalid prop'),
|
||||
componentStack: expect.anything(),
|
||||
componentStackType: expect.stringMatching(/(stack|legacy)/),
|
||||
message: {
|
||||
content:
|
||||
'Warning: Invalid prop `invalid` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.',
|
||||
substitutions: [{length: 7, offset: 23}],
|
||||
},
|
||||
});
|
||||
|
||||
// The Warning: prefix is added due to a hack in LogBox to prevent double logging.
|
||||
expect(mockError.mock.calls[0][0].startsWith('Warning: ')).toBe(true);
|
||||
// We also interpolate the string before passing to the underlying console method.
|
||||
expect(mockError.mock.calls[0]).toEqual([
|
||||
expect.stringMatching(
|
||||
'Warning: Invalid prop `invalid` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.\n at FragmentWithProp',
|
||||
),
|
||||
]);
|
||||
});
|
||||
|
||||
it('handles a manual console.error without a component stack in LogBox', () => {
|
||||
const LogBox = require('../LogBox').default;
|
||||
const spy = jest.spyOn(LogBox, 'addException');
|
||||
installLogBox();
|
||||
|
||||
// console.error handling depends on installing the ExceptionsManager error reporter.
|
||||
ExceptionsManager.installConsoleErrorReporter();
|
||||
|
||||
// Spy console.error after LogBox is installed
|
||||
// so we can assert on what React logs.
|
||||
jest.spyOn(console, 'error');
|
||||
|
||||
let output;
|
||||
TestRenderer.act(() => {
|
||||
output = TestRenderer.create(<ManualConsoleError />);
|
||||
});
|
||||
|
||||
// Manual console errors should show a collapsed error dialog.
|
||||
// When there is no component stack, we expect these errors to:
|
||||
// - Go to the LogBox patch and fall through to console.error.
|
||||
// - Get picked up by the ExceptionsManager console.error override.
|
||||
// - Get passed back to LogBox via addException (non-fatal).
|
||||
expect(output).toBeDefined();
|
||||
expect(mockWarn).not.toBeCalled();
|
||||
expect(spy).toBeCalledTimes(1);
|
||||
expect(console.error).toBeCalledTimes(1);
|
||||
expect(console.error.mock.calls[0]).toEqual(['Manual console error']);
|
||||
expect(spy).toHaveBeenCalledWith({
|
||||
id: 1,
|
||||
isComponentError: false,
|
||||
isFatal: false,
|
||||
name: 'console.error',
|
||||
originalMessage: 'Manual console error',
|
||||
message: 'console.error: Manual console error',
|
||||
extraData: expect.anything(),
|
||||
componentStack: null,
|
||||
stack: expect.anything(),
|
||||
});
|
||||
|
||||
// No Warning: prefix is added due since this is falling through.
|
||||
expect(mockError.mock.calls[0]).toEqual(['Manual console error']);
|
||||
});
|
||||
|
||||
it('handles a manual console.error with a component stack in LogBox', () => {
|
||||
const spy = jest.spyOn(LogBoxData, 'addLog');
|
||||
installLogBox();
|
||||
|
||||
// console.error handling depends on installing the ExceptionsManager error reporter.
|
||||
ExceptionsManager.installConsoleErrorReporter();
|
||||
|
||||
// Spy console.error after LogBox is installed
|
||||
// so we can assert on what React logs.
|
||||
jest.spyOn(console, 'error');
|
||||
|
||||
let output;
|
||||
TestRenderer.act(() => {
|
||||
output = TestRenderer.create(<ManualConsoleErrorWithStack />);
|
||||
});
|
||||
|
||||
// Manual console errors should show a collapsed error dialog.
|
||||
// When there is a component stack, we expect these errors to:
|
||||
// - Go to the LogBox patch and be detected as a React error.
|
||||
// - Check the warning filter to see if there is a fiter setting.
|
||||
// - Call console.error with the parsed error.
|
||||
// - Get picked up by ExceptionsManager console.error override.
|
||||
// - Log to console.error.
|
||||
expect(output).toBeDefined();
|
||||
expect(mockWarn).not.toBeCalled();
|
||||
expect(console.error).toBeCalledTimes(1);
|
||||
expect(spy).toBeCalledTimes(1);
|
||||
expect(console.error.mock.calls[0]).toEqual([
|
||||
expect.stringContaining(
|
||||
'Manual console error\n at ManualConsoleErrorWithStack',
|
||||
),
|
||||
]);
|
||||
expect(spy).toHaveBeenCalledWith({
|
||||
level: 'error',
|
||||
category: expect.stringContaining('Warning: Manual console error'),
|
||||
componentStack: expect.anything(),
|
||||
componentStackType: 'stack',
|
||||
message: {
|
||||
content: 'Warning: Manual console error',
|
||||
substitutions: [],
|
||||
},
|
||||
});
|
||||
|
||||
// The Warning: prefix is added due to a hack in LogBox to prevent double logging.
|
||||
// We also interpolate the string before passing to the underlying console method.
|
||||
expect(mockError.mock.calls[0]).toEqual([
|
||||
expect.stringMatching(
|
||||
'Warning: Manual console error\n at ManualConsoleErrorWithStack',
|
||||
),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
+130
-30
@@ -13,6 +13,7 @@
|
||||
|
||||
const LogBoxData = require('../Data/LogBoxData');
|
||||
const LogBox = require('../LogBox').default;
|
||||
const ExceptionsManager = require('../../Core/ExceptionsManager.js');
|
||||
|
||||
declare var console: any;
|
||||
|
||||
@@ -34,15 +35,18 @@ describe('LogBox', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
jest.restoreAllMocks();
|
||||
console.error = jest.fn();
|
||||
console.log = jest.fn();
|
||||
console.warn = jest.fn();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
LogBox.uninstall();
|
||||
// Reset ExceptionManager patching.
|
||||
if (console._errorOriginal) {
|
||||
console._errorOriginal = null;
|
||||
}
|
||||
console.error = error;
|
||||
console.log = log;
|
||||
console.warn = warn;
|
||||
});
|
||||
|
||||
@@ -95,7 +99,7 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('registers warnings', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
|
||||
LogBox.install();
|
||||
|
||||
@@ -105,13 +109,14 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('reports a LogBox exception if we fail to add warnings', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
const mockError = new Error('Simulated error');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'reportLogBoxError');
|
||||
|
||||
// Picking a random implementation detail to simulate throwing.
|
||||
(LogBoxData.isMessageIgnored: any).mockImplementation(() => {
|
||||
jest.spyOn(LogBoxData, 'isMessageIgnored').mockImplementation(() => {
|
||||
throw mockError;
|
||||
});
|
||||
const mockError = new Error('Simulated error');
|
||||
|
||||
LogBox.install();
|
||||
|
||||
@@ -123,7 +128,8 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('only registers errors beginning with "Warning: "', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
|
||||
LogBox.install();
|
||||
|
||||
@@ -133,7 +139,8 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('registers react errors with the formatting from filter', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
|
||||
mockFilterResult({
|
||||
finalFormat: 'Custom format',
|
||||
@@ -157,7 +164,8 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('registers errors with component stack as errors by default', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
|
||||
mockFilterResult({});
|
||||
|
||||
@@ -174,7 +182,8 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('registers errors with component stack as errors by default if not found in warning filter', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
|
||||
mockFilterResult({
|
||||
monitorEvent: 'warning_unhandled',
|
||||
@@ -193,10 +202,12 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('registers errors with component stack with legacy suppression as warning', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
|
||||
mockFilterResult({
|
||||
suppressDialog_LEGACY: true,
|
||||
monitorEvent: 'warning',
|
||||
});
|
||||
|
||||
LogBox.install();
|
||||
@@ -211,10 +222,12 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('registers errors with component stack and a forced dialog as fatals', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
|
||||
mockFilterResult({
|
||||
forceDialogImmediately: true,
|
||||
monitorEvent: 'warning',
|
||||
});
|
||||
|
||||
LogBox.install();
|
||||
@@ -229,7 +242,8 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('registers warning module errors with the formatting from filter', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
|
||||
mockFilterResult({
|
||||
finalFormat: 'Custom format',
|
||||
@@ -248,7 +262,8 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('registers warning module errors as errors by default', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
|
||||
mockFilterResult({});
|
||||
|
||||
@@ -262,10 +277,12 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('registers warning module errors with only legacy suppression as warning', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
|
||||
mockFilterResult({
|
||||
suppressDialog_LEGACY: true,
|
||||
monitorEvent: 'warning',
|
||||
});
|
||||
|
||||
LogBox.install();
|
||||
@@ -277,10 +294,12 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('registers warning module errors with a forced dialog as fatals', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
|
||||
mockFilterResult({
|
||||
forceDialogImmediately: true,
|
||||
monitorEvent: 'warning',
|
||||
});
|
||||
|
||||
LogBox.install();
|
||||
@@ -292,10 +311,12 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('ignores warning module errors that are suppressed completely', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
|
||||
mockFilterResult({
|
||||
suppressCompletely: true,
|
||||
monitorEvent: 'warning',
|
||||
});
|
||||
|
||||
LogBox.install();
|
||||
@@ -305,10 +326,11 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('ignores warning module errors that are pattern ignored', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
jest.spyOn(LogBoxData, 'isMessageIgnored').mockReturnValue(true);
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
|
||||
mockFilterResult({});
|
||||
(LogBoxData.isMessageIgnored: any).mockReturnValue(true);
|
||||
|
||||
LogBox.install();
|
||||
|
||||
@@ -317,10 +339,11 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('ignores warning module errors that are from LogBox itself', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
jest.spyOn(LogBoxData, 'isLogBoxErrorMessage').mockReturnValue(true);
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
|
||||
mockFilterResult({});
|
||||
(LogBoxData.isLogBoxErrorMessage: any).mockReturnValue(true);
|
||||
|
||||
LogBox.install();
|
||||
|
||||
@@ -329,8 +352,9 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('ignores logs that are pattern ignored"', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
(LogBoxData.isMessageIgnored: any).mockReturnValue(true);
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
jest.spyOn(LogBoxData, 'isMessageIgnored').mockReturnValue(true);
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
|
||||
LogBox.install();
|
||||
|
||||
@@ -339,8 +363,8 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('does not add logs that are from LogBox itself"', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
(LogBoxData.isLogBoxErrorMessage: any).mockReturnValue(true);
|
||||
jest.spyOn(LogBoxData, 'isLogBoxErrorMessage').mockReturnValue(true);
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
|
||||
LogBox.install();
|
||||
|
||||
@@ -349,7 +373,7 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('ignores logs starting with "(ADVICE)"', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
|
||||
LogBox.install();
|
||||
|
||||
@@ -358,7 +382,7 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('does not ignore logs formatted to start with "(ADVICE)"', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
|
||||
LogBox.install();
|
||||
|
||||
@@ -376,7 +400,7 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('ignores console methods after uninstalling', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
|
||||
LogBox.install();
|
||||
LogBox.uninstall();
|
||||
@@ -389,7 +413,7 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('does not add logs after uninstalling', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
|
||||
LogBox.install();
|
||||
LogBox.uninstall();
|
||||
@@ -406,7 +430,7 @@ describe('LogBox', () => {
|
||||
});
|
||||
|
||||
it('does not add exceptions after uninstalling', () => {
|
||||
jest.mock('../Data/LogBoxData');
|
||||
jest.spyOn(LogBoxData, 'addException');
|
||||
|
||||
LogBox.install();
|
||||
LogBox.uninstall();
|
||||
@@ -482,4 +506,80 @@ describe('LogBox', () => {
|
||||
'Custom: after installing for the second time',
|
||||
);
|
||||
});
|
||||
|
||||
it('registers errors with component stack as errors by default, when ExceptionManager is registered first', () => {
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
|
||||
ExceptionsManager.installConsoleErrorReporter();
|
||||
LogBox.install();
|
||||
|
||||
console.error(
|
||||
'HIT\n at Text (/path/to/Component:30:175)\n at DoesNotUseKey',
|
||||
);
|
||||
|
||||
expect(LogBoxData.addLog).toBeCalledWith(
|
||||
expect.objectContaining({level: 'error'}),
|
||||
);
|
||||
expect(LogBoxData.checkWarningFilter).toBeCalledWith(
|
||||
'HIT\n at Text (/path/to/Component:30:175)\n at DoesNotUseKey',
|
||||
);
|
||||
});
|
||||
|
||||
it('registers errors with component stack as errors by default, when ExceptionManager is registered second', () => {
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
jest.spyOn(LogBoxData, 'addLog');
|
||||
|
||||
LogBox.install();
|
||||
ExceptionsManager.installConsoleErrorReporter();
|
||||
|
||||
console.error(
|
||||
'HIT\n at Text (/path/to/Component:30:175)\n at DoesNotUseKey',
|
||||
);
|
||||
|
||||
expect(LogBoxData.addLog).toBeCalledWith(
|
||||
expect.objectContaining({level: 'error'}),
|
||||
);
|
||||
expect(LogBoxData.checkWarningFilter).toBeCalledWith(
|
||||
'HIT\n at Text (/path/to/Component:30:175)\n at DoesNotUseKey',
|
||||
);
|
||||
});
|
||||
|
||||
it('registers errors without component stack as errors by default, when ExceptionManager is registered first', () => {
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
jest.spyOn(LogBoxData, 'addException');
|
||||
|
||||
ExceptionsManager.installConsoleErrorReporter();
|
||||
LogBox.install();
|
||||
|
||||
console.error('HIT');
|
||||
|
||||
// Errors without a component stack skip the warning filter and
|
||||
// fall through to the ExceptionManager, which are then reported
|
||||
// back to LogBox as non-fatal exceptions, in a convuluted dance
|
||||
// in the most legacy cruft way.
|
||||
expect(LogBoxData.addException).toBeCalledWith(
|
||||
expect.objectContaining({originalMessage: 'HIT'}),
|
||||
);
|
||||
expect(LogBoxData.checkWarningFilter).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('registers errors without component stack as errors by default, when ExceptionManager is registered second', () => {
|
||||
jest.spyOn(LogBoxData, 'checkWarningFilter');
|
||||
jest.spyOn(LogBoxData, 'addException');
|
||||
|
||||
LogBox.install();
|
||||
ExceptionsManager.installConsoleErrorReporter();
|
||||
|
||||
console.error('HIT');
|
||||
|
||||
// Errors without a component stack skip the warning filter and
|
||||
// fall through to the ExceptionManager, which are then reported
|
||||
// back to LogBox as non-fatal exceptions, in a convuluted dance
|
||||
// in the most legacy cruft way.
|
||||
expect(LogBoxData.addException).toBeCalledWith(
|
||||
expect.objectContaining({originalMessage: 'HIT'}),
|
||||
);
|
||||
expect(LogBoxData.checkWarningFilter).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
+24
@@ -30,3 +30,27 @@ export const FragmentWithProp = () => {
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export const ManualConsoleError = () => {
|
||||
console.error('Manual console error');
|
||||
return (
|
||||
<React.Fragment>
|
||||
{['foo', 'bar'].map(item => (
|
||||
<Text key={item}>{item}</Text>
|
||||
))}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export const ManualConsoleErrorWithStack = () => {
|
||||
console.error(
|
||||
'Manual console error\n at ManualConsoleErrorWithStack (/path/to/ManualConsoleErrorWithStack:30:175)\n at TestApp',
|
||||
);
|
||||
return (
|
||||
<React.Fragment>
|
||||
{['foo', 'bar'].map(item => (
|
||||
<Text key={item}>{item}</Text>
|
||||
))}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ import type {RootTag} from '../Types/RootTagTypes';
|
||||
import type {IPerformanceLogger} from '../Utilities/createPerformanceLogger';
|
||||
import type {DisplayModeType} from './DisplayMode';
|
||||
|
||||
import BatchedBridge from '../BatchedBridge/BatchedBridge';
|
||||
import registerCallableModule from '../Core/registerCallableModule';
|
||||
import BugReporting from '../BugReporting/BugReporting';
|
||||
import createPerformanceLogger from '../Utilities/createPerformanceLogger';
|
||||
import infoLog from '../Utilities/infoLog';
|
||||
@@ -363,8 +363,8 @@ global.RN$SurfaceRegistry = {
|
||||
|
||||
if (global.RN$Bridgeless === true) {
|
||||
console.log('Bridgeless mode is enabled');
|
||||
} else {
|
||||
BatchedBridge.registerCallableModule('AppRegistry', AppRegistry);
|
||||
}
|
||||
|
||||
registerCallableModule('AppRegistry', AppRegistry);
|
||||
|
||||
module.exports = AppRegistry;
|
||||
|
||||
@@ -35,6 +35,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property (nonatomic, assign, readonly) CGFloat zoomScale;
|
||||
@property (nonatomic, assign, readonly) CGPoint contentOffset;
|
||||
@property (nonatomic, assign, readonly) UIEdgeInsets contentInset;
|
||||
@property (nullable, nonatomic, copy) NSDictionary<NSAttributedStringKey, id> *typingAttributes;
|
||||
|
||||
// This protocol disallows direct access to `selectedTextRange` property because
|
||||
// unwise usage of it can break the `delegate` behavior. So, we always have to
|
||||
|
||||
@@ -23,8 +23,8 @@ NSDictionary* RCTGetReactNativeVersion(void)
|
||||
__rnVersion = @{
|
||||
RCTVersionMajor: @(0),
|
||||
RCTVersionMinor: @(76),
|
||||
RCTVersionPatch: @(0),
|
||||
RCTVersionPrerelease: @"rc.4",
|
||||
RCTVersionPatch: @(2),
|
||||
RCTVersionPrerelease: [NSNull null],
|
||||
};
|
||||
});
|
||||
return __rnVersion;
|
||||
|
||||
+47
-3
@@ -61,6 +61,13 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
||||
*/
|
||||
BOOL _comingFromJS;
|
||||
BOOL _didMoveToWindow;
|
||||
|
||||
/*
|
||||
* Newly initialized default typing attributes contain a no-op NSParagraphStyle and NSShadow. These cause inequality
|
||||
* between the AttributedString backing the input and those generated from state. We store these attributes to make
|
||||
* later comparison insensitive to them.
|
||||
*/
|
||||
NSDictionary<NSAttributedStringKey, id> *_originalTypingAttributes;
|
||||
}
|
||||
|
||||
#pragma mark - UIView overrides
|
||||
@@ -76,6 +83,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
||||
_ignoreNextTextInputCall = NO;
|
||||
_comingFromJS = NO;
|
||||
_didMoveToWindow = NO;
|
||||
_originalTypingAttributes = [_backedTextInputView.typingAttributes copy];
|
||||
|
||||
[self addSubview:_backedTextInputView];
|
||||
[self initializeReturnKeyType];
|
||||
@@ -84,6 +92,20 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)updateEventEmitter:(const EventEmitter::Shared &)eventEmitter
|
||||
{
|
||||
[super updateEventEmitter:eventEmitter];
|
||||
|
||||
NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
|
||||
[_backedTextInputView.defaultTextAttributes mutableCopy];
|
||||
|
||||
RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
|
||||
eventEmitterWrapper.eventEmitter = _eventEmitter;
|
||||
defaultAttributes[RCTAttributedStringEventEmitterKey] = eventEmitterWrapper;
|
||||
|
||||
_backedTextInputView.defaultTextAttributes = defaultAttributes;
|
||||
}
|
||||
|
||||
- (void)didMoveToWindow
|
||||
{
|
||||
[super didMoveToWindow];
|
||||
@@ -236,8 +258,11 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
||||
}
|
||||
|
||||
if (newTextInputProps.textAttributes != oldTextInputProps.textAttributes) {
|
||||
_backedTextInputView.defaultTextAttributes =
|
||||
NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
|
||||
RCTNSTextAttributesFromTextAttributes(newTextInputProps.getEffectiveTextAttributes(RCTFontSizeMultiplier()));
|
||||
defaultAttributes[RCTAttributedStringEventEmitterKey] =
|
||||
_backedTextInputView.defaultTextAttributes[RCTAttributedStringEventEmitterKey];
|
||||
_backedTextInputView.defaultTextAttributes = defaultAttributes;
|
||||
}
|
||||
|
||||
if (newTextInputProps.selectionColor != oldTextInputProps.selectionColor) {
|
||||
@@ -418,6 +443,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
||||
|
||||
- (void)textInputDidChangeSelection
|
||||
{
|
||||
[self _updateTypingAttributes];
|
||||
if (_comingFromJS) {
|
||||
return;
|
||||
}
|
||||
@@ -674,9 +700,26 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
||||
[_backedTextInputView scrollRangeToVisible:NSMakeRange(offsetStart, 0)];
|
||||
}
|
||||
[self _restoreTextSelection];
|
||||
[self _updateTypingAttributes];
|
||||
_lastStringStateWasUpdatedWith = attributedString;
|
||||
}
|
||||
|
||||
// Ensure that newly typed text will inherit any custom attributes. We follow the logic of RN Android, where attributes
|
||||
// to the left of the cursor are copied into new text, unless we are at the start of the field, in which case we will
|
||||
// copy the attributes from text to the right. This allows consistency between backed input and new AttributedText
|
||||
// https://github.com/facebook/react-native/blob/3102a58df38d96f3dacef0530e4dbb399037fcd2/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/SetSpanOperation.kt#L30
|
||||
- (void)_updateTypingAttributes
|
||||
{
|
||||
if (_backedTextInputView.attributedText.length > 0) {
|
||||
NSUInteger offsetStart = [_backedTextInputView offsetFromPosition:_backedTextInputView.beginningOfDocument
|
||||
toPosition:_backedTextInputView.selectedTextRange.start];
|
||||
|
||||
NSUInteger samplePoint = offsetStart == 0 ? 0 : offsetStart - 1;
|
||||
_backedTextInputView.typingAttributes = [_backedTextInputView.attributedText attributesAtIndex:samplePoint
|
||||
effectiveRange:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_setMultiline:(BOOL)multiline
|
||||
{
|
||||
[_backedTextInputView removeFromSuperview];
|
||||
@@ -732,9 +775,10 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
||||
_backedTextInputView.markedTextRange || _backedTextInputView.isSecureTextEntry || fontHasBeenUpdatedBySystem;
|
||||
|
||||
if (shouldFallbackToBareTextComparison) {
|
||||
return ([newText.string isEqualToString:oldText.string]);
|
||||
return [newText.string isEqualToString:oldText.string];
|
||||
} else {
|
||||
return ([newText isEqualToAttributedString:oldText]);
|
||||
return RCTIsAttributedStringEffectivelySame(
|
||||
newText, oldText, _originalTypingAttributes, static_cast<const TextInputProps &>(*_props).textAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -833,6 +833,8 @@ static RCTBorderStyle RCTBorderStyleFromBorderStyle(BorderStyle borderStyle)
|
||||
_backgroundColorLayer.mask = maskLayer;
|
||||
_backgroundColorLayer.cornerRadius = 0;
|
||||
}
|
||||
|
||||
[_backgroundColorLayer removeAllAnimations];
|
||||
}
|
||||
|
||||
// borders
|
||||
|
||||
@@ -3306,7 +3306,6 @@ public final class com/facebook/react/modules/core/TimingModule : com/facebook/f
|
||||
public fun createTimer (DDDZ)V
|
||||
public fun deleteTimer (D)V
|
||||
public fun emitTimeDriftWarning (Ljava/lang/String;)V
|
||||
public fun initialize ()V
|
||||
public fun invalidate ()V
|
||||
public fun setSendIdleEvents (Z)V
|
||||
}
|
||||
@@ -3798,13 +3797,13 @@ public abstract class com/facebook/react/packagerconnection/NotificationOnlyHand
|
||||
public final fun onRequest (Ljava/lang/Object;Lcom/facebook/react/packagerconnection/Responder;)V
|
||||
}
|
||||
|
||||
public final class com/facebook/react/packagerconnection/PackagerConnectionSettings {
|
||||
public class com/facebook/react/packagerconnection/PackagerConnectionSettings {
|
||||
public fun <init> (Landroid/content/Context;)V
|
||||
public final fun getAdditionalOptionsForPackager ()Ljava/util/Map;
|
||||
public final fun getDebugServerHost ()Ljava/lang/String;
|
||||
public fun getDebugServerHost ()Ljava/lang/String;
|
||||
public final fun getPackageName ()Ljava/lang/String;
|
||||
public final fun setAdditionalOptionForPackager (Ljava/lang/String;Ljava/lang/String;)V
|
||||
public final fun setDebugServerHost (Ljava/lang/String;)V
|
||||
public fun setDebugServerHost (Ljava/lang/String;)V
|
||||
}
|
||||
|
||||
public final class com/facebook/react/packagerconnection/ReconnectingWebSocket : okhttp3/WebSocketListener {
|
||||
|
||||
@@ -557,7 +557,6 @@ android {
|
||||
listOf(
|
||||
"src/main/res/devsupport",
|
||||
"src/main/res/shell",
|
||||
"src/main/res/views/alert",
|
||||
"src/main/res/views/modal",
|
||||
"src/main/res/views/uimanager"))
|
||||
java.exclude("com/facebook/react/processing")
|
||||
|
||||
@@ -36,7 +36,7 @@ if(CMAKE_HOST_WIN32)
|
||||
endif()
|
||||
|
||||
file(GLOB input_SRC CONFIGURE_DEPENDS
|
||||
*.cpp
|
||||
${REACT_ANDROID_DIR}/cmake-utils/default-app-setup/*.cpp
|
||||
${BUILD_DIR}/generated/autolinking/src/main/jni/*.cpp)
|
||||
|
||||
add_library(${CMAKE_PROJECT_NAME} SHARED ${input_SRC})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION_NAME=0.76.0-rc.4
|
||||
VERSION_NAME=0.76.2
|
||||
react.internal.publishingGroup=com.facebook.react
|
||||
|
||||
android.useAndroidX=true
|
||||
|
||||
+4
-8
@@ -124,15 +124,11 @@ public abstract class HeadlessJsTaskService extends Service implements HeadlessJ
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
ReactContext reactContext = getReactContext();
|
||||
|
||||
if (getReactNativeHost().hasInstance()) {
|
||||
ReactInstanceManager reactInstanceManager = getReactNativeHost().getReactInstanceManager();
|
||||
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||
if (reactContext != null) {
|
||||
HeadlessJsTaskContext headlessJsTaskContext =
|
||||
HeadlessJsTaskContext.getInstance(reactContext);
|
||||
headlessJsTaskContext.removeTaskEventListener(this);
|
||||
}
|
||||
if (reactContext != null) {
|
||||
HeadlessJsTaskContext headlessJsTaskContext = HeadlessJsTaskContext.getInstance(reactContext);
|
||||
headlessJsTaskContext.removeTaskEventListener(this);
|
||||
}
|
||||
if (sWakeLock != null) {
|
||||
sWakeLock.release();
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@ import androidx.annotation.AnyThread
|
||||
import androidx.annotation.UiThread
|
||||
import com.facebook.infer.annotation.ThreadConfined
|
||||
import com.facebook.react.common.annotations.UnstableReactNativeAPI
|
||||
import com.facebook.react.uimanager.events.EventDispatcher
|
||||
|
||||
@OptIn(UnstableReactNativeAPI::class)
|
||||
public interface UIManager : PerformanceCounter {
|
||||
@@ -78,7 +79,7 @@ public interface UIManager : PerformanceCounter {
|
||||
public fun dispatchCommand(reactTag: Int, commandId: String, commandArgs: ReadableArray?)
|
||||
|
||||
/** @return the [EventDispatcher] object that is used by this class. */
|
||||
public fun <T> getEventDispatcher(): T
|
||||
public val eventDispatcher: EventDispatcher
|
||||
|
||||
/**
|
||||
* Used by native animated module to bypass the process of updating the values through the shadow
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ protected constructor(
|
||||
packages,
|
||||
jsMainModuleName,
|
||||
bundleAssetName ?: "index",
|
||||
null,
|
||||
jsBundleFile,
|
||||
isHermesEnabled ?: true,
|
||||
useDeveloperSupport,
|
||||
)
|
||||
|
||||
-1
@@ -1021,7 +1021,6 @@ public class FabricUIManager
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
@SuppressWarnings("unchecked")
|
||||
public EventDispatcher getEventDispatcher() {
|
||||
return mEventDispatcher;
|
||||
}
|
||||
|
||||
+2
@@ -65,6 +65,7 @@ public open class JavaTimerManager(
|
||||
|
||||
init {
|
||||
reactApplicationContext.addLifecycleEventListener(this)
|
||||
HeadlessJsTaskContext.getInstance(reactApplicationContext).addTaskEventListener(this)
|
||||
}
|
||||
|
||||
override fun onHostPause() {
|
||||
@@ -103,6 +104,7 @@ public open class JavaTimerManager(
|
||||
}
|
||||
|
||||
public open fun onInstanceDestroy() {
|
||||
HeadlessJsTaskContext.getInstance(reactApplicationContext).removeTaskEventListener(this)
|
||||
reactApplicationContext.removeLifecycleEventListener(this)
|
||||
clearFrameCallback()
|
||||
clearChoreographerIdleCallback()
|
||||
|
||||
-8
@@ -12,7 +12,6 @@ import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.bridge.WritableArray
|
||||
import com.facebook.react.common.annotations.VisibleForTesting
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager
|
||||
import com.facebook.react.jstasks.HeadlessJsTaskContext
|
||||
import com.facebook.react.module.annotations.ReactModule
|
||||
|
||||
/** Native module for JS timer execution. Timers fire on frame boundaries. */
|
||||
@@ -24,11 +23,6 @@ public class TimingModule(
|
||||
private val javaTimerManager: JavaTimerManager =
|
||||
JavaTimerManager(reactContext, this, ReactChoreographer.getInstance(), devSupportManager)
|
||||
|
||||
override fun initialize() {
|
||||
HeadlessJsTaskContext.getInstance(getReactApplicationContext())
|
||||
.addTaskEventListener(javaTimerManager)
|
||||
}
|
||||
|
||||
override fun createTimer(
|
||||
callbackIDDouble: Double,
|
||||
durationDouble: Double,
|
||||
@@ -68,8 +62,6 @@ public class TimingModule(
|
||||
}
|
||||
|
||||
override fun invalidate() {
|
||||
val headlessJsTaskContext = HeadlessJsTaskContext.getInstance(getReactApplicationContext())
|
||||
headlessJsTaskContext.removeTaskEventListener(javaTimerManager)
|
||||
javaTimerManager.onInstanceDestroy()
|
||||
}
|
||||
|
||||
|
||||
+5
-57
@@ -12,20 +12,11 @@ import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.view.AccessibilityDelegateCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.infer.annotation.Nullsafe;
|
||||
import com.facebook.react.R;
|
||||
|
||||
/** A fragment used to display the dialog. */
|
||||
@Nullsafe(Nullsafe.Mode.LOCAL)
|
||||
@@ -75,55 +66,15 @@ public class AlertFragment extends DialogFragment implements DialogInterface.OnC
|
||||
return isAppCompat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a custom dialog title View that has the role of "Heading" and focusable for
|
||||
* accessibility purposes.
|
||||
*
|
||||
* @returns accessible TextView title
|
||||
*/
|
||||
private static View getAccessibleTitle(Context activityContext, String titleText) {
|
||||
LayoutInflater inflater = LayoutInflater.from(activityContext);
|
||||
|
||||
// This layout matches the sizing and styling of AlertDialog's title_template (minus the icon)
|
||||
// since the whole thing gets tossed out when setting a custom title
|
||||
View titleContainer = inflater.inflate(R.layout.alert_title_layout, null);
|
||||
|
||||
TextView accessibleTitle =
|
||||
Assertions.assertNotNull(titleContainer.findViewById(R.id.alert_title));
|
||||
accessibleTitle.setText(titleText);
|
||||
accessibleTitle.setFocusable(true);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
accessibleTitle.setAccessibilityHeading(true);
|
||||
} else {
|
||||
ViewCompat.setAccessibilityDelegate(
|
||||
accessibleTitle,
|
||||
new AccessibilityDelegateCompat() {
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(
|
||||
View view, AccessibilityNodeInfoCompat info) {
|
||||
super.onInitializeAccessibilityNodeInfo(accessibleTitle, info);
|
||||
info.setHeading(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return titleContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a dialog compatible only with AppCompat activities. This function should be kept in
|
||||
* sync with {@link createAppDialog}.
|
||||
*/
|
||||
private static Dialog createAppCompatDialog(
|
||||
Context activityContext, Bundle arguments, DialogInterface.OnClickListener fragment) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activityContext);
|
||||
AlertDialog.Builder builder =
|
||||
new AlertDialog.Builder(activityContext).setTitle(arguments.getString(ARG_TITLE));
|
||||
|
||||
if (arguments.containsKey(ARG_TITLE)) {
|
||||
String title = Assertions.assertNotNull(arguments.getString(ARG_TITLE));
|
||||
View accessibleTitle = getAccessibleTitle(activityContext, title);
|
||||
builder.setCustomTitle(accessibleTitle);
|
||||
}
|
||||
if (arguments.containsKey(ARG_BUTTON_POSITIVE)) {
|
||||
builder.setPositiveButton(arguments.getString(ARG_BUTTON_POSITIVE), fragment);
|
||||
}
|
||||
@@ -154,13 +105,10 @@ public class AlertFragment extends DialogFragment implements DialogInterface.OnC
|
||||
@Deprecated(since = "0.75.0", forRemoval = true)
|
||||
private static Dialog createAppDialog(
|
||||
Context activityContext, Bundle arguments, DialogInterface.OnClickListener fragment) {
|
||||
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(activityContext);
|
||||
android.app.AlertDialog.Builder builder =
|
||||
new android.app.AlertDialog.Builder(activityContext)
|
||||
.setTitle(arguments.getString(ARG_TITLE));
|
||||
|
||||
if (arguments.containsKey(ARG_TITLE)) {
|
||||
String title = Assertions.assertNotNull(arguments.getString(ARG_TITLE));
|
||||
View accessibleTitle = getAccessibleTitle(activityContext, title);
|
||||
builder.setCustomTitle(accessibleTitle);
|
||||
}
|
||||
if (arguments.containsKey(ARG_BUTTON_POSITIVE)) {
|
||||
builder.setPositiveButton(arguments.getString(ARG_BUTTON_POSITIVE), fragment);
|
||||
}
|
||||
|
||||
+2
-2
@@ -17,6 +17,6 @@ public class ReactNativeVersion {
|
||||
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
|
||||
"major", 0,
|
||||
"minor", 76,
|
||||
"patch", 0,
|
||||
"prerelease", "rc.4");
|
||||
"patch", 2,
|
||||
"prerelease", null);
|
||||
}
|
||||
|
||||
+2
-2
@@ -15,13 +15,13 @@ import android.preference.PreferenceManager
|
||||
import com.facebook.common.logging.FLog
|
||||
import com.facebook.react.modules.systeminfo.AndroidInfoHelpers
|
||||
|
||||
public class PackagerConnectionSettings(private val appContext: Context) {
|
||||
public open class PackagerConnectionSettings(private val appContext: Context) {
|
||||
private val preferences: SharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(appContext)
|
||||
public val packageName: String = appContext.packageName
|
||||
private val _additionalOptionsForPackager: MutableMap<String, String> = mutableMapOf()
|
||||
|
||||
public var debugServerHost: String
|
||||
public open var debugServerHost: String
|
||||
get() {
|
||||
// Check host setting first. If empty try to detect emulator type and use default
|
||||
// hostname for those
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ import com.facebook.yoga.YogaConstants
|
||||
public abstract class BaseViewManagerDelegate<T : View, U : BaseViewManagerInterface<T>>(
|
||||
@Suppress("NoHungarianNotation") @JvmField protected val mViewManager: U
|
||||
) : ViewManagerDelegate<T> {
|
||||
override public fun setProperty(view: T, propName: String, value: Any?) {
|
||||
override public fun setProperty(view: T, propName: String?, value: Any?) {
|
||||
when (propName) {
|
||||
ViewProps.ACCESSIBILITY_ACTIONS ->
|
||||
mViewManager.setAccessibilityActions(view, value as ReadableArray?)
|
||||
@@ -104,6 +104,6 @@ public abstract class BaseViewManagerDelegate<T : View, U : BaseViewManagerInter
|
||||
}
|
||||
}
|
||||
|
||||
override public fun receiveCommand(view: T, commandName: String, args: ReadableArray?): Unit =
|
||||
override public fun receiveCommand(view: T, commandName: String?, args: ReadableArray?): Unit =
|
||||
Unit
|
||||
}
|
||||
|
||||
+19
-2
@@ -18,7 +18,24 @@ import com.facebook.react.bridge.ReadableArray
|
||||
* @param <T> the type of the view supported by this delegate </T>
|
||||
*/
|
||||
public interface ViewManagerDelegate<T : View?> {
|
||||
public fun setProperty(view: T, propName: String, value: Any?)
|
||||
|
||||
public fun receiveCommand(view: T, commandName: String, args: ReadableArray?)
|
||||
/**
|
||||
* Sets a property on a view managed by this view manager.
|
||||
*
|
||||
* @param view the view to set the property on
|
||||
* @param propName the name of the property to set (NOTE: should be `String` but is kept as
|
||||
* `String?` to avoid breaking changes)
|
||||
* @param value the value to set the property to
|
||||
*/
|
||||
public fun setProperty(view: T, propName: String?, value: Any?)
|
||||
|
||||
/**
|
||||
* Executes a command from JS to the view
|
||||
*
|
||||
* @param view the view to execute the command on
|
||||
* @param commandName the name of the command to execute (NOTE: should be `String` but is kept as
|
||||
* `String?` to avoid breaking changes)
|
||||
* @param args the arguments to pass to the command
|
||||
*/
|
||||
public fun receiveCommand(view: T, commandName: String?, args: ReadableArray?)
|
||||
}
|
||||
|
||||
+34
-17
@@ -26,6 +26,7 @@ import android.view.WindowManager
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
import android.widget.FrameLayout
|
||||
import androidx.annotation.UiThread
|
||||
import com.facebook.common.logging.FLog
|
||||
import com.facebook.react.R
|
||||
import com.facebook.react.bridge.GuardedRunnable
|
||||
import com.facebook.react.bridge.LifecycleEventListener
|
||||
@@ -33,6 +34,7 @@ import com.facebook.react.bridge.ReactContext
|
||||
import com.facebook.react.bridge.UiThreadUtil
|
||||
import com.facebook.react.bridge.WritableMap
|
||||
import com.facebook.react.bridge.WritableNativeMap
|
||||
import com.facebook.react.common.ReactConstants
|
||||
import com.facebook.react.common.annotations.VisibleForTesting
|
||||
import com.facebook.react.config.ReactFeatureFlags
|
||||
import com.facebook.react.uimanager.JSPointerDispatcher
|
||||
@@ -294,7 +296,14 @@ public class ReactModalHostView(context: ThemedReactContext) :
|
||||
* changed. This has the pleasant side-effect of us not having to preface all Modals with "top:
|
||||
* statusBarHeight", since that margin will be included in the FrameLayout.
|
||||
*/
|
||||
get() = FrameLayout(context).apply { addView(dialogRootViewGroup) }
|
||||
get() =
|
||||
FrameLayout(context).apply {
|
||||
addView(dialogRootViewGroup)
|
||||
if (!statusBarTranslucent) {
|
||||
// this is needed to prevent content hiding behind systems bars < API 30
|
||||
this.fitsSystemWindows = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* updateProperties will update the properties that do not require us to recreate the dialog
|
||||
@@ -306,29 +315,37 @@ public class ReactModalHostView(context: ThemedReactContext) :
|
||||
val dialogWindow =
|
||||
checkNotNull(dialog.window) { "dialog must have window when we call updateProperties" }
|
||||
val currentActivity = getCurrentActivity()
|
||||
if (currentActivity == null || currentActivity.isFinishing) {
|
||||
if (currentActivity == null || currentActivity.isFinishing || currentActivity.isDestroyed) {
|
||||
// If the activity has disappeared, then we shouldn't update the window associated to the
|
||||
// Dialog.
|
||||
return
|
||||
}
|
||||
val activityWindow = currentActivity.window
|
||||
if (activityWindow != null) {
|
||||
val activityWindowFlags = activityWindow.attributes.flags
|
||||
if ((activityWindowFlags and WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0) {
|
||||
dialogWindow.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
} else {
|
||||
dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
try {
|
||||
val activityWindow = currentActivity.window
|
||||
if (activityWindow != null) {
|
||||
val activityWindowFlags = activityWindow.attributes.flags
|
||||
if ((activityWindowFlags and WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0) {
|
||||
dialogWindow.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
} else {
|
||||
dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dialogWindow.setStatusBarTranslucency(statusBarTranslucent)
|
||||
dialogWindow.setStatusBarTranslucency(statusBarTranslucent)
|
||||
|
||||
if (transparent) {
|
||||
dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
||||
} else {
|
||||
dialogWindow.setDimAmount(0.5f)
|
||||
dialogWindow.setFlags(
|
||||
WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
||||
if (transparent) {
|
||||
dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
||||
} else {
|
||||
dialogWindow.setDimAmount(0.5f)
|
||||
dialogWindow.setFlags(
|
||||
WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
||||
}
|
||||
} catch (e: IllegalArgumentException) {
|
||||
// This is to prevent a crash from the following error, without a clear repro steps:
|
||||
// java.lang.IllegalArgumentException: View=DecorView@c94931b[XxxActivity] not attached to
|
||||
// window manager
|
||||
FLog.e(
|
||||
ReactConstants.TAG, "ReactModalHostView: error while setting window flags: ", e.message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical|start"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="?android:attr/dialogPreferredPadding"
|
||||
android:paddingTop="18dp"
|
||||
android:paddingEnd="?android:attr/dialogPreferredPadding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/alert_title"
|
||||
style="?android:attr/windowTitleStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textSize="18sp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -92,7 +92,7 @@ class RootViewTest {
|
||||
val eventEmitterModuleMock = mock(RCTEventEmitter::class.java)
|
||||
whenever(catalystInstanceMock.getNativeModule(UIManagerModule::class.java))
|
||||
.thenReturn(uiManager)
|
||||
whenever(uiManager.getEventDispatcher()).thenReturn(eventDispatcher)
|
||||
whenever(uiManager.eventDispatcher).thenReturn(eventDispatcher)
|
||||
|
||||
// RootView IDs is React Native follow the 11, 21, 31, ... progression.
|
||||
val rootViewId = 11
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ class NativeAnimatedNodeTraversalTest {
|
||||
|
||||
uiManagerMock = mock(UIManagerModule::class.java)
|
||||
eventDispatcherMock = mock(EventDispatcher::class.java)
|
||||
whenever(uiManagerMock.getEventDispatcher()).thenAnswer { eventDispatcherMock }
|
||||
whenever(uiManagerMock.eventDispatcher).thenAnswer { eventDispatcherMock }
|
||||
whenever(uiManagerMock.constants).thenAnswer {
|
||||
mapOf("customDirectEventTypes" to emptyMap<Any, Any>())
|
||||
}
|
||||
|
||||
+1
-1
@@ -488,7 +488,7 @@ class TouchEventDispatchTest {
|
||||
spy(FabricUIManager(reactContext, viewManagerRegistry, batchEventDispatchedListener))
|
||||
uiManager.initialize()
|
||||
|
||||
eventDispatcher = uiManager.getEventDispatcher()
|
||||
eventDispatcher = uiManager.eventDispatcher
|
||||
|
||||
// Ignore scheduled choreographer work
|
||||
val reactChoreographerMock = mock(ReactChoreographer::class.java)
|
||||
|
||||
+5
-1
@@ -17,6 +17,7 @@ import com.facebook.react.bridge.UIManagerListener
|
||||
import com.facebook.react.bridge.WritableMap
|
||||
import com.facebook.react.common.annotations.UnstableReactNativeAPI
|
||||
import com.facebook.react.fabric.interop.UIBlockViewResolver
|
||||
import com.facebook.react.uimanager.events.EventDispatcher
|
||||
|
||||
@OptIn(UnstableReactNativeAPI::class)
|
||||
class FakeUIManager : UIManager, UIBlockViewResolver {
|
||||
@@ -65,7 +66,10 @@ class FakeUIManager : UIManager, UIBlockViewResolver {
|
||||
error("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun <T : Any?> getEventDispatcher(): T {
|
||||
override val eventDispatcher: EventDispatcher
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
fun <T : Any?> getEventDispatcher(): T {
|
||||
error("Not yet implemented")
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace facebook::react {
|
||||
constexpr struct {
|
||||
int32_t Major = 0;
|
||||
int32_t Minor = 76;
|
||||
int32_t Patch = 0;
|
||||
std::string_view Prerelease = "rc.4";
|
||||
int32_t Patch = 2;
|
||||
std::string_view Prerelease = "";
|
||||
} ReactNativeVersion;
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
+3
-2
@@ -83,7 +83,7 @@ AttributedString TextInputShadowNode::getAttributedString(
|
||||
.string = getConcreteProps().text,
|
||||
.textAttributes = textAttributes,
|
||||
// TODO: Is this really meant to be by value?
|
||||
.parentShadowView = ShadowView{}});
|
||||
.parentShadowView = ShadowView(*this)});
|
||||
|
||||
auto attachments = Attachments{};
|
||||
BaseTextShadowNode::buildAttributedString(
|
||||
@@ -110,7 +110,8 @@ void TextInputShadowNode::updateStateIfNeeded(
|
||||
(!state.layoutManager || state.layoutManager == textLayoutManager_) &&
|
||||
"`StateData` refers to a different `TextLayoutManager`");
|
||||
|
||||
if (state.reactTreeAttributedString == reactTreeAttributedString &&
|
||||
if (state.reactTreeAttributedString.isContentEqual(
|
||||
reactTreeAttributedString) &&
|
||||
state.layoutManager == textLayoutManager_) {
|
||||
return;
|
||||
}
|
||||
|
||||
+12
-1
@@ -22,7 +22,7 @@ NSString *const RCTTextAttributesAccessibilityRoleAttributeName = @"Accessibilit
|
||||
/*
|
||||
* Creates `NSTextAttributes` from given `facebook::react::TextAttributes`
|
||||
*/
|
||||
NSDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(
|
||||
NSMutableDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(
|
||||
const facebook::react::TextAttributes &textAttributes);
|
||||
|
||||
/*
|
||||
@@ -41,6 +41,17 @@ NSString *RCTNSStringFromStringApplyingTextTransform(NSString *string, facebook:
|
||||
|
||||
void RCTApplyBaselineOffset(NSMutableAttributedString *attributedText);
|
||||
|
||||
/*
|
||||
* Whether two `NSAttributedString` lead to the same underlying displayed text, even if they are not strictly equal.
|
||||
* I.e. is one string substitutable for the other when backing a control (which may have some ignorable attributes
|
||||
* provided).
|
||||
*/
|
||||
BOOL RCTIsAttributedStringEffectivelySame(
|
||||
NSAttributedString *text1,
|
||||
NSAttributedString *text2,
|
||||
NSDictionary<NSAttributedStringKey, id> *insensitiveAttributes,
|
||||
const facebook::react::TextAttributes &baseTextAttributes);
|
||||
|
||||
@interface RCTWeakEventEmitterWrapper : NSObject
|
||||
@property (nonatomic, assign) facebook::react::SharedEventEmitter eventEmitter;
|
||||
@end
|
||||
|
||||
+165
-2
@@ -35,6 +35,24 @@ using namespace facebook::react;
|
||||
_weakEventEmitter.reset();
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
// We consider the underlying EventEmitter as the identity
|
||||
if (![object isKindOfClass:[self class]]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
auto thisEventEmitter = [self eventEmitter];
|
||||
auto otherEventEmitter = [((RCTWeakEventEmitterWrapper *)object) eventEmitter];
|
||||
return thisEventEmitter == otherEventEmitter;
|
||||
}
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
// We consider the underlying EventEmitter as the identity
|
||||
return (NSUInteger)_weakEventEmitter.lock().get();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
inline static UIFontWeight RCTUIFontWeightFromInteger(NSInteger fontWeight)
|
||||
@@ -178,7 +196,8 @@ inline static UIColor *RCTEffectiveBackgroundColorFromTextAttributes(const TextA
|
||||
return effectiveBackgroundColor ?: [UIColor clearColor];
|
||||
}
|
||||
|
||||
NSDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(const TextAttributes &textAttributes)
|
||||
NSMutableDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(
|
||||
const TextAttributes &textAttributes)
|
||||
{
|
||||
NSMutableDictionary<NSAttributedStringKey, id> *attributes = [NSMutableDictionary dictionaryWithCapacity:10];
|
||||
|
||||
@@ -302,7 +321,7 @@ NSDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(c
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = [NSString stringWithUTF8String:roleStr.c_str()];
|
||||
}
|
||||
|
||||
return [attributes copy];
|
||||
return attributes;
|
||||
}
|
||||
|
||||
void RCTApplyBaselineOffset(NSMutableAttributedString *attributedText)
|
||||
@@ -466,3 +485,147 @@ NSString *RCTNSStringFromStringApplyingTextTransform(NSString *string, TextTrans
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL RCTIsParagraphStyleEffectivelySame(
|
||||
NSParagraphStyle *style1,
|
||||
NSParagraphStyle *style2,
|
||||
const TextAttributes &baseTextAttributes)
|
||||
{
|
||||
if (style1 == nil || style2 == nil) {
|
||||
return style1 == nil && style2 == nil;
|
||||
}
|
||||
|
||||
// The NSParagraphStyle included as part of typingAttributes may eventually resolve "natural" directions to
|
||||
// physical direction, so we should compare resolved directions
|
||||
auto naturalAlignment =
|
||||
baseTextAttributes.layoutDirection.value_or(LayoutDirection::LeftToRight) == LayoutDirection::LeftToRight
|
||||
? NSTextAlignmentLeft
|
||||
: NSTextAlignmentRight;
|
||||
|
||||
NSWritingDirection naturalBaseWritingDirection = baseTextAttributes.baseWritingDirection.has_value()
|
||||
? RCTNSWritingDirectionFromWritingDirection(baseTextAttributes.baseWritingDirection.value())
|
||||
: [NSParagraphStyle defaultWritingDirectionForLanguage:nil];
|
||||
|
||||
if (style1.alignment == NSTextAlignmentNatural || style1.baseWritingDirection == NSWritingDirectionNatural) {
|
||||
NSMutableParagraphStyle *mutableStyle1 = [style1 mutableCopy];
|
||||
style1 = mutableStyle1;
|
||||
|
||||
if (mutableStyle1.alignment == NSTextAlignmentNatural) {
|
||||
mutableStyle1.alignment = naturalAlignment;
|
||||
}
|
||||
|
||||
if (mutableStyle1.baseWritingDirection == NSWritingDirectionNatural) {
|
||||
mutableStyle1.baseWritingDirection = naturalBaseWritingDirection;
|
||||
}
|
||||
}
|
||||
|
||||
if (style2.alignment == NSTextAlignmentNatural || style2.baseWritingDirection == NSWritingDirectionNatural) {
|
||||
NSMutableParagraphStyle *mutableStyle2 = [style2 mutableCopy];
|
||||
style2 = mutableStyle2;
|
||||
|
||||
if (mutableStyle2.alignment == NSTextAlignmentNatural) {
|
||||
mutableStyle2.alignment = naturalAlignment;
|
||||
}
|
||||
|
||||
if (mutableStyle2.baseWritingDirection == NSWritingDirectionNatural) {
|
||||
mutableStyle2.baseWritingDirection = naturalBaseWritingDirection;
|
||||
}
|
||||
}
|
||||
|
||||
return [style1 isEqual:style2];
|
||||
}
|
||||
|
||||
static BOOL RCTIsAttributeEffectivelySame(
|
||||
NSAttributedStringKey attributeKey,
|
||||
NSDictionary<NSAttributedStringKey, id> *attributes1,
|
||||
NSDictionary<NSAttributedStringKey, id> *attributes2,
|
||||
NSDictionary<NSAttributedStringKey, id> *insensitiveAttributes,
|
||||
const TextAttributes &baseTextAttributes)
|
||||
{
|
||||
id attribute1 = attributes1[attributeKey] ?: insensitiveAttributes[attributeKey];
|
||||
id attribute2 = attributes2[attributeKey] ?: insensitiveAttributes[attributeKey];
|
||||
|
||||
// Normalize attributes which can inexact but still effectively the same
|
||||
if ([attributeKey isEqualToString:NSParagraphStyleAttributeName]) {
|
||||
return RCTIsParagraphStyleEffectivelySame(attribute1, attribute2, baseTextAttributes);
|
||||
}
|
||||
|
||||
// Otherwise rely on built-in comparison
|
||||
return [attribute1 isEqual:attribute2];
|
||||
}
|
||||
|
||||
BOOL RCTIsAttributedStringEffectivelySame(
|
||||
NSAttributedString *text1,
|
||||
NSAttributedString *text2,
|
||||
NSDictionary<NSAttributedStringKey, id> *insensitiveAttributes,
|
||||
const TextAttributes &baseTextAttributes)
|
||||
{
|
||||
if (![text1.string isEqualToString:text2.string]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
// We check that for every fragment in the old string
|
||||
// 1. The new string's fragment overlapping the first spans the same characters
|
||||
// 2. The attributes of each matching fragment are the same, ignoring those which match insensitive attibutes
|
||||
__block BOOL areAttributesSame = YES;
|
||||
[text1 enumerateAttributesInRange:NSMakeRange(0, text1.length)
|
||||
options:0
|
||||
usingBlock:^(
|
||||
NSDictionary<NSAttributedStringKey, id> *text1Attributes,
|
||||
NSRange text1Range,
|
||||
BOOL *text1Stop) {
|
||||
[text2 enumerateAttributesInRange:text1Range
|
||||
options:0
|
||||
usingBlock:^(
|
||||
NSDictionary<NSAttributedStringKey, id> *text2Attributes,
|
||||
NSRange text2Range,
|
||||
BOOL *text2Stop) {
|
||||
if (!NSEqualRanges(text1Range, text2Range)) {
|
||||
areAttributesSame = NO;
|
||||
*text1Stop = YES;
|
||||
*text2Stop = YES;
|
||||
return;
|
||||
}
|
||||
|
||||
// Compare every attribute in text1 to the corresponding attribute
|
||||
// in text2, or the set of insensitive attributes if not present
|
||||
for (NSAttributedStringKey key in text1Attributes) {
|
||||
if (!RCTIsAttributeEffectivelySame(
|
||||
key,
|
||||
text1Attributes,
|
||||
text2Attributes,
|
||||
insensitiveAttributes,
|
||||
baseTextAttributes)) {
|
||||
areAttributesSame = NO;
|
||||
*text1Stop = YES;
|
||||
*text2Stop = YES;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (NSAttributedStringKey key in text2Attributes) {
|
||||
// We have already compared this attribute if it is present in
|
||||
// both
|
||||
if (text1Attributes[key] != nil) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// But we still need to compare attributes if it is only present
|
||||
// in text 2, to compare against insensitive attributes
|
||||
if (!RCTIsAttributeEffectivelySame(
|
||||
key,
|
||||
text1Attributes,
|
||||
text2Attributes,
|
||||
insensitiveAttributes,
|
||||
baseTextAttributes)) {
|
||||
areAttributesSame = NO;
|
||||
*text1Stop = YES;
|
||||
*text2Stop = YES;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}];
|
||||
}];
|
||||
|
||||
return areAttributesSame;
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -204,7 +204,7 @@ async function main() {
|
||||
|
||||
const proc = spawn(
|
||||
'npx',
|
||||
['@react-native-community/cli', ...process.argv.slice(2)],
|
||||
['@react-native-community/cli@latest', ...process.argv.slice(2)],
|
||||
{
|
||||
stdio: 'inherit',
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "A framework for building native apps using React",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -109,13 +109,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@jest/create-cache-key-function": "^29.6.3",
|
||||
"@react-native/assets-registry": "0.76.0-rc.4",
|
||||
"@react-native/codegen": "0.76.0-rc.4",
|
||||
"@react-native/community-cli-plugin": "0.76.0-rc.4",
|
||||
"@react-native/gradle-plugin": "0.76.0-rc.4",
|
||||
"@react-native/js-polyfills": "0.76.0-rc.4",
|
||||
"@react-native/normalize-colors": "0.76.0-rc.4",
|
||||
"@react-native/virtualized-lists": "0.76.0-rc.4",
|
||||
"@react-native/assets-registry": "0.76.2",
|
||||
"@react-native/codegen": "0.76.2",
|
||||
"@react-native/community-cli-plugin": "0.76.2",
|
||||
"@react-native/gradle-plugin": "0.76.2",
|
||||
"@react-native/js-polyfills": "0.76.2",
|
||||
"@react-native/normalize-colors": "0.76.2",
|
||||
"@react-native/virtualized-lists": "0.76.2",
|
||||
"abort-controller": "^3.0.0",
|
||||
"anser": "^1.4.9",
|
||||
"ansi-regex": "^5.0.0",
|
||||
@@ -131,8 +131,8 @@
|
||||
"jest-environment-node": "^29.6.3",
|
||||
"jsc-android": "^250231.0.0",
|
||||
"memoize-one": "^5.0.0",
|
||||
"metro-runtime": "^0.81.0-alpha.2",
|
||||
"metro-source-map": "^0.81.0-alpha.2",
|
||||
"metro-runtime": "^0.81.0",
|
||||
"metro-source-map": "^0.81.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"nullthrows": "^1.1.1",
|
||||
"pretty-format": "^29.7.0",
|
||||
|
||||
@@ -12,19 +12,33 @@ class NewArchitectureHelper
|
||||
@@NewArchWarningEmitted = false # Used not to spam warnings to the user.
|
||||
|
||||
def self.set_clang_cxx_language_standard_if_needed(installer)
|
||||
cxxBuildsettingsName = "CLANG_CXX_LANGUAGE_STANDARD"
|
||||
projects = installer.aggregate_targets
|
||||
.map{ |t| t.user_project }
|
||||
.uniq{ |p| p.path }
|
||||
|
||||
projects.each do |project|
|
||||
Pod::UI.puts("Setting CLANG_CXX_LANGUAGE_STANDARD to #{ Helpers::Constants::cxx_language_standard } on #{ project.path }")
|
||||
Pod::UI.puts("Setting #{cxxBuildsettingsName} to #{ Helpers::Constants::cxx_language_standard } on #{ project.path }")
|
||||
|
||||
project.build_configurations.each do |config|
|
||||
config.build_settings["CLANG_CXX_LANGUAGE_STANDARD"] = Helpers::Constants::cxx_language_standard
|
||||
config.build_settings[cxxBuildsettingsName] = Helpers::Constants::cxx_language_standard
|
||||
end
|
||||
|
||||
project.save()
|
||||
end
|
||||
|
||||
installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result|
|
||||
target_installation_result.native_target.build_configurations.each do |config|
|
||||
config.build_settings[cxxBuildsettingsName] = Helpers::Constants::cxx_language_standard
|
||||
end
|
||||
end
|
||||
|
||||
# Override targets that would set spec.xcconfig to define c++ version
|
||||
installer.aggregate_targets.each do |aggregate_target|
|
||||
aggregate_target.xcconfigs.each do |config_name, config_file|
|
||||
config_file.attributes[cxxBuildsettingsName] = Helpers::Constants::cxx_language_standard
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.computeFlags(is_new_arch_enabled)
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
require 'shellwords'
|
||||
|
||||
require_relative "./helpers.rb"
|
||||
|
||||
# Utilities class for React Native Cocoapods
|
||||
@@ -237,8 +239,8 @@ class ReactNativePodsUtils
|
||||
# When installing pods with a yarn alias, yarn creates a fake yarn and node executables
|
||||
# in a temporary folder.
|
||||
# Using `node --print "process.argv[0]";` we are able to retrieve the actual path from which node is running.
|
||||
# see https://github.com/facebook/react-native/issues/43285 for more info
|
||||
node_binary = `node --print "process.argv[0]";`
|
||||
# see https://github.com/facebook/react-native/issues/43285 for more info. We've tweaked this slightly.
|
||||
node_binary = Shellwords.escape(`node --print "process.argv[0]"`.strip)
|
||||
system("echo 'export NODE_BINARY=#{node_binary}' > #{file_path}.local")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -489,11 +489,22 @@ function rootCodegenTargetNeedsThirdPartyComponentProvider(pkgJson, platform) {
|
||||
return !pkgJsonIncludesGeneratedCode(pkgJson) && platform === 'ios';
|
||||
}
|
||||
|
||||
function dependencyNeedsThirdPartyComponentProvider(schemaInfo, platform) {
|
||||
function dependencyNeedsThirdPartyComponentProvider(
|
||||
schemaInfo,
|
||||
platform,
|
||||
appCodegenConfigSpec,
|
||||
) {
|
||||
// Filter the react native core library out.
|
||||
// In the future, core library and third party library should
|
||||
// use the same way to generate/register the fabric components.
|
||||
return !isReactNativeCoreLibrary(schemaInfo.library.config.name, platform);
|
||||
// We also have to filter out the the components defined in the app
|
||||
// because the RCTThirdPartyComponentProvider is generated inside Fabric,
|
||||
// which lives in a different target from the app and it has no visibility over
|
||||
// the symbols defined in the app.
|
||||
return (
|
||||
!isReactNativeCoreLibrary(schemaInfo.library.config.name, platform) &&
|
||||
schemaInfo.library.config.name !== appCodegenConfigSpec
|
||||
);
|
||||
}
|
||||
|
||||
function mustGenerateNativeCode(includeLibraryPath, schemaInfo) {
|
||||
@@ -704,8 +715,12 @@ function execute(projectRoot, targetPlatform, baseOutputPath) {
|
||||
if (
|
||||
rootCodegenTargetNeedsThirdPartyComponentProvider(pkgJson, platform)
|
||||
) {
|
||||
const filteredSchemas = schemaInfos.filter(
|
||||
dependencyNeedsThirdPartyComponentProvider,
|
||||
const filteredSchemas = schemaInfos.filter(schemaInfo =>
|
||||
dependencyNeedsThirdPartyComponentProvider(
|
||||
schemaInfo,
|
||||
platform,
|
||||
pkgJson.codegenConfig?.name,
|
||||
),
|
||||
);
|
||||
const schemas = filteredSchemas.map(schemaInfo => schemaInfo.schema);
|
||||
const supportedApplePlatforms = filteredSchemas.map(
|
||||
|
||||
@@ -1 +1 @@
|
||||
hermes-2024-09-09-RNv0.76.0-db6d12e202e15f7a446d8848d6ca8f7abb3cfb32
|
||||
hermes-2024-11-12-RNv0.76.2-5b4aa20c719830dcf5684832b89a6edb95ac3d64
|
||||
@@ -41,6 +41,7 @@ declare module 'react-native/Libraries/Utilities/codegenNativeComponent' {
|
||||
|
||||
declare module 'react-native/Libraries/Types/CodegenTypes' {
|
||||
import type {NativeSyntheticEvent} from 'react-native';
|
||||
import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
|
||||
|
||||
// Event types
|
||||
// We're not using the PaperName, it is only used to codegen view config settings
|
||||
@@ -59,6 +60,7 @@ declare module 'react-native/Libraries/Types/CodegenTypes' {
|
||||
export type Float = number;
|
||||
export type Int32 = number;
|
||||
export type UnsafeObject = object;
|
||||
export type UnsafeMixed = unknown;
|
||||
|
||||
type DefaultTypes = number | boolean | string | ReadonlyArray<string>;
|
||||
// Default handling, ignore the unused value
|
||||
@@ -71,4 +73,8 @@ declare module 'react-native/Libraries/Types/CodegenTypes' {
|
||||
Type extends DefaultTypes,
|
||||
Value extends Type | string | undefined | null,
|
||||
> = Type | undefined | null;
|
||||
|
||||
export type EventEmitter<T> = (
|
||||
handler: (arg: T) => void | Promise<void>,
|
||||
) => EventSubscription;
|
||||
}
|
||||
|
||||
@@ -8,3 +8,4 @@ ruby ">= 2.6.10"
|
||||
gem 'cocoapods', '~> 1.13', '!= 1.15.0', '!= 1.15.1'
|
||||
gem 'rexml'
|
||||
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
|
||||
gem 'xcodeproj', '< 1.26.0'
|
||||
|
||||
+286
-286
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/tester",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"private": true,
|
||||
"description": "React Native tester app.",
|
||||
"license": "MIT",
|
||||
@@ -23,8 +23,8 @@
|
||||
"clean-ios": "rm -rf build/generated/ios Pods Podfile.lock"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": "0.76.0-rc.4",
|
||||
"@react-native/popup-menu-android": "0.76.0-rc.4",
|
||||
"@react-native/oss-library-example": "0.76.2",
|
||||
"@react-native/popup-menu-android": "0.76.2",
|
||||
"flow-enums-runtime": "^0.0.6",
|
||||
"invariant": "^2.2.4",
|
||||
"nullthrows": "^1.1.1"
|
||||
@@ -42,8 +42,8 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@react-native-community/cli": "15.0.0-alpha.2",
|
||||
"@react-native-community/cli-platform-android": "15.0.0-alpha.2",
|
||||
"@react-native-community/cli-platform-ios": "15.0.0-alpha.2"
|
||||
"@react-native-community/cli": "15.0.1",
|
||||
"@react-native-community/cli-platform-android": "15.0.1",
|
||||
"@react-native-community/cli-platform-ios": "15.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/typescript-config",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Default TypeScript configuration for React Native apps",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/virtualized-lists",
|
||||
"version": "0.76.0-rc.4",
|
||||
"version": "0.76.2",
|
||||
"description": "Virtualized lists for React Native.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1091,7 +1091,18 @@
|
||||
"@babel/plugin-transform-modules-commonjs" "^7.24.7"
|
||||
"@babel/plugin-transform-typescript" "^7.24.7"
|
||||
|
||||
"@babel/register@^7.13.16", "@babel/register@^7.24.6":
|
||||
"@babel/register@7.22.5":
|
||||
version "7.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.5.tgz#e4d8d0f615ea3233a27b5c6ada6750ee59559939"
|
||||
integrity sha512-vV6pm/4CijSQ8Y47RH5SopXzursN35RQINfGJkmOlcpAtGuf94miFvIPhCKGQN7WGIcsgG1BHEX2KVdTYwTwUQ==
|
||||
dependencies:
|
||||
clone-deep "^4.0.1"
|
||||
find-cache-dir "^2.0.0"
|
||||
make-dir "^2.1.0"
|
||||
pirates "^4.0.5"
|
||||
source-map-support "^0.5.16"
|
||||
|
||||
"@babel/register@^7.13.16":
|
||||
version "7.24.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.24.6.tgz#59e21dcc79e1d04eed5377633b0f88029a6bef9e"
|
||||
integrity sha512-WSuFCc2wCqMeXkz/i3yfAAsxwWflEgbVkZzivgAmXl/MxrXeoYFZOOPllbC8R8WTF7u61wSRQtDVZ1879cdu6w==
|
||||
@@ -1123,7 +1134,20 @@
|
||||
"@babel/parser" "^7.25.0"
|
||||
"@babel/types" "^7.25.0"
|
||||
|
||||
"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3", "@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3", "@babel/traverse@^7.25.4":
|
||||
"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3":
|
||||
version "7.25.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.6.tgz#04fad980e444f182ecf1520504941940a90fea41"
|
||||
integrity sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.24.7"
|
||||
"@babel/generator" "^7.25.6"
|
||||
"@babel/parser" "^7.25.6"
|
||||
"@babel/template" "^7.25.0"
|
||||
"@babel/types" "^7.25.6"
|
||||
debug "^4.3.1"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3", "@babel/traverse@^7.25.4":
|
||||
version "7.25.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.6.tgz#04fad980e444f182ecf1520504941940a90fea41"
|
||||
integrity sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==
|
||||
@@ -1747,45 +1771,55 @@
|
||||
optionalDependencies:
|
||||
npmlog "2 || ^3.1.0 || ^4.0.0"
|
||||
|
||||
"@react-native-community/cli-clean@15.0.0-alpha.2":
|
||||
version "15.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-15.0.0-alpha.2.tgz#c6598086cd1432deaa2bed82f6d2833feb112091"
|
||||
integrity sha512-QNq5lZpoxGHIneKBB1S8hSpvgFYGST7CP1GWrgrmOaIieNFsh2oWhTePzGyxUgxr0i0qzolmWwuwqqyIPMUSyQ==
|
||||
"@react-native-community/cli-clean@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-15.0.1.tgz#80ce09ffe0d62bb265447007f24dc8dcbf8fe7d3"
|
||||
integrity sha512-flGTfT005UZvW2LAXVowZ/7ri22oiiZE4pPgMvc8klRxO5uofKIRuohgiHybHtiCo/HNqIz45JmZJvuFrhc4Ow==
|
||||
dependencies:
|
||||
"@react-native-community/cli-tools" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-tools" "15.0.1"
|
||||
chalk "^4.1.2"
|
||||
execa "^5.0.0"
|
||||
fast-glob "^3.3.2"
|
||||
|
||||
"@react-native-community/cli-config@15.0.0-alpha.2":
|
||||
version "15.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-15.0.0-alpha.2.tgz#fe535e9174593041ec0c8e6abbb9cb4127195315"
|
||||
integrity sha512-gkmVP7s5sR74HOz2unPsRdNTEmwQyzpeEcB2OI3g35WAyccpYO7OpmpE1PlQ0O9qKdQlQJKbL7fq2DhqswVAdg==
|
||||
"@react-native-community/cli-config-apple@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-config-apple/-/cli-config-apple-15.0.1.tgz#2d845599eada1b479df6716a25dc871c3d202f38"
|
||||
integrity sha512-GEHUx4NRp9W9or6vygn0TgNeFkcJdNjrtko0vQEJAS4gJdWqP/9LqqwJNlUfaW5jHBN7TKALAMlfRmI12Op3sg==
|
||||
dependencies:
|
||||
"@react-native-community/cli-tools" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-tools" "15.0.1"
|
||||
chalk "^4.1.2"
|
||||
execa "^5.0.0"
|
||||
fast-glob "^3.3.2"
|
||||
|
||||
"@react-native-community/cli-config@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-15.0.1.tgz#fe44472757ebca4348fe4861ceaf9d4daff26767"
|
||||
integrity sha512-SL3/9zIyzQQPKWei0+W1gNHxCPurrxqpODUWnVLoP38DNcvYCGtsRayw/4DsXgprZfBC+FsscNpd3IDJrG59XA==
|
||||
dependencies:
|
||||
"@react-native-community/cli-tools" "15.0.1"
|
||||
chalk "^4.1.2"
|
||||
cosmiconfig "^9.0.0"
|
||||
deepmerge "^4.3.0"
|
||||
fast-glob "^3.3.2"
|
||||
joi "^17.2.1"
|
||||
|
||||
"@react-native-community/cli-debugger-ui@15.0.0-alpha.2":
|
||||
version "15.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-15.0.0-alpha.2.tgz#8ee14142c270c83fb5072050cad4f97e99ec5e5a"
|
||||
integrity sha512-odOFpsOgbCc2si2+D16eyeY4h4u3qu12XssRGV8VqvhKLh0khQ/wA6y01/1ghy1sA0Pus1LyBwFEix6X3epXBw==
|
||||
"@react-native-community/cli-debugger-ui@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-15.0.1.tgz#bed0d7af5ecb05222bdb7d6e74e21326a583bcf1"
|
||||
integrity sha512-xkT2TLS8zg5r7Vl9l/2f7JVUoFECnVBS+B5ivrSu2PNZhKkr9lRmJFxC9aVLFb5lIxQQKNDvEyiIDNfP7wjJiA==
|
||||
dependencies:
|
||||
serve-static "^1.13.1"
|
||||
|
||||
"@react-native-community/cli-doctor@15.0.0-alpha.2":
|
||||
version "15.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-15.0.0-alpha.2.tgz#d83c4146111c5f3c2e2468d6cdcb4e76ed0e4e37"
|
||||
integrity sha512-kcBwSUMmD0AGP+kvlxTkzGlMLxOqCZIJ6pBbpnTPAhSjYrvYzHNZTTYqeggcACR7mlERot0t6tJvXeGHP1s59g==
|
||||
"@react-native-community/cli-doctor@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-15.0.1.tgz#63cc42e7302f2bfa3739b29fea57b68d5d68fa03"
|
||||
integrity sha512-YCu44lZR3zZxJJYVTqYZFz9cT9KBfbKI4q2MnKOvkamt00XY3usooMqfuwBAdvM/yvpx7M5w8kbM/nPyj4YCvQ==
|
||||
dependencies:
|
||||
"@react-native-community/cli-config" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-platform-android" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-platform-apple" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-platform-ios" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-tools" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-config" "15.0.1"
|
||||
"@react-native-community/cli-platform-android" "15.0.1"
|
||||
"@react-native-community/cli-platform-apple" "15.0.1"
|
||||
"@react-native-community/cli-platform-ios" "15.0.1"
|
||||
"@react-native-community/cli-tools" "15.0.1"
|
||||
chalk "^4.1.2"
|
||||
command-exists "^1.2.8"
|
||||
deepmerge "^4.3.0"
|
||||
@@ -1798,44 +1832,43 @@
|
||||
wcwidth "^1.0.1"
|
||||
yaml "^2.2.1"
|
||||
|
||||
"@react-native-community/cli-platform-android@15.0.0-alpha.2":
|
||||
version "15.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-15.0.0-alpha.2.tgz#479f743086fb3c853d9a8038e26035d25776db7c"
|
||||
integrity sha512-cKHbENaYreKCRtF8cSgTX3mn8XeupTVNzF57tWtOq6Prs+9Bd8ZsOylFZEvkyb3wY1S+BFDAXebAGzbL9ZlY3w==
|
||||
"@react-native-community/cli-platform-android@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-15.0.1.tgz#9706fe454d0e2af4680c3ea1937830c93041a35f"
|
||||
integrity sha512-QlAMomj6H6TY6pHwjTYMsHDQLP5eLzjAmyW1qb03w/kyS/72elK2bjsklNWJrscFY9TMQLqw7qoAsXf1m5t/dg==
|
||||
dependencies:
|
||||
"@react-native-community/cli-tools" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-tools" "15.0.1"
|
||||
chalk "^4.1.2"
|
||||
execa "^5.0.0"
|
||||
fast-glob "^3.3.2"
|
||||
fast-xml-parser "^4.4.1"
|
||||
logkitty "^0.7.1"
|
||||
|
||||
"@react-native-community/cli-platform-apple@15.0.0-alpha.2":
|
||||
version "15.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-apple/-/cli-platform-apple-15.0.0-alpha.2.tgz#561272ec7bf6cbedf8737cf1b71566b63e9b704b"
|
||||
integrity sha512-eXE6KES4mNWQA1c/d+aWQnNsgjD7rdrsMAH4t0xOhXn4XWCw1FF6Y7PjUY8fi784RFIzEYB2xiVMvWQsC6BmAQ==
|
||||
"@react-native-community/cli-platform-apple@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-apple/-/cli-platform-apple-15.0.1.tgz#af3c9bc910c96e823a488c21e7d68a9b4a07c8d1"
|
||||
integrity sha512-iQj1Dt2fr/Q7X2CQhyhWnece3eLDCark1osfiwpViksOfTH2WdpNS3lIwlFcIKhsieFU7YYwbNuFqQ3tF9Dlvw==
|
||||
dependencies:
|
||||
"@react-native-community/cli-tools" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-config-apple" "15.0.1"
|
||||
"@react-native-community/cli-tools" "15.0.1"
|
||||
chalk "^4.1.2"
|
||||
execa "^5.0.0"
|
||||
fast-glob "^3.3.2"
|
||||
fast-xml-parser "^4.4.1"
|
||||
ora "^5.4.1"
|
||||
|
||||
"@react-native-community/cli-platform-ios@15.0.0-alpha.2":
|
||||
version "15.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-15.0.0-alpha.2.tgz#c237e561d60d3aa463d51327b37e6943910f7bb5"
|
||||
integrity sha512-7teqYOMf7SnBmUbSeGklDS2lJCpAa1LKzmy/L8vFiayWImUTJHKzkJyZNzhmiLSImcibFYVH7uaD2DWuFNcrOQ==
|
||||
"@react-native-community/cli-platform-ios@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-15.0.1.tgz#a1cb78c3d43b9c2bbb411a074ef11364f2a94bbf"
|
||||
integrity sha512-6pKzXEIgGL20eE1uOn8iSsNBlMzO1LG+pQOk+7mvD172EPhKm/lRzUVDX5gO/2jvsGoNw6VUW0JX1FI2firwqA==
|
||||
dependencies:
|
||||
"@react-native-community/cli-platform-apple" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-platform-apple" "15.0.1"
|
||||
|
||||
"@react-native-community/cli-server-api@15.0.0-alpha.2":
|
||||
version "15.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-15.0.0-alpha.2.tgz#37dcfe41cc7204e01290c616c9262e5e71f70424"
|
||||
integrity sha512-e4bHsl/J006+coMTOpj6i44QPDat/X2s1sc3rqQkFL5vHIduB+Z6IyDI+W9F5uHrJhtQukE5NdajkjcXyjGLVA==
|
||||
"@react-native-community/cli-server-api@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-15.0.1.tgz#e7975e7638343248835fd379803d557c0ae24d75"
|
||||
integrity sha512-f3rb3t1ELLaMSX5/LWO/IykglBIgiP3+pPnyl8GphHnBpf3bdIcp7fHlHLemvHE06YxT2nANRxRPjy1gNskenA==
|
||||
dependencies:
|
||||
"@react-native-community/cli-debugger-ui" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-tools" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-debugger-ui" "15.0.1"
|
||||
"@react-native-community/cli-tools" "15.0.1"
|
||||
compression "^1.7.1"
|
||||
connect "^3.6.5"
|
||||
errorhandler "^1.5.1"
|
||||
@@ -1844,10 +1877,10 @@
|
||||
serve-static "^1.13.1"
|
||||
ws "^6.2.3"
|
||||
|
||||
"@react-native-community/cli-tools@15.0.0-alpha.2":
|
||||
version "15.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-15.0.0-alpha.2.tgz#0c02c61a30730814925d6c1e08d43b57ec083f24"
|
||||
integrity sha512-XzjIFizlqLtwHqhFJHbYfedFOIebFEt1bdLSsHi2HSiZQlltW8KTwWiHC1VHfoEpePErvP2/jsx/dZtX7wNNSw==
|
||||
"@react-native-community/cli-tools@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-15.0.1.tgz#3cc5398da72b5d365eb4a30468ebce2bf37fa591"
|
||||
integrity sha512-N79A+u/94roanfmNohVcNGu6Xg+0idh63JHZFLC9OJJuZwTifGMLDfSTHZATpR1J7rebozQ5ClcSUePavErnSg==
|
||||
dependencies:
|
||||
appdirsjs "^1.2.4"
|
||||
chalk "^4.1.2"
|
||||
@@ -1856,29 +1889,30 @@
|
||||
mime "^2.4.1"
|
||||
open "^6.2.0"
|
||||
ora "^5.4.1"
|
||||
prompts "^2.4.2"
|
||||
semver "^7.5.2"
|
||||
shell-quote "^1.7.3"
|
||||
sudo-prompt "^9.0.0"
|
||||
|
||||
"@react-native-community/cli-types@15.0.0-alpha.2":
|
||||
version "15.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-15.0.0-alpha.2.tgz#12d62c7e928115758bbb7de6ded3d21a57dbb7b9"
|
||||
integrity sha512-5gLZKQLG4ejrMEzdBw0KaGcX7jTTpWoGypxqL+8sQ7Pkenklfsr1RJRFxv+hzO/yX9psMFMgZUXluLajWwuvcg==
|
||||
"@react-native-community/cli-types@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-15.0.1.tgz#ebdb5bc76ade44b2820174fdcb2a3a05999686ec"
|
||||
integrity sha512-sWiJ62kkGu2mgYni2dsPxOMBzpwTjNsDH1ubY4mqcNEI9Zmzs0vRwwDUEhYqwNGys9+KpBKoZRrT2PAlhO84xA==
|
||||
dependencies:
|
||||
joi "^17.2.1"
|
||||
|
||||
"@react-native-community/cli@15.0.0-alpha.2":
|
||||
version "15.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-15.0.0-alpha.2.tgz#e465127a176a9eac3f0c1e4a16bd1830627fbbfb"
|
||||
integrity sha512-Yf7kupKmEuytelafCNeNug4ZAC0i7GPgKVyXfRhwVtVp5ykXtWcng2bqPa4YRl4fgWgu5JhoOQhVMEV1cUDzAA==
|
||||
"@react-native-community/cli@15.0.1":
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-15.0.1.tgz#d703d55cc6540ce3d29fd2fbf3303bea0ffd96f2"
|
||||
integrity sha512-xIGPytx2bj5HxFk0c7S25AVuJowHmEFg5LFC9XosKc0TSOjP1r6zGC6OqC/arQV/pNuqmZN2IFnpgJn0Bn+hhQ==
|
||||
dependencies:
|
||||
"@react-native-community/cli-clean" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-config" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-debugger-ui" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-doctor" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-server-api" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-tools" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-types" "15.0.0-alpha.2"
|
||||
"@react-native-community/cli-clean" "15.0.1"
|
||||
"@react-native-community/cli-config" "15.0.1"
|
||||
"@react-native-community/cli-debugger-ui" "15.0.1"
|
||||
"@react-native-community/cli-doctor" "15.0.1"
|
||||
"@react-native-community/cli-server-api" "15.0.1"
|
||||
"@react-native-community/cli-tools" "15.0.1"
|
||||
"@react-native-community/cli-types" "15.0.1"
|
||||
chalk "^4.1.2"
|
||||
commander "^9.4.1"
|
||||
deepmerge "^4.3.0"
|
||||
@@ -2810,6 +2844,20 @@ babel-plugin-syntax-hermes-parser@0.23.1, babel-plugin-syntax-hermes-parser@^0.2
|
||||
dependencies:
|
||||
hermes-parser "0.23.1"
|
||||
|
||||
babel-plugin-syntax-hermes-parser@0.24.0:
|
||||
version "0.24.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.24.0.tgz#79d0c73daae7bd7d4b07f64ee281c75aa48845cf"
|
||||
integrity sha512-J4wETqz7ehbyYl2uge65zsfr0Ue+0yJYYMMkGAWpZc0fB02z4JAcx+mJEXVU14yiihGwqVUlR7oS4/gDYOxUdA==
|
||||
dependencies:
|
||||
hermes-parser "0.24.0"
|
||||
|
||||
babel-plugin-syntax-hermes-parser@^0.25.1:
|
||||
version "0.25.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.25.1.tgz#58b539df973427fcfbb5176a3aec7e5dee793cb0"
|
||||
integrity sha512-IVNpGzboFLfXZUAwkLFcI/bnqVbwky0jP3eBno4HKtqvQJAHBLdgxiG6lQ4to0+Q/YCN3PO0od5NZwIKyY4REQ==
|
||||
dependencies:
|
||||
hermes-parser "0.25.1"
|
||||
|
||||
babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0:
|
||||
version "7.0.0-beta.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf"
|
||||
@@ -4890,6 +4938,16 @@ hermes-estree@0.23.1:
|
||||
resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.23.1.tgz#d0bac369a030188120ee7024926aabe5a9f84fdb"
|
||||
integrity sha512-eT5MU3f5aVhTqsfIReZ6n41X5sYn4IdQL0nvz6yO+MMlPxw49aSARHLg/MSehQftyjnrE8X6bYregzSumqc6cg==
|
||||
|
||||
hermes-estree@0.24.0:
|
||||
version "0.24.0"
|
||||
resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.24.0.tgz#487dc1ddc0bae698c2d79f34153ac9bf62d7b3c0"
|
||||
integrity sha512-LyoXLB7IFzeZW0EvAbGZacbxBN7t6KKSDqFJPo3Ydow7wDlrDjXwsdiAHV6XOdvEN9MEuWXsSIFN4tzpyrXIHw==
|
||||
|
||||
hermes-estree@0.25.1:
|
||||
version "0.25.1"
|
||||
resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.25.1.tgz#6aeec17d1983b4eabf69721f3aa3eb705b17f480"
|
||||
integrity sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==
|
||||
|
||||
hermes-parser@0.23.1:
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.23.1.tgz#e5de648e664f3b3d84d01b48fc7ab164f4b68205"
|
||||
@@ -4897,6 +4955,20 @@ hermes-parser@0.23.1:
|
||||
dependencies:
|
||||
hermes-estree "0.23.1"
|
||||
|
||||
hermes-parser@0.24.0:
|
||||
version "0.24.0"
|
||||
resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.24.0.tgz#2ed19d079efc0848eb1f800f0c393a074c4696fb"
|
||||
integrity sha512-IJooSvvu2qNRe7oo9Rb04sUT4omtZqZqf9uq9WM25Tb6v3usmvA93UqfnnoWs5V0uYjEl9Al6MNU10MCGKLwpg==
|
||||
dependencies:
|
||||
hermes-estree "0.24.0"
|
||||
|
||||
hermes-parser@0.25.1:
|
||||
version "0.25.1"
|
||||
resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.25.1.tgz#5be0e487b2090886c62bd8a11724cd766d5f54d1"
|
||||
integrity sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==
|
||||
dependencies:
|
||||
hermes-estree "0.25.1"
|
||||
|
||||
hermes-transform@0.23.1:
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/hermes-transform/-/hermes-transform-0.23.1.tgz#ea6d401117db8398de9723dc1cf936a9a3c8477b"
|
||||
@@ -6360,76 +6432,76 @@ merge2@^1.3.0, merge2@^1.4.1:
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||
|
||||
metro-babel-register@^0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.81.0-alpha.2.tgz#3ed905de8b7079a63483871e692bb17deabe656c"
|
||||
integrity sha512-XBSStCShFqU487ee7gfj23N9tU65NN9axIv/BxL9Kl1bA91/lXn82X8QaAlcyzOv8+ulSm96h1JN/jnmCVotgA==
|
||||
metro-babel-register@^0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.81.0.tgz#05e9deda5633e38aceb7120b1865cbbc63c5b8ef"
|
||||
integrity sha512-CU9D49k9ti02ebHXuYlbDNPdBj0C4SnCDIGk328epmcO0p++WzFSWWO92cGc7i0HqKyzgeMskPGJV825Eh7zSg==
|
||||
dependencies:
|
||||
"@babel/core" "^7.25.2"
|
||||
"@babel/plugin-proposal-export-namespace-from" "^7.18.9"
|
||||
"@babel/plugin-transform-flow-strip-types" "^7.25.2"
|
||||
"@babel/plugin-transform-modules-commonjs" "^7.24.8"
|
||||
"@babel/preset-typescript" "^7.24.7"
|
||||
"@babel/register" "^7.24.6"
|
||||
"@babel/register" "7.22.5"
|
||||
babel-plugin-replace-ts-export-assignment "^0.0.2"
|
||||
babel-plugin-syntax-hermes-parser "0.23.1"
|
||||
babel-plugin-syntax-hermes-parser "0.24.0"
|
||||
babel-plugin-transform-flow-enums "^0.0.2"
|
||||
escape-string-regexp "^1.0.5"
|
||||
flow-enums-runtime "^0.0.6"
|
||||
|
||||
metro-babel-transformer@0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.81.0-alpha.2.tgz#b4e3173c342c986c0b98acd72c64ee4da4c37ee1"
|
||||
integrity sha512-OGjDXZGthGnMKH6GGrCYomXl5JT3CXhbPQe9Q0T2+AvFG5OYj4/SAhxqPZ0LgJ+aGAubCD30WoYJ+CZ0H1eEmg==
|
||||
metro-babel-transformer@0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.81.0.tgz#cf468eafea52e4d8a77844eb7257f8a76e9d9d94"
|
||||
integrity sha512-Dc0QWK4wZIeHnyZ3sevWGTnnSkIDDn/SWyfrn99zbKbDOCoCYy71PAn9uCRrP/hduKLJQOy+tebd63Rr9D8tXg==
|
||||
dependencies:
|
||||
"@babel/core" "^7.25.2"
|
||||
flow-enums-runtime "^0.0.6"
|
||||
hermes-parser "0.23.1"
|
||||
hermes-parser "0.24.0"
|
||||
nullthrows "^1.1.1"
|
||||
|
||||
metro-cache-key@0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.81.0-alpha.2.tgz#85dff024d894b44f9d61422786063074e6345403"
|
||||
integrity sha512-XE6LdsTrz5lBWznCKUBGrGlwQrbrHp37Q0SLRgG3xGDI33QmGD8U9DdY4siyGUdo+JD+h1T1RfAM72zWefn9Sw==
|
||||
metro-cache-key@0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.81.0.tgz#5db34fa1a323a2310205bda7abd0df9614e36f45"
|
||||
integrity sha512-qX/IwtknP9bQZL78OK9xeSvLM/xlGfrs6SlUGgHvrxtmGTRSsxcyqxR+c+7ch1xr05n62Gin/O44QKg5V70rNQ==
|
||||
dependencies:
|
||||
flow-enums-runtime "^0.0.6"
|
||||
|
||||
metro-cache@0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.81.0-alpha.2.tgz#044d1132c66ffb6f49a4c5c70591296e0125908f"
|
||||
integrity sha512-fAnaC/PTY0CxG4oaHWYd6JIKUF7lPswHEQvrAcULohdc7qdaOlLZwhIn5+IbhGoi2wYmygNtJAQ75dmaW5udQw==
|
||||
metro-cache@0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.81.0.tgz#90470d10d190ad708f04c6e337eec2c7cddb3db0"
|
||||
integrity sha512-DyuqySicHXkHUDZFVJmh0ygxBSx6pCKUrTcSgb884oiscV/ROt1Vhye+x+OIHcsodyA10gzZtrVtxIFV4l9I4g==
|
||||
dependencies:
|
||||
exponential-backoff "^3.1.1"
|
||||
flow-enums-runtime "^0.0.6"
|
||||
metro-core "0.81.0-alpha.2"
|
||||
metro-core "0.81.0"
|
||||
|
||||
metro-config@0.81.0-alpha.2, metro-config@^0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.81.0-alpha.2.tgz#a110744b72c1397d818568b3b4dc8e096fb58393"
|
||||
integrity sha512-HcAxiXW3nahJBKB2RmM7v+Y1hDsBw0tQWIksmIoRTEm6LqF0XbrONEg0MS5sGvWSe3TH3+hG/CWA9Brs9kuKuA==
|
||||
metro-config@0.81.0, metro-config@^0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.81.0.tgz#8f8074033cb7e9ddb5b0459642adf6880bc9fbc1"
|
||||
integrity sha512-6CinEaBe3WLpRlKlYXXu8r1UblJhbwD6Gtnoib5U8j6Pjp7XxMG9h/DGMeNp9aGLDu1OieUqiXpFo7O0/rR5Kg==
|
||||
dependencies:
|
||||
connect "^3.6.5"
|
||||
cosmiconfig "^5.0.5"
|
||||
flow-enums-runtime "^0.0.6"
|
||||
jest-validate "^29.6.3"
|
||||
metro "0.81.0-alpha.2"
|
||||
metro-cache "0.81.0-alpha.2"
|
||||
metro-core "0.81.0-alpha.2"
|
||||
metro-runtime "0.81.0-alpha.2"
|
||||
metro "0.81.0"
|
||||
metro-cache "0.81.0"
|
||||
metro-core "0.81.0"
|
||||
metro-runtime "0.81.0"
|
||||
|
||||
metro-core@0.81.0-alpha.2, metro-core@^0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.81.0-alpha.2.tgz#bf997b05bda00491194c95934ce5b1374f8d093e"
|
||||
integrity sha512-U8bknkQK0a15F5ZPku5QP/ZmnYxhbYY5X+Pw0Gx+rpkeWf8vdfB+4r/usuzIh9kaZErZHTZNEMI7dZ4/4boRpQ==
|
||||
metro-core@0.81.0, metro-core@^0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.81.0.tgz#d0b634f9cf97849b7730c59457ab7a439811d4c8"
|
||||
integrity sha512-CVkM5YCOAFkNMvJai6KzA0RpztzfEKRX62/PFMOJ9J7K0uq/UkOFLxcgpcncMIrfy0PbfEj811b69tjULUQe1Q==
|
||||
dependencies:
|
||||
flow-enums-runtime "^0.0.6"
|
||||
lodash.throttle "^4.1.1"
|
||||
metro-resolver "0.81.0-alpha.2"
|
||||
metro-resolver "0.81.0"
|
||||
|
||||
metro-file-map@0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.81.0-alpha.2.tgz#450310f28da447f6e6438acf1bc387895c58d416"
|
||||
integrity sha512-bR/V5oKIk2OTNpTx9Xy2pYKDEUYbngUs/YsLFDkK4YFuO1FDJZxTcPr6sgMSJignz/AC2gx/oO3zpbO7I3GKJQ==
|
||||
metro-file-map@0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.81.0.tgz#af0ccf4f8db4fd8429f78f231faa49dde2c402c3"
|
||||
integrity sha512-zMDI5uYhQCyxbye/AuFx/pAbsz9K+vKL7h1ShUXdN2fz4VUPiyQYRsRqOoVG1DsiCgzd5B6LW0YW77NFpjDQeg==
|
||||
dependencies:
|
||||
anymatch "^3.0.3"
|
||||
debug "^2.2.0"
|
||||
@@ -6445,69 +6517,69 @@ metro-file-map@0.81.0-alpha.2:
|
||||
optionalDependencies:
|
||||
fsevents "^2.3.2"
|
||||
|
||||
metro-memory-fs@^0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.81.0-alpha.2.tgz#241280cc64ade326f1ffb1df6fc77506de7f9858"
|
||||
integrity sha512-4owL5ha/vNmwZvHhIQ48lZ1gSqbaIHOpt1Mmv3iQoe/z9Foe+SYLTPbCU3Dt5yK9oWDvkBYKag66LxPoCsPLRA==
|
||||
metro-memory-fs@^0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.81.0.tgz#f11ac95bb294f3fd4c933cf93ab9ee6da626d352"
|
||||
integrity sha512-hbmyOuVigPU81Kd+CUCq7tXgEkrHmteWG1WJHTEwldoLHuYUzSeaoE8LlLUbqPF+OPW0asYx/cTDrfNM8KCuqw==
|
||||
dependencies:
|
||||
flow-enums-runtime "^0.0.6"
|
||||
|
||||
metro-minify-terser@0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.81.0-alpha.2.tgz#bd844986ef08f6c5f7ae57828ae973256bb27000"
|
||||
integrity sha512-cAqqFWP5UO0ImNu7c3xIrXCLltvm9OIng2kIe/+nU9CC70K7pATxdtWpC0PA9dt2MsfY2583i3pu/rr5qIY0Yw==
|
||||
metro-minify-terser@0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.81.0.tgz#8b0abe977d63a99b99fa94d53678ef3170d5b659"
|
||||
integrity sha512-U2ramh3W822ZR1nfXgIk+emxsf5eZSg10GbQrT0ZizImK8IZ5BmJY+BHRIkQgHzWFpExOVxC7kWbGL1bZALswA==
|
||||
dependencies:
|
||||
flow-enums-runtime "^0.0.6"
|
||||
terser "^5.15.0"
|
||||
|
||||
metro-resolver@0.81.0-alpha.2, metro-resolver@^0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.81.0-alpha.2.tgz#30402262f96ee1f1aa43408b1f91508a50da1be5"
|
||||
integrity sha512-C4KGAki0jeUq1wqFrsD0R6FgmYL+6weDuze/5SolMmBflaU03hY9ZiQUsNuEWgU7+OG+A0q6PBwcskBUXBpW6Q==
|
||||
metro-resolver@0.81.0, metro-resolver@^0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.81.0.tgz#141f4837e1e0c5a1810ea02f2d9be3c9f6cf3766"
|
||||
integrity sha512-Uu2Q+buHhm571cEwpPek8egMbdSTqmwT/5U7ZVNpK6Z2ElQBBCxd7HmFAslKXa7wgpTO2FAn6MqGeERbAtVDUA==
|
||||
dependencies:
|
||||
flow-enums-runtime "^0.0.6"
|
||||
|
||||
metro-runtime@0.81.0-alpha.2, metro-runtime@^0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.81.0-alpha.2.tgz#216f02d5473799379403db71a0a6ec1b791197f6"
|
||||
integrity sha512-uP+7ejq7R+WOV39TucJsgeRalA8jlw5l3JtID+Iu8zZvzJT0WO4VlINAFVS5n6Xk7tK+dkqGH1oF0lst1X+qNw==
|
||||
metro-runtime@0.81.0, metro-runtime@^0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.81.0.tgz#63af9b3fec15d1f307d89ef4881f5ba2c592291e"
|
||||
integrity sha512-6oYB5HOt37RuGz2eV4A6yhcl+PUTwJYLDlY9vhT+aVjbUWI6MdBCf69vc4f5K5Vpt+yOkjy+2LDwLS0ykWFwYw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.25.0"
|
||||
flow-enums-runtime "^0.0.6"
|
||||
|
||||
metro-source-map@0.81.0-alpha.2, metro-source-map@^0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.81.0-alpha.2.tgz#c8264efda5e312cb87a9b0ac78b7eb0e6808c92a"
|
||||
integrity sha512-R5obOY4guE8D2fckCjoYrf+NHWwiorOBPSLr9jXLKXqdo7c3dCG9Fp9U1vJc4qKTJjhHN+bHND/+Ih8UPHH9zg==
|
||||
metro-source-map@0.81.0, metro-source-map@^0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.81.0.tgz#ca83964124bb227d5f0bdb1ee304dbfe635f869e"
|
||||
integrity sha512-TzsVxhH83dyxg4A4+L1nzNO12I7ps5IHLjKGZH3Hrf549eiZivkdjYiq/S5lOB+p2HiQ+Ykcwtmcja95LIC62g==
|
||||
dependencies:
|
||||
"@babel/traverse" "^7.25.3"
|
||||
"@babel/traverse--for-generate-function-map" "npm:@babel/traverse@^7.25.3"
|
||||
"@babel/types" "^7.25.2"
|
||||
flow-enums-runtime "^0.0.6"
|
||||
invariant "^2.2.4"
|
||||
metro-symbolicate "0.81.0-alpha.2"
|
||||
metro-symbolicate "0.81.0"
|
||||
nullthrows "^1.1.1"
|
||||
ob1 "0.81.0-alpha.2"
|
||||
ob1 "0.81.0"
|
||||
source-map "^0.5.6"
|
||||
vlq "^1.0.0"
|
||||
|
||||
metro-symbolicate@0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.81.0-alpha.2.tgz#7aebb285b516b03df09ac8b3cc57611f7642db94"
|
||||
integrity sha512-S5v09d93mg3C8iGwAZwhDwiDg5kW7DnGi9OOvb8+gtBJ9EzxV9/z3BPG1NFkzQ/ymnIEUcaQ1N8BpEgrXnsI6g==
|
||||
metro-symbolicate@0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.81.0.tgz#b7b1eae8bfd6ad2a922fa2bcb9f2144e464adafb"
|
||||
integrity sha512-C/1rWbNTPYp6yzID8IPuQPpVGzJ2rbWYBATxlvQ9dfK5lVNoxcwz77hjcY8ISLsRRR15hyd/zbjCNKPKeNgE1Q==
|
||||
dependencies:
|
||||
flow-enums-runtime "^0.0.6"
|
||||
invariant "^2.2.4"
|
||||
metro-source-map "0.81.0-alpha.2"
|
||||
metro-source-map "0.81.0"
|
||||
nullthrows "^1.1.1"
|
||||
source-map "^0.5.6"
|
||||
through2 "^2.0.1"
|
||||
vlq "^1.0.0"
|
||||
|
||||
metro-transform-plugins@0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.81.0-alpha.2.tgz#7fd204f91975c4dc8145d613b54f982ec892ba84"
|
||||
integrity sha512-VtK38ytQ9mK1v/JOm1wW1AvZjO/Fsd8krNZy6riRj2fstcKkNx6LL1j5TtwINBUjCY1WPrpunQtG+Wc98LMiHQ==
|
||||
metro-transform-plugins@0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.81.0.tgz#614c0e50593df545487b3f3383fed810c608fb32"
|
||||
integrity sha512-uErLAPBvttGCrmGSCa0dNHlOTk3uJFVEVWa5WDg6tQ79PRmuYRwzUgLhVzn/9/kyr75eUX3QWXN79Jvu4txt6Q==
|
||||
dependencies:
|
||||
"@babel/core" "^7.25.2"
|
||||
"@babel/generator" "^7.25.0"
|
||||
@@ -6516,29 +6588,29 @@ metro-transform-plugins@0.81.0-alpha.2:
|
||||
flow-enums-runtime "^0.0.6"
|
||||
nullthrows "^1.1.1"
|
||||
|
||||
metro-transform-worker@0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.81.0-alpha.2.tgz#a18a386139c9e74e189e5bc94c6d6028aba35ba7"
|
||||
integrity sha512-DBzR0gf7rBB42NDFuZ9hfTrvpSNDnKSHsp+TKMBtsVRtb3UpbnuH1iiO7HNV7Dro5E8nNjkYuUnLE6tC6CNFYQ==
|
||||
metro-transform-worker@0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.81.0.tgz#43e63c95014f36786f0e1a132c778c6392950de7"
|
||||
integrity sha512-HrQ0twiruhKy0yA+9nK5bIe3WQXZcC66PXTvRIos61/EASLAP2DzEmW7IxN/MGsfZegN2UzqL2CG38+mOB45vg==
|
||||
dependencies:
|
||||
"@babel/core" "^7.25.2"
|
||||
"@babel/generator" "^7.25.0"
|
||||
"@babel/parser" "^7.25.3"
|
||||
"@babel/types" "^7.25.2"
|
||||
flow-enums-runtime "^0.0.6"
|
||||
metro "0.81.0-alpha.2"
|
||||
metro-babel-transformer "0.81.0-alpha.2"
|
||||
metro-cache "0.81.0-alpha.2"
|
||||
metro-cache-key "0.81.0-alpha.2"
|
||||
metro-minify-terser "0.81.0-alpha.2"
|
||||
metro-source-map "0.81.0-alpha.2"
|
||||
metro-transform-plugins "0.81.0-alpha.2"
|
||||
metro "0.81.0"
|
||||
metro-babel-transformer "0.81.0"
|
||||
metro-cache "0.81.0"
|
||||
metro-cache-key "0.81.0"
|
||||
metro-minify-terser "0.81.0"
|
||||
metro-source-map "0.81.0"
|
||||
metro-transform-plugins "0.81.0"
|
||||
nullthrows "^1.1.1"
|
||||
|
||||
metro@0.81.0-alpha.2, metro@^0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/metro/-/metro-0.81.0-alpha.2.tgz#69059bda8f4194809d206cfae89ff2f06a53e5a7"
|
||||
integrity sha512-ZfL5IjEEuMtM5A5tVKL2LNv/WO6Gj1RhdIsW+3uz3BB0Y/ZqMdfp61qVWNCV7kGWMqunee3ER0P1EUuPHfIb0Q==
|
||||
metro@0.81.0, metro@^0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/metro/-/metro-0.81.0.tgz#cffe9b7d597728dee8b57903ca155417b7c13a4f"
|
||||
integrity sha512-kzdzmpL0gKhEthZ9aOV7sTqvg6NuTxDV8SIm9pf9sO8VVEbKrQk5DNcwupOUjgPPFAuKUc2NkT0suyT62hm2xg==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.24.7"
|
||||
"@babel/core" "^7.25.2"
|
||||
@@ -6556,24 +6628,24 @@ metro@0.81.0-alpha.2, metro@^0.81.0-alpha.2:
|
||||
error-stack-parser "^2.0.6"
|
||||
flow-enums-runtime "^0.0.6"
|
||||
graceful-fs "^4.2.4"
|
||||
hermes-parser "0.23.1"
|
||||
hermes-parser "0.24.0"
|
||||
image-size "^1.0.2"
|
||||
invariant "^2.2.4"
|
||||
jest-worker "^29.6.3"
|
||||
jsc-safe-url "^0.2.2"
|
||||
lodash.throttle "^4.1.1"
|
||||
metro-babel-transformer "0.81.0-alpha.2"
|
||||
metro-cache "0.81.0-alpha.2"
|
||||
metro-cache-key "0.81.0-alpha.2"
|
||||
metro-config "0.81.0-alpha.2"
|
||||
metro-core "0.81.0-alpha.2"
|
||||
metro-file-map "0.81.0-alpha.2"
|
||||
metro-resolver "0.81.0-alpha.2"
|
||||
metro-runtime "0.81.0-alpha.2"
|
||||
metro-source-map "0.81.0-alpha.2"
|
||||
metro-symbolicate "0.81.0-alpha.2"
|
||||
metro-transform-plugins "0.81.0-alpha.2"
|
||||
metro-transform-worker "0.81.0-alpha.2"
|
||||
metro-babel-transformer "0.81.0"
|
||||
metro-cache "0.81.0"
|
||||
metro-cache-key "0.81.0"
|
||||
metro-config "0.81.0"
|
||||
metro-core "0.81.0"
|
||||
metro-file-map "0.81.0"
|
||||
metro-resolver "0.81.0"
|
||||
metro-runtime "0.81.0"
|
||||
metro-source-map "0.81.0"
|
||||
metro-symbolicate "0.81.0"
|
||||
metro-transform-plugins "0.81.0"
|
||||
metro-transform-worker "0.81.0"
|
||||
mime-types "^2.1.27"
|
||||
nullthrows "^1.1.1"
|
||||
serialize-error "^2.1.0"
|
||||
@@ -6851,10 +6923,10 @@ oauth-sign@~0.9.0:
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
||||
|
||||
ob1@0.81.0-alpha.2:
|
||||
version "0.81.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.81.0-alpha.2.tgz#45ac7fc423577fee88425476908793905df6a3c5"
|
||||
integrity sha512-wii3uNfV58CK6KzM6o1HzlUAYZJbsbNm3dQHMQJeTok6jZzF/aDYZrbuI4U4V4HkKxrHL2QgRf2rKDlDU9Au9g==
|
||||
ob1@0.81.0:
|
||||
version "0.81.0"
|
||||
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.81.0.tgz#dc3154cca7aa9c2eb58f5ac63e9ee23ff4c6f520"
|
||||
integrity sha512-6Cvrkxt1tqaRdWqTAMcVYEiO5i1xcF9y7t06nFdjFqkfPsEloCf8WwhXdwBpNUkVYSQlSGS7cDgVQR86miBfBQ==
|
||||
dependencies:
|
||||
flow-enums-runtime "^0.0.6"
|
||||
|
||||
@@ -7177,7 +7249,7 @@ pinpoint@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/pinpoint/-/pinpoint-1.1.0.tgz#0cf7757a6977f1bf7f6a32207b709e377388e874"
|
||||
integrity sha512-+04FTD9x7Cls2rihLlo57QDCcHoLBGn5Dk51SwtFBWkUWLxZaBXyNVpCw1S+atvE7GmnFjeaRZ0WLq3UYuqAdg==
|
||||
|
||||
pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.6:
|
||||
pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.5, pirates@^4.0.6:
|
||||
version "4.0.6"
|
||||
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9"
|
||||
integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==
|
||||
|
||||
Reference in New Issue
Block a user