From 6a1d9af14da5af034a019f2616677e3f077b1ce5 Mon Sep 17 00:00:00 2001 From: Piotr Trocki Date: Tue, 10 Sep 2019 13:49:07 +0200 Subject: [PATCH 01/15] Migrate findAssets file --- ...{findAssets-test.js => findAssets-test.ts} | 2 +- .../config/{findAssets.js => findAssets.ts} | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) rename packages/cli/src/tools/config/__tests__/{findAssets-test.js => findAssets-test.ts} (99%) rename packages/cli/src/tools/config/{findAssets.js => findAssets.ts} (64%) diff --git a/packages/cli/src/tools/config/__tests__/findAssets-test.js b/packages/cli/src/tools/config/__tests__/findAssets-test.ts similarity index 99% rename from packages/cli/src/tools/config/__tests__/findAssets-test.js rename to packages/cli/src/tools/config/__tests__/findAssets-test.ts index a6387ce8f..8c4581ebb 100644 --- a/packages/cli/src/tools/config/__tests__/findAssets-test.js +++ b/packages/cli/src/tools/config/__tests__/findAssets-test.ts @@ -32,7 +32,7 @@ describe('findAssets', () => { it('returns an array of all files in given folders', () => { const assets = findAssets('/testDir', ['fonts', 'images']); - + expect(Array.isArray(assets)).toBeTruthy(); expect(assets).toHaveLength(3); }); diff --git a/packages/cli/src/tools/config/findAssets.js b/packages/cli/src/tools/config/findAssets.ts similarity index 64% rename from packages/cli/src/tools/config/findAssets.js rename to packages/cli/src/tools/config/findAssets.ts index 416581db8..e1dad8010 100644 --- a/packages/cli/src/tools/config/findAssets.js +++ b/packages/cli/src/tools/config/findAssets.ts @@ -1,11 +1,7 @@ -/** - * @flow - */ - import glob from 'glob'; import path from 'path'; -const findAssetsInFolder = folder => { +const findAssetsInFolder = (folder: string): string[] => { const assets = glob.sync(path.join(folder, '**'), {nodir: true}); if (process.platform === 'win32') { return assets.map(asset => asset.split('/').join('\\')); @@ -19,12 +15,13 @@ const findAssetsInFolder = folder => { * * It returns an array of absolute paths to files found. */ -export default function findAssets(folder: string, assets: string[]) { +export default function findAssets( + folder: string, + assets: Array, +): Array { return (assets || []) .map(asset => path.join(folder, asset)) - .reduce( - (acc, assetPath) => - (acc.concat(findAssetsInFolder(assetPath)): Array), - [], - ); + .reduce((acc: string[], assetPath: string) => { + return acc.concat(findAssetsInFolder(assetPath)); + }, []); } From 4e9b11139549633f0227da13ab4ffd601ccf855f Mon Sep 17 00:00:00 2001 From: Piotr Trocki Date: Tue, 10 Sep 2019 13:54:04 +0200 Subject: [PATCH 02/15] migrate findDependencies to ts --- .../{findDependencies-test.js => findDependencies-test.ts} | 0 .../tools/config/{findDependencies.js => findDependencies.ts} | 4 ---- 2 files changed, 4 deletions(-) rename packages/cli/src/tools/config/__tests__/{findDependencies-test.js => findDependencies-test.ts} (100%) rename packages/cli/src/tools/config/{findDependencies.js => findDependencies.ts} (96%) diff --git a/packages/cli/src/tools/config/__tests__/findDependencies-test.js b/packages/cli/src/tools/config/__tests__/findDependencies-test.ts similarity index 100% rename from packages/cli/src/tools/config/__tests__/findDependencies-test.js rename to packages/cli/src/tools/config/__tests__/findDependencies-test.ts diff --git a/packages/cli/src/tools/config/findDependencies.js b/packages/cli/src/tools/config/findDependencies.ts similarity index 96% rename from packages/cli/src/tools/config/findDependencies.js rename to packages/cli/src/tools/config/findDependencies.ts index c5f392964..4d5eb39f1 100644 --- a/packages/cli/src/tools/config/findDependencies.js +++ b/packages/cli/src/tools/config/findDependencies.ts @@ -1,7 +1,3 @@ -/** - * @flow - */ - import path from 'path'; import fs from 'fs'; From d73fabf28ddbfd34eed351949c8859eb3eab2cfa Mon Sep 17 00:00:00 2001 From: Piotr Trocki Date: Tue, 10 Sep 2019 14:10:22 +0200 Subject: [PATCH 03/15] Migrate errors file to ts --- .../src/tools/config/{errors.js => errors.ts} | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) rename packages/cli/src/tools/config/{errors.js => errors.ts} (87%) diff --git a/packages/cli/src/tools/config/errors.js b/packages/cli/src/tools/config/errors.ts similarity index 87% rename from packages/cli/src/tools/config/errors.js rename to packages/cli/src/tools/config/errors.ts index 3b1fbbc55..ad86dbd34 100644 --- a/packages/cli/src/tools/config/errors.js +++ b/packages/cli/src/tools/config/errors.ts @@ -1,13 +1,10 @@ -/** - * @flow - */ import {CLIError} from '@react-native-community/cli-tools'; type JoiErrorDetails = { - message: string, - path: string[], - type: K, - context: T, + message: string; + path: string[]; + type: K; + context: T; }; type JoiErrorT = { @@ -15,12 +12,12 @@ type JoiErrorT = { JoiErrorDetails< 'object.allowUnknown' | 'object.base' | 'string.base', { - key: string, - label: string, - value: Object, - }, - >, - >, + key: string; + label: string; + value: Object; + } + > + >; }; export class JoiError extends CLIError { From 940a9d1f636cc34e1b3c1a974b047592a47ec7ff Mon Sep 17 00:00:00 2001 From: Piotr Trocki Date: Tue, 10 Sep 2019 14:27:56 +0200 Subject: [PATCH 04/15] migrate schema file to ts --- packages/cli/package.json | 1 + packages/cli/src/tools/config/{schema.js => schema.ts} | 8 +++----- yarn.lock | 8 ++++++++ 3 files changed, 12 insertions(+), 5 deletions(-) rename packages/cli/src/tools/config/{schema.js => schema.ts} (97%) diff --git a/packages/cli/package.json b/packages/cli/package.json index 4eafca169..29e87050b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -70,6 +70,7 @@ "devDependencies": { "@types/command-exists": "^1.2.0", "@types/graceful-fs": "^4.1.3", + "@types/hapi__joi": "^15.0.4", "@types/minimist": "^1.2.0", "@types/mkdirp": "^0.5.2", "@types/semver": "^6.0.2", diff --git a/packages/cli/src/tools/config/schema.js b/packages/cli/src/tools/config/schema.ts similarity index 97% rename from packages/cli/src/tools/config/schema.js rename to packages/cli/src/tools/config/schema.ts index 7850227bd..79f53f36b 100644 --- a/packages/cli/src/tools/config/schema.js +++ b/packages/cli/src/tools/config/schema.ts @@ -1,9 +1,7 @@ -/** - * @flow - */ -import t from '@hapi/joi'; +import * as t from '@hapi/joi'; +import {SchemaLike} from '@hapi/joi'; -const map = (key, value) => +const map = (key: RegExp | SchemaLike, value: SchemaLike) => t .object() .unknown(true) diff --git a/yarn.lock b/yarn.lock index 962931f1a..4ff8aa5aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2067,6 +2067,14 @@ dependencies: "@types/node" "*" +"@types/hapi__joi@*", "@types/hapi__joi@^15.0.4": + version "15.0.4" + resolved "https://registry.yarnpkg.com/@types/hapi__joi/-/hapi__joi-15.0.4.tgz#49e2e1e6da15ade0fdd6db4daf94aecb07bb391b" + integrity sha512-VSS6zc7AIOdHVXmqKaGNPYl8eGrMvWi0R5pt3evJL3UdxO8XS28/XAkBXNyLQoymHxhMd4bF3o1U9mZkWDeN8w== + dependencies: + "@types/hapi__joi" "*" + + "@types/istanbul-lib-coverage@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.0.tgz#1eb8c033e98cf4e1a4cedcaf8bcafe8cb7591e85" From 1242721e1de7f76bd3040a47c4cf36ea1841c81a Mon Sep 17 00:00:00 2001 From: Piotr Trocki Date: Wed, 11 Sep 2019 11:29:54 +0200 Subject: [PATCH 05/15] Migrate readConfig to ts. --- packages/cli-types/src/index.ts | 83 +++++++++++ packages/cli/package.json | 1 + packages/cli/src/tools/config/errors.ts | 29 +--- ...onfigFromDisk.js => readConfigFromDisk.ts} | 138 ++++++++++-------- ...deModuleDir.js => resolveNodeModuleDir.ts} | 4 - ...ativePath.js => resolveReactNativePath.ts} | 3 - yarn.lock | 8 +- 7 files changed, 171 insertions(+), 95 deletions(-) rename packages/cli/src/tools/config/{readConfigFromDisk.js => readConfigFromDisk.ts} (62%) rename packages/cli/src/tools/config/{resolveNodeModuleDir.js => resolveNodeModuleDir.ts} (79%) rename packages/cli/src/tools/config/{resolveReactNativePath.js => resolveReactNativePath.ts} (97%) diff --git a/packages/cli-types/src/index.ts b/packages/cli-types/src/index.ts index 39b5c5518..c37e90408 100644 --- a/packages/cli-types/src/index.ts +++ b/packages/cli-types/src/index.ts @@ -138,6 +138,89 @@ export interface Config { type Diff = T extends U ? never : T; +/** + * Config defined by a developer for a library + */ + +export type UserDependencyConfig = Diff< + Config, + {root: any; haste: any; assets: any; project: any; reactNativePath: any} +> & { + dependencies?: { + [key: string]: { + name: string; + root: string; + platforms: { + android?: AndroidDependencyConfig | null; + ios?: IOSDependencyConfig | null; + [key: string]: any; + }; + assets: string[]; + hooks: { + prelink?: string; + postlink?: string; + }; + params: InquirerPrompt[]; + }; + } | null; + platforms?: { + android: PlatformConfig< + AndroidProjectConfig, + AndroidProjectParams, + AndroidDependencyConfig, + AndroidDependencyParams + >; + ios: PlatformConfig< + IOSProjectConfig, + IOSProjectParams, + IOSDependencyConfig, + IOSDependencyParams + >; + [name: string]: PlatformConfig; + } | null; + commands?: Command[]; + haste?: { + platforms: Array; + providesModuleNodeModules: Array; + } | null; +}; + +// export type UserDependencyConfig = { +// dependencies?: { +// [key: string]: { +// name: string; +// root: string; +// platforms: { +// android?: AndroidDependencyConfig | null; +// ios?: IOSDependencyConfig | null; +// [key: string]: any; +// }; +// assets: string[]; +// hooks: { +// prelink?: string; +// postlink?: string; +// }; +// params: InquirerPrompt[]; +// }; +// } | null; +// platforms?: { +// android: PlatformConfig< +// AndroidProjectConfig, +// AndroidProjectParams, +// AndroidDependencyConfig, +// AndroidDependencyParams +// >; +// ios: PlatformConfig< +// IOSProjectConfig, +// IOSProjectParams, +// IOSDependencyConfig, +// IOSDependencyParams +// >; +// [name: string]: PlatformConfig; +// } | null; +// commands?: Command[]; +// }; + /** * Shares some structure with ConfigT, except that haste and root * are calculated and can't be defined diff --git a/packages/cli/package.json b/packages/cli/package.json index 29e87050b..8ca6c698a 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -70,6 +70,7 @@ "devDependencies": { "@types/command-exists": "^1.2.0", "@types/graceful-fs": "^4.1.3", + "@types/cosmiconfig": "^5.0.3", "@types/hapi__joi": "^15.0.4", "@types/minimist": "^1.2.0", "@types/mkdirp": "^0.5.2", diff --git a/packages/cli/src/tools/config/errors.ts b/packages/cli/src/tools/config/errors.ts index ad86dbd34..c3e789543 100644 --- a/packages/cli/src/tools/config/errors.ts +++ b/packages/cli/src/tools/config/errors.ts @@ -1,34 +1,17 @@ import {CLIError} from '@react-native-community/cli-tools'; - -type JoiErrorDetails = { - message: string; - path: string[]; - type: K; - context: T; -}; - -type JoiErrorT = { - details: Array< - JoiErrorDetails< - 'object.allowUnknown' | 'object.base' | 'string.base', - { - key: string; - label: string; - value: Object; - } - > - >; -}; +import {ValidationError} from '@hapi/joi'; export class JoiError extends CLIError { - constructor(joiError: JoiErrorT) { + constructor(joiError: ValidationError) { super( joiError.details .map(error => { const name = error.path.join('.'); switch (error.type) { case 'object.allowUnknown': { - const value = JSON.stringify(error.context.value); + const value = JSON.stringify( + error.context && error.context.label, + ); return ` Unknown option ${name} with value "${value}" was found. This is either a typing error or a user mistake. Fixing it will remove this message. @@ -37,7 +20,7 @@ export class JoiError extends CLIError { case 'object.base': case 'string.base': { const expectedType = error.type.replace('.base', ''); - const actualType = typeof error.context.value; + const actualType = typeof (error.context && error.context.value); return ` Option ${name} must be a ${expectedType}, instead got ${actualType} `; diff --git a/packages/cli/src/tools/config/readConfigFromDisk.js b/packages/cli/src/tools/config/readConfigFromDisk.ts similarity index 62% rename from packages/cli/src/tools/config/readConfigFromDisk.js rename to packages/cli/src/tools/config/readConfigFromDisk.ts index 197ed237b..3d719eca5 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.js +++ b/packages/cli/src/tools/config/readConfigFromDisk.ts @@ -1,21 +1,17 @@ -/** - * @flow - * - * Loads and validates a project configuration - */ import Joi from '@hapi/joi'; import cosmiconfig from 'cosmiconfig'; import path from 'path'; import chalk from 'chalk'; import { - type UserDependencyConfigT, - type UserConfigT, - type CommandT, -} from 'types'; + UserConfig, + Command, + UserDependencyConfig, + Config, +} from '../../../../cli-types'; import {JoiError} from './errors'; import * as schema from './schema'; import {logger} from '@react-native-community/cli-tools'; -import resolveReactNativePath from './resolveReactNativePath'; +// import resolveReactNativePath from './resolveReactNativePath'; const MIGRATION_GUIDE = `Migration guide: ${chalk.dim.underline( 'https://github.com/react-native-community/cli/blob/master/docs/configuration.md', @@ -26,35 +22,36 @@ const MIGRATION_GUIDE = `Migration guide: ${chalk.dim.underline( */ const searchPlaces = ['react-native.config.js']; -function readLegacyConfigFromDisk(rootFolder: string): UserConfigT | void { - let config; +function readLegacyConfigFromDisk(rootFolder: string): UserConfig | null { + let config: any; try { + // @ts-ignore json file config = require(path.join(rootFolder, 'package.json')).rnpm; } catch (error) { // when `init` is running, there's no package.json yet - return undefined; + return; } if (!config) { - return undefined; + return; } - const transformedConfig = { - project: { - ios: config.ios, - android: config.android, - }, - assets: config.assets, - commands: [], - dependencies: {}, - platforms: {}, - get reactNativePath() { - return config.reactNativePath - ? path.resolve(rootFolder, config.reactNativePath) - : resolveReactNativePath(rootFolder); - }, - }; + // const transformedConfig = { + // project: { + // ios: config.ios, + // android: config.android, + // }, + // assets: config.assets, + // commands: [], + // dependencies: {}, + // platforms: {}, + // get reactNativePath() { + // return config.reactNativePath + // ? path.resolve(rootFolder, config.reactNativePath) + // : resolveReactNativePath(rootFolder); + // }, + // }; logger.warn( `Your project is using deprecated "${chalk.bold( @@ -64,14 +61,15 @@ function readLegacyConfigFromDisk(rootFolder: string): UserConfigT | void { )}" file to configure the React Native CLI. ${MIGRATION_GUIDE}`, ); - return transformedConfig; + return; + // return transformedConfig; } /** * Reads a project configuration as defined by the user in the current * workspace. */ -export function readConfigFromDisk(rootFolder: string): UserConfigT { +export function readConfigFromDisk(rootFolder: string): UserConfig { const explorer = cosmiconfig('react-native', {searchPlaces}); const {config} = explorer.searchSync(rootFolder) || { @@ -84,6 +82,7 @@ export function readConfigFromDisk(rootFolder: string): UserConfigT { throw new JoiError(result.error); } + // @ts-ignore return result.value; } @@ -93,7 +92,7 @@ export function readConfigFromDisk(rootFolder: string): UserConfigT { */ export function readDependencyConfigFromDisk( rootFolder: string, -): {config: UserDependencyConfigT, legacy?: boolean} { +): {config: Config; legacy?: boolean} { const explorer = cosmiconfig('react-native', { stopDir: rootFolder, searchPlaces, @@ -120,18 +119,13 @@ export function readDependencyConfigFromDisk( * Each of the files can export a commands (object) or an array of commands */ const loadProjectCommands = ( - root, - commands: ?(Array | string), -): Array => { - return [] - .concat(commands || []) - .reduce((acc: Array, cmdPath: string) => { - const cmds: Array | CommandT = require(path.join( - root, - cmdPath, - )); - return acc.concat(cmds); - }, []); + root: string, + commands?: string[], +): Array => { + return (commands || []).reduce((acc: Array, cmdPath: string) => { + const cmds: Array | Command = require(path.join(root, cmdPath)); + return acc.concat(cmds); + }, []); }; /** @@ -139,7 +133,7 @@ const loadProjectCommands = ( */ function readLegacyDependencyConfigFromDisk( rootFolder: string, -): ?UserDependencyConfigT { +): UserDependencyConfig | null | undefined { let config = {}; try { @@ -148,14 +142,18 @@ function readLegacyDependencyConfigFromDisk( // package.json is usually missing in local libraries that are not in // project "dependencies", so we just return a bare config return { - dependency: { - platforms: {}, - assets: [], - hooks: {}, - params: [], + dependencies: { + dependencies: { + name: '', + root: '', + platforms: {}, + assets: [], + hooks: {}, + params: [], + }, }, + platforms: null, commands: [], - platforms: {}, }; } @@ -163,22 +161,34 @@ function readLegacyDependencyConfigFromDisk( return undefined; } - const transformedConfig = { - dependency: { - platforms: { - ios: config.ios, - android: config.android, + return { + dependencies: { + dependencies: { + name: '', + root: '', + platforms: { + // @ts-ignore + ios: config.ios, + // @ts-ignore + android: config.android, + }, + // @ts-ignore + assets: config.assets, + // @ts-ignore + hooks: config.commands, + // @ts-ignore + params: config.params, }, - assets: config.assets, - hooks: config.commands, - params: config.params, }, - haste: config.haste, - commands: loadProjectCommands(rootFolder, config.plugin), + // @ts-ignore platforms: config.platform - ? require(path.join(rootFolder, config.platform)) + ? // + // @ts-ignore + require(path.join(rootFolder, config.platform || '')) : {}, + // @ts-ignore + commands: loadProjectCommands(rootFolder, config.plugin), + // @ts-ignore + haste: config.haste, }; - - return transformedConfig; } diff --git a/packages/cli/src/tools/config/resolveNodeModuleDir.js b/packages/cli/src/tools/config/resolveNodeModuleDir.ts similarity index 79% rename from packages/cli/src/tools/config/resolveNodeModuleDir.js rename to packages/cli/src/tools/config/resolveNodeModuleDir.ts index 09a0e4917..7a03950cd 100644 --- a/packages/cli/src/tools/config/resolveNodeModuleDir.js +++ b/packages/cli/src/tools/config/resolveNodeModuleDir.ts @@ -1,6 +1,3 @@ -/** - * @flow - */ import path from 'path'; /** @@ -11,7 +8,6 @@ export default function resolveNodeModuleDir( packageName: string, ): string { return path.dirname( - // $FlowIssue: Wrong `require.resolve` type definition require.resolve(path.join(packageName, 'package.json'), { paths: [root], }), diff --git a/packages/cli/src/tools/config/resolveReactNativePath.js b/packages/cli/src/tools/config/resolveReactNativePath.ts similarity index 97% rename from packages/cli/src/tools/config/resolveReactNativePath.js rename to packages/cli/src/tools/config/resolveReactNativePath.ts index dbce4e5c8..db5150fff 100644 --- a/packages/cli/src/tools/config/resolveReactNativePath.js +++ b/packages/cli/src/tools/config/resolveReactNativePath.ts @@ -1,6 +1,3 @@ -/** - * @flow - */ import {CLIError} from '@react-native-community/cli-tools'; import resolveNodeModuleDir from './resolveNodeModuleDir'; diff --git a/yarn.lock b/yarn.lock index 4ff8aa5aa..48086f37b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2032,6 +2032,13 @@ resolved "https://registry.yarnpkg.com/@types/command-exists/-/command-exists-1.2.0.tgz#d97e0ed10097090e4ab0367ed425b0312fad86f3" integrity sha512-ugsxEJfsCuqMLSuCD4PIJkp5Uk2z6TCMRCgYVuhRo5cYQY3+1xXTQkSlPtkpGHuvWMjS2KTeVQXxkXRACMbM6A== +"@types/cosmiconfig@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/cosmiconfig/-/cosmiconfig-5.0.3.tgz#880644bb155d4038d3b752159684b777b0a159dd" + integrity sha512-HgTGG7X5y9pLl3pixeo2XtDEFD8rq2EuH+S4mK6teCnAwWMucQl6v1D43hI4Uw1VJh6nu59lxLkqXHRl4uwThA== + dependencies: + "@types/node" "*" + "@types/events@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" @@ -2074,7 +2081,6 @@ dependencies: "@types/hapi__joi" "*" - "@types/istanbul-lib-coverage@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.0.tgz#1eb8c033e98cf4e1a4cedcaf8bcafe8cb7591e85" From e3953be13e9c94c355e991469317070e6a76ea5a Mon Sep 17 00:00:00 2001 From: Piotr Trocki Date: Wed, 11 Sep 2019 14:32:52 +0200 Subject: [PATCH 06/15] Revert readConfigFromDisk --- packages/cli-types/src/index.ts | 83 ----------- ...onfigFromDisk.ts => readConfigFromDisk.js} | 138 ++++++++---------- 2 files changed, 64 insertions(+), 157 deletions(-) rename packages/cli/src/tools/config/{readConfigFromDisk.ts => readConfigFromDisk.js} (62%) diff --git a/packages/cli-types/src/index.ts b/packages/cli-types/src/index.ts index c37e90408..39b5c5518 100644 --- a/packages/cli-types/src/index.ts +++ b/packages/cli-types/src/index.ts @@ -138,89 +138,6 @@ export interface Config { type Diff = T extends U ? never : T; -/** - * Config defined by a developer for a library - */ - -export type UserDependencyConfig = Diff< - Config, - {root: any; haste: any; assets: any; project: any; reactNativePath: any} -> & { - dependencies?: { - [key: string]: { - name: string; - root: string; - platforms: { - android?: AndroidDependencyConfig | null; - ios?: IOSDependencyConfig | null; - [key: string]: any; - }; - assets: string[]; - hooks: { - prelink?: string; - postlink?: string; - }; - params: InquirerPrompt[]; - }; - } | null; - platforms?: { - android: PlatformConfig< - AndroidProjectConfig, - AndroidProjectParams, - AndroidDependencyConfig, - AndroidDependencyParams - >; - ios: PlatformConfig< - IOSProjectConfig, - IOSProjectParams, - IOSDependencyConfig, - IOSDependencyParams - >; - [name: string]: PlatformConfig; - } | null; - commands?: Command[]; - haste?: { - platforms: Array; - providesModuleNodeModules: Array; - } | null; -}; - -// export type UserDependencyConfig = { -// dependencies?: { -// [key: string]: { -// name: string; -// root: string; -// platforms: { -// android?: AndroidDependencyConfig | null; -// ios?: IOSDependencyConfig | null; -// [key: string]: any; -// }; -// assets: string[]; -// hooks: { -// prelink?: string; -// postlink?: string; -// }; -// params: InquirerPrompt[]; -// }; -// } | null; -// platforms?: { -// android: PlatformConfig< -// AndroidProjectConfig, -// AndroidProjectParams, -// AndroidDependencyConfig, -// AndroidDependencyParams -// >; -// ios: PlatformConfig< -// IOSProjectConfig, -// IOSProjectParams, -// IOSDependencyConfig, -// IOSDependencyParams -// >; -// [name: string]: PlatformConfig; -// } | null; -// commands?: Command[]; -// }; - /** * Shares some structure with ConfigT, except that haste and root * are calculated and can't be defined diff --git a/packages/cli/src/tools/config/readConfigFromDisk.ts b/packages/cli/src/tools/config/readConfigFromDisk.js similarity index 62% rename from packages/cli/src/tools/config/readConfigFromDisk.ts rename to packages/cli/src/tools/config/readConfigFromDisk.js index 3d719eca5..197ed237b 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.ts +++ b/packages/cli/src/tools/config/readConfigFromDisk.js @@ -1,17 +1,21 @@ +/** + * @flow + * + * Loads and validates a project configuration + */ import Joi from '@hapi/joi'; import cosmiconfig from 'cosmiconfig'; import path from 'path'; import chalk from 'chalk'; import { - UserConfig, - Command, - UserDependencyConfig, - Config, -} from '../../../../cli-types'; + type UserDependencyConfigT, + type UserConfigT, + type CommandT, +} from 'types'; import {JoiError} from './errors'; import * as schema from './schema'; import {logger} from '@react-native-community/cli-tools'; -// import resolveReactNativePath from './resolveReactNativePath'; +import resolveReactNativePath from './resolveReactNativePath'; const MIGRATION_GUIDE = `Migration guide: ${chalk.dim.underline( 'https://github.com/react-native-community/cli/blob/master/docs/configuration.md', @@ -22,36 +26,35 @@ const MIGRATION_GUIDE = `Migration guide: ${chalk.dim.underline( */ const searchPlaces = ['react-native.config.js']; -function readLegacyConfigFromDisk(rootFolder: string): UserConfig | null { - let config: any; +function readLegacyConfigFromDisk(rootFolder: string): UserConfigT | void { + let config; try { - // @ts-ignore json file config = require(path.join(rootFolder, 'package.json')).rnpm; } catch (error) { // when `init` is running, there's no package.json yet - return; + return undefined; } if (!config) { - return; + return undefined; } - // const transformedConfig = { - // project: { - // ios: config.ios, - // android: config.android, - // }, - // assets: config.assets, - // commands: [], - // dependencies: {}, - // platforms: {}, - // get reactNativePath() { - // return config.reactNativePath - // ? path.resolve(rootFolder, config.reactNativePath) - // : resolveReactNativePath(rootFolder); - // }, - // }; + const transformedConfig = { + project: { + ios: config.ios, + android: config.android, + }, + assets: config.assets, + commands: [], + dependencies: {}, + platforms: {}, + get reactNativePath() { + return config.reactNativePath + ? path.resolve(rootFolder, config.reactNativePath) + : resolveReactNativePath(rootFolder); + }, + }; logger.warn( `Your project is using deprecated "${chalk.bold( @@ -61,15 +64,14 @@ function readLegacyConfigFromDisk(rootFolder: string): UserConfig | null { )}" file to configure the React Native CLI. ${MIGRATION_GUIDE}`, ); - return; - // return transformedConfig; + return transformedConfig; } /** * Reads a project configuration as defined by the user in the current * workspace. */ -export function readConfigFromDisk(rootFolder: string): UserConfig { +export function readConfigFromDisk(rootFolder: string): UserConfigT { const explorer = cosmiconfig('react-native', {searchPlaces}); const {config} = explorer.searchSync(rootFolder) || { @@ -82,7 +84,6 @@ export function readConfigFromDisk(rootFolder: string): UserConfig { throw new JoiError(result.error); } - // @ts-ignore return result.value; } @@ -92,7 +93,7 @@ export function readConfigFromDisk(rootFolder: string): UserConfig { */ export function readDependencyConfigFromDisk( rootFolder: string, -): {config: Config; legacy?: boolean} { +): {config: UserDependencyConfigT, legacy?: boolean} { const explorer = cosmiconfig('react-native', { stopDir: rootFolder, searchPlaces, @@ -119,13 +120,18 @@ export function readDependencyConfigFromDisk( * Each of the files can export a commands (object) or an array of commands */ const loadProjectCommands = ( - root: string, - commands?: string[], -): Array => { - return (commands || []).reduce((acc: Array, cmdPath: string) => { - const cmds: Array | Command = require(path.join(root, cmdPath)); - return acc.concat(cmds); - }, []); + root, + commands: ?(Array | string), +): Array => { + return [] + .concat(commands || []) + .reduce((acc: Array, cmdPath: string) => { + const cmds: Array | CommandT = require(path.join( + root, + cmdPath, + )); + return acc.concat(cmds); + }, []); }; /** @@ -133,7 +139,7 @@ const loadProjectCommands = ( */ function readLegacyDependencyConfigFromDisk( rootFolder: string, -): UserDependencyConfig | null | undefined { +): ?UserDependencyConfigT { let config = {}; try { @@ -142,18 +148,14 @@ function readLegacyDependencyConfigFromDisk( // package.json is usually missing in local libraries that are not in // project "dependencies", so we just return a bare config return { - dependencies: { - dependencies: { - name: '', - root: '', - platforms: {}, - assets: [], - hooks: {}, - params: [], - }, + dependency: { + platforms: {}, + assets: [], + hooks: {}, + params: [], }, - platforms: null, commands: [], + platforms: {}, }; } @@ -161,34 +163,22 @@ function readLegacyDependencyConfigFromDisk( return undefined; } - return { - dependencies: { - dependencies: { - name: '', - root: '', - platforms: { - // @ts-ignore - ios: config.ios, - // @ts-ignore - android: config.android, - }, - // @ts-ignore - assets: config.assets, - // @ts-ignore - hooks: config.commands, - // @ts-ignore - params: config.params, + const transformedConfig = { + dependency: { + platforms: { + ios: config.ios, + android: config.android, }, + assets: config.assets, + hooks: config.commands, + params: config.params, }, - // @ts-ignore + haste: config.haste, + commands: loadProjectCommands(rootFolder, config.plugin), platforms: config.platform - ? // - // @ts-ignore - require(path.join(rootFolder, config.platform || '')) + ? require(path.join(rootFolder, config.platform)) : {}, - // @ts-ignore - commands: loadProjectCommands(rootFolder, config.plugin), - // @ts-ignore - haste: config.haste, }; + + return transformedConfig; } From 8e82c6ae4bfa604bc0c8cd483e21001e6270cd89 Mon Sep 17 00:00:00 2001 From: Piotr Trocki Date: Thu, 12 Sep 2019 16:28:59 +0200 Subject: [PATCH 07/15] Convert readConfigFromDisk to ts --- packages/cli-types/src/index.ts | 17 +- .../{index-test.js => index-test.ts} | 0 .../src/tools/config/{index.js => index.ts} | 32 ++- .../src/tools/config/readConfigFromDisk.js | 184 ---------------- .../src/tools/config/readConfigFromDisk.ts | 206 ++++++++++++++++++ 5 files changed, 231 insertions(+), 208 deletions(-) rename packages/cli/src/tools/config/__tests__/{index-test.js => index-test.ts} (100%) rename packages/cli/src/tools/config/{index.js => index.ts} (93%) delete mode 100644 packages/cli/src/tools/config/readConfigFromDisk.js create mode 100644 packages/cli/src/tools/config/readConfigFromDisk.ts diff --git a/packages/cli-types/src/index.ts b/packages/cli-types/src/index.ts index 39b5c5518..736753681 100644 --- a/packages/cli-types/src/index.ts +++ b/packages/cli-types/src/index.ts @@ -104,7 +104,7 @@ export interface Dependency { * @property commands - An array of commands that are present in 3rd party packages * @property haste - Haste configuration resolved based on available plugins */ -export interface Config { +export type Config = { root: string; reactNativePath: string; project: { @@ -134,15 +134,17 @@ export interface Config { platforms: Array; providesModuleNodeModules: Array; }; -} - -type Diff = T extends U ? never : T; +}; /** * Shares some structure with ConfigT, except that haste and root * are calculated and can't be defined */ -export type UserConfig = Diff & { +// For Omit, see https://devblogs.microsoft.com/typescript/announcing-typescript-3-5/#the-omit-helper-type +// export interface UserConfig +// extends Omit, 'haste'>, 'root'> {} + +export type UserConfig = Omit & { reactNativePath: string | void; // Additional project settings @@ -153,6 +155,11 @@ export type UserConfig = Diff & { }; }; +export type UserDependencyConfig = Omit< + Config, + 'root' | 'reactNativePath' | 'project' | 'assets' +>; + export { IOSProjectConfig, IOSProjectParams, diff --git a/packages/cli/src/tools/config/__tests__/index-test.js b/packages/cli/src/tools/config/__tests__/index-test.ts similarity index 100% rename from packages/cli/src/tools/config/__tests__/index-test.js rename to packages/cli/src/tools/config/__tests__/index-test.ts diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.ts similarity index 93% rename from packages/cli/src/tools/config/index.js rename to packages/cli/src/tools/config/index.ts index 1037c0a70..6458ef99f 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.ts @@ -1,6 +1,3 @@ -/** - * @flow - */ import path from 'path'; import chalk from 'chalk'; import {logger, inlineString} from '@react-native-community/cli-tools'; @@ -13,26 +10,23 @@ import { readConfigFromDisk, readDependencyConfigFromDisk, } from './readConfigFromDisk'; -import type { - ConfigT, - UserDependencyConfigT, - UserConfigT, - DependencyConfigT, -} from 'types'; -// $FlowFixMe - converted to TS import assign from '../assign'; -// $FlowFixMe - converted to TS import merge from '../merge'; import resolveNodeModuleDir from './resolveNodeModuleDir'; +import { + UserConfig, + Config +} from '../../../../cli-types'; +import {UserDependencyConfig} from '@react-native-community/cli-types/src'; function getDependencyConfig( root: string, dependencyName: string, - finalConfig: ConfigT, - config: UserDependencyConfigT, - userConfig: UserConfigT, + finalConfig: Config, + config: UserDependencyConfig, + userConfig: UserConfig, isPlatform: boolean, -): DependencyConfigT { +): UserDependencyConfig | void{ return merge( { root, @@ -65,11 +59,11 @@ function getDependencyConfig( /** * Loads CLI configuration */ -function loadConfig(projectRoot: string = process.cwd()): ConfigT { +function loadConfig(projectRoot: string = process.cwd()): Config | void{ let lazyProject; const userConfig = readConfigFromDisk(projectRoot); - const initialConfig: ConfigT = { + const initialConfig: Config = { root: projectRoot, get reactNativePath() { return userConfig.reactNativePath @@ -110,7 +104,7 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { ...Object.keys(userConfig.dependencies), ...findDependencies(projectRoot), ]), - ).reduce((acc: ConfigT, dependencyName) => { + ).reduce((acc: Config, dependencyName) => { const localDependencyRoot = userConfig.dependencies[dependencyName] && userConfig.dependencies[dependencyName].root; @@ -193,7 +187,7 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { ], platforms: [...acc.haste.platforms, ...haste.platforms], }, - }): ConfigT); + }): Config); }, initialConfig); if (depsWithWarnings.length) { diff --git a/packages/cli/src/tools/config/readConfigFromDisk.js b/packages/cli/src/tools/config/readConfigFromDisk.js deleted file mode 100644 index 197ed237b..000000000 --- a/packages/cli/src/tools/config/readConfigFromDisk.js +++ /dev/null @@ -1,184 +0,0 @@ -/** - * @flow - * - * Loads and validates a project configuration - */ -import Joi from '@hapi/joi'; -import cosmiconfig from 'cosmiconfig'; -import path from 'path'; -import chalk from 'chalk'; -import { - type UserDependencyConfigT, - type UserConfigT, - type CommandT, -} from 'types'; -import {JoiError} from './errors'; -import * as schema from './schema'; -import {logger} from '@react-native-community/cli-tools'; -import resolveReactNativePath from './resolveReactNativePath'; - -const MIGRATION_GUIDE = `Migration guide: ${chalk.dim.underline( - 'https://github.com/react-native-community/cli/blob/master/docs/configuration.md', -)}`; - -/** - * Places to look for the new configuration - */ -const searchPlaces = ['react-native.config.js']; - -function readLegacyConfigFromDisk(rootFolder: string): UserConfigT | void { - let config; - - try { - config = require(path.join(rootFolder, 'package.json')).rnpm; - } catch (error) { - // when `init` is running, there's no package.json yet - return undefined; - } - - if (!config) { - return undefined; - } - - const transformedConfig = { - project: { - ios: config.ios, - android: config.android, - }, - assets: config.assets, - commands: [], - dependencies: {}, - platforms: {}, - get reactNativePath() { - return config.reactNativePath - ? path.resolve(rootFolder, config.reactNativePath) - : resolveReactNativePath(rootFolder); - }, - }; - - logger.warn( - `Your project is using deprecated "${chalk.bold( - 'rnpm', - )}" config that will stop working from next release. Please use a "${chalk.bold( - 'react-native.config.js', - )}" file to configure the React Native CLI. ${MIGRATION_GUIDE}`, - ); - - return transformedConfig; -} - -/** - * Reads a project configuration as defined by the user in the current - * workspace. - */ -export function readConfigFromDisk(rootFolder: string): UserConfigT { - const explorer = cosmiconfig('react-native', {searchPlaces}); - - const {config} = explorer.searchSync(rootFolder) || { - config: readLegacyConfigFromDisk(rootFolder), - }; - - const result = Joi.validate(config, schema.projectConfig); - - if (result.error) { - throw new JoiError(result.error); - } - - return result.value; -} - -/** - * Reads a dependency configuration as defined by the developer - * inside `node_modules`. - */ -export function readDependencyConfigFromDisk( - rootFolder: string, -): {config: UserDependencyConfigT, legacy?: boolean} { - const explorer = cosmiconfig('react-native', { - stopDir: rootFolder, - searchPlaces, - }); - - const {config, legacy} = explorer.searchSync(rootFolder) || { - config: readLegacyDependencyConfigFromDisk(rootFolder), - legacy: true, - }; - - const result = Joi.validate(config, schema.dependencyConfig); - - if (result.error) { - throw new JoiError(result.error); - } - - return {config: result.value, legacy: legacy && config !== undefined}; -} - -/** - * Returns an array of commands that are defined in the project. - * - * `config.project` can be either an array of paths or a single string. - * Each of the files can export a commands (object) or an array of commands - */ -const loadProjectCommands = ( - root, - commands: ?(Array | string), -): Array => { - return [] - .concat(commands || []) - .reduce((acc: Array, cmdPath: string) => { - const cmds: Array | CommandT = require(path.join( - root, - cmdPath, - )); - return acc.concat(cmds); - }, []); -}; - -/** - * Reads a legacy configuration from a `package.json` "rnpm" key. - */ -function readLegacyDependencyConfigFromDisk( - rootFolder: string, -): ?UserDependencyConfigT { - let config = {}; - - try { - config = require(path.join(rootFolder, 'package.json')).rnpm; - } catch (error) { - // package.json is usually missing in local libraries that are not in - // project "dependencies", so we just return a bare config - return { - dependency: { - platforms: {}, - assets: [], - hooks: {}, - params: [], - }, - commands: [], - platforms: {}, - }; - } - - if (!config) { - return undefined; - } - - const transformedConfig = { - dependency: { - platforms: { - ios: config.ios, - android: config.android, - }, - assets: config.assets, - hooks: config.commands, - params: config.params, - }, - haste: config.haste, - commands: loadProjectCommands(rootFolder, config.plugin), - platforms: config.platform - ? require(path.join(rootFolder, config.platform)) - : {}, - }; - - return transformedConfig; -} diff --git a/packages/cli/src/tools/config/readConfigFromDisk.ts b/packages/cli/src/tools/config/readConfigFromDisk.ts new file mode 100644 index 000000000..b9e2b03cc --- /dev/null +++ b/packages/cli/src/tools/config/readConfigFromDisk.ts @@ -0,0 +1,206 @@ +import Joi from '@hapi/joi'; +import cosmiconfig from 'cosmiconfig'; +import path from 'path'; +import chalk from 'chalk'; +import {JoiError} from './errors'; +import * as schema from './schema'; +import {logger} from '@react-native-community/cli-tools'; +import resolveReactNativePath from './resolveReactNativePath'; +import { + UserConfig, + AndroidProjectConfig, + IOSProjectConfig, + Command, + InquirerPrompt, +} from '../../../../cli-types'; + +import {UserDependencyConfig} from '@react-native-community/cli-types/src'; +const MIGRATION_GUIDE = `Migration guide: ${chalk.dim.underline( + 'https://github.com/react-native-community/cli/blob/master/docs/configuration.md', +)}`; + +type LegacyConfig = { + ios: IOSProjectConfig; + android: AndroidProjectConfig; + assets: string[]; + reactNativePath: string; +}; + +type LegacyDependencyConfig = { + platform: any; + ios: IOSProjectConfig; + android: AndroidProjectConfig; + assets: string[]; + plugin: Array; + params: InquirerPrompt[]; + haste: any; + commands: Command[]; +}; + +/** + * Places to look for the new configuration + */ +const searchPlaces = ['react-native.config.js']; + +function readLegacyConfigFromDisk(rootFolder: string): UserConfig | void { + let config: LegacyConfig; + + try { + config = require(path.join(rootFolder, 'package.json')).rnpm; + } catch (error) { + // when `init` is running, there's no package.json yet + return undefined; + } + + if (!config) { + return undefined; + } + + const reactNativePath = config.reactNativePath + ? path.resolve(rootFolder, config.reactNativePath) + : resolveReactNativePath(rootFolder); + + const transformedConfig: UserConfig = { + reactNativePath: reactNativePath, + project: { + android: config.android, + ios: config.ios, + }, + assets: config.assets, + commands: [], + }; + + logger.warn( + `Your project is using deprecated "${chalk.bold( + 'rnpm', + )}" config that will stop working from next release. Please use a "${chalk.bold( + 'react-native.config.js', + )}" file to configure the React Native CLI. ${MIGRATION_GUIDE}`, + ); + + return transformedConfig; +} + +/** + * Reads a project configuration as defined by the user in the current + * workspace. + */ +export function readConfigFromDisk(rootFolder: string): UserConfig { + const explorer = cosmiconfig('react-native', {searchPlaces}); + + const {config} = explorer.searchSync(rootFolder) || { + config: readLegacyConfigFromDisk(rootFolder), + }; + + const result = Joi.validate(config, schema.projectConfig); + + if (result.error) { + throw new JoiError(result.error); + } + + return config as UserConfig; +} + +/** + * Reads a dependency configuration as defined by the developer + * inside `node_modules`. + */ +export function readDependencyConfigFromDisk( + rootFolder: string, +): {config: UserDependencyConfig; legacy?: boolean} { + const explorer = cosmiconfig('react-native', { + stopDir: rootFolder, + searchPlaces, + }); + const config: cosmiconfig.CosmiconfigResult = explorer.searchSync(rootFolder); + const legacy = config ? true : false; + // @ts-ignore Joi validate the type + const dependencyConfig: UserDependencyConfig = config + ? (config.config as UserDependencyConfig) + : readLegacyDependencyConfigFromDisk(rootFolder); + + const result = Joi.validate(config, schema.dependencyConfig); + + if (result.error) { + throw new JoiError(result.error); + } + + return {config: dependencyConfig, legacy: legacy && config !== undefined}; +} + +// /** +// * Returns an array of commands that are defined in the project. +// * +// * `config.project` can be either an array of paths or a single string. +// * Each of the files can export a commands (object) or an array of commands +// */ +const loadProjectCommands = ( + root: string, + ...commands: string[] +): Command[] => { + return commands.reduce((acc: Command[], cmdPath: string) => { + const cmds: Array | Command = require(path.join(root, cmdPath)); + return acc.concat(cmds); + }, []); +}; + +// /** +// * Reads a legacy configuration from a `package.json` "rnpm" key. +// */ +function readLegacyDependencyConfigFromDisk( + rootFolder: string, +): UserDependencyConfig | undefined { + let config: LegacyDependencyConfig; + + try { + config = require(path.join(rootFolder, 'package.json')).rnpm; + } catch (error) { + // package.json is usually missing in local libraries that are not in + // project "dependencies", so we just return a bare config + return { + assets: [], + dependencies: { + dep: { + name: '', + root: '', + platforms: {}, + assets: null, + hooks: null, + params: null, + }, + }, + platforms: null, + commands: [], + haste: null, + }; + } + + if (!config) { + return undefined; + } + + const platforms = config.platform + ? require(path.join(rootFolder, config.platform)) + : {}; + const transformedConfig: UserDependencyConfig = { + assets: [], + dependencies: { + dep: { + name: '', + root: '', + platforms: { + android: config.android, + ios: config.ios, + }, + assets: config.assets, + hooks: config.commands, + params: config.params, + }, + }, + platforms: platforms, + commands: loadProjectCommands(rootFolder, ...config.plugin), + haste: config.haste, + }; + + return transformedConfig; +} From 92b049eca18b2b2cb079f42bf8a448568478c8d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Mon, 16 Sep 2019 09:33:47 +0200 Subject: [PATCH 08/15] try to clean up --- packages/cli-types/src/index.ts | 44 ++++++++++---- packages/cli-types/src/ios.ts | 2 +- packages/cli/src/cliEntry.js | 1 + packages/cli/src/commands/install/install.ts | 6 +- .../config/__mocks__/{index.js => index.ts} | 4 -- ...deModuleDir.js => resolveNodeModuleDir.ts} | 4 -- .../tools/config/__tests__/findAssets-test.ts | 2 +- packages/cli/src/tools/config/index.ts | 29 +++++---- .../src/tools/config/readConfigFromDisk.ts | 59 ++++++++----------- packages/cli/src/tools/merge.ts | 5 +- 10 files changed, 77 insertions(+), 79 deletions(-) rename packages/cli/src/tools/config/__mocks__/{index.js => index.ts} (96%) rename packages/cli/src/tools/config/__mocks__/{resolveNodeModuleDir.js => resolveNodeModuleDir.ts} (91%) diff --git a/packages/cli-types/src/index.ts b/packages/cli-types/src/index.ts index 736753681..648d92462 100644 --- a/packages/cli-types/src/index.ts +++ b/packages/cli-types/src/index.ts @@ -94,6 +94,12 @@ export interface Dependency { params: InquirerPrompt[]; } +export type ProjectConfig = { + android?: AndroidProjectConfig; + ios?: IOSProjectConfig; + [key: string]: any; +}; + /** * @property root - Root where the configuration has been resolved from * @property reactNativePath - Path to React Native source @@ -107,27 +113,23 @@ export interface Dependency { export type Config = { root: string; reactNativePath: string; - project: { - android?: AndroidProjectConfig; - ios?: IOSProjectConfig; - [key: string]: any; - }; + project: ProjectConfig; assets: string[]; dependencies: {[key: string]: Dependency}; platforms: { - android: PlatformConfig< + android?: PlatformConfig< AndroidProjectConfig, AndroidProjectParams, AndroidDependencyConfig, AndroidDependencyParams >; - ios: PlatformConfig< + ios?: PlatformConfig< IOSProjectConfig, IOSProjectParams, IOSDependencyConfig, IOSDependencyParams >; - [name: string]: PlatformConfig; + [name: string]: PlatformConfig | void; }; commands: Command[]; haste: { @@ -155,10 +157,28 @@ export type UserConfig = Omit & { }; }; -export type UserDependencyConfig = Omit< - Config, - 'root' | 'reactNativePath' | 'project' | 'assets' ->; +export type UserDependencyConfig = { + // Additional dependency settings + dependency: { + platforms: { + android?: AndroidDependencyParams; + ios?: IOSDependencyParams; + [key: string]: any; + }; + assets: string[]; + hooks: Dependency['hooks']; + params: InquirerPrompt[]; + }; + // An array of commands that ship with the dependency + commands: Command[]; + // An array of extra platforms to load + platforms: Config['platforms']; + // Haste config defined by legacy `rnpm` + haste?: { + platforms: string[]; + providesModuleNodeModules: string[]; + }; +}; export { IOSProjectConfig, diff --git a/packages/cli-types/src/ios.ts b/packages/cli-types/src/ios.ts index 173f2116d..7129dffd3 100644 --- a/packages/cli-types/src/ios.ts +++ b/packages/cli-types/src/ios.ts @@ -10,7 +10,7 @@ export interface IOSProjectParams { sharedLibraries?: string[]; libraryFolder?: string; plist: Array; - scriptPhases: Array; + scriptPhases?: Array; } export interface IOSDependencyParams extends IOSProjectParams {} diff --git a/packages/cli/src/cliEntry.js b/packages/cli/src/cliEntry.js index 062960709..f65fc8558 100644 --- a/packages/cli/src/cliEntry.js +++ b/packages/cli/src/cliEntry.js @@ -23,6 +23,7 @@ import {logger} from '@react-native-community/cli-tools'; // $FlowFixMe - converted to TS import {setProjectDir} from './tools/packageManager'; import pkgJson from '../package.json'; +// $FlowFixMe - converted to TS import loadConfig from './tools/config'; commander diff --git a/packages/cli/src/commands/install/install.ts b/packages/cli/src/commands/install/install.ts index fcf95ab69..df74364d0 100644 --- a/packages/cli/src/commands/install/install.ts +++ b/packages/cli/src/commands/install/install.ts @@ -7,9 +7,9 @@ */ import {logger} from '@react-native-community/cli-tools'; import * as PackageManager from '../../tools/packageManager'; -import link from '../link/link'; -// @ts-ignore FIXME after converting tools/config -import loadConfig from '../../tools/config'; // eslint-disable-line import/namespace, import/default +// @ts-ignore FIXME after converting link/link +import link from '../link/link'; // eslint-disable-line import/namespace, import/default +import loadConfig from '../../tools/config'; async function install(args: Array): Promise { const name = args[0]; diff --git a/packages/cli/src/tools/config/__mocks__/index.js b/packages/cli/src/tools/config/__mocks__/index.ts similarity index 96% rename from packages/cli/src/tools/config/__mocks__/index.js rename to packages/cli/src/tools/config/__mocks__/index.ts index 78f27628a..08a213a9a 100644 --- a/packages/cli/src/tools/config/__mocks__/index.js +++ b/packages/cli/src/tools/config/__mocks__/index.ts @@ -1,7 +1,3 @@ -/** - * @flow - */ - export default function mockedLoadConfig() { return { root: '/project/root', diff --git a/packages/cli/src/tools/config/__mocks__/resolveNodeModuleDir.js b/packages/cli/src/tools/config/__mocks__/resolveNodeModuleDir.ts similarity index 91% rename from packages/cli/src/tools/config/__mocks__/resolveNodeModuleDir.js rename to packages/cli/src/tools/config/__mocks__/resolveNodeModuleDir.ts index d85dee2ae..6b739df3d 100644 --- a/packages/cli/src/tools/config/__mocks__/resolveNodeModuleDir.js +++ b/packages/cli/src/tools/config/__mocks__/resolveNodeModuleDir.ts @@ -1,7 +1,3 @@ -/** - * @flow - */ - const path = require('path'); export default function resolveNodeModuleDir( diff --git a/packages/cli/src/tools/config/__tests__/findAssets-test.ts b/packages/cli/src/tools/config/__tests__/findAssets-test.ts index 8c4581ebb..a6387ce8f 100644 --- a/packages/cli/src/tools/config/__tests__/findAssets-test.ts +++ b/packages/cli/src/tools/config/__tests__/findAssets-test.ts @@ -32,7 +32,7 @@ describe('findAssets', () => { it('returns an array of all files in given folders', () => { const assets = findAssets('/testDir', ['fonts', 'images']); - + expect(Array.isArray(assets)).toBeTruthy(); expect(assets).toHaveLength(3); }); diff --git a/packages/cli/src/tools/config/index.ts b/packages/cli/src/tools/config/index.ts index 6458ef99f..a3e24b963 100644 --- a/packages/cli/src/tools/config/index.ts +++ b/packages/cli/src/tools/config/index.ts @@ -1,5 +1,9 @@ import path from 'path'; import chalk from 'chalk'; +import { + UserDependencyConfig, + ProjectConfig, +} from '@react-native-community/cli-types'; import {logger, inlineString} from '@react-native-community/cli-tools'; import * as ios from '@react-native-community/cli-platform-ios'; import * as android from '@react-native-community/cli-platform-android'; @@ -13,11 +17,7 @@ import { import assign from '../assign'; import merge from '../merge'; import resolveNodeModuleDir from './resolveNodeModuleDir'; -import { - UserConfig, - Config -} from '../../../../cli-types'; -import {UserDependencyConfig} from '@react-native-community/cli-types/src'; +import {UserConfig, Config} from '../../../../cli-types'; function getDependencyConfig( root: string, @@ -26,7 +26,7 @@ function getDependencyConfig( config: UserDependencyConfig, userConfig: UserConfig, isPlatform: boolean, -): UserDependencyConfig | void{ +): UserDependencyConfig { return merge( { root, @@ -59,8 +59,8 @@ function getDependencyConfig( /** * Loads CLI configuration */ -function loadConfig(projectRoot: string = process.cwd()): Config | void{ - let lazyProject; +function loadConfig(projectRoot: string = process.cwd()): Config | void { + let lazyProject: ProjectConfig; const userConfig = readConfigFromDisk(projectRoot); const initialConfig: Config = { @@ -97,7 +97,7 @@ function loadConfig(projectRoot: string = process.cwd()): Config | void{ }, }; - let depsWithWarnings = []; + let depsWithWarnings: Array<[string, string]> = []; const finalConfig = Array.from( new Set([ @@ -108,8 +108,8 @@ function loadConfig(projectRoot: string = process.cwd()): Config | void{ const localDependencyRoot = userConfig.dependencies[dependencyName] && userConfig.dependencies[dependencyName].root; - let root; - let config; + let root: string; + let config: UserDependencyConfig; try { root = localDependencyRoot || @@ -161,10 +161,9 @@ function loadConfig(projectRoot: string = process.cwd()): Config | void{ platforms: Object.keys(config.platforms), }; - return (assign({}, acc, { + return assign({}, acc, { dependencies: assign({}, acc.dependencies, { - // $FlowExpectedError: Dynamic getters are not supported - get [dependencyName]() { + get [dependencyName](): UserDependencyConfig { return getDependencyConfig( root, dependencyName, @@ -187,7 +186,7 @@ function loadConfig(projectRoot: string = process.cwd()): Config | void{ ], platforms: [...acc.haste.platforms, ...haste.platforms], }, - }): Config); + }) as Config; }, initialConfig); if (depsWithWarnings.length) { diff --git a/packages/cli/src/tools/config/readConfigFromDisk.ts b/packages/cli/src/tools/config/readConfigFromDisk.ts index b9e2b03cc..55a50bd84 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.ts +++ b/packages/cli/src/tools/config/readConfigFromDisk.ts @@ -34,7 +34,6 @@ type LegacyDependencyConfig = { plugin: Array; params: InquirerPrompt[]; haste: any; - commands: Command[]; }; /** @@ -56,18 +55,20 @@ function readLegacyConfigFromDisk(rootFolder: string): UserConfig | void { return undefined; } - const reactNativePath = config.reactNativePath - ? path.resolve(rootFolder, config.reactNativePath) - : resolveReactNativePath(rootFolder); - const transformedConfig: UserConfig = { - reactNativePath: reactNativePath, project: { android: config.android, ios: config.ios, }, assets: config.assets, commands: [], + dependencies: {}, + platforms: {}, + get reactNativePath() { + return config.reactNativePath + ? path.resolve(rootFolder, config.reactNativePath) + : resolveReactNativePath(rootFolder); + }, }; logger.warn( @@ -158,20 +159,14 @@ function readLegacyDependencyConfigFromDisk( // package.json is usually missing in local libraries that are not in // project "dependencies", so we just return a bare config return { - assets: [], - dependencies: { - dep: { - name: '', - root: '', - platforms: {}, - assets: null, - hooks: null, - params: null, - }, + dependency: { + platforms: {}, + assets: [], + hooks: {}, + params: [], }, - platforms: null, commands: [], - haste: null, + platforms: {}, }; } @@ -179,27 +174,21 @@ function readLegacyDependencyConfigFromDisk( return undefined; } - const platforms = config.platform - ? require(path.join(rootFolder, config.platform)) - : {}; const transformedConfig: UserDependencyConfig = { - assets: [], - dependencies: { - dep: { - name: '', - root: '', - platforms: { - android: config.android, - ios: config.ios, - }, - assets: config.assets, - hooks: config.commands, - params: config.params, + dependency: { + platforms: { + ios: config.ios, + android: config.android, }, + assets: config.assets, + hooks: config.commands, + params: config.params, }, - platforms: platforms, - commands: loadProjectCommands(rootFolder, ...config.plugin), haste: config.haste, + commands: loadProjectCommands(rootFolder, ...config.plugin), + platforms: config.platform + ? require(path.join(rootFolder, config.platform)) + : {}, }; return transformedConfig; diff --git a/packages/cli/src/tools/merge.ts b/packages/cli/src/tools/merge.ts index cf4817ba2..e4305529c 100644 --- a/packages/cli/src/tools/merge.ts +++ b/packages/cli/src/tools/merge.ts @@ -4,10 +4,7 @@ import deepmerge from 'deepmerge'; * `deepmerge` concatenates arrays by default instead of overwriting them. * We define custom merging function for arrays to change that behaviour */ -export default function merge( - x: Array<{[key: string]: any}>, - y: Array<{[key: string]: any}>, -) { +export default function merge(x: X, y: Y) { return deepmerge(x, y, { arrayMerge: (_destinationArray: any[], sourceArray: any[]): any[] => sourceArray, From f72daf5206f2a0474f6b3839d8be69fad5587912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Mon, 16 Sep 2019 10:39:48 +0200 Subject: [PATCH 09/15] fixups --- packages/cli-types/src/index.ts | 25 +++--------- packages/cli/src/tools/config/findAssets.ts | 7 ++-- packages/cli/src/tools/config/index.ts | 27 ++++++++----- .../src/tools/config/readConfigFromDisk.ts | 39 +++++++++++-------- .../src/link/common/registerNativeModule.ts | 3 +- 5 files changed, 51 insertions(+), 50 deletions(-) diff --git a/packages/cli-types/src/index.ts b/packages/cli-types/src/index.ts index 648d92462..ae442dbfd 100644 --- a/packages/cli-types/src/index.ts +++ b/packages/cli-types/src/index.ts @@ -117,19 +117,19 @@ export type Config = { assets: string[]; dependencies: {[key: string]: Dependency}; platforms: { - android?: PlatformConfig< + android: PlatformConfig< AndroidProjectConfig, AndroidProjectParams, AndroidDependencyConfig, AndroidDependencyParams >; - ios?: PlatformConfig< + ios: PlatformConfig< IOSProjectConfig, IOSProjectParams, IOSDependencyConfig, IOSDependencyParams >; - [name: string]: PlatformConfig | void; + [name: string]: PlatformConfig; }; commands: Command[]; haste: { @@ -139,16 +139,12 @@ export type Config = { }; /** - * Shares some structure with ConfigT, except that haste and root + * Shares some structure with Config, except that haste and root * are calculated and can't be defined */ -// For Omit, see https://devblogs.microsoft.com/typescript/announcing-typescript-3-5/#the-omit-helper-type -// export interface UserConfig -// extends Omit, 'haste'>, 'root'> {} -export type UserConfig = Omit & { +export type UserConfig = Omit, 'haste'> & { reactNativePath: string | void; - // Additional project settings project: { android?: AndroidProjectParams; @@ -159,16 +155,7 @@ export type UserConfig = Omit & { export type UserDependencyConfig = { // Additional dependency settings - dependency: { - platforms: { - android?: AndroidDependencyParams; - ios?: IOSDependencyParams; - [key: string]: any; - }; - assets: string[]; - hooks: Dependency['hooks']; - params: InquirerPrompt[]; - }; + dependency: Omit, 'root'>; // An array of commands that ship with the dependency commands: Command[]; // An array of extra platforms to load diff --git a/packages/cli/src/tools/config/findAssets.ts b/packages/cli/src/tools/config/findAssets.ts index e1dad8010..54394ddf2 100644 --- a/packages/cli/src/tools/config/findAssets.ts +++ b/packages/cli/src/tools/config/findAssets.ts @@ -21,7 +21,8 @@ export default function findAssets( ): Array { return (assets || []) .map(asset => path.join(folder, asset)) - .reduce((acc: string[], assetPath: string) => { - return acc.concat(findAssetsInFolder(assetPath)); - }, []); + .reduce( + (acc, assetPath) => acc.concat(findAssetsInFolder(assetPath)), + [] as string[], + ); } diff --git a/packages/cli/src/tools/config/index.ts b/packages/cli/src/tools/config/index.ts index a3e24b963..f5b1f1ca2 100644 --- a/packages/cli/src/tools/config/index.ts +++ b/packages/cli/src/tools/config/index.ts @@ -3,6 +3,9 @@ import chalk from 'chalk'; import { UserDependencyConfig, ProjectConfig, + Dependency, + UserConfig, + Config, } from '@react-native-community/cli-types'; import {logger, inlineString} from '@react-native-community/cli-tools'; import * as ios from '@react-native-community/cli-platform-ios'; @@ -17,7 +20,6 @@ import { import assign from '../assign'; import merge from '../merge'; import resolveNodeModuleDir from './resolveNodeModuleDir'; -import {UserConfig, Config} from '../../../../cli-types'; function getDependencyConfig( root: string, @@ -26,7 +28,7 @@ function getDependencyConfig( config: UserDependencyConfig, userConfig: UserConfig, isPlatform: boolean, -): UserDependencyConfig { +): Dependency { return merge( { root, @@ -46,20 +48,20 @@ function getDependencyConfig( ); return dependency; }, - {}, + {} as Config['platforms'], ), assets: findAssets(root, config.dependency.assets), hooks: config.dependency.hooks, params: config.dependency.params, }, userConfig.dependencies[dependencyName] || {}, - ); + ) as Dependency; } /** * Loads CLI configuration */ -function loadConfig(projectRoot: string = process.cwd()): Config | void { +function loadConfig(projectRoot: string = process.cwd()): Config { let lazyProject: ProjectConfig; const userConfig = readConfigFromDisk(projectRoot); @@ -87,10 +89,13 @@ function loadConfig(projectRoot: string = process.cwd()): Config | void { lazyProject = {}; for (const platform in finalConfig.platforms) { - lazyProject[platform] = finalConfig.platforms[platform].projectConfig( - projectRoot, - userConfig.project[platform] || {}, - ); + const platformConfig = finalConfig.platforms[platform]; + if (platformConfig) { + lazyProject[platform] = platformConfig.projectConfig( + projectRoot, + userConfig.project[platform] || {}, + ); + } } return lazyProject; @@ -141,9 +146,11 @@ function loadConfig(projectRoot: string = process.cwd()): Config | void { */ if (dependencyName === 'react-native') { if (Object.keys(config.platforms).length === 0) { + // @ts-ignore - this code is soon going to be removed config.platforms = {ios, android}; } if (config.commands.length === 0) { + // @ts-ignore - this code is soon going to be removed config.commands = [...ios.commands, ...android.commands]; } } @@ -163,7 +170,7 @@ function loadConfig(projectRoot: string = process.cwd()): Config | void { return assign({}, acc, { dependencies: assign({}, acc.dependencies, { - get [dependencyName](): UserDependencyConfig { + get [dependencyName](): Dependency { return getDependencyConfig( root, dependencyName, diff --git a/packages/cli/src/tools/config/readConfigFromDisk.ts b/packages/cli/src/tools/config/readConfigFromDisk.ts index 55a50bd84..2fff23f9f 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.ts +++ b/packages/cli/src/tools/config/readConfigFromDisk.ts @@ -9,12 +9,13 @@ import resolveReactNativePath from './resolveReactNativePath'; import { UserConfig, AndroidProjectConfig, + AndroidDependencyConfig, IOSProjectConfig, + IOSDependencyConfig, Command, InquirerPrompt, -} from '../../../../cli-types'; - -import {UserDependencyConfig} from '@react-native-community/cli-types/src'; + UserDependencyConfig, +} from '@react-native-community/cli-types'; const MIGRATION_GUIDE = `Migration guide: ${chalk.dim.underline( 'https://github.com/react-native-community/cli/blob/master/docs/configuration.md', )}`; @@ -24,12 +25,15 @@ type LegacyConfig = { android: AndroidProjectConfig; assets: string[]; reactNativePath: string; + hooks?: { + [key: string]: string; + }; }; type LegacyDependencyConfig = { platform: any; - ios: IOSProjectConfig; - android: AndroidProjectConfig; + ios: IOSDependencyConfig; + android: AndroidDependencyConfig; assets: string[]; plugin: Array; params: InquirerPrompt[]; @@ -63,6 +67,7 @@ function readLegacyConfigFromDisk(rootFolder: string): UserConfig | void { assets: config.assets, commands: [], dependencies: {}, + // @ts-ignore - TODO: platforms can be empty, adjust types platforms: {}, get reactNativePath() { return config.reactNativePath @@ -113,11 +118,11 @@ export function readDependencyConfigFromDisk( stopDir: rootFolder, searchPlaces, }); - const config: cosmiconfig.CosmiconfigResult = explorer.searchSync(rootFolder); + const config = explorer.searchSync(rootFolder); const legacy = config ? true : false; // @ts-ignore Joi validate the type const dependencyConfig: UserDependencyConfig = config - ? (config.config as UserDependencyConfig) + ? config.config : readLegacyDependencyConfigFromDisk(rootFolder); const result = Joi.validate(config, schema.dependencyConfig); @@ -129,12 +134,12 @@ export function readDependencyConfigFromDisk( return {config: dependencyConfig, legacy: legacy && config !== undefined}; } -// /** -// * Returns an array of commands that are defined in the project. -// * -// * `config.project` can be either an array of paths or a single string. -// * Each of the files can export a commands (object) or an array of commands -// */ +/** + * Returns an array of commands that are defined in the project. + * + * `config.project` can be either an array of paths or a single string. + * Each of the files can export a commands (object) or an array of commands + */ const loadProjectCommands = ( root: string, ...commands: string[] @@ -145,9 +150,9 @@ const loadProjectCommands = ( }, []); }; -// /** -// * Reads a legacy configuration from a `package.json` "rnpm" key. -// */ +/** + * Reads a legacy configuration from a `package.json` "rnpm" key. + */ function readLegacyDependencyConfigFromDisk( rootFolder: string, ): UserDependencyConfig | undefined { @@ -158,6 +163,7 @@ function readLegacyDependencyConfigFromDisk( } catch (error) { // package.json is usually missing in local libraries that are not in // project "dependencies", so we just return a bare config + // @ts-ignore - TODO: platforms can be empty, adjust types return { dependency: { platforms: {}, @@ -181,6 +187,7 @@ function readLegacyDependencyConfigFromDisk( android: config.android, }, assets: config.assets, + // @ts-ignore – likely a bug, but we don't care because legacy config is soon to be removed hooks: config.commands, params: config.params, }, diff --git a/packages/platform-ios/src/link/common/registerNativeModule.ts b/packages/platform-ios/src/link/common/registerNativeModule.ts index e5b26f1ad..8b2d21b94 100644 --- a/packages/platform-ios/src/link/common/registerNativeModule.ts +++ b/packages/platform-ios/src/link/common/registerNativeModule.ts @@ -17,8 +17,7 @@ export default function registerNativeModule( name: string, dependencyConfig: IOSDependencyConfig, // FIXME: Params is never used - _params?: any, - // @ts-ignore + _params: any | undefined, projectConfig: IOSProjectConfig, ) { if (projectConfig.podfile && dependencyConfig.podspecPath) { From d679560f5607b1d36c22b61fe94ce7bb422b51cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Mon, 16 Sep 2019 10:44:18 +0200 Subject: [PATCH 10/15] eslint fix --- packages/cli/src/commands/info/__tests__/info.test.ts | 1 - packages/cli/src/commands/upgrade/__tests__/upgrade.test.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/cli/src/commands/info/__tests__/info.test.ts b/packages/cli/src/commands/info/__tests__/info.test.ts index 6635182e7..a888126d1 100644 --- a/packages/cli/src/commands/info/__tests__/info.test.ts +++ b/packages/cli/src/commands/info/__tests__/info.test.ts @@ -1,7 +1,6 @@ // @flow import info from '../info'; import {logger} from '@react-native-community/cli-tools'; -// eslint-disable-next-line import/namespace, import/default import loadConfig from '../../../tools/config'; jest.mock('../../../tools/config'); diff --git a/packages/cli/src/commands/upgrade/__tests__/upgrade.test.ts b/packages/cli/src/commands/upgrade/__tests__/upgrade.test.ts index ec9a01af8..4a090e5d1 100644 --- a/packages/cli/src/commands/upgrade/__tests__/upgrade.test.ts +++ b/packages/cli/src/commands/upgrade/__tests__/upgrade.test.ts @@ -5,7 +5,7 @@ import snapshotDiff from 'snapshot-diff'; import stripAnsi from 'strip-ansi'; import upgrade from '../upgrade'; import {fetch, logger} from '@react-native-community/cli-tools'; -import loadConfig from '../../../tools/config'; // eslint-disable-line import/namespace, import/default +import loadConfig from '../../../tools/config'; import merge from '../../../tools/merge'; jest.mock('https'); From 8d0ab68e3dd0b16888db8f4a41699d33485c16ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 18 Sep 2019 22:07:09 +0200 Subject: [PATCH 11/15] fixups --- packages/cli/src/commands/install/install.ts | 3 +- .../__snapshots__/index-test.js.snap | 218 ---------------- .../__snapshots__/index-test.ts.snap | 234 ++++++++++++++++++ packages/cli/src/tools/config/errors.ts | 2 +- .../src/tools/config/readConfigFromDisk.ts | 22 +- 5 files changed, 248 insertions(+), 231 deletions(-) delete mode 100644 packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap create mode 100644 packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap diff --git a/packages/cli/src/commands/install/install.ts b/packages/cli/src/commands/install/install.ts index df74364d0..6f3a8fbce 100644 --- a/packages/cli/src/commands/install/install.ts +++ b/packages/cli/src/commands/install/install.ts @@ -7,8 +7,7 @@ */ import {logger} from '@react-native-community/cli-tools'; import * as PackageManager from '../../tools/packageManager'; -// @ts-ignore FIXME after converting link/link -import link from '../link/link'; // eslint-disable-line import/namespace, import/default +import link from '../link/link'; import loadConfig from '../../tools/config'; async function install(args: Array): Promise { diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap deleted file mode 100644 index 89f237697..000000000 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap +++ /dev/null @@ -1,218 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should automatically put "react-native" into haste config 1`] = ` -Object { - "platforms": Array [ - "ios", - "android", - ], - "providesModuleNodeModules": Array [ - "react-native", - ], -} -`; - -exports[`should handle deprecated "rnpm" in project root: returns valid config 1`] = ` -Object { - "assets": Array [ - "<>/fonts/SampleFont.ttf", - ], - "commands": Array [], - "dependencies": Object {}, - "haste": Object { - "platforms": Array [], - "providesModuleNodeModules": Array [], - }, - "platforms": Object {}, - "project": Object {}, - "reactNativePath": "<>/node_modules/react-native", - "root": "<>", -} -`; - -exports[`should have a valid structure by default 1`] = ` -Object { - "assets": Array [], - "commands": Array [], - "dependencies": Object {}, - "haste": Object { - "platforms": Array [], - "providesModuleNodeModules": Array [], - }, - "platforms": Object {}, - "project": Object {}, - "reactNativePath": "<>", - "root": "<>", -} -`; - -exports[`should load an out-of-tree "windows" platform that ships with a dependency 1`] = ` -Object { - "haste": Object { - "platforms": Array [ - "windows", - ], - "providesModuleNodeModules": Array [ - "react-native-windows", - ], - }, - "platforms": Object { - "windows": Object {}, - }, -} -`; - -exports[`should load commands from "react-native-foo" and "react-native-bar" packages 1`] = ` -Array [ - Object { - "func": [Function], - "name": "foo-command", - }, - Object { - "func": [Function], - "name": "bar-command", - }, -] -`; - -exports[`should merge project configuration with default values: snapshoting \`react-native-test\` config 1`] = ` -Object { - "assets": Array [ - "foo", - ], - "hooks": Object {}, - "name": "react-native-test", - "params": Array [], - "platforms": Object { - "android": null, - "ios": Object { - "folder": "<>/node_modules/react-native-test", - "libraryFolder": "Libraries", - "pbxprojPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj/project.pbxproj", - "plist": Array [], - "podfile": null, - "podspecPath": null, - "projectName": "HelloWorld.xcodeproj", - "projectPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj", - "scriptPhases": Array [], - "sharedLibraries": Array [], - "sourceDir": "./abc", - }, - }, - "root": "<>/node_modules/react-native-test", -} -`; - -exports[`should not add default React Native config when one present 1`] = ` -Array [ - Object { - "func": [Function], - "name": "test", - }, -] -`; - -exports[`should read \`rnpm\` config from a dependency and transform it to a new format: foo config 1`] = ` -Object { - "assets": Array [], - "hooks": Object {}, - "name": "react-native-foo", - "params": Array [], - "platforms": Object { - "android": null, - "ios": Object { - "folder": "<>/node_modules/react-native-foo", - "libraryFolder": "Libraries", - "pbxprojPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj/project.pbxproj", - "plist": Array [], - "podfile": null, - "podspecPath": null, - "projectName": "customProject.xcodeproj", - "projectPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj", - "scriptPhases": Array [], - "sharedLibraries": Array [], - "sourceDir": "<>/node_modules/react-native-foo/customLocation", - }, - }, - "root": "<>/node_modules/react-native-foo", -} -`; - -exports[`should read \`rnpm\` config from a dependency and transform it to a new format: haste config 1`] = ` -Object { - "platforms": Array [ - "ios", - "android", - "dummy", - ], - "providesModuleNodeModules": Array [ - "react-native", - "react-native-dummy", - ], -} -`; - -exports[`should read a config of a dependency and use it to load other settings 1`] = ` -Object { - "assets": Array [], - "hooks": Object {}, - "name": "react-native-test", - "params": Array [], - "platforms": Object { - "android": null, - "ios": Object { - "folder": "<>/node_modules/react-native-test", - "libraryFolder": "Libraries", - "pbxprojPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj/project.pbxproj", - "plist": Array [], - "podfile": null, - "podspecPath": "<>/node_modules/react-native-test/ReactNativeTest.podspec", - "projectName": "customProject.xcodeproj", - "projectPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj", - "scriptPhases": Array [], - "sharedLibraries": Array [], - "sourceDir": "<>/node_modules/react-native-test/customLocation", - }, - }, - "root": "<>/node_modules/react-native-test", -} -`; - -exports[`should return dependencies from package.json 1`] = ` -Object { - "react-native": Object { - "assets": Array [], - "hooks": Object {}, - "name": "react-native", - "params": Array [], - "platforms": Object { - "android": null, - "ios": null, - }, - "root": "<>/node_modules/react-native", - }, - "react-native-test": Object { - "assets": Array [], - "hooks": Object {}, - "name": "react-native-test", - "params": Array [], - "platforms": Object { - "android": null, - "ios": Object { - "folder": "<>/node_modules/react-native-test", - "libraryFolder": "Libraries", - "pbxprojPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj/project.pbxproj", - "plist": Array [], - "podfile": null, - "podspecPath": null, - "projectName": "HelloWorld.xcodeproj", - "projectPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj", - "scriptPhases": Array [], - "sharedLibraries": Array [], - "sourceDir": "<>/node_modules/react-native-test/ios", - }, - }, - "root": "<>/node_modules/react-native-test", - }, -} -`; diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap new file mode 100644 index 000000000..41ca82c70 --- /dev/null +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap @@ -0,0 +1,234 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should automatically put "react-native" into haste config 1`] = ` +Object { + "platforms": Array [], + "providesModuleNodeModules": Array [], +} +`; + +exports[`should handle deprecated "rnpm" in project root: returns valid config 1`] = ` +Object { + "assets": Array [ + "<>/fonts/SampleFont.ttf", + ], + "commands": Array [], + "dependencies": Object {}, + "haste": Object { + "platforms": Array [], + "providesModuleNodeModules": Array [], + }, + "platforms": Object {}, + "project": Object {}, + "reactNativePath": "<>/node_modules/react-native", + "root": "<>", +} +`; + +exports[`should have a valid structure by default 1`] = ` +Object { + "assets": Array [], + "commands": Array [], + "dependencies": Object {}, + "haste": Object { + "platforms": Array [], + "providesModuleNodeModules": Array [], + }, + "platforms": Object {}, + "project": Object {}, + "reactNativePath": "<>", + "root": "<>", +} +`; + +exports[`should load an out-of-tree "windows" platform that ships with a dependency 1`] = ` +Object { + "haste": Object { + "platforms": Array [], + "providesModuleNodeModules": Array [], + }, + "platforms": Object {}, +} +`; + +exports[`should load commands from "react-native-foo" and "react-native-bar" packages 1`] = `Array []`; + +exports[`should merge project configuration with default values: snapshoting \`react-native-test\` config 1`] = ` +Object { + "assets": Array [ + "foo", + ], + "hooks": Object {}, + "name": "react-native-test", + "params": Array [], + "platforms": Object { + "ios": Object { + "sourceDir": "./abc", + }, + }, + "root": "<>/node_modules/react-native-test", +} +`; + +exports[`should not add default React Native config when one present 1`] = ` +Array [ + Object { + "description": "starts iOS device syslog tail", + "func": [Function], + "name": "log-ios", + }, + Object { + "description": "builds your app and starts it on iOS simulator", + "examples": Array [ + Object { + "cmd": "react-native run-ios --simulator \\"iPhone 5\\"", + "desc": "Run on a different simulator, e.g. iPhone 5", + }, + Object { + "cmd": "react-native run-ios --project-path \\"./app/ios\\"", + "desc": "Pass a non-standard location of iOS directory", + }, + Object { + "cmd": "react-native run-ios --device \\"Max's iPhone\\"", + "desc": "Run on a connected device, e.g. Max's iPhone", + }, + Object { + "cmd": "react-native run-ios --simulator \\"Apple TV\\" --scheme \\"helloworld-tvOS\\"", + "desc": "Run on the AppleTV simulator", + }, + ], + "func": [Function], + "name": "run-ios", + "options": Array [ + Object { + "default": "iPhone X", + "description": "Explicitly set simulator to use. Optionally include iOS version betweenparenthesis at the end to match an exact version: \\"iPhone 6 (10.0)\\"", + "name": "--simulator [string]", + }, + Object { + "default": "Debug", + "description": "Explicitly set the scheme configuration to use", + "name": "--configuration [string]", + }, + Object { + "description": "Explicitly set Xcode scheme to use", + "name": "--scheme [string]", + }, + Object { + "default": "ios", + "description": "Path relative to project root where the Xcode project (.xcodeproj) lives.", + "name": "--project-path [string]", + }, + Object { + "description": "Explicitly set device to use by name. The value is not required if you have a single device connected.", + "name": "--device [string]", + }, + Object { + "description": "Explicitly set device to use by udid", + "name": "--udid [string]", + }, + Object { + "description": "Do not launch packager while building", + "name": "--no-packager", + }, + Object { + "description": "Do not use xcpretty even if installed", + "name": "--verbose", + }, + Object { + "default": 8081, + "name": "--port [number]", + "parse": [Function], + }, + Object { + "default": [Function], + "description": "Launches the Metro Bundler in a new window using the specified terminal path.", + "name": "--terminal [string]", + }, + ], + }, + Object { + "description": "starts logkitty", + "func": [Function], + "name": "log-android", + }, + Object { + "description": "builds your app and starts it on a connected Android emulator or device", + "func": [Function], + "name": "run-android", + "options": Array [ + Object { + "default": "", + "description": "Override the root directory for the android build (which contains the android directory)", + "name": "--root [string]", + }, + Object { + "default": "debug", + "description": "Specify your app's build variant", + "name": "--variant [string]", + }, + Object { + "default": "app", + "description": "Specify a different application folder name for the android source. If not, we assume is \\"app\\"", + "name": "--appFolder [string]", + }, + Object { + "default": "", + "description": "Specify an applicationId to launch after build.", + "name": "--appId [string]", + }, + Object { + "default": "", + "description": "Specify an applicationIdSuffix to launch after build.", + "name": "--appIdSuffix [string]", + }, + Object { + "default": "MainActivity", + "description": "Name of the activity to start", + "name": "--main-activity [string]", + }, + Object { + "description": "builds your app and starts it on a specific device/simulator with the given device id (listed by running \\"adb devices\\" on the command line).", + "name": "--deviceId [string]", + }, + Object { + "description": "Do not launch packager while building", + "name": "--no-packager", + }, + Object { + "default": 8081, + "name": "--port [number]", + "parse": [Function], + }, + Object { + "default": "iTerm.app", + "description": "Launches the Metro Bundler in a new window using the specified terminal path.", + "name": "--terminal [string]", + }, + Object { + "description": "Run custom Gradle tasks. By default it's \\"installDebug\\"", + "name": "--tasks [list]", + "parse": [Function], + }, + Object { + "default": false, + "description": "Do not run \\"jetifier\\" – the AndroidX transition tool. By default it runs before Gradle to ease working with libraries that don't support AndroidX yet. See more at: https://www.npmjs.com/package/jetifier.", + "name": "--no-jetifier", + }, + ], + }, +] +`; + +exports[`should read a config of a dependency and use it to load other settings 1`] = ` +Object { + "assets": Array [], + "hooks": Object {}, + "name": "react-native-test", + "params": Array [], + "platforms": Object {}, + "root": "<>/node_modules/react-native-test", +} +`; + +exports[`should return dependencies from package.json 1`] = `Object {}`; diff --git a/packages/cli/src/tools/config/errors.ts b/packages/cli/src/tools/config/errors.ts index c3e789543..d3409befb 100644 --- a/packages/cli/src/tools/config/errors.ts +++ b/packages/cli/src/tools/config/errors.ts @@ -10,7 +10,7 @@ export class JoiError extends CLIError { switch (error.type) { case 'object.allowUnknown': { const value = JSON.stringify( - error.context && error.context.label, + error.context && error.context.value, ); return ` Unknown option ${name} with value "${value}" was found. diff --git a/packages/cli/src/tools/config/readConfigFromDisk.ts b/packages/cli/src/tools/config/readConfigFromDisk.ts index 2fff23f9f..1f58ba267 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.ts +++ b/packages/cli/src/tools/config/readConfigFromDisk.ts @@ -61,8 +61,8 @@ function readLegacyConfigFromDisk(rootFolder: string): UserConfig | void { const transformedConfig: UserConfig = { project: { - android: config.android, ios: config.ios, + android: config.android, }, assets: config.assets, commands: [], @@ -104,7 +104,7 @@ export function readConfigFromDisk(rootFolder: string): UserConfig { throw new JoiError(result.error); } - return config as UserConfig; + return result.value as UserConfig; } /** @@ -118,12 +118,14 @@ export function readDependencyConfigFromDisk( stopDir: rootFolder, searchPlaces, }); - const config = explorer.searchSync(rootFolder); - const legacy = config ? true : false; - // @ts-ignore Joi validate the type - const dependencyConfig: UserDependencyConfig = config - ? config.config - : readLegacyDependencyConfigFromDisk(rootFolder); + // @ts-ignore + let config: UserDependencyConfig = explorer.searchSync(rootFolder); + const legacy = !!config; + + if (legacy) { + // @ts-ignore TODO: legacy config can be undefined + config = readLegacyDependencyConfigFromDisk(rootFolder); + } const result = Joi.validate(config, schema.dependencyConfig); @@ -131,7 +133,7 @@ export function readDependencyConfigFromDisk( throw new JoiError(result.error); } - return {config: dependencyConfig, legacy: legacy && config !== undefined}; + return {config: result.value, legacy: legacy && config !== undefined}; } /** @@ -156,7 +158,7 @@ const loadProjectCommands = ( function readLegacyDependencyConfigFromDisk( rootFolder: string, ): UserDependencyConfig | undefined { - let config: LegacyDependencyConfig; + let config = {} as LegacyDependencyConfig; try { config = require(path.join(rootFolder, 'package.json')).rnpm; From 7402f0dab351ff8ce07b9acf51d7acdabd44ef88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 18 Sep 2019 22:22:38 +0200 Subject: [PATCH 12/15] another fixups --- .../__snapshots__/index-test.ts.snap | 232 +++++++----------- .../src/tools/config/readConfigFromDisk.ts | 12 +- 2 files changed, 90 insertions(+), 154 deletions(-) diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap index 41ca82c70..2dbfc00fc 100644 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap @@ -2,8 +2,13 @@ exports[`should automatically put "react-native" into haste config 1`] = ` Object { - "platforms": Array [], - "providesModuleNodeModules": Array [], + "platforms": Array [ + "ios", + "android", + ], + "providesModuleNodeModules": Array [ + "react-native", + ], } `; @@ -51,7 +56,18 @@ Object { } `; -exports[`should load commands from "react-native-foo" and "react-native-bar" packages 1`] = `Array []`; +exports[`should load commands from "react-native-foo" and "react-native-bar" packages 1`] = ` +Array [ + Object { + "func": [Function], + "name": "foo-command", + }, + Object { + "func": [Function], + "name": "bar-command", + }, +] +`; exports[`should merge project configuration with default values: snapshoting \`react-native-test\` config 1`] = ` Object { @@ -62,7 +78,18 @@ Object { "name": "react-native-test", "params": Array [], "platforms": Object { + "android": null, "ios": Object { + "folder": "<>/node_modules/react-native-test", + "libraryFolder": "Libraries", + "pbxprojPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj/project.pbxproj", + "plist": Array [], + "podfile": null, + "podspecPath": null, + "projectName": "HelloWorld.xcodeproj", + "projectPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj", + "scriptPhases": Array [], + "sharedLibraries": Array [], "sourceDir": "./abc", }, }, @@ -73,149 +100,8 @@ Object { exports[`should not add default React Native config when one present 1`] = ` Array [ Object { - "description": "starts iOS device syslog tail", - "func": [Function], - "name": "log-ios", - }, - Object { - "description": "builds your app and starts it on iOS simulator", - "examples": Array [ - Object { - "cmd": "react-native run-ios --simulator \\"iPhone 5\\"", - "desc": "Run on a different simulator, e.g. iPhone 5", - }, - Object { - "cmd": "react-native run-ios --project-path \\"./app/ios\\"", - "desc": "Pass a non-standard location of iOS directory", - }, - Object { - "cmd": "react-native run-ios --device \\"Max's iPhone\\"", - "desc": "Run on a connected device, e.g. Max's iPhone", - }, - Object { - "cmd": "react-native run-ios --simulator \\"Apple TV\\" --scheme \\"helloworld-tvOS\\"", - "desc": "Run on the AppleTV simulator", - }, - ], "func": [Function], - "name": "run-ios", - "options": Array [ - Object { - "default": "iPhone X", - "description": "Explicitly set simulator to use. Optionally include iOS version betweenparenthesis at the end to match an exact version: \\"iPhone 6 (10.0)\\"", - "name": "--simulator [string]", - }, - Object { - "default": "Debug", - "description": "Explicitly set the scheme configuration to use", - "name": "--configuration [string]", - }, - Object { - "description": "Explicitly set Xcode scheme to use", - "name": "--scheme [string]", - }, - Object { - "default": "ios", - "description": "Path relative to project root where the Xcode project (.xcodeproj) lives.", - "name": "--project-path [string]", - }, - Object { - "description": "Explicitly set device to use by name. The value is not required if you have a single device connected.", - "name": "--device [string]", - }, - Object { - "description": "Explicitly set device to use by udid", - "name": "--udid [string]", - }, - Object { - "description": "Do not launch packager while building", - "name": "--no-packager", - }, - Object { - "description": "Do not use xcpretty even if installed", - "name": "--verbose", - }, - Object { - "default": 8081, - "name": "--port [number]", - "parse": [Function], - }, - Object { - "default": [Function], - "description": "Launches the Metro Bundler in a new window using the specified terminal path.", - "name": "--terminal [string]", - }, - ], - }, - Object { - "description": "starts logkitty", - "func": [Function], - "name": "log-android", - }, - Object { - "description": "builds your app and starts it on a connected Android emulator or device", - "func": [Function], - "name": "run-android", - "options": Array [ - Object { - "default": "", - "description": "Override the root directory for the android build (which contains the android directory)", - "name": "--root [string]", - }, - Object { - "default": "debug", - "description": "Specify your app's build variant", - "name": "--variant [string]", - }, - Object { - "default": "app", - "description": "Specify a different application folder name for the android source. If not, we assume is \\"app\\"", - "name": "--appFolder [string]", - }, - Object { - "default": "", - "description": "Specify an applicationId to launch after build.", - "name": "--appId [string]", - }, - Object { - "default": "", - "description": "Specify an applicationIdSuffix to launch after build.", - "name": "--appIdSuffix [string]", - }, - Object { - "default": "MainActivity", - "description": "Name of the activity to start", - "name": "--main-activity [string]", - }, - Object { - "description": "builds your app and starts it on a specific device/simulator with the given device id (listed by running \\"adb devices\\" on the command line).", - "name": "--deviceId [string]", - }, - Object { - "description": "Do not launch packager while building", - "name": "--no-packager", - }, - Object { - "default": 8081, - "name": "--port [number]", - "parse": [Function], - }, - Object { - "default": "iTerm.app", - "description": "Launches the Metro Bundler in a new window using the specified terminal path.", - "name": "--terminal [string]", - }, - Object { - "description": "Run custom Gradle tasks. By default it's \\"installDebug\\"", - "name": "--tasks [list]", - "parse": [Function], - }, - Object { - "default": false, - "description": "Do not run \\"jetifier\\" – the AndroidX transition tool. By default it runs before Gradle to ease working with libraries that don't support AndroidX yet. See more at: https://www.npmjs.com/package/jetifier.", - "name": "--no-jetifier", - }, - ], + "name": "test", }, ] `; @@ -226,9 +112,61 @@ Object { "hooks": Object {}, "name": "react-native-test", "params": Array [], - "platforms": Object {}, + "platforms": Object { + "android": null, + "ios": Object { + "folder": "<>/node_modules/react-native-test", + "libraryFolder": "Libraries", + "pbxprojPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj/project.pbxproj", + "plist": Array [], + "podfile": null, + "podspecPath": "<>/node_modules/react-native-test/ReactNativeTest.podspec", + "projectName": "customProject.xcodeproj", + "projectPath": "<>/node_modules/react-native-test/customLocation/customProject.xcodeproj", + "scriptPhases": Array [], + "sharedLibraries": Array [], + "sourceDir": "<>/node_modules/react-native-test/customLocation", + }, + }, "root": "<>/node_modules/react-native-test", } `; -exports[`should return dependencies from package.json 1`] = `Object {}`; +exports[`should return dependencies from package.json 1`] = ` +Object { + "react-native": Object { + "assets": Array [], + "hooks": Object {}, + "name": "react-native", + "params": Array [], + "platforms": Object { + "android": null, + "ios": null, + }, + "root": "<>/node_modules/react-native", + }, + "react-native-test": Object { + "assets": Array [], + "hooks": Object {}, + "name": "react-native-test", + "params": Array [], + "platforms": Object { + "android": null, + "ios": Object { + "folder": "<>/node_modules/react-native-test", + "libraryFolder": "Libraries", + "pbxprojPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj/project.pbxproj", + "plist": Array [], + "podfile": null, + "podspecPath": null, + "projectName": "HelloWorld.xcodeproj", + "projectPath": "<>/node_modules/react-native-test/ios/HelloWorld.xcodeproj", + "scriptPhases": Array [], + "sharedLibraries": Array [], + "sourceDir": "<>/node_modules/react-native-test/ios", + }, + }, + "root": "<>/node_modules/react-native-test", + }, +} +`; diff --git a/packages/cli/src/tools/config/readConfigFromDisk.ts b/packages/cli/src/tools/config/readConfigFromDisk.ts index 1f58ba267..ca761acf3 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.ts +++ b/packages/cli/src/tools/config/readConfigFromDisk.ts @@ -118,14 +118,12 @@ export function readDependencyConfigFromDisk( stopDir: rootFolder, searchPlaces, }); - // @ts-ignore - let config: UserDependencyConfig = explorer.searchSync(rootFolder); - const legacy = !!config; - if (legacy) { - // @ts-ignore TODO: legacy config can be undefined - config = readLegacyDependencyConfigFromDisk(rootFolder); - } + const searchResult = explorer.searchSync(rootFolder); + const legacy = !searchResult; + let config = searchResult + ? (searchResult.config as UserDependencyConfig) + : (readLegacyDependencyConfigFromDisk(rootFolder) as UserDependencyConfig); const result = Joi.validate(config, schema.dependencyConfig); From a47b6d1ccccc9f65ad6ab60c48a564afeac5d760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 18 Sep 2019 22:35:19 +0200 Subject: [PATCH 13/15] fix tests --- .../__snapshots__/index-test.ts.snap | 52 +++++++++++++++++-- .../src/tools/config/readConfigFromDisk.ts | 16 +++--- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap index 2dbfc00fc..89f237697 100644 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap @@ -49,10 +49,16 @@ Object { exports[`should load an out-of-tree "windows" platform that ships with a dependency 1`] = ` Object { "haste": Object { - "platforms": Array [], - "providesModuleNodeModules": Array [], + "platforms": Array [ + "windows", + ], + "providesModuleNodeModules": Array [ + "react-native-windows", + ], + }, + "platforms": Object { + "windows": Object {}, }, - "platforms": Object {}, } `; @@ -106,6 +112,46 @@ Array [ ] `; +exports[`should read \`rnpm\` config from a dependency and transform it to a new format: foo config 1`] = ` +Object { + "assets": Array [], + "hooks": Object {}, + "name": "react-native-foo", + "params": Array [], + "platforms": Object { + "android": null, + "ios": Object { + "folder": "<>/node_modules/react-native-foo", + "libraryFolder": "Libraries", + "pbxprojPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj/project.pbxproj", + "plist": Array [], + "podfile": null, + "podspecPath": null, + "projectName": "customProject.xcodeproj", + "projectPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj", + "scriptPhases": Array [], + "sharedLibraries": Array [], + "sourceDir": "<>/node_modules/react-native-foo/customLocation", + }, + }, + "root": "<>/node_modules/react-native-foo", +} +`; + +exports[`should read \`rnpm\` config from a dependency and transform it to a new format: haste config 1`] = ` +Object { + "platforms": Array [ + "ios", + "android", + "dummy", + ], + "providesModuleNodeModules": Array [ + "react-native", + "react-native-dummy", + ], +} +`; + exports[`should read a config of a dependency and use it to load other settings 1`] = ` Object { "assets": Array [], diff --git a/packages/cli/src/tools/config/readConfigFromDisk.ts b/packages/cli/src/tools/config/readConfigFromDisk.ts index ca761acf3..069d354a5 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.ts +++ b/packages/cli/src/tools/config/readConfigFromDisk.ts @@ -142,12 +142,14 @@ export function readDependencyConfigFromDisk( */ const loadProjectCommands = ( root: string, - ...commands: string[] -): Command[] => { - return commands.reduce((acc: Command[], cmdPath: string) => { - const cmds: Array | Command = require(path.join(root, cmdPath)); - return acc.concat(cmds); - }, []); + commands: Array | string | undefined, +): Array => { + return ([] as string[]) + .concat(commands || []) + .reduce((acc: Array, cmdPath: string) => { + const cmds: Array | Command = require(path.join(root, cmdPath)); + return acc.concat(cmds); + }, []); }; /** @@ -192,7 +194,7 @@ function readLegacyDependencyConfigFromDisk( params: config.params, }, haste: config.haste, - commands: loadProjectCommands(rootFolder, ...config.plugin), + commands: loadProjectCommands(rootFolder, config.plugin), platforms: config.platform ? require(path.join(rootFolder, config.platform)) : {}, From 41b2e12731b0aaec62fa6b7cc2633bc5a2302122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 18 Sep 2019 22:39:07 +0200 Subject: [PATCH 14/15] lint fix --- packages/cli/src/commands/link/__tests__/link-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/commands/link/__tests__/link-test.ts b/packages/cli/src/commands/link/__tests__/link-test.ts index fd4974f69..bcb7021cc 100644 --- a/packages/cli/src/commands/link/__tests__/link-test.ts +++ b/packages/cli/src/commands/link/__tests__/link-test.ts @@ -1,5 +1,5 @@ import {func as link} from '../link'; -import loadConfig from '../../../tools/config'; // eslint-disable-line import/namespace, import/default +import loadConfig from '../../../tools/config'; import makeHook from '../makeHook'; jest.mock('chalk', () => ({grey: str => str, bold: str => str})); jest.mock('../../../tools/config'); From 70b801daea7b8a7ed82c8fcef9cbce80d7807995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 26 Sep 2019 11:05:33 +0200 Subject: [PATCH 15/15] fix omit --- packages/cli-types/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli-types/src/index.ts b/packages/cli-types/src/index.ts index ae442dbfd..7738f22ec 100644 --- a/packages/cli-types/src/index.ts +++ b/packages/cli-types/src/index.ts @@ -143,7 +143,7 @@ export type Config = { * are calculated and can't be defined */ -export type UserConfig = Omit, 'haste'> & { +export type UserConfig = Omit & { reactNativePath: string | void; // Additional project settings project: { @@ -155,7 +155,7 @@ export type UserConfig = Omit, 'haste'> & { export type UserDependencyConfig = { // Additional dependency settings - dependency: Omit, 'root'>; + dependency: Omit; // An array of commands that ship with the dependency commands: Command[]; // An array of extra platforms to load