├── .gitignore ├── .npmignore ├── HISTORY.md ├── LICENSE ├── README.md ├── bin └── rnpackager ├── package.json ├── react-native ├── cli.js ├── local-cli │ ├── __mocks__ │ │ └── beeper.js │ ├── bundle │ │ ├── __mocks__ │ │ │ └── sign.js │ │ ├── __tests__ │ │ │ ├── getAssetDestPathAndroid-test.js │ │ │ └── getAssetDestPathIOS-test.js │ │ ├── assetPathUtils.js │ │ ├── buildBundle.js │ │ ├── bundle.js │ │ ├── bundleCommandLineArgs.js │ │ ├── getAssetDestPathAndroid.js │ │ ├── getAssetDestPathIOS.js │ │ ├── output │ │ │ ├── bundle.js │ │ │ ├── meta.js │ │ │ ├── unbundle │ │ │ │ ├── as-assets.js │ │ │ │ ├── as-indexed-file.js │ │ │ │ ├── build-unbundle-sourcemap-with-metadata.js │ │ │ │ ├── index.js │ │ │ │ ├── magic-number.js │ │ │ │ ├── util.js │ │ │ │ └── write-sourcemap.js │ │ │ └── writeFile.js │ │ ├── saveAssets.js │ │ ├── types.flow.js │ │ └── unbundle.js │ ├── cli.js │ ├── cliEntry.js │ ├── commands.js │ ├── core │ │ ├── __fixtures__ │ │ │ ├── android.js │ │ │ ├── commands.js │ │ │ ├── dependencies.js │ │ │ ├── files │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── Main.java │ │ │ │ ├── ReactPackage.java │ │ │ │ ├── package.json │ │ │ │ └── project.pbxproj │ │ │ ├── ios.js │ │ │ └── projects.js │ │ ├── __tests__ │ │ │ ├── android │ │ │ │ ├── findAndroidAppFolder.spec.js │ │ │ │ ├── findManifest.spec.js │ │ │ │ ├── findPackageClassName.spec.js │ │ │ │ ├── getDependencyConfig.spec.js │ │ │ │ ├── getProjectConfig.spec.js │ │ │ │ └── readManifest.spec.js │ │ │ ├── findAssets.spec.js │ │ │ ├── findPlugins.spec.js │ │ │ ├── ios │ │ │ │ ├── findProject.spec.js │ │ │ │ └── getProjectConfig.spec.js │ │ │ └── makeCommand.spec.js │ │ ├── android │ │ │ ├── findAndroidAppFolder.js │ │ │ ├── findManifest.js │ │ │ ├── findPackageClassName.js │ │ │ ├── index.js │ │ │ └── readManifest.js │ │ ├── default.config.js │ │ ├── findAssets.js │ │ ├── findPlugins.js │ │ ├── index.js │ │ ├── ios │ │ │ ├── findProject.js │ │ │ └── index.js │ │ ├── makeCommand.js │ │ ├── windows │ │ │ ├── findNamespace.js │ │ │ ├── findPackageClassName.js │ │ │ ├── findProject.js │ │ │ ├── findWindowsSolution.js │ │ │ ├── generateGUID.js │ │ │ └── index.js │ │ └── wrapCommands.js │ ├── dependencies │ │ └── dependencies.js │ ├── eject │ │ └── eject.js │ ├── generator │ │ ├── copyProjectTemplateAndReplace.js │ │ ├── printRunInstructions.js │ │ ├── promptSync.js │ │ └── templates.js │ ├── init │ │ └── init.js │ ├── install │ │ ├── install.js │ │ └── uninstall.js │ ├── library │ │ └── library.js │ ├── link │ │ ├── __fixtures__ │ │ │ ├── android │ │ │ │ ├── 0.17 │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── patchedMainActivity.java │ │ │ │ ├── 0.18 │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── patchedMainActivity.java │ │ │ │ ├── 0.20 │ │ │ │ │ └── MainActivity.java │ │ │ │ ├── build.gradle │ │ │ │ ├── patchedBuild.gradle │ │ │ │ ├── patchedSettings.gradle │ │ │ │ └── settings.gradle │ │ │ ├── linearGradient.pbxproj │ │ │ └── project.pbxproj │ │ ├── __tests__ │ │ │ ├── android │ │ │ │ ├── applyPatch.spec.js │ │ │ │ ├── isInstalled.spec.js │ │ │ │ ├── makeBuildPatch.spec.js │ │ │ │ ├── makeImportPatch.spec.js │ │ │ │ ├── makePackagePatch.spec.js │ │ │ │ ├── makeSettingsPatch.spec.js │ │ │ │ └── makeStringsPatch.spec.js │ │ │ ├── getDependencyConfig.spec.js │ │ │ ├── getProjectDependencies.spec.js │ │ │ ├── groupFilesByType.spec.js │ │ │ ├── ios │ │ │ │ ├── addFileToProject.spec.js │ │ │ │ ├── addProjectToLibraries.spec.js │ │ │ │ ├── addSharedLibraries.spec.js │ │ │ │ ├── createGroup.spec.js │ │ │ │ ├── getBuildProperty.spec.js │ │ │ │ ├── getGroup.spec.js │ │ │ │ ├── getHeaderSearchPath.spec.js │ │ │ │ ├── getHeadersInFolder.spec.js │ │ │ │ ├── getPlist.spec.js │ │ │ │ ├── getPlistPath.spec.js │ │ │ │ ├── getProducts.spec.js │ │ │ │ ├── hasLibraryImported.spec.js │ │ │ │ ├── isInstalled.spec.js │ │ │ │ ├── mapHeaderSearchPaths.spec.js │ │ │ │ ├── removeProjectFromLibraries.js │ │ │ │ ├── removeProjectFromProject.spec.js │ │ │ │ └── removeSharedLibrary.spec.js │ │ │ ├── link.spec.js │ │ │ └── promiseWaterfall.spec.js │ │ ├── android │ │ │ ├── copyAssets.js │ │ │ ├── fs.js │ │ │ ├── isInstalled.js │ │ │ ├── patches │ │ │ │ ├── applyParams.js │ │ │ │ ├── applyPatch.js │ │ │ │ ├── makeBuildPatch.js │ │ │ │ ├── makeImportPatch.js │ │ │ │ ├── makePackagePatch.js │ │ │ │ ├── makeSettingsPatch.js │ │ │ │ ├── makeStringsPatch.js │ │ │ │ └── revokePatch.js │ │ │ ├── registerNativeModule.js │ │ │ ├── unlinkAssets.js │ │ │ └── unregisterNativeModule.js │ │ ├── commandStub.js │ │ ├── getDependencyConfig.js │ │ ├── getProjectDependencies.js │ │ ├── groupFilesByType.js │ │ ├── ios │ │ │ ├── addFileToProject.js │ │ │ ├── addProjectToLibraries.js │ │ │ ├── addSharedLibraries.js │ │ │ ├── addToHeaderSearchPaths.js │ │ │ ├── copyAssets.js │ │ │ ├── createGroup.js │ │ │ ├── createGroupWithMessage.js │ │ │ ├── getBuildProperty.js │ │ │ ├── getGroup.js │ │ │ ├── getHeaderSearchPath.js │ │ │ ├── getHeadersInFolder.js │ │ │ ├── getPlist.js │ │ │ ├── getPlistPath.js │ │ │ ├── getProducts.js │ │ │ ├── hasLibraryImported.js │ │ │ ├── isInstalled.js │ │ │ ├── mapHeaderSearchPaths.js │ │ │ ├── registerNativeModule.js │ │ │ ├── removeFromHeaderSearchPaths.js │ │ │ ├── removeFromPbxItemContainerProxySection.js │ │ │ ├── removeFromPbxReferenceProxySection.js │ │ │ ├── removeFromProjectReferences.js │ │ │ ├── removeFromStaticLibraries.js │ │ │ ├── removeProductGroup.js │ │ │ ├── removeProjectFromLibraries.js │ │ │ ├── removeProjectFromProject.js │ │ │ ├── removeSharedLibraries.js │ │ │ ├── unlinkAssets.js │ │ │ └── unregisterNativeModule.js │ │ ├── link.js │ │ ├── pollParams.js │ │ ├── promiseWaterfall.js │ │ ├── promisify.js │ │ ├── unlink.js │ │ └── windows │ │ │ ├── isInstalled.js │ │ │ ├── patches │ │ │ ├── applyParams.js │ │ │ ├── applyPatch.js │ │ │ ├── makePackagePatch.js │ │ │ ├── makeProjectPatch.js │ │ │ ├── makeSolutionPatch.js │ │ │ ├── makeUsingPatch.js │ │ │ └── revokePatch.js │ │ │ ├── registerNativeModule.js │ │ │ └── unregisterNativeModule.js │ ├── logAndroid │ │ └── logAndroid.js │ ├── logIOS │ │ └── logIOS.js │ ├── runAndroid │ │ ├── adb.js │ │ └── runAndroid.js │ ├── runIOS │ │ ├── __tests__ │ │ │ ├── findMatchingSimulator-test.js │ │ │ ├── findXcodeProject-test.js │ │ │ └── parseIOSDevicesList-test.js │ │ ├── findMatchingSimulator.js │ │ ├── findXcodeProject.js │ │ ├── parseIOSDevicesList.js │ │ └── runIOS.js │ ├── server │ │ ├── checkNodeVersion.js │ │ ├── formatBanner.js │ │ ├── middleware │ │ │ ├── copyToClipBoardMiddleware.js │ │ │ ├── cpuProfilerMiddleware.js │ │ │ ├── getDevToolsMiddleware.js │ │ │ ├── heapCapture │ │ │ │ ├── Makefile │ │ │ │ ├── heapCapture.html │ │ │ │ ├── package.json │ │ │ │ ├── src │ │ │ │ │ ├── AggrowData.js │ │ │ │ │ ├── AggrowExpander.js │ │ │ │ │ ├── AggrowTable.jsx │ │ │ │ │ ├── DataColumnSelector.jsx │ │ │ │ │ ├── Draggable.jsx │ │ │ │ │ ├── DropTarget.jsx │ │ │ │ │ ├── ExpanderConfiguration.jsx │ │ │ │ │ ├── StackExpanderCreator.jsx │ │ │ │ │ ├── StackRegistry.js │ │ │ │ │ ├── StringInterner.js │ │ │ │ │ ├── TableConfiguration.jsx │ │ │ │ │ ├── TableHeader.jsx │ │ │ │ │ ├── aggrow.js │ │ │ │ │ ├── heapCapture.js │ │ │ │ │ └── index.js │ │ │ │ └── webpack.config.js │ │ │ ├── heapCaptureMiddleware.js │ │ │ ├── index.html │ │ │ ├── indexPage.js │ │ │ ├── loadRawBodyMiddleware.js │ │ │ ├── openStackFrameInEditorMiddleware.js │ │ │ ├── statusPageMiddleware.js │ │ │ ├── systraceProfileMiddleware.js │ │ │ └── unless.js │ │ ├── runServer.js │ │ ├── server.js │ │ └── util │ │ │ ├── attachHMRServer.js │ │ │ ├── copyToClipBoard.js │ │ │ ├── debugger.html │ │ │ ├── debuggerWorker.js │ │ │ ├── inspectorProxy.js │ │ │ ├── launchChrome.js │ │ │ ├── launchEditor.js │ │ │ ├── messageSocket.js │ │ │ └── webSocketProxy.js │ ├── setup_env.bat │ ├── setup_env.sh │ ├── templates │ │ ├── HelloNavigation │ │ │ ├── README.md │ │ │ ├── components │ │ │ │ ├── KeyboardSpacer.js │ │ │ │ └── ListItem.js │ │ │ ├── dependencies.json │ │ │ ├── index.android.js │ │ │ ├── index.ios.js │ │ │ ├── lib │ │ │ │ └── Backend.js │ │ │ └── views │ │ │ │ ├── HomeScreenTabNavigator.js │ │ │ │ ├── MainNavigator.js │ │ │ │ ├── chat │ │ │ │ ├── ChatListScreen.js │ │ │ │ ├── ChatScreen.js │ │ │ │ └── chat-icon.png │ │ │ │ └── welcome │ │ │ │ ├── WelcomeScreen.js │ │ │ │ ├── WelcomeText.android.js │ │ │ │ ├── WelcomeText.ios.js │ │ │ │ └── welcome-icon.png │ │ ├── HelloWorld │ │ │ ├── __tests__ │ │ │ │ ├── index.android.js │ │ │ │ └── index.ios.js │ │ │ ├── _babelrc │ │ │ ├── _buckconfig │ │ │ ├── _flowconfig │ │ │ ├── _gitattributes │ │ │ ├── _gitignore │ │ │ ├── _watchmanconfig │ │ │ ├── android │ │ │ │ ├── app │ │ │ │ │ ├── BUCK │ │ │ │ │ ├── build.gradle │ │ │ │ │ ├── proguard-rules.pro │ │ │ │ │ └── src │ │ │ │ │ │ └── main │ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ │ ├── java │ │ │ │ │ │ └── com │ │ │ │ │ │ │ └── helloworld │ │ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ │ │ └── MainApplication.java │ │ │ │ │ │ └── res │ │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ └── values │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── build.gradle │ │ │ │ ├── gradle.properties │ │ │ │ ├── gradle │ │ │ │ │ └── wrapper │ │ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ │ │ └── gradle-wrapper.properties │ │ │ │ ├── gradlew │ │ │ │ ├── gradlew.bat │ │ │ │ ├── keystores │ │ │ │ │ ├── BUCK │ │ │ │ │ └── debug.keystore.properties │ │ │ │ └── settings.gradle │ │ │ ├── app.json │ │ │ ├── index.android.js │ │ │ ├── index.ios.js │ │ │ └── ios │ │ │ │ ├── HelloWorld-tvOS │ │ │ │ └── Info.plist │ │ │ │ ├── HelloWorld-tvOSTests │ │ │ │ └── Info.plist │ │ │ │ ├── HelloWorld.xcodeproj │ │ │ │ ├── project.pbxproj │ │ │ │ └── xcshareddata │ │ │ │ │ └── xcschemes │ │ │ │ │ ├── HelloWorld-tvOS.xcscheme │ │ │ │ │ └── HelloWorld.xcscheme │ │ │ │ ├── HelloWorld │ │ │ │ ├── AppDelegate.h │ │ │ │ ├── AppDelegate.m │ │ │ │ ├── Base.lproj │ │ │ │ │ └── LaunchScreen.xib │ │ │ │ ├── Images.xcassets │ │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Info.plist │ │ │ │ └── main.m │ │ │ │ └── HelloWorldTests │ │ │ │ ├── HelloWorldTests.m │ │ │ │ └── Info.plist │ │ └── README.md │ ├── upgrade │ │ └── upgrade.js │ ├── util │ │ ├── Config.js │ │ ├── PackageManager.js │ │ ├── __mocks__ │ │ │ └── log.js │ │ ├── assertRequiredOptions.js │ │ ├── copyAndReplace.js │ │ ├── findSymlinksPaths.js │ │ ├── isPackagerRunning.js │ │ ├── isValidPackageName.js │ │ ├── log.js │ │ ├── parseCommandLine.js │ │ ├── walk.js │ │ └── yarn.js │ └── wrong-react-native.js ├── package.json ├── packager │ ├── README.md │ ├── babelRegisterOnly.js │ ├── blacklist.js │ ├── defaults.js │ ├── index.js │ ├── launchPackager.bat │ ├── launchPackager.command │ ├── package.json │ ├── packager.sh │ ├── react-native-xcode.sh │ ├── react-packager.js │ ├── rn-babelrc.json │ ├── rn-cli.config.js │ ├── src │ │ ├── AssetServer │ │ │ ├── __tests__ │ │ │ │ └── AssetServer-test.js │ │ │ └── index.js │ │ ├── Bundler │ │ │ ├── Bundle.js │ │ │ ├── BundleBase.js │ │ │ ├── HMRBundle.js │ │ │ ├── __tests__ │ │ │ │ ├── Bundle-test.js │ │ │ │ └── Bundler-test.js │ │ │ ├── index.js │ │ │ └── source-map │ │ │ │ ├── B64Builder.js │ │ │ │ ├── Generator.js │ │ │ │ ├── __tests__ │ │ │ │ ├── B64Builder-test.js │ │ │ │ ├── Generator-test.js │ │ │ │ └── source-map-test.js │ │ │ │ ├── encode.js │ │ │ │ ├── package.json │ │ │ │ └── source-map.js │ │ ├── Cache │ │ │ └── __mocks__ │ │ │ │ └── Cache.js │ │ ├── JSTransformer │ │ │ ├── README.md │ │ │ ├── __mocks__ │ │ │ │ ├── lodash.js │ │ │ │ ├── q.js │ │ │ │ └── worker.js │ │ │ ├── __tests__ │ │ │ │ └── Transformer-test.js │ │ │ ├── index.js │ │ │ └── worker │ │ │ │ ├── __tests__ │ │ │ │ ├── constant-folding-test.js │ │ │ │ ├── extract-dependencies-test.js │ │ │ │ ├── inline-test.js │ │ │ │ ├── minify-test.js │ │ │ │ └── worker-test.js │ │ │ │ ├── constant-folding.js │ │ │ │ ├── extract-dependencies.js │ │ │ │ ├── index.js │ │ │ │ ├── inline.js │ │ │ │ ├── minify.js │ │ │ │ └── worker.js │ │ ├── Logger │ │ │ ├── Types.js │ │ │ ├── __mocks__ │ │ │ │ └── chalk.js │ │ │ ├── __tests__ │ │ │ │ └── Logger-test.js │ │ │ └── index.js │ │ ├── ModuleGraph │ │ │ ├── Graph.js │ │ │ ├── ModuleGraph.js │ │ │ ├── __tests__ │ │ │ │ ├── Graph-test.js │ │ │ │ └── ModuleGraph-test.js │ │ │ ├── node-haste │ │ │ │ ├── HasteFS.js │ │ │ │ ├── Module.js │ │ │ │ ├── ModuleCache.js │ │ │ │ ├── Package.js │ │ │ │ ├── node-haste.flow.js │ │ │ │ ├── node-haste.js │ │ │ │ └── package.json │ │ │ ├── output │ │ │ │ ├── __tests__ │ │ │ │ │ └── util-test.js │ │ │ │ ├── as-plain-bundle.js │ │ │ │ ├── source-map.js │ │ │ │ └── util.js │ │ │ ├── package.json │ │ │ ├── silent-console.js │ │ │ ├── test-helpers.js │ │ │ ├── types.flow.js │ │ │ ├── worker.js │ │ │ └── worker │ │ │ │ ├── __tests__ │ │ │ │ ├── collect-dependencies-test.js │ │ │ │ ├── optimize-module-test.js │ │ │ │ ├── transform-module-test.js │ │ │ │ └── wrap-worker-fn-test.js │ │ │ │ ├── collect-dependencies.js │ │ │ │ ├── generate.js │ │ │ │ ├── optimize-module.js │ │ │ │ ├── transform-module.js │ │ │ │ └── wrap-worker-fn.js │ │ ├── Resolver │ │ │ ├── __tests__ │ │ │ │ └── Resolver-test.js │ │ │ ├── index.js │ │ │ └── polyfills │ │ │ │ ├── Array.es6.js │ │ │ │ ├── Array.prototype.es6.js │ │ │ │ ├── Number.es6.js │ │ │ │ ├── Object.es7.js │ │ │ │ ├── String.prototype.es6.js │ │ │ │ ├── __tests__ │ │ │ │ └── Object.es7-test.js │ │ │ │ ├── babelHelpers.js │ │ │ │ ├── console.js │ │ │ │ ├── error-guard.js │ │ │ │ ├── polyfills.js │ │ │ │ ├── prelude.js │ │ │ │ ├── prelude_dev.js │ │ │ │ └── require.js │ │ ├── Server │ │ │ ├── MultipartResponse.js │ │ │ ├── __tests__ │ │ │ │ ├── MultipartResponse-test.js │ │ │ │ └── Server-test.js │ │ │ └── index.js │ │ ├── __mocks__ │ │ │ └── debug.js │ │ ├── lib │ │ │ ├── BatchProcessor.js │ │ │ ├── GlobalTransformCache.js │ │ │ ├── JsonReporter.js │ │ │ ├── ModuleTransport.js │ │ │ ├── SourceMap.js │ │ │ ├── TerminalReporter.js │ │ │ ├── TransformCache.js │ │ │ ├── __mocks__ │ │ │ │ ├── BatchProcessor.js │ │ │ │ ├── GlobalTransformCache.js │ │ │ │ ├── TransformCache.js │ │ │ │ └── declareOpts.js │ │ │ ├── __tests__ │ │ │ │ ├── BatchProcessor-test.js │ │ │ │ ├── TransformCache-test.js │ │ │ │ ├── declareOpts-test.js │ │ │ │ └── terminal-test.js │ │ │ ├── declareOpts.js │ │ │ ├── relativizeSourceMap.js │ │ │ ├── reporting.js │ │ │ ├── terminal.js │ │ │ └── toFixedHex.js │ │ └── node-haste │ │ │ ├── AssetModule.js │ │ │ ├── Cache │ │ │ ├── __mocks__ │ │ │ │ └── index.js │ │ │ ├── __tests__ │ │ │ │ └── Cache-test.js │ │ │ └── index.js │ │ │ ├── DependencyGraph │ │ │ ├── DependencyGraphHelpers.js │ │ │ ├── HasteMap.js │ │ │ ├── ResolutionRequest.js │ │ │ ├── ResolutionResponse.js │ │ │ ├── assets │ │ │ │ └── empty-module.js │ │ │ └── docblock.js │ │ │ ├── Module.js │ │ │ ├── ModuleCache.js │ │ │ ├── Package.js │ │ │ ├── Polyfill.js │ │ │ ├── __mocks__ │ │ │ ├── fs.js │ │ │ └── graceful-fs.js │ │ │ ├── __tests__ │ │ │ ├── AssetModule-test.js │ │ │ ├── DependencyGraph-test.js │ │ │ └── Module-test.js │ │ │ ├── index.js │ │ │ ├── lib │ │ │ ├── AsyncTaskGroup.js │ │ │ ├── MapWithDefaults.js │ │ │ ├── __tests__ │ │ │ │ ├── getAssetDataFromName-test.js │ │ │ │ ├── getInverseDependencies-test.js │ │ │ │ └── getPlatformExtension-test.js │ │ │ ├── getAssetDataFromName.js │ │ │ ├── getInverseDependencies.js │ │ │ ├── getPlatformExtension.js │ │ │ └── replacePatterns.js │ │ │ └── types.js │ └── transformer.js └── setupBabel.js └── tests ├── index.js ├── package.json └── widget.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .* 3 | !.babelrc 4 | yarn.lock 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | tests/ 3 | node_modules/ 4 | __tests__/ 5 | lib/ 6 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | ## HISTORY 2 | 3 | ### 0.11.0 / 2017-03-14 4 | 5 | - add package.json.name as namespace of module name: https://github.com/react-component/rn-packager/pull/9 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 react-component 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /bin/rnpackager: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 4 | 'use strict'; 5 | 6 | const cli = require('../react-native/cli.js'); 7 | cli.run(); 8 | -------------------------------------------------------------------------------- /react-native/cli.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | module.exports = require('./local-cli/cli.js'); 12 | -------------------------------------------------------------------------------- /react-native/local-cli/__mocks__/beeper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | // beeper@1.1.0 has a return statement outside of a function 12 | // and therefore doesn't parse. Let's mock it so that we can 13 | // run the tests. 14 | module.exports = function () {}; 15 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/__mocks__/sign.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | function sign(source) { 12 | return source; 13 | } 14 | 15 | module.exports = sign; 16 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/__tests__/getAssetDestPathIOS-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | jest.dontMock('../getAssetDestPathIOS'); 12 | 13 | const getAssetDestPathIOS = require('../getAssetDestPathIOS'); 14 | 15 | describe('getAssetDestPathIOS', () => { 16 | it('should build correct path', () => { 17 | const asset = { 18 | name: 'icon', 19 | type: 'png', 20 | httpServerLocation: '/assets/test', 21 | }; 22 | 23 | expect(getAssetDestPathIOS(asset, 1)).toBe('assets/test/icon.png'); 24 | }); 25 | 26 | it('should consider scale', () => { 27 | const asset = { 28 | name: 'icon', 29 | type: 'png', 30 | httpServerLocation: '/assets/test', 31 | }; 32 | 33 | expect(getAssetDestPathIOS(asset, 2)).toBe('assets/test/icon@2x.png'); 34 | expect(getAssetDestPathIOS(asset, 3)).toBe('assets/test/icon@3x.png'); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/bundle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const buildBundle = require('./buildBundle'); 12 | const bundleCommandLineArgs = require('./bundleCommandLineArgs'); 13 | const outputBundle = require('./output/bundle'); 14 | 15 | /** 16 | * Builds the bundle starting to look for dependencies at the given entry path. 17 | */ 18 | function bundleWithOutput(argv, config, args, output, packagerInstance) { 19 | if (!output) { 20 | output = outputBundle; 21 | } 22 | return buildBundle(args, config, output, packagerInstance); 23 | } 24 | 25 | function bundle(argv, config, args, packagerInstance) { 26 | return bundleWithOutput(argv, config, args, undefined, packagerInstance); 27 | } 28 | 29 | module.exports = { 30 | name: 'bundle', 31 | description: 'builds the javascript bundle for offline use', 32 | func: bundle, 33 | options: bundleCommandLineArgs, 34 | 35 | // not used by the CLI itself 36 | withOutput: bundleWithOutput, 37 | }; 38 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/getAssetDestPathAndroid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const assetPathUtils = require('./assetPathUtils'); 12 | const path = require('path'); 13 | 14 | function getAssetDestPathAndroid(asset, scale) { 15 | const androidFolder = assetPathUtils.getAndroidDrawableFolderName(asset, scale); 16 | const fileName = assetPathUtils.getAndroidResourceIdentifier(asset); 17 | return path.join(androidFolder, fileName + '.' + asset.type); 18 | } 19 | 20 | module.exports = getAssetDestPathAndroid; 21 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/getAssetDestPathIOS.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const path = require('path'); 12 | 13 | function getAssetDestPathIOS(asset, scale) { 14 | const suffix = scale === 1 ? '' : '@' + scale + 'x'; 15 | const fileName = asset.name + suffix + '.' + asset.type; 16 | return path.join(asset.httpServerLocation.substr(1), fileName); 17 | } 18 | 19 | module.exports = getAssetDestPathIOS; 20 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/output/meta.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | /* global Buffer: true */ 12 | 13 | const crypto = require('crypto'); 14 | 15 | const isUTF8 = encoding => /^utf-?8$/i.test(encoding); 16 | 17 | const constantFor = encoding => 18 | /^ascii$/i.test(encoding) ? 1 : 19 | isUTF8(encoding) ? 2 : 20 | /^(?:utf-?16(?:le)?|ucs-?2)$/.test(encoding) ? 3 : 0; 21 | 22 | module.exports = function(code, encoding) { 23 | const hash = crypto.createHash('sha1'); 24 | hash.update(code, encoding); 25 | const digest = hash.digest('binary'); 26 | const signature = Buffer.alloc ? Buffer.alloc(digest.length + 1) : new Buffer(digest.length + 1); // remove the new Buffer call when RN drops support for Node 4 27 | signature.write(digest, 'binary'); 28 | signature.writeUInt8( 29 | constantFor(tryAsciiPromotion(code, encoding)), 30 | signature.length - 1); 31 | return signature; 32 | }; 33 | 34 | function tryAsciiPromotion(string, encoding) { 35 | if (!isUTF8(encoding)) { return encoding; } 36 | for (let i = 0, n = string.length; i < n; i++) { 37 | if (string.charCodeAt(i) > 0x7f) { return encoding; } 38 | } 39 | return 'ascii'; 40 | } 41 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/output/unbundle/build-unbundle-sourcemap-with-metadata.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | const {combineSourceMaps, joinModules} = require('./util'); 14 | 15 | import type {ModuleGroups, ModuleTransportLike} from '../../types.flow'; 16 | 17 | type Params = { 18 | lazyModules: Array, 19 | moduleGroups?: ModuleGroups, 20 | startupModules: Array, 21 | }; 22 | 23 | module.exports = ({startupModules, lazyModules, moduleGroups}: Params) => { 24 | const startupModule: ModuleTransportLike = { 25 | code: joinModules(startupModules), 26 | id: Number.MIN_SAFE_INTEGER, 27 | map: combineSourceMaps({modules: startupModules}), 28 | }; 29 | return combineSourceMaps({ 30 | modules: [startupModule].concat(lazyModules), 31 | moduleGroups, 32 | withCustomOffsets: true, 33 | }); 34 | }; 35 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/output/unbundle/magic-number.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | module.exports = 0xFB0BD1E5; 14 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/output/unbundle/write-sourcemap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | const writeFile = require('../writeFile'); 14 | 15 | function writeSourcemap( 16 | fileName: string, 17 | contents: string, 18 | log: (x: string) => void, 19 | ): Promise<> { 20 | if (!fileName) { 21 | return Promise.resolve(); 22 | } 23 | log('Writing sourcemap output to:', fileName); 24 | const writeMap = writeFile(fileName, contents, null); 25 | writeMap.then(() => log('Done writing sourcemap output')); 26 | return writeMap; 27 | } 28 | 29 | module.exports = writeSourcemap; 30 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/output/writeFile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | const denodeify = require('denodeify'); 14 | const fs = require('fs'); 15 | 16 | type WriteFn = 17 | (file: string, data: string | Buffer, encoding?: ?string) => Promise; 18 | const writeFile: WriteFn = denodeify(fs.writeFile); 19 | 20 | module.exports = writeFile; 21 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/types.flow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | import type Bundle from '../../packager/src/Bundler/Bundle'; 14 | import type {Unbundle} from '../../packager/src/Bundler/Bundle'; 15 | import type ModuleTransport from '../../packager/src/lib/ModuleTransport'; 16 | import type {MixedSourceMap} from '../../packager/src/lib/SourceMap'; 17 | 18 | export type {Bundle, ModuleTransport, MixedSourceMap as SourceMap, Unbundle}; 19 | 20 | export type ModuleGroups = {| 21 | groups: Map>, 22 | modulesById: Map, 23 | modulesInGroups: Set, 24 | |}; 25 | 26 | export type ModuleTransportLike = { 27 | code: string, 28 | id: number, 29 | map?: $PropertyType, 30 | +name?: string, 31 | }; 32 | 33 | export type OutputOptions = { 34 | bundleOutput: string, 35 | bundleEncoding?: 'utf8' | 'utf16le' | 'ascii', 36 | dev?: boolean, 37 | platform: string, 38 | sourcemapOutput?: string, 39 | sourcemapSourcesRoot?: string, 40 | }; 41 | 42 | export type RequestOptions = {| 43 | entryFile: string, 44 | sourceMapUrl?: string, 45 | dev?: boolean, 46 | minify: boolean, 47 | platform: string, 48 | |}; 49 | -------------------------------------------------------------------------------- /react-native/local-cli/bundle/unbundle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const bundleWithOutput = require('./bundle').withOutput; 12 | const bundleCommandLineArgs = require('./bundleCommandLineArgs'); 13 | const outputUnbundle = require('./output/unbundle'); 14 | 15 | /** 16 | * Builds the bundle starting to look for dependencies at the given entry path. 17 | */ 18 | function unbundle(argv, config, args, packagerInstance) { 19 | return bundleWithOutput(argv, config, args, outputUnbundle, packagerInstance); 20 | } 21 | 22 | module.exports = { 23 | name: 'unbundle', 24 | description: 'builds javascript as "unbundle" for offline use', 25 | func: unbundle, 26 | options: bundleCommandLineArgs.concat({ 27 | command: '--indexed-unbundle', 28 | description: 'Force indexed unbundle file format, even when building for android', 29 | default: false, 30 | }), 31 | }; 32 | -------------------------------------------------------------------------------- /react-native/local-cli/cli.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | // gracefulify() has to be called before anything else runs 12 | require('graceful-fs').gracefulify(require('fs')); 13 | 14 | // This file must be able to run in node 0.12 without babel so we can show that 15 | // it is not supported. This is why the rest of the cli code is in `cliEntry.js`. 16 | require('./server/checkNodeVersion')(); 17 | 18 | require('../setupBabel')(); 19 | 20 | var cliEntry = require('./cliEntry'); 21 | 22 | if (require.main === module) { 23 | cliEntry.run(); 24 | } 25 | 26 | module.exports = cliEntry; 27 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__fixtures__/android.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | const manifest = fs.readFileSync(path.join(__dirname, './files/AndroidManifest.xml')); 5 | const mainJavaClass = fs.readFileSync(path.join(__dirname, './files/Main.java')); 6 | 7 | exports.valid = { 8 | src: { 9 | 'AndroidManifest.xml': manifest, 10 | main: { 11 | com: { 12 | some: { 13 | example: { 14 | 'Main.java': mainJavaClass, 15 | 'ReactPackage.java': fs.readFileSync(path.join(__dirname, './files/ReactPackage.java')), 16 | }, 17 | }, 18 | }, 19 | }, 20 | }, 21 | }; 22 | 23 | exports.corrupted = { 24 | src: { 25 | 'AndroidManifest.xml': manifest, 26 | main: { 27 | com: { 28 | some: { 29 | example: {}, 30 | }, 31 | }, 32 | }, 33 | }, 34 | }; 35 | 36 | exports.noPackage = { 37 | src: { 38 | 'AndroidManifest.xml': manifest, 39 | main: { 40 | com: { 41 | some: { 42 | example: { 43 | 'Main.java': mainJavaClass, 44 | }, 45 | }, 46 | }, 47 | }, 48 | }, 49 | }; 50 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__fixtures__/commands.js: -------------------------------------------------------------------------------- 1 | exports.single = { 2 | func: () => {}, 3 | description: 'Test action', 4 | name: 'test', 5 | }; 6 | 7 | exports.multiple = [{ 8 | func: () => {}, 9 | description: 'Test action #1', 10 | name: 'test1', 11 | }, { 12 | func: () => {}, 13 | description: 'Test action #2', 14 | name: 'test2', 15 | }]; 16 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__fixtures__/dependencies.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const android = require('./android'); 4 | 5 | const pjson = fs.readFileSync(path.join(__dirname, 'files', 'package.json')); 6 | 7 | module.exports = { 8 | valid: { 9 | 'package.json': pjson, 10 | android: android.valid, 11 | }, 12 | withAssets: { 13 | 'package.json': pjson, 14 | android: android.valid, 15 | fonts: { 16 | 'A.ttf': '', 17 | 'B.ttf': '', 18 | }, 19 | images: { 20 | 'C.jpg': '', 21 | }, 22 | }, 23 | noPackage: { 24 | 'package.json': pjson, 25 | android: android.noPackage, 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__fixtures__/files/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__fixtures__/files/Main.java: -------------------------------------------------------------------------------- 1 | package com.some.example; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | public class SomeExamplePackage {} 9 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__fixtures__/files/ReactPackage.java: -------------------------------------------------------------------------------- 1 | package com.some.example; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.JavaScriptModule; 5 | import com.facebook.react.bridge.NativeModule; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.react.uimanager.ViewManager; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class SomeExamplePackage implements ReactPackage { 15 | 16 | public SomeExamplePackage() {} 17 | 18 | @Override 19 | public List createNativeModules( 20 | ReactApplicationContext reactContext) { 21 | List modules = new ArrayList<>(); 22 | modules.add(new SomeExampleModule(reactContext)); 23 | return modules; 24 | } 25 | 26 | @Override 27 | public List> createJSModules() { 28 | return Collections.emptyList(); 29 | } 30 | 31 | @Override 32 | public List createViewManagers(ReactApplicationContext reactContext) { 33 | return Collections.emptyList(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__fixtures__/ios.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | exports.valid = { 5 | 'demoProject.xcodeproj': { 6 | 'project.pbxproj': fs.readFileSync(path.join(__dirname, './files/project.pbxproj')), 7 | }, 8 | }; 9 | 10 | exports.validTestName = { 11 | 'MyTestProject.xcodeproj': { 12 | 'project.pbxproj': fs.readFileSync(path.join(__dirname, './files/project.pbxproj')), 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__fixtures__/projects.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const android = require('./android'); 4 | const ios = require('./ios'); 5 | 6 | const flat = { 7 | android: android.valid, 8 | ios: ios.valid, 9 | }; 10 | 11 | const nested = { 12 | android: { 13 | app: android.valid, 14 | }, 15 | ios: ios.valid, 16 | }; 17 | 18 | const withExamples = { 19 | Examples: flat, 20 | ios: ios.valid, 21 | android: android.valid, 22 | }; 23 | 24 | module.exports = { flat, nested, withExamples }; 25 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__tests__/android/findAndroidAppFolder.spec.js: -------------------------------------------------------------------------------- 1 | jest.autoMockOff(); 2 | 3 | const findAndroidAppFolder = require('../../android/findAndroidAppFolder'); 4 | const mockFs = require('mock-fs'); 5 | const mocks = require('../../__fixtures__/android'); 6 | 7 | describe('android::findAndroidAppFolder', () => { 8 | beforeAll(() => mockFs({ 9 | empty: {}, 10 | nested: { 11 | android: { 12 | app: mocks.valid, 13 | }, 14 | }, 15 | flat: { 16 | android: mocks.valid, 17 | }, 18 | })); 19 | 20 | it('should return an android app folder if it exists in the given folder', () => { 21 | expect(findAndroidAppFolder('flat')).toBe('android'); 22 | expect(findAndroidAppFolder('nested')).toBe('android/app'); 23 | }); 24 | 25 | it('should return `null` if there\'s no android app folder', () => { 26 | expect(findAndroidAppFolder('empty')).toBe(null); 27 | }); 28 | 29 | afterAll(mockFs.restore); 30 | }); 31 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__tests__/android/findManifest.spec.js: -------------------------------------------------------------------------------- 1 | jest.autoMockOff(); 2 | 3 | const findManifest = require('../../android/findManifest'); 4 | const mockFs = require('mock-fs'); 5 | const mocks = require('../../__fixtures__/android'); 6 | 7 | describe('android::findManifest', () => { 8 | 9 | beforeAll(() => mockFs({ 10 | empty: {}, 11 | flat: { 12 | android: mocks.valid, 13 | }, 14 | })); 15 | 16 | it('should return a manifest path if file exists in the folder', () => { 17 | expect(typeof findManifest('flat')).toBe('string'); 18 | }); 19 | 20 | it('should return `null` if there is no manifest in the folder', () => { 21 | expect(findManifest('empty')).toBe(null); 22 | }); 23 | 24 | afterAll(mockFs.restore); 25 | }); 26 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__tests__/android/findPackageClassName.spec.js: -------------------------------------------------------------------------------- 1 | jest.autoMockOff(); 2 | 3 | const findPackageClassName = require('../../android/findPackageClassName'); 4 | const mockFs = require('mock-fs'); 5 | const mocks = require('../../__fixtures__/android'); 6 | 7 | describe('android::findPackageClassName', () => { 8 | 9 | beforeAll(() => mockFs({ 10 | empty: {}, 11 | flat: { 12 | android: mocks.valid, 13 | }, 14 | })); 15 | 16 | it('should return manifest content if file exists in the folder', () => { 17 | expect(typeof findPackageClassName('flat')).toBe('string'); 18 | }); 19 | 20 | it('should return `null` if there\'s no matches', () => { 21 | expect(findPackageClassName('empty')).toBe(null); 22 | }); 23 | 24 | afterAll(mockFs.restore); 25 | }); 26 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__tests__/android/readManifest.spec.js: -------------------------------------------------------------------------------- 1 | jest.autoMockOff(); 2 | 3 | const findManifest = require('../../android/findManifest'); 4 | const readManifest = require('../../android/readManifest'); 5 | const mockFs = require('mock-fs'); 6 | const mocks = require('../../__fixtures__/android'); 7 | 8 | describe('android::readManifest', () => { 9 | 10 | beforeAll(() => mockFs({ 11 | empty: {}, 12 | nested: { 13 | android: { 14 | app: mocks.valid, 15 | }, 16 | }, 17 | })); 18 | 19 | it('should return manifest content if file exists in the folder', () => { 20 | const manifestPath = findManifest('nested'); 21 | expect(readManifest(manifestPath)).not.toBe(null); 22 | expect(typeof readManifest(manifestPath)).toBe('object'); 23 | }); 24 | 25 | it('should throw an error if there is no manifest in the folder', () => { 26 | const fakeManifestPath = findManifest('empty'); 27 | expect(() => readManifest(fakeManifestPath)).toThrow(); 28 | }); 29 | 30 | afterAll(mockFs.restore); 31 | }); 32 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__tests__/findAssets.spec.js: -------------------------------------------------------------------------------- 1 | jest.autoMockOff(); 2 | 3 | const findAssets = require('../findAssets'); 4 | const mockFs = require('mock-fs'); 5 | const dependencies = require('../__fixtures__/dependencies'); 6 | const isArray = (arg) => 7 | Object.prototype.toString.call(arg) === '[object Array]'; 8 | 9 | describe('findAssets', () => { 10 | 11 | beforeEach(() => mockFs({ testDir: dependencies.withAssets })); 12 | 13 | it('should return an array of all files in given folders', () => { 14 | const assets = findAssets('testDir', ['fonts', 'images']); 15 | 16 | expect(isArray(assets)).toBeTruthy(); 17 | expect(assets.length).toEqual(3); 18 | }); 19 | 20 | it('should prepend assets paths with the folder path', () => { 21 | const assets = findAssets('testDir', ['fonts', 'images']); 22 | 23 | assets.forEach(assetPath => expect(assetPath).toContain('testDir')); 24 | }); 25 | 26 | it('should return an empty array if given assets are null', () => { 27 | expect(findAssets('testDir', null).length).toEqual(0); 28 | }); 29 | 30 | afterEach(mockFs.restore); 31 | }); 32 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__tests__/ios/getProjectConfig.spec.js: -------------------------------------------------------------------------------- 1 | jest.autoMockOff(); 2 | 3 | const getProjectConfig = require('../../ios').projectConfig; 4 | const mockFs = require('mock-fs'); 5 | const projects = require('../../__fixtures__/projects'); 6 | 7 | describe('ios::getProjectConfig', () => { 8 | const userConfig = {}; 9 | 10 | beforeEach(() => mockFs({ testDir: projects })); 11 | 12 | it('should return an object with ios project configuration', () => { 13 | const folder = 'testDir/nested'; 14 | 15 | expect(getProjectConfig(folder, userConfig)).not.toBe(null); 16 | expect(typeof getProjectConfig(folder, userConfig)).toBe('object'); 17 | }); 18 | 19 | it('should return `null` if ios project was not found', () => { 20 | const folder = 'testDir/empty'; 21 | 22 | expect(getProjectConfig(folder, userConfig)).toBe(null); 23 | }); 24 | 25 | it('should return normalized shared library names', () => { 26 | const projectConfig = getProjectConfig('testDir/nested', { 27 | sharedLibraries: ['libc++', 'libz.tbd', 'HealthKit', 'HomeKit.framework'], 28 | }); 29 | 30 | expect(projectConfig.sharedLibraries).toEqual( 31 | ['libc++.tbd', 'libz.tbd', 'HealthKit.framework', 'HomeKit.framework'] 32 | ); 33 | }); 34 | 35 | afterEach(mockFs.restore); 36 | }); 37 | -------------------------------------------------------------------------------- /react-native/local-cli/core/__tests__/makeCommand.spec.js: -------------------------------------------------------------------------------- 1 | var spawnError = false; 2 | 3 | jest.setMock('child_process', { 4 | spawn: () => ({ 5 | on: (ev, cb) => cb(spawnError), 6 | }), 7 | }); 8 | jest.dontMock('../makeCommand'); 9 | 10 | const makeCommand = require('../makeCommand'); 11 | 12 | describe('makeCommand', () => { 13 | const command = makeCommand('echo'); 14 | 15 | it('should generate a function around shell command', () => { 16 | expect(typeof command).toBe('function'); 17 | }); 18 | 19 | it('should throw an error if there\'s no callback provided', () => { 20 | expect(command).toThrow(); 21 | }); 22 | 23 | it('should invoke a callback after command execution', () => { 24 | const spy = jest.genMockFunction(); 25 | command(spy); 26 | 27 | expect(spy.mock.calls.length).toBe(1); 28 | }); 29 | 30 | it('should throw an error if spawn ended up with error', () => { 31 | spawnError = true; 32 | const cb = jest.genMockFunction(); 33 | expect(() => command(cb)).toThrow(); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /react-native/local-cli/core/android/findAndroidAppFolder.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const fs = require('fs'); 12 | const path = require('path'); 13 | 14 | /** 15 | * @param {String} folder Folder to seek in 16 | * @return {String} 17 | */ 18 | module.exports = function findAndroidAppFolder(folder) { 19 | const flat = 'android'; 20 | const nested = path.join('android', 'app'); 21 | 22 | if (fs.existsSync(path.join(folder, nested))) { 23 | return nested; 24 | } 25 | 26 | if (fs.existsSync(path.join(folder, flat))) { 27 | return flat; 28 | } 29 | 30 | return null; 31 | }; 32 | -------------------------------------------------------------------------------- /react-native/local-cli/core/android/findManifest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const glob = require('glob'); 12 | const path = require('path'); 13 | 14 | /** 15 | * Find an android application path in the folder 16 | * 17 | * @param {String} folder Name of the folder where to seek 18 | * @return {String} 19 | */ 20 | module.exports = function findManifest(folder) { 21 | const manifestPath = glob.sync(path.join('**', 'AndroidManifest.xml'), { 22 | cwd: folder, 23 | ignore: ['node_modules/**', '**/build/**', 'Examples/**', 'examples/**'], 24 | })[0]; 25 | 26 | return manifestPath ? path.join(folder, manifestPath) : null; 27 | }; 28 | -------------------------------------------------------------------------------- /react-native/local-cli/core/android/findPackageClassName.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const fs = require('fs'); 12 | const glob = require('glob'); 13 | const path = require('path'); 14 | 15 | /** 16 | * Gets package's class name (class that implements ReactPackage) 17 | * by searching for its declaration in all Java files present in the folder 18 | * 19 | * @param {String} folder Folder to find java files 20 | */ 21 | module.exports = function getPackageClassName(folder) { 22 | const files = glob.sync('**/*.java', { cwd: folder }); 23 | 24 | const packages = files 25 | .map(filePath => fs.readFileSync(path.join(folder, filePath), 'utf8')) 26 | .map(file => file.match(/class (.*) implements ReactPackage/)) 27 | .filter(match => match); 28 | 29 | return packages.length ? packages[0][1] : null; 30 | }; 31 | -------------------------------------------------------------------------------- /react-native/local-cli/core/android/readManifest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const fs = require('fs'); 12 | const xml = require('xmldoc'); 13 | 14 | /** 15 | * @param {String} manifestPath 16 | * @return {XMLDocument} Parsed manifest's content 17 | */ 18 | module.exports = function readManifest(manifestPath) { 19 | return new xml.XmlDocument(fs.readFileSync(manifestPath, 'utf8')); 20 | }; 21 | -------------------------------------------------------------------------------- /react-native/local-cli/core/findAssets.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const glob = require('glob'); 12 | const path = require('path'); 13 | 14 | const findAssetsInFolder = (folder) => 15 | glob.sync(path.join(folder, '**'), { nodir: true }); 16 | 17 | /** 18 | * Given an array of assets folders, e.g. ['Fonts', 'Images'], 19 | * it globs in them to find all files that can be copied. 20 | * 21 | * It returns an array of absolute paths to files found. 22 | */ 23 | module.exports = function findAssets(folder, assets) { 24 | return (assets || []) 25 | .map(assetsFolder => path.join(folder, assetsFolder)) 26 | .reduce((_assets, assetsFolder) => 27 | _assets.concat(findAssetsInFolder(assetsFolder)), 28 | [] 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /react-native/local-cli/core/makeCommand.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const spawn = require('child_process').spawn; 12 | 13 | module.exports = function makeCommand(command) { 14 | return (cb) => { 15 | if (!cb) { 16 | throw new Error(`You missed a callback function for the ${command} command`); 17 | } 18 | 19 | const args = command.split(' '); 20 | const cmd = args.shift(); 21 | 22 | const commandProcess = spawn(cmd, args, { 23 | stdio: 'inherit', 24 | stdin: 'inherit', 25 | }); 26 | 27 | commandProcess.on('close', function prelink(code) { 28 | if (code) { 29 | throw new Error(`Error occured during executing "${command}" command`); 30 | } 31 | 32 | cb(); 33 | }); 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /react-native/local-cli/core/windows/findNamespace.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const fs = require('fs'); 12 | const glob = require('glob'); 13 | const path = require('path'); 14 | 15 | /** 16 | * Gets package's namespace 17 | * by searching for its declaration in all C# files present in the folder 18 | * 19 | * @param {String} folder Folder to find C# files 20 | */ 21 | module.exports = function getNamespace(folder) { 22 | const files = glob.sync('**/*.cs', { cwd: folder }); 23 | 24 | const packages = files 25 | .map(filePath => fs.readFileSync(path.join(folder, filePath), 'utf8')) 26 | .map(file => file.match(/namespace (.*)[\s\S]+IReactPackage/)) 27 | .filter(match => match); 28 | 29 | return packages.length ? packages[0][1] : null; 30 | }; 31 | -------------------------------------------------------------------------------- /react-native/local-cli/core/windows/findPackageClassName.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const fs = require('fs'); 12 | const glob = require('glob'); 13 | const path = require('path'); 14 | 15 | /** 16 | * Gets package's class name (class that implements IReactPackage) 17 | * by searching for its declaration in all C# files present in the folder 18 | * 19 | * @param {String} folder Folder to find C# files 20 | */ 21 | module.exports = function getPackageClassName(folder) { 22 | const files = glob.sync('**/*.cs', { cwd: folder }); 23 | 24 | const packages = files 25 | .map(filePath => fs.readFileSync(path.join(folder, filePath), 'utf8')) 26 | .map(file => file.match(/class (.*) : IReactPackage/)) 27 | .filter(match => match); 28 | 29 | return packages.length ? packages[0][1] : null; 30 | }; 31 | -------------------------------------------------------------------------------- /react-native/local-cli/core/windows/findProject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const glob = require('glob'); 12 | const path = require('path'); 13 | 14 | /** 15 | * Find an C# project file 16 | * 17 | * @param {String} folder Name of the folder where to seek 18 | * @return {String} 19 | */ 20 | module.exports = function findManifest(folder) { 21 | const csprojPath = glob.sync(path.join('**', '*.csproj'), { 22 | cwd: folder, 23 | ignore: ['node_modules/**', '**/build/**', 'Examples/**', 'examples/**'], 24 | })[0]; 25 | 26 | return csprojPath ? path.join(folder, csprojPath) : null; 27 | }; 28 | -------------------------------------------------------------------------------- /react-native/local-cli/core/windows/generateGUID.js: -------------------------------------------------------------------------------- 1 | const s4 = () => { 2 | return Math.floor((1 + Math.random()) * 0x10000) 3 | .toString(16) 4 | .substring(1); 5 | } 6 | 7 | module.exports = function generateGUID() { 8 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' + 9 | s4() + '-' + s4() + s4() + s4(); 10 | } 11 | -------------------------------------------------------------------------------- /react-native/local-cli/core/wrapCommands.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const makeCommand = require('./makeCommand'); 12 | 13 | module.exports = function wrapCommands(commands) { 14 | const mappedCommands = {}; 15 | Object.keys(commands || []).forEach((k) => { 16 | mappedCommands[k] = makeCommand(commands[k]); 17 | }); 18 | return mappedCommands; 19 | }; 20 | -------------------------------------------------------------------------------- /react-native/local-cli/generator/printRunInstructions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | var chalk = require('chalk'); 12 | var path = require('path'); 13 | 14 | function printRunInstructions(projectDir, projectName) { 15 | const absoluteProjectDir = path.resolve(projectDir); 16 | // iOS 17 | const xcodeProjectPath = path.resolve(projectDir, 'ios', projectName) + '.xcodeproj'; 18 | const relativeXcodeProjectPath = path.relative(process.cwd(), xcodeProjectPath); 19 | console.log(chalk.white.bold('To run your app on iOS:')); 20 | console.log(' cd ' + absoluteProjectDir); 21 | console.log(' react-native run-ios'); 22 | console.log(' - or -'); 23 | console.log(' Open ' + relativeXcodeProjectPath + ' in Xcode'); 24 | console.log(' Hit the Run button'); 25 | // Android 26 | console.log(chalk.white.bold('To run your app on Android:')); 27 | console.log(' cd ' + absoluteProjectDir); 28 | console.log(' Have an Android emulator running (quickest way to get started), or a device connected'); 29 | console.log(' react-native run-android'); 30 | } 31 | 32 | module.exports = printRunInstructions; 33 | -------------------------------------------------------------------------------- /react-native/local-cli/install/install.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const spawnSync = require('child_process').spawnSync; 12 | const log = require('npmlog'); 13 | const PackageManager = require('../util/PackageManager'); 14 | const spawnOpts = { 15 | stdio: 'inherit', 16 | stdin: 'inherit', 17 | }; 18 | 19 | log.heading = 'rnpm-install'; 20 | 21 | function install(args, config) { 22 | const name = args[0]; 23 | 24 | let res = PackageManager.add(name); 25 | 26 | if (res.status) { 27 | process.exit(res.status); 28 | } 29 | 30 | res = spawnSync('react-native', ['link', name], spawnOpts); 31 | 32 | if (res.status) { 33 | process.exit(res.status); 34 | } 35 | 36 | log.info(`Module ${name} has been successfully installed & linked`); 37 | } 38 | 39 | module.exports = { 40 | func: install, 41 | description: 'install and link native dependencies', 42 | name: 'install ', 43 | }; 44 | -------------------------------------------------------------------------------- /react-native/local-cli/install/uninstall.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const spawnSync = require('child_process').spawnSync; 12 | const log = require('npmlog'); 13 | const PackageManager = require('../util/PackageManager'); 14 | const spawnOpts = { 15 | stdio: 'inherit', 16 | stdin: 'inherit', 17 | }; 18 | 19 | log.heading = 'rnpm-install'; 20 | 21 | function uninstall(args, config) { 22 | const name = args[0]; 23 | 24 | var res = spawnSync('react-native', ['unlink', name], spawnOpts); 25 | 26 | if (res.status) { 27 | process.exit(res.status); 28 | } 29 | 30 | res = PackageManager.remove(name); 31 | 32 | if (res.status) { 33 | process.exit(res.status); 34 | } 35 | 36 | log.info(`Module ${name} has been successfully uninstalled & unlinked`); 37 | } 38 | 39 | module.exports = { 40 | func: uninstall, 41 | description: 'uninstall and unlink native dependencies', 42 | name: 'uninstall ', 43 | }; 44 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__fixtures__/android/0.18/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.testrn; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactPackage; 5 | import com.facebook.react.shell.MainReactPackage; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | public class MainActivity extends ReactActivity { 11 | 12 | /** 13 | * Returns the name of the main component registered from JavaScript. 14 | * This is used to schedule rendering of the component. 15 | */ 16 | @Override 17 | protected String getMainComponentName() { 18 | return "TestRN"; 19 | } 20 | 21 | /** 22 | * Returns whether dev mode should be enabled. 23 | * This enables e.g. the dev menu. 24 | */ 25 | @Override 26 | protected boolean getUseDeveloperSupport() { 27 | return BuildConfig.DEBUG; 28 | } 29 | 30 | /** 31 | * A list of packages used by the app. If the app uses additional views 32 | * or modules besides the default ones, add more packages here. 33 | */ 34 | @Override 35 | protected List getPackages() { 36 | return Arrays.asList( 37 | new MainReactPackage()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__fixtures__/android/0.18/patchedMainActivity.java: -------------------------------------------------------------------------------- 1 | package com.testrn; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.oblador.vectoricons.VectorIconsPackage; 5 | import com.facebook.react.ReactPackage; 6 | import com.facebook.react.shell.MainReactPackage; 7 | 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | public class MainActivity extends ReactActivity { 12 | 13 | /** 14 | * Returns the name of the main component registered from JavaScript. 15 | * This is used to schedule rendering of the component. 16 | */ 17 | @Override 18 | protected String getMainComponentName() { 19 | return "TestRN"; 20 | } 21 | 22 | /** 23 | * Returns whether dev mode should be enabled. 24 | * This enables e.g. the dev menu. 25 | */ 26 | @Override 27 | protected boolean getUseDeveloperSupport() { 28 | return BuildConfig.DEBUG; 29 | } 30 | 31 | /** 32 | * A list of packages used by the app. If the app uses additional views 33 | * or modules besides the default ones, add more packages here. 34 | */ 35 | @Override 36 | protected List getPackages() { 37 | return Arrays.asList( 38 | new MainReactPackage(), 39 | new VectorIconsPackage()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__fixtures__/android/0.20/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.myawesomeproject; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactPackage; 5 | import com.facebook.react.shell.MainReactPackage; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | public class MainActivity extends ReactActivity { 11 | 12 | /** 13 | * Returns the name of the main component registered from JavaScript. 14 | * This is used to schedule rendering of the component. 15 | */ 16 | @Override 17 | protected String getMainComponentName() { 18 | return "TestRN"; 19 | } 20 | 21 | /** 22 | * Returns whether dev mode should be enabled. 23 | * This enables e.g. the dev menu. 24 | */ 25 | @Override 26 | protected boolean getUseDeveloperSupport() { 27 | return BuildConfig.DEBUG; 28 | } 29 | 30 | /** 31 | * A list of packages used by the app. If the app uses additional views 32 | * or modules besides the default ones, add more packages here. 33 | */ 34 | @Override 35 | protected List getPackages() { 36 | return Arrays.asList( 37 | new MainReactPackage() 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__fixtures__/android/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compile fileTree(dir: "libs", include: ["*.jar"]) 3 | compile "com.android.support:appcompat-v7:23.0.1" 4 | compile "com.facebook.react:react-native:0.18.+" 5 | } 6 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__fixtures__/android/patchedBuild.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compile project(':test') 3 | compile fileTree(dir: "libs", include: ["*.jar"]) 4 | compile "com.android.support:appcompat-v7:23.0.1" 5 | compile "com.facebook.react:react-native:0.18.+" 6 | } 7 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__fixtures__/android/patchedSettings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'TestRN' 2 | 3 | include ':app' 4 | include ':test' 5 | project(':test').projectDir = new File(rootProject.projectDir, '../node_modules/test/android') 6 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__fixtures__/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'TestRN' 2 | 3 | include ':app' 4 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/android/applyPatch.spec.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.autoMockOff(); 13 | 14 | const applyParams = require('../../android/patches/applyParams'); 15 | 16 | describe('applyParams', () => { 17 | it('apply params to the string', () => { 18 | expect( 19 | applyParams('${foo}', {foo: 'foo'}, 'react-native') 20 | ).toEqual('getResources().getString(R.string.reactNative_foo)'); 21 | }); 22 | 23 | it('use null if no params provided', () => { 24 | expect( 25 | applyParams('${foo}', {}, 'react-native') 26 | ).toEqual('null'); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/android/isInstalled.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const path = require('path'); 6 | const isInstalled = require('../../android/isInstalled'); 7 | 8 | const projectConfig = { 9 | buildGradlePath: path.join(__dirname, '../../__fixtures__/android/patchedBuild.gradle'), 10 | }; 11 | 12 | describe('android::isInstalled', () => { 13 | it('should return true when project is already in build.gradle', () => 14 | expect(isInstalled(projectConfig, 'test')).toBeTruthy() 15 | ); 16 | 17 | it('should return false when project is not in build.gradle', () => 18 | expect(isInstalled(projectConfig, 'test2')).toBeFalsy() 19 | ); 20 | }); 21 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/android/makeBuildPatch.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const makeBuildPatch = require('../../android/patches/makeBuildPatch'); 6 | const name = 'test'; 7 | 8 | describe('makeBuildPatch', () => { 9 | it('should build a patch function', () => { 10 | expect(Object.prototype.toString(makeBuildPatch(name))) 11 | .toBe('[object Object]'); 12 | }); 13 | 14 | it('should make a correct patch', () => { 15 | const {patch} = makeBuildPatch(name); 16 | expect(patch).toBe(` compile project(':${name}')\n`); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/android/makeImportPatch.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const makeImportPatch = require('../../android/patches/makeImportPatch'); 6 | 7 | const packageImportPath = 'import some.example.project'; 8 | 9 | describe('makeImportPatch', () => { 10 | it('should build a patch', () => { 11 | expect(Object.prototype.toString(makeImportPatch(packageImportPath))) 12 | .toBe('[object Object]'); 13 | }); 14 | 15 | it('MainActivity contains a correct import patch', () => { 16 | const {patch} = makeImportPatch(packageImportPath); 17 | 18 | expect(patch).toBe('\n' + packageImportPath); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/android/makePackagePatch.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const makePackagePatch = require('../../android/patches/makePackagePatch'); 6 | const applyParams = require('../../android/patches/applyParams'); 7 | 8 | const packageInstance = 'new SomeLibrary(${foo}, ${bar}, \'something\')'; 9 | const name = 'some-library'; 10 | const params = { 11 | foo: 'foo', 12 | bar: 'bar', 13 | }; 14 | 15 | describe('makePackagePatch@0.20', () => { 16 | it('should build a patch', () => { 17 | const packagePatch = makePackagePatch(packageInstance, params, name); 18 | expect(Object.prototype.toString(packagePatch)) 19 | .toBe('[object Object]'); 20 | }); 21 | 22 | it('MainActivity contains a correct 0.20 import patch', () => { 23 | const {patch} = makePackagePatch(packageInstance, params, name); 24 | const processedInstance = applyParams(packageInstance, params, name); 25 | 26 | expect(patch).toBe(',\n ' + processedInstance); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/android/makeSettingsPatch.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const path = require('path'); 6 | const makeSettingsPatch = require('../../android/patches/makeSettingsPatch'); 7 | 8 | const name = 'test'; 9 | const projectConfig = { 10 | sourceDir: '/home/project/android/app', 11 | settingsGradlePath: '/home/project/android/settings.gradle', 12 | }; 13 | const dependencyConfig = { 14 | sourceDir: `/home/project/node_modules/${name}/android`, 15 | }; 16 | 17 | describe('makeSettingsPatch', () => { 18 | it('should build a patch function', () => { 19 | expect(Object.prototype.toString( 20 | makeSettingsPatch(name, dependencyConfig, projectConfig) 21 | )).toBe('[object Object]'); 22 | }); 23 | 24 | it('should make a correct patch', () => { 25 | const projectDir = path.relative( 26 | path.dirname(projectConfig.settingsGradlePath), 27 | dependencyConfig.sourceDir 28 | ); 29 | 30 | const {patch} = makeSettingsPatch(name, dependencyConfig, projectConfig); 31 | 32 | expect(patch) 33 | .toBe( 34 | `include ':${name}'\n` + 35 | `project(':${name}').projectDir = ` + 36 | `new File(rootProject.projectDir, '${projectDir}')\n` 37 | ); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/android/makeStringsPatch.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const makeStringsPatch = require('../../android/patches/makeStringsPatch'); 6 | 7 | describe('makeStringsPatch', () => { 8 | it('should export a patch with element', () => { 9 | const params = { 10 | keyA: 'valueA', 11 | }; 12 | 13 | expect(makeStringsPatch(params, 'module').patch) 14 | .toContain('valueA'); 15 | }); 16 | 17 | it('should export an empty patch if no params given', () => { 18 | expect(makeStringsPatch({}, 'module').patch).toBe(''); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/getDependencyConfig.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const getDependencyConfig = require('../getDependencyConfig'); 6 | const sinon = require('sinon'); 7 | 8 | describe('getDependencyConfig', () => { 9 | it('should return an array of dependencies\' rnpm config', () => { 10 | const config = { 11 | getDependencyConfig: sinon.stub(), 12 | }; 13 | 14 | expect(Array.isArray(getDependencyConfig(config, ['abcd']))).toBeTruthy(); 15 | expect(config.getDependencyConfig.callCount).toEqual(1); 16 | }); 17 | 18 | it('should filter out invalid react-native projects', () => { 19 | const config = { 20 | getDependencyConfig: sinon.stub().throws(new Error('Cannot require')), 21 | }; 22 | 23 | expect(getDependencyConfig(config, ['abcd'])).toEqual([]); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/getProjectDependencies.spec.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.autoMockOff(); 13 | 14 | const getProjectDependencies = require('../getProjectDependencies'); 15 | const path = require('path'); 16 | 17 | describe('getProjectDependencies', () => { 18 | beforeEach(() => { 19 | jest.resetModules(); 20 | }); 21 | it('should return an array of project dependencies', () => { 22 | jest.setMock( 23 | path.join(process.cwd(), './package.json'), 24 | { dependencies: { lodash: '^6.0.0', 'react-native': '^16.0.0' }} 25 | ); 26 | 27 | expect(getProjectDependencies()).toEqual(['lodash']); 28 | }); 29 | 30 | it('should return an empty array when no dependencies set', () => { 31 | jest.setMock(path.join(process.cwd(), './package.json'), {}); 32 | expect(getProjectDependencies()).toEqual([]); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/groupFilesByType.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const groupFilesByType = require('../groupFilesByType'); 6 | 7 | describe('groupFilesByType', () => { 8 | 9 | it('should group files by its type', () => { 10 | const fonts = [ 11 | 'fonts/a.ttf', 12 | 'fonts/b.ttf', 13 | ]; 14 | const images = [ 15 | 'images/a.jpg', 16 | 'images/c.jpeg', 17 | ]; 18 | 19 | const groupedFiles = groupFilesByType(fonts.concat(images)); 20 | 21 | expect(groupedFiles.font).toEqual(fonts); 22 | expect(groupedFiles.image).toEqual(images); 23 | }); 24 | 25 | }); 26 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/addFileToProject.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const path = require('path'); 7 | const addFileToProject = require('../../ios/addFileToProject'); 8 | const _ = require('lodash'); 9 | 10 | const project = xcode.project( 11 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 12 | ); 13 | 14 | describe('ios::addFileToProject', () => { 15 | beforeEach(() => { 16 | project.parseSync(); 17 | }); 18 | 19 | xit('should add file to a project', () => { 20 | expect( 21 | _.includes( 22 | Object.keys(project.pbxFileReferenceSection()), 23 | addFileToProject(project, '../../__fixtures__/linearGradient.pbxproj').fileRef 24 | ) 25 | ).toBeTruthy(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/addProjectToLibraries.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const path = require('path'); 7 | const PbxFile = require('xcode/lib/pbxFile'); 8 | const addProjectToLibraries = require('../../ios/addProjectToLibraries'); 9 | const last = require('lodash').last; 10 | 11 | const project = xcode.project( 12 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 13 | ); 14 | 15 | describe('ios::addProjectToLibraries', () => { 16 | beforeEach(() => { 17 | project.parseSync(); 18 | }); 19 | 20 | it('should append file to Libraries group', () => { 21 | const file = new PbxFile('fakePath'); 22 | const libraries = project.pbxGroupByName('Libraries'); 23 | 24 | addProjectToLibraries(libraries, file); 25 | 26 | const child = last(libraries.children); 27 | 28 | expect((['value', 'comment']), child).toBeTruthy(); 29 | expect(child.comment).toBe(file.basename); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/getBuildProperty.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const path = require('path'); 7 | const getBuildProperty = require('../../ios/getBuildProperty'); 8 | 9 | const project = xcode.project( 10 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 11 | ); 12 | 13 | describe('ios::getBuildProperty', () => { 14 | beforeEach(() => { 15 | project.parseSync(); 16 | }); 17 | 18 | it('should return build property from main target', () => { 19 | const plistPath = getBuildProperty(project, 'INFOPLIST_FILE'); 20 | expect(plistPath).toEqual('Basic/Info.plist'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/getGroup.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const getGroup = require('../../ios/getGroup'); 7 | const path = require('path'); 8 | 9 | const project = xcode.project( 10 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 11 | ); 12 | 13 | describe('ios::getGroup', () => { 14 | beforeEach(() => { 15 | project.parseSync(); 16 | }); 17 | 18 | it('should return a top-level group', () => { 19 | const group = getGroup(project, 'Libraries'); 20 | expect(group.children.length > 0).toBeTruthy(); 21 | expect(group.name).toBe('Libraries'); 22 | }); 23 | 24 | it('should return nested group when specified', () => { 25 | const group = getGroup(project, 'NestedGroup/Libraries'); 26 | expect(group.children.length).toBe(0); // our test nested Libraries is empty 27 | expect(group.name).toBe('Libraries'); 28 | }); 29 | 30 | it('should return null when no group found', () => { 31 | const group = getGroup(project, 'I-Dont-Exist'); 32 | expect(group).toBeNull(); 33 | }); 34 | 35 | it('should return top-level group when name not specified', () => { 36 | const mainGroupId = project.getFirstProject().firstProject.mainGroup; 37 | const mainGroup = project.getPBXGroupByKey(mainGroupId); 38 | const group = getGroup(project); 39 | expect(group).toEqual(mainGroup); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/getHeadersInFolder.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const getHeadersInFolder = require('../../ios/getHeadersInFolder'); 6 | 7 | describe('ios::getHeadersInFolder', () => { 8 | xit('should return an array of all headers in given folder', () => { 9 | jest.setMock({ 10 | 'FileA.h': '', 11 | 'FileB.h': '', 12 | }); 13 | 14 | const foundHeaders = getHeadersInFolder(process.cwd()); 15 | 16 | expect(foundHeaders.length).toBe(2); 17 | 18 | getHeadersInFolder(process.cwd()).forEach(headerPath => { 19 | expect(headerPath).to.contain(process.cwd()); 20 | }); 21 | }); 22 | 23 | xit('should ignore all headers in Pods, Examples & node_modules', () => { 24 | jest.setMock({ 25 | 'FileA.h': '', 26 | 'FileB.h': '', 27 | Pods: { 28 | 'FileC.h': '', 29 | }, 30 | Examples: { 31 | 'FileD.h': '', 32 | }, 33 | node_modules: { 34 | 'FileE.h': '', 35 | }, 36 | }); 37 | 38 | expect(getHeadersInFolder(process.cwd()).length).to.equals(2); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/getPlist.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const getPlist = require('../../ios/getPlist'); 7 | const path = require('path'); 8 | 9 | const project = xcode.project( 10 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 11 | ); 12 | 13 | describe('ios::getPlist', () => { 14 | beforeEach(() => { 15 | project.parseSync(); 16 | }); 17 | 18 | it('should return null when `.plist` file missing', () => { 19 | const plistPath = getPlist(project, process.cwd()); 20 | expect(plistPath).toBeNull(); 21 | }); 22 | 23 | // @todo - Happy scenario 24 | }); 25 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/getPlistPath.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const getPlistPath = require('../../ios/getPlistPath'); 7 | const path = require('path'); 8 | 9 | const project = xcode.project( 10 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 11 | ); 12 | 13 | describe('ios::getPlistPath', () => { 14 | beforeEach(() => { 15 | project.parseSync(); 16 | }); 17 | 18 | it('should return path without Xcode $(SRCROOT)', () => { 19 | const plistPath = getPlistPath(project, '/'); 20 | expect(plistPath).toBe('/Basic/Info.plist'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/getProducts.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const getProducts = require('../../ios/getProducts'); 7 | const path = require('path'); 8 | 9 | const project = xcode.project( 10 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 11 | ); 12 | 13 | describe('ios::getProducts', () => { 14 | beforeEach(() => { 15 | project.parseSync(); 16 | }); 17 | 18 | it('should return an array of static libraries project exports', () => { 19 | const products = getProducts(project); 20 | expect(products.length).toBe(1); 21 | expect(products).toContain('libRCTActionSheet.a'); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/hasLibraryImported.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const hasLibraryImported = require('../../ios/hasLibraryImported'); 7 | const path = require('path'); 8 | 9 | const project = xcode.project( 10 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 11 | ); 12 | 13 | describe('ios::hasLibraryImported', () => { 14 | beforeEach(() => { 15 | project.parseSync(); 16 | }); 17 | 18 | it('should return true if project has been already imported', () => { 19 | const libraries = project.pbxGroupByName('Libraries'); 20 | expect(hasLibraryImported(libraries, 'React.xcodeproj')).toBeTruthy(); 21 | }); 22 | 23 | it('should return false if project is not imported', () => { 24 | const libraries = project.pbxGroupByName('Libraries'); 25 | expect(hasLibraryImported(libraries, 'ACME.xcodeproj')).toBeFalsy(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/isInstalled.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const path = require('path'); 6 | const isInstalled = require('../../ios/isInstalled'); 7 | 8 | const baseProjectConfig = { 9 | pbxprojPath: path.join(__dirname, '../../__fixtures__/project.pbxproj'), 10 | libraryFolder: 'Libraries', 11 | }; 12 | 13 | describe('ios::isInstalled', () => { 14 | it('should return true when .xcodeproj in Libraries', () => { 15 | const dependencyConfig = { projectName: 'React.xcodeproj' }; 16 | expect(isInstalled(baseProjectConfig, dependencyConfig)).toBeTruthy(); 17 | }); 18 | 19 | it('should return false when .xcodeproj not in Libraries', () => { 20 | const dependencyConfig = { projectName: 'Missing.xcodeproj' }; 21 | expect(isInstalled(baseProjectConfig, dependencyConfig)).toBeFalsy(); 22 | }); 23 | 24 | it('should return false when `LibraryFolder` is missing', () => { 25 | const dependencyConfig = { projectName: 'React.xcodeproj' }; 26 | const projectConfig = Object.assign({}, baseProjectConfig, { libraryFolder: 'Missing' }); 27 | expect(isInstalled(projectConfig, dependencyConfig)).toBeFalsy(); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/mapHeaderSearchPaths.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const mapHeaderSearchPaths = require('../../ios/mapHeaderSearchPaths'); 7 | const path = require('path'); 8 | 9 | const project = xcode.project( 10 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 11 | ); 12 | 13 | describe('ios::mapHeaderSearchPaths', () => { 14 | beforeEach(() => { 15 | project.parseSync(); 16 | }); 17 | 18 | /** 19 | * Based on the fixtures, our assumption is that this function 20 | * has to be executed two times. 21 | */ 22 | it('should be called twice', () => { 23 | const callback = jest.fn(); 24 | mapHeaderSearchPaths(project, callback); 25 | 26 | expect(callback.mock.calls.length).toBe(2); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/removeProjectFromLibraries.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const PbxFile = require('xcode/lib/pbxFile'); 7 | const addProjectToLibraries = require('../../ios/addProjectToLibraries'); 8 | const removeProjectFromLibraries = require('../../ios/removeProjectFromLibraries'); 9 | const last = require('lodash').last; 10 | const path = require('path'); 11 | 12 | const project = xcode.project( 13 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 14 | ); 15 | 16 | describe('ios::removeProjectFromLibraries', () => { 17 | beforeEach(() => { 18 | project.parseSync(); 19 | 20 | addProjectToLibraries( 21 | project.pbxGroupByName('Libraries'), 22 | new PbxFile('fakePath') 23 | ); 24 | }); 25 | 26 | it('should remove file from Libraries group', () => { 27 | const file = new PbxFile('fakePath'); 28 | const libraries = project.pbxGroupByName('Libraries'); 29 | 30 | removeProjectFromLibraries(libraries, file); 31 | 32 | const child = last(libraries.children); 33 | 34 | expect(child.comment).not.toBe(file.basename); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/removeProjectFromProject.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const pbxFile = require('xcode/lib/pbxFile'); 7 | const addFileToProject = require('../../ios/addFileToProject'); 8 | const removeProjectFromProject = require('../../ios/removeProjectFromProject'); 9 | const path = require('path'); 10 | 11 | const project = xcode.project( 12 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 13 | ); 14 | const filePath = '../../__fixtures__/linearGradient.pbxproj'; 15 | 16 | describe('ios::addFileToProject', () => { 17 | beforeEach(() => { 18 | project.parseSync(); 19 | addFileToProject(project, filePath); 20 | }); 21 | 22 | it('should return removed file', () => { 23 | expect(removeProjectFromProject(project, filePath) instanceof pbxFile) 24 | .toBeTruthy(); 25 | }); 26 | 27 | it('should remove file from a project', () => { 28 | const file = removeProjectFromProject(project, filePath); 29 | expect(project.pbxFileReferenceSection()[file.fileRef]).not.toBeDefined(); 30 | }); 31 | 32 | xit('should remove file from PBXContainerProxy', () => { 33 | // todo(mike): add in .xcodeproj after Xcode modifications so we can test extra 34 | // removals later. 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/ios/removeSharedLibrary.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const xcode = require('xcode'); 6 | const path = require('path'); 7 | const addSharedLibraries = require('../../ios/addSharedLibraries'); 8 | const removeSharedLibraries = require('../../ios/removeSharedLibraries'); 9 | const getGroup = require('../../ios/getGroup'); 10 | 11 | const project = xcode.project( 12 | path.join(__dirname, '../../__fixtures__/project.pbxproj') 13 | ); 14 | 15 | describe('ios::removeSharedLibraries', () => { 16 | 17 | beforeEach(() => { 18 | project.parseSync(); 19 | addSharedLibraries(project, ['libc++.tbd', 'libz.tbd']); 20 | }); 21 | 22 | it('should remove only the specified shared library', () => { 23 | removeSharedLibraries(project, ['libc++.tbd']); 24 | 25 | const frameworksGroup = getGroup(project, 'Frameworks'); 26 | expect(frameworksGroup.children.length).toEqual(1); 27 | expect(frameworksGroup.children[0].comment).toEqual('libz.tbd'); 28 | }); 29 | 30 | it('should ignore missing shared libraries', () => { 31 | removeSharedLibraries(project, ['libxml2.tbd']); 32 | 33 | const frameworksGroup = getGroup(project, 'Frameworks'); 34 | expect(frameworksGroup.children.length).toEqual(2); 35 | }); 36 | 37 | }); 38 | -------------------------------------------------------------------------------- /react-native/local-cli/link/__tests__/promiseWaterfall.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.autoMockOff(); 4 | 5 | const sinon = require('sinon'); 6 | const promiseWaterfall = require('../promiseWaterfall'); 7 | 8 | describe('promiseWaterfall', () => { 9 | 10 | it('should run promises in a sequence', (done) => { 11 | const tasks = [sinon.stub(), sinon.stub()]; 12 | 13 | promiseWaterfall(tasks).then(() => { 14 | expect(tasks[0].calledBefore(tasks[1])).toBeTruthy(); 15 | done(); 16 | }); 17 | }); 18 | 19 | it('should resolve with last promise value', (done) => { 20 | const tasks = [sinon.stub().returns(1), sinon.stub().returns(2)]; 21 | 22 | promiseWaterfall(tasks).then(value => { 23 | expect(value).toEqual(2); 24 | done(); 25 | }); 26 | }); 27 | 28 | it('should stop the sequence when one of promises is rejected', (done) => { 29 | const error = new Error(); 30 | const tasks = [sinon.stub().throws(error), sinon.stub().returns(2)]; 31 | 32 | promiseWaterfall(tasks).catch(err => { 33 | expect(err).toEqual(error); 34 | expect(tasks[1].callCount).toEqual(0); 35 | done(); 36 | }); 37 | }); 38 | 39 | }); 40 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/copyAssets.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra'); 2 | const path = require('path'); 3 | const groupFilesByType = require('../groupFilesByType'); 4 | 5 | /** 6 | * Copies each file from an array of assets provided to targetPath directory 7 | * 8 | * For now, the only types of files that are handled are: 9 | * - Fonts (otf, ttf) - copied to targetPath/fonts under original name 10 | */ 11 | module.exports = function copyAssetsAndroid(files, targetPath) { 12 | const assets = groupFilesByType(files); 13 | 14 | (assets.font || []).forEach(asset => 15 | fs.copySync(asset, path.join(targetPath, 'fonts', path.basename(asset))) 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/fs.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra'); 2 | 3 | exports.readFile = (file) => 4 | () => fs.readFileSync(file, 'utf8'); 5 | 6 | exports.writeFile = (file, content) => content ? 7 | fs.writeFileSync(file, content, 'utf8') : 8 | (c) => fs.writeFileSync(file, c, 'utf8'); 9 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/isInstalled.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const makeBuildPatch = require('./patches/makeBuildPatch'); 3 | 4 | module.exports = function isInstalled(config, name) { 5 | return fs 6 | .readFileSync(config.buildGradlePath) 7 | .indexOf(makeBuildPatch(name).patch) > -1; 8 | }; 9 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/patches/applyParams.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | const toCamelCase = require('lodash').camelCase; 11 | 12 | module.exports = function applyParams(str, params, prefix) { 13 | return str.replace( 14 | /\$\{(\w+)\}/g, 15 | (pattern, param) => { 16 | const name = toCamelCase(prefix) + '_' + param; 17 | 18 | return params[param] 19 | ? `getResources().getString(R.string.${name})` 20 | : null; 21 | } 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/patches/applyPatch.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | module.exports = function applyPatch(file, patch) { 4 | fs.writeFileSync(file, fs 5 | .readFileSync(file, 'utf8') 6 | .replace(patch.pattern, match => `${match}${patch.patch}`) 7 | ); 8 | }; 9 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/patches/makeBuildPatch.js: -------------------------------------------------------------------------------- 1 | module.exports = function makeBuildPatch(name) { 2 | return { 3 | pattern: /[^ \t]dependencies {\n/, 4 | patch: ` compile project(':${name}')\n`, 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/patches/makeImportPatch.js: -------------------------------------------------------------------------------- 1 | module.exports = function makeImportPatch(packageImportPath) { 2 | return { 3 | pattern: 'import com.facebook.react.ReactApplication;', 4 | patch: '\n' + packageImportPath, 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/patches/makePackagePatch.js: -------------------------------------------------------------------------------- 1 | const applyParams = require('./applyParams'); 2 | 3 | module.exports = function makePackagePatch(packageInstance, params, prefix) { 4 | const processedInstance = applyParams(packageInstance, params, prefix); 5 | 6 | return { 7 | pattern: 'new MainReactPackage()', 8 | patch: ',\n ' + processedInstance, 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/patches/makeSettingsPatch.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const isWin = process.platform === 'win32'; 3 | 4 | module.exports = function makeSettingsPatch(name, androidConfig, projectConfig) { 5 | var projectDir = path.relative( 6 | path.dirname(projectConfig.settingsGradlePath), 7 | androidConfig.sourceDir 8 | ); 9 | 10 | /* 11 | * Fix for Windows 12 | * Backslashes is the escape character and will result in 13 | * an invalid path in settings.gradle 14 | * https://github.com/rnpm/rnpm/issues/113 15 | */ 16 | if (isWin) { 17 | projectDir = projectDir.replace(/\\/g, '/'); 18 | } 19 | 20 | return { 21 | pattern: '\n', 22 | patch: `include ':${name}'\n` + 23 | `project(':${name}').projectDir = ` + 24 | `new File(rootProject.projectDir, '${projectDir}')\n`, 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/patches/makeStringsPatch.js: -------------------------------------------------------------------------------- 1 | const toCamelCase = require('lodash').camelCase; 2 | 3 | module.exports = function makeStringsPatch(params, prefix) { 4 | const values = Object.keys(params) 5 | .map(param => { 6 | const name = toCamelCase(prefix) + '_' + param; 7 | return ' ' + 8 | `${params[param]}`; 9 | }); 10 | 11 | const patch = values.length > 0 12 | ? values.join('\n') + '\n' 13 | : ''; 14 | 15 | return { 16 | pattern: '\n', 17 | patch, 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/patches/revokePatch.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | module.exports = function revokePatch(file, patch) { 4 | fs.writeFileSync(file, fs 5 | .readFileSync(file, 'utf8') 6 | .replace(patch.patch, '') 7 | ); 8 | }; 9 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/registerNativeModule.js: -------------------------------------------------------------------------------- 1 | const applyPatch = require('./patches/applyPatch'); 2 | const makeStringsPatch = require('./patches/makeStringsPatch'); 3 | const makeSettingsPatch = require('./patches/makeSettingsPatch'); 4 | const makeBuildPatch = require('./patches/makeBuildPatch'); 5 | const makeImportPatch = require('./patches/makeImportPatch'); 6 | const makePackagePatch = require('./patches/makePackagePatch'); 7 | 8 | module.exports = function registerNativeAndroidModule( 9 | name, 10 | androidConfig, 11 | params, 12 | projectConfig 13 | ) { 14 | const buildPatch = makeBuildPatch(name); 15 | 16 | applyPatch( 17 | projectConfig.settingsGradlePath, 18 | makeSettingsPatch(name, androidConfig, projectConfig) 19 | ); 20 | 21 | applyPatch(projectConfig.buildGradlePath, buildPatch); 22 | applyPatch(projectConfig.stringsPath, makeStringsPatch(params, name)); 23 | 24 | applyPatch( 25 | projectConfig.mainFilePath, 26 | makePackagePatch(androidConfig.packageInstance, params, name) 27 | ); 28 | 29 | applyPatch( 30 | projectConfig.mainFilePath, 31 | makeImportPatch(androidConfig.packageImportPath) 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /react-native/local-cli/link/android/unlinkAssets.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra'); 2 | const path = require('path'); 3 | const groupFilesByType = require('../groupFilesByType'); 4 | 5 | /** 6 | * Copies each file from an array of assets provided to targetPath directory 7 | * 8 | * For now, the only types of files that are handled are: 9 | * - Fonts (otf, ttf) - copied to targetPath/fonts under original name 10 | */ 11 | module.exports = function unlinkAssetsAndroid(files, targetPath) { 12 | const grouped = groupFilesByType(files); 13 | 14 | grouped.font.forEach((file) => { 15 | const filename = path.basename(file); 16 | if (fs.existsSync(filename)) { 17 | fs.unlinkSync(path.join(targetPath, 'fonts', filename)); 18 | } 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /react-native/local-cli/link/commandStub.js: -------------------------------------------------------------------------------- 1 | module.exports = (cb) => cb(); -------------------------------------------------------------------------------- /react-native/local-cli/link/getDependencyConfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given an array of dependencies - it returns their RNPM config 3 | * if they were valid. 4 | */ 5 | module.exports = function getDependencyConfig(config, deps) { 6 | return deps.reduce((acc, name) => { 7 | try { 8 | return acc.concat({ 9 | config: config.getDependencyConfig(name), 10 | name, 11 | }); 12 | } catch (err) { 13 | console.log(err); 14 | return acc; 15 | } 16 | }, []); 17 | }; 18 | -------------------------------------------------------------------------------- /react-native/local-cli/link/getProjectDependencies.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | /** 4 | * Returns an array of dependencies that should be linked/checked. 5 | */ 6 | module.exports = function getProjectDependencies() { 7 | const pjson = require(path.join(process.cwd(), './package.json')); 8 | return Object.keys(pjson.dependencies || {}).filter(name => name !== 'react-native'); 9 | }; 10 | -------------------------------------------------------------------------------- /react-native/local-cli/link/groupFilesByType.js: -------------------------------------------------------------------------------- 1 | const groupBy = require('lodash').groupBy; 2 | const mime = require('mime'); 3 | 4 | /** 5 | * Since there are no officially registered MIME types 6 | * for ttf/otf yet http://www.iana.org/assignments/media-types/media-types.xhtml, 7 | * we define two non-standard ones for the sake of parsing 8 | */ 9 | mime.define({ 10 | 'font/opentype': ['otf'], 11 | 'font/truetype': ['ttf'], 12 | }); 13 | 14 | /** 15 | * Given an array of files, it groups it by it's type. 16 | * Type of the file is inferred from it's mimetype based on the extension 17 | * file ends up with. The returned value is an object with properties that 18 | * correspond to the first part of the mimetype, e.g. images will be grouped 19 | * under `image` key since the mimetype for them is `image/jpg` etc. 20 | * 21 | * Example: 22 | * Given an array ['fonts/a.ttf', 'images/b.jpg'], 23 | * the returned object will be: {font: ['fonts/a.ttf'], image: ['images/b.jpg']} 24 | */ 25 | module.exports = function groupFilesByType(assets) { 26 | return groupBy(assets, type => mime.lookup(type).split('/')[0]); 27 | }; 28 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/addFileToProject.js: -------------------------------------------------------------------------------- 1 | const PbxFile = require('xcode/lib/pbxFile'); 2 | 3 | /** 4 | * Given xcodeproj and filePath, it creates new file 5 | * from path provided, adds it to the project 6 | * and returns newly created instance of a file 7 | */ 8 | module.exports = function addFileToProject(project, filePath) { 9 | const file = new PbxFile(filePath); 10 | file.uuid = project.generateUuid(); 11 | file.fileRef = project.generateUuid(); 12 | project.addToPbxFileReferenceSection(file); 13 | return file; 14 | }; 15 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/addProjectToLibraries.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given an array of xcodeproj libraries and pbxFile, 3 | * it appends it to that group 4 | * 5 | * Important: That function mutates `libraries` and it's not pure. 6 | * It's mainly due to limitations of `xcode` library. 7 | */ 8 | module.exports = function addProjectToLibraries(libraries, file) { 9 | return libraries.children.push({ 10 | value: file.fileRef, 11 | comment: file.basename, 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/addSharedLibraries.js: -------------------------------------------------------------------------------- 1 | const createGroupWithMessage = require('./createGroupWithMessage'); 2 | 3 | module.exports = function addSharedLibraries(project, libraries) { 4 | if (!libraries.length) { 5 | return; 6 | } 7 | 8 | // Create a Frameworks group if necessary. 9 | createGroupWithMessage(project, 'Frameworks'); 10 | 11 | const target = project.getFirstTarget().uuid; 12 | 13 | for (var name of libraries) { 14 | project.addFramework(name, { target }); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/addToHeaderSearchPaths.js: -------------------------------------------------------------------------------- 1 | const mapHeaderSearchPaths = require('./mapHeaderSearchPaths'); 2 | 3 | module.exports = function addToHeaderSearchPaths(project, path) { 4 | mapHeaderSearchPaths(project, searchPaths => searchPaths.concat(path)); 5 | }; 6 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/createGroup.js: -------------------------------------------------------------------------------- 1 | const getGroup = require('./getGroup'); 2 | 3 | const hasGroup = (pbxGroup, name) => pbxGroup.children.find(group => group.comment === name); 4 | 5 | /** 6 | * Given project and path of the group, it deeply creates a given group 7 | * making all outer groups if neccessary 8 | * 9 | * Returns newly created group 10 | */ 11 | module.exports = function createGroup(project, path) { 12 | return path.split('/').reduce( 13 | (group, name) => { 14 | if (!hasGroup(group, name)) { 15 | const uuid = project.pbxCreateGroup(name, '""'); 16 | 17 | group.children.push({ 18 | value: uuid, 19 | comment: name, 20 | }); 21 | } 22 | 23 | return project.pbxGroupByName(name); 24 | }, 25 | getGroup(project) 26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/createGroupWithMessage.js: -------------------------------------------------------------------------------- 1 | const log = require('npmlog'); 2 | 3 | const createGroup = require('./createGroup'); 4 | const getGroup = require('./getGroup'); 5 | 6 | /** 7 | * Given project and path of the group, it checks if a group exists at that path, 8 | * and deeply creates a group for that path if its does not already exist. 9 | * 10 | * Returns the existing or newly created group 11 | */ 12 | module.exports = function createGroupWithMessage(project, path) { 13 | var group = getGroup(project, path); 14 | 15 | if (!group) { 16 | group = createGroup(project, path); 17 | 18 | log.warn( 19 | 'ERRGROUP', 20 | `Group '${path}' does not exist in your XCode project. We have created it automatically for you.` 21 | ); 22 | } 23 | 24 | return group; 25 | }; 26 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/getBuildProperty.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Gets build property from the main target build section 3 | * 4 | * It differs from the project.getBuildProperty exposed by xcode in the way that: 5 | * - it only checks for build property in the main target `Debug` section 6 | * - `xcode` library iterates over all build sections and because it misses 7 | * an early return when property is found, it will return undefined/wrong value 8 | * when there's another build section typically after the one you want to access 9 | * without the property defined (e.g. CocoaPods sections appended to project 10 | * miss INFOPLIST_FILE), see: https://github.com/alunny/node-xcode/blob/master/lib/pbxProject.js#L1765 11 | */ 12 | module.exports = function getBuildProperty(project, prop) { 13 | const target = project.getFirstTarget().firstTarget; 14 | const config = project.pbxXCConfigurationList()[target.buildConfigurationList]; 15 | const buildSection = project.pbxXCBuildConfigurationSection()[config.buildConfigurations[0].value]; 16 | 17 | return buildSection.buildSettings[prop]; 18 | }; 19 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/getGroup.js: -------------------------------------------------------------------------------- 1 | const getFirstProject = (project) => project.getFirstProject().firstProject; 2 | 3 | const findGroup = (group, name) => group.children.find(group => group.comment === name); 4 | 5 | /** 6 | * Returns group from .xcodeproj if one exists, null otherwise 7 | * 8 | * Unlike node-xcode `pbxGroupByName` - it does not return `first-matching` 9 | * group if multiple groups with the same name exist 10 | * 11 | * If path is not provided, it returns top-level group 12 | */ 13 | module.exports = function getGroup(project, path) { 14 | const firstProject = getFirstProject(project); 15 | 16 | var group = project.getPBXGroupByKey(firstProject.mainGroup); 17 | 18 | if (!path) { 19 | return group; 20 | } 21 | 22 | for (var name of path.split('/')) { 23 | var foundGroup = findGroup(group, name); 24 | 25 | if (foundGroup) { 26 | group = project.getPBXGroupByKey(foundGroup.value); 27 | } else { 28 | group = null; 29 | break; 30 | } 31 | } 32 | 33 | return group; 34 | }; 35 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/getHeadersInFolder.js: -------------------------------------------------------------------------------- 1 | const glob = require('glob'); 2 | const path = require('path'); 3 | 4 | const GLOB_EXCLUDE_PATTERN = ['node_modules/**', 'Pods/**', 'Examples/**', 'examples/**']; 5 | 6 | /** 7 | * Given folder, it returns an array of all header files 8 | * inside it, ignoring node_modules and examples 9 | */ 10 | module.exports = function getHeadersInFolder(folder) { 11 | return glob 12 | .sync('**/*.h', { 13 | cwd: folder, 14 | nodir: true, 15 | ignore: GLOB_EXCLUDE_PATTERN, 16 | }) 17 | .map(file => path.join(folder, file)); 18 | }; 19 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/getPlist.js: -------------------------------------------------------------------------------- 1 | const plistParser = require('plist'); 2 | const getPlistPath = require('./getPlistPath'); 3 | const fs = require('fs'); 4 | 5 | /** 6 | * Returns Info.plist located in the iOS project 7 | * 8 | * Returns `null` if INFOPLIST_FILE is not specified. 9 | */ 10 | module.exports = function getPlist(project, sourceDir) { 11 | const plistPath = getPlistPath(project, sourceDir); 12 | 13 | if (!plistPath || !fs.existsSync(plistPath)) { 14 | return null; 15 | } 16 | 17 | return plistParser.parse( 18 | fs.readFileSync(plistPath, 'utf-8') 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/getPlistPath.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const getBuildProperty = require('./getBuildProperty'); 3 | 4 | module.exports = function getPlistPath(project, sourceDir) { 5 | const plistFile = getBuildProperty(project, 'INFOPLIST_FILE'); 6 | 7 | if (!plistFile) { 8 | return null; 9 | } 10 | 11 | return path.join( 12 | sourceDir, 13 | plistFile.replace(/"/g, '').replace('$(SRCROOT)', '') 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/getProducts.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given xcodeproj it returns list of products ending with 3 | * .a extension, so that we know what elements add to target 4 | * project static library 5 | */ 6 | module.exports = function getProducts(project) { 7 | return project 8 | .pbxGroupByName('Products') 9 | .children 10 | .map(c => c.comment) 11 | .filter(c => c.indexOf('.a') > -1); 12 | }; 13 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/hasLibraryImported.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given an array of libraries already imported and packageName that will be 3 | * added, returns true or false depending on whether the library is already linked 4 | * or not 5 | */ 6 | module.exports = function hasLibraryImported(libraries, packageName) { 7 | return libraries.children 8 | .filter(library => library.comment === packageName) 9 | .length > 0; 10 | }; 11 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/isInstalled.js: -------------------------------------------------------------------------------- 1 | const xcode = require('xcode'); 2 | const getGroup = require('./getGroup'); 3 | const hasLibraryImported = require('./hasLibraryImported'); 4 | 5 | /** 6 | * Returns true if `xcodeproj` specified by dependencyConfig is present 7 | * in a top level `libraryFolder` 8 | */ 9 | module.exports = function isInstalled(projectConfig, dependencyConfig) { 10 | const project = xcode.project(projectConfig.pbxprojPath).parseSync(); 11 | const libraries = getGroup(project, projectConfig.libraryFolder); 12 | 13 | if (!libraries) { 14 | return false; 15 | } 16 | 17 | return hasLibraryImported(libraries, dependencyConfig.projectName); 18 | }; 19 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/mapHeaderSearchPaths.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given Xcode project and path, iterate over all build configurations 3 | * and execute func with HEADER_SEARCH_PATHS from current section 4 | * 5 | * We cannot use builtin addToHeaderSearchPaths method since react-native init does not 6 | * use $(TARGET_NAME) for PRODUCT_NAME, but sets it manually so that method will skip 7 | * that target. 8 | * 9 | * To workaround that issue and make it more bullet-proof for different names, 10 | * we iterate over all configurations and look for `lc++` linker flag to detect 11 | * React Native target. 12 | * 13 | * Important: That function mutates `buildSettings` and it's not pure thus you should 14 | * not rely on its return value 15 | */ 16 | const defaultHeaderPaths = ['"$(inherited)"']; 17 | 18 | module.exports = function headerSearchPathIter(project, func) { 19 | const config = project.pbxXCBuildConfigurationSection(); 20 | 21 | Object 22 | .keys(config) 23 | .filter(ref => ref.indexOf('_comment') === -1) 24 | .forEach(ref => { 25 | const buildSettings = config[ref].buildSettings; 26 | const shouldVisitBuildSettings = ( 27 | Array.isArray(buildSettings.OTHER_LDFLAGS) ? 28 | buildSettings.OTHER_LDFLAGS : 29 | [] 30 | ) 31 | .indexOf('"-lc++"') >= 0; 32 | 33 | if (shouldVisitBuildSettings) { 34 | buildSettings.HEADER_SEARCH_PATHS = func( 35 | buildSettings.HEADER_SEARCH_PATHS || defaultHeaderPaths 36 | ); 37 | } 38 | }); 39 | }; 40 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/removeFromHeaderSearchPaths.js: -------------------------------------------------------------------------------- 1 | const mapHeaderSearchPaths = require('./mapHeaderSearchPaths'); 2 | 3 | /** 4 | * Given Xcode project and absolute path, it makes sure there are no headers referring to it 5 | */ 6 | module.exports = function addToHeaderSearchPaths(project, path) { 7 | mapHeaderSearchPaths(project, 8 | searchPaths => searchPaths.filter(searchPath => searchPath !== path) 9 | ); 10 | }; 11 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/removeFromPbxItemContainerProxySection.js: -------------------------------------------------------------------------------- 1 | /** 2 | * For all files that are created and referenced from another `.xcodeproj` - 3 | * a new PBXItemContainerProxy is created that contains `containerPortal` value 4 | * which equals to xcodeproj file.uuid from PBXFileReference section. 5 | */ 6 | module.exports = function removeFromPbxItemContainerProxySection(project, file) { 7 | const section = project.hash.project.objects.PBXContainerItemProxy; 8 | 9 | for (var key of Object.keys(section)) { 10 | if (section[key].containerPortal === file.uuid) { 11 | delete section[key]; 12 | } 13 | } 14 | 15 | return; 16 | }; 17 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/removeFromPbxReferenceProxySection.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Every file added to the project from another project is attached to 3 | * `PBXItemContainerProxy` through `PBXReferenceProxy`. 4 | */ 5 | module.exports = function removeFromPbxReferenceProxySection(project, file) { 6 | const section = project.hash.project.objects.PBXReferenceProxy; 7 | 8 | for (var key of Object.keys(section)) { 9 | if (section[key].path === file.basename) { 10 | delete section[key]; 11 | } 12 | } 13 | 14 | return; 15 | }; 16 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/removeFromProjectReferences.js: -------------------------------------------------------------------------------- 1 | /** 2 | * For each file (.xcodeproj), there's an entry in `projectReferences` created 3 | * that has two entries - `ProjectRef` - reference to a file.uuid and 4 | * `ProductGroup` - uuid of a Products group. 5 | * 6 | * When projectReference is found - it's deleted and the removed value is returned 7 | * so that ProductGroup in PBXGroup section can be removed as well. 8 | * 9 | * Otherwise returns null 10 | */ 11 | module.exports = function removeFromProjectReferences(project, file) { 12 | const firstProject = project.getFirstProject().firstProject; 13 | 14 | const projectRef = firstProject.projectReferences.find(item => item.ProjectRef === file.uuid); 15 | 16 | if (!projectRef) { 17 | return null; 18 | } 19 | 20 | firstProject.projectReferences.splice( 21 | firstProject.projectReferences.indexOf(projectRef), 22 | 1 23 | ); 24 | 25 | return projectRef; 26 | }; 27 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/removeFromStaticLibraries.js: -------------------------------------------------------------------------------- 1 | const PbxFile = require('xcode/lib/pbxFile'); 2 | const removeFromPbxReferenceProxySection = require('./removeFromPbxReferenceProxySection'); 3 | 4 | /** 5 | * Removes file from static libraries 6 | * 7 | * Similar to `node-xcode` addStaticLibrary 8 | */ 9 | module.exports = function removeFromStaticLibraries(project, path, opts) { 10 | const file = new PbxFile(path); 11 | 12 | file.target = opts ? opts.target : undefined; 13 | 14 | project.removeFromPbxFileReferenceSection(file); 15 | project.removeFromPbxBuildFileSection(file); 16 | project.removeFromPbxFrameworksBuildPhase(file); 17 | project.removeFromLibrarySearchPaths(file); 18 | removeFromPbxReferenceProxySection(project, file); 19 | 20 | return file; 21 | }; 22 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/removeProductGroup.js: -------------------------------------------------------------------------------- 1 | module.exports = function removeProductGroup(project, productGroupId) { 2 | const section = project.hash.project.objects.PBXGroup; 3 | 4 | for (var key of Object.keys(section)) { 5 | if (key === productGroupId) { 6 | delete section[key]; 7 | } 8 | } 9 | 10 | return; 11 | }; 12 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/removeProjectFromLibraries.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given an array of xcodeproj libraries and pbxFile, 3 | * it removes it from that group by comparing basenames 4 | * 5 | * Important: That function mutates `libraries` and it's not pure. 6 | * It's mainly due to limitations of `xcode` library. 7 | */ 8 | module.exports = function removeProjectFromLibraries(libraries, file) { 9 | libraries.children = libraries.children.filter(library => 10 | library.comment !== file.basename 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/removeProjectFromProject.js: -------------------------------------------------------------------------------- 1 | const PbxFile = require('xcode/lib/pbxFile'); 2 | const removeFromPbxItemContainerProxySection = require('./removeFromPbxItemContainerProxySection'); 3 | const removeFromProjectReferences = require('./removeFromProjectReferences'); 4 | const removeProductGroup = require('./removeProductGroup'); 5 | 6 | /** 7 | * Given xcodeproj and filePath, it creates new file 8 | * from path provided and removes it. That operation is required since 9 | * underlying method requires PbxFile instance to be passed (it does not 10 | * have to have uuid or fileRef defined since it will do equality check 11 | * by path) 12 | * 13 | * Returns removed file (that one will have UUID) 14 | */ 15 | module.exports = function removeProjectFromProject(project, filePath) { 16 | const file = project.removeFromPbxFileReferenceSection(new PbxFile(filePath)); 17 | const projectRef = removeFromProjectReferences(project, file); 18 | 19 | if (projectRef) { 20 | removeProductGroup(project, projectRef.ProductGroup); 21 | } 22 | 23 | removeFromPbxItemContainerProxySection(project, file); 24 | 25 | return file; 26 | }; 27 | -------------------------------------------------------------------------------- /react-native/local-cli/link/ios/removeSharedLibraries.js: -------------------------------------------------------------------------------- 1 | module.exports = function removeSharedLibraries(project, libraries) { 2 | if (!libraries.length) { 3 | return; 4 | } 5 | 6 | const target = project.getFirstTarget().uuid; 7 | 8 | for (var name of libraries) { 9 | project.removeFramework(name, { target }); 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /react-native/local-cli/link/pollParams.js: -------------------------------------------------------------------------------- 1 | var inquirer = require('inquirer'); 2 | 3 | module.exports = (questions) => new Promise((resolve, reject) => { 4 | if (!questions) { 5 | return resolve({}); 6 | } 7 | 8 | inquirer.prompt(questions, resolve); 9 | }); 10 | -------------------------------------------------------------------------------- /react-native/local-cli/link/promiseWaterfall.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given an array of promise creators, executes them in a sequence. 3 | * 4 | * If any of the promises in the chain fails, all subsequent promises 5 | * will be skipped 6 | * 7 | * Returns the value last promise from a sequence resolved 8 | */ 9 | module.exports = function promiseWaterfall(tasks) { 10 | return tasks.reduce( 11 | (prevTaskPromise, task) => prevTaskPromise.then(task), 12 | Promise.resolve() 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /react-native/local-cli/link/promisify.js: -------------------------------------------------------------------------------- 1 | module.exports = (func) => new Promise((resolve, reject) => 2 | func((err, res) => err ? reject(err) : resolve(res)) 3 | ); -------------------------------------------------------------------------------- /react-native/local-cli/link/windows/isInstalled.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const makeUsingPatch = require('./patches/makeUsingPatch'); 3 | 4 | module.exports = function isInstalled(config, dependencyConfig) { 5 | return fs 6 | .readFileSync(config.mainPage) 7 | .indexOf(makeUsingPatch(dependencyConfig.packageUsingPath).patch) > -1; 8 | }; 9 | -------------------------------------------------------------------------------- /react-native/local-cli/link/windows/patches/applyParams.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | const toCamelCase = require('lodash').camelCase; 11 | 12 | module.exports = function applyParams(str, params, prefix) { 13 | return str.replace( 14 | /\$\{(\w+)\}/g, 15 | (pattern, param) => { 16 | const name = toCamelCase(prefix) + '_' + param; 17 | 18 | return params[param] 19 | ? `getResources().getString(R.string.${name})` 20 | : null; 21 | } 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /react-native/local-cli/link/windows/patches/applyPatch.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | module.exports = function applyPatch(file, patch, flip = false) { 4 | 5 | fs.writeFileSync(file, fs 6 | .readFileSync(file, 'utf8') 7 | .replace(patch.pattern, match => { 8 | return flip ? `${patch.patch}${match}` : `${match}${patch.patch}` 9 | }) 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /react-native/local-cli/link/windows/patches/makePackagePatch.js: -------------------------------------------------------------------------------- 1 | const applyParams = require('./applyParams'); 2 | 3 | module.exports = function makePackagePatch(packageInstance, params, prefix) { 4 | const processedInstance = applyParams(packageInstance, params, prefix); 5 | 6 | return { 7 | pattern: 'new MainReactPackage()', 8 | patch: ',\n ' + processedInstance, 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /react-native/local-cli/link/windows/patches/makeProjectPatch.js: -------------------------------------------------------------------------------- 1 | module.exports = function makeProjectPatch(windowsConfig) { 2 | 3 | const projectInsert = ` 4 | {${windowsConfig.pathGUID}} 5 | ${windowsConfig.projectName} 6 | 7 | `; 8 | 9 | return { 10 | pattern: '', 11 | patch: projectInsert, 12 | unpatch: new RegExp(` { 19 | _logAndroid(resolve, reject); 20 | }); 21 | } 22 | 23 | function _logAndroid() { 24 | try { 25 | const adbPath = process.env.ANDROID_HOME 26 | ? process.env.ANDROID_HOME + '/platform-tools/adb' 27 | : 'adb'; 28 | 29 | const adbArgs = ['logcat', '*:S', 'ReactNative:V', 'ReactNativeJS:V']; 30 | 31 | console.log(chalk.bold( 32 | `Starting the logger (${adbPath} ${adbArgs.join(' ')})...` 33 | )); 34 | 35 | const log = child_process.spawnSync(adbPath, adbArgs, {stdio: 'inherit'}); 36 | 37 | if (log.error !== null) { 38 | throw log.error; 39 | } 40 | 41 | } catch (e) { 42 | console.log(chalk.red( 43 | 'adb invocation failed. Do you have adb in your PATH?' 44 | )); 45 | return Promise.reject(); 46 | } 47 | } 48 | 49 | module.exports = { 50 | name: 'log-android', 51 | description: 'starts adb logcat', 52 | func: logAndroid, 53 | }; 54 | -------------------------------------------------------------------------------- /react-native/local-cli/runAndroid/adb.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 12 | const child_process = require('child_process'); 13 | 14 | /** 15 | * Parses the output of the 'adb devices' command 16 | */ 17 | function parseDevicesResult(result: string): Array { 18 | if (!result) { 19 | return []; 20 | } 21 | 22 | const devices = []; 23 | const lines = result.trim().split(/\r?\n/); 24 | 25 | for (let i=0; i < lines.length; i++) { 26 | let words = lines[i].split(/[ ,\t]+/).filter((w) => w !== ''); 27 | 28 | if (words[1] === 'device') { 29 | devices.push(words[0]); 30 | } 31 | } 32 | return devices; 33 | } 34 | 35 | /** 36 | * Executes the commands needed to get a list of devices from ADB 37 | */ 38 | function getDevices(): Array { 39 | try { 40 | const devicesResult = child_process.execSync('adb devices'); 41 | return parseDevicesResult(devicesResult.toString()); 42 | } catch (e) { 43 | return []; 44 | } 45 | 46 | 47 | } 48 | 49 | module.exports = { 50 | parseDevicesResult: parseDevicesResult, 51 | getDevices: getDevices 52 | }; -------------------------------------------------------------------------------- /react-native/local-cli/runIOS/__tests__/parseIOSDevicesList-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.dontMock('../parseIOSDevicesList'); 13 | var parseIOSDevicesList = require('../parseIOSDevicesList'); 14 | 15 | describe('parseIOSDevicesList', () => { 16 | it('parses typical output', () => { 17 | var devices = parseIOSDevicesList([ 18 | 'Known Devices:', 19 | 'Maxs MacBook Pro [11111111-1111-1111-1111-111111111111]', 20 | "Max's iPhone (9.2) [11111111111111111111aaaaaaaaaaaaaaaaaaaa]", 21 | 'iPad 2 (9.3) [07538CE4-675B-4EDA-90F2-3DD3CD93309D] (Simulator)', 22 | 'iPad Air (9.3) [0745F6D1-6DC5-4427-B9A6-6FBA327ED65A] (Simulator)', 23 | 'iPhone 6s (9.3) [3DBE4ECF-9A86-469E-921B-EE0F9C9AB8F4] (Simulator)', 24 | 'Known Templates:', 25 | 'Activity Monitor', 26 | 'Blank', 27 | 'System Usage', 28 | 'Zombies' 29 | ].join('\n')); 30 | 31 | expect(devices).toEqual([ 32 | {name: "Max's iPhone", udid: '11111111111111111111aaaaaaaaaaaaaaaaaaaa', version: '9.2'}, 33 | ]); 34 | }); 35 | 36 | it('ignores garbage', () => { 37 | expect(parseIOSDevicesList('Something went terribly wrong (-42)')).toEqual([]); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /react-native/local-cli/runIOS/findXcodeProject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | const path = require('path'); 14 | 15 | type ProjectInfo = { 16 | name: string; 17 | isWorkspace: boolean; 18 | } 19 | 20 | function findXcodeProject(files: Array): ?ProjectInfo { 21 | const sortedFiles = files.sort(); 22 | for (let i = sortedFiles.length - 1; i >= 0; i--) { 23 | const fileName = files[i]; 24 | const ext = path.extname(fileName); 25 | 26 | if (ext === '.xcworkspace') { 27 | return { 28 | name: fileName, 29 | isWorkspace: true, 30 | }; 31 | } 32 | if (ext === '.xcodeproj') { 33 | return { 34 | name: fileName, 35 | isWorkspace: false, 36 | }; 37 | } 38 | } 39 | 40 | return null; 41 | } 42 | 43 | module.exports = findXcodeProject; 44 | -------------------------------------------------------------------------------- /react-native/local-cli/runIOS/parseIOSDevicesList.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | type IOSDeviceInfo = { 14 | name: string; 15 | udid: string; 16 | version: string; 17 | } 18 | 19 | /** 20 | * Parses the output of `xcrun simctl list devices` command 21 | */ 22 | function parseIOSDevicesList(text: string): Array { 23 | const devices = []; 24 | text.split('\n').forEach((line) => { 25 | const device = line.match(/(.*?) \((.*?)\) \[(.*?)\]/); 26 | const noSimulator = line.match(/(.*?) \((.*?)\) \[(.*?)\] \((.*?)\)/); 27 | if (device != null && noSimulator == null){ 28 | var name = device[1]; 29 | var version = device[2]; 30 | var udid = device[3]; 31 | devices.push({udid, name, version}); 32 | } 33 | }); 34 | 35 | return devices; 36 | } 37 | 38 | module.exports = parseIOSDevicesList; 39 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/copyToClipBoardMiddleware.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const copyToClipBoard = require('../util/copyToClipBoard'); 12 | var chalk = require('chalk'); 13 | 14 | /** 15 | * Handle the request from JS to copy contents onto host system clipboard. 16 | * This is only supported on Mac for now. 17 | */ 18 | module.exports = function(req, res, next) { 19 | if (req.url === '/copy-to-clipboard') { 20 | var ret = copyToClipBoard(req.rawBody); 21 | if (!ret) { 22 | console.warn(chalk.red('Copy button is not supported on this platform!')); 23 | } 24 | res.end('OK'); 25 | } else { 26 | next(); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/heapCapture/Makefile: -------------------------------------------------------------------------------- 1 | SHELL := /bin/bash 2 | 3 | all: 4 | NODE_PATH="../../../../node_modules/" babel --presets babel-preset-react-native --source-maps inline -d out src 5 | for f in out/*.js; do echo -e "\n// @generated" >> $$f; done 6 | 7 | watch: 8 | NODE_PATH="../../../../node_modules/" babel --watch --presets babel-preset-react-native -d out src 9 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/heapCapture/heapCapture.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSC Heap Capture 6 | 7 | 8 | Loading... This could take a while depending on how big the profile is. Check devtools console for errors. 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/heapCapture/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsc-heap-capture", 3 | "version": "1.0.0", 4 | "description": "processes captured heaps from javascript core", 5 | "main": "bundle.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "webpack" 9 | }, 10 | "author": "cwdick", 11 | "devDependencies": { 12 | "babel-core": "^6.17.0", 13 | "babel-loader": "^6.2.5", 14 | "babel-plugin-transform-class-properties": "^6.16.0", 15 | "babel-preset-es2015": "^6.16.0", 16 | "babel-preset-react": "^6.16.0", 17 | "react": "^0.14.1", 18 | "react-dom": "^0.14.1", 19 | "webpack": "^1.13.2" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/heapCapture/src/DataColumnSelector.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import invariant from 'invariant'; 4 | import React from 'react'; 5 | 6 | import AggrowData from './AggrowData'; 7 | import type { AggrowColumn } from './AggrowData'; 8 | 9 | type Props = { 10 | aggrow: AggrowData, 11 | filter: (column: AggrowColumn) => boolean, 12 | onSelect: (columnName: string) => void, 13 | selected?: string, 14 | } 15 | 16 | export default class DataColumnSelector extends React.Component { 17 | static defaultProps = { 18 | filter: (): boolean => true, 19 | }; 20 | 21 | props: Props; 22 | 23 | _handleChange = (e: SyntheticEvent) => { 24 | invariant(e.target instanceof HTMLSelectElement, 'Expected element'); 25 | const changed = Number.parseInt(e.target.value, 10); 26 | this.props.onSelect(this.props.aggrow.columns[changed].name); 27 | } 28 | 29 | render(): React.Element<*> { 30 | const columns = this.props.aggrow.columns.filter(this.props.filter); 31 | const selected = columns.findIndex( 32 | (c: AggrowColumn): boolean => c.name === this.props.selected); 33 | return ( 34 | 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/heapCapture/src/Draggable.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from 'react'; 4 | 5 | type Props = { 6 | id: string, 7 | children?: any, 8 | } 9 | 10 | export default class Draggable extends React.Component { 11 | props: Props; 12 | 13 | _handleDragStart = (e: SyntheticDragEvent) => { 14 | e.dataTransfer.setData('text', this.props.id); 15 | } 16 | 17 | render(): React.Element<*> { 18 | return React.cloneElement( 19 | React.Children.only(this.props.children), 20 | { 21 | draggable: 'true', 22 | onDragStart: this._handleDragStart, 23 | } 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/heapCapture/src/DropTarget.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from 'react'; 4 | 5 | type Props = { 6 | id: string, 7 | dropAction: (sourceId: string, thisId: string) => void, 8 | children?: any, 9 | } 10 | 11 | export default class DropTarget extends React.Component { 12 | props: Props; 13 | 14 | _handleDragOver = (e: SyntheticDragEvent) => { 15 | e.preventDefault(); 16 | } 17 | 18 | _handleDrop = (e: SyntheticDragEvent) => { 19 | const sourceId = e.dataTransfer.getData('text'); 20 | e.preventDefault(); 21 | this.props.dropAction(sourceId, this.props.id); 22 | } 23 | 24 | render(): React.Element<*> { 25 | return React.cloneElement( 26 | React.Children.only(this.props.children), 27 | { 28 | onDragOver: this._handleDragOver, 29 | onDrop: this._handleDrop, 30 | } 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/heapCapture/src/ExpanderConfiguration.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from 'react'; 4 | 5 | import AggrowExpander from './AggrowExpander'; 6 | import Draggable from './Draggable'; 7 | 8 | type Props = { 9 | expander: AggrowExpander; 10 | id: number; 11 | } 12 | 13 | export default function ExpanderConfiguration(props: Props): React.Element<*> { 14 | const expander = props.expander; 15 | const id = props.id; 16 | return ( 17 | 18 |
25 | {expander.getExpanderName(id)} 26 |
27 |
28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/heapCapture/src/StringInterner.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | type InternedStringsTable = { 4 | [key: string]: number, 5 | } 6 | 7 | export default class StringInterner { 8 | strings: Array = []; 9 | ids: InternedStringsTable = {}; 10 | 11 | intern(s: string): number { 12 | const find = this.ids[s]; 13 | if (find === undefined) { 14 | const id = this.strings.length; 15 | this.ids[s] = id; 16 | this.strings.push(s); 17 | return id; 18 | } 19 | 20 | return find; 21 | } 22 | 23 | get(id: number): string { 24 | return this.strings[id]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/heapCapture/src/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import Aggrow from './Aggrow'; 4 | import AggrowData from './AggrowData'; 5 | import type { AggrowColumnDef } from './AggrowData'; 6 | import AggrowExpander from './AggrowExpander'; 7 | import AggrowTable from './AggrowTable'; 8 | import StackRegistry from './StackRegistry'; 9 | import type { Stack } from './StackRegistry'; 10 | import StringInterner from './StringInterner'; 11 | 12 | export type { 13 | AggrowColumnDef, 14 | Stack, 15 | }; 16 | 17 | export { 18 | Aggrow, 19 | AggrowData, 20 | AggrowExpander, 21 | AggrowTable, 22 | StackRegistry, 23 | StringInterner, 24 | }; 25 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/heapCapture/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | 3 | module.exports = { 4 | devtool: 'inline-source-map', 5 | entry: './src/heapCapture.js', 6 | resolve: { 7 | extensions: ["", ".js", ".jsx"], 8 | }, 9 | module: { 10 | loaders: [ 11 | { 12 | test: /\.jsx?$/, 13 | include: /\/src\//, 14 | loader: 'babel-loader', 15 | query: { 16 | presets: [ 'react', 'es2015' ], 17 | plugins: [ 'transform-class-properties' ] 18 | }, 19 | }, 20 | ], 21 | }, 22 | plugins: [ 23 | new webpack.BannerPlugin('\n// @generated\n', { raw: true }), 24 | ], 25 | output: { 26 | path: './', 27 | filename: 'bundle.js', 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | React Native 5 | 6 | 7 |

React Native packager is running.

8 |

Visit documentation

9 | 10 | 11 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/indexPage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const fs = require('fs'); 12 | const path = require('path'); 13 | 14 | module.exports = function(req, res, next) { 15 | if (req.url === '/') { 16 | res.end(fs.readFileSync(path.join(__dirname, 'index.html'))); 17 | } else { 18 | next(); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/loadRawBodyMiddleware.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | module.exports = function(req, res, next) { 12 | req.rawBody = ''; 13 | req.setEncoding('utf8'); 14 | 15 | req.on('data', function(chunk) { 16 | req.rawBody += chunk; 17 | }); 18 | 19 | req.on('end', function() { 20 | next(); 21 | }); 22 | }; 23 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/openStackFrameInEditorMiddleware.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const launchEditor = require('../util/launchEditor'); 12 | 13 | module.exports = function({projectRoots}) { 14 | return function(req, res, next) { 15 | if (req.url === '/open-stack-frame') { 16 | const frame = JSON.parse(req.rawBody); 17 | launchEditor(frame.file, frame.lineNumber, projectRoots); 18 | res.end('OK'); 19 | } else { 20 | next(); 21 | } 22 | }; 23 | }; 24 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/statusPageMiddleware.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | /** 12 | * Status page so that anyone who needs to can verify that the packager is 13 | * running on 8081 and not another program / service. 14 | */ 15 | module.exports = function(req, res, next) { 16 | if (req.url === '/status') { 17 | res.end('packager-status:running'); 18 | } else { 19 | next(); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /react-native/local-cli/server/middleware/unless.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | module.exports = (url, middleware) => { 12 | return (req, res, next) => { 13 | if (req.url === url || req.url.startsWith(url + '/')) { 14 | middleware(req, res, next); 15 | } else { 16 | next(); 17 | } 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /react-native/local-cli/server/util/copyToClipBoard.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | var child_process = require('child_process'); 12 | var spawn = child_process.spawn; 13 | 14 | /** 15 | * Copy the content to host system clipboard. 16 | * This is only supported on Mac and Windows for now. 17 | */ 18 | function copyToClipBoard(content) { 19 | switch (process.platform) { 20 | case 'darwin': 21 | var child = spawn('pbcopy', []); 22 | child.stdin.end(new Buffer(content, 'utf8')); 23 | return true; 24 | case 'win32': 25 | var child = spawn('clip', []); 26 | child.stdin.end(new Buffer(content, 'utf8')); 27 | return true; 28 | default: 29 | return false; 30 | } 31 | } 32 | 33 | module.exports = copyToClipBoard; 34 | -------------------------------------------------------------------------------- /react-native/local-cli/server/util/launchChrome.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | const opn = require('opn'); 14 | 15 | function getChromeAppName(): string { 16 | switch (process.platform) { 17 | case 'darwin': 18 | return 'google chrome'; 19 | case 'win32': 20 | return 'chrome'; 21 | default: 22 | return 'google-chrome'; 23 | } 24 | } 25 | 26 | function launchChrome(url: string) { 27 | opn(url, {app: [getChromeAppName()]}, function(err) { 28 | if (err) { 29 | console.error('Google Chrome exited with error:', err); 30 | } 31 | }); 32 | } 33 | 34 | module.exports = launchChrome; 35 | -------------------------------------------------------------------------------- /react-native/local-cli/server/util/messageSocket.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | 12 | function attachToServer(server, path) { 13 | var WebSocketServer = require('ws').Server; 14 | var wss = new WebSocketServer({ 15 | server: server, 16 | path: path 17 | }); 18 | var clients = []; 19 | 20 | function sendFrom(source, data) { 21 | clients.forEach((client) => { 22 | if (client !== source) { 23 | try { 24 | client.send(data); 25 | } catch (e) { 26 | // Sometimes this call throws 'not opened' 27 | } 28 | } 29 | }); 30 | } 31 | 32 | wss.on('connection', function(ws) { 33 | clients.push(ws); 34 | ws.onclose = 35 | ws.onerror = () => { 36 | ws.onmessage = null; 37 | clients = clients.filter((client) => client !== ws); 38 | }; 39 | ws.onmessage = ({data}) => sendFrom(ws, data); 40 | }); 41 | 42 | return { 43 | broadcast: (message) => { 44 | sendFrom(null, JSON.stringify(message)); 45 | } 46 | }; 47 | } 48 | 49 | module.exports = { 50 | attachToServer: attachToServer 51 | }; 52 | -------------------------------------------------------------------------------- /react-native/local-cli/setup_env.bat: -------------------------------------------------------------------------------- 1 | :: Copyright (c) 2015-present, Facebook, Inc. 2 | :: All rights reserved. 3 | :: 4 | :: This source code is licensed under the BSD-style license found in the 5 | :: LICENSE file in the root directory of this source tree. An additional grant 6 | :: of patent rights can be found in the PATENTS file in the same directory. 7 | -------------------------------------------------------------------------------- /react-native/local-cli/setup_env.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-present, Facebook, Inc. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the BSD-style license found in the 5 | # LICENSE file in the root directory of this source tree. An additional grant 6 | # of patent rights can be found in the PATENTS file in the same directory. 7 | 8 | # 2048 is the max for non root users on Mac 9 | ulimit -n 2048 10 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloNavigation/components/ListItem.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React, { Component } from 'react'; 4 | import { 5 | Platform, 6 | StyleSheet, 7 | Text, 8 | TouchableHighlight, 9 | TouchableNativeFeedback, 10 | View, 11 | } from 'react-native'; 12 | 13 | /** 14 | * Renders the right type of Touchable for the list item, based on platform. 15 | */ 16 | const Touchable = ({onPress, children}) => { 17 | const child = React.Children.only(children); 18 | if (Platform.OS === 'android') { 19 | return ( 20 | 21 | {child} 22 | 23 | ); 24 | } else { 25 | return ( 26 | 27 | {child} 28 | 29 | ); 30 | } 31 | } 32 | 33 | const ListItem = ({label, onPress}) => ( 34 | 35 | 36 | {label} 37 | 38 | 39 | ); 40 | 41 | const styles = StyleSheet.create({ 42 | item: { 43 | height: 48, 44 | justifyContent: 'center', 45 | paddingLeft: 12, 46 | borderBottomWidth: StyleSheet.hairlineWidth, 47 | borderBottomColor: '#ddd', 48 | }, 49 | label: { 50 | fontSize: 16, 51 | } 52 | }); 53 | 54 | export default ListItem; 55 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloNavigation/dependencies.json: -------------------------------------------------------------------------------- 1 | { 2 | "react-navigation": "1.0.0-beta.1" 3 | } 4 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloNavigation/index.android.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | 3 | import MainNavigator from './views/MainNavigator'; 4 | 5 | AppRegistry.registerComponent('HelloWorld', () => MainNavigator); 6 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloNavigation/index.ios.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | 3 | import MainNavigator from './views/MainNavigator'; 4 | 5 | AppRegistry.registerComponent('HelloWorld', () => MainNavigator); 6 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloNavigation/views/HomeScreenTabNavigator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { TabNavigator } from 'react-navigation'; 4 | 5 | import ChatListScreen from './chat/ChatListScreen'; 6 | import WelcomeScreen from './welcome/WelcomeScreen'; 7 | 8 | /** 9 | * Screen with tabs shown on app startup. 10 | */ 11 | const HomeScreenTabNavigator = TabNavigator({ 12 | Welcome: { 13 | screen: WelcomeScreen, 14 | }, 15 | Chats: { 16 | screen: ChatListScreen, 17 | }, 18 | }); 19 | 20 | export default HomeScreenTabNavigator; 21 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloNavigation/views/MainNavigator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * This is an example React Native app demonstrates ListViews, text input and 5 | * navigation between a few screens. 6 | * https://github.com/facebook/react-native 7 | */ 8 | 9 | import React, { Component } from 'react'; 10 | import { StackNavigator } from 'react-navigation'; 11 | 12 | import HomeScreenTabNavigator from './HomeScreenTabNavigator'; 13 | import ChatScreen from './chat/ChatScreen'; 14 | 15 | /** 16 | * Top-level navigator. Renders the application UI. 17 | */ 18 | const MainNavigator = StackNavigator({ 19 | Home: { 20 | screen: HomeScreenTabNavigator, 21 | }, 22 | Chat: { 23 | screen: ChatScreen, 24 | }, 25 | }); 26 | 27 | export default MainNavigator; 28 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloNavigation/views/chat/chat-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-component/rn-packager/8fbf4066ff791bc18155fc929d76b6e51be40515/react-native/local-cli/templates/HelloNavigation/views/chat/chat-icon.png -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloNavigation/views/welcome/WelcomeScreen.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React, { Component } from 'react'; 4 | import { 5 | Image, 6 | Platform, 7 | StyleSheet, 8 | } from 'react-native'; 9 | 10 | import ListItem from '../../components/ListItem'; 11 | import WelcomeText from './WelcomeText'; 12 | 13 | export default class WelcomeScreen extends Component { 14 | 15 | static navigationOptions = { 16 | title: 'Welcome', 17 | header: { 18 | visible: Platform.OS === 'ios', 19 | }, 20 | tabBar: { 21 | icon: ({ tintColor }) => ( 22 | 27 | ), 28 | }, 29 | } 30 | 31 | render() { 32 | return ( 33 | 34 | ); 35 | } 36 | } 37 | 38 | const styles = StyleSheet.create({ 39 | icon: { 40 | width: 30, 41 | height: 26, 42 | }, 43 | }); 44 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloNavigation/views/welcome/WelcomeText.android.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React, { Component } from 'react'; 4 | import { 5 | StyleSheet, 6 | Text, 7 | View, 8 | } from 'react-native'; 9 | 10 | export default class WelcomeText extends Component { 11 | render() { 12 | return ( 13 | 14 | 15 | Welcome to React Native! 16 | 17 | 18 | This app shows the basics of navigating between a few screens, 19 | working with ListView and handling text input. 20 | 21 | 22 | Modify any files to get started. For example try changing the 23 | file views/welcome/WelcomeText.android.js. 24 | 25 | 26 | Double tap R on your keyboard to reload,{'\n'} 27 | Shake or press menu button for dev menu. 28 | 29 | 30 | ); 31 | } 32 | } 33 | 34 | const styles = StyleSheet.create({ 35 | container: { 36 | flex: 1, 37 | justifyContent: 'center', 38 | alignItems: 'center', 39 | backgroundColor: 'white', 40 | padding: 20, 41 | }, 42 | welcome: { 43 | fontSize: 20, 44 | textAlign: 'center', 45 | margin: 16, 46 | }, 47 | instructions: { 48 | textAlign: 'center', 49 | color: '#333333', 50 | marginBottom: 12, 51 | }, 52 | }); 53 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloNavigation/views/welcome/WelcomeText.ios.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React, { Component } from 'react'; 4 | import { 5 | StyleSheet, 6 | Text, 7 | View, 8 | } from 'react-native'; 9 | 10 | export default class WelcomeText extends Component { 11 | render() { 12 | return ( 13 | 14 | 15 | Welcome to React Native! 16 | 17 | 18 | This app shows the basics of navigating between a few screens, 19 | working with ListView and handling text input. 20 | 21 | 22 | Modify any files to get started. For example try changing the 23 | file{'\n'}views/welcome/WelcomeText.ios.js. 24 | 25 | 26 | Press Cmd+R to reload,{'\n'} 27 | Cmd+D or shake for dev menu. 28 | 29 | 30 | ); 31 | } 32 | } 33 | 34 | const styles = StyleSheet.create({ 35 | container: { 36 | flex: 1, 37 | justifyContent: 'center', 38 | alignItems: 'center', 39 | backgroundColor: 'white', 40 | padding: 20, 41 | }, 42 | welcome: { 43 | fontSize: 20, 44 | textAlign: 'center', 45 | margin: 16, 46 | }, 47 | instructions: { 48 | textAlign: 'center', 49 | color: '#333333', 50 | marginBottom: 12, 51 | }, 52 | }); 53 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloNavigation/views/welcome/welcome-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-component/rn-packager/8fbf4066ff791bc18155fc929d76b6e51be40515/react-native/local-cli/templates/HelloNavigation/views/welcome/welcome-icon.png -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/__tests__/index.android.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import Index from '../index.android.js'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | const tree = renderer.create( 10 | 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/__tests__/index.ios.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import Index from '../index.ios.js'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | const tree = renderer.create( 10 | 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/_babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/_buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/_gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/_gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 50 | 51 | fastlane/report.xml 52 | fastlane/Preview.html 53 | fastlane/screenshots 54 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/_watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/app/src/main/java/com/helloworld/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.helloworld; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "HelloWorld"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/app/src/main/java/com/helloworld/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.helloworld; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.ReactApplication; 6 | import com.facebook.react.ReactNativeHost; 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.shell.MainReactPackage; 9 | import com.facebook.soloader.SoLoader; 10 | 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | public class MainApplication extends Application implements ReactApplication { 15 | 16 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 17 | @Override 18 | public boolean getUseDeveloperSupport() { 19 | return BuildConfig.DEBUG; 20 | } 21 | 22 | @Override 23 | protected List getPackages() { 24 | return Arrays.asList( 25 | new MainReactPackage() 26 | ); 27 | } 28 | }; 29 | 30 | @Override 31 | public ReactNativeHost getReactNativeHost() { 32 | return mReactNativeHost; 33 | } 34 | 35 | @Override 36 | public void onCreate() { 37 | super.onCreate(); 38 | SoLoader.init(this, /* native exopackage */ false); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-component/rn-packager/8fbf4066ff791bc18155fc929d76b6e51be40515/react-native/local-cli/templates/HelloWorld/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-component/rn-packager/8fbf4066ff791bc18155fc929d76b6e51be40515/react-native/local-cli/templates/HelloWorld/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-component/rn-packager/8fbf4066ff791bc18155fc929d76b6e51be40515/react-native/local-cli/templates/HelloWorld/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-component/rn-packager/8fbf4066ff791bc18155fc929d76b6e51be40515/react-native/local-cli/templates/HelloWorld/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Hello App Display Name 3 | 4 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.2.3' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenLocal() 18 | jcenter() 19 | maven { 20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 21 | url "$rootDir/../node_modules/react-native/android" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-component/rn-packager/8fbf4066ff791bc18155fc929d76b6e51be40515/react-native/local-cli/templates/HelloWorld/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 6 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = 'debug', 3 | store = 'debug.keystore', 4 | properties = 'debug.keystore.properties', 5 | visibility = [ 6 | 'PUBLIC', 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'HelloWorld' 2 | 3 | include ':app' 4 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HelloWorld", 3 | "displayName": "HelloWorld" 4 | } -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/index.android.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View 13 | } from 'react-native'; 14 | 15 | export default class HelloWorld extends Component { 16 | render() { 17 | return ( 18 | 19 | 20 | Welcome to React Native! 21 | 22 | 23 | To get started, edit index.android.js 24 | 25 | 26 | Double tap R on your keyboard to reload,{'\n'} 27 | Shake or press menu button for dev menu 28 | 29 | 30 | ); 31 | } 32 | } 33 | 34 | const styles = StyleSheet.create({ 35 | container: { 36 | flex: 1, 37 | justifyContent: 'center', 38 | alignItems: 'center', 39 | backgroundColor: '#F5FCFF', 40 | }, 41 | welcome: { 42 | fontSize: 20, 43 | textAlign: 'center', 44 | margin: 10, 45 | }, 46 | instructions: { 47 | textAlign: 'center', 48 | color: '#333333', 49 | marginBottom: 5, 50 | }, 51 | }); 52 | 53 | AppRegistry.registerComponent('HelloWorld', () => HelloWorld); 54 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/index.ios.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View 13 | } from 'react-native'; 14 | 15 | export default class HelloWorld extends Component { 16 | render() { 17 | return ( 18 | 19 | 20 | Welcome to React Native! 21 | 22 | 23 | To get started, edit index.ios.js 24 | 25 | 26 | Press Cmd+R to reload,{'\n'} 27 | Cmd+D or shake for dev menu 28 | 29 | 30 | ); 31 | } 32 | } 33 | 34 | const styles = StyleSheet.create({ 35 | container: { 36 | flex: 1, 37 | justifyContent: 'center', 38 | alignItems: 'center', 39 | backgroundColor: '#F5FCFF', 40 | }, 41 | welcome: { 42 | fontSize: 20, 43 | textAlign: 'center', 44 | margin: 10, 45 | }, 46 | instructions: { 47 | textAlign: 'center', 48 | color: '#333333', 49 | marginBottom: 5, 50 | }, 51 | }); 52 | 53 | AppRegistry.registerComponent('HelloWorld', () => HelloWorld); 54 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/ios/HelloWorld-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/ios/HelloWorld/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/ios/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/ios/HelloWorld/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /react-native/local-cli/templates/HelloWorld/ios/HelloWorldTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /react-native/local-cli/util/__mocks__/log.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | module.exports.out = () => jest.genMockFn(); 12 | module.exports.err = () => jest.genMockFn(); 13 | -------------------------------------------------------------------------------- /react-native/local-cli/util/assertRequiredOptions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const { Option } = require('commander'); 12 | const { camelCase } = require('lodash'); 13 | 14 | // Commander.js has a 2 years old open issue to support <...> syntax 15 | // for options. Until that gets merged, we run the checks manually 16 | // https://github.com/tj/commander.js/issues/230 17 | module.exports = function assertRequiredOptions(options, passedOptions) { 18 | options.forEach(opt => { 19 | const option = new Option(opt.command); 20 | 21 | if (!option.required) { 22 | return; 23 | } 24 | 25 | const name = camelCase(option.long); 26 | 27 | if (!passedOptions[name]) { 28 | // Provide commander.js like error message 29 | throw new Error(`error: option '${option.long}' missing`); 30 | } 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /react-native/local-cli/util/isPackagerRunning.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const fetch = require('node-fetch'); 12 | 13 | /** 14 | * Indicates whether or not the packager is running. It returns a promise that 15 | * when fulfilled can returns one out of these possible values: 16 | * - `running`: the packager is running 17 | * - `not_running`: the packager nor any process is running on the expected 18 | * port. 19 | * - `unrecognized`: one other process is running on the port we expect the 20 | * packager to be running. 21 | */ 22 | function isPackagerRunning() { 23 | return fetch('http://localhost:8081/status').then( 24 | res => res.text().then(body => 25 | body === 'packager-status:running' ? 'running' : 'unrecognized' 26 | ), 27 | () => 'not_running' 28 | ); 29 | } 30 | 31 | module.exports = isPackagerRunning; 32 | -------------------------------------------------------------------------------- /react-native/local-cli/util/isValidPackageName.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | function isValidPackageName(name) { 12 | return name.match(/^[$A-Z_][0-9A-Z_$]*$/i); 13 | } 14 | 15 | module.exports = isValidPackageName; 16 | -------------------------------------------------------------------------------- /react-native/local-cli/util/log.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | var _enabled = true; 12 | 13 | function disable() { 14 | _enabled = false; 15 | } 16 | 17 | function log(stream, module) { 18 | return function() { 19 | if (!_enabled) { 20 | return; 21 | } 22 | const message = Array.prototype.slice.call(arguments).join(' '); 23 | stream.write(module + ': ' + message + '\n'); 24 | }; 25 | } 26 | 27 | module.exports.out = log.bind(null, process.stdout); 28 | module.exports.err = log.bind(null, process.stderr); 29 | module.exports.disable = disable; 30 | -------------------------------------------------------------------------------- /react-native/local-cli/util/walk.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const fs = require('fs'); 12 | const path = require('path'); 13 | 14 | function walk(current) { 15 | if (!fs.lstatSync(current).isDirectory()) { 16 | return [current]; 17 | } 18 | 19 | const files = fs.readdirSync(current).map(child => { 20 | child = path.join(current, child); 21 | return walk(child); 22 | }); 23 | return [].concat.apply([current], files); 24 | } 25 | 26 | module.exports = walk; 27 | -------------------------------------------------------------------------------- /react-native/local-cli/wrong-react-native.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Copyright (c) 2015-present, Facebook, Inc. 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. An additional grant 9 | * of patent rights can be found in the PATENTS file in the same directory. 10 | */ 11 | 12 | var script = process.argv[1]; 13 | var installedGlobally = script.indexOf('node_modules/.bin/react-native') === -1; 14 | 15 | if (installedGlobally) { 16 | console.error([ 17 | '\033[31mLooks like you installed react-native globally, maybe you meant react-native-cli?', 18 | 'To fix the issue, run:\033[0m', 19 | 'npm uninstall -g react-native', 20 | 'npm install -g react-native-cli' 21 | ].join('\n')); 22 | process.exit(1); 23 | } else { 24 | require('./cli').run(); 25 | } 26 | -------------------------------------------------------------------------------- /react-native/packager/babelRegisterOnly.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | Array.prototype.values || require('core-js/fn/array/values'); 12 | Object.entries || require('core-js/fn/object/entries'); 13 | Object.values || require('core-js/fn/object/values'); 14 | 15 | var _only = []; 16 | 17 | function registerOnly(onlyList) { 18 | require('babel-register')(config(onlyList)); 19 | } 20 | 21 | function config(onlyList) { 22 | _only = _only.concat(onlyList); 23 | return { 24 | presets: ['es2015-node'], 25 | plugins: [ 26 | 'transform-flow-strip-types', 27 | 'syntax-trailing-function-commas', 28 | 'transform-object-rest-spread', 29 | ], 30 | only: _only, 31 | retainLines: true, 32 | sourceMaps: 'inline', 33 | babelrc: false, 34 | }; 35 | } 36 | 37 | module.exports = exports = registerOnly; 38 | exports.config = config; 39 | -------------------------------------------------------------------------------- /react-native/packager/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 12 | 'use strict'; 13 | 14 | require('../setupBabel')(); 15 | module.exports = require('./react-packager'); 16 | -------------------------------------------------------------------------------- /react-native/packager/launchPackager.bat: -------------------------------------------------------------------------------- 1 | :: Copyright (c) 2015-present, Facebook, Inc. 2 | :: All rights reserved. 3 | :: 4 | :: This source code is licensed under the BSD-style license found in the 5 | :: LICENSE file in the root directory of this source tree. An additional grant 6 | :: of patent rights can be found in the PATENTS file in the same directory. 7 | 8 | @echo off 9 | title React Packager 10 | node "%~dp0..\local-cli\cli.js" start 11 | pause 12 | exit 13 | -------------------------------------------------------------------------------- /react-native/packager/launchPackager.command: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright (c) 2015-present, Facebook, Inc. 4 | # All rights reserved. 5 | # 6 | # This source code is licensed under the BSD-style license found in the 7 | # LICENSE file in the root directory of this source tree. An additional grant 8 | # of patent rights can be found in the PATENTS file in the same directory. 9 | 10 | # Set terminal title 11 | echo -en "\033]0;React Packager\a" 12 | clear 13 | 14 | THIS_DIR=$(dirname "$0") 15 | pushd "$THIS_DIR" 16 | source ./packager.sh 17 | popd 18 | 19 | echo "Process terminated. Press to close the window" 20 | read 21 | -------------------------------------------------------------------------------- /react-native/packager/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.5.0", 3 | "name": "react-native-packager", 4 | "description": "Build native apps with React!", 5 | "repository": { 6 | "type": "git", 7 | "url": "git@github.com:facebook/react-native.git" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /react-native/packager/packager.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright (c) 2015-present, Facebook, Inc. 4 | # All rights reserved. 5 | # 6 | # This source code is licensed under the BSD-style license found in the 7 | # LICENSE file in the root directory of this source tree. An additional grant 8 | # of patent rights can be found in the PATENTS file in the same directory. 9 | 10 | THIS_DIR=$(dirname "$0") 11 | node "$THIS_DIR/../local-cli/cli.js" start "$@" 12 | -------------------------------------------------------------------------------- /react-native/packager/rn-babelrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ "react-native" ], 3 | "plugins": [] 4 | } 5 | -------------------------------------------------------------------------------- /react-native/packager/rn-cli.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * React Native CLI configuration file 10 | */ 11 | 'use strict'; 12 | 13 | const blacklist = require('./blacklist'); 14 | const path = require('path'); 15 | 16 | module.exports = { 17 | getProjectRoots() { 18 | return this._getRoots(); 19 | }, 20 | 21 | getAssetExts() { 22 | return []; 23 | }, 24 | 25 | getBlacklistRE() { 26 | return blacklist(); 27 | }, 28 | 29 | _getRoots() { 30 | // match on either path separator 31 | if (__dirname.match(/node_modules[\/\\]react-native[\/\\]packager$/)) { 32 | // packager is running from node_modules of another project 33 | return [path.resolve(__dirname, '../../..')]; 34 | } else if (__dirname.match(/Pods\/React\/packager$/)) { 35 | // packager is running from node_modules of another project 36 | return [path.resolve(__dirname, '../../..')]; 37 | } else { 38 | return [path.resolve(__dirname, '..')]; 39 | } 40 | }, 41 | 42 | getTransformModulePath() { 43 | return require.resolve('./transformer'); 44 | }, 45 | 46 | }; 47 | -------------------------------------------------------------------------------- /react-native/packager/src/Bundler/source-map/package.json: -------------------------------------------------------------------------------- 1 | {"main": "source-map.js"} 2 | -------------------------------------------------------------------------------- /react-native/packager/src/Cache/__mocks__/Cache.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const mockColor = () => { 12 | return { 13 | bold: () => { return { }; }, 14 | }; 15 | }; 16 | 17 | mockColor.bold = function() { 18 | return {}; 19 | }; 20 | 21 | module.exports = { 22 | dim: s => s, 23 | magenta: mockColor, 24 | white: mockColor, 25 | blue: mockColor, 26 | yellow: mockColor, 27 | green: mockColor, 28 | bold: mockColor, 29 | red: mockColor, 30 | cyan: mockColor, 31 | gray: mockColor, 32 | black: mockColor, 33 | }; 34 | -------------------------------------------------------------------------------- /react-native/packager/src/JSTransformer/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-component/rn-packager/8fbf4066ff791bc18155fc929d76b6e51be40515/react-native/packager/src/JSTransformer/README.md -------------------------------------------------------------------------------- /react-native/packager/src/JSTransformer/__mocks__/lodash.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | // Bug with Jest because we're going to the node_modules that is a sibling 12 | // of what jest thinks our root (the dir with the package.json) should be. 13 | module.exports = require.requireActual('lodash'); 14 | -------------------------------------------------------------------------------- /react-native/packager/src/JSTransformer/__mocks__/q.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | // Bug with Jest because we're going to the node_modules that is a sibling 12 | // of what jest thinks our root (the dir with the package.json) should be. 13 | 14 | module.exports = require.requireActual('q'); 15 | -------------------------------------------------------------------------------- /react-native/packager/src/JSTransformer/__mocks__/worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | module.exports = function (data, callback) { 12 | callback(null, {}); 13 | }; 14 | -------------------------------------------------------------------------------- /react-native/packager/src/JSTransformer/worker/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | 'use strict'; 11 | 12 | require('../../../../setupBabel')(); 13 | module.exports = require('./worker'); 14 | -------------------------------------------------------------------------------- /react-native/packager/src/JSTransformer/worker/minify.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 12 | 'use strict'; 13 | 14 | const uglify = require('uglify-js'); 15 | 16 | function minify(filename: string, code: string, sourceMap: ?string) { 17 | const minifyResult = uglify.minify(code, { 18 | fromString: true, 19 | inSourceMap: sourceMap, 20 | outSourceMap: true, 21 | output: { 22 | ascii_only: true, 23 | screw_ie8: true, 24 | }, 25 | }); 26 | 27 | minifyResult.map = JSON.parse(minifyResult.map); 28 | minifyResult.map.sources = [filename]; 29 | return minifyResult; 30 | } 31 | 32 | module.exports = minify; 33 | -------------------------------------------------------------------------------- /react-native/packager/src/Logger/Types.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | * 11 | */ 12 | 'use strict'; 13 | 14 | export type ActionLogEntryData = { 15 | action_name: string, 16 | }; 17 | 18 | export type ActionStartLogEntry = { 19 | action_name?: string, 20 | action_phase?: string, 21 | log_entry_label: string, 22 | log_session?: string, 23 | start_timestamp?: [number, number], 24 | }; 25 | 26 | export type LogEntry = { 27 | action_name?: string, 28 | action_phase?: string, 29 | duration_ms?: number, 30 | log_entry_label: string, 31 | log_session?: string, 32 | start_timestamp?: [number, number], 33 | }; 34 | -------------------------------------------------------------------------------- /react-native/packager/src/Logger/__mocks__/chalk.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const mockColor = () => { 12 | return { 13 | bold: () => { return { }; }, 14 | }; 15 | }; 16 | 17 | mockColor.bold = function() { 18 | return {}; 19 | }; 20 | 21 | mockColor.bgRed = function() { 22 | return {}; 23 | }; 24 | 25 | module.exports = { 26 | dim: s => s, 27 | magenta: mockColor, 28 | white: mockColor, 29 | blue: mockColor, 30 | yellow: mockColor, 31 | green: mockColor, 32 | bold: mockColor, 33 | red: mockColor, 34 | cyan: mockColor, 35 | gray: mockColor, 36 | black: mockColor, 37 | }; 38 | -------------------------------------------------------------------------------- /react-native/packager/src/ModuleGraph/node-haste/Module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 12 | 'use strict'; 13 | 14 | import type {TransformedFile} from '../types.flow'; 15 | import type {ModuleCache} from './node-haste.flow'; 16 | 17 | module.exports = class Module { 18 | hasteID: Promise; 19 | moduleCache: ModuleCache; 20 | name: Promise; 21 | path: string; 22 | type: 'Module'; 23 | 24 | constructor( 25 | path: string, 26 | moduleCache: ModuleCache, 27 | info: Promise, 28 | ) { 29 | this.hasteID = info.then(({hasteID}) => hasteID); 30 | this.moduleCache = moduleCache; 31 | this.name = this.hasteID.then(name => name || getName(path)); 32 | this.path = path; 33 | this.type = 'Module'; 34 | } 35 | 36 | getName() { 37 | return this.name; 38 | } 39 | 40 | getPackage() { 41 | return this.moduleCache.getPackageOf(this.path); 42 | } 43 | 44 | isHaste() { 45 | return this.hasteID.then(Boolean); 46 | } 47 | }; 48 | 49 | function getName(path) { 50 | return path.replace(/^.*[\/\\]node_modules[\///]/, ''); 51 | } 52 | -------------------------------------------------------------------------------- /react-native/packager/src/ModuleGraph/node-haste/package.json: -------------------------------------------------------------------------------- 1 | {"main":"node-haste.js"} 2 | -------------------------------------------------------------------------------- /react-native/packager/src/ModuleGraph/output/as-plain-bundle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | const {createIndexMap} = require('./source-map'); 14 | const {addModuleIdsToModuleWrapper} = require('./util'); 15 | 16 | import type {OutputFn} from '../types.flow'; 17 | 18 | module.exports = ( 19 | (modules, filename, idForPath) => { 20 | let code = ''; 21 | let line = 0; 22 | const sections = []; 23 | 24 | for (const module of modules) { 25 | const {file} = module; 26 | const moduleCode = file.type === 'module' 27 | ? addModuleIdsToModuleWrapper(module, idForPath) 28 | : file.code; 29 | 30 | code += moduleCode + '\n'; 31 | if (file.map) { 32 | sections.push({ 33 | map: file.map, 34 | offset: {column: 0, line} 35 | }); 36 | } 37 | line += countLines(moduleCode); 38 | } 39 | 40 | return {code, map: createIndexMap({file: filename, sections})}; 41 | }: OutputFn); 42 | 43 | const reLine = /^/gm; 44 | function countLines(string: string): number { 45 | //$FlowFixMe This regular expression always matches 46 | return string.match(reLine).length; 47 | } 48 | -------------------------------------------------------------------------------- /react-native/packager/src/ModuleGraph/output/source-map.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | type CreateIndexMapOptions = {| 14 | file?: string, 15 | sections?: Array 16 | |}; 17 | 18 | type IndexMap = MapBase & { 19 | sections: Array, 20 | }; 21 | 22 | type IndexMapSection = { 23 | map: IndexMap | MappingsMap, 24 | offset: {line: number, column: number}, 25 | }; 26 | 27 | type MapBase = { 28 | // always the first entry in the source map entry object per 29 | // https://fburl.com/source-map-spec#heading=h.qz3o9nc69um5 30 | version: 3, 31 | file?: string, 32 | }; 33 | 34 | type MappingsMap = MapBase & { 35 | mappings: string, 36 | names: Array, 37 | sourceRoot?: string, 38 | sources: Array, 39 | sourcesContent?: Array, 40 | }; 41 | 42 | export type SourceMap = IndexMap | MappingsMap; 43 | 44 | exports.createIndexMap = (opts?: CreateIndexMapOptions): IndexMap => ({ 45 | version: 3, 46 | file: opts && opts.file, 47 | sections: opts && opts.sections || [], 48 | }); 49 | -------------------------------------------------------------------------------- /react-native/packager/src/ModuleGraph/package.json: -------------------------------------------------------------------------------- 1 | {"main": "ModuleGraph.js"} 2 | -------------------------------------------------------------------------------- /react-native/packager/src/ModuleGraph/silent-console.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const {Console} = require('console'); 12 | const {Writable} = require('stream'); 13 | 14 | const write = (_, __, callback) => callback(); 15 | module.exports = new Console(new Writable({write, writev: write})); 16 | -------------------------------------------------------------------------------- /react-native/packager/src/ModuleGraph/test-helpers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const generate = require('babel-generator').default; 12 | const stub = require('sinon/lib/sinon/stub'); 13 | 14 | exports.fn = () => { 15 | const s = stub(); 16 | const f = jest.fn(s); 17 | f.stub = s; 18 | return f; 19 | }; 20 | 21 | const generateOptions = {concise: true}; 22 | exports.codeFromAst = ast => generate(ast, generateOptions).code; 23 | exports.comparableCode = code => code.trim().replace(/\s\s+/g, ' '); 24 | -------------------------------------------------------------------------------- /react-native/packager/src/ModuleGraph/worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | const asyncify = require('async/asyncify'); 14 | const optimizeModule = require('./worker/optimize-module'); 15 | const transformModule = require('./worker/transform-module'); 16 | const wrapWorkerFn = require('./worker/wrap-worker-fn'); 17 | 18 | import type {OptimizationOptions} from './worker/optimize-module'; 19 | import type {TransformOptions} from './worker/transform-module'; 20 | import type {WorkerFnWithIO} from './worker/wrap-worker-fn'; 21 | 22 | exports.optimizeModule = 23 | (wrapWorkerFn(asyncify(optimizeModule)): WorkerFnWithIO); 24 | exports.transformModule = 25 | (wrapWorkerFn(transformModule): WorkerFnWithIO); 26 | -------------------------------------------------------------------------------- /react-native/packager/src/ModuleGraph/worker/generate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 'use strict'; 12 | 13 | const babelGenerate = require('babel-generator').default; 14 | 15 | function generate(ast: Object, filename: string, sourceCode: string) { 16 | return babelGenerate(ast, { 17 | comments: false, 18 | compact: true, 19 | filename, 20 | sourceFileName: filename, 21 | sourceMaps: true, 22 | sourceMapTarget: filename, 23 | }, sourceCode); 24 | } 25 | 26 | module.exports = generate; 27 | -------------------------------------------------------------------------------- /react-native/packager/src/Resolver/polyfills/Number.es6.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @provides Number.es6 10 | * @polyfill 11 | */ 12 | 13 | /* eslint-disable strict */ 14 | 15 | if (Number.EPSILON === undefined) { 16 | Object.defineProperty(Number, 'EPSILON', { 17 | value: Math.pow(2, -52), 18 | }); 19 | } 20 | if (Number.MAX_SAFE_INTEGER === undefined) { 21 | Object.defineProperty(Number, 'MAX_SAFE_INTEGER', { 22 | value: Math.pow(2, 53) - 1, 23 | }); 24 | } 25 | if (Number.MIN_SAFE_INTEGER === undefined) { 26 | Object.defineProperty(Number, 'MIN_SAFE_INTEGER', { 27 | value: -(Math.pow(2, 53) - 1), 28 | }); 29 | } 30 | if (!Number.isNaN) { 31 | // https://github.com/dherman/tc39-codex-wiki/blob/master/data/es6/number/index.md#polyfill-for-numberisnan 32 | const globalIsNaN = global.isNaN; 33 | Object.defineProperty(Number, 'isNaN', { 34 | configurable: true, 35 | enumerable: false, 36 | value: function isNaN(value) { 37 | return typeof value === 'number' && globalIsNaN(value); 38 | }, 39 | writable: true, 40 | }); 41 | } 42 | -------------------------------------------------------------------------------- /react-native/packager/src/Resolver/polyfills/prelude.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @polyfill 10 | */ 11 | 12 | /* eslint-disable strict */ 13 | 14 | global.__DEV__ = false; 15 | 16 | global.__BUNDLE_START_TIME__ = Date.now(); 17 | -------------------------------------------------------------------------------- /react-native/packager/src/Resolver/polyfills/prelude_dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @polyfill 10 | */ 11 | 12 | /* eslint-disable strict */ 13 | 14 | global.__DEV__ = true; 15 | 16 | global.__BUNDLE_START_TIME__ = Date.now(); 17 | -------------------------------------------------------------------------------- /react-native/packager/src/__mocks__/debug.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | module.exports = () => () => {}; 12 | -------------------------------------------------------------------------------- /react-native/packager/src/lib/JsonReporter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 12 | 'use strict'; 13 | 14 | import {Writable} from 'stream'; 15 | 16 | class JsonReporter { 17 | 18 | _stream: Writable; 19 | 20 | constructor(stream: Writable) { 21 | this._stream = stream; 22 | } 23 | 24 | update(event: TEvent) { 25 | this._stream.write(JSON.stringify(event) + '\n'); 26 | } 27 | 28 | } 29 | 30 | module.exports = JsonReporter; 31 | -------------------------------------------------------------------------------- /react-native/packager/src/lib/SourceMap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 12 | 'use strict'; 13 | 14 | import type {SourceMap as BabelSourceMap} from 'babel-core'; 15 | 16 | export type SourceMap = BabelSourceMap; 17 | 18 | export type CombinedSourceMap = { 19 | version: number, 20 | file?: string, 21 | sections: Array<{ 22 | offset: {line: number, column: number}, 23 | map: MixedSourceMap, 24 | }>, 25 | }; 26 | 27 | type FBExtensions = {x_facebook_offsets?: Array}; 28 | 29 | export type MixedSourceMap 30 | = SourceMap 31 | | CombinedSourceMap 32 | | (SourceMap & FBExtensions) 33 | | (CombinedSourceMap & FBExtensions); 34 | -------------------------------------------------------------------------------- /react-native/packager/src/lib/__mocks__/BatchProcessor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | 'use strict'; 11 | 12 | const {EventEmitter} = require('events'); 13 | 14 | class BatchProcessorMock { 15 | 16 | constructor(_, processBatch) { 17 | this._processBatch = processBatch; 18 | this._queue = []; 19 | BatchProcessorMock.mocks.emit('new', this); 20 | } 21 | 22 | queue(item, callback) { 23 | this._queue.push([item, callback]); 24 | } 25 | 26 | flushMock() { 27 | const {_queue} = this; 28 | this._queue = []; 29 | process.nextTick(() => { 30 | this._processBatch(_queue.map(pair => pair[0]), (error, res) => { 31 | _queue.forEach((pair, i) => pair[1](error, res && res[i])); 32 | }); 33 | }); 34 | } 35 | 36 | } 37 | 38 | BatchProcessorMock.mocks = new EventEmitter(); 39 | 40 | module.exports = BatchProcessorMock; 41 | -------------------------------------------------------------------------------- /react-native/packager/src/lib/__mocks__/GlobalTransformCache.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 12 | 'use strict'; 13 | 14 | function get() { 15 | return null; 16 | } 17 | 18 | module.exports = {get}; 19 | -------------------------------------------------------------------------------- /react-native/packager/src/lib/__mocks__/TransformCache.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | 'use strict'; 11 | 12 | const imurmurhash = require('imurmurhash'); 13 | const jsonStableStringify = require('json-stable-stringify'); 14 | 15 | const transformCache = new Map(); 16 | 17 | const mock = { 18 | lastWrite: null, 19 | reset() { 20 | transformCache.clear(); 21 | mock.lastWrite = null; 22 | }, 23 | }; 24 | 25 | const transformCacheKeyOf = (props) => 26 | props.filePath + '-' + imurmurhash(props.sourceCode) 27 | .hash(props.transformCacheKey) 28 | .hash(jsonStableStringify(props.transformOptions || {})) 29 | .result().toString(16); 30 | 31 | function writeSync(props) { 32 | transformCache.set(transformCacheKeyOf(props), props.result); 33 | mock.lastWrite = props; 34 | } 35 | 36 | function readSync(props) { 37 | return transformCache.get(transformCacheKeyOf(props)); 38 | } 39 | 40 | module.exports = { 41 | writeSync, 42 | readSync, 43 | mock, 44 | }; 45 | -------------------------------------------------------------------------------- /react-native/packager/src/lib/__mocks__/declareOpts.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | module.exports = function(declared) { 12 | return function(opts) { 13 | for (var p in declared) { 14 | if (opts[p] == null && declared[p].default != null){ 15 | opts[p] = declared[p].default; 16 | } 17 | } 18 | return opts; 19 | }; 20 | }; 21 | -------------------------------------------------------------------------------- /react-native/packager/src/lib/relativizeSourceMap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 12 | 'use strict'; 13 | 14 | const path = require('path'); 15 | 16 | import type { MixedSourceMap } from './SourceMap'; 17 | 18 | function relativizeSourceMapInternal(sourceMap: any, sourcesRoot: string) { 19 | if (sourceMap.sections) { 20 | for (var i = 0; i < sourceMap.sections.length; i++) { 21 | relativizeSourceMapInternal(sourceMap.sections[i].map, sourcesRoot); 22 | } 23 | } else { 24 | for (var i = 0; i < sourceMap.sources.length; i++) { 25 | sourceMap.sources[i] = path.relative(sourcesRoot, sourceMap.sources[i]); 26 | } 27 | } 28 | } 29 | 30 | function relativizeSourceMap(sourceMap: MixedSourceMap, sourcesRoot?: string): MixedSourceMap { 31 | if (!sourcesRoot) { 32 | return sourceMap; 33 | } 34 | relativizeSourceMapInternal(sourceMap, sourcesRoot); 35 | return sourceMap; 36 | } 37 | 38 | module.exports = relativizeSourceMap; 39 | -------------------------------------------------------------------------------- /react-native/packager/src/lib/toFixedHex.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 12 | 'use strict'; 13 | 14 | const leftPad = require('left-pad'); 15 | 16 | function toFixedHex(length: number, number: number): string { 17 | return leftPad(number.toString(16), length, '0'); 18 | } 19 | 20 | module.exports = toFixedHex; 21 | -------------------------------------------------------------------------------- /react-native/packager/src/node-haste/Cache/__mocks__/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | class Cache { 12 | get(filepath, field, cb) { 13 | return cb(filepath); 14 | } 15 | 16 | invalidate(filepath) { } 17 | end() { } 18 | } 19 | 20 | module.exports = Cache; 21 | -------------------------------------------------------------------------------- /react-native/packager/src/node-haste/DependencyGraph/assets/empty-module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | -------------------------------------------------------------------------------- /react-native/packager/src/node-haste/Polyfill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 12 | 'use strict'; 13 | 14 | const Module = require('./Module'); 15 | 16 | import type {ConstructorArgs} from './Module'; 17 | 18 | class Polyfill extends Module { 19 | 20 | _id: string; 21 | _dependencies: Array; 22 | 23 | constructor(options: ConstructorArgs & { 24 | id: string, 25 | dependencies: Array, 26 | }) { 27 | super(options); 28 | this._id = options.id; 29 | this._dependencies = options.dependencies; 30 | } 31 | 32 | isHaste() { 33 | return Promise.resolve(false); 34 | } 35 | 36 | getName() { 37 | return Promise.resolve(this._id); 38 | } 39 | 40 | getPackage() { 41 | return null; 42 | } 43 | 44 | getDependencies() { 45 | return Promise.resolve(this._dependencies); 46 | } 47 | 48 | isJSON() { 49 | return false; 50 | } 51 | 52 | isPolyfill() { 53 | return true; 54 | } 55 | } 56 | 57 | module.exports = Polyfill; 58 | -------------------------------------------------------------------------------- /react-native/packager/src/node-haste/__mocks__/fs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | module.exports = require('graceful-fs'); 12 | -------------------------------------------------------------------------------- /react-native/packager/src/node-haste/__tests__/AssetModule-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | jest.autoMockOff(); 12 | 13 | const AssetModule = require('../AssetModule'); 14 | 15 | describe('AssetModule:', () => { 16 | const defaults = {file: '/arbitrary'}; 17 | 18 | it('has no dependencies by default', () => { 19 | return new AssetModule(defaults).getDependencies() 20 | .then(deps => expect(deps).toEqual([])); 21 | }); 22 | 23 | it('can be parametrized with dependencies', () => { 24 | const dependencies = ['arbitrary', 'dependencies']; 25 | return new AssetModule({...defaults, dependencies}).getDependencies() 26 | .then(deps => expect(deps).toEqual(dependencies)); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /react-native/packager/src/node-haste/lib/AsyncTaskGroup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | module.exports = class AsyncTaskGroup { 12 | constructor() { 13 | this._runningTasks = new Set(); 14 | this._resolve = null; 15 | this.done = new Promise(resolve => this._resolve = resolve); 16 | } 17 | 18 | start(taskHandle) { 19 | this._runningTasks.add(taskHandle); 20 | } 21 | 22 | end(taskHandle) { 23 | const runningTasks = this._runningTasks; 24 | if (runningTasks.delete(taskHandle) && runningTasks.size === 0) { 25 | this._resolve(); 26 | } 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /react-native/packager/src/node-haste/lib/MapWithDefaults.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | module.exports = function MapWithDefaults(factory, iterable) { 12 | // This can't be `MapWithDefaults extends Map`, b/c the way babel transforms 13 | // super calls in constructors: Map.call(this, iterable) throws for native 14 | // Map objects in node 4+. 15 | // TODO(davidaurelio) switch to a transform that does not transform classes 16 | // and super calls, and change this into a class 17 | 18 | const map = iterable ? new Map(iterable) : new Map(); 19 | const {get} = map; 20 | map.get = key => { 21 | if (map.has(key)) { 22 | return get.call(map, key); 23 | } 24 | 25 | const value = factory(key); 26 | map.set(key, value); 27 | return value; 28 | }; 29 | return map; 30 | }; 31 | -------------------------------------------------------------------------------- /react-native/packager/src/node-haste/lib/getInverseDependencies.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | function resolveModuleRequires(resolutionResponse, module) { 12 | const pairs = resolutionResponse.getResolvedDependencyPairs(module); 13 | return pairs 14 | ? pairs.map(([, dependencyModule]) => dependencyModule) 15 | : []; 16 | } 17 | 18 | function getModuleDependents(cache, module) { 19 | let dependents = cache.get(module); 20 | if (!dependents) { 21 | dependents = new Set(); 22 | cache.set(module, dependents); 23 | } 24 | return dependents; 25 | } 26 | 27 | /** 28 | * Returns an object that indicates in which module each module is required. 29 | */ 30 | function getInverseDependencies(resolutionResponse) { 31 | const cache = new Map(); 32 | 33 | resolutionResponse.dependencies.forEach(module => { 34 | resolveModuleRequires(resolutionResponse, module).forEach(dependency => { 35 | getModuleDependents(cache, dependency).add(module); 36 | }); 37 | }); 38 | 39 | return cache; 40 | } 41 | 42 | module.exports = getInverseDependencies; 43 | -------------------------------------------------------------------------------- /react-native/packager/src/node-haste/lib/getPlatformExtension.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 'use strict'; 10 | 11 | const SUPPORTED_PLATFORM_EXTS = new Set([ 12 | 'android', 13 | 'ios', 14 | 'web', 15 | ]); 16 | 17 | // Extract platform extension: index.ios.js -> ios 18 | function getPlatformExtension(file, platforms = SUPPORTED_PLATFORM_EXTS) { 19 | const last = file.lastIndexOf('.'); 20 | const secondToLast = file.lastIndexOf('.', last - 1); 21 | if (secondToLast === -1) { 22 | return null; 23 | } 24 | const platform = file.substring(secondToLast + 1, last); 25 | return platforms.has(platform) ? platform : null; 26 | } 27 | 28 | module.exports = getPlatformExtension; 29 | -------------------------------------------------------------------------------- /react-native/packager/src/node-haste/lib/replacePatterns.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | 'use strict'; 11 | 12 | exports.IMPORT_RE = /(\bimport\s+(?:[^'"]+\s+from\s+)??)(['"])([^'"]+)(\2)/g; 13 | exports.EXPORT_RE = /(\bexport\s+(?:[^'"]+\s+from\s+)??)(['"])([^'"]+)(\2)/g; 14 | exports.REQUIRE_RE = /(\brequire\s*?\(\s*?)(['"`])([^'"`]+)(\2\s*?\))/g; 15 | -------------------------------------------------------------------------------- /react-native/packager/src/node-haste/types.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @flow 10 | */ 11 | 12 | 'use strict'; 13 | 14 | // TODO(cpojer): Create a jest-types repo. 15 | export type HasteFS = { 16 | exists(filePath: string): boolean, 17 | getAllFiles(): Array, 18 | matchFiles(pattern: RegExp | string): Array, 19 | }; 20 | -------------------------------------------------------------------------------- /tests/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { AppRegistry, Text } from 'react-native'; 3 | import ImagePicker from 'react-native-image-picker'; 4 | import Widget from './widget'; 5 | 6 | class HelloWorldApp extends Component { 7 | render() { 8 | return ( 9 | Hello world! 10 | ); 11 | } 12 | } 13 | 14 | AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp); 15 | -------------------------------------------------------------------------------- /tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "private": true, 4 | "dependencies": { 5 | "react-native-image-picker": "x" 6 | }, 7 | "devDependencies": { 8 | "react": "~15.4.1", 9 | "react-native": "0.42.3" 10 | }, 11 | "scripts": { 12 | "start": "node ../bin/rnpackager start" 13 | }, 14 | "tnpm": { 15 | "mode": "yarn" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/widget.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Text } from 'react-native'; 3 | 4 | class Widget extends Component { 5 | render() { 6 | return ( 7 | Widget! 8 | ); 9 | } 10 | } 11 | 12 | export default Widget; 13 | --------------------------------------------------------------------------------