nativescript
Version:
Command-line interface for building NativeScript projects
877 lines (764 loc) • 25.1 kB
TypeScript
import type { SupportedPlatform } from "../constants";
import {
IAndroidBuildOptionsSettings,
IProvision,
ITeamIdentifier,
IPlatformBuildData,
} from "../declarations";
import { ICheckEnvironmentRequirementsOutput, IPlatformData } from "./platform";
import { IPluginData, IBasePluginData } from "./plugins";
import {
IStringDictionary,
IProjectDir,
IDeviceIdentifier,
IRelease,
IPlatform,
IDependencyInformation,
ISpawnResult,
} from "../common/declarations";
import { SupportedConfigValues } from "../tools/config-manipulation/config-transformer";
import * as constants from "../constants";
interface IProjectName {
/**
* Name of the newly created application.
*/
projectName: string;
}
interface IProjectSettingsBase extends IProjectName {
/**
* Defines whether the `npm install` command should be executed with `--ignore-scripts` option.
* When it is passed, all scripts (postinstall for example) will not be executed.
*/
ignoreScripts?: boolean;
/**
* Selected template from which to create the project. If not specified, defaults to hello-world template.
* Template can be any npm package, local dir, github url, .tgz file.
* If it is set to `angular` or `ng`, default NativeScript Angular Hello World template will be used.
* If it is set to `typescript` or `tsc`, default NativeScript TypeScript Hello World template will be used.
*/
template?: string;
/**
* Application identifier for the newly created application. If not specified, defaults to org.nativescript.<projectName>.
*/
appId?: string;
}
/**
* Describes information passed to project creation hook (createProject).
*/
interface IProjectCreationSettings extends IProjectSettingsBase, IProjectDir {}
/**
* Describes available settings when creating new NativeScript application.
*/
interface IProjectSettings extends IProjectSettingsBase {
/**
* Path where the project will be created. If not specified, defaults to current working dir.
*/
pathToProject?: string;
/**
* Defines if invalid application name can be used for project creation.
*/
force?: boolean;
}
interface ICreateProjectData extends IProjectDir, IProjectName {}
interface IProjectService {
validateProjectName(opts: {
projectName: string;
force: boolean;
pathToProject: string;
}): Promise<string>;
/**
* Creates new NativeScript application.
* @param {any} projectSettings Options describing new project - its name, appId, path and template from which to be created.
* @returns {Promise<void>}
*/
createProject(projectSettings: IProjectSettings): Promise<ICreateProjectData>;
/**
* Checks if the specified project is valid NativeScript project.
* @param {string} pathToProject Directory to check.
* @returns {boolean} returns true if the project is valid NativeScript project.
*/
isValidNativeScriptProject(pathToProject?: string): boolean;
/**
* Checks if App_Resources exists, or pulls down a fresh set
* from the default template otherwise.
* @param {string} projectDir
*/
ensureAppResourcesExist(projectDir: string): Promise<void>;
}
interface INsConfigPlaform {
id?: string;
}
interface IOSSPMPackageBase {
name: string;
libs: string[];
/**
* Optional: If you have more targets (like widgets for example)
* you can list their names here to include the Swift Package with them
*/
targets?: string[];
}
export interface IOSRemoteSPMPackage extends IOSSPMPackageBase {
repositoryURL: string;
version: string;
}
export interface IOSLocalSPMPackage extends IOSSPMPackageBase {
path: string;
}
export type IOSSPMPackage = IOSRemoteSPMPackage | IOSLocalSPMPackage;
interface INsConfigIOS extends INsConfigPlaform {
discardUncaughtJsExceptions?: boolean;
/**
* Swift Package Manager
* List packages to be included in the iOS build.
*/
SPMPackages?: Array<IOSSPMPackage>;
}
interface INSConfigVisionOS extends INsConfigIOS {}
interface INsConfigAndroid extends INsConfigPlaform {
v8Flags?: string;
codeCache?: boolean;
heapSnapshotScript?: string;
"snapshot.blob"?: string;
profilerOutputDir?: string;
gcThrottleTime?: number;
profiling?: string;
markingMode?: string;
handleTimeZoneChanges?: boolean;
maxLogcatObjectSize?: number;
forceLog?: boolean;
memoryCheckInterval?: number;
freeMemoryRatio?: number;
suppressCallJSMethodExceptions?: boolean;
discardUncaughtJsExceptions?: boolean;
enableLineBreakpoints?: boolean;
enableMultithreadedJavascript?: boolean;
}
interface INsConfigHooks {
type?: string;
script: string;
}
interface INsConfig {
id?: string;
main?: string;
appPath?: string;
appResourcesPath?: string;
shared?: boolean;
overridePods?: string;
webpackConfigPath?: string;
ios?: INsConfigIOS;
android?: INsConfigAndroid;
visionos?: INSConfigVisionOS;
ignoredNativeDependencies?: string[];
hooks?: INsConfigHooks[];
projectName?: string;
}
interface IProjectData extends ICreateProjectData {
platformsDir: string;
projectFilePath: string;
projectId: string;
projectIdentifiers?: Mobile.IProjectIdentifier;
dependencies: any;
ignoredDependencies?: string[];
devDependencies: IStringDictionary;
appDirectoryPath: string;
appResourcesDirectoryPath: string;
projectType: string;
packageJsonData: any;
nsConfig: INsConfig;
androidManifestPath: string;
appGradlePath: string;
gradleFilesDirectoryPath: string;
infoPlistPath: string;
buildXcconfigPath: string;
podfilePath: string;
initialized?: boolean;
/**
* Defines if the project is a code sharing one.
* Value is true when project has nativescript.config and it has `shared: true` in it.
*/
isShared: boolean;
/**
* Defines the path to the configuration file passed to webpack process.
* By default this is the webpack.config.js at the root of the application.
* The value can be changed by setting `webpackConfigPath` in nativescript.config.
*/
webpackConfigPath: string;
projectName: string;
/**
* Initializes project data with the given project directory. If none supplied defaults to --path option or cwd.
* @param {string} projectDir Project root directory.
* @returns {void}
*/
initializeProjectData(projectDir?: string): void;
initializeProjectDataFromContent(
packageJsonContent: string,
projectDir?: string,
): void;
getAppDirectoryPath(projectDir?: string): string;
getAppDirectoryRelativePath(): string;
getAppResourcesDirectoryPath(projectDir?: string): string;
getAppResourcesRelativeDirectoryPath(): string;
}
interface IProjectDataService {
/**
* Returns a value from `nativescript` key in project's package.json.
* @param {string} projectDir The project directory - the place where the root package.json is located.
* @param {string} propertyName The name of the property to be checked in `nativescript` key.
* @returns {any} The value of the property.
*/
getNSValue(projectDir: string, propertyName: string): any;
/**
* Sets a value in the `nativescript` key in a project's package.json.
* @param {string} projectDir The project directory - the place where the root package.json is located.
* @param {string} key Key to be added to `nativescript` key in project's package.json.
* @param {any} value Value of the key to be added to `nativescript` key in project's package.json.
* @returns {void}
*/
setNSValue(projectDir: string, key: string, value: any): void;
/**
* Removes a property from `nativescript` key in project's package.json.
* @param {string} projectDir The project directory - the place where the root package.json is located.
* @param {string} propertyName The name of the property to be removed from `nativescript` key.
* @returns {void}
*/
removeNSProperty(projectDir: string, propertyName: string): void;
/**
* Removes a property from `nativescript.config`.
* @param {string} projectDir The project directory - the place where the `nativescript.config` is located.
* @param {string} propertyName The name of the property to be removed.
* @returns {void}
*/
removeNSConfigProperty(projectDir: string, propertyName: string): void;
/**
* Removes dependency from package.json
* @param {string} projectDir The project directory - the place where the root package.json is located.
* @param {string} dependencyName Name of the dependency that has to be removed.
* @returns {void}
*/
removeDependency(projectDir: string, dependencyName: string): void;
getProjectData(projectDir?: string): IProjectData;
/**
* Gives information about the whole assets structure for both iOS and Android.
* For each of the platforms, the returned object will contain icons, splashBackgrounds, splashCenterImages and splashImages (only for iOS).
* @param {IProjectDir} opts Object with a single property - projectDir. This is the root directory where NativeScript project is located.
* @returns {Promise<IAssetsStructure>} An object describing the current asset structure.
*/
getAssetsStructure(opts: IProjectDir): Promise<IAssetsStructure>;
/**
* Gives information about the whole assets structure for iOS.
* The returned object will contain icons, splashBackgrounds, splashCenterImages and splashImages.
* @param {IProjectDir} opts Object with a single property - projectDir. This is the root directory where NativeScript project is located.
* @returns {Promise<IAssetGroup>} An object describing the current asset structure for iOS.
*/
getIOSAssetsStructure(opts: IProjectDir): Promise<IAssetGroup>;
/**
* Gives information about the whole assets structure for Android.
* The returned object will contain icons, splashBackgrounds and splashCenterImages.
* @param {IProjectDir} opts Object with a single property - projectDir. This is the root directory where NativeScript project is located.
* @returns {Promise<IAssetGroup>} An object describing the current asset structure for Android.
*/
getAndroidAssetsStructure(opts: IProjectDir): Promise<IAssetGroup>;
/**
* Returns array with paths to all `.js` or `.ts` files in application's app directory.
* @param {string} projectDir Path to application.
* @returns {string[]} Array of paths to `.js` or `.ts` files.
*/
getAppExecutableFiles(projectDir: string): string[];
/**
* Returns package details for runtime, respecting the nativescript key for legacy projects
* @param {string} projectDir Path to application.
* @param {string} platform Platform key
*/
getRuntimePackage(
projectDir: string,
platform: SupportedPlatform,
): IBasePluginData;
/**
* Returns a value from `nativescript` key in project's package.json.
* @param {string} jsonData The project directory - the place where the root package.json is located.
* @param {string} propertyName The name of the property to be checked in `nativescript` key.
* @returns {any} The value of the property.
* @deprecated no longer used - will be removed in 8.0.
*/
getNSValueFromContent(jsonData: Object, propertyName: string): any;
}
interface IProjectCleanupService {
/**
* Clean multiple paths
* @param {string[]} pathsToClean
*/
clean(
pathsToClean: string[],
options?: IProjectCleanupOptions,
): Promise<IProjectCleanupResult>;
/**
* Clean a single path
* @param {string} pathToClean
*/
cleanPath(
pathToClean: string,
options?: IProjectCleanupOptions,
): Promise<IProjectCleanupResult>;
}
interface IProjectCleanupOptions {
/**
* When set, the cleanup service will calculate the size of the cleaned up files.
*/
stats?: boolean;
/**
* When set, the cleanup service will not delete any files.
*/
dryRun?: boolean;
/**
* When set, the cleanup service will not print any messages to the console.
*/
silent?: boolean;
}
interface IProjectCleanupResult {
ok: boolean;
/**
* When stats is set to true, this will contain a map of the cleaned up paths and their size.
*/
stats?: Map<string, number>;
}
interface IProjectPathCleanupResult {
ok: boolean;
/**
* When stats is set to true, this will contain the size of the cleaned path in bytes.
*/
size?: number;
}
interface IBackup {
create(): IBackup;
restore(): IBackup;
remove(): IBackup;
isUpToDate(): boolean;
addPath(path: string): IBackup;
addPaths(paths: string[]): IBackup;
}
interface IProjectBackupService {
getBackup(name: string): IBackup;
backup(name: string, pathsToBackup: string[]): IBackup;
restore(name: string, pathsToRestore: string[]): IBackup;
}
interface IProjectConfigInformation {
hasTSConfig: boolean;
hasJSConfig: boolean;
hasNSConfig: boolean;
usingNSConfig: boolean;
TSConfigPath: string;
JSConfigPath: string;
NSConfigPath: string;
}
interface IProjectConfigService {
/**
* read the nativescript.config.(js|ts) file
* @returns {INsConfig} the parsed config data
*/
readConfig(projectDir?: string): INsConfig;
/**
* Get value for a given config key path
* @param key the property key path
*/
getValue(key: string, defaultValue?: any): any;
/**
* Set value for a given config key path
* @param key the property key path
* @param value
*/
setValue(key: string, value: SupportedConfigValues): Promise<boolean>;
/**
* Override legacy fallback - and force using the new configs
* Used by the migrate service to force the config service to
* write new values into the new configs.
* @param force
*/
setForceUsingNewConfig(force: boolean): boolean;
/**
* Override legacy fallback - and force using the legacy configs
* Used by the migrate service to force the config service to
* read values from the old configs
* @param force
*/
setForceUsingLegacyConfig(force: boolean): boolean;
detectProjectConfigs(projectDir?: string): IProjectConfigInformation;
getDefaultTSConfig(appId: string, appPath: string): string;
writeDefaultConfig(projectDir?: string, appId?: string): boolean | string;
writeLegacyNSConfigIfNeeded(
projectDir: string,
runtimePackage: IBasePluginData,
): Promise<void>;
}
interface IAssetItem {
path: string;
size: string;
width: number;
height: number;
filename: string;
directory: string;
scale: string;
idiom: string;
resizeOperation?: string;
overlayImageScale?: number;
rgba?: boolean;
// additional operations for special cases
operation?: "delete" | "writeXMLColor";
data?: any;
}
interface IAssetSubGroup {
images: IAssetItem[];
info?: { version: string; author: string };
[imageType: string]: any;
}
interface IAssetGroup {
icons: IAssetSubGroup;
splashBackgrounds: IAssetSubGroup;
splashCenterImages: IAssetSubGroup;
splashImages?: IAssetSubGroup;
[imageType: string]: IAssetSubGroup;
}
interface IAssetsStructure {
ios: IAssetGroup;
android: IAssetGroup;
}
interface IImageDefinitionGroup {
icons: IAssetItem[];
splashBackgrounds: IAssetItem[];
splashCenterImages: IAssetItem[];
splashImages?: IAssetItem[];
}
interface IImageDefinitionsStructure {
ios: IImageDefinitionGroup;
android: IImageDefinitionGroup;
android_legacy: IImageDefinitionGroup;
}
interface ITemplateData {
/**
* The normalized template name
* In case no --template option is provided, use default template name
* In case --template <templateName> option is provided, use <templateName>
* In case --template <templateName>@<version> is provided, use <templateName>
* In case --ng option is provided, use default angular template name
* In case --ts option is provided, use default typescript template name
*/
templateName: string;
/**
* The path to the template.
* In case template is v1, will be {pathToProjectDir}/node_modules/{templateName}.
* In case template is v2, will be null.
*/
// templatePath: string;
/**
* The whole content of package.json file
*/
templatePackageJsonContent: ITemplatePackageJsonContent;
/**
* The version of the package used for creating the application.
*/
version: string;
}
interface ITemplatePackageJsonContent extends IBasePluginData {
dependencies: IStringDictionary;
devDependencies: IStringDictionary;
nativescript?: {
templateVersion?: string;
};
}
/**
* Describes working with templates.
*/
interface IProjectTemplatesService {
/**
* Prepares template for project creation.
* In case templateName is not provided, use defaultTemplatePath.
* In case templateName is a special word, validated from us (for ex. typescript), resolve the real template name and add it to npm cache.
* In any other cases try to `npm install` the specified templateName to temp directory.
* @param {string} templateName The name of the template.
* @return {ITemplateData} Data describing the template - location where it is installed and its NativeScript version.
*/
prepareTemplate(
templateName: string,
projectDir: string,
): Promise<ITemplateData>;
}
interface IPlatformProjectServiceBase {
getPluginPlatformsFolderPath(
pluginData: IPluginData,
platform: string,
): string;
getFrameworkVersion(projectData: IProjectData): string;
}
interface IBuildForDevice {
buildForDevice: boolean;
}
interface IiCloudContainerEnvironment {
iCloudContainerEnvironment: string;
}
interface INativePrepare {
skipNativePrepare: boolean;
forceRebuildNativeApp?: boolean;
restartLiveSync?: boolean;
}
interface IBuildConfig
extends IAndroidBuildOptionsSettings,
IiOSBuildConfig,
IProjectDir {
clean?: boolean;
architectures?: string[];
buildOutputStdio?: string;
platform?: string;
_device?: Mobile.IDevice;
}
/**
* Describes iOS-specific build configuration properties
*/
interface IiOSBuildConfig
extends IBuildForDevice,
IiCloudContainerEnvironment,
IDeviceIdentifier,
IProvision,
ITeamIdentifier,
IRelease {
/**
* Identifier of the mobile provision which will be used for the build. If not set a provision will be selected automatically if possible.
*/
mobileProvisionIdentifier?: string;
/**
* Code sign identity used for build. If not set iPhone Developer is used as a default when building for device.
*/
codeSignIdentity?: string;
}
/**
* Describes service used for building a project locally.
*/
interface ILocalBuildService {
/**
* Builds a project locally.
* @param {string} platform Platform for which to build.
* @param {IPlatformBuildData} platformBuildOptions Additional options for controlling the build.
* @return {Promise<string>} Path to the build output.
*/
build(
platform: string,
platformBuildOptions: IPlatformBuildData,
): Promise<string>;
/**
* Removes build artifacts specific to the platform
* @param {ICleanNativeAppData} data Data describing the clean app process
* @returns {void}
*/
cleanNativeApp(data: ICleanNativeAppData): Promise<void>;
}
interface ICleanNativeAppData extends IProjectDir, IPlatform {}
interface IValidatePlatformOutput {
checkEnvironmentRequirementsOutput: ICheckEnvironmentRequirementsOutput;
}
interface ITestExecutionService {
startKarmaServer(
platform: string,
liveSyncInfo: ILiveSyncInfo,
deviceDescriptors: ILiveSyncDeviceDescriptor[],
): Promise<void>;
canStartKarmaServer(projectData: IProjectData): Promise<boolean>;
}
interface ITestInitializationService {
getDependencies(framework: string): IDependencyInformation[];
getFrameworkNames(): string[];
}
/**
* Describes a service used to facilitate communication with CocoaPods
*/
interface ICocoaPodsService {
/**
* Get the header needed for the beginning of every Podfile
* @param {string} targetName The name of the target (usually the same as the project's name).
* @return {string} The header which needs to be placed at the beginning of a Podfile.
*/
getPodfileHeader(targetName: string): string;
/**
* Get the footer needed for the end of every Podfile
* @return {string} The footer which needs to be placed at the end of a Podfile.
*/
getPodfileFooter(): string;
/**
* Merges the Podfile's content from App_Resources in the project's Podfile.
* @param projectData Information about the project.
* @param platformData Information about the platform.
* @returns {Promise<void>}
*/
applyPodfileFromAppResources(
projectData: IProjectData,
platformData: IPlatformData,
): Promise<void>;
applyPodfileArchExclusions(
projectData: IProjectData,
platformData: IPlatformData,
): Promise<void>;
applyPodfileFromExtensions(
projectData: IProjectData,
platformData: IPlatformData,
): Promise<void>;
/**
* Prepares the Podfile content of a plugin and merges it in the project's Podfile.
* @param {string} moduleName The module which the Podfile is from.
* @param {string} podfilePath The path to the podfile.
* @param {IProjectData} projectData Information about the project.
* @param {IPlatformData} platformData Information about the platform.
* @returns {Promise<void>}
*/
applyPodfileToProject(
moduleName: string,
podfilePath: string,
projectData: IProjectData,
platformData: IPlatformData,
): Promise<void>;
/**
* Gives the path to the plugin's Podfile.
* @param {IPluginData} pluginData Information about the plugin.
* @returns {string} Path to plugin's Podfile
*/
getPluginPodfilePath(pluginData: IPluginData): string;
/**
* Removes plugins Podfile content from the project.
* @param {string} moduleName The name of the module.
* @param {string} podfilePath The path to the module's Podfile.
* @param {string} projectData Information about the project.
* @param {string} nativeProjectPath Path to the native Xcode project.
* @returns {void}
*/
removePodfileFromProject(
moduleName: string,
podfilePath: string,
projectData: IProjectData,
nativeProjectPath: string,
): void;
/**
* Gives the path to project's Podfile.
* @param {string} nativeProjectPath Path to the native Xcode project.
* @returns {string} Path to project's Podfile.
*/
getProjectPodfilePath(nativeProjectPath: string): string;
/**
* Executes `pod install` or `sanboxpod install` in the passed project.
* @param {string} projectRoot The root directory of the native iOS project.
* @param {string} xcodeProjPath The full path to the .xcodeproj file.
* @returns {Promise<ISpawnResult>} Information about the spawned process.
*/
executePodInstall(
projectRoot: string,
xcodeProjPath: string,
): Promise<ISpawnResult>;
/**
* Merges pod's xcconfig file into project's xcconfig file
* @param projectData
* @param platformData
* @param opts
*/
mergePodXcconfigFile(
projectData: IProjectData,
platformData: IPlatformData,
opts: IRelease,
): Promise<void>;
}
interface ICocoaPodsPlatformManager {
addPlatformSection(
projectData: IProjectData,
podfilePlatformData: IPodfilePlatformData,
projectPodfileContent: string,
): string;
removePlatformSection(
moduleName: string,
projectPodFileContent: string,
podfilePath: string,
): string;
replacePlatformRow(
podfileContent: string,
podfilePath: string,
): { replacedContent: string; podfilePlatformData: IPodfilePlatformData };
}
declare const enum BuildNames {
debug = "Debug",
release = "Release",
}
interface IXcodeTargetBuildConfigurationProperty {
name: string;
value: any;
buildNames?: BuildNames[];
}
/**
* Describes a service used to add and remove iOS extension
*/
interface IIOSNativeTargetService {
addTargetToProject(
targetRootPath: string,
targetFolder: string,
targetType: string,
project: IXcode.project,
platformData: IPlatformData,
parentTarget?: string,
): IXcode.target;
prepareSigning(
targetUuids: string[],
projectData: IProjectData,
projectPath: string,
): void;
getTargetDirectories(folderPath: string): string[];
setXcodeTargetBuildConfigurationProperties(
properties: IXcodeTargetBuildConfigurationProperty[],
targetName: string,
project: IXcode.project,
): void;
setConfigurationsFromJsonFile(
jsonPath: string,
targetUuid: string,
targetName: string,
project: IXcode.project,
): void;
}
/**
* Describes a service used to add and remove iOS extension
*/
interface IIOSExtensionsService {
addExtensionsFromPath(
options: IAddExtensionsFromPathOptions,
): Promise<boolean>;
removeExtensions(options: IRemoveExtensionsOptions): void;
}
interface IIOSWatchAppService {
addWatchAppFromPath(options: IAddWatchAppFromPathOptions): Promise<boolean>;
removeWatchApp(options: IRemoveWatchAppOptions): void;
hasWatchApp(platformData: IPlatformData, projectData: IProjectData): boolean;
}
interface IAddTargetFromPathOptions {
projectData: IProjectData;
platformData: IPlatformData;
pbxProjPath: string;
}
interface IAddExtensionsFromPathOptions extends IAddTargetFromPathOptions {
extensionsFolderPath: string;
}
interface IAddWatchAppFromPathOptions extends IAddTargetFromPathOptions {
watchAppFolderPath: string;
}
interface IRemoveExtensionsOptions {
pbxProjPath: string;
}
interface IRemoveWatchAppOptions extends IRemoveExtensionsOptions {}
interface IRubyFunction {
functionName: string;
functionParameters?: string;
}
interface IPodfilePlatformData {
/**
* The content of the whole pod's platform row
*/
content: string;
/**
* The version of the pod's platform
*/
version: string;
/**
* The path to the pod's file
*/
path: string;
}