Skip to content
This repository was archived by the owner on May 4, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('devices info', () => {
const file = path.join(projectRoot, '.expo', 'devices.json');
expect(fs.existsSync(file)).toBe(true);

const { devices } = JSON.parse(fs.readFileSync(file, 'utf8').toString());
const { devices } = JSON.parse(fs.readFileSync(file, 'utf8'));
expect(devices.length).toBe(1);
expect(devices[0].installationId).toBe('test-device-id');
});
Expand Down
4 changes: 2 additions & 2 deletions packages/@expo/cli/src/utils/mergeGitIgnorePaths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export function mergeGitIgnorePaths(
return null;
}

const targetGitIgnore = fs.readFileSync(targetGitIgnorePath).toString();
const sourceGitIgnore = fs.readFileSync(sourceGitIgnorePath).toString();
const targetGitIgnore = fs.readFileSync(targetGitIgnorePath, 'utf8');
const sourceGitIgnore = fs.readFileSync(sourceGitIgnorePath, 'utf8');
const merged = mergeGitIgnoreContents(targetGitIgnore, sourceGitIgnore);
// Only rewrite the file if it was modified.
if (merged.contents) {
Expand Down
4 changes: 2 additions & 2 deletions packages/@expo/config-plugins/src/android/Package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export async function renameJniOnDiskForType({
filesToUpdate.forEach((filepath: string) => {
try {
if (fs.lstatSync(filepath).isFile() && ['.h', '.cpp'].includes(path.extname(filepath))) {
let contents = fs.readFileSync(filepath).toString();
let contents = fs.readFileSync(filepath, 'utf8');
contents = contents.replace(
new RegExp(transformJavaClassDescriptor(currentPackageName).replace(/\//g, '\\/'), 'g'),
transformJavaClassDescriptor(packageName)
Expand Down Expand Up @@ -207,7 +207,7 @@ export async function renamePackageOnDiskForType({
filesToUpdate.forEach((filepath: string) => {
try {
if (fs.lstatSync(filepath).isFile()) {
let contents = fs.readFileSync(filepath).toString();
let contents = fs.readFileSync(filepath, 'utf8');
if (path.extname(filepath) === '.kt') {
contents = replacePackageName(contents, currentPackageName, kotlinSanitizedPackageName);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('e2e: Android locales', () => {
},
};
const mockJSONFile = {
readAsync: (path) => JSON.parse(vol.readFileSync(path).toString()),
readAsync: (path) => JSON.parse(vol.readFileSync(path, 'utf8') as string),
};
jest.mock('../../utils/XML', () => mockXML);
jest.mock('@expo/json-file', () => mockJSONFile);
Expand All @@ -84,21 +84,21 @@ describe('e2e: Android locales', () => {
{ projectRoot }
);

expect(vol.readFileSync('/app/android/app/src/main/res/values-b+es/strings.xml').toString())
expect(vol.readFileSync('/app/android/app/src/main/res/values-b+es/strings.xml', 'utf8'))
.toMatchInlineSnapshot(`
"<resources>
<string name="CFBundleDisplayName">"spanish-name"</string>
</resources>"
`);
// backwards compatibility
expect(vol.readFileSync('/app/android/app/src/main/res/values-b+en/strings.xml').toString())
expect(vol.readFileSync('/app/android/app/src/main/res/values-b+en/strings.xml', 'utf8'))
.toMatchInlineSnapshot(`
"<resources>
<string name="CFBundleDisplayName">"us-name"</string>
<string name="app_name">"us-name"</string>
</resources>"
`);
expect(vol.readFileSync('/app/android/app/src/main/res/values-b+en+US/strings.xml').toString())
expect(vol.readFileSync('/app/android/app/src/main/res/values-b+en+US/strings.xml', 'utf8'))
.toMatchInlineSnapshot(`
"<resources>
<string name="app_name">"us-name"</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,24 @@ public class SomeClass {
await renamePackageOnDisk({ android: { package: 'xyz.bront.app' } }, '/myapp');
const mainActivityPath = '/myapp/android/app/src/main/java/xyz/bront/app/MainActivity.java';
expect(fs.existsSync(mainActivityPath)).toBeTruthy();
expect(fs.readFileSync(mainActivityPath).toString()).toMatch('package xyz.bront.app');
expect(fs.readFileSync(mainActivityPath, 'utf8')).toMatch('package xyz.bront.app');

const nestedClassPath =
'/myapp/android/app/src/main/java/xyz/bront/app/example/SomeClass.java';
expect(fs.existsSync(nestedClassPath)).toBeTruthy();
expect(fs.readFileSync(nestedClassPath).toString()).toMatch('package xyz.bront.app');
expect(fs.readFileSync(nestedClassPath).toString()).not.toMatch('com.lololol');
expect(fs.readFileSync(nestedClassPath, 'utf8')).toMatch('package xyz.bront.app');
expect(fs.readFileSync(nestedClassPath, 'utf8')).not.toMatch('com.lololol');

const buckPath = '/myapp/android/app/BUCK';
expect(fs.readFileSync(buckPath).toString()).toMatch('package = "xyz.bront.app"');
expect(fs.readFileSync(buckPath).toString()).not.toMatch('com.lololol');
expect(fs.readFileSync(buckPath, 'utf8')).toMatch('package = "xyz.bront.app"');
expect(fs.readFileSync(buckPath, 'utf8')).not.toMatch('com.lololol');
});

it('does not clobber itself if package has similar parts', async () => {
await renamePackageOnDisk({ android: { package: 'com.bront' } }, '/myapp');
const mainActivityPath = '/myapp/android/app/src/main/java/com/bront/MainActivity.java';
expect(fs.existsSync(mainActivityPath)).toBeTruthy();
expect(fs.readFileSync(mainActivityPath).toString()).toMatch('package com.bront');
expect(fs.readFileSync(mainActivityPath, 'utf8')).toMatch('package com.bront');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe('FileHookTransform', () => {

it('should call hook function from createFingerprintAsync', async () => {
vol.fromJSON(require('../sourcer/__tests__/fixtures/ExpoManaged47Project.json'));
const packageJson = JSON.parse(vol.readFileSync('/app/package.json', 'utf8').toString());
const packageJson = JSON.parse(vol.readFileSync('/app/package.json', 'utf8') as string);
jest.doMock('/app/package.json', () => packageJson, { virtual: true });
const options = await normalizeOptionsAsync('/app', { fileHookTransform: mockHook });
await createFingerprintAsync('/app', options);
Expand All @@ -121,7 +121,7 @@ describe('FileHookTransform', () => {
}
) as jest.MockedFunction<FileHookTransformFunction>;
vol.fromJSON(require('../sourcer/__tests__/fixtures/ExpoManaged47Project.json'));
const packageJson = JSON.parse(vol.readFileSync('/app/package.json', 'utf8').toString());
const packageJson = JSON.parse(vol.readFileSync('/app/package.json', 'utf8') as string);
jest.doMock('/app/package.json', () => packageJson, { virtual: true });
const options = await normalizeOptionsAsync('/app', { fileHookTransform: mockExpoConfigHook });
const result = await createFingerprintAsync('/app', options);
Expand Down
79 changes: 77 additions & 2 deletions packages/@expo/fingerprint/src/__tests__/Fingerprint-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,36 @@ describe(diffFingerprintChangesAsync, () => {

expect(normalizedDiff).toMatchInlineSnapshot(`
[
{
"addedSource": {
"contents": "{"extraDependencies":[],"coreFeatures":[],"modules":[]}",
"debugInfo": {
"hash": "10c4144650e3af1f596683ac4ae7a6fd971f7447",
},
"hash": "10c4144650e3af1f596683ac4ae7a6fd971f7447",
"id": "expoAutolinkingConfig:android",
"reasons": [
"expoAutolinkingAndroid",
],
"type": "contents",
},
"op": "added",
},
{
"addedSource": {
"contents": "{"extraDependencies":[],"coreFeatures":[],"modules":[]}",
"debugInfo": {
"hash": "10c4144650e3af1f596683ac4ae7a6fd971f7447",
},
"hash": "10c4144650e3af1f596683ac4ae7a6fd971f7447",
"id": "expoAutolinkingConfig:ios",
"reasons": [
"expoAutolinkingIos",
],
"type": "contents",
},
"op": "added",
},
{
"addedSource": {
"contents": "{"android":{"adaptiveIcon":{"backgroundColor":"#FFFFFF","foregroundImage":"./assets/adaptive-icon.png"}},"assetBundlePatterns":["**/*"],"icon":"./assets/icon.png","ios":{"supportsTablet":true},"name":"sdk47","orientation":"portrait","platforms":["android","ios","web"],"slug":"sdk47","splash":{"backgroundColor":"#ffffff","image":"./assets/splash.png","resizeMode":"contain"},"updates":{"fallbackToCacheTimeout":0},"userInterfaceStyle":"light","version":"1.0.0","web":{"favicon":"./assets/favicon.png"}}",
Expand All @@ -86,13 +116,58 @@ describe(diffFingerprintChangesAsync, () => {
},
"op": "added",
},
{
"addedSource": {
"contents": "{"setup:docs":"./scripts/download-dependencies.sh","setup:native":"./scripts/download-dependencies.sh && ./scripts/setup-react-android.sh","postinstall":"yarn-deduplicate && yarn workspace @expo/cli prepare && patch-package && node ./tools/bin/expotools.js validate-workspace-dependencies","install:react-native-lab":"(([ \\"$(ls -A react-native-lab/react-native)\\" ] && (yarn --cwd react-native-lab/react-native install --frozen-lockfile || true)) || echo \\"Skipping installing Node modules in react-native-lab/react-native (directory empty)\\")","lint":"eslint .","tsc":"echo 'You are trying to run \\"tsc\\" in the workspace root. Run it from an individual package instead.' && exit 1"}",
"debugInfo": {
"hash": "c4f835988805180a373d4ff37cef6ce53cb14995",
},
"hash": "c4f835988805180a373d4ff37cef6ce53cb14995",
"id": "packageJson:scripts",
"reasons": [
"packageJson:scripts",
],
"type": "contents",
},
"op": "added",
},
{
"addedSource": {
"contents": "{}",
"debugInfo": {
"hash": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f",
},
"hash": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f",
"id": "rncoreAutolinkingConfig:android",
"reasons": [
"rncoreAutolinkingAndroid",
],
"type": "contents",
},
"op": "added",
},
{
"addedSource": {
"contents": "{}",
"debugInfo": {
"hash": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f",
},
"hash": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f",
"id": "rncoreAutolinkingConfig:ios",
"reasons": [
"rncoreAutolinkingIos",
],
"type": "contents",
},
"op": "added",
},
]
`);
});

it('should return diff from contents changes', async () => {
vol.fromJSON(require('../sourcer/__tests__/fixtures/ExpoManaged47Project.json'));
const packageJson = JSON.parse(vol.readFileSync('/app/package.json', 'utf8').toString());
const packageJson = JSON.parse(vol.readFileSync('/app/package.json', 'utf8') as string);
jest.doMock('/app/package.json', () => packageJson, { virtual: true });
const fingerprint = await createFingerprintAsync(
'/app',
Expand Down Expand Up @@ -158,7 +233,7 @@ describe(diffFingerprintChangesAsync, () => {
'/app',
await normalizeOptionsAsync('/app', { debug: true })
);
const config = JSON.parse(vol.readFileSync('/app/app.json', 'utf8').toString());
const config = JSON.parse(vol.readFileSync('/app/app.json', 'utf8') as string);
config.expo.jsEngine = 'jsc';
vol.writeFileSync('/app/app.json', JSON.stringify(config, null, 2));
const diff = await diffFingerprintChangesAsync(
Expand Down
28 changes: 14 additions & 14 deletions packages/@expo/fingerprint/src/sourcer/__tests__/Expo-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,15 @@ describe(getExpoConfigSourcesAsync, () => {

it('should contain expo config', async () => {
vol.fromJSON(require('./fixtures/ExpoManaged47Project.json'));
const appJson = JSON.parse(vol.readFileSync('/app/app.json', 'utf8').toString());
const appJson = JSON.parse(vol.readFileSync('/app/app.json', 'utf8') as string);
const options = await normalizeOptionsAsync('/app');
const { config, loadedModules } = await getExpoConfigAsync('/app', options);
const sources = await getExpoConfigSourcesAsync('/app', config, loadedModules, options);
const expoConfigSource = sources.find<HashSourceContents>(
(source): source is HashSourceContents =>
source.type === 'contents' && source.id === 'expoConfig'
);
const expoConfig = JSON.parse(expoConfigSource?.contents?.toString() ?? 'null');
const expoConfig = JSON.parse((expoConfigSource?.contents as string) ?? 'null');
expect(expoConfig).not.toBeNull();
expect(expoConfig.name).toEqual(appJson.expo.name);
});
Expand All @@ -203,7 +203,7 @@ describe(getExpoConfigSourcesAsync, () => {
const { config, loadedModules } = await getExpoConfigAsync('/app', options);
const sources = await getExpoConfigSourcesAsync('/app', config, loadedModules, options);

const appJsonContents = vol.readFileSync('/app/app.json', 'utf8').toString();
const appJsonContents = vol.readFileSync('/app/app.json', 'utf8') as string;
const appJson = JSON.parse(appJsonContents);
const { name } = appJson.expo;
// Re-insert name to change the object order
Expand All @@ -225,7 +225,7 @@ describe(getExpoConfigSourcesAsync, () => {

it('should transform expo config paths as relative paths', async () => {
vol.fromJSON(require('./fixtures/ExpoManaged47Project.json'));
const appJson = JSON.parse(vol.readFileSync('/app/app.json', 'utf8').toString());
const appJson = JSON.parse(vol.readFileSync('/app/app.json', 'utf8') as string);
appJson.expo.extra ||= {};
appJson.expo.extra.testFile = '/app/test-file.txt';
appJson.expo.extra.testNestedFile = '/app/nested/test-file.txt';
Expand All @@ -237,7 +237,7 @@ describe(getExpoConfigSourcesAsync, () => {
(source): source is HashSourceContents =>
source.type === 'contents' && source.id === 'expoConfig'
);
const expoConfig = JSON.parse(expoConfigSource?.contents?.toString() ?? 'null');
const expoConfig = JSON.parse((expoConfigSource?.contents as string) ?? 'null');
expect(expoConfig.extra.testFile).toBe('test-file.txt');
expect(expoConfig.extra.testNestedFile).toBe('nested/test-file.txt');
});
Expand All @@ -263,7 +263,7 @@ describe(getExpoConfigSourcesAsync, () => {
vol.writeFileSync('/app/assets/icon-light.png', 'PNG data');
vol.writeFileSync('/app/assets/icon-dark.png', 'PNG data');
vol.writeFileSync('/app/assets/icon-tinted.png', 'PNG data');
const appJson = JSON.parse(vol.readFileSync('/app/app.json', 'utf8').toString());
const appJson = JSON.parse(vol.readFileSync('/app/app.json', 'utf8') as string);
appJson.expo.ios ||= {};
appJson.expo.ios.icon = {
light: '/app/assets/icon-light.png',
Expand Down Expand Up @@ -299,7 +299,7 @@ describe(getExpoConfigSourcesAsync, () => {
vol.fromJSON(require('./fixtures/ExpoManaged47Project.json'));
vol.mkdirSync('/app/assets');
copyDirSync(path.join(__dirname, 'fixtures', 'ExpoGo.icon'), '/app/assets/ExpoGo.icon');
const appJson = JSON.parse(vol.readFileSync('/app/app.json', 'utf8').toString());
const appJson = JSON.parse(vol.readFileSync('/app/app.json', 'utf8') as string);
appJson.expo.ios ||= {};
appJson.expo.ios.icon = '/app/assets/ExpoGo.icon';
vol.writeFileSync('/app/app.json', JSON.stringify(appJson, null, 2));
Expand All @@ -319,7 +319,7 @@ describe(getExpoConfigSourcesAsync, () => {
it('should contain external google service files with override hash key', async () => {
vol.fromJSON(require('./fixtures/ExpoManaged47Project.json'));
vol.writeFileSync('/app/google-services.json', 'JSON data');
const appJson = JSON.parse(vol.readFileSync('/app/app.json', 'utf8').toString());
const appJson = JSON.parse(vol.readFileSync('/app/app.json', 'utf8') as string);
appJson.expo.android ||= {};
appJson.expo.android.googleServicesFile = '/app/google-services.json';
vol.writeFileSync('/app/app.json', JSON.stringify(appJson, null, 2));
Expand All @@ -342,7 +342,7 @@ describe(getExpoConfigSourcesAsync, () => {
vol.writeFileSync('/app/assets/images/splash-icon.png', 'PNG data');

const config = {
exp: JSON.parse(vol.readFileSync('/app/app.json', 'utf8').toString()).expo,
exp: JSON.parse(vol.readFileSync('/app/app.json', 'utf8') as string).expo,
};
const configResult = JSON.stringify({ config, loadedModules: [] });
const mockSpawnWithIpcAsync = spawnWithIpcAsync as jest.MockedFunction<
Expand Down Expand Up @@ -435,7 +435,7 @@ describe(`getExpoConfigSourcesAsync - sourceSkips`, () => {
(source): source is HashSourceContents =>
source.type === 'contents' && source.id === 'expoConfig'
);
const expoConfig = JSON.parse(expoConfigSource?.contents?.toString() ?? 'null');
const expoConfig = JSON.parse((expoConfigSource?.contents as string) ?? 'null');
expect(expoConfig).not.toBeNull();
expect(expoConfig.version).toBeUndefined();
expect(expoConfig.android.versionCode).toBeUndefined();
Expand Down Expand Up @@ -471,7 +471,7 @@ module.exports = config;
(source): source is HashSourceContents =>
source.type === 'contents' && source.id === 'expoConfig'
);
const expoConfig = JSON.parse(expoConfigSource?.contents?.toString() ?? 'null');
const expoConfig = JSON.parse((expoConfigSource?.contents as string) ?? 'null');
expect(expoConfig).not.toBeNull();
expect(expoConfig.version).toBeUndefined();
expect(expoConfig.android.versionCode).toBeUndefined();
Expand Down Expand Up @@ -509,7 +509,7 @@ module.exports = config;
(source): source is HashSourceContents =>
source.type === 'contents' && source.id === 'expoConfig'
);
const expoConfig = JSON.parse(expoConfigSource?.contents?.toString() ?? 'null');
const expoConfig = JSON.parse((expoConfigSource?.contents as string) ?? 'null');
expect(expoConfig).not.toBeNull();
expect(expoConfig.version).toBeUndefined();
expect(expoConfig.android.versionCode).toBeUndefined();
Expand Down Expand Up @@ -540,7 +540,7 @@ module.exports = config;
(source): source is HashSourceContents =>
source.type === 'contents' && source.id === 'expoConfig'
);
const expoConfig = JSON.parse(expoConfigSource?.contents?.toString() ?? 'null');
const expoConfig = JSON.parse((expoConfigSource?.contents as string) ?? 'null');
expect(expoConfig).not.toBeNull();
expect(expoConfig.runtimeVersion).toBeUndefined();
expect(expoConfig.android.runtimeVersion).toBeUndefined();
Expand Down Expand Up @@ -570,7 +570,7 @@ module.exports = config;
(source): source is HashSourceContents =>
source.type === 'contents' && source.id === 'expoConfig'
);
const expoConfig = JSON.parse(expoConfigSource?.contents?.toString() ?? 'null');
const expoConfig = JSON.parse((expoConfigSource?.contents as string) ?? 'null');
expect(expoConfig).not.toBeNull();
expect(expoConfig.runtimeVersion).toMatchObject({ policy: 'test' });
expect(expoConfig.android.runtimeVersion).toMatchObject({ policy: 'test' });
Expand Down
Loading