diff --git a/.husky/pre-commit b/.husky/pre-commit index 20d0d06e58..962fa559e0 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -npm run lint +npm run sanity diff --git a/__mocks__/@rnv/core.ts b/__mocks__/@rnv/core.ts index 9e73020b28..1623ebcf5a 100644 --- a/__mocks__/@rnv/core.ts +++ b/__mocks__/@rnv/core.ts @@ -262,6 +262,7 @@ rnvcore.confirmActiveBundler = () => null; rnvcore.getAppFolder = jest.fn(); rnvcore.logToSummary = jest.fn(); rnvcore.logTask = jest.fn(); +rnvcore.logDefault = jest.fn(); rnvcore.logDebug = jest.fn(); rnvcore.logInfo = jest.fn(); rnvcore.logError = jest.fn(); diff --git a/buildHooks/src/index.js b/buildHooks/src/index.ts similarity index 100% rename from buildHooks/src/index.js rename to buildHooks/src/index.ts diff --git a/buildHooks/src/prePublish.js b/buildHooks/src/prePublish.ts similarity index 78% rename from buildHooks/src/prePublish.js rename to buildHooks/src/prePublish.ts index 74ac28f6b5..6f65a8677a 100644 --- a/buildHooks/src/prePublish.js +++ b/buildHooks/src/prePublish.ts @@ -1,5 +1,5 @@ import path from 'path'; -import { copyFileSync, fixPackageObject, fsExistsSync, readObjectSync, writeFileSync } from '@rnv/core'; +import { RnvContext, copyFileSync, fixPackageObject, fsExistsSync, readObjectSync, writeFileSync } from '@rnv/core'; import fs from 'fs'; const merge = require('deepmerge'); @@ -31,8 +31,18 @@ const VERSIONED_PACKAGES = [ 'renative', ]; -const setPackageVersions = (c, version, versionedPackages) => { - var v = { +type PackageConfig = { + pkgName?: string; + rnvPath?: string; + pkgPath?: string; + pkgFile?: any; + rnvFile?: any; +}; + +type PackageConfigs = Record; + +const setPackageVersions = (c: RnvContext, version: string | undefined, versionedPackages: string[]) => { + const v = { version: version, }; const pkgFolder = path.join(c.paths.project.dir, 'packages'); @@ -42,7 +52,13 @@ const setPackageVersions = (c, version, versionedPackages) => { }); }; -const updatePkgDeps = (pkgConfig, depKey, packageName, packageConfigs, semVer = '') => { +const updatePkgDeps = ( + pkgConfig: PackageConfig, + depKey: string, + packageName: string, + packageConfigs: PackageConfigs, + semVer = '' +) => { const { pkgFile } = pkgConfig; if (pkgFile) { @@ -64,7 +80,7 @@ const updatePkgDeps = (pkgConfig, depKey, packageName, packageConfigs, semVer = } }; -const updateRenativeDeps = (pkgConfig, packageName, packageConfigs) => { +const updateRenativeDeps = (pkgConfig: PackageConfig, packageName: string, packageConfigs: PackageConfigs) => { const { rnvFile } = pkgConfig; if (rnvFile) { @@ -85,7 +101,7 @@ const updateRenativeDeps = (pkgConfig, packageName, packageConfigs) => { } }; -export const prePublish = async (c) => { +export const prePublish = async (c: RnvContext) => { const v = { version: c.files.project.package.version, }; @@ -114,11 +130,11 @@ export const prePublish = async (c) => { const dirs = fs.readdirSync(pkgDirPath); - const packageNamesAll = []; - const packageConfigs = {}; + const packageNamesAll: string[] = []; + const packageConfigs: PackageConfigs = {}; - const parsePackages = (dirPath) => { - let pkgName; + const parsePackages = (dirPath: string) => { + let pkgName: string | undefined; let rnvPath; let _pkgPath; let rnvFile; @@ -127,8 +143,8 @@ export const prePublish = async (c) => { if (fs.statSync(dirPath).isDirectory()) { _pkgPath = path.join(dirPath, 'package.json'); if (fsExistsSync(_pkgPath)) { - pkgFile = readObjectSync(_pkgPath); - pkgName = pkgFile.name; + pkgFile = readObjectSync(_pkgPath); + pkgName = pkgFile?.name; } const _rnvPath = path.join(dirPath, 'renative.json'); if (fsExistsSync(_rnvPath)) { @@ -136,14 +152,16 @@ export const prePublish = async (c) => { rnvFile = readObjectSync(rnvPath); } } - packageConfigs[pkgName] = { - pkgName, - rnvPath, - pkgPath: _pkgPath, - pkgFile, - rnvFile, - }; - packageNamesAll.push(pkgName); + if (pkgName) { + packageConfigs[pkgName] = { + pkgName, + rnvPath, + pkgPath: _pkgPath, + pkgFile, + rnvFile, + }; + packageNamesAll.push(pkgName); + } }; parsePackages(c.paths.project.dir); @@ -170,7 +188,7 @@ export const prePublish = async (c) => { return true; }; -const _updateJson = (pPath, updateObj) => { +const _updateJson = (pPath: string | undefined, updateObj: object) => { const pObj = readObjectSync(pPath); if (!pObj) { diff --git a/package.json b/package.json index 8600b46e92..ce460f3a47 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "title": "ReNative", "husky": { "hooks": { - "pre-commit": "yarn lint && yarn test" + "pre-commit": "yarn sanity" } }, "lint-staged": { diff --git a/packages/app-harness/buildHooks/src/index.js b/packages/app-harness/buildHooks/src/index.ts similarity index 100% rename from packages/app-harness/buildHooks/src/index.js rename to packages/app-harness/buildHooks/src/index.ts diff --git a/packages/app-harness/buildHooks/src/setup/apple.js b/packages/app-harness/buildHooks/src/setup/apple.js deleted file mode 100644 index d96aa0a1d6..0000000000 --- a/packages/app-harness/buildHooks/src/setup/apple.js +++ /dev/null @@ -1,28 +0,0 @@ -import path from 'path' -import { executeAsync, logInfo, logError } from '@rnv/core'; - -export default async (c) => { - const certRelativePath = c.files.workspace.project?.configPrivate?.apple?.p12?.path; - - if (!certRelativePath) { - return logError('No configPrivate found. You sure you decrypted?', true); - } - const certPass = c.files.workspace.project?.configPrivate?.apple?.p12?.password; - const certPath = path.resolve(c.paths.workspace.project.dir, certRelativePath); - - logInfo(`Importing certificate ${certPath}`); - await executeAsync(`fastlane run import_certificate certificate_path:${certPath} certificate_password:${certPass} keychain_name:login`, { privateParams: [certPass] }); - - const profiles = c.files.workspace.project?.configPrivate?.apple?.provisioningProfiles; - - if (!profiles) { - return; - } - - await Promise.all(profiles.map(async (profile) => { - const profileRelativePath = profile?.path; - const profilePath = path.resolve(c.paths.workspace.project.dir, profileRelativePath); - logInfo(`Installing provisioning profile ${profilePath}`); - await executeAsync(`fastlane run install_provisioning_profile path:${profilePath}`); - })) -} \ No newline at end of file diff --git a/packages/app-harness/buildHooks/src/setup/apple.ts b/packages/app-harness/buildHooks/src/setup/apple.ts new file mode 100644 index 0000000000..a324865728 --- /dev/null +++ b/packages/app-harness/buildHooks/src/setup/apple.ts @@ -0,0 +1,35 @@ +import path from 'path'; +import { executeAsync, logInfo, logError, RnvContext } from '@rnv/core'; + +export default async (c: RnvContext) => { + // TODO: This is a temporary solution. We need to find a better way to handle untyped values + const cfPrivate: any = c.files.workspace.project?.configPrivate; + const certRelativePath = cfPrivate?.apple?.p12?.path; + + if (!certRelativePath) { + return logError('No configPrivate found. You sure you decrypted?', true); + } + const certPass = cfPrivate?.apple?.p12?.password; + const certPath = path.resolve(c.paths.workspace.project.dir, certRelativePath); + + logInfo(`Importing certificate ${certPath}`); + await executeAsync( + `fastlane run import_certificate certificate_path:${certPath} certificate_password:${certPass} keychain_name:login`, + { privateParams: [certPass] } + ); + + const profiles = cfPrivate?.apple?.provisioningProfiles; + + if (!profiles) { + return; + } + + await Promise.all( + profiles.map(async (profile: { path: string }) => { + const profileRelativePath = profile?.path; + const profilePath = path.resolve(c.paths.workspace.project.dir, profileRelativePath); + logInfo(`Installing provisioning profile ${profilePath}`); + await executeAsync(`fastlane run install_provisioning_profile path:${profilePath}`); + }) + ); +}; diff --git a/packages/app-harness/buildHooks/tsconfig.json b/packages/app-harness/buildHooks/tsconfig.json new file mode 100644 index 0000000000..82dac4d899 --- /dev/null +++ b/packages/app-harness/buildHooks/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@rnv/core/tsconfig.hooks.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + } +} diff --git a/packages/app-harness/next.config.js b/packages/app-harness/next.config.js index 7fd91fe64e..e82ad67a8d 100644 --- a/packages/app-harness/next.config.js +++ b/packages/app-harness/next.config.js @@ -1,7 +1,7 @@ -const { withRNV } = require('@rnv/engine-rn-next'); +const { withRNVNext } = require('@rnv/engine-rn-next'); const config = { compress: false, }; -module.exports = withRNV(config); +module.exports = withRNVNext(config); diff --git a/packages/app-harness/renative.json b/packages/app-harness/renative.json index 325f17f96e..f3a80bd476 100644 --- a/packages/app-harness/renative.json +++ b/packages/app-harness/renative.json @@ -183,6 +183,9 @@ } } }, + "tvos": { + "disabled": true + }, "version": "1.11.0" }, "react-native": { diff --git a/packages/app-harness/src/app/index.tsx b/packages/app-harness/src/app/index.tsx index 6926beb950..dc8019169f 100644 --- a/packages/app-harness/src/app/index.tsx +++ b/packages/app-harness/src/app/index.tsx @@ -1,83 +1,96 @@ import React, { useEffect, useState } from 'react'; -import { Button, Text, View } from 'react-native'; -import SplashScreen from 'react-native-splash-screen'; -import NewModuleButton from './NewModuleButton'; -import { OrientationLocker, PORTRAIT, LANDSCAPE } from 'react-native-orientation-locker'; -import { isPlatformAndroid, isPlatformIos } from '@rnv/renative'; -import PushNotificationIOS from '@react-native-community/push-notification-ios'; -import { request, PERMISSIONS } from 'react-native-permissions'; +import { Button, Image, ScrollView, Text, View } from 'react-native'; +import { OrientationLocker, PORTRAIT, LANDSCAPE } from '../components/OrientationLocker'; +import { NewModuleButton } from '../components/NewModuleButton'; +import { SplashScreen } from '../components/SplashScreen'; +import { ICON_LOGO, testProps } from '../config'; +import styles from '../styles'; +import { addNotificationListeners, removeNotificationListeners } from '../components/Notifications'; +import { requestPermissions } from '../components/Permissions'; +import { TestCase } from '../components/TestCase'; const App = () => { const [showVideo, setShowVideo] = useState(false); useEffect(() => { SplashScreen.hide(); - }, []); - - useEffect(() => { - if (!isPlatformIos) return; - PushNotificationIOS.requestPermissions(); - PushNotificationIOS.addEventListener('notification', onRemoteNotification); - PushNotificationIOS.addEventListener('register', onRegistered); - PushNotificationIOS.addEventListener('registrationError', onError); + addNotificationListeners(); return () => { - PushNotificationIOS.removeEventListener('notification'); - PushNotificationIOS.removeEventListener('register'); - PushNotificationIOS.removeEventListener('registrationError'); + removeNotificationListeners(); }; - }); - - const requestPermission = () => { - request(PERMISSIONS.IOS.CONTACTS).then((result) => { - console.log(result); - }); - }; - - const onRegistered = (deviceToken) => { - console.log(`Device Token: ${deviceToken}`); - }; - - const onError = (error) => { - console.log(`Error on notification register: ${error}`); - }; - - const onRemoteNotification = (notification) => { - const isClicked = notification.getData().userInteraction === 1; - - if (isClicked) { - // Navigate user to another screen - } else { - // Do something else with push notification - } - // Use the appropriate result based on what you needed to do for this notification - const result = PushNotificationIOS.FetchResult.NoData; - notification.finish(result); - }; + }, []); return ( - - ReNative Harness !! - {`hermes: ${typeof HermesInternal === 'object' && HermesInternal !== null ? 'yes' : 'no'}`} - {isPlatformIos &&