|
| 1 | +import { BuildEvent, Builder, BuilderConfiguration, BuilderContext } from '@angular-devkit/architect'; |
| 2 | +import { BrowserBuilder } from '@angular-devkit/build-angular/src/browser'; |
| 3 | +import { BrowserBuilderSchema } from '@angular-devkit/build-angular/src/browser/schema'; |
| 4 | +import { getSystemPath, join, normalize } from '@angular-devkit/core'; |
| 5 | +import { Observable, of } from 'rxjs'; |
| 6 | +import { concatMap, tap } from 'rxjs/operators'; |
| 7 | + |
| 8 | +import { CordovaBuildBuilderSchema } from './schema'; |
| 9 | + |
| 10 | +export { CordovaBuildBuilderSchema }; |
| 11 | + |
| 12 | +export class CordovaBuildBuilder implements Builder<CordovaBuildBuilderSchema> { |
| 13 | + constructor(public context: BuilderContext) {} |
| 14 | + |
| 15 | + run(builderConfig: BuilderConfiguration<CordovaBuildBuilderSchema>): Observable<BuildEvent> { |
| 16 | + const browserBuilder = new BrowserBuilder(this.context); // TODO: shouldn't this use `architect.getBuilder()`? |
| 17 | + |
| 18 | + return this.buildBrowserConfig(builderConfig.options).pipe( |
| 19 | + concatMap(browserConfig => browserBuilder.run(browserConfig)) |
| 20 | + ); |
| 21 | + } |
| 22 | + |
| 23 | + buildBrowserConfig(options: CordovaBuildBuilderSchema): Observable<BuilderConfiguration<BrowserBuilderSchema>> { |
| 24 | + let browserConfig: BuilderConfiguration<BrowserBuilderSchema>; |
| 25 | + |
| 26 | + return of(null).pipe(// tslint:disable-line:no-null-keyword |
| 27 | + concatMap(() => this._getBrowserConfig(options)), |
| 28 | + tap(config => browserConfig = config), |
| 29 | + tap(() => this.prepareBrowserConfig(options, browserConfig.options)), |
| 30 | + concatMap(() => of(browserConfig)) |
| 31 | + ); |
| 32 | + } |
| 33 | + |
| 34 | + // Mutates browserOptions |
| 35 | + prepareBrowserConfig(options: CordovaBuildBuilderSchema, browserOptions: BrowserBuilderSchema) { |
| 36 | + const cordovaBasePath = normalize(options.cordovaBasePath ? options.cordovaBasePath : '.'); |
| 37 | + |
| 38 | + // We always need to output the build to `www` because it is a hard |
| 39 | + // requirement of Cordova. |
| 40 | + browserOptions.outputPath = join(cordovaBasePath, normalize('www')); |
| 41 | + |
| 42 | + if (options.cordovaAssets) { |
| 43 | + const platformWWWPath = join(cordovaBasePath, normalize(`platforms/${options.platform}/platform_www`)); |
| 44 | + |
| 45 | + // Add Cordova www assets that were generated whenever platform(s) and |
| 46 | + // plugin(s) are added. This includes `cordova.js`, |
| 47 | + // `cordova_plugins.js`, and all plugin JS. |
| 48 | + browserOptions.assets.push({ |
| 49 | + glob: '**/*', |
| 50 | + input: getSystemPath(platformWWWPath), |
| 51 | + output: './', |
| 52 | + }); |
| 53 | + |
| 54 | + // Register `cordova.js` as a global script so it is included in |
| 55 | + // `index.html`. |
| 56 | + browserOptions.scripts.push({ |
| 57 | + input: getSystemPath(join(platformWWWPath, normalize('cordova.js'))), |
| 58 | + bundleName: 'cordova', |
| 59 | + lazy: false, |
| 60 | + }); |
| 61 | + } |
| 62 | + } |
| 63 | + |
| 64 | + protected _getBrowserConfig(options: CordovaBuildBuilderSchema): Observable<BuilderConfiguration<BrowserBuilderSchema>> { |
| 65 | + const { architect } = this.context; |
| 66 | + const [ project, target, configuration ] = options.browserTarget.split(':'); |
| 67 | + const browserTargetSpec = { project, target, configuration, overrides: {} }; |
| 68 | + const builderConfig = architect.getBuilderConfiguration<BrowserBuilderSchema>(browserTargetSpec); |
| 69 | + |
| 70 | + return architect.getBuilderDescription(builderConfig).pipe( |
| 71 | + concatMap(browserDescription => architect.validateBuilderOptions(builderConfig, browserDescription)) |
| 72 | + ); |
| 73 | + } |
| 74 | +} |
| 75 | + |
| 76 | +export default CordovaBuildBuilder; |
0 commit comments