diff --git a/.gitignore b/.gitignore
index e8d87581..82cb0860 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,11 +20,17 @@ npm-debug.log*
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
node_modules
-#jspm
-jspm_packages
+# compiled css
+lib/**/*.css
+# files produced by ngc
+lib/**/*.ngfactory.ts
+lib/**/*.css.shim.ts
+
+# other
/dist
/demo/build
.tmp
/coverage
.ghpages-tmp
+stats.json
diff --git a/.travis.yml b/.travis.yml
index 31d1a1e5..74e598aa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,12 +25,11 @@ addons:
cache:
directories:
- node_modules
- - jspm_packages
-before_install:
-- travis_retry npm install jspm
-- jspm config registries.github.auth $JSPM_GITHUB_AUTH_TOKEN
before_script:
-- npm run jspm-install
+ - npm run e2e-server > /dev/null & # kill e2e server
+ - sleep 3 # give server time to start
+after_script:
+ - kill %1 # kill e2e server
before_deploy:
- npm run build-dist
deploy:
diff --git a/build/helpers.js b/build/helpers.js
new file mode 100644
index 00000000..25bd2532
--- /dev/null
+++ b/build/helpers.js
@@ -0,0 +1,9 @@
+const path = require('path');
+function root(args) {
+ args = Array.prototype.slice.call(arguments, 0);
+ return path.join.apply(path, [__dirname, '..'].concat(args));
+}
+
+module.exports = {
+ root: root
+}
diff --git a/build/paths.js b/build/paths.js
index 63a59b59..2707c00c 100644
--- a/build/paths.js
+++ b/build/paths.js
@@ -1,15 +1,9 @@
var path = require('path');
var paths = {
- source: 'lib/**/*.ts',
- html: 'lib/**/*.html',
- scss: 'lib/**/*.scss',
- sourceEntryPoint: 'lib/index.js',
- outputName: 'redoc',
+ outputName: 'redoc.min.js',
output: 'dist/',
- tmp: '.tmp/',
demo: 'demo/**/*',
- tests: '{lib,tests}/**/*.spec.ts',
releases: 'demo/releases/'
}
diff --git a/build/tasks/build.js b/build/tasks/build.js
deleted file mode 100644
index 39d51162..00000000
--- a/build/tasks/build.js
+++ /dev/null
@@ -1,165 +0,0 @@
-var gulp = require('gulp');
-var runSequence = require('run-sequence');
-var Builder = require('systemjs-builder');
-var inlineNg2Template = require('gulp-inline-ng2-template');
-var path = require('path');
-var sourcemaps = require('gulp-sourcemaps');
-var paths = require('../paths');
-var fs= require('fs');
-var concat = require('gulp-concat');
-var gulp = require('gulp');
-var sass = require('gulp-sass');
-var replace = require('gulp-replace');
-var rename = require('gulp-rename');
-var argv = require('yargs').argv;
-var gulpIf = require('gulp-if');
-var sassCopm = require('node-sass');
-var ts = require('typescript');
-
-gulp.task('build', function (callback) {
- if (argv.skipRebuild) {
- console.log('>>> Rebuild skipped')
- return callback();
- }
- return runSequence(
- 'clean',
- 'transpile',
- 'bundle',
- 'concatDeps',
- 'copyDebug',
- callback
- );
-});
-
-gulp.task('transpile', function(cb) {
- return runSequence(
- 'tsc',
- 'inlineTemplates',
- cb
- );
-});
-
-gulp.task('copyDebug', () => {
- if (!argv.prod) {
- // copy for be accessible from demo for debug
- cp(paths.redocBuilt + '.js', paths.redocBuilt + '.min.js');
- }
-});
-
-gulp.task('tsc', function() {
- exec('tsc -v');
- exec('tsc -p ./tsconfig.json');
-});
-
-gulp.task('inlineTemplates', ['sass'], function() {
- return gulp.src('.tmp/**/*.js', { base: './tmp' })
- .pipe(replace(/'(.*?)\.css'/g, '\'$1.scss\''))
- .pipe(inlineNg2Template({
- base: './',
- useRelativePaths: true,
- styleProcessor: compileSass,
- customFilePath: function(ext, file) {
- var cwd = process.cwd();
- var relative = path.relative(cwd, file);
- relative = relative.substring('5');
- return path.join(cwd, relative);
- }
- }))
- .pipe(gulp.dest(paths.tmp));
-});
-
-function compileSass(ext, file, cb) {
- file = file.replace('../../shared/styles/variables', 'lib/shared/styles/variables');
- file = file.replace('json-schema-common', 'lib/components/JsonSchema/json-schema-common');
- file = file.replace('../../shared/styles/share-link', 'lib/shared/styles/share-link');
- file = file.replace('../JsonSchema/lib/components/JsonSchema/json-schema-common', 'lib/components/JsonSchema/json-schema-common');
- file = file.replace('../../styles/variables', 'lib/shared/styles/variables');
-
- cb(null, sassCopm.renderSync({data: file}).css);
-}
-
-var JS_DEPS = argv.prod ? [
- 'lib/utils/browser-update.js',
- 'node_modules/zone.js/dist/zone.min.js',
- 'node_modules/reflect-metadata/Reflect.js',
- 'node_modules/babel-polyfill/dist/polyfill.min.js'
-]: [
- 'lib/utils/browser-update.js',
- 'node_modules/zone.js/dist/zone.js',
- 'node_modules/zone.js/dist/long-stack-trace-zone.js',
- 'node_modules/reflect-metadata/Reflect.js',
- 'node_modules/babel-polyfill/dist/polyfill.js'
-];
-
-var outputFileName = paths.redocBuilt + (argv.prod ? '.min.js' : '.js');
-
-gulp.task('sass', function () {
- return gulp.src(paths.scss, { base: './' })
- .pipe(sass.sync({outputStyle: 'compressed'}).on('error', sass.logError))
- .pipe(gulp.dest(paths.tmp));
-});
-
-// concatenate angular2 deps
-gulp.task('concatDeps', ['concatPrism'], function() {
- return gulp.src(JS_DEPS.concat([path.join(paths.tmp, 'prismjs-bundle.js'), outputFileName]))
- .pipe(gulpIf(!argv.prod, sourcemaps.init({loadMaps: true})))
- .pipe(concat(outputFileName))
- .pipe(gulpIf(!argv.prod, sourcemaps.write('.')))
- .pipe(gulp.dest('.'))
-});
-
-gulp.task('bundle', ['injectVersionFile'], function bundle(done) {
- mkdir('-p', 'dist');
- cp('lib/index.js', path.join(paths.tmp, paths.sourceEntryPoint));
- var builder = new Builder('./', 'system.config.js');
-
- builder
- .buildStatic(path.join(paths.tmp, paths.sourceEntryPoint),
- outputFileName,
- { format:'umd', sourceMaps: !argv.prod, lowResSourceMaps: true, minify: argv.prod, mangle: false, globalName: 'Redoc' }
- )
- .then(() => {
- // wait some time to allow flush
- setTimeout(() => done(), 500);
- })
- .catch(err => done(err));
-});
-
-gulp.task('concatPrism', function() {
- require('../../system.config.js');
- var prismFolder = System.normalizeSync('prismjs').substring(8);
- prismFolder = prismFolder.substring(0, prismFolder.length -3);
- var prismFiles = [
- 'prism.js',
- 'components/prism-actionscript.js',
- 'components/prism-c.js',
- 'components/prism-cpp.js',
- 'components/prism-csharp.js',
- 'components/prism-php.js',
- 'components/prism-coffeescript.js',
- 'components/prism-go.js',
- 'components/prism-haskell.js',
- 'components/prism-java.js',
- 'components/prism-lua.js',
- 'components/prism-matlab.js',
- 'components/prism-perl.js',
- 'components/prism-python.js',
- 'components/prism-r.js',
- 'components/prism-ruby.js',
- 'components/prism-bash.js',
- 'components/prism-swift.js',
- 'components/prism-objectivec.js',
- 'components/prism-scala.js'
- ].map(file => path.join(prismFolder, file));
-
- return gulp.src(prismFiles)
- .pipe(concat(path.join(paths.tmp, 'prismjs-bundle.js')))
- .pipe(gulp.dest('.'));
-});
-
-// needs inlineTemplates run before to create .tmp/lib folder
-gulp.task('injectVersionFile', function() {
- var version = require('../../package.json').version;
- var exportStatement = `export var redocVersion = "${version}"`;
- fs.writeFileSync(path.join(paths.tmp, 'lib/version.js'), exportStatement);
-})
diff --git a/build/tasks/clean.js b/build/tasks/clean.js
deleted file mode 100644
index f96f5682..00000000
--- a/build/tasks/clean.js
+++ /dev/null
@@ -1,9 +0,0 @@
-var gulp = require('gulp');
-var paths = require('../paths');
-var del = require('del');
-var vinylPaths = require('vinyl-paths');
-
-gulp.task('clean', function () {
- return gulp.src([paths.output, paths.tmp])
- .pipe(vinylPaths(del));
-});
diff --git a/build/tasks/e2e.js b/build/tasks/e2e.js
deleted file mode 100644
index ad09d558..00000000
--- a/build/tasks/e2e.js
+++ /dev/null
@@ -1,34 +0,0 @@
-var gulp = require('gulp');
-var gp = require('gulp-protractor');
-var browserSync = require('browser-sync').create('bs-e2e');
-
-gulp.task('test-server', function (done) {
- browserSync.init({
- open: false,
- notify: false,
- port: 3000,
- ghostMode: false,
- server: {
- baseDir: './tests/e2e',
- routes: {
- '/dist': './dist',
- '/swagger.yml': './demo/swagger.yml'
- },
- }
- }, done);
-});
-
-
-gulp.task('e2e', ['build', 'test-server'], function(done) {
- gulp.src(['tests/e2e/**/*.js'], { read:false })
- .pipe(gp.protractor({
- configFile: './protractor.conf.js'
- })).on('error', function(e) {
- browserSync.exit();
- throw e;
- done();
- }).on('end', function() {
- browserSync.exit();
- done();
- });
-});
diff --git a/build/tasks/lint.js b/build/tasks/lint.js
deleted file mode 100644
index 526dc523..00000000
--- a/build/tasks/lint.js
+++ /dev/null
@@ -1,15 +0,0 @@
-var gulp = require('gulp');
-var tslint = require('gulp-tslint');
-var paths = require('../paths');
-
-gulp.task('lint', function () {
- return gulp.src([paths.source, paths.tests])
- .pipe(tslint({
- rulesDirectory: 'node_modules/codelyzer'
- }))
- .pipe(tslint.report(require('tslint-stylish'), {
- emitError: true,
- sort: true,
- bell: true
- }));
-});
diff --git a/build/tasks/serve.js b/build/tasks/serve.js
deleted file mode 100644
index 93105d83..00000000
--- a/build/tasks/serve.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var gulp = require('gulp');
-var browserSync = require('browser-sync').create('bs');
-
-gulp.task('serve', ['watch'], function (done) {
- browserSync.init({
- open: false,
- notify: false,
- port: 9000,
- server: {
- baseDir: './demo',
- routes: {
- '/dist': './dist'
- },
- },
- reloadDelay: 500
- }, done);
-});
diff --git a/build/tasks/test.js b/build/tasks/test.js
deleted file mode 100644
index c572bac5..00000000
--- a/build/tasks/test.js
+++ /dev/null
@@ -1,52 +0,0 @@
-var gulp = require('gulp');
-var runSequence = require('run-sequence');
-var Server = require('karma').Server;
-var remapIstanbul = require('remap-istanbul/lib/gulpRemapIstanbul');
-
-gulp.task('prepare-test', function(cb) {
- return runSequence(
- 'clean',
- 'transpile',
- 'concatPrism',
- 'injectVersionFile',
- cb
- );
-})
-/**
- * Run test once and exit
- */
-gulp.task('test', ['prepare-test'], function (done) {
- new Server({
- configFile: __dirname + '/../../karma.conf.js',
- singleRun: true
- }, karmaDone).start();
-
- function karmaDone (exitCode) {
- remapCoverage(done, exitCode);
- }
-});
-
-function remapCoverage(done, statusCode) {
- console.log('Remapping coverage to TypeScript format...');
- gulp.src('coverage/**/coverage-final.json')
- .pipe(remapIstanbul({
- reports: {
- 'lcovonly': 'coverage/lcov.info',
- 'text-summary': 'coverage/text-summary.txt',
- 'html': 'coverage'
- }
- }))
- .on('finish', function () {
- console.log('Remapping done!');
- console.log(cat('coverage/text-summary.txt').stdout);
- console.log('Test Done with exit code: ' + statusCode);
- if (process.env.TRAVIS) {
- console.log('uploading to coveralls')
- var out = cat('coverage/lcov.info').exec('coveralls');
- if (out.code !== 0) {
- console.warn('Failed upload to coveralls');
- }
- }
- done(statusCode);
- });
-};
diff --git a/build/tasks/watch.js b/build/tasks/watch.js
deleted file mode 100644
index a0cdcdda..00000000
--- a/build/tasks/watch.js
+++ /dev/null
@@ -1,14 +0,0 @@
-var gulp = require('gulp');
-var paths = require('../paths');
-var browserSync = require('browser-sync').get('bs');
-
-function changed(event) {
- console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
-}
-
-gulp.task('watch', ['build'], function () {
- gulp.watch([ paths.source ], [ 'build', browserSync.reload ]).on('change', changed);
- gulp.watch([ paths.html ], [ 'build', browserSync.reload]).on('change', changed);
- gulp.watch([ paths.scss ], [ 'build', browserSync.reload]).on('change', changed);
- gulp.watch([ paths.demo ], [ '', browserSync.reload ]).on('change', changed);
-});
diff --git a/build/webpack.dev.js b/build/webpack.dev.js
new file mode 100644
index 00000000..bdd0deb4
--- /dev/null
+++ b/build/webpack.dev.js
@@ -0,0 +1,98 @@
+const webpack = require('webpack');
+const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
+
+const root = require('./helpers').root;
+const VERSION = JSON.stringify(require('../package.json').version);
+
+// TODO Refactor common parts of config
+
+module.exports = {
+ context: root(),
+ devtool: 'cheap-module-source-map',
+ debug: false,
+
+ resolve: {
+ extensions: ['', '.ts', '.js', '.json', '.css', '.scss', '.html'],
+ root: root('lib'),
+ descriptionFiles: ['package.json'],
+ modules: [
+ 'node_modules',
+ root('lib')
+ ],
+ alias: {
+ './lib/bootstrap': root('lib/bootstrap.dev'),
+ http: 'stream-http',
+ https: 'stream-http'
+ }
+ },
+ externals: {
+ "jquery": "jQuery"
+ },
+ node: {
+ fs: "empty"
+ },
+ entry: {
+ 'redoc': './lib/index.ts',
+ 'vendor': './lib/vendor.ts',
+ 'polyfills': './lib/polyfills.ts'
+ },
+
+ devServer: {
+ outputPath: root('dist'),
+ watchOptions: {
+ poll: true
+ },
+ port: 9000,
+ hot: true,
+ stats: {
+ modules: false,
+ cached: false,
+ chunk: false
+ }
+ },
+
+ output: {
+ path: root('dist'),
+ filename: '[name].js',
+ sourceMapFilename: '[name].map',
+ chunkFilename: '[id].chunk.js'
+ },
+
+ module: {
+ loaders: [{
+ test: /\.ts$/,
+ loaders: [
+ 'awesome-typescript-loader',
+ 'angular2-template-loader'
+ ],
+ exclude: [/\.(spec|e2e)\.ts$/]
+ },{
+ test: /lib\/.*\.css$/,
+ loaders: ['raw-loader'],
+ exclude: [/redoc-initial-styles\.css$/]
+ },{
+ test: /\.css$/,
+ loaders: ['style', 'css?-import'],
+ exclude: [/lib\/(?!.*redoc-initial-styles).*\.css$/]
+ },{
+ test: /\.html$/,
+ loader: 'raw-loader'
+ }]
+ },
+
+ plugins: [
+ new webpack.HotModuleReplacementPlugin(),
+
+ new webpack.optimize.CommonsChunkPlugin({
+ name: ['vendor', 'polyfills'],
+ minChunks: Infinity
+ }),
+
+ new webpack.DefinePlugin({
+ 'IS_PRODUCTION': false,
+ 'LIB_VERSION': VERSION
+ }),
+
+ new ForkCheckerPlugin()
+ ],
+}
diff --git a/build/webpack.prod.js b/build/webpack.prod.js
new file mode 100644
index 00000000..6943e7d1
--- /dev/null
+++ b/build/webpack.prod.js
@@ -0,0 +1,82 @@
+const webpack = require('webpack');
+
+const VERSION = JSON.stringify(require('../package.json').version);
+
+const root = require('./helpers').root;
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+
+module.exports = {
+ context: root(),
+ debug: false,
+ devtool: 'cheap-module-source-map',
+
+ resolve: {
+ extensions: ['', '.ts', '.js', '.json', '.css', '.scss', '.html'],
+ root: root('lib'),
+ descriptionFiles: ['package.json'],
+ modules: [
+ 'node_modules',
+ root('lib')
+ ],
+ alias: {
+ http: 'stream-http',
+ https: 'stream-http'
+ }
+ },
+ externals: {
+ "jquery": "jQuery"
+ },
+ node: {
+ fs: "empty"
+ },
+ entry: {
+ 'redoc': ['./lib/polyfills.ts', './lib/vendor.ts', './lib/index.ts']
+ },
+
+ output: {
+ path: root('dist'),
+ filename: '[name].min.js',
+ sourceMapFilename: '[name].min.map',
+ library: 'Redoc',
+ libraryTarget: 'umd',
+ umdNamedDefine: true
+ },
+
+ module: {
+ // preLoaders: [{
+ // test: /\.js$/,
+ // loader: 'source-map'
+ // // },
+ loaders: [{
+ test: /\.ts$/,
+ loader: 'awesome-typescript-loader',
+ exclude: /(node_modules)/
+ }, {
+ test: /\.css$/,
+ loaders: ['style', 'css?-import']
+ }]
+ },
+
+ plugins: [
+ new webpack.LoaderOptionsPlugin({
+ minimize: true,
+ debug: false
+ }),
+ new webpack.optimize.UglifyJsPlugin({
+ compress: {
+ warnings: false,
+ screw_ie8: true
+ },
+ mangle: { screw_ie8 : true },
+ output: {
+ comments: false
+ },
+ sourceMap: false
+ }),
+
+ new webpack.DefinePlugin({
+ 'IS_PRODUCTION': true,
+ 'LIB_VERSION': VERSION
+ })
+ ],
+}
diff --git a/build/webpack.test.js b/build/webpack.test.js
new file mode 100644
index 00000000..9cea6f9e
--- /dev/null
+++ b/build/webpack.test.js
@@ -0,0 +1,100 @@
+const webpack = require('webpack');
+const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
+
+const root = require('./helpers').root;
+const VERSION = JSON.stringify(require('../package.json').version);
+
+
+module.exports = {
+ //context: root(),
+ devtool: 'inline-source-map',
+ debug: true,
+ resolve: {
+ extensions: ['', '.ts', '.js', '.json', '.css', '.scss', '.html'],
+ root: root('lib'),
+ descriptionFiles: ['package.json'],
+ modules: [
+ 'node_modules',
+ root('lib'),
+ ],
+ alias: {
+ './lib/bootstrap': root('lib/bootstrap.dev'),
+ http: 'stream-http',
+ https: 'stream-http'
+ }
+ },
+ externals: {
+ "jquery": "jQuery"
+ },
+ node: {
+ fs: "empty"
+ },
+
+ output: {
+ path: root('dist'),
+ filename: '[name].js',
+ sourceMapFilename: '[name].map',
+ chunkFilename: '[id].chunk.js'
+ },
+
+ module: {
+ loaders: [ {
+ test: /\.ts$/,
+ loaders: [
+ 'awesome-typescript-loader'
+ ],
+ query: {
+ "sourceMap": false,
+ "inlineSourceMap": true,
+ "removeComments": true,
+ "module": "commonjs"
+ }
+ }, {
+ test: /\.ts$/,
+ loaders: [
+ 'angular2-template-loader'
+ ],
+ exclude: [/\.(spec|e2e)\.ts$/]
+ },{
+ test: /lib\/.*\.css$/,
+ loaders: ['raw-loader'],
+ exclude: [/redoc-initial-styles\.css$/]
+ },{
+ test: /\.css$/,
+ loaders: ['style', 'css?-import'],
+ exclude: [/lib\/(?!.*redoc-initial-styles).*\.css$/]
+ },{
+ test: /\.html$/,
+ loader: 'raw-loader'
+ }],
+ postLoaders: [
+
+ /**
+ * Instruments JS files with Istanbul for subsequent code coverage reporting.
+ * Instrument only testing sources.
+ *
+ * See: https://github.com/deepsweet/istanbul-instrumenter-loader
+ */
+ {
+ test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader',
+ include: root('lib'),
+ exclude: [
+ /\.(e2e|spec)\.ts$/,
+ /node_modules/
+ ]
+ }
+
+ ]
+ },
+
+
+ plugins: [
+
+ new webpack.DefinePlugin({
+ 'IS_PRODUCTION': false,
+ 'LIB_VERSION': VERSION
+ }),
+
+ new ForkCheckerPlugin()
+ ],
+}
diff --git a/demo/index.html b/demo/index.html
index 6e236386..8cb4b1d5 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -25,7 +25,10 @@
-
+
+
+
+
+