2017-04-16 17:40:47 -04:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
// Canonical path provides a consistent path (i.e. always forward slashes) across different OSes
|
|
|
|
const path = require('canonical-path');
|
|
|
|
const archiver = require('archiver');
|
|
|
|
const fs = require('fs-extra');
|
|
|
|
const globby = require('globby');
|
|
|
|
|
|
|
|
const PackageJsonCustomizer = require('./customizer/package-json/packageJsonCustomizer');
|
|
|
|
const regionExtractor = require('../transforms/examples-package/services/region-parser');
|
|
|
|
|
2017-08-22 15:31:15 -04:00
|
|
|
const EXAMPLE_CONFIG_NAME = 'example-config.json';
|
|
|
|
|
2017-04-16 17:40:47 -04:00
|
|
|
class ExampleZipper {
|
|
|
|
constructor(sourceDirName, outputDirName) {
|
|
|
|
this.examplesPackageJson = path.join(__dirname, '../examples/shared/package.json');
|
2017-08-22 15:31:15 -04:00
|
|
|
this.examplesSystemjsConfig = path.join(__dirname, '../examples/shared/boilerplate/systemjs/src/systemjs.config.js');
|
|
|
|
this.examplesSystemjsLoaderConfig = path.join(__dirname, '../examples/shared/boilerplate/systemjs/src/systemjs-angular-loader.js');
|
|
|
|
this.exampleTsconfig = path.join(__dirname, '../examples/shared/boilerplate/systemjs/src/tsconfig.json');
|
2017-04-16 17:40:47 -04:00
|
|
|
this.customizer = new PackageJsonCustomizer();
|
|
|
|
|
2017-11-03 13:08:28 -04:00
|
|
|
let gpathStackblitz = path.join(sourceDirName, '**/*stackblitz.json');
|
2017-04-16 17:40:47 -04:00
|
|
|
let gpathZipper = path.join(sourceDirName, '**/zipper.json');
|
2017-11-03 13:08:28 -04:00
|
|
|
let configFileNames = globby.sync([gpathStackblitz, gpathZipper], { ignore: ['**/node_modules/**'] });
|
2017-04-16 17:40:47 -04:00
|
|
|
configFileNames.forEach((configFileName) => {
|
|
|
|
this._zipExample(configFileName, sourceDirName, outputDirName);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
_changeTypeRoots(tsconfig) {
|
|
|
|
return tsconfig.replace('../../../', '../');
|
|
|
|
}
|
|
|
|
|
|
|
|
_createZipArchive(zipFileName) {
|
|
|
|
let dirName = path.dirname(zipFileName);
|
|
|
|
fs.ensureDirSync(dirName);
|
|
|
|
let output = fs.createWriteStream(zipFileName);
|
|
|
|
let archive = archiver('zip');
|
|
|
|
|
|
|
|
archive.on('error', function (err) {
|
|
|
|
throw err;
|
|
|
|
});
|
|
|
|
|
|
|
|
archive.pipe(output);
|
|
|
|
return archive;
|
|
|
|
}
|
|
|
|
|
2017-08-22 15:31:15 -04:00
|
|
|
_getExampleType(sourceFolder) {
|
|
|
|
const filePath = path.join(sourceFolder, EXAMPLE_CONFIG_NAME);
|
|
|
|
try {
|
|
|
|
return require(filePath, 'utf-8').projectType || 'cli';
|
|
|
|
} catch (err) { // empty file, so it is cli
|
|
|
|
return 'cli';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-14 09:02:49 -05:00
|
|
|
// rename a custom main.ts or index.html file
|
2018-05-02 08:13:32 -04:00
|
|
|
_renameFile(file, exampleType) {
|
|
|
|
if (/src\/main[-.]\w+\.ts$/.test(file) && exampleType !== 'universal') {
|
2017-12-14 09:02:49 -05:00
|
|
|
return 'src/main.ts';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (/src\/index[-.]\w+\.html$/.test(file)) {
|
|
|
|
return 'src/index.html';
|
|
|
|
}
|
|
|
|
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
2017-04-16 17:40:47 -04:00
|
|
|
_zipExample(configFileName, sourceDirName, outputDirName) {
|
|
|
|
let json = require(configFileName, 'utf-8');
|
|
|
|
const basePath = json.basePath || '';
|
|
|
|
const jsonFileName = configFileName.replace(/^.*[\\\/]/, '');
|
|
|
|
let relativeDirName = path.dirname(path.relative(sourceDirName, configFileName));
|
|
|
|
let exampleZipName;
|
2017-08-22 15:31:15 -04:00
|
|
|
const exampleType = this._getExampleType(path.join(sourceDirName, relativeDirName));
|
2017-04-16 17:40:47 -04:00
|
|
|
if (relativeDirName.indexOf('/') !== -1) { // Special example
|
2017-11-22 08:58:21 -05:00
|
|
|
exampleZipName = relativeDirName.split('/').join('-');
|
2017-04-16 17:40:47 -04:00
|
|
|
} else {
|
2017-11-03 13:08:28 -04:00
|
|
|
exampleZipName = jsonFileName.replace(/(stackblitz|zipper).json/, relativeDirName);
|
2017-04-16 17:40:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
const exampleDirName = path.dirname(configFileName);
|
|
|
|
const outputFileName = path.join(outputDirName, relativeDirName, exampleZipName + '.zip');
|
|
|
|
let defaultIncludes = ['**/*.ts', '**/*.js', '**/*.es6', '**/*.css', '**/*.html', '**/*.md', '**/*.json', '**/*.png'];
|
2017-08-22 15:31:15 -04:00
|
|
|
let alwaysIncludes = [
|
|
|
|
'bs-config.json',
|
2018-04-12 22:20:01 -04:00
|
|
|
'e2e/protractor.conf.js',
|
2018-04-30 08:23:24 -04:00
|
|
|
'angular.json',
|
2017-08-22 15:31:15 -04:00
|
|
|
'.editorconfig',
|
|
|
|
'.gitignore',
|
|
|
|
'tslint.json',
|
|
|
|
'karma-test-shim.js',
|
2017-12-14 09:02:49 -05:00
|
|
|
'tsconfig.json',
|
2017-08-22 15:31:15 -04:00
|
|
|
'src/testing/**/*',
|
|
|
|
'src/.babelrc',
|
2018-04-12 22:20:01 -04:00
|
|
|
'src/browserslist',
|
2017-08-22 15:31:15 -04:00
|
|
|
'src/favicon.ico',
|
2018-04-12 22:20:01 -04:00
|
|
|
'src/karma.conf.js',
|
2017-12-14 09:02:49 -05:00
|
|
|
'src/polyfills.ts',
|
2018-05-16 16:30:39 -04:00
|
|
|
'src/test.ts',
|
2017-12-14 09:02:49 -05:00
|
|
|
'src/typings.d.ts',
|
|
|
|
'src/environments/**/*',
|
2018-04-12 22:20:01 -04:00
|
|
|
'src/tsconfig.*',
|
|
|
|
'src/tslint.*'
|
2017-08-22 15:31:15 -04:00
|
|
|
];
|
2017-12-14 09:02:49 -05:00
|
|
|
var alwaysExcludes = [
|
2017-04-16 17:40:47 -04:00
|
|
|
'!**/bs-config.e2e.json',
|
2017-11-03 13:08:28 -04:00
|
|
|
'!**/*stackblitz.*',
|
2017-04-16 17:40:47 -04:00
|
|
|
'!**/*zipper.*',
|
|
|
|
'!**/systemjs.config.js',
|
|
|
|
'!**/npm-debug.log',
|
|
|
|
'!**/package.json',
|
|
|
|
'!**/example-config.json',
|
|
|
|
'!**/wallaby.js',
|
|
|
|
// AoT related files
|
|
|
|
'!**/aot/**/*.*',
|
|
|
|
'!**/*-aot.*'
|
|
|
|
];
|
|
|
|
|
|
|
|
if (json.files) {
|
|
|
|
if (json.files.length > 0) {
|
|
|
|
json.files = json.files.map(file => {
|
|
|
|
if (file.startsWith('!')) {
|
|
|
|
if (file.startsWith('!**')) {
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
|
|
|
return '!' + basePath + file.substr(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return basePath + file;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (json.files[0].substr(0, 1) === '!') {
|
|
|
|
json.files = defaultIncludes.concat(json.files);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
json.files = defaultIncludes;
|
|
|
|
}
|
|
|
|
|
|
|
|
json.files = json.files.concat(alwaysIncludes);
|
|
|
|
|
|
|
|
let gpaths = json.files.map((fileName) => {
|
|
|
|
fileName = fileName.trim();
|
|
|
|
if (fileName.substr(0, 1) === '!') {
|
|
|
|
return '!' + path.join(exampleDirName, fileName.substr(1));
|
|
|
|
} else {
|
|
|
|
return path.join(exampleDirName, fileName);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-12-14 09:02:49 -05:00
|
|
|
Array.prototype.push.apply(gpaths, alwaysExcludes);
|
2017-04-16 17:40:47 -04:00
|
|
|
|
|
|
|
let fileNames = globby.sync(gpaths, { ignore: ['**/node_modules/**']});
|
|
|
|
|
|
|
|
let zip = this._createZipArchive(outputFileName);
|
|
|
|
fileNames.forEach((fileName) => {
|
|
|
|
let relativePath = path.relative(exampleDirName, fileName);
|
2018-05-02 08:13:32 -04:00
|
|
|
relativePath = this._renameFile(relativePath, exampleType);
|
2017-04-16 17:40:47 -04:00
|
|
|
let content = fs.readFileSync(fileName, 'utf8');
|
|
|
|
let extn = path.extname(fileName).substr(1);
|
|
|
|
// if we don't need to clean up the file then we can do the following.
|
|
|
|
// zip.append(fs.createReadStream(fileName), { name: relativePath });
|
|
|
|
let output = regionExtractor()(content, extn).contents;
|
|
|
|
|
|
|
|
zip.append(output, { name: relativePath } )
|
|
|
|
});
|
|
|
|
|
|
|
|
// we need the package.json from _examples root, not the _boilerplate one
|
|
|
|
zip.append(this.customizer.generate(exampleType), { name: 'package.json' });
|
|
|
|
// also a systemjs config
|
2017-08-22 15:31:15 -04:00
|
|
|
if (exampleType === 'systemjs') {
|
2017-04-16 17:40:47 -04:00
|
|
|
zip.append(fs.readFileSync(this.examplesSystemjsConfig, 'utf8'), { name: 'src/systemjs.config.js' });
|
|
|
|
zip.append(fs.readFileSync(this.examplesSystemjsLoaderConfig, 'utf8'), { name: 'src/systemjs-angular-loader.js' });
|
2017-08-22 15:31:15 -04:00
|
|
|
// a modified tsconfig
|
|
|
|
let tsconfig = fs.readFileSync(this.exampleTsconfig, 'utf8');
|
|
|
|
zip.append(this._changeTypeRoots(tsconfig), {name: 'src/tsconfig.json'});
|
2017-04-16 17:40:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
zip.finalize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = ExampleZipper;
|