diff --git a/packages/@ionic/cli/src/definitions.ts b/packages/@ionic/cli/src/definitions.ts index 7b49e6216b..bdc31ca4f3 100644 --- a/packages/@ionic/cli/src/definitions.ts +++ b/packages/@ionic/cli/src/definitions.ts @@ -691,15 +691,16 @@ export interface Ionic1BuildOptions extends BuildOptions<'ionic1'> {} export interface CustomBuildOptions extends BuildOptions<'custom'> {} export interface GenerateOptions { - type: string; name: string; } export interface AngularGenerateOptions extends GenerateOptions { [key: string]: any; // TODO + schematic: string; } export interface IonicAngularGenerateOptions extends GenerateOptions { + type: string; module: boolean; constants: boolean; } diff --git a/packages/@ionic/cli/src/lib/generate.ts b/packages/@ionic/cli/src/lib/generate.ts index 2299845f78..f453ff44e1 100644 --- a/packages/@ionic/cli/src/lib/generate.ts +++ b/packages/@ionic/cli/src/lib/generate.ts @@ -15,8 +15,8 @@ export abstract class GenerateRunner implements Runne protected abstract readonly e: GenerateRunnerDeps; createOptionsFromCommandLine(inputs: CommandLineInputs, options: CommandLineOptions): GenerateOptions { - const [ type, name ] = inputs; - return { type, name }; + const [ name ] = inputs; + return { name }; } async ensureCommandLine(inputs: CommandLineInputs, options: CommandLineOptions): Promise { /* overwritten in subclasses */ } diff --git a/packages/@ionic/cli/src/lib/project/angular/generate.ts b/packages/@ionic/cli/src/lib/project/angular/generate.ts index b05866ed3b..468eb4251f 100644 --- a/packages/@ionic/cli/src/lib/project/angular/generate.ts +++ b/packages/@ionic/cli/src/lib/project/angular/generate.ts @@ -58,7 +58,7 @@ To test a generator before file modifications are made, use the ${input('--dry-r ], inputs: [ { - name: 'type', + name: 'schematic', summary: `The type of feature (e.g. ${['page', 'component', 'directive', 'service'].map(c => input(c)).join(', ')})`, validators: [validators.required], }, @@ -75,22 +75,22 @@ To test a generator before file modifications are made, use the ${input('--dry-r if (inputs[0]) { this.validateFeatureType(inputs[0]); } else { - const type = await this.e.prompt({ + const schematic = await this.e.prompt({ type: 'list', - name: 'type', + name: 'schematic', message: 'What would you like to generate?', choices: SCHEMATICS, }); - inputs[0] = type; + inputs[0] = schematic; } if (!inputs[1]) { - const type = SCHEMATIC_ALIAS.get(inputs[0]) || inputs[0]; + const schematic = SCHEMATIC_ALIAS.get(inputs[0]) || inputs[0]; const name = await this.e.prompt({ type: 'input', name: 'name', - message: `Name/path of ${input(type)}:`, + message: `Name/path of ${input(schematic)}:`, validate: v => validators.required(v), }); @@ -99,7 +99,8 @@ To test a generator before file modifications are made, use the ${input('--dry-r } createOptionsFromCommandLine(inputs: CommandLineInputs, options: CommandLineOptions): AngularGenerateOptions { - const baseOptions = super.createOptionsFromCommandLine(inputs, options); + const [schematic, name] = inputs; + const baseOptions = {name, schematic} const project = options['project'] ? String(options['project']) : 'app'; // TODO: this is a little gross, is there a better way to pass in all the @@ -113,22 +114,22 @@ To test a generator before file modifications are made, use the ${input('--dry-r async run(options: AngularGenerateOptions) { const { name } = options; - const type = SCHEMATIC_ALIAS.get(options.type) || options.type; + const schematic = SCHEMATIC_ALIAS.get(options.schematic) || options.schematic; try { - await this.generateComponent(type, name, lodash.omit(options, 'type', 'name')); + await this.generateComponent(schematic, name, lodash.omit(options, 'schematic', 'name')); } catch (e) { debug(e); - throw new FatalException(`Could not generate ${input(type)}.`); + throw new FatalException(`Could not generate ${input(schematic)}.`); } if (!options['dry-run']) { - this.e.log.ok(`Generated ${input(type)}!`); + this.e.log.ok(`Generated ${input(schematic)}!`); } } - private validateFeatureType(type: string) { - if (type === 'provider') { + private validateFeatureType(schematic: string) { + if (schematic === 'provider') { throw new FatalException( `Please use ${input('ionic generate service')} for generating service providers.\n` + `For more information, please see the Angular documentation${ancillary('[1]')} on services.\n\n` + @@ -136,17 +137,17 @@ To test a generator before file modifications are made, use the ${input('--dry-r ); } - if (!SCHEMATICS.includes(type) && !SCHEMATIC_ALIAS.get(type)) { + if (!SCHEMATICS.includes(schematic) && !SCHEMATIC_ALIAS.get(schematic)) { throw new FatalException( - `${input(type)} is not a known feature.\n` + + `${input(schematic)} is not a known feature.\n` + `Use ${input('npx ng g --help')} to list available types of features.` ); } } - private async generateComponent(type: string, name: string, options: { [key: string]: string | boolean; }) { + private async generateComponent(schematic: string, name: string, options: { [key: string]: string | boolean; }) { const args = { - _: ['generate', type, name], + _: ['generate', schematic, name], // convert `--no-` style options to `--=false` ...lodash.mapValues(options, v => v === false ? 'false' : v), }; diff --git a/packages/@ionic/cli/src/lib/project/index.ts b/packages/@ionic/cli/src/lib/project/index.ts index 349123f31e..4d69ceee82 100644 --- a/packages/@ionic/cli/src/lib/project/index.ts +++ b/packages/@ionic/cli/src/lib/project/index.ts @@ -307,12 +307,6 @@ export async function createProjectFromDetails(details: ProjectDetailsResult, de case 'vue': const { VueProject } = await import('./vue'); return new VueProject(details, deps); - case 'ionic-angular': - const { IonicAngularProject } = await import('./ionic-angular'); - return new IonicAngularProject(details, deps); - case 'ionic1': - const { Ionic1Project } = await import('./ionic1'); - return new Ionic1Project(details, deps); case 'custom': const { CustomProject } = await import('./custom'); return new CustomProject(details, deps); diff --git a/packages/@ionic/cli/src/lib/project/ionic-angular/__tests__/build.ts b/packages/@ionic/cli/src/lib/project/ionic-angular/__tests__/build.ts deleted file mode 100644 index e254a7b6ad..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic-angular/__tests__/build.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { IonicAngularBuildCLI } from '../build'; - -describe('@ionic/cli', () => { - - describe('lib/ionic-angular', () => { - - describe('IonicAngularBuildCLI', () => { - - describe('buildOptionsToAppScriptsArgs', () => { - - const options = { - '--': ['--generateSourceMap', 'false'], - prod: true, - aot: true, - minifyjs: true, - minifycss: true, - optimizejs: true, - }; - - it('should transform defaults', async () => { - const appscripts = new IonicAngularBuildCLI({} as any); - const result = await (appscripts as any).buildOptionsToAppScriptsArgs({ _: [], '--': [] }); - expect(result).toEqual([]); - }); - - it('should transform options', async () => { - const appscripts = new IonicAngularBuildCLI({} as any); - const result = await (appscripts as any).buildOptionsToAppScriptsArgs(options); - expect(result).toEqual(['--prod', '--aot', '--minifyjs', '--minifycss', '--optimizejs', '--generateSourceMap', 'false']); - }); - - }); - - }); - - }); - -}); diff --git a/packages/@ionic/cli/src/lib/project/ionic-angular/__tests__/index.ts b/packages/@ionic/cli/src/lib/project/ionic-angular/__tests__/index.ts deleted file mode 100644 index b44e7c9ba6..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic-angular/__tests__/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -import * as path from 'path' -import { IonicAngularProject } from '../'; - -describe('@ionic/cli', () => { - - describe('lib/project/ionic-angular', () => { - - describe('IonicAngularProject', () => { - - let p: IonicAngularProject; - - beforeEach(() => { - p = new IonicAngularProject({ context: 'app', configPath: '/path/to/proj/file' } as any, {} as any); - jest.spyOn(p, 'config', 'get').mockImplementation(() => ({ get: () => undefined } as any)); - }); - - it('should set directory attribute', async () => { - expect(p.directory).toEqual(path.resolve('/path/to/proj')); - }); - - describe('getSourceDir', () => { - - it('should default to src', async () => { - const result = await p.getSourceDir(); - expect(result).toEqual(path.resolve('/path/to/proj/src')); - }); - - }); - - }); - - }); - -}); diff --git a/packages/@ionic/cli/src/lib/project/ionic-angular/__tests__/serve.ts b/packages/@ionic/cli/src/lib/project/ionic-angular/__tests__/serve.ts deleted file mode 100644 index d8baa3727d..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic-angular/__tests__/serve.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { IonicAngularServeRunner } from '../serve'; - -describe('@ionic/cli', () => { - - describe('lib/project/ionic-angular/serve', () => { - - describe('IonicAngularServeRunner', () => { - - describe('createOptionsFromCommandLine', () => { - - const defaults = { - '--': [], - publicHost: undefined, - host: 'localhost', - browser: undefined, - browserOption: undefined, - consolelogs: false, - engine: 'browser', - env: undefined, - externalAddressRequired: false, - lab: false, - labHost: 'localhost', - labPort: 8200, - livereload: true, - livereloadPort: 35729, - notificationPort: 53703, - open: false, - port: 8100, - proxy: true, - serverlogs: false, - project: undefined, - verbose: false, - }; - - it('should provide defaults with no options', () => { - const runner = new IonicAngularServeRunner({} as any); - const result = runner.createOptionsFromCommandLine([], { _: [] }); - expect(result).toEqual(defaults); - }); - - it('should provide options from negations of cli flag defaults', () => { - const runner = new IonicAngularServeRunner({} as any); - const result = runner.createOptionsFromCommandLine([], { _: [], livereload: false, proxy: false, lab: true, open: true, externalAddressRequired: true }); - expect(result).toEqual({ ...defaults, livereload: false, proxy: false, lab: true, open: true, externalAddressRequired: true }); - }); - - it('should allow overrides of default values', () => { - const runner = new IonicAngularServeRunner({} as any); - const result = runner.createOptionsFromCommandLine([], { _: [], host: '0.0.0.0', port: '1111', 'livereload-port': '2222', 'dev-logger-port': '3333', env: 'prod' }); - expect(result).toEqual({ ...defaults, host: '0.0.0.0', port: 1111, livereloadPort: 2222, notificationPort: 3333, env: 'prod' }); - }); - - it('should respect --external flag', () => { - const runner = new IonicAngularServeRunner({} as any); - const result = runner.createOptionsFromCommandLine([], { _: [], host: 'localhost', external: true }); - expect(result).toEqual({ ...defaults, host: '0.0.0.0' }); - }); - - it('should pass on separated args', () => { - const runner = new IonicAngularServeRunner({} as any); - const result = runner.createOptionsFromCommandLine([], { _: [], '--': ['foo', '--bar'] }); - expect(result).toEqual({ ...defaults, '--': ['foo', '--bar'] }); - }); - - }); - - }); - - }); - -}); diff --git a/packages/@ionic/cli/src/lib/project/ionic-angular/ailments.ts b/packages/@ionic/cli/src/lib/project/ionic-angular/ailments.ts deleted file mode 100644 index 99b8ac81fa..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic-angular/ailments.ts +++ /dev/null @@ -1,272 +0,0 @@ -import * as semver from 'semver'; - -import { ProjectType, TreatableAilment } from '../../../definitions'; -import { BUILD_SCRIPT } from '../../build'; -import { ancillary, input, strong } from '../../color'; -import { Ailment, AilmentDeps } from '../../doctor'; -import { SERVE_SCRIPT } from '../../serve'; -import { pkgFromRegistry, pkgManagerArgs } from '../../utils/npm'; - -import { IonicAngularProject } from './'; -import { DEFAULT_BUILD_SCRIPT_VALUE } from './build'; -import { DEFAULT_SERVE_SCRIPT_VALUE } from './serve'; - -export interface IonicAngularAilmentDeps extends AilmentDeps { - readonly project: IonicAngularProject; -} - -export abstract class IonicAngularAilment extends Ailment { - readonly projects: ProjectType[] = ['ionic-angular']; - protected readonly project: IonicAngularProject; - - constructor(deps: IonicAngularAilmentDeps) { - super(deps); - this.project = deps.project; - } -} - -export class IonicAngularUpdateAvailable extends IonicAngularAilment { - readonly id = 'ionic-angular-update-available'; - currentVersion?: string; - latestVersion?: string; - - async getVersionPair(): Promise<[string, string]> { - if (!this.currentVersion || !this.latestVersion) { - const [ currentPkg ] = await this.project.getPackageJson('ionic-angular'); - const latestPkg = await pkgFromRegistry(this.config.get('npmClient'), { pkg: 'ionic-angular' }); - this.currentVersion = currentPkg ? currentPkg.version : undefined; - this.latestVersion = latestPkg ? latestPkg.version : undefined; - } - - if (!this.currentVersion || !this.latestVersion) { - return ['0.0.0', '0.0.0']; - } - - return [ this.currentVersion, this.latestVersion ]; - } - - async getMessage() { - const [ currentVersion, latestVersion ] = await this.getVersionPair(); - - return ( - `Update available for Ionic Framework.\n` + - `An update is available for ${strong('ionic-angular')} (${ancillary(currentVersion)} => ${ancillary(latestVersion)}).\n` - ).trim(); - } - - async detected() { - const [ currentVersion, latestVersion ] = await this.getVersionPair(); - const diff = semver.diff(currentVersion, latestVersion); - - return diff === 'minor' || diff === 'patch'; - } - - async getTreatmentSteps() { - const [ , latestVersion ] = await this.getVersionPair(); - const args = await pkgManagerArgs(this.config.get('npmClient'), { command: 'install', pkg: `ionic-angular@${latestVersion ? latestVersion : 'latest'}` }); - - return [ - { message: `Visit ${strong('https://github.com/ionic-team/ionic/releases')} for each upgrade's instructions` }, - { message: `If no instructions, run: ${input(args.join(' '))}` }, - { message: `Watch for npm warnings about peer dependencies--they may need manual updating` }, - ]; - } -} - -export class IonicAngularMajorUpdateAvailable extends IonicAngularAilment { - readonly id = 'ionic-angular-major-update-available'; - currentVersion?: string; - latestVersion?: string; - - async getVersionPair(): Promise<[string, string]> { - if (!this.currentVersion || !this.latestVersion) { - const [ currentPkg ] = await this.project.getPackageJson('ionic-angular'); - const latestPkg = await pkgFromRegistry(this.config.get('npmClient'), { pkg: 'ionic-angular' }); - this.currentVersion = currentPkg ? currentPkg.version : undefined; - this.latestVersion = latestPkg ? latestPkg.version : undefined; - } - - if (!this.currentVersion || !this.latestVersion) { - return ['0.0.0', '0.0.0']; - } - - return [ this.currentVersion, this.latestVersion ]; - } - - async getMessage() { - const [ currentVersion, latestVersion ] = await this.getVersionPair(); - - return ( - `Major update available for Ionic Framework.\n` + - `A major update is available for ${strong('ionic-angular')} (${ancillary(currentVersion)} => ${ancillary(latestVersion)}).\n` - ).trim(); - } - - async detected() { - const [ currentVersion, latestVersion ] = await this.getVersionPair(); - const diff = semver.diff(currentVersion, latestVersion); - - return diff === 'major'; - } - - async getTreatmentSteps() { - return [ - { message: `Visit ${strong('https://ionicframework.com/blog')} and ${strong('https://github.com/ionic-team/ionic/releases')} for upgrade instructions` }, - ]; - } -} - -export class AppScriptsUpdateAvailable extends IonicAngularAilment implements TreatableAilment { - readonly id = 'app-scripts-update-available'; - readonly treatable = true; - currentVersion?: string; - latestVersion?: string; - - async getVersionPair(): Promise<[string, string]> { - if (!this.currentVersion || !this.latestVersion) { - const [ currentPkg ] = await this.project.getPackageJson('@ionic/app-scripts'); - const latestPkg = await pkgFromRegistry(this.config.get('npmClient'), { pkg: '@ionic/app-scripts' }); - this.currentVersion = currentPkg ? currentPkg.version : undefined; - this.latestVersion = latestPkg ? latestPkg.version : undefined; - } - - if (!this.currentVersion || !this.latestVersion) { - return ['0.0.0', '0.0.0']; - } - - return [ this.currentVersion, this.latestVersion ]; - } - - async getMessage() { - const [ currentVersion, latestVersion ] = await this.getVersionPair(); - - return ( - `Update available for ${strong('@ionic/app-scripts')}.\n` + - `An update is available for ${strong('@ionic/app-scripts')} (${ancillary(currentVersion)} => ${ancillary(latestVersion)}).\n` - ).trim(); - } - - async detected() { - const [ currentVersion, latestVersion ] = await this.getVersionPair(); - const diff = semver.diff(currentVersion, latestVersion); - - return diff === 'minor' || diff === 'patch'; - } - - async getTreatmentSteps() { - const [ , latestVersion ] = await this.getVersionPair(); - const [ manager, ...managerArgs ] = await pkgManagerArgs(this.config.get('npmClient'), { command: 'install', pkg: `@ionic/app-scripts@${latestVersion ? latestVersion : 'latest'}`, saveDev: true }); - - return [ - { - message: `Run: ${input(manager + ' ' + managerArgs.join(' '))}`, - treat: async () => { - await this.shell.run(manager, managerArgs, {}); - }, - }, - ]; - } -} - -export class AppScriptsMajorUpdateAvailable extends IonicAngularAilment { - readonly id = 'app-scripts-major-update-available'; - currentVersion?: string; - latestVersion?: string; - - async getVersionPair(): Promise<[string, string]> { - if (!this.currentVersion || !this.latestVersion) { - const [ currentPkg ] = await this.project.getPackageJson('@ionic/app-scripts'); - const latestPkg = await pkgFromRegistry(this.config.get('npmClient'), { pkg: '@ionic/app-scripts' }); - this.currentVersion = currentPkg ? currentPkg.version : undefined; - this.latestVersion = latestPkg ? latestPkg.version : undefined; - } - - if (!this.currentVersion || !this.latestVersion) { - return ['0.0.0', '0.0.0']; - } - - return [ this.currentVersion, this.latestVersion ]; - } - - async getMessage() { - const [ currentVersion, latestVersion ] = await this.getVersionPair(); - - return ( - `Major update available for ${strong('@ionic/app-scripts')}.\n` + - `A major update is available for ${strong('@ionic/app-scripts')} (${ancillary(currentVersion)} => ${ancillary(latestVersion)}).\n` - ).trim(); - } - - async detected() { - const [ currentVersion, latestVersion ] = await this.getVersionPair(); - const diff = semver.diff(currentVersion, latestVersion); - - return diff === 'major'; - } - - async getTreatmentSteps() { - return [ - { message: `Visit ${strong('https://github.com/ionic-team/ionic-app-scripts/releases')} for upgrade instructions` }, - ]; - } -} - -export class IonicAngularPackageJsonHasDefaultIonicBuildCommand extends IonicAngularAilment { - readonly id = 'ionic-angular-package-json-has-default-ionic-build-command'; - currentVersion?: string; - latestVersion?: string; - - async getMessage() { - return ( - `The ${strong(BUILD_SCRIPT)} npm script is unchanged.\n` + - `The Ionic CLI now looks for the ${strong(BUILD_SCRIPT)} npm script in ${strong('package.json')} for a custom build script to run instead of the default (${input(DEFAULT_BUILD_SCRIPT_VALUE)}). If you don't use it, it's considered quicker and cleaner to just remove it.` - ).trim(); - } - - async detected() { - const pkg = await this.project.requirePackageJson(); - - if (pkg.scripts && pkg.scripts[BUILD_SCRIPT] === DEFAULT_BUILD_SCRIPT_VALUE) { - return true; - } - - return false; - } - - async getTreatmentSteps() { - return [ - { message: `Remove the ${strong(BUILD_SCRIPT)} npm script from ${strong('package.json')}` }, - { message: `Continue using ${input('ionic build')} normally` }, - ]; - } -} - -export class IonicAngularPackageJsonHasDefaultIonicServeCommand extends IonicAngularAilment { - readonly id = 'ionic-angular-package-json-has-default-ionic-serve-command'; - currentVersion?: string; - latestVersion?: string; - - async getMessage() { - return ( - `The ${strong(SERVE_SCRIPT)} npm script is unchanged.\n` + - `The Ionic CLI now looks for the ${strong(SERVE_SCRIPT)} npm script in ${strong('package.json')} for a custom serve script to run instead of the default (${input(DEFAULT_SERVE_SCRIPT_VALUE)}). If you don't use it, it's considered quicker and cleaner to just remove it.` - ).trim(); - } - - async detected() { - const pkg = await this.project.requirePackageJson(); - - if (pkg.scripts && pkg.scripts[SERVE_SCRIPT] === DEFAULT_SERVE_SCRIPT_VALUE) { - return true; - } - - return false; - } - - async getTreatmentSteps() { - return [ - { message: `Remove the ${strong(SERVE_SCRIPT)} npm script from ${strong('package.json')}` }, - { message: `Continue using ${input('ionic serve')} normally` }, - ]; - } -} diff --git a/packages/@ionic/cli/src/lib/project/ionic-angular/app-scripts.ts b/packages/@ionic/cli/src/lib/project/ionic-angular/app-scripts.ts deleted file mode 100644 index 793be39ee4..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic-angular/app-scripts.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { MetadataGroup } from '@ionic/cli-framework'; -import { compileNodeModulesPaths } from '@ionic/cli-framework/utils/node'; -import * as Debug from 'debug'; - -import { CommandMetadataOption } from '../../../definitions'; -import { weak } from '../../color'; - -const debug = Debug('ionic:lib:project:ionic-angular:app-scripts'); - -export async function importAppScripts(projectDir: string): Promise { - const pkg = '@ionic/app-scripts'; - - debug('Importing %s', pkg); - const p = require.resolve(pkg, { paths: compileNodeModulesPaths(projectDir) }); - const m = require(p); - debug('fin'); - - return m; -} - -export const APP_SCRIPTS_OPTIONS: CommandMetadataOption[] = [ - { - name: 'prod', - summary: 'Build the application for production', - type: Boolean, - groups: ['app-scripts', 'cordova'], - hint: weak('[app-scripts]'), - }, - { - name: 'aot', - summary: 'Perform ahead-of-time compilation for this build', - type: Boolean, - groups: [MetadataGroup.ADVANCED, 'app-scripts', 'cordova'], - hint: weak('[app-scripts]'), - }, - { - name: 'minifyjs', - summary: 'Minify JS for this build', - type: Boolean, - groups: [MetadataGroup.ADVANCED, 'app-scripts', 'cordova'], - hint: weak('[app-scripts]'), - }, - { - name: 'minifycss', - summary: 'Minify CSS for this build', - type: Boolean, - groups: [MetadataGroup.ADVANCED, 'app-scripts', 'cordova'], - hint: weak('[app-scripts]'), - }, - { - name: 'optimizejs', - summary: 'Perform JS optimizations for this build', - type: Boolean, - groups: [MetadataGroup.ADVANCED, 'app-scripts', 'cordova'], - hint: weak('[app-scripts]'), - }, - { - name: 'env', - summary: '', - groups: [MetadataGroup.HIDDEN, MetadataGroup.ADVANCED, 'app-scripts', 'cordova'], - hint: weak('[app-scripts]'), - }, -]; diff --git a/packages/@ionic/cli/src/lib/project/ionic-angular/build.ts b/packages/@ionic/cli/src/lib/project/ionic-angular/build.ts deleted file mode 100644 index 8d4b7da8d9..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic-angular/build.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { MetadataGroup, unparseArgs } from '@ionic/cli-framework'; -import * as Debug from 'debug'; - -import { CommandLineInputs, CommandLineOptions, CommandMetadata, IonicAngularBuildOptions } from '../../../definitions'; -import { BUILD_SCRIPT, BuildCLI, BuildRunner, BuildRunnerDeps } from '../../build'; -import { ancillary, input, strong, weak } from '../../color'; - -import { IonicAngularProject } from './'; -import { APP_SCRIPTS_OPTIONS } from './app-scripts'; - -const debug = Debug('ionic:lib:project:ionic-angular:build'); - -export const DEFAULT_PROGRAM = 'ionic-app-scripts'; -export const DEFAULT_BUILD_SCRIPT_VALUE = `${DEFAULT_PROGRAM} build`; - -export interface IonicAngularBuildRunnerDeps extends BuildRunnerDeps { - readonly project: IonicAngularProject; -} - -export class IonicAngularBuildRunner extends BuildRunner { - constructor(protected readonly e: IonicAngularBuildRunnerDeps) { - super(); - } - - async getCommandMetadata(): Promise> { - return { - description: ` -${input('ionic build')} uses ${strong('@ionic/app-scripts')}. See the project's ${strong('README.md')}[^app-scripts-readme] for documentation. Options not listed below are considered advanced and can be passed to the ${input('ionic-app-scripts')} CLI using the ${input('--')} separator after the Ionic CLI arguments. See the examples. - `, - footnotes: [ - { - id: 'app-scripts-readme', - url: 'https://github.com/ionic-team/ionic-app-scripts/blob/master/README.md', - }, - ], - options: [ - { - name: 'source-map', - summary: 'Output sourcemaps', - type: Boolean, - groups: [MetadataGroup.ADVANCED, 'cordova'], - hint: weak('[app-scripts]'), - }, - ...APP_SCRIPTS_OPTIONS, - ], - exampleCommands: [ - '--prod', - ], - }; - } - - createOptionsFromCommandLine(inputs: CommandLineInputs, options: CommandLineOptions): IonicAngularBuildOptions { - const baseOptions = super.createBaseOptionsFromCommandLine(inputs, options); - const sourcemaps = typeof options['source-map'] === 'boolean' ? Boolean(options['source-map']) : undefined; - - return { - ...baseOptions, - type: 'ionic-angular', - prod: options['prod'] ? true : false, - sourcemaps, - aot: options['aot'] ? true : false, - minifyjs: options['minifyjs'] ? true : false, - minifycss: options['minifycss'] ? true : false, - optimizejs: options['optimizejs'] ? true : false, - env: options['env'] ? String(options['env']) : undefined, - }; - } - - async buildProject(options: IonicAngularBuildOptions): Promise { - const appscripts = new IonicAngularBuildCLI(this.e); - await appscripts.build(options); - } -} - -export class IonicAngularBuildCLI extends BuildCLI { - readonly name = 'Ionic App Scripts'; - readonly pkg = '@ionic/app-scripts'; - readonly program = DEFAULT_PROGRAM; - readonly prefix = 'app-scripts'; - readonly script?: string = BUILD_SCRIPT; - - protected buildOptionsToAppScriptsArgs(options: IonicAngularBuildOptions): string[] { - const minimistArgs = { - _: [], - prod: options.prod ? true : false, - aot: options.aot ? true : false, - minifyjs: options.minifyjs ? true : false, - minifycss: options.minifycss ? true : false, - optimizejs: options.optimizejs ? true : false, - generateSourceMap: typeof options.sourcemaps !== 'undefined' ? options.sourcemaps ? 'true' : 'false' : undefined, - target: options.engine === 'cordova' ? 'cordova' : undefined, - platform: options.platform, - env: options.env, - }; - - return [...unparseArgs(minimistArgs, { allowCamelCase: true, useEquals: false }), ...options['--']]; - } - - protected async buildArgs(options: IonicAngularBuildOptions): Promise { - const { pkgManagerArgs } = await import('../../utils/npm'); - - const args = this.buildOptionsToAppScriptsArgs(options); - - if (this.resolvedProgram === this.program) { - return ['build', ...args]; - } else { - const [ , ...pkgArgs ] = await pkgManagerArgs(this.e.config.get('npmClient'), { command: 'run', script: this.script, scriptArgs: [...args] }); - return pkgArgs; - } - } - - protected async resolveProgram(): Promise { - if (typeof this.script !== 'undefined') { - debug(`Looking for ${ancillary(this.script)} npm script.`); - - const pkg = await this.e.project.requirePackageJson(); - - if (pkg.scripts && pkg.scripts[this.script]) { - if (pkg.scripts[this.script] === DEFAULT_BUILD_SCRIPT_VALUE) { - debug(`Found ${ancillary(this.script)}, but it is the default. Not running.`); - } else { - debug(`Using ${ancillary(this.script)} npm script.`); - return this.e.config.get('npmClient'); - } - } - } - - return this.program; - } -} diff --git a/packages/@ionic/cli/src/lib/project/ionic-angular/generate.ts b/packages/@ionic/cli/src/lib/project/ionic-angular/generate.ts deleted file mode 100644 index ddc7fbfa8f..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic-angular/generate.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { contains, unparseArgs, validators } from '@ionic/cli-framework'; - -import { CommandLineInputs, CommandLineOptions, CommandMetadata, IonicAngularGenerateOptions } from '../../../definitions'; -import { input, strong, weak } from '../../color'; -import { GenerateRunner, GenerateRunnerDeps } from '../../generate'; - -import { IonicAngularProject } from './'; -import { importAppScripts } from './app-scripts'; - -const GENERATOR_TYPES = ['component', 'directive', 'page', 'pipe', 'provider', 'tabs']; - -export interface IonicAngularGenerateRunnerDeps extends GenerateRunnerDeps { - readonly project: IonicAngularProject; -} - -export class IonicAngularGenerateRunner extends GenerateRunner { - constructor(protected readonly e: IonicAngularGenerateRunnerDeps) { - super(); - } - - async getCommandMetadata(): Promise> { - return { - groups: [], - summary: `Generate pipes, components, pages, directives, providers, and tabs`, - description: ` -Automatically create components for your Ionic app. - -The given ${input('name')} is normalized into an appropriate naming convention. For example, ${input('ionic generate page neat')} creates a page by the name of ${input('NeatPage')} in ${input('src/pages/neat/')}. - `, - exampleCommands: [ - '', - ...GENERATOR_TYPES, - 'component foo', - 'page Login', - 'page Detail --no-module', - 'page About --constants', - 'pipe MyFilterPipe', - ], - inputs: [ - { - name: 'type', - summary: `The type of generator (e.g. ${GENERATOR_TYPES.map(t => input(t)).join(', ')})`, - validators: [validators.required, contains(GENERATOR_TYPES, {})], - }, - { - name: 'name', - summary: 'The name of the component being generated', - validators: [validators.required], - }, - ], - options: [ - { - name: 'module', - summary: 'Do not generate an NgModule for the page', - hint: weak('[page]'), - type: Boolean, - default: true, - }, - { - name: 'constants', - summary: 'Generate a page constant file for lazy-loaded pages', - hint: weak('[page]'), - type: Boolean, - default: false, - }, - ], - }; - } - - async ensureCommandLine(inputs: CommandLineInputs, options: CommandLineOptions): Promise { - if (!inputs[0]) { - const generatorType = await this.e.prompt({ - type: 'list', - name: 'generatorType', - message: 'What would you like to generate:', - choices: GENERATOR_TYPES, - }); - - inputs[0] = generatorType; - } - - if (!inputs[1]) { - const generatorName = await this.e.prompt({ - type: 'input', - name: 'generatorName', - message: 'What should the name be?', - validate: v => validators.required(v), - }); - - inputs[1] = generatorName; - } - } - - createOptionsFromCommandLine(inputs: CommandLineInputs, options: CommandLineOptions): IonicAngularGenerateOptions { - const baseOptions = super.createOptionsFromCommandLine(inputs, options); - - return { - ...baseOptions, - module: options['module'] ? true : false, - constants: options['constants'] ? true : false, - }; - } - - async run(options: IonicAngularGenerateOptions) { - const AppScripts = await importAppScripts(this.e.project.directory); - - const appScriptsArgs = unparseArgs({ _: [], module: options.module, constants: options.constants }, { useEquals: false, ignoreFalse: true, allowCamelCase: true }); - AppScripts.setProcessArgs(['node', 'appscripts'].concat(appScriptsArgs)); - AppScripts.setCwd(this.e.project.directory); - - const context = AppScripts.generateContext(); - - switch (options.type) { - case 'page': - await AppScripts.processPageRequest(context, options.name, options); - break; - case 'component': - const componentData = await this.getModules(context, 'component'); - await AppScripts.processComponentRequest(context, options.name, componentData); - break; - case 'directive': - const directiveData = await this.getModules(context, 'directive'); - await AppScripts.processDirectiveRequest(context, options.name, directiveData); - break; - case 'pipe': - const pipeData = await this.getModules(context, 'pipe'); - await AppScripts.processPipeRequest(context, options.name, pipeData); - break; - case 'provider': - const providerData = context.appNgModulePath; - await AppScripts.processProviderRequest(context, options.name, providerData); - break; - case 'tabs': - const tabsData = await this.tabsPrompt(); - await AppScripts.processTabsRequest(context, options.name, tabsData, options); - break; - } - - this.e.log.ok(`Generated a ${strong(options.type)}${options.type === 'tabs' ? ' page' : ''} named ${strong(options.name)}!`); - } - - async tabsPrompt() { - const tabNames = []; - - const howMany = await this.e.prompt({ - type: 'input', - name: 'howMany', - message: 'How many tabs?', - validate: v => validators.numeric(v), - }); - - for (let i = 0; i < parseInt(howMany, 10); i++) { - const tabName = await this.e.prompt({ - type: 'input', - name: 'tabName', - message: 'Name of this tab:', - }); - - tabNames.push(tabName); - } - - return tabNames; - } - - async getModules(context: any, kind: string) { - switch (kind) { - case 'component': - return context.componentsNgModulePath ? context.componentsNgModulePath : context.appNgModulePath; - case 'pipe': - return context.pipesNgModulePath ? context.pipesNgModulePath : context.appNgModulePath; - case 'directive': - return context.directivesNgModulePath ? context.directivesNgModulePath : context.appNgModulePath; - } - } -} diff --git a/packages/@ionic/cli/src/lib/project/ionic-angular/index.ts b/packages/@ionic/cli/src/lib/project/ionic-angular/index.ts deleted file mode 100644 index 1e93ef8b5f..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic-angular/index.ts +++ /dev/null @@ -1,89 +0,0 @@ -import * as Debug from 'debug'; -import * as lodash from 'lodash'; - -import { Project } from '../'; -import { IAilmentRegistry, InfoItem } from '../../../definitions'; -import { strong } from '../../color'; - -const debug = Debug('ionic:lib:project:ionic-angular'); - -export class IonicAngularProject extends Project { - readonly type: 'ionic-angular' = 'ionic-angular'; - - async getInfo(): Promise { - const [ - [ ionicAngularPkg ], - [ appScriptsPkg ], - ] = await Promise.all([ - this.getPackageJson('ionic-angular'), - this.getPackageJson('@ionic/app-scripts'), - ]); - - return [ - ...(await super.getInfo()), - { - group: 'ionic', - name: 'Ionic Framework', - key: 'framework', - value: ionicAngularPkg ? `ionic-angular ${ionicAngularPkg.version}` : 'not installed', - }, - { - group: 'ionic', - name: '@ionic/app-scripts', - key: 'app_scripts_version', - value: appScriptsPkg ? appScriptsPkg.version : 'not installed', - }, - ]; - } - - async getDocsUrl(): Promise { - return 'https://ion.link/v3-docs'; - } - - async registerAilments(registry: IAilmentRegistry): Promise { - await super.registerAilments(registry); - const ailments = await import('./ailments'); - const deps = { ...this.e, project: this }; - - registry.register(new ailments.IonicAngularUpdateAvailable(deps)); - registry.register(new ailments.IonicAngularMajorUpdateAvailable(deps)); - registry.register(new ailments.AppScriptsUpdateAvailable(deps)); - registry.register(new ailments.AppScriptsMajorUpdateAvailable(deps)); - registry.register(new ailments.IonicAngularPackageJsonHasDefaultIonicBuildCommand(deps)); - registry.register(new ailments.IonicAngularPackageJsonHasDefaultIonicServeCommand(deps)); - } - - async detected() { - try { - const pkg = await this.requirePackageJson(); - const deps = lodash.assign({}, pkg.dependencies, pkg.devDependencies); - - if (typeof deps['ionic-angular'] === 'string') { - debug(`${strong('ionic-angular')} detected in ${strong('package.json')}`); - return true; - } - } catch (e) { - // ignore - } - - return false; - } - - async requireBuildRunner(): Promise { - const { IonicAngularBuildRunner } = await import('./build'); - const deps = { ...this.e, project: this }; - return new IonicAngularBuildRunner(deps); - } - - async requireServeRunner(): Promise { - const { IonicAngularServeRunner } = await import('./serve'); - const deps = { ...this.e, project: this }; - return new IonicAngularServeRunner(deps); - } - - async requireGenerateRunner(): Promise { - const { IonicAngularGenerateRunner } = await import('./generate'); - const deps = { ...this.e, project: this }; - return new IonicAngularGenerateRunner(deps); - } -} diff --git a/packages/@ionic/cli/src/lib/project/ionic-angular/serve.ts b/packages/@ionic/cli/src/lib/project/ionic-angular/serve.ts deleted file mode 100644 index 045947e716..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic-angular/serve.ts +++ /dev/null @@ -1,212 +0,0 @@ -import { MetadataGroup, ParsedArgs, unparseArgs } from '@ionic/cli-framework'; -import { str2num } from '@ionic/cli-framework/utils/string'; -import * as Debug from 'debug'; - -import { CommandLineInputs, CommandLineOptions, CommandMetadata, IonicAngularServeOptions, ServeDetails } from '../../../definitions'; -import { ancillary, weak } from '../../color'; -import { BIND_ALL_ADDRESS, DEFAULT_DEV_LOGGER_PORT, DEFAULT_LIVERELOAD_PORT, LOCAL_ADDRESSES, SERVE_SCRIPT, ServeCLI, ServeRunner, ServeRunnerDeps } from '../../serve'; -import { findOpenIonicPorts } from '../common'; - -import { IonicAngularProject } from './'; -import { APP_SCRIPTS_OPTIONS } from './app-scripts'; - -const debug = Debug('ionic:lib:project:ionic-angular:serve'); - -const DEFAULT_PROGRAM = 'ionic-app-scripts'; -export const DEFAULT_SERVE_SCRIPT_VALUE = `${DEFAULT_PROGRAM} serve`; - -export interface IonicAngularServeRunnerDeps extends ServeRunnerDeps { - readonly project: IonicAngularProject; -} - -export class IonicAngularServeRunner extends ServeRunner { - constructor(protected readonly e: IonicAngularServeRunnerDeps) { - super(); - } - - async getCommandMetadata(): Promise> { - return { - options: [ - { - name: 'consolelogs', - summary: 'Print app console logs to Ionic CLI', - type: Boolean, - groups: ['cordova'], - aliases: ['c'], - hint: weak('[app-scripts]'), - }, - { - name: 'serverlogs', - summary: 'Print dev server logs to Ionic CLI', - type: Boolean, - aliases: ['s'], - groups: [MetadataGroup.HIDDEN, 'cordova'], - hint: weak('[app-scripts]'), - }, - { - name: 'livereload-port', - summary: 'Use specific port for live-reload', - default: DEFAULT_LIVERELOAD_PORT.toString(), - aliases: ['r'], - groups: [MetadataGroup.ADVANCED, 'cordova'], - hint: weak('[app-scripts]'), - spec: { value: 'port' }, - }, - { - name: 'dev-logger-port', - summary: 'Use specific port for dev server', - default: DEFAULT_DEV_LOGGER_PORT.toString(), - groups: [MetadataGroup.ADVANCED, 'cordova'], - hint: weak('[app-scripts]'), - spec: { value: 'port' }, - }, - { - name: 'proxy', - summary: 'Do not add proxies', - type: Boolean, - default: true, - groups: [MetadataGroup.ADVANCED, 'cordova'], - hint: weak('[app-scripts]'), - // TODO: Adding 'x' to aliases here has some weird behavior with minimist. - }, - { - name: 'source-map', - summary: 'Output sourcemaps', - type: Boolean, - groups: [MetadataGroup.ADVANCED, 'cordova'], - hint: weak('[app-scripts]'), - }, - ...APP_SCRIPTS_OPTIONS, - ], - exampleCommands: [ - '-c', '-- --enableLint false', - ], - }; - } - - createOptionsFromCommandLine(inputs: CommandLineInputs, options: CommandLineOptions): IonicAngularServeOptions { - const baseOptions = super.createOptionsFromCommandLine(inputs, options); - const sourcemaps = typeof options['source-map'] === 'boolean' ? Boolean(options['source-map']) : undefined; - const livereloadPort = str2num(options['livereload-port'], DEFAULT_LIVERELOAD_PORT); - const notificationPort = str2num(options['dev-logger-port'], DEFAULT_DEV_LOGGER_PORT); - - return { - ...baseOptions, - sourcemaps, - consolelogs: options['consolelogs'] ? true : false, - serverlogs: options['serverlogs'] ? true : false, - livereloadPort, - notificationPort, - env: options['env'] ? String(options['env']) : undefined, - }; - } - - modifyOpenUrl(url: string, options: IonicAngularServeOptions): string { - return `${url}${options.browserOption ? options.browserOption : ''}${options.platform ? `?ionicplatform=${options.platform}` : ''}`; - } - - async serveProject(options: IonicAngularServeOptions): Promise { - const [ externalIP, availableInterfaces ] = await this.selectExternalIP(options); - const { port, livereloadPort, notificationPort } = await findOpenIonicPorts(options.host, options); - - options.port = port; - options.livereloadPort = livereloadPort; - options.notificationPort = notificationPort; - - const appscripts = new IonicAngularServeCLI(this.e); - await appscripts.serve(options); - - return { - custom: appscripts.resolvedProgram !== appscripts.program, - protocol: 'http', - localAddress: 'localhost', - externalAddress: externalIP, - externalNetworkInterfaces: availableInterfaces, - port, - externallyAccessible: ![BIND_ALL_ADDRESS, ...LOCAL_ADDRESSES].includes(externalIP), - }; - } - - getUsedPorts(options: IonicAngularServeOptions, details: ServeDetails): number[] { - return [ - ...super.getUsedPorts(options, details), - ...options.livereloadPort ? [options.livereloadPort] : [], - ...options.notificationPort ? [options.notificationPort] : [], - ]; - } -} - -class IonicAngularServeCLI extends ServeCLI { - readonly name = 'Ionic App Scripts'; - readonly pkg = '@ionic/app-scripts'; - readonly program = DEFAULT_PROGRAM; - readonly prefix = 'app-scripts'; - readonly script?: string = SERVE_SCRIPT; - - protected stdoutFilter(line: string): boolean { - if (this.resolvedProgram !== this.program) { - return super.stdoutFilter(line); - } - - if (line.includes('server running')) { - this.emit('ready'); - return false; - } - - return true; - } - - protected async buildArgs(options: IonicAngularServeOptions): Promise { - const { pkgManagerArgs } = await import('../../utils/npm'); - - const args = this.serveOptionsToAppScriptsArgs(options); - - if (this.resolvedProgram === this.program) { - return ['serve', ...args]; - } else { - const [ , ...pkgArgs ] = await pkgManagerArgs(this.e.config.get('npmClient'), { command: 'run', script: this.script, scriptArgs: [...args] }); - return pkgArgs; - } - } - - protected serveOptionsToAppScriptsArgs(options: IonicAngularServeOptions): string[] { - const args: ParsedArgs = { - _: [], - address: options.host, - port: String(options.port), - 'livereload-port': String(options.livereloadPort), - 'dev-logger-port': String(options.notificationPort), - consolelogs: options.consolelogs, - serverlogs: options.serverlogs, - nobrowser: true, - nolivereload: !options.livereload, - noproxy: !options.proxy, - iscordovaserve: options.engine === 'cordova', - generateSourceMap: typeof options.sourcemaps !== 'undefined' ? options.sourcemaps ? 'true' : 'false' : undefined, - platform: options.platform, - target: options.engine === 'cordova' ? 'cordova' : undefined, - env: options.env, - }; - - return [...unparseArgs(args, { allowCamelCase: true, useEquals: false }), ...options['--']]; - } - - protected async resolveProgram(): Promise { - if (typeof this.script !== 'undefined') { - debug(`Looking for ${ancillary(this.script)} npm script.`); - - const pkg = await this.e.project.requirePackageJson(); - - if (pkg.scripts && pkg.scripts[this.script]) { - if (pkg.scripts[this.script] === DEFAULT_SERVE_SCRIPT_VALUE) { - debug(`Found ${ancillary(this.script)}, but it is the default. Not running.`); - } else { - debug(`Using ${ancillary(this.script)} npm script.`); - return this.e.config.get('npmClient'); - } - } - } - - return this.program; - } -} diff --git a/packages/@ionic/cli/src/lib/project/ionic1/__tests__/index.ts b/packages/@ionic/cli/src/lib/project/ionic1/__tests__/index.ts deleted file mode 100644 index 1e330ef2f0..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic1/__tests__/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import * as path from 'path' -import { Ionic1Project } from '../'; - -describe('@ionic/cli', () => { - - describe('lib/project/ionic1', () => { - - describe('Ionic1Project', () => { - - let p: Ionic1Project; - - beforeEach(() => { - p = new Ionic1Project({ context: 'app', configPath: '/path/to/proj/file' } as any, {} as any); - jest.spyOn(p, 'config', 'get').mockImplementation(() => ({ get: () => undefined } as any)); - }); - - it('should set directory attribute', async () => { - expect(p.directory).toEqual(path.resolve('/path/to/proj')); - }); - - }); - - }); - -}); diff --git a/packages/@ionic/cli/src/lib/project/ionic1/__tests__/serve.ts b/packages/@ionic/cli/src/lib/project/ionic1/__tests__/serve.ts deleted file mode 100644 index 50e1888d6d..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic1/__tests__/serve.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Ionic1ServeRunner } from '../serve'; - -describe('@ionic/cli', () => { - - describe('lib/project/ionic1/serve', () => { - - describe('Ionic1ServeRunner', () => { - - describe('createOptionsFromCommandLine', () => { - - const defaults = { - '--': [], - publicHost: undefined, - host: 'localhost', - browser: undefined, - browserOption: undefined, - consolelogs: false, - engine: 'browser', - externalAddressRequired: false, - lab: false, - labHost: 'localhost', - labPort: 8200, - livereload: true, - livereloadPort: 35729, - notificationPort: 53703, - open: false, - port: 8100, - proxy: true, - serverlogs: false, - project: undefined, - verbose: false, - }; - - it('should provide defaults with no options', () => { - const runner = new Ionic1ServeRunner({} as any); - const result = runner.createOptionsFromCommandLine([], { _: [] }); - expect(result).toEqual(defaults); - }); - - it('should provide options from negations of cli flag defaults', () => { - const runner = new Ionic1ServeRunner({} as any); - const result = runner.createOptionsFromCommandLine([], { _: [], livereload: false, proxy: false, lab: true, open: true, externalAddressRequired: true }); - expect(result).toEqual({ ...defaults, livereload: false, proxy: false, lab: true, open: true, externalAddressRequired: true }); - }); - - it('should allow overrides of default values', () => { - const runner = new Ionic1ServeRunner({} as any); - const result = runner.createOptionsFromCommandLine([], { _: [], host: '0.0.0.0', port: '1111', 'livereload-port': '2222', 'dev-logger-port': '3333' }); - expect(result).toEqual({ ...defaults, host: '0.0.0.0', port: 1111, livereloadPort: 2222, notificationPort: 3333 }); - }); - - it('should respect --external flag', () => { - const runner = new Ionic1ServeRunner({} as any); - const result = runner.createOptionsFromCommandLine([], { _: [], host: 'localhost', external: true }); - expect(result).toEqual({ ...defaults, host: '0.0.0.0' }); - }); - - it('should pass on separated args', () => { - const runner = new Ionic1ServeRunner({} as any); - const result = runner.createOptionsFromCommandLine([], { _: [], '--': ['foo', '--bar'] }); - expect(result).toEqual({ ...defaults, '--': ['foo', '--bar'] }); - }); - - }); - - }); - - }); - -}); diff --git a/packages/@ionic/cli/src/lib/project/ionic1/build.ts b/packages/@ionic/cli/src/lib/project/ionic1/build.ts deleted file mode 100644 index ed8e7a1963..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic1/build.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { CommandLineInputs, CommandLineOptions, CommandMetadata, Ionic1BuildOptions } from '../../../definitions'; -import { BUILD_SCRIPT, BuildCLI, BuildRunner, BuildRunnerDeps } from '../../build'; - -import { Ionic1Project } from './'; - -export interface Ionic1BuildRunnerDeps extends BuildRunnerDeps { - readonly project: Ionic1Project; -} - -export class Ionic1BuildRunner extends BuildRunner { - constructor(protected readonly e: Ionic1BuildRunnerDeps) { - super(); - } - - async getCommandMetadata(): Promise> { - return {}; - } - - createOptionsFromCommandLine(inputs: CommandLineInputs, options: CommandLineOptions): Ionic1BuildOptions { - const baseOptions = super.createBaseOptionsFromCommandLine(inputs, options); - - return { - ...baseOptions, - type: 'ionic1', - }; - } - - async buildProject(options: Ionic1BuildOptions): Promise { - const v1 = new Ionic1BuildCLI(this.e); - await v1.build(options); - } -} - -class Ionic1BuildCLI extends BuildCLI { - readonly name = 'Ionic 1 Toolkit'; - readonly pkg = '@ionic/v1-toolkit'; - readonly program = 'ionic-v1'; - readonly prefix = 'v1'; - readonly script = BUILD_SCRIPT; - - protected async buildArgs(options: Ionic1BuildOptions): Promise { - const { pkgManagerArgs } = await import('../../utils/npm'); - - if (this.resolvedProgram === this.program) { - return ['build']; - } else { - const [ , ...pkgArgs ] = await pkgManagerArgs(this.e.config.get('npmClient'), { command: 'run', script: this.script }); - return pkgArgs; - } - } -} diff --git a/packages/@ionic/cli/src/lib/project/ionic1/index.ts b/packages/@ionic/cli/src/lib/project/ionic1/index.ts deleted file mode 100644 index 5d2bb181ad..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic1/index.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { PackageJson } from '@ionic/cli-framework'; -import { readJson } from '@ionic/utils-fs'; -import { prettyPath } from '@ionic/utils-terminal'; -import * as Debug from 'debug'; -import * as lodash from 'lodash'; -import * as path from 'path'; - -import { Project } from '../'; -import { InfoItem } from '../../../definitions'; -import { strong } from '../../color'; -import { FatalException, RunnerNotFoundException } from '../../errors'; - -const debug = Debug('ionic:lib:project:angular'); - -export const ERROR_INVALID_BOWER_JSON = 'INVALID_BOWER_JSON'; - -export interface BowerJson { - name: string; - dependencies?: { [key: string]: string | undefined; }; - devDependencies?: { [key: string]: string | undefined; }; -} - -function isBowerJson(obj: any): obj is BowerJson { - return obj && typeof obj.name === 'string'; -} - -async function readBowerJsonFile(p: string): Promise { - const bowerJson = await readJson(p); - - if (!isBowerJson(bowerJson)) { - throw ERROR_INVALID_BOWER_JSON; - } - - return bowerJson; -} - -export class Ionic1Project extends Project { - readonly type: 'ionic1' = 'ionic1'; - protected bowerJsonFile?: BowerJson; - - async getInfo(): Promise { - const [ - ionic1Version, - [ v1ToolkitPkg ], - ] = await (Promise.all([ - this.getFrameworkVersion(), - this.getPackageJson('@ionic/v1-toolkit'), - ])); - - return [ - ...(await super.getInfo()), - { - group: 'ionic', - name: 'Ionic Framework', - key: 'framework', - value: ionic1Version ? `ionic1 ${ionic1Version}` : 'unknown', - }, - { - group: 'ionic', - name: '@ionic/v1-toolkit', - value: v1ToolkitPkg ? v1ToolkitPkg.version : 'not installed', - }, - ]; - } - - async detected() { - try { - const bwr = await readBowerJsonFile(path.resolve(this.directory, 'bower.json')); - const deps = lodash.assign({}, bwr.dependencies, bwr.devDependencies); - - if (typeof deps['ionic'] === 'string') { - debug(`${strong('ionic')} detected in ${strong('bower.json')}`); - return true; - } - } catch (e) { - // ignore - } - - return false; - } - - async getSourceDir(): Promise { - return this.getDistDir(); // ionic1's source directory is the dist directory - } - - async getDocsUrl(): Promise { - return 'https://ion.link/v1-docs'; - } - - // this method search not only package.json - async getFrameworkVersion(): Promise { - const ionicVersionFilePath = path.resolve(await this.getDistDir(), 'lib', 'ionic', 'version.json'); // TODO - const bowerJsonPath = path.resolve(this.directory, 'bower.json'); - - try { - try { - const ionicVersionJson = await readJson(ionicVersionFilePath); - return ionicVersionJson['version']; - } catch (e) { - const bwr = await this.loadBowerJson(); - const deps = lodash.assign({}, bwr.dependencies, bwr.devDependencies); - - const ionicEntry = deps['ionic']; - - if (!ionicEntry) { - return; - } - - const m = ionicEntry.match(/.+#(.+)/); - - if (m && m[1]) { - return m[1]; - } - } - } catch (e) { - this.e.log.error(`Error with ${strong(prettyPath(bowerJsonPath))} file: ${e}`); - } - } - - async loadBowerJson(): Promise { - if (!this.bowerJsonFile) { - const bowerJsonPath = path.resolve(this.directory, 'bower.json'); - try { - this.bowerJsonFile = await readBowerJsonFile(bowerJsonPath); - } catch (e) { - if (e instanceof SyntaxError) { - throw new FatalException(`Could not parse ${strong('bower.json')}. Is it a valid JSON file?`); - } else if (e === ERROR_INVALID_BOWER_JSON) { - throw new FatalException(`The ${strong('bower.json')} file seems malformed.`); - } - - throw e; // Probably file not found - } - } - - return this.bowerJsonFile; - } - - async requireBuildRunner(): Promise { - const { Ionic1BuildRunner } = await import('./build'); - const deps = { ...this.e, project: this }; - return new Ionic1BuildRunner(deps); - } - - async requireServeRunner(): Promise { - const { Ionic1ServeRunner } = await import('./serve'); - const deps = { ...this.e, project: this }; - return new Ionic1ServeRunner(deps); - } - - async requireGenerateRunner(): Promise { - throw new RunnerNotFoundException('Generators are not supported in Ionic 1 projects.'); - } -} diff --git a/packages/@ionic/cli/src/lib/project/ionic1/serve.ts b/packages/@ionic/cli/src/lib/project/ionic1/serve.ts deleted file mode 100644 index 8a26d68cd9..0000000000 --- a/packages/@ionic/cli/src/lib/project/ionic1/serve.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { MetadataGroup } from '@ionic/cli-framework'; -import { str2num } from '@ionic/cli-framework/utils/string'; - -import { CommandLineInputs, CommandLineOptions, CommandMetadata, Ionic1ServeOptions, ServeDetails } from '../../../definitions'; -import { BIND_ALL_ADDRESS, DEFAULT_DEV_LOGGER_PORT, DEFAULT_LIVERELOAD_PORT, LOCAL_ADDRESSES, SERVE_SCRIPT, ServeCLI, ServeRunner, ServeRunnerDeps } from '../../serve'; -import { findOpenIonicPorts } from '../common'; - -import { Ionic1Project } from './'; - -export interface Ionic1ServeRunnerDeps extends ServeRunnerDeps { - readonly project: Ionic1Project; -} - -export class Ionic1ServeRunner extends ServeRunner { - constructor(protected readonly e: Ionic1ServeRunnerDeps) { - super(); - } - - async getCommandMetadata(): Promise> { - return { - options: [ - { - name: 'consolelogs', - summary: 'Print app console logs to Ionic CLI', - type: Boolean, - groups: ['cordova'], - aliases: ['c'], - }, - { - name: 'serverlogs', - summary: 'Print dev server logs to Ionic CLI', - type: Boolean, - aliases: ['s'], - groups: [MetadataGroup.HIDDEN, 'cordova'], - }, - { - name: 'livereload-port', - summary: 'Use specific port for live-reload', - default: DEFAULT_LIVERELOAD_PORT.toString(), - aliases: ['r'], - groups: [MetadataGroup.ADVANCED, 'cordova'], - spec: { value: 'port' }, - }, - { - name: 'dev-logger-port', - summary: 'Use specific port for dev server communication', - default: DEFAULT_DEV_LOGGER_PORT.toString(), - groups: [MetadataGroup.ADVANCED, 'cordova'], - spec: { value: 'port' }, - }, - { - name: 'proxy', - summary: 'Do not add proxies', - type: Boolean, - default: true, - groups: [MetadataGroup.ADVANCED, 'cordova'], - // TODO: Adding 'x' to aliases here has some weird behavior with minimist. - }, - ], - exampleCommands: [ - '-c', - ], - }; - } - - createOptionsFromCommandLine(inputs: CommandLineInputs, options: CommandLineOptions): Ionic1ServeOptions { - const baseOptions = super.createOptionsFromCommandLine(inputs, options); - const livereloadPort = str2num(options['livereload-port'], DEFAULT_LIVERELOAD_PORT); - const notificationPort = str2num(options['dev-logger-port'], DEFAULT_DEV_LOGGER_PORT); - - return { - ...baseOptions, - consolelogs: options['consolelogs'] ? true : false, - serverlogs: options['serverlogs'] ? true : false, - livereloadPort, - notificationPort, - }; - } - - modifyOpenUrl(url: string, options: Ionic1ServeOptions): string { - return `${url}${options.browserOption ? options.browserOption : ''}${options.platform ? `?ionicplatform=${options.platform}` : ''}`; - } - - async serveProject(options: Ionic1ServeOptions): Promise { - const [ externalIP, availableInterfaces ] = await this.selectExternalIP(options); - const { port, livereloadPort, notificationPort } = await findOpenIonicPorts(options.host, options); - - options.port = port; - options.livereloadPort = livereloadPort; - options.notificationPort = notificationPort; - - const v1 = new Ionic1ServeCLI(this.e); - await v1.serve(options); - - return { - custom: v1.resolvedProgram !== v1.program, - protocol: 'http', - localAddress: 'localhost', - externalAddress: externalIP, - externalNetworkInterfaces: availableInterfaces, - port, - externallyAccessible: ![BIND_ALL_ADDRESS, ...LOCAL_ADDRESSES].includes(externalIP), - }; - } - - getUsedPorts(options: Ionic1ServeOptions, details: ServeDetails): number[] { - return [ - ...super.getUsedPorts(options, details), - ...options.livereloadPort ? [options.livereloadPort] : [], - ...options.notificationPort ? [options.notificationPort] : [], - ]; - } -} - -class Ionic1ServeCLI extends ServeCLI { - readonly name = 'Ionic 1 Toolkit'; - readonly pkg = '@ionic/v1-toolkit'; - readonly program = 'ionic-v1'; - readonly prefix = 'v1'; - readonly script = SERVE_SCRIPT; - - protected stdoutFilter(line: string): boolean { - if (this.resolvedProgram !== this.program) { - return super.stdoutFilter(line); - } - - if (line.includes('server running')) { - this.emit('ready'); - return false; - } - - return true; - } - - protected async buildArgs(options: Ionic1ServeOptions): Promise { - const { pkgManagerArgs } = await import('../../utils/npm'); - - const args = [ - `--host=${options.host}`, - `--port=${String(options.port)}`, - `--livereload-port=${String(options.livereloadPort)}`, - `--dev-port=${String(options.notificationPort)}`, - `--engine=${options.engine}`, - ]; - - if (options.platform) { - args.push(`--platform=${options.platform}`); - } - - if (options.consolelogs) { - args.push('-c'); - } - - if (this.resolvedProgram === this.program) { - return ['serve', ...args]; - } else { - const [ , ...pkgArgs ] = await pkgManagerArgs(this.e.config.get('npmClient'), { command: 'run', script: this.script, scriptArgs: [...args] }); - return pkgArgs; - } - } -}