diff --git a/.gitignore b/.gitignore
index ca31f6aa9..1075883f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,6 +59,15 @@ nativescript/src/**/*.js
nativescript/src/**/*.js.map
nativescript/*.d.ts
!nativescript/src/references.d.ts
+electron/app
+electron/config
+electron/node_modules
+electron/platforms
+electron/src/app
+electron/src/**/*.js
+electron/src/**/*.js.map
+electron/*.d.ts
+!electron/src/references.d.ts
desktop
gulpfile.js
gulpfile.js.map
diff --git a/electron/helpers.js b/electron/helpers.js
new file mode 100644
index 000000000..b62f83f56
--- /dev/null
+++ b/electron/helpers.js
@@ -0,0 +1,40 @@
+var path = require('path');
+var zlib = require('zlib');
+
+
+// Helper functions
+
+function hasProcessFlag(flag) {
+ return process.argv.join('').indexOf(flag) > -1;
+}
+
+function gzipMaxLevel(buffer, callback) {
+ return zlib['gzip'](buffer, {level: 9}, callback);
+}
+
+function root(args) {
+ args = Array.prototype.slice.call(arguments, 0);
+ return path.join.apply(path, [__dirname].concat(args));
+}
+
+function rootNode(args) {
+ args = Array.prototype.slice.call(arguments, 0);
+ return root.apply(path, ['node_modules'].concat(args));
+}
+
+function prependExt(extensions, args) {
+ args = args || [];
+ if (!Array.isArray(args)) { args = [args] }
+ return extensions.reduce(function(memo, val) {
+ return memo.concat(val, args.map(function(prefix) {
+ return prefix + val;
+ }));
+ }, ['']);
+}
+
+exports.hasProcessFlag = hasProcessFlag;
+exports.gzipMaxLevel = gzipMaxLevel;
+exports.root = root;
+exports.rootNode = rootNode;
+exports.prependExt = prependExt;
+exports.prepend = prependExt;
\ No newline at end of file
diff --git a/electron/karma.conf.js b/electron/karma.conf.js
new file mode 100644
index 000000000..1774837de
--- /dev/null
+++ b/electron/karma.conf.js
@@ -0,0 +1,123 @@
+module.exports = function (config) {
+ var testWebpackConfig = require('./webpack.test.js')({ env: 'test' });
+
+ var configuration = {
+
+ // base path that will be used to resolve all patterns (e.g. files, exclude)
+ basePath: '',
+
+ /*
+ * Frameworks to use
+ *
+ * available frameworks: https://npmjs.org/browse/keyword/karma-adapter
+ */
+ frameworks: ['jasmine'],
+
+ // list of files to exclude
+ exclude: [],
+
+ client: {
+ captureConsole: false
+ },
+
+ /*
+ * list of files / patterns to load in the browser
+ *
+ * we are building the test environment in ./spec-bundle.js
+ */
+ files: [
+ { pattern: './config/spec-bundle.js', watched: false },
+ { pattern: './src/assets/**/*', watched: false, included: false, served: true, nocache: false }
+ ],
+
+ /*
+ * By default all assets are served at http://localhost:[PORT]/base/
+ */
+ proxies: {
+ "/assets/": "/base/src/assets/"
+ },
+
+ /*
+ * preprocess matching files before serving them to the browser
+ * available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
+ */
+ preprocessors: { './config/spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] },
+
+ // Webpack Config at ./webpack.test.js
+ webpack: testWebpackConfig,
+
+ coverageReporter: {
+ type: 'in-memory'
+ },
+
+ remapCoverageReporter: {
+ 'text-summary': null,
+ json: './coverage/coverage.json',
+ html: './coverage/html'
+ },
+
+ // Webpack please don't spam the console when running in karma!
+ webpackMiddleware: {
+ // webpack-dev-middleware configuration
+ // i.e.
+ noInfo: true,
+ // and use stats to turn off verbose output
+ stats: {
+ // options i.e.
+ chunks: false
+ }
+ },
+
+ /*
+ * test results reporter to use
+ *
+ * possible values: 'dots', 'progress'
+ * available reporters: https://npmjs.org/browse/keyword/karma-reporter
+ */
+ reporters: ['mocha', 'coverage', 'remap-coverage'],
+
+ // web server port
+ port: 9876,
+
+ // enable / disable colors in the output (reporters and logs)
+ colors: true,
+
+ /*
+ * level of logging
+ * possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+ */
+ logLevel: config.LOG_WARN,
+
+ // enable / disable watching file and executing tests whenever any file changes
+ autoWatch: false,
+
+ /*
+ * start these browsers
+ * available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
+ */
+ browsers: [
+ 'Chrome'
+ ],
+
+ customLaunchers: {
+ ChromeTravisCi: {
+ base: 'Chrome',
+ flags: ['--no-sandbox']
+ }
+ },
+
+ /*
+ * Continuous Integration mode
+ * if true, Karma captures browsers, runs the tests and exits
+ */
+ singleRun: true
+ };
+
+ if (process.env.TRAVIS) {
+ configuration.browsers = [
+ 'ChromeTravisCi'
+ ];
+ }
+
+ config.set(configuration);
+};
\ No newline at end of file
diff --git a/electron/package.js b/electron/package.js
new file mode 100644
index 000000000..8445f03b7
--- /dev/null
+++ b/electron/package.js
@@ -0,0 +1,58 @@
+"use strict";
+
+var packager = require('electron-packager');
+const pkg = require('./package.json');
+const argv = require('minimist')(process.argv.slice(2));
+const devDeps = Object.keys(pkg.devDependencies);
+
+const appName = argv.name || pkg.productName;
+const shouldUseAsar = argv.asar || false;
+const shouldBuildAll = argv.all || false;
+const arch = argv.arch || 'all';
+const platform = argv.platform || 'darwin';
+
+const DEFAULT_OPTS = {
+ dir: './src/app',
+ name: appName,
+ asar: shouldUseAsar,
+ ignore: [
+ ].concat(devDeps.map(name => `/node_modules/${name}($|/)`))
+};
+
+const icon = './src/app/dist/assets/app-icon';
+
+if (icon) {
+ DEFAULT_OPTS.icon = icon;
+}
+
+pack(platform, arch, function done(err, appPath) {
+ console.log(err);
+});
+
+function pack(plat, arch, cb) {
+ // there is no darwin ia32 electron
+ if (plat === 'darwin' && arch === 'ia32') return;
+
+ const iconObj = {
+ icon: DEFAULT_OPTS.icon + (() => {
+ let extension = '.png';
+ if (plat === 'darwin') {
+ extension = '.icns';
+ } else if (plat === 'win32') {
+ extension = '.ico';
+ }
+ return extension;
+ })()
+ };
+
+ const opts = Object.assign({}, DEFAULT_OPTS, iconObj, {
+ platform: plat,
+ arch,
+ prune: true,
+ all: shouldBuildAll,
+ 'app-version': pkg.version || DEFAULT_OPTS.version,
+ out: `release/${plat}-${arch}`
+ });
+
+ packager(opts, cb);
+}
\ No newline at end of file
diff --git a/electron/package.json b/electron/package.json
new file mode 100644
index 000000000..078a2a7b8
--- /dev/null
+++ b/electron/package.json
@@ -0,0 +1,73 @@
+{
+ "name": "angular-seed-advanced",
+ "main": "app.js",
+ "version": "0.0.0",
+ "nativescript": {
+ "id": "com.yourdomain.nativescript",
+ "tns-ios": {
+ "version": "2.5.0"
+ },
+ "tns-android": {
+ "version": "2.5.0"
+ }
+ },
+ "scripts": {
+ "preinstall": "mkdirp app",
+ "clean": "rimraf platforms node_modules lib hooks app && mkdirp app",
+ "ns-bundle": "ns-bundle",
+ "start-android-bundle": "npm run ns-bundle --android --start-app",
+ "start-ios-bundle": "npm run ns-bundle --ios --start-app",
+ "build-android-bundle": "npm run ns-bundle --android --build-app",
+ "build-ios-bundle": "npm run ns-bundle --ios --build-app"
+ },
+ "dependencies": {
+ "@angular/animations": "~4.0.0",
+ "@angular/common": "~4.0.0",
+ "@angular/compiler": "~4.0.0",
+ "@angular/core": "~4.0.0",
+ "@angular/forms": "~4.0.0",
+ "@angular/http": "~4.0.0",
+ "@angular/platform-browser": "~4.0.0",
+ "@angular/platform-browser-dynamic": "~4.0.0",
+ "@angular/router": "~4.0.0",
+ "@ngrx/core": "^1.2.0",
+ "@ngrx/effects": "^2.0.0",
+ "@ngrx/store": "^2.2.1",
+ "@ngx-translate/core": "^6.0.1",
+ "@ngx-translate/http-loader": "0.0.3",
+ "angulartics2": "^1.6.4",
+ "lodash": "^4.17.4",
+ "nativescript-angular": "1.5.0",
+ "nativescript-dev-webpack": "^0.3.1",
+ "nativescript-theme-core": "^1.0.3",
+ "ngrx-store-freeze": "0.1.9",
+ "reflect-metadata": "^0.1.8",
+ "rxjs": "~5.2.0",
+ "tns-core-modules": "^2.5.2",
+ "url": "0.10.3",
+ "zone.js": "~0.8.2"
+ },
+ "devDependencies": {
+ "@angular/compiler-cli": "~4.0.0",
+ "@ngrx/store-devtools": "^3.2.4",
+ "@ngtools/webpack": "~1.3.0",
+ "@types/lodash": "4.14.59",
+ "@types/jasmine": "^2.5.47",
+ "babel-traverse": "6.20.0",
+ "babel-types": "6.20.0",
+ "babylon": "6.14.1",
+ "copy-webpack-plugin": "~4.0.1",
+ "extract-text-webpack-plugin": "~2.1.0",
+ "fs-extra": "^2.1.2",
+ "htmlparser2": "^3.9.2",
+ "lazy": "1.0.11",
+ "nativescript-css-loader": "~0.26.1",
+ "nativescript-dev-android-snapshot": "^0.*.*",
+ "nativescript-dev-webpack": "^0.3.6",
+ "raw-loader": "~0.5.1",
+ "resolve-url-loader": "~2.0.2",
+ "typescript": "~2.1.4",
+ "webpack": "2.3.2",
+ "webpack-sources": "~0.2.3"
+ }
+}
\ No newline at end of file
diff --git a/electron/src/_common.scss b/electron/src/_common.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/electron/src/app.scss b/electron/src/app.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/electron/src/app.ts b/electron/src/app.ts
new file mode 100644
index 000000000..8db53d358
--- /dev/null
+++ b/electron/src/app.ts
@@ -0,0 +1,7 @@
+// nativescript
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+// app
+import { ElectronModule } from './electron.module';
+
+platformBrowserDynamic().bootstrapModule(ElectronModule);
diff --git a/electron/src/assets/data.json b/electron/src/assets/data.json
new file mode 100644
index 000000000..d371e9ce9
--- /dev/null
+++ b/electron/src/assets/data.json
@@ -0,0 +1,6 @@
+[
+ "Edsger Dijkstra",
+ "Donald Knuth",
+ "Alan Turing",
+ "Grace Hopper"
+]
diff --git a/electron/src/assets/favicon/favicon-DEV.ico b/electron/src/assets/favicon/favicon-DEV.ico
new file mode 100644
index 000000000..2b6c8f0a9
Binary files /dev/null and b/electron/src/assets/favicon/favicon-DEV.ico differ
diff --git a/electron/src/assets/favicon/favicon-PROD.ico b/electron/src/assets/favicon/favicon-PROD.ico
new file mode 100644
index 000000000..7556dacd7
Binary files /dev/null and b/electron/src/assets/favicon/favicon-PROD.ico differ
diff --git a/electron/src/assets/i18n/bg.json b/electron/src/assets/i18n/bg.json
new file mode 100644
index 000000000..60d246079
--- /dev/null
+++ b/electron/src/assets/i18n/bg.json
@@ -0,0 +1,11 @@
+{
+ "HOME": "у дома",
+ "ABOUT": "около",
+ "HELLO": "Здравей",
+ "LOVE_TECH": "Обичам технологиите!",
+ "ABOUT_ADD": "Искаш повече? Добавете ги себе си!",
+ "ABOUT_REWARD": "За награда, тук е списък на страхотни компютърни специалисти:",
+ "INPUT_HINT": "Въвеждане на нов компютърен специалист...",
+ "ADD_BTN_TEXT": "Добави",
+ "SUCCESS_MSG": "Вашият разполагане на ъгловото Seed Advanced работи перфектно."
+}
diff --git a/electron/src/assets/i18n/en.json b/electron/src/assets/i18n/en.json
new file mode 100644
index 000000000..97814db05
--- /dev/null
+++ b/electron/src/assets/i18n/en.json
@@ -0,0 +1,11 @@
+{
+ "HOME": "Home",
+ "ABOUT": "About",
+ "HELLO": "Hello",
+ "LOVE_TECH": "I love technology!",
+ "ABOUT_ADD": "You want more? Add them yourself!",
+ "ABOUT_REWARD": "For reward, here is a list of awesome computer scientists:",
+ "INPUT_HINT": "Enter a new computer scientist...",
+ "ADD_BTN_TEXT": "Add",
+ "SUCCESS_MSG": "Your deployment of Angular Seed Advanced worked perfectly."
+}
diff --git a/electron/src/assets/i18n/es.json b/electron/src/assets/i18n/es.json
new file mode 100644
index 000000000..37e890520
--- /dev/null
+++ b/electron/src/assets/i18n/es.json
@@ -0,0 +1,11 @@
+{
+ "HOME": "Casa",
+ "ABOUT": "Acerca de",
+ "HELLO": "Hola",
+ "LOVE_TECH": "Me encanta la tecnología!",
+ "ABOUT_ADD": "¿Quieres más? Añadir a ti mismo!",
+ "ABOUT_REWARD": "Para recompensa, aquí hay una lista de científicos informáticos impresionantes:",
+ "INPUT_HINT": "Introduzca un nuevo científico de la computación...",
+ "ADD_BTN_TEXT": "Añadir",
+ "SUCCESS_MSG": "Su despliegue de Angular avanzada Semilla funcionó a la perfección."
+}
diff --git a/electron/src/assets/i18n/fr.json b/electron/src/assets/i18n/fr.json
new file mode 100644
index 000000000..8d72aa98e
--- /dev/null
+++ b/electron/src/assets/i18n/fr.json
@@ -0,0 +1,11 @@
+{
+ "HOME": "Accueil",
+ "ABOUT": "À propos",
+ "HELLO": "Bonjour",
+ "LOVE_TECH": "J'adore la technologie !",
+ "ABOUT_ADD": "Vous en voulez plus? Ajoutez-les vous-même !",
+ "ABOUT_REWARD": "En récompense, voici une liste de géniaux informaticiens :",
+ "INPUT_HINT": "Ajouter un nouvel informaticien...",
+ "ADD_BTN_TEXT": "Ajouter",
+ "SUCCESS_MSG": "Votre déploiement d'Angular Seed Advanced a parfaitement fonctionné."
+}
diff --git a/electron/src/assets/i18n/ru.json b/electron/src/assets/i18n/ru.json
new file mode 100644
index 000000000..433ec6b3c
--- /dev/null
+++ b/electron/src/assets/i18n/ru.json
@@ -0,0 +1,11 @@
+{
+ "HOME": "Главная",
+ "ABOUT": "Справка",
+ "HELLO": "Здравствуйте",
+ "LOVE_TECH": "Я люблю технологию!",
+ "ABOUT_ADD": "Хочешь больше? Добавь их самостоятельно!",
+ "ABOUT_REWARD": "В награду, вот список классных компьютерных ученых:",
+ "INPUT_HINT": "Введите нового ученого...",
+ "ADD_BTN_TEXT": "Добавить",
+ "SUCCESS_MSG": "Ваш Angular Seed Advanced развернут отлично."
+}
diff --git a/electron/src/assets/logo.icns b/electron/src/assets/logo.icns
new file mode 100644
index 000000000..983a10d3e
Binary files /dev/null and b/electron/src/assets/logo.icns differ
diff --git a/electron/src/assets/logo.ico b/electron/src/assets/logo.ico
new file mode 100644
index 000000000..eb28b1385
Binary files /dev/null and b/electron/src/assets/logo.ico differ
diff --git a/electron/src/assets/svg/more.svg b/electron/src/assets/svg/more.svg
new file mode 100644
index 000000000..1b6b1dd01
--- /dev/null
+++ b/electron/src/assets/svg/more.svg
@@ -0,0 +1,7 @@
+
diff --git a/electron/src/assets/svg/smile.svg b/electron/src/assets/svg/smile.svg
new file mode 100644
index 000000000..368c12e4c
--- /dev/null
+++ b/electron/src/assets/svg/smile.svg
@@ -0,0 +1,170 @@
+
+
+
+
diff --git a/electron/src/electron.module.ts b/electron/src/electron.module.ts
new file mode 100644
index 000000000..d3b7728a5
--- /dev/null
+++ b/electron/src/electron.module.ts
@@ -0,0 +1,100 @@
+// angular
+import { NgModule } from '@angular/core';
+import { APP_BASE_HREF } from '@angular/common';
+import { BrowserModule } from '@angular/platform-browser';
+import { RouterModule } from '@angular/router';
+import { Http } from '@angular/http';
+
+// libs
+import { StoreModule } from '@ngrx/store';
+import { EffectsModule } from '@ngrx/effects';
+import { StoreDevtoolsModule } from '@ngrx/store-devtools';
+import { TranslateLoader } from '@ngx-translate/core';
+
+// app
+import { APP_COMPONENTS, AppComponent } from './app/components/index';
+import { routes } from './app/components/app.routes';
+
+// feature modules
+import { CoreModule } from './app/shared/core/core.module';
+import { AppReducer } from './app/shared/ngrx/index';
+import { AnalyticsModule } from './app/shared/analytics/analytics.module';
+import { MultilingualModule, translateLoaderFactory } from './app/shared/i18n/multilingual.module';
+import { MultilingualEffects } from './app/shared/i18n/index';
+import { SampleModule } from './app/shared/sample/sample.module';
+import { NameListEffects } from './app/shared/sample/index';
+
+// config
+import { Config, WindowService, ConsoleService } from './app/shared/core/index';
+Config.PLATFORM_TARGET = Config.PLATFORMS.WEB;
+if (String('<%= BUILD_TYPE %>') === 'dev') {
+ // only output console logging in dev mode
+ Config.DEBUG.LEVEL_4 = true;
+}
+
+// sample config (extra)
+import { AppConfig } from './app/shared/sample/services/app-config';
+import { MultilingualService } from './app/shared/i18n/services/multilingual.service';
+// custom i18n language support
+MultilingualService.SUPPORTED_LANGUAGES = AppConfig.SUPPORTED_LANGUAGES;
+
+let routerModule = RouterModule.forRoot(routes);
+
+if (String('<%= TARGET_DESKTOP %>') === 'true') {
+ Config.PLATFORM_TARGET = Config.PLATFORMS.DESKTOP;
+ // desktop (electron) must use hash
+ routerModule = RouterModule.forRoot(routes, {useHash: true});
+}
+
+declare var window, console;
+
+// For AoT compilation to work:
+export function win() {
+ return window;
+}
+export function cons() {
+ return console;
+}
+
+let DEV_IMPORTS: any[] = [];
+
+if (String('<%= BUILD_TYPE %>') === 'dev') {
+ DEV_IMPORTS = [
+ ...DEV_IMPORTS,
+ StoreDevtoolsModule.instrumentOnlyWithExtension()
+ ];
+}
+
+@NgModule({
+ imports: [
+ BrowserModule,
+ CoreModule.forRoot([
+ { provide: WindowService, useFactory: (win) },
+ { provide: ConsoleService, useFactory: (cons) }
+ ]),
+ routerModule,
+ AnalyticsModule,
+ MultilingualModule.forRoot([{
+ provide: TranslateLoader,
+ deps: [Http],
+ useFactory: (translateLoaderFactory)
+ }]),
+ SampleModule,
+ StoreModule.provideStore(AppReducer),
+ DEV_IMPORTS,
+ EffectsModule.run(MultilingualEffects),
+ EffectsModule.run(NameListEffects)
+ ],
+ declarations: [
+ APP_COMPONENTS
+ ],
+ providers: [
+ {
+ provide: APP_BASE_HREF,
+ useValue: '<%= APP_BASE %>'
+ }
+ ],
+ bootstrap: [AppComponent]
+})
+
+export class ElectronModule { }
diff --git a/electron/src/main.desktop.ts b/electron/src/main.desktop.ts
new file mode 100644
index 000000000..9a16ad174
--- /dev/null
+++ b/electron/src/main.desktop.ts
@@ -0,0 +1,270 @@
+process.env.NODE_ENV = process.env.NODE_ENV || 'production';
+console.log(`Electron launching with NODE_ENV: ${process.env.NODE_ENV}`);
+
+// electron
+const electron = require('electron');
+const app = electron.app;
+const Menu: any = electron.Menu;
+const shell: any = electron.shell;
+// const {crashReporter} = require('electron');
+const BrowserWindow = electron.BrowserWindow;
+let mainWindow: any = null;
+let template: any;
+let menu: any;
+
+// app
+import { DesktopConfig } from './app/shared/electron/index';
+
+// Sample
+// You would need a valid `submitURL` to use
+// crashReporter.start({
+// productName: 'AngularSeedAdvanced',
+// companyName: 'NathanWalker',
+// submitURL: 'https://github.com/NathanWalker/angular-seed-advanced',
+// autoSubmit: true
+// });
+
+if (process.env.NODE_ENV === 'development') {
+ require('electron-debug')();
+}
+
+app.on('window-all-closed', () => {
+ if (process.platform !== 'darwin') {
+ app.quit();
+ }
+});
+
+app.on('ready', () => {
+
+ // Initialize the window to our specified dimensions
+ mainWindow = new BrowserWindow({ width: 900, height: 620 });
+
+ // Tell Electron where to load the entry point from
+ mainWindow.loadURL('file://' + __dirname + '/index.html');
+
+ // Clear out the main window when the app is closed
+ mainWindow.on('closed', () => {
+ mainWindow = null;
+ });
+
+ mainWindow.webContents.on('did-navigate-in-page', (e: any, url: string) => {
+ console.log(`Page navigated: ${url}`);
+ });
+
+ let appTitle: string = `Angular Seed Advanced`;
+
+ let langMenu: any = {
+ label: 'Language',
+ submenu: []
+ };
+ for (var lang of DesktopConfig.SUPPORTED_LANGUAGES) {
+ let code = lang.code;
+ let langOption = {
+ label: lang.title,
+ click:() => {
+ console.log(`Change lang: ${code}`);
+ mainWindow.webContents.executeJavaScript(`window.dispatchEvent(new CustomEvent('changeLang', {detail: { value: '${code}'} }));`);
+ }
+ };
+ langMenu.submenu.push(langOption);
+ }
+
+ let helpMenu: any = {
+ label: 'Help',
+ submenu: [{
+ label: 'Learn More',
+ click:() => {
+ shell.openExternal('https://github.com/NathanWalker/angular-seed-advanced');
+ }
+ }, {
+ label: 'Issues',
+ click:() => {
+ shell.openExternal('https://github.com/NathanWalker/angular-seed-advanced/issues');
+ }
+ }, {
+ label: `My Amazing Parent: Minko Gechev's Angular Seed`,
+ click:() => {
+ shell.openExternal('https://github.com/mgechev/angular-seed');
+ }
+ }, {
+ label: 'Angular 2',
+ click:() => {
+ shell.openExternal('https://angular.io/');
+ }
+ }, {
+ label: 'Electron',
+ click:() => {
+ shell.openExternal('http://electron.atom.io/');
+ }
+ }, {
+ label: 'Electron Docs',
+ click: () => {
+ shell.openExternal('https://github.com/atom/electron/tree/master/docs');
+ }
+ }, {
+ label: 'Codeology Visualization',
+ click:() => {
+ shell.openExternal('http://codeology.braintreepayments.com/nathanwalker/angular-seed-advanced');
+ }
+ }]
+ };
+
+ if (process.platform === 'darwin') {
+ template = [{
+ label: appTitle,
+ submenu: [{
+ label: `About ${appTitle}`,
+ selector: 'orderFrontStandardAboutPanel:'
+ }, {
+ type: 'separator'
+ }, {
+ label: 'Services',
+ submenu: []
+ }, {
+ type: 'separator'
+ }, {
+ label: 'Hide Angular Seed Advanced',
+ accelerator: 'Command+H',
+ selector: 'hide:'
+ }, {
+ label: 'Hide Others',
+ accelerator: 'Command+Shift+H',
+ selector: 'hideOtherApplications:'
+ }, {
+ label: 'Show All',
+ selector: 'unhideAllApplications:'
+ }, {
+ type: 'separator'
+ }, {
+ label: 'Quit',
+ accelerator: 'Command+Q',
+ click:() => {
+ app.quit();
+ }
+ }]
+ }, {
+ label: 'Edit',
+ submenu: [{
+ label: 'Undo',
+ accelerator: 'Command+Z',
+ selector: 'undo:'
+ }, {
+ label: 'Redo',
+ accelerator: 'Shift+Command+Z',
+ selector: 'redo:'
+ }, {
+ type: 'separator'
+ }, {
+ label: 'Cut',
+ accelerator: 'Command+X',
+ selector: 'cut:'
+ }, {
+ label: 'Copy',
+ accelerator: 'Command+C',
+ selector: 'copy:'
+ }, {
+ label: 'Paste',
+ accelerator: 'Command+V',
+ selector: 'paste:'
+ }, {
+ label: 'Select All',
+ accelerator: 'Command+A',
+ selector: 'selectAll:'
+ }]
+ }, {
+ label: 'View',
+ submenu: (process.env.NODE_ENV === 'development') ? [{
+ label: 'Reload',
+ accelerator: 'Command+R',
+ click:() => {
+ mainWindow.reload();
+ }
+ }, {
+ label: 'Toggle Full Screen',
+ accelerator: 'Ctrl+Command+F',
+ click:() => {
+ mainWindow.setFullScreen(!mainWindow.isFullScreen());
+ }
+ }, {
+ label: 'Toggle Developer Tools',
+ accelerator: 'Alt+Command+I',
+ click:() => {
+ mainWindow.toggleDevTools();
+ }
+ }] : [{
+ label: 'Toggle Full Screen',
+ accelerator: 'Ctrl+Command+F',
+ click:() => {
+ mainWindow.setFullScreen(!mainWindow.isFullScreen());
+ }
+ }]
+ }, {
+ label: 'Window',
+ submenu: [{
+ label: 'Minimize',
+ accelerator: 'Command+M',
+ selector: 'performMiniaturize:'
+ }, {
+ label: 'Close',
+ accelerator: 'Command+W',
+ selector: 'performClose:'
+ }, {
+ type: 'separator'
+ }, {
+ label: 'Bring All to Front',
+ selector: 'arrangeInFront:'
+ }]
+ },
+ langMenu,
+ helpMenu];
+
+ menu = Menu.buildFromTemplate(template);
+ Menu.setApplicationMenu(menu);
+ } else {
+ template = [{
+ label: '&File',
+ submenu: [{
+ label: '&Open',
+ accelerator: 'Ctrl+O'
+ }, {
+ label: '&Close',
+ accelerator: 'Ctrl+W',
+ click:() => {
+ mainWindow.close();
+ }
+ }]
+ }, {
+ label: '&View',
+ submenu: (process.env.NODE_ENV === 'development') ? [{
+ label: '&Reload',
+ accelerator: 'Ctrl+R',
+ click:() => {
+ mainWindow.reload();
+ }
+ }, {
+ label: 'Toggle &Full Screen',
+ accelerator: 'F11',
+ click:() => {
+ mainWindow.setFullScreen(!mainWindow.isFullScreen());
+ }
+ }, {
+ label: 'Toggle &Developer Tools',
+ accelerator: 'Alt+Ctrl+I',
+ click:() => {
+ mainWindow.toggleDevTools();
+ }
+ }] : [{
+ label: 'Toggle &Full Screen',
+ accelerator: 'F11',
+ click:() => {
+ mainWindow.setFullScreen(!mainWindow.isFullScreen());
+ }
+ }]
+ },
+ langMenu,
+ helpMenu];
+ menu = Menu.buildFromTemplate(template);
+ mainWindow.setMenu(menu);
+ }
+
+});
diff --git a/electron/src/package.json b/electron/src/package.json
new file mode 100644
index 000000000..102631975
--- /dev/null
+++ b/electron/src/package.json
@@ -0,0 +1,5 @@
+{
+ "name": "angular-seed-advanced",
+ "version": "1.0.0",
+ "main": "main.desktop.js"
+}
diff --git a/electron/src/polyfills.ts b/electron/src/polyfills.ts
new file mode 100644
index 000000000..27f20b00d
--- /dev/null
+++ b/electron/src/polyfills.ts
@@ -0,0 +1,13 @@
+import 'core-js/es6';
+import 'core-js/es7/reflect';
+require('zone.js/dist/zone.js');
+//Error['stackTraceLimit'] = Infinity;
+
+require('zone.js/dist/long-stack-trace-zone');
+
+// RxJS
+// to include every operator uncomment
+// require('rxjs/Rx');
+
+require('rxjs/add/operator/map');
+require('rxjs/add/operator/mergeMap');
\ No newline at end of file
diff --git a/electron/src/tsconfig.json b/electron/src/tsconfig.json
new file mode 100644
index 000000000..58aaff659
--- /dev/null
+++ b/electron/src/tsconfig.json
@@ -0,0 +1,39 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "module": "commonjs",
+ "declaration": false,
+ "removeComments": true,
+ "noLib": false,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "lib": [
+ "es6",
+ "dom",
+ "es2015.iterable"
+ ],
+ "sourceMap": true,
+ "pretty": true,
+ "noEmitHelpers": true,
+ "allowUnreachableCode": false,
+ "allowUnusedLabels": false,
+ "noImplicitAny": false,
+ "noImplicitReturns": true,
+ "noImplicitUseStrict": false,
+ "noFallthroughCasesInSwitch": true,
+ "typeRoots": [
+ "../node_modules/@types",
+ "../node_modules"
+ ],
+ "types": [
+ "jasmine",
+ "node"
+ ]
+ },
+ "exclude": [
+ "node_modules",
+ "platforms",
+ "*.aot.ts"
+ ],
+ "compileOnSave": false
+}
diff --git a/electron/src/vendor.ts b/electron/src/vendor.ts
new file mode 100644
index 000000000..f085d3f93
--- /dev/null
+++ b/electron/src/vendor.ts
@@ -0,0 +1,9 @@
+require('./vendor-platform');
+
+require('reflect-metadata');
+require('@angular/platform-browser');
+require('@angular/core');
+require('@angular/common');
+require('@angular/forms');
+require('@angular/http');
+require('@angular/router');
diff --git a/electron/tools/webpack/elec-loader.js b/electron/tools/webpack/elec-loader.js
new file mode 100644
index 000000000..127e57cc2
--- /dev/null
+++ b/electron/tools/webpack/elec-loader.js
@@ -0,0 +1,137 @@
+const fs = require('fs-extra');
+const loaderUtils = require('loader-utils');;
+const _ = require('lodash');
+const template = _.template;
+
+const htmlCssRegexp = /\.component\.(html|css)/;
+const htmlCssReplaceStr = '.component.elec.\$1';
+const serviceRegexp = /\.service\.(ts|js)/;
+const serviceReplaceStr = '.service.elec.\$1';
+const componentRegexp = /\.component\.(ts|js)/;
+const componentReplaceStr = '.component.elec.\$1';
+const componentFactoryRegexp = /\.component\.ngfactory\.(ts|js)/;
+
+const ng2TemplateUrlRegex = /templateUrl *:(.*)$/gm;
+const ng2StyleUrlsRegex = /styleUrls *:(\s*\[[^\]]*?\])/g;
+const ng2StringReplaceRegexp = /(['"])((?:[^\\]\\\1|.)*?)\1/g;
+const ng2ModuleIdRegexp = /(moduleId *: *module\.id,)$/gm;
+
+function replaceViewStringsWithRequires(string) {
+ return string.replace(ng2StringReplaceRegexp, function (match, quote, url) {
+ if (url.charAt(0) !== '.') {
+ url = './' + url;
+ }
+
+ const elecViewPath = url.replace(htmlCssRegexp, htmlCssReplaceStr);
+ if (fs.existsSync(elecViewPath)) {
+ return 'require(\'' + elecViewPath + '\')';
+ }
+
+ return 'require(\'' + url + '\')';
+ });
+}
+
+function replaceServiceStringsWithRequires(string) {
+ return string.replace(ng2StringReplaceRegexp, function (match, quote, url) {
+ if (url.charAt(0) !== '.') {
+ url = './' + url;
+ }
+
+ const elecSvcPath = url.replace(serviceRegexp, serviceReplaceStr);
+ if (fs.existsSync(elecSvcPath)) {
+ return 'require(\'' + elecSvcPath + '\')';
+ }
+
+ return 'require(\'' + url + '\')';
+ });
+}
+
+function replaceComponentStringsWithRequires(string) {
+ return string.replace(ng2StringReplaceRegexp, function (match, quote, url) {
+ if (url.charAt(0) !== '.') {
+ url = './' + url;
+ }
+
+ const elecCmpPath = url.replace(serviceRegexp, serviceReplaceStr);
+ if (fs.existsSync(elecCmpPath)) {
+ return 'require(\'' + elecCmpPath + '\')';
+ }
+
+ return 'require(\'' + url + '\')';
+ });
+}
+
+function injectTemplateVariables(loaderContext, source) {
+ // Inject template variables via lodash.template
+ // Note: We only support the '= varname ?>' syntax (default matches and breaks on es6 string literals).
+ const query = loaderUtils.getOptions(loaderContext);
+
+ const tpl = template(source, {
+ interpolate: /<%=([\s\S]+?)%>/g,
+ });
+
+ return tpl(query.data);
+}
+
+module.exports = function tnsLoader(source) {
+ if (this.resourcePath.match(elecSvcPath)) {
+ // If a electron-version of the service file exists, replace the source with the content of that file.
+ const elecSvcPath = this.resourcePath.replace(serviceRegexp, serviceReplaceStr);
+ if (fs.existsSync(elecSvcPath)) {
+ const elecSvcSource = fs.readFileSync(elecSvcPath, 'UTF-8');
+ source = 'module.exports == ' + JSON.stringify(elecSvcSource);
+ }
+ }
+ if (this.resourcePath.math(elecCmpPath)) {
+ // If a electron-version of the component file exists, replace the source with the content of that file.
+ const elecCmpPath = this.resourcePath.replace(componentRegexp, componentReplaceStr);
+ if (fs.existsSync(elecCmpPath)) {
+ const elecCmpSource = fs.readFileSync(elecCmpPath, 'UTF-8');
+ source = 'module.exports = ' + JSON.stringify(elecCmpSource);
+ //Replace module.id needed??
+ const styleProperty = 'styles';
+ const templateProperty = 'template';
+
+ source = source.replace(ng2TemplateUrlRegex, function replaceTemplateUrl(match, url) {
+ return templateProperty + ':' + replaceStringsWithRequires(url);
+ })
+ .replace(ng2StyleUrlsRegex, function replaceStyleUrls(match, urls) {
+ return styleProperty + ':' + replaceStringsWithRequires(urls);
+ })
+ .replace(ng2ModuleIdRegexp, function moduleId(match, moduleId) {
+ return '/* ' + moduleId + ' */';
+ });
+ }
+ }
+ if (this.resourcePath.match(htmlCssRegexp)) {
+ // If a tns-version of the html/css file exists, replace the source with the content of that file.
+ const elecViewPath = this.resourcePath.replace(htmlCssRegexp, htmlCssReplaceStr);
+ if (fs.existsSync(elecViewPath)) {
+ const elecViewSource = fs.readFileSync(elecViewPath, 'UTF-8');
+ source = 'module.exports = ' + JSON.stringify(elecViewSource);
+ }
+
+ } else if (this.resourcePath.match(componentRegexp)) {
+ // For ng2 components cnnvert:
+ // styleUrls = ['file1', ..., fileN] => styles = [require('file1'), ..., require('fileN')]
+ // templateUrl: 'file' => template: require('file')
+ //
+ // Removes moduleId
+ const styleProperty = 'styles';
+ const templateProperty = 'template';
+
+ source = source.replace(ng2TemplateUrlRegex, function replaceTemplateUrl(match, url) {
+ return templateProperty + ':' + replaceStringsWithRequires(url);
+ })
+ .replace(ng2StyleUrlsRegex, function replaceStyleUrls(match, urls) {
+ return styleProperty + ':' + replaceStringsWithRequires(urls);
+ })
+ .replace(ng2ModuleIdRegexp, function moduleId(match, moduleId) {
+ return '/* ' + moduleId + ' */';
+ });
+ } else if (this.resourcePath.match(componentFactoryRegexp)) {
+ // TODO: should/could we do something with the NgFactory files?
+ }
+
+ return injectTemplateVariables(this, source);
+};
diff --git a/electron/tsconfig.aot.json b/electron/tsconfig.aot.json
new file mode 100644
index 000000000..b1221e9af
--- /dev/null
+++ b/electron/tsconfig.aot.json
@@ -0,0 +1,35 @@
+{
+ "extend": "./tsconfig",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "ui/*": ["node_modules/tns-core-modules/ui/*"],
+ "platform": ["node_modules/tns-core-modules/platform"],
+ "image-source": ["node_modules/tns-core-modules/image-source"],
+ "xml": ["node_modules/tns-core-modules/xml"],
+ "xhr": ["node_modules/tns-core-modules/xhr"],
+ "text": ["node_modules/tns-core-modules/text"],
+ "data": ["node_modules/tns-core-modules/data"],
+ "fetch": ["node_modules/tns-core-modules/fetch"],
+ "trace": ["node_modules/tns-core-modules/trace"],
+ "fps-meter": ["node_modules/tns-core-modules/fps-meter"],
+ "color": ["node_modules/tns-core-modules/color"],
+ "application-settings": ["node_modules/tns-core-modules/application-settings"],
+ "http": ["node_modules/tns-core-modules/http"],
+ "camera": ["node_modules/tns-core-modules/camera"],
+ "console": ["node_modules/tns-core-modules/console"],
+ "timer": ["node_modules/tns-core-modules/timer"],
+ "utils": ["node_modules/tns-core-modules/utils"],
+ "location": ["node_modules/tns-core-modules/location"],
+ "file-system": ["node_modules/tns-core-modules/file-system"],
+ "application": ["node_modules/tns-core-modules/application"],
+ "image-asset": ["node_modules/tns-core-modules/image-asset"],
+ "connectivity": ["node_modules/tns-core-modules/connectivity"],
+ "globals": ["node_modules/tns-core-modules/globals"]
+ }
+ },
+ "angularCompilerOptions": {
+ "skipMetadataEmit": true,
+ "genDir": "./"
+ }
+}
diff --git a/electron/tsconfig.json b/electron/tsconfig.json
new file mode 100644
index 000000000..7be367f89
--- /dev/null
+++ b/electron/tsconfig.json
@@ -0,0 +1,37 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "allowSyntheticDefaultImports": true,
+ "sourceMap": true,
+ "strictNullChecks": false,
+ "baseUrl": "./src",
+ "paths": {},
+ "lib": [
+ "dom",
+ "es6"
+ ],
+ "types": [
+ "node"
+ ],
+ "typeRoots": [
+ "node_modules/@types"
+ ]
+ },
+ "exclude": [
+ "node_modules",
+ "dist"
+ ],
+ "awesomeTypescriptLoaderOptions": {
+ "forkChecker": true,
+ "useWebpackText": true
+ },
+ "compileOnSave": false,
+ "buildOnSave": false,
+ "atom": {
+ "rewriteTsconfig": false
+ }
+}
diff --git a/electron/tslint.json b/electron/tslint.json
new file mode 100644
index 000000000..633ff8b1e
--- /dev/null
+++ b/electron/tslint.json
@@ -0,0 +1,80 @@
+{
+ "rulesDirectory": [
+ "node_modules/codelyzer"
+ ],
+ "rules": {
+ "directive-selector-name": [true, "camelCase"],
+ "component-selector-name": [true, "kebab-case"],
+ "directive-selector-type": [true, "attribute"],
+ "component-selector-type": [true, "element"],
+ "directive-selector-prefix": [true, "ae"],
+ "component-selector-prefix": [true, "ae"],
+ "use-input-property-decorator": true,
+ "use-output-property-decorator": true,
+ "use-host-property-decorator": true,
+ "no-attribute-parameter-decorator": true,
+ "no-input-rename": true,
+ "no-output-rename": true,
+ "no-forward-ref" :true,
+ "use-life-cycle-interface": true,
+ "use-pipe-transform-interface": true,
+ "pipe-naming": [true, "camelCase", "sg"],
+ "component-class-suffix": true,
+ "directive-class-suffix": true,
+ "import-destructuring-spacing": true,
+ "class-name": true,
+ "curly": false,
+ "eofline": true,
+ "indent": [
+ true,
+ "spaces"
+ ],
+ "max-line-length": [
+ true,
+ 300
+ ],
+ "member-ordering": [
+ true,
+ "public-before-private",
+ "static-before-instance",
+ "variables-before-functions"
+ ],
+ "no-arg": true,
+ "no-construct": true,
+ "no-duplicate-key": true,
+ "no-duplicate-variable": true,
+ "no-empty": false,
+ "no-eval": true,
+ "trailing-comma": true,
+ "no-trailing-whitespace": false,
+ "no-unused-expression": true,
+ "no-unused-variable": false,
+ "no-unreachable": true,
+ "no-use-before-declare": true,
+ "one-line": [
+ true,
+ "check-open-brace",
+ "check-catch",
+ "check-else",
+ "check-whitespace"
+ ],
+ "quotemark": [
+ true,
+ "single"
+ ],
+ "semicolon": true,
+ "triple-equals": [
+ false,
+ "allow-null-check"
+ ],
+ "variable-name": false,
+ "whitespace": [
+ true,
+ "check-branch",
+ "check-decl",
+ "check-operator",
+ "check-separator",
+ "check-type"
+ ]
+ }
+}
diff --git a/electron/webpack.config.js b/electron/webpack.config.js
new file mode 100644
index 000000000..d0dd7d48c
--- /dev/null
+++ b/electron/webpack.config.js
@@ -0,0 +1,196 @@
+var webpack = require('webpack');
+//var nsWebpack = require('nativescript-dev-webpack');
+//var nativescriptTarget = require('nativescript-dev-webpack/nativescript-target');
+var path = require('path');
+var CopyWebpackPlugin = require('copy-webpack-plugin');
+var ExtractTextPlugin = require('extract-text-webpack-plugin');
+//var AotPlugin = require('@ngtools/webpack').AotPlugin;
+
+module.exports = function(platform, destinationApp) {
+ if (!destinationApp) {
+ //Default destination inside platforms//...
+ destinationApp = nsWebpack.getAppPath(platform);
+ }
+
+ // Setup the tnsLoader
+ var elecLoader = {
+ loader: 'elec-loader',
+ options: {
+ // data file is for now generated by the 'gulp build.js.tns'-task.
+ //data: require('./app/build-config.json'),
+ },
+ };
+
+ var entry = {};
+ //Discover entry module from package.json
+ entry.bundle = './app'
+ //Vendor entry with third party libraries.
+ entry.vendor = './vendor';
+ //app.css bundle
+ entry['app.css'] = './app.css';
+
+ var plugins = [
+ new ExtractTextPlugin('app.css'),
+ //Vendor libs go to the vendor.js chunk
+ new webpack.optimize.CommonsChunkPlugin({
+ name: ['vendor']
+ }),
+ //Define useful constants like TNS_WEBPACK
+ // new webpack.DefinePlugin({
+ // global: 'global',
+ // __dirname: '__dirname',
+ // 'global.TNS_WEBPACK': 'true',
+ // }),
+ //Copy assets to out dir. Add your own globs as needed.
+ new CopyWebpackPlugin([{
+ from: 'css/**'
+ }, {
+ from: 'fonts/**'
+ }, {
+ from: '**/*.jpg'
+ }, {
+ from: '**/*.png'
+ }, {
+ from: '**/*.xml'
+ }, {
+ from: 'assets',
+ to: 'assets',
+ type: 'dir',
+ }, ], {
+ ignore: []
+ }),
+ //Generate a bundle starter script and activate it in package.json
+ // new nsWebpack.GenerateBundleStarterPlugin([
+ // './vendor',
+ // './bundle',
+ // ]),
+
+ // Exclude explicitly required but never declared in XML elements.
+ // Loader nativescript-dev-webpack/tns-xml-loader should be added for *.xml/html files.
+ //new nsWebpack.ExcludeUnusedElementsPlugin(),
+
+ //Angular AOT compiler
+ // new AotPlugin({
+ // tsConfigPath: 'tsconfig.aot.json',
+ // entryModule: path.resolve(__dirname, 'app/electron.module#ElectronModule'),
+ // typeChecking: false
+ // }),
+ // new nsWebpack.StyleUrlResolvePlugin({
+ // platform
+ // }),
+ ];
+
+// if (process.env.npm_config_uglify) {
+// //Work around an Android issue by setting compress = false
+// var compress = platform !== 'android';
+// plugins.push(new webpack.optimize.UglifyJsPlugin({
+// mangle: {
+// except: nsWebpack.uglifyMangleExcludes,
+// },
+// compress: compress,
+// }));
+// }
+
+ return {
+ context: path.resolve('./src/app'),
+ target: 'electron-renderer',
+ entry: entry,
+ output: {
+ pathinfo: true,
+ path: path.resolve('./app'),
+ libraryTarget: 'commonjs2',
+ filename: '[name].js',
+ },
+ resolve: {
+ //Resolve platform-specific modules like module.android.js
+ extensions: [
+ '.aot.ts',
+ '.ts',
+ '.js',
+ '.css',
+ ],
+ //Resolve {N} system modules from tns-core-modules
+ modules: [
+ 'node_modules/tns-core-modules',
+ 'node_modules'
+ ]
+ },
+ resolveLoader: {
+ alias: {
+ 'elec-loader': path.join(__dirname, 'tools', 'webpack', 'elec-loader.js'),
+ }
+ },
+ // node: {
+ // //Disable node shims that conflict with NativeScript
+ // 'http': false,
+ // 'timers': false,
+ // 'setImmediate': false,
+ // },
+ module: {
+ rules: [{
+ test: /\.html$|\.xml$/,
+ use: [
+ elecLoader,
+ 'raw-loader',
+ //'nativescript-dev-webpack/tns-xml-loader'
+ ]
+ },
+ // Root app.css file gets extracted with bundled dependencies
+ {
+ test: /app\.css$/,
+ use: ExtractTextPlugin.extract([
+ 'resolve-url-loader',
+ //'nativescript-css-loader',
+ //'nativescript-dev-webpack/platform-css-loader',
+ ]),
+ },
+ // Other CSS files get bundled using the raw loader
+ {
+ test: /\.css$/,
+ exclude: /app\.css$/,
+ use: [
+ elecLoader,
+ 'raw-loader',
+ ]
+ },
+ // Compile TypeScript files with ahead-of-time compiler.
+ {
+ test: /\.ts$/,
+ use: [
+ elecLoader,
+ //'nativescript-dev-webpack/tns-aot-loader',
+ //'@ngtools/webpack',
+ ]
+ },
+
+ /*
+ * Json loader support for *.json files.
+ *
+ * See: https://github.com/webpack/json-loader
+ */
+ {
+ test: /\.json$/,
+ use: 'json-loader'
+ },
+
+ // SASS support
+ {
+ test: /\.scss$/,
+ use: [
+ 'raw-loader',
+ 'resolve-url-loader',
+ 'sass-loader'
+ ]
+ },
+
+ /* File loader for supporting images, for example, in CSS files.
+ */
+ {
+ test: /\.(jpg|png|gif)$/,
+ use: 'file-loader'
+ }
+ ]
+ },
+ plugins: plugins,
+ };
+};
diff --git a/electron/webpack.test.js b/electron/webpack.test.js
new file mode 100644
index 000000000..2b4381819
--- /dev/null
+++ b/electron/webpack.test.js
@@ -0,0 +1,248 @@
+const helpers = require('./helpers');
+
+/**
+ * Webpack Plugins
+ */
+const ProvidePlugin = require('webpack/lib/ProvidePlugin');
+const DefinePlugin = require('webpack/lib/DefinePlugin');
+const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
+const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
+
+/**
+ * Webpack Constants
+ */
+const ENV = process.env.ENV = process.env.NODE_ENV = 'test';
+
+/**
+ * Webpack configuration
+ *
+ * See: http://webpack.github.io/docs/configuration.html#cli
+ */
+module.exports = function (options) {
+ return {
+
+ /**
+ * Source map for Karma from the help of karma-sourcemap-loader & karma-webpack
+ *
+ * Do not change, leave as is or it wont work.
+ * See: https://github.com/webpack/karma-webpack#source-maps
+ */
+ devtool: 'inline-source-map',
+
+ /**
+ * Options affecting the resolving of modules.
+ *
+ * See: http://webpack.github.io/docs/configuration.html#resolve
+ */
+ resolve: {
+
+ /**
+ * An array of extensions that should be used to resolve modules.
+ *
+ * See: http://webpack.github.io/docs/configuration.html#resolve-extensions
+ */
+ extensions: ['.ts', '.js'],
+
+ /**
+ * Make sure root is src
+ */
+ modules: [helpers.root('src'), 'node_modules']
+
+ },
+
+ /**
+ * Options affecting the normal modules.
+ *
+ * See: http://webpack.github.io/docs/configuration.html#module
+ *
+ * 'use:' revered back to 'loader:' as a temp. workaround for #1188
+ * See: https://github.com/AngularClass/angular2-webpack-starter/issues/1188#issuecomment-262872034
+ */
+ module: {
+
+ rules: [
+
+ /**
+ * Source map loader support for *.js files
+ * Extracts SourceMaps for source files that as added as sourceMappingURL comment.
+ *
+ * See: https://github.com/webpack/source-map-loader
+ */
+ {
+ enforce: 'pre',
+ test: /\.js$/,
+ loader: 'source-map-loader',
+ exclude: [
+ // these packages have problems with their sourcemaps
+ helpers.root('node_modules/rxjs'),
+ helpers.root('node_modules/@angular')
+ ]
+ },
+
+ /**
+ * Typescript loader support for .ts and Angular 2 async routes via .async.ts
+ *
+ * See: https://github.com/s-panferov/awesome-typescript-loader
+ */
+ {
+ test: /\.ts$/,
+ use: [
+ {
+ loader: 'awesome-typescript-loader',
+ query: {
+ // use inline sourcemaps for "karma-remap-coverage" reporter
+ sourceMap: false,
+ inlineSourceMap: true,
+ compilerOptions: {
+
+ // Remove TypeScript helpers to be injected
+ // below by DefinePlugin
+ removeComments: true
+
+ }
+ },
+ },
+ 'angular2-template-loader'
+ ],
+ exclude: [/\.e2e\.ts$/]
+ },
+
+ /**
+ * Json loader support for *.json files.
+ *
+ * See: https://github.com/webpack/json-loader
+ */
+ {
+ test: /\.json$/,
+ loader: 'json-loader',
+ exclude: [helpers.root('src/index.html')]
+ },
+
+ /**
+ * Raw loader support for *.css files
+ * Returns file content as string
+ *
+ * See: https://github.com/webpack/raw-loader
+ */
+ {
+ test: /\.css$/,
+ loader: ['to-string-loader', 'css-loader'],
+ exclude: [helpers.root('src/index.html')]
+ },
+
+ /**
+ * Raw loader support for *.scss files
+ *
+ * See: https://github.com/webpack/raw-loader
+ */
+ {
+ test: /\.scss$/,
+ loader: ['raw-loader', 'sass-loader'],
+ exclude: [helpers.root('src/index.html')]
+ },
+
+ /**
+ * Raw loader support for *.html
+ * Returns file content as string
+ *
+ * See: https://github.com/webpack/raw-loader
+ */
+ {
+ test: /\.html$/,
+ loader: 'raw-loader',
+ exclude: [helpers.root('src/index.html')]
+ },
+
+ /**
+ * Instruments JS files with Istanbul for subsequent code coverage reporting.
+ * Instrument only testing sources.
+ *
+ * See: https://github.com/deepsweet/istanbul-instrumenter-loader
+ */
+ {
+ enforce: 'post',
+ test: /\.(js|ts)$/,
+ loader: 'istanbul-instrumenter-loader',
+ include: helpers.root('src'),
+ exclude: [
+ /\.(e2e|spec)\.ts$/,
+ /node_modules/
+ ]
+ }
+
+ ]
+ },
+
+ /**
+ * Add additional plugins to the compiler.
+ *
+ * See: http://webpack.github.io/docs/configuration.html#plugins
+ */
+ plugins: [
+
+ /**
+ * Plugin: DefinePlugin
+ * Description: Define free variables.
+ * Useful for having development builds with debug logging or adding global constants.
+ *
+ * Environment helpers
+ *
+ * See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
+ */
+ // NOTE: when adding more properties make sure you include them in custom-typings.d.ts
+ new DefinePlugin({
+ 'ENV': JSON.stringify(ENV),
+ 'HMR': false,
+ 'process.env': {
+ 'ENV': JSON.stringify(ENV),
+ 'NODE_ENV': JSON.stringify(ENV),
+ 'HMR': false,
+ }
+ }),
+
+ /**
+ * Plugin: ContextReplacementPlugin
+ * Description: Provides context to Angular's use of System.import
+ *
+ * See: https://webpack.github.io/docs/list-of-plugins.html#contextreplacementplugin
+ * See: https://github.com/angular/angular/issues/11580
+ */
+ new ContextReplacementPlugin(
+ // The (\\|\/) piece accounts for path separators in *nix and Windows
+ /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
+ helpers.root('src'), // location of your src
+ {
+ // your Angular Async Route paths relative to this root directory
+ }
+ ),
+
+ /**
+ * Plugin LoaderOptionsPlugin (experimental)
+ *
+ * See: https://gist.github.com/sokra/27b24881210b56bbaff7
+ */
+ new LoaderOptionsPlugin({
+ debug: false,
+ options: {
+ // legacy options go here
+ }
+ }),
+
+ ],
+ /**
+ * Include polyfills or mocks for various node stuff
+ * Description: Node configuration
+ *
+ * See: https://webpack.github.io/docs/configuration.html#node
+ */
+ node: {
+ global: true,
+ process: false,
+ crypto: 'empty',
+ module: false,
+ clearImmediate: false,
+ setImmediate: false
+ }
+
+ };
+}
diff --git a/nativescript/package.json b/nativescript/package.json
index 813ea1c61..078a2a7b8 100644
--- a/nativescript/package.json
+++ b/nativescript/package.json
@@ -70,4 +70,4 @@
"webpack": "2.3.2",
"webpack-sources": "~0.2.3"
}
-}
+}
\ No newline at end of file
diff --git a/nativescript/src/App_Resources/Android/drawable-hdpi/icon.png b/nativescript/src/App_Resources/Android/drawable-hdpi/icon.png
old mode 100755
new mode 100644
diff --git a/nativescript/src/App_Resources/Android/drawable-ldpi/icon.png b/nativescript/src/App_Resources/Android/drawable-ldpi/icon.png
old mode 100755
new mode 100644
diff --git a/nativescript/src/App_Resources/Android/drawable-mdpi/icon.png b/nativescript/src/App_Resources/Android/drawable-mdpi/icon.png
old mode 100755
new mode 100644
diff --git a/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png b/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png
old mode 100755
new mode 100644
diff --git a/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png b/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png
old mode 100755
new mode 100644
diff --git a/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png b/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png
old mode 100755
new mode 100644
diff --git a/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png b/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png
old mode 100755
new mode 100644
diff --git a/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png b/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png
old mode 100755
new mode 100644
diff --git a/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png b/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png
old mode 100755
new mode 100644
diff --git a/package.json b/package.json
index 114eabbe6..8b6913dd4 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"karma": "karma",
"karma.start": "karma start",
"nativescript-install": "cd nativescript && npm install",
+ "electron-install": "cd electron && npm install",
"postinstall": "gulp check.versions && gulp build.bundle.rxjs && npm prune && gulp webdriver && npm run nativescript-install && node tools/install.js",
"reinstall": "npm cache clean && npm install",
"serve.coverage": "gulp serve.coverage --color",
@@ -43,7 +44,7 @@
"serve.prod.rollup.aot": "gulp serve.prod.rollup.aot --color --env-config prod --build-type prod",
"start": "gulp serve.dev --color",
"start.deving": "gulp start.deving --color",
- "start.desktop": "gulp desktop && NODE_ENV=development electron ./dist/dev",
+ "start.desktop": "npm run gulp build.elec && cd electron && electron ./app/app",
"start.livesync.desktop": "gulp desktop && NODE_ENV=development gulp desktop.watch",
"start.livesync.desktop.windows": "gulp desktop && SET NODE_ENV=development && gulp desktop.watch",
"start.desktop.windows": "gulp desktop && SET NODE_ENV=development && electron ./dist/dev",
@@ -192,6 +193,7 @@
"reflect-metadata": "^0.1.8",
"rxjs": "~5.2.0",
"systemjs": "0.19.41",
+ "webpack-target-electron-renderer": "^0.4.0",
"zone.js": "^0.8.4"
}
}
diff --git a/src/client/app/components/about/about.component.html b/src/client/app/components/about/about.component.html
old mode 100755
new mode 100644
diff --git a/src/client/app/components/app.component.html b/src/client/app/components/app.component.html
old mode 100755
new mode 100644
diff --git a/src/client/app/components/home/home.component.html b/src/client/app/components/home/home.component.html
old mode 100755
new mode 100644
diff --git a/src/client/app/components/home/home.component.scss b/src/client/app/components/home/home.component.scss
old mode 100755
new mode 100644
diff --git a/src/client/app/shared/sample/components/navbar.component.css b/src/client/app/shared/sample/components/navbar.component.scss
similarity index 100%
rename from src/client/app/shared/sample/components/navbar.component.css
rename to src/client/app/shared/sample/components/navbar.component.scss
diff --git a/src/client/app/shared/sample/components/toolbar.component.css b/src/client/app/shared/sample/components/toolbar.component.scss
similarity index 100%
rename from src/client/app/shared/sample/components/toolbar.component.css
rename to src/client/app/shared/sample/components/toolbar.component.scss
diff --git a/tools/config/seed-advanced.config.ts b/tools/config/seed-advanced.config.ts
index c860018d0..060dc6de4 100644
--- a/tools/config/seed-advanced.config.ts
+++ b/tools/config/seed-advanced.config.ts
@@ -21,9 +21,22 @@ export class SeedAdvancedConfig extends SeedConfig {
ANALYTICS_TRACKING_ID: '',
};
- /**
- * Holds added packages for desktop build.
+ /**
+ * The base folder of the electron application source files.
+ * @type {string}
*/
+ ELECTRON_BASE_DIR = 'electron';
+
+ ELECTRON_APP_SRC = `${this.ELECTRON_BASE_DIR}/${this.srcSubdir}`;
+
+ ELECTRON_APP_DEST = `${this.ELECTRON_BASE_DIR}/${this.destSubdir}`;
+
+ ELECTRON_CONFIG = {
+ ANALYTICS_TRACKING_ID: '',
+ };
+ /**
+ * Holds added packages for desktop build.
+ */
DESKTOP_PACKAGES: ExtendPackages[] = [];
constructor() {
@@ -47,7 +60,7 @@ export class SeedAdvancedConfig extends SeedConfig {
if (this.TARGET_MOBILE_HYBRID) {
// Perhaps Ionic or Cordova
// This is not implemented in the seed but here to show you way forward if you wanted to add
- bootstrap = 'main.mobile.hybrid';
+ bootstrap = 'main.mobile.hybrid';
}
if (argv['analytics']) {
@@ -149,10 +162,10 @@ export class SeedAdvancedConfig extends SeedConfig {
* Need to duplicate this in the project.config.ts to
* pick up packages there too.
*/
- this.DESKTOP_PACKAGES = [
+ this.DESKTOP_PACKAGES = [
...this.DESKTOP_PACKAGES,
...additionalPackages,
- ];
+ ];
this.addPackagesBundles(additionalPackages);
diff --git a/tools/config/seed.tasks.json b/tools/config/seed.tasks.json
index 48f18c981..46695c915 100644
--- a/tools/config/seed.tasks.json
+++ b/tools/config/seed.tasks.json
@@ -82,6 +82,12 @@
"build.js.tns"
],
+ "build.elec": [
+ "build.assets.elec",
+ "build.elec_html_css",
+ "build.js.elec"
+ ],
+
"build.prod.tns": [
"clean.tns",
"tslint.tns",
diff --git a/tools/install.js b/tools/install.js
index 09274f59c..6a42f09d2 100644
--- a/tools/install.js
+++ b/tools/install.js
@@ -12,6 +12,7 @@ var path = require('path');
var webAppPath = '../src/client/app';
var webAssetsPath = '../src/client/assets';
var nativescriptAppPath = '../nativescript/src/app/';
+var electronAppPath = '../electron/src/app/';
// Root SymLink Code for Windows
if (process.argv.length > 2) {
@@ -33,6 +34,9 @@ try {
if (fs.existsSync(resolve(nativescriptAppPath))) {
fs.unlinkSync(resolve(nativescriptAppPath));
}
+ if (fs.existsSync(resolve(electronAppPath))) {
+ fs.unlinkSync(resolve(electronAppPath));
+ }
} catch (err) {
}
@@ -105,6 +109,10 @@ function createSymLink() {
console.log("Attempting to Symlink", webAppPath, nativescriptAppPath);
}
fs.symlinkSync(resolve(webAppPath), resolve(nativescriptAppPath), 'junction');
+ if (debugging) {
+ console.log("Attempting to Symlink", webAppPath, electronAppPath);
+ }
+ fs.symlinkSync(resolve(webAppPath), resolve(electronAppPath), 'junction');
}
/**
diff --git a/tools/tasks/project/desktop.build.ts b/tools/tasks/project/desktop.build.ts
index 6e91b69cb..96c7caa2a 100644
--- a/tools/tasks/project/desktop.build.ts
+++ b/tools/tasks/project/desktop.build.ts
@@ -1,17 +1,73 @@
import * as gulp from 'gulp';
-import { join } from 'path';
-var newer = require('gulp-newer');
+import * as gulpLoadPlugins from 'gulp-load-plugins';
+import * as merge from 'merge-stream';
+import * as fs from 'fs';
+import * as path from 'path';
import Config from '../../config';
+import { makeTsProject, TemplateLocalsBuilder } from '../../utils';
+import { TypeScriptTask } from '../typescript_task';
-export = () => {
- let src = [
- join(Config.APP_SRC, 'package.json')
- ];
- return gulp.src(src)
- .pipe(newer({
- dest: Config.APP_DEST,
- map: function(path: String) { return path.replace('.ts', '.js').replace('.scss', '.css'); }
- }))
- .pipe(gulp.dest(Config.APP_DEST));
-};
+const plugins = gulpLoadPlugins();
+
+const jsonSystemConfig = JSON.stringify(Config.ELECTRON_CONFIG);
+
+/**
+ * Executes the build process, transpiling the TypeScript files (except the spec and e2e-spec files) for the development
+ * environment.
+ */
+export =
+ class BuildJsDev extends TypeScriptTask {
+ run() {
+ const src = [
+ '**/*.ts',
+ 'app/**/*.ts',
+ '!**/*.spec.ts',
+ '!app/**/*.spec.ts',
+ '!**/*.e2e-spec.ts',
+ '!app/**/*.e2e-spec.ts',
+ '!app/shared/test/**/*',
+ `!**/${Config.NG_FACTORY_FILE}.ts`,
+ ];
+
+ const tsProject = makeTsProject({}, Config.ELECTRON_APP_SRC);
+
+ const result = gulp.src([
+ ...src,
+ '!**/*.aot.ts',
+ ], {
+ base: Config.ELECTRON_APP_SRC,
+ cwd: Config.ELECTRON_APP_SRC,
+ })
+ .pipe(plugins.sourcemaps.init())
+ .pipe(tsProject());
+
+ const template = (Object).assign(
+ new TemplateLocalsBuilder().withStringifiedSystemConfigDev().build(), {
+ SYSTEM_CONFIG_ELECTRON: jsonSystemConfig
+ },
+ );
+
+ const transpiled = result.js
+ .pipe(plugins.sourcemaps.write())
+ // Use for debugging with Webstorm/IntelliJ
+ // https://github.com/mgechev/angular-seed/issues/1220
+ // .pipe(plugins.sourcemaps.write('.', {
+ // includeContent: false,
+ // sourceRoot: (file: any) =>
+ // relative(file.path, PROJECT_ROOT + '/' + APP_SRC).replace(sep, '/') + '/' + APP_SRC
+ // }))
+ .pipe(plugins.template(template))
+ .pipe(gulp.dest(Config.ELECTRON_APP_DEST));
+
+ const copy = gulp.src(src, {
+ base: Config.ELECTRON_APP_SRC,
+ cwd: Config.ELECTRON_APP_SRC,
+ })
+ .pipe(gulp.dest(Config.ELECTRON_APP_DEST));
+
+ fs.writeFileSync(path.join(Config.ELECTRON_APP_DEST, 'build-config.json'), JSON.stringify(template));
+
+ return merge(transpiled, copy);
+ }
+ };
diff --git a/tools/tasks/seed/build.assets.elec.ts b/tools/tasks/seed/build.assets.elec.ts
new file mode 100644
index 000000000..43a3a24e7
--- /dev/null
+++ b/tools/tasks/seed/build.assets.elec.ts
@@ -0,0 +1,45 @@
+import * as gulp from 'gulp';
+import * as merge from 'merge-stream';
+import { join } from 'path';
+import * as newer from 'gulp-newer';
+
+import { AssetsTask } from '../assets_task';
+import Config from '../../config';
+
+function copyFiles(paths: string[], subdir: string) {
+ const dest = join(Config.ELECTRON_APP_SRC, subdir);
+
+ return gulp.src(paths)
+ .pipe(newer(dest))
+ .pipe(gulp.dest(dest));
+}
+
+function copyAssets() {
+ const paths: string[] = [
+ join(Config.APP_SRC, 'assets', '**'),
+ '!' + join(Config.APP_SRC, 'assets', 'icons', '**', '*'),
+ ].concat(Config.TEMP_FILES.map((p) => { return '!' + p; }));
+
+ return copyFiles(paths, 'assets');
+}
+
+function copyAppFonts() {
+ const paths: string[] = [
+ join(Config.ELECTRON_APP_SRC, 'fonts', '**', '*.otf'),
+ join(Config.ELECTRON_APP_SRC, 'fonts', '**', '*.ttf'),
+ ];
+
+ return copyFiles(paths, 'fonts');
+}
+
+export =
+ class BuildElectronAssetsTask extends AssetsTask {
+ run() {
+ return merge(
+ copyAssets(),
+ copyAppFonts(),
+ copyFiles([join(Config.ELECTRON_APP_SRC, 'package.json')], ''),
+ );
+ }
+ };
+
diff --git a/tools/tasks/seed/build.elec_html_css.ts b/tools/tasks/seed/build.elec_html_css.ts
new file mode 100644
index 000000000..83ee4ba98
--- /dev/null
+++ b/tools/tasks/seed/build.elec_html_css.ts
@@ -0,0 +1,91 @@
+import * as gulp from 'gulp';
+import * as gulpLoadPlugins from 'gulp-load-plugins';
+import * as merge from 'merge-stream';
+import * as util from 'gulp-util';
+import * as rename from 'gulp-rename';
+
+import Config from '../../config';
+import { CssTask } from '../css_task';
+
+const plugins = gulpLoadPlugins();
+const reportPostCssError = (e: any) => util.log(util.colors.red(e.message));
+
+function renamer() {
+ return rename((path: any) => {
+ path.basename = path.basename.replace(/\.elec/, '');
+ });
+}
+
+function prepareTemplates() {
+ return gulp.src([
+ '**/*.html',
+ 'app/**/*.html',
+ '!app/**/*.component.html',
+ ], {
+ base: Config.ELECTRON_APP_SRC,
+ cwd: Config.ELECTRON_APP_SRC,
+ })
+ .pipe(renamer())
+ .pipe(gulp.dest(Config.ELECTRON_APP_DEST));
+}
+
+function processComponentStylesheets() {
+ return Config.ENABLE_SCSS ?
+ merge(
+ processComponentScss(),
+ processComponentCss())
+ :
+ processComponentCss();
+}
+
+function processComponentCss() {
+ return gulp.src([
+ '**/*.css',
+ 'app/**/*.css',
+ '!app/**/*.component.css',
+ ], {
+ base: Config.ELECTRON_APP_SRC,
+ cwd: Config.ELECTRON_APP_SRC,
+ })
+ .pipe(renamer())
+ //.on('error', reportPostCssError) // Causes Property 'pipe' does not exist on type 'EventEmitter'.
+ .pipe(gulp.dest(Config.ELECTRON_APP_DEST));
+}
+
+/**
+ * Process scss files referenced from Angular component `styleUrls` metadata
+ */
+function processComponentScss() {
+ const stream = gulp.src([
+ '**/*.scss',
+ 'app/**/*.scss',
+ '!app/**/*.component.scss',
+ ], {
+ base: Config.ELECTRON_APP_SRC,
+ cwd: Config.ELECTRON_APP_SRC,
+ })
+ .pipe(plugins.sourcemaps.init())
+ .pipe(plugins.sass(Config.getPluginConfig('gulp-sass-tns')).on('error', plugins.sass.logError))
+ .pipe(plugins.sourcemaps.write());
+
+ return stream
+ .pipe(renamer())
+ .pipe(gulp.dest(Config.ELECTRON_APP_DEST));
+}
+
+export =
+ class BuildElectronCSS extends CssTask {
+ shallRun(files: String[]) {
+ // Only run if tns-resources
+ return files.some((f) =>
+ // tns.html, tns.scss or tns.css under nativescript/src/app
+ (f.indexOf('electron/src/app') !== -1 && !!f.match(/\.elec\.(s?css|html)$/)) ||
+ // .html, .scss or .css NOT under nativescript/src/app
+ (f.indexOf('electron/src/app') === -1 && !!f.match(/\.(s?css|html)$/))
+ );
+ }
+
+ run() {
+ return merge(processComponentStylesheets(), prepareTemplates());
+ }
+ };
diff --git a/tools/tasks/seed/build.js.elec.ts b/tools/tasks/seed/build.js.elec.ts
new file mode 100644
index 000000000..6d5123d1e
--- /dev/null
+++ b/tools/tasks/seed/build.js.elec.ts
@@ -0,0 +1,75 @@
+import * as gulp from 'gulp';
+import * as gulpLoadPlugins from 'gulp-load-plugins';
+import * as merge from 'merge-stream';
+import * as fs from 'fs';
+import * as path from 'path';
+
+import Config from '../../config';
+import { makeTsProject, TemplateLocalsBuilder } from '../../utils';
+import { TypeScriptTask } from '../typescript_task';
+
+const plugins = gulpLoadPlugins();
+
+const jsonSystemConfig = JSON.stringify(Config.ELECTRON_CONFIG);
+
+/**
+ * Executes the build process, transpiling the TypeScript files (except the spec and e2e-spec files) for the development
+ * environment.
+ */
+export =
+ class BuildJsDev extends TypeScriptTask {
+ run() {
+ const src = [
+ '**/*.ts',
+ 'app/**/*.ts',
+ '!**/*.spec.ts',
+ '!app/**/*.spec.ts',
+ '!**/*.e2e-spec.ts',
+ '!app/**/*.e2e-spec.ts',
+ '!app/shared/test/**/*',
+ `!**/${Config.NG_FACTORY_FILE}.ts`,
+ ];
+
+ const tsProject = makeTsProject({}, Config.ELECTRON_APP_SRC);
+
+ const result = gulp.src([
+ ...src,
+ '!**/*.aot.ts',
+ ], {
+ base: Config.ELECTRON_APP_SRC,
+ cwd: Config.ELECTRON_APP_SRC,
+ })
+ .pipe(plugins.sourcemaps.init())
+ .pipe(tsProject());
+
+ const template = (Object).assign(
+ new TemplateLocalsBuilder().withStringifiedSystemConfigDev().build(), {
+ SYSTEM_CONFIG_TNS: jsonSystemConfig
+ },
+ );
+
+ const transpiled = result.js
+ .pipe(plugins.sourcemaps.write())
+ // Use for debugging with Webstorm/IntelliJ
+ // https://github.com/mgechev/angular-seed/issues/1220
+ // .pipe(plugins.sourcemaps.write('.', {
+ // includeContent: false,
+ // sourceRoot: (file: any) =>
+ // relative(file.path, PROJECT_ROOT + '/' + APP_SRC).replace(sep, '/') + '/' + APP_SRC
+ // }))
+ .pipe(plugins.template(template))
+ .pipe(gulp.dest(Config.ELECTRON_APP_DEST));
+
+ const copy = gulp.src(src, {
+ base: Config.ELECTRON_APP_SRC,
+ cwd: Config.ELECTRON_APP_SRC,
+ })
+ .pipe(gulp.dest(Config.ELECTRON_APP_DEST));
+
+ fs.writeFileSync(path.join(Config.ELECTRON_APP_DEST, 'build-config.json'), JSON.stringify(template));
+
+ return merge(transpiled, copy);
+ }
+ };
+
+
diff --git a/tools/tasks/seed/build.tns_html_css.ts b/tools/tasks/seed/build.tns_html_css.ts
index c695cd7f5..c1460a04f 100644
--- a/tools/tasks/seed/build.tns_html_css.ts
+++ b/tools/tasks/seed/build.tns_html_css.ts
@@ -48,7 +48,7 @@ function processComponentCss() {
cwd: Config.TNS_APP_SRC,
})
.pipe(renamer())
- .on('error', reportPostCssError)
+ //.on('error', reportPostCssError) // Causes Property 'pipe' does not exist on type 'EventEmitter'.
.pipe(gulp.dest(Config.TNS_APP_DEST));
}