Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions packages/cli-types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -104,14 +110,10 @@ 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: {
android?: AndroidProjectConfig;
ios?: IOSProjectConfig;
[key: string]: any;
};
project: ProjectConfig;
assets: string[];
dependencies: {[key: string]: Dependency};
platforms: {
Expand All @@ -134,17 +136,15 @@ export interface Config {
platforms: Array<string>;
providesModuleNodeModules: Array<string>;
};
}

type Diff<T, U> = T extends U ? never : T;
};

/**
* 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
*/
export type UserConfig = Diff<Config, {root: any; haste: any}> & {
reactNativePath: string | void;

export type UserConfig = Omit<Config, 'root' | 'haste'> & {
reactNativePath: string | void;
// Additional project settings
project: {
android?: AndroidProjectParams;
Expand All @@ -153,6 +153,20 @@ export type UserConfig = Diff<Config, {root: any; haste: any}> & {
};
};

export type UserDependencyConfig = {
// Additional dependency settings
dependency: Omit<Dependency, 'name' | 'root'>;
// 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,
IOSProjectParams,
Expand Down
2 changes: 1 addition & 1 deletion packages/cli-types/src/ios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface IOSProjectParams {
sharedLibraries?: string[];
libraryFolder?: string;
plist: Array<any>;
scriptPhases: Array<any>;
scriptPhases?: Array<any>;
}

export interface IOSDependencyParams extends IOSProjectParams {}
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
"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",
"@types/semver": "^6.0.2",
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/cliEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion packages/cli/src/commands/info/__tests__/info.test.ts
Original file line number Diff line number Diff line change
@@ -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');
Expand Down
3 changes: 1 addition & 2 deletions packages/cli/src/commands/install/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
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
import loadConfig from '../../tools/config';

async function install(args: Array<string>): Promise<void> {
const name = args[0];
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/link/__tests__/link-test.ts
Original file line number Diff line number Diff line change
@@ -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');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/**
* @flow
*/

export default function mockedLoadConfig() {
return {
root: '/project/root',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/**
* @flow
*/

const path = require('path');

export default function resolveNodeModuleDir(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,17 @@
/**
* @flow
*/
import {CLIError} from '@react-native-community/cli-tools';

type JoiErrorDetails<K, T> = {
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.value,
);
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.
Expand All @@ -40,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}
`;
Expand Down
Original file line number Diff line number Diff line change
@@ -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('\\'));
Expand All @@ -19,12 +15,14 @@ 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<string>,
): Array<string> {
return (assets || [])
.map(asset => path.join(folder, asset))
.reduce(
(acc, assetPath) =>
(acc.concat(findAssetsInFolder(assetPath)): Array<string>),
[],
(acc, assetPath) => acc.concat(findAssetsInFolder(assetPath)),
[] as string[],
);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/**
* @flow
*/

import path from 'path';
import fs from 'fs';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
/**
* @flow
*/
import path from 'path';
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';
import * as android from '@react-native-community/cli-platform-android';
Expand All @@ -13,26 +17,18 @@ 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';

function getDependencyConfig(
root: string,
dependencyName: string,
finalConfig: ConfigT,
config: UserDependencyConfigT,
userConfig: UserConfigT,
finalConfig: Config,
config: UserDependencyConfig,
userConfig: UserConfig,
isPlatform: boolean,
): DependencyConfigT {
): Dependency {
return merge(
{
root,
Expand All @@ -52,24 +48,24 @@ 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()): ConfigT {
let lazyProject;
function loadConfig(projectRoot: string = process.cwd()): Config {
let lazyProject: ProjectConfig;
const userConfig = readConfigFromDisk(projectRoot);

const initialConfig: ConfigT = {
const initialConfig: Config = {
root: projectRoot,
get reactNativePath() {
return userConfig.reactNativePath
Expand All @@ -93,29 +89,32 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT {

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;
},
};

let depsWithWarnings = [];
let depsWithWarnings: Array<[string, string]> = [];

const finalConfig = Array.from(
new Set([
...Object.keys(userConfig.dependencies),
...findDependencies(projectRoot),
]),
).reduce((acc: ConfigT, dependencyName) => {
).reduce((acc: Config, dependencyName) => {
const localDependencyRoot =
userConfig.dependencies[dependencyName] &&
userConfig.dependencies[dependencyName].root;
let root;
let config;
let root: string;
let config: UserDependencyConfig;
try {
root =
localDependencyRoot ||
Expand Down Expand Up @@ -147,9 +146,11 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT {
*/
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];
}
}
Expand All @@ -167,10 +168,9 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT {
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](): Dependency {
return getDependencyConfig(
root,
dependencyName,
Expand All @@ -193,7 +193,7 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT {
],
platforms: [...acc.haste.platforms, ...haste.platforms],
},
}): ConfigT);
}) as Config;
}, initialConfig);

if (depsWithWarnings.length) {
Expand Down
Loading