UNPKG

@nstudio/angular

Version:

Angular Plugin for xplat

286 lines (262 loc) 10.8 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = default_1; const schematics_1 = require("@angular-devkit/schematics"); const devkit_1 = require("@nx/devkit"); const generators_1 = require("@nx/angular/generators"); const xplat_1 = require("@nstudio/xplat"); const xplat_utils_1 = require("@nstudio/xplat-utils"); function default_1(options) { if (!options.name) { throw new schematics_1.SchematicsException((0, xplat_1.missingArgument)('name', 'Provide a name for your app.', 'nx g @nstudio/angular:app my-app')); } if (options.useXplat) { // xplat is configured for sass only (at moment) options.style = 'scss'; } return (0, schematics_1.chain)([ (0, xplat_utils_1.prerun)(options), // adjust naming convention xplat_1.XplatHelpers.applyAppNamingConvention(options, 'web'), // use xplat or not options.useXplat ? (0, schematics_1.externalSchematic)('@nstudio/angular', 'xplat', { platforms: 'web', framework: 'angular', }) : (0, schematics_1.noop)(), (tree, context) => { const nrwlWebOptions = Object.assign(Object.assign({}, options), { standalone: false, skipInstall: true }); // remove non schema validated properties delete nrwlWebOptions.groupByName; delete nrwlWebOptions.useXplat; delete nrwlWebOptions.skipInstall; delete nrwlWebOptions.platforms; delete nrwlWebOptions.framework; delete nrwlWebOptions.isTesting; delete nrwlWebOptions.target; delete nrwlWebOptions.npmScope; delete nrwlWebOptions.setupSandbox; if (!options.directory) { // default to apps nrwlWebOptions.directory = 'apps'; } else if (options.directory.indexOf('apps/') === -1) { // ensure ends up in apps directory nrwlWebOptions.directory = `apps/${options.directory}`; } if (options.useXplat) { // when generating xplat architecture, ensure: // 1. sass is used nrwlWebOptions.style = 'scss'; } // NOTE: This is what this needs to be: return (0, devkit_1.convertNxGenerator)(generators_1.applicationGenerator)(nrwlWebOptions); }, (tree, context) => addHeadlessE2e(options)(tree, context), options.useXplat ? (tree, context) => addAppFiles(options)(tree, context) : (0, schematics_1.noop)(), options.useXplat ? (tree, context) => addAppFiles(options, 'routing')(tree, context) : (0, schematics_1.noop)(), // adjust app files options.useXplat ? (tree, context) => adjustAppFiles(options, tree, context) : (0, schematics_1.noop)(), ]); } /** * Add headless options to e2e tests * @param options */ function addHeadlessE2e(options) { const framework = options.e2eTestRunner; return (0, schematics_1.noop)(); } function addAppFiles(options, extra = '') { extra = extra ? `${extra}_` : ''; const directory = options.directory ? `${options.directory}/` : ''; return (0, schematics_1.branchAndMerge)((0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)(`./_${extra}files`), [ (0, schematics_1.template)(Object.assign(Object.assign(Object.assign({}, options), (0, xplat_1.getDefaultTemplateOptions)()), { xplatFolderName: xplat_1.XplatHelpers.getXplatFoldername('web', 'angular') })), (0, schematics_1.move)(`apps/${directory}${options.name}`), ]))); } function adjustAppFiles(options, tree, context) { return __awaiter(this, void 0, void 0, function* () { const directory = options.directory ? `${options.directory}/` : ''; tree.overwrite(`/apps/${directory}${options.name}/src/index.html`, indexContent(options.name)); tree.overwrite(`/apps/${directory}${options.name}/src/main.ts`, mainContent()); tree.overwrite(`/apps/${directory}${options.name}/src/styles.scss`, `@import 'scss/index';`); tree.overwrite(`/apps/${directory}${options.name}/src/app/app.component.html`, options.routing ? `<router-outlet></router-outlet>` : appCmpHtml(options.name)); if (options.routing) { // update home route to reflect with root cmp would have been tree.overwrite(`/apps/${directory}${options.name}/src/app/features/home/components/home.component.html`, appCmpHtml(options.name)); } tree.overwrite(`/apps/${directory}${options.name}/src/app/app.component.ts`, appCmpContent()); tree.overwrite(`/apps/${directory}${options.name}/src/app/app.component.spec.ts`, appCmpSpec()); tree.overwrite(`/apps/${directory}${options.name}/src/app/app.module.ts`, appModuleContent(options)); return (0, schematics_1.noop)(); }); } function indexContent(name) { return `<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>${(0, xplat_utils_1.getNpmScope)()} ${name}</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <${(0, xplat_utils_1.getPrefix)()}-root></${(0, xplat_utils_1.getPrefix)()}-root> </body> </html>`; } function mainContent() { return `import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; // libs import { environment } from '@${(0, xplat_utils_1.getNpmScope)()}/xplat/core'; // app import { AppModule } from './app/app.module'; if (environment.production) { enableProdMode(); } platformBrowserDynamic() .bootstrapModule(AppModule) .catch(err => console.log(err)); `; } function appCmpHtml(name) { return `<div class="p-x-20"> <${(0, xplat_utils_1.getPrefix)()}-header title="${name}"></${(0, xplat_utils_1.getPrefix)()}-header> <h2>Nx</h2> Nx is a smart and extensible build framework to help you architect, test, and build at any scale — integrating seamlessly with modern technologies and libraries while providing a robust CLI, caching, dependency management, and more. <a href="https://nx.dev">Learn more about Nx.</a> <h1>{{'welcome' | translate}}!</h1> <h3>Try things out</h3> <a href="https://nstudio.io/xplat">Learn more about xplat.</a> </div>`; } function appCmpContent() { return `import { Component } from '@angular/core'; // xplat import { AppBaseComponent } from '@${(0, xplat_utils_1.getNpmScope)()}/xplat/${xplat_1.XplatHelpers.getXplatFoldername('web', 'angular')}/features'; @Component({ selector: '${(0, xplat_utils_1.getPrefix)()}-root', templateUrl: './app.component.html' }) export class AppComponent extends AppBaseComponent { constructor() { super(); } } `; } /** * @todo Pass this initial tests */ function appCmpSpec() { return ` describe('Web App component generic test', () => { it('Should be true', () => { expect(true).toBeTruthy(); }); }); /*import { TestBed, async } from '@angular/core/testing'; import { HttpClient } from '@angular/common/http'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; import { AppComponent } from './app.component'; const translationsEn = require('../assets/i18n/en.json'); export function HttpLoaderFactory(httpClient: HttpClient) { return new TranslateHttpLoader(httpClient); } describe('AppComponent', () => { let translate: TranslateService; let http: HttpTestingController; beforeEach( async(() => { TestBed.configureTestingModule({ imports: [ HttpClientTestingModule, TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient] } }) ], declarations: [AppComponent], providers: [TranslateService] }).compileComponents(); translate = TestBed.get(TranslateService); http = TestBed.get(HttpTestingController); }) ); it( 'should create the app', async(() => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.debugElement.componentInstance; expect(app).toBeTruthy(); }) ); it( 'should render xplat hello in a h2 tag', async(() => { spyOn(translate, 'getBrowserLang').and.returnValue('en'); translate.use('en'); const fixture = TestBed.createComponent(AppComponent); const compiled = fixture.debugElement.nativeElement; // the DOM should be empty for now since the translations haven't been rendered yet expect(compiled.querySelector('h1').textContent).toEqual(''); http.expectOne('/assets/i18n/en.json').flush(translationsEn); // Finally, assert that there are no outstanding requests. http.verify(); fixture.detectChanges(); expect(compiled.querySelector('h2').textContent).toContain( 'Hello xplat' ); }) ); }); */ `; } function appModuleContent(options) { return `import { NgModule } from '@angular/core'; // app import { CoreModule } from './core/core.module'; import { SharedModule } from './features/shared/shared.module'; ${options.routing ? `import { AppRoutingModule } from './app.routing';` : ''} import { AppComponent } from './app.component'; @NgModule({ imports: [ CoreModule, SharedModule${options.routing ? `, AppRoutingModule` : ''} ], declarations: [AppComponent], bootstrap: [AppComponent] }) export class AppModule {} `; }