Socket
Socket
Sign inDemoInstall

grunt-ts

Package Overview
Dependencies
Maintainers
3
Versions
149
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

grunt-ts - npm Package Compare versions

Comparing version 1.6.4 to 1.7.0

38

package.json
{
"author": "basarat",
"name": "grunt-ts",
"description": "Compile and manage your TypeScript project",
"version": "1.6.4",
"homepage": "https://github.com/basarat/grunt-ts",
"description": "Compile and manage your TypeScript project",
"version": "1.7.0",
"homepage": "https://github.com/grunt-ts/grunt-ts",
"repository": {
"type": "git",
"url": "git@github.com:basarat/grunt-ts.git"
"url": "git@github.com:grunt-ts/grunt-ts.git"
},
"bugs": {
"url": "https://github.com/basarat/grunt-ts/issues"
"url": "https://github.com/grunt-ts/grunt-ts/issues"
},

@@ -17,3 +17,3 @@ "licenses": [

"type": "MIT",
"url": "https://github.com/basarat/grunt-ts/blob/master/LICENSE"
"url": "https://github.com/grunt-ts/grunt-ts/blob/master/LICENSE"
}

@@ -30,13 +30,20 @@ ],

"email": "viralidealogue@gmail.com"
},
{
"name": "bartvds",
"email": "bartvanderschoor@gmail.com"
}
],
],
"engines": {
"node": ">= 0.8.0"
},
"scripts": {
"test": "grunt test"
},
"dependencies": {
"typescript": "0.9.5",
"chokidar": "0.6.2",
"shelljs": "0.1.4",
"chokidar": "0.6.2",
"underscore": "1.5.1",
"underscore.string": "2.3.3"
"underscore.string": "2.3.3",
"es6-promise": "~0.1.1"
},

@@ -48,5 +55,9 @@ "peerDependencies": {

"grunt": "~0.4.0",
"grunt-tslint": "~0.4.0",
"grunt-contrib-clean": "~0.4.0",
"grunt-contrib-watch": "~0.5.1",
"grunt-contrib-nodeunit": "~0.1.2"
"grunt-contrib-jshint": "~0.8.0",
"grunt-contrib-nodeunit": "~0.2.2",
"tslint-path-formatter": "~0.1.1",
"source-map-support": "~0.2.5",
"jshint-path-reporter": "~0.1.3"
},

@@ -56,4 +67,5 @@ "optionalDependencies": {},

"gruntplugin",
"typescript"
"typescript",
"compiler"
]
}

@@ -1,22 +0,23 @@

grunt-ts
================
Written from scratch TypeScript compiler task for GruntJS.
It differs from grunt-typescript which is another excellent [grunt plugin for typescript](https://npmjs.org/package/grunt-typescript).
# grunt-ts
Following are the reasons why it was created.
[![Build Status](https://secure.travis-ci.org/basarat/grunt-ts.png?branch=master)](http://travis-ci.org/basarat/grunt-ts) [![NPM version](https://badge.fury.io/js/grunt-ts.png)](http://badge.fury.io/js/grunt-ts)
- This is written in [TypeScript](https://github.com/basarat/grunt-ts/blob/master/tasks/ts.ts)
- Gives a typescript development workflow in addition to simple file compilation.
- Super simple to update to the [latest version of the typescript](https://github.com/basarat/grunt-ts/commit/ffede564f2b20bc4dc207cb1a30dc57db7c44fe5)
Written from scratch TypeScript compiler task for GruntJS. It differs from grunt-typescript which is another excellent [grunt plugin for TypeScript](https://npmjs.org/package/grunt-typescript).
Check how it can help streamline your front end development : [Sample usage with AngularJS](http://www.youtube.com/watch?v=0-6vT7xgE4Y&hd=1)
Following are the reasons why grunt-ts was created:
Additional / longer / more basic video tutorial : http://youtu.be/Km0DpfX5ZxM
- Written in [TypeScript](https://github.com/basarat/grunt-ts/blob/master/tasks/ts.ts)
- Enables a TypeScript development workflow in addition to simple file compilation.
- Super simple to update to the [latest version of the TypeScript](https://github.com/basarat/grunt-ts/commit/ffede564f2b20bc4dc207cb1a30dc57db7c44fe5)
*If you know Grunt. Here is a quickstart full featured [Gruntfile](https://github.com/basarat/grunt-ts/blob/master/sample/Gruntfile.js)*
Check how grunt-ts can help streamline front end development: [Sample usage with AngularJS](http://www.youtube.com/watch?v=0-6vT7xgE4Y&hd=1)
Following are some key features:
======================
Additional / longer / more basic video tutorial: http://youtu.be/Km0DpfX5ZxM
###Compiler support
For a quickstart see the full featured [Gruntfile](https://github.com/basarat/grunt-ts/blob/master/sample/Gruntfile.js).
## Following are some key features:
### Compiler support
Supports the following compiler flags in both original format and camelCase (preferred):

@@ -36,24 +37,21 @@

Can also do js *file concatenation* using `--out`. Additionally supports an output directory for the generated
javascript using `--outDir` flag.
For file ordering look at Javascript Generation below.
There is also support for js *file concatenation* using `--out`. Additionally supported is an output directory for the generated JavaScript using `--outDir` flag. For file ordering look at JavaScript Generation below.
###Reference file generation
Can generate a reference.ts file for you which contains a reference to all your ts files.
This means you never need to cross reference files manually. Just reference `reference.ts` :)
### Reference file generation
Grunt-ts can generate a reference.ts file which contains a reference to all ts files.
####Javascript generation and ordering
Also if you specify both an out js file via `out` && a reference file via `reference`
it uses the generated reference file to *order the code in the generated javascript*.
This means there will never be a need to cross reference files manually, instead just reference `reference.ts` :)
In your `reference.ts` file you can specify the order for the few files you care about
and leave the rest to be maintained by grunt-ts.
E.g. in the following case the generated javascript for `someBaseClass.ts` is guaranteed to be at the top,
and the generated javascript for `main.ts`is guaranteed to be at the bottom of the single merged js file.
Everything between `grunt-start` and `grunt-end` is generated and maintained
for you. If there is no `grunt-start` section found, it is created for you. If `reference.ts` does not
exist originally, it is created for you.
#### JavaScript generation and ordering
When a output file is specified via `out` in combination with a reference file via `reference` then grunt-ts uses the generated reference file to *order the code in the generated JavaScript*.
Use `reference.ts` to specify the order for the few files the build really cares about and leave the rest to be maintained by grunt-ts.
E.g. in the following case the generated JavaScript for `someBaseClass.ts` is guaranteed to be at the top, and the generated JavaScript for `main.ts` is guaranteed to be at the bottom of the single merged js file.
Everything between `grunt-start` and `grunt-end` is generated and maintained by grunt-ts. If there is no `grunt-start` section found, it is created. If `reference.ts` does not exist originally, it is also created.
```typescript

@@ -63,3 +61,3 @@

// You can even put comments here and they are preserved
// Put comments here and they are preserved

@@ -75,9 +73,12 @@ //grunt-start

####Javscript generation Redirect
If you specify `outDir` all output javascript are redirected to this folder.
This helps keep your source folder clean.
#### JavaScript generation redirect
####AMD / RequireJS support
If you specify both `outDir` and `amdloader` option a Javascript requireJS loader file is created using the information
available from `reference.ts`. The file consists of three sections.
If an `outDir` is specified all output JavaScript is redirected to this folder to keep the source folder clean.
#### AMD / RequireJS support
When both `outDir` and `amdloader` options are specified a JavaScript requireJS loader file is created using the information available from `reference.ts`.
The file consists of three sections.:
* The initial ordered section.

@@ -87,3 +88,3 @@ * A middle order independent section loaded asynchronously.

e.g the following `reference` file
E.g the following `reference` file:

@@ -102,3 +103,3 @@ ```typescript

Corresponds to an `amdloader` (edited for readability):
This corresponds to an `amdloader` (edited for readability):

@@ -124,58 +125,66 @@ ```typescript

#####Advantage of using amdloader option
The following combination of circumstances are why you would use it instead of Compiler supported AMD.
##### Advantage of using amdloader option
* You want to use RequireJS since you prefer to debug "js" files instead of "ts" files.
This is useful in some cases and the most common way is using AMD
* You want the ability to individually compile only changed files (for a faster dev-compile-run cycle)
* However, File order doesn't matter to you, even when you have inter file depenendency (e.g. AngularJS runtime Dependency injection)
The following combination of circumstances are the main use-case for amdloader compared to the original Compiler supported AMD:
In such a case you can either create a `loader.js` manually or have grunt create it for you.
* Use RequireJS since allows to debug "js" files instead of "ts" files. This is useful in some cases, the most common way is using AMD.
* Keep the ability to individually compile only changed files (for a faster dev-compile-run cycle)
* However, File order doesn't matter, even when there is a inter file depenendency (e.g. AngularJS runtime Dependency injection)
**Further Explanation** If you use `export class Foo{}` at the root level of your file the only
way to use the type information
of Foo in another file is via an import statement `import foo = require('./potentially/long/path/to/Foo');`
The ordering implied by this isn't necessary when using a runtime Dependency injection framework like AngularJS.
Having a loader gives you the js debugging (+ async) advantages
of RequireJS without the overhead of constantly requesting via `import` to get the TypeScript type inference and
worrying about file paths when they are not relevant.
In such a case it is possible to either create a `loader.js` manually or have grunt create one.
PS: your individual file SourceMaps will continue to work. So now you can debug individual "JS" or "TS" files :)
**Further Explanation** When using `export class Foo{}` at the root level of the file the only way to use the type information of Foo in another file is via an import statement: `import foo = require('./potentially/long/path/to/Foo');`.
The ordering implied by this isn't necessary when using a runtime Dependency Injection framework like AngularJS.
###Html 2 TypeScript support
Can re-encode html files into typescript and makes them available as a variable. e.g.
a file called `test.html` containing
Having a loader gives the js debugging (+ async) advantages of RequireJS without the overhead of constantly requesting via `import` to get the TypeScript type inference and worrying about file paths when they are not relevant.
Note: the individual file source-map will continue to work so it is possible to debug individual "JS" or "TS" files :)
### Html 2 TypeScript support
Grunt-ts can re-encode html files into TypeScript and make them available as a variable.
For example a file called `test.html`:
```html
<div> Some Content </div>
```
is compiled to a typescript file `test.html.ts` containing:
Will be compiled to a TypeScript file `test.html.ts` containing:
```typescript
module test { export var html = '<div> Some content </div>' }
```
so that you can use use the variable `test.html` within your typescript to get the content of test.html
as a string. The motivation is to remove http requests to load templates in various front end frameworks.
####Html 2 TypeScript usage in AngularJS
This is great for putting variables in templateCache : http://docs.angularjs.org/api/ng.$templateCache
or even using the html string directly by setting it to the `template` properties (directives/views) instead of `templateUrl`
This will export the variable `test.html` within the TypeScript scope to get the content of test.html as a string, with the main benefit of limiting the http-requests needed to load templates in various front-end frameworks.
####Html 2 TypeScript usage in EmberJS
You can specify this string to the template on a view : http://emberjs.com/api/classes/Ember.View.html
#### Html 2 TypeScript usage in AngularJS
This is great for putting variables in templateCache: http://docs.angularjs.org/api/ng.$templateCache or even using the html string directly by setting it to the `template` properties (directives/views) instead of `templateUrl`
#### Html 2 TypeScript usage in EmberJS
It is possible to specify this string to the template on a view: http://emberjs.com/api/classes/Ember.View.html
Specifically: http://stackoverflow.com/a/9867375/390330
###Live file watching and building
Can watch a directory for you and recompile your typescript files when any typescript file changes, gets added, gets removed.
This makes sure your project is always build ready :)
### Live file watching and building
Grunt-ts can watch a directory and recompile TypeScript files when any TypeScript file changes, gets added, gets removed. Internallythe `chokidar` module is used to makes sure the project is always build ready :)
npm install
======================
## Installation
The npm package is available here : https://npmjs.org/package/grunt-ts
Grunt-ts is published as [npm package](https://npmjs.org/package/grunt-ts):
## Installation Documentation
Install nodejs. Then install grunt-cli using `npm install -g grunt-cli`. Next you can install `grunt` and `grunt-ts` by creating a `package.json`
file containing the following:
````bash
$ npm install grunt-ts --save-dev
````
For new projects and user new to node, make sure to have installed nodejs, then install grunt-cli:
````bash
$ npm install -g grunt-cli
````
Next install `grunt` and `grunt-ts` by creating a `package.json` file containing the following:
```javascript

@@ -189,75 +198,105 @@ {

```
and run `npm install` from the same directory. This will download both grunt and grunt-ts for you.
Then run `npm install` from the same directory. This will download both grunt and grunt-ts.
## Configuration Documentation
Create a `Gruntfile.js`. Modify it to load grunt-ts by adding the following lines:
module.exports = function (grunt) {
```javascript
module.exports = function (grunt) {
// load the task
grunt.loadNpmTasks("grunt-ts");
// load the task
grunt.loadNpmTasks("grunt-ts");
// Configure grunt here
}
// Configure grunt here
}
```
Then add some configuration for the plugin like so:
Add some configuration for the plugin:
grunt.initConfig({
...
ts: {
dev: { // a particular target
src: ["test/work/**/*.ts"], // The source typescript files, http://gruntjs.com/configuring-tasks#files
html: ["test/work/**/*.tpl.html"], // The source html files, https://github.com/basarat/grunt-ts#html-2-typescript-support
reference: "./test/reference.ts", // If specified, generate this file that you can use for your reference management
out: 'test/out.js', // If specified, generate an out.js file which is the merged js file
outDir: 'test/outputdirectory', // If specified, the generate javascript files are placed here. Only works if out is not specified
watch: 'test', // If specified, watches this directory for changes, and re-runs the current target
options: { // use to override the default options, http://gruntjs.com/configuring-tasks#options
target: 'es3', // 'es3' (default) | 'es5'
module: 'commonjs', // 'amd' (default) | 'commonjs'
sourceMap: true, // true (default) | false
declaration: false, // true | false (default)
removeComments: true // true (default) | false
},
```javascript
grunt.initConfig({
...
ts: {
// A specific target
build: {
// The source TypeScript files, http://gruntjs.com/configuring-tasks#files
src: ["test/work/**/*.ts"],
// The source html files, https://github.com/basarat/grunt-ts#html-2-typescript-support
html: ["test/work/**/*.tpl.html"],
// If specified, generate this file that to can use for reference management
reference: "./test/reference.ts",
// If specified, generate an out.js file which is the merged js file
out: 'test/out.js',
// If specified, the generate JavaScript files are placed here. Only works if out is not specified
outDir: 'test/outputdirectory',
// If specified, watches this directory for changes, and re-runs the current target
watch: 'test',
// Use to override the default options, http://gruntjs.com/configuring-tasks#options
options: {
// 'es3' (default) | 'es5'
target: 'es3',
// 'amd' (default) | 'commonjs'
module: 'commonjs',
// true (default) | false
sourceMap: true,
// true | false (default)
declaration: false,
// true (default) | false
removeComments: true
},
build: { // another target
src: ["test/work/**/*.ts"],
options: { // override the main options for this target
sourceMap: false,
}
},
},
...
});
// Another target
dist: {
src: ["test/work/**/*.ts"],
// Override the main options for this target
options: {
sourceMap: false,
}
},
},
...
});
```
I also recommend adding a default target you want to run in case you do not want to specify any arguments to grunt:
It is recommended to add a default target to run in case no arguments to grunt are specified:
```js
grunt.registerTask("default", ["ts:build"]);
```
grunt.registerTask("default", ["ts:dev"]);
```
You can see/grab an up-to-date sample grunt file here: https://github.com/basarat/grunt-ts/blob/master/sample/Gruntfile.js
For an example of an up-to-date configuration look at the [sample gruntfile](https://github.com/basarat/grunt-ts/blob/master/sample/Gruntfile.js)
### Different configurations per target
Configuration options are per target. You can see how you can have one set of default options and then override
these selectively for a target (e.g `build` , `dev`, `staging` etc).
This is provided by grunt : http://gruntjs.com/configuring-tasks#options
### Different configurations per target
Grunt-ts supports the Grunt convention of having [multiple configuration targets](http://gruntjs.com/configuring-tasks#options) per task. It is convenient to have one set of default options and then override these selectively for a target (e.g `build` , `dev`, `staging` etc).
### Awesome file globs
You can do pretty fancy stuff with your src file selection.
Again provided by grunt : http://gruntjs.com/configuring-tasks#files
# Contributing
For advanced use-cases there is support for [Grunt's selection options](http://gruntjs.com/configuring-tasks#files), such as using globbing or using a callback to filter paths.
## Building the project:
## Contributing
tsc "./tasks/ts.ts" --sourcemap --module commonjs
With npm and grunt-cli installed, run the following from the root of the repository:
## Running the tests:
```bash
$ npm install
```
With npm and grunt-cli installed, run the following from the root of the repository,
### Building the project:
grunt ts
```bash
$ grunt build
```
### Running the tests builds:
Some tests expect failures and will be labelled.
```bash
$ grunt test
```
We welcome new methods for writing automated tests that are a little less of a manual process.
## License
Licensed under the MIT License.

@@ -1,6 +0,16 @@

/// <reference path="../defs/node/node.d.ts"/>
/// <reference path="../defs/grunt/gruntjs.d.ts"/>
/// <reference path="../defs/underscore/underscore.d.ts"/>
/// <reference path="../defs/underscore.string/underscore.string.d.ts"/>
/// <reference path="../defs/tsd.d.ts"/>
/*
* grunt-ts
* Licensed under the MIT license.
*/
// Typescript imports
var _ = require('underscore');
var _str = require('underscore.string');
var path = require('path');
var fs = require('fs');
// plain vanilla imports
var pathSeperator = path.sep;
var Promise = require('es6-promise').Promise;
var ReferenceOrder;

@@ -49,58 +59,133 @@ (function (ReferenceOrder) {

// Typescript imports
var _ = require('underscore');
var _str = require('underscore.string');
var path = require('path');
var fs = require('fs');
/**
* Get a random hex value
*
* @returns {string} hex string
*/
function getRandomHex(length) {
if (typeof length === "undefined") { length = 16; }
var name = '';
do {
name += Math.round(Math.random() * Math.pow(16, 8)).toString(16);
} while(name.length < length);
// plain vanilla imports
var shell = require('shelljs');
var pathSeperator = path.sep;
return name.substr(0, length);
}
/**
* Get a unique temp file
*
* @returns {string} unique-ish path to file in given directory.
* @throws when it cannot create a temp file in the specified directory
*/
function getTempFile(prefix, dir) {
if (typeof dir === "undefined") { dir = ''; }
prefix = (prefix ? prefix + '-' : '');
var attempts = 100;
do {
var name = prefix + getRandomHex(8) + '.tmp.txt';
var dest = path.join(dir, name);
if (!fs.existsSync(dest)) {
return dest;
}
attempts--;
} while(attempts > 0);
throw 'Cannot create temp file in ' + dir;
}
/**
* Run a map operation async in series (simplified)
*/
function asyncSeries(arr, iter) {
arr = arr.slice(0);
var memo = [];
// Run one at a time
return new Promise(function (resolve, reject) {
var next = function () {
if (arr.length === 0) {
resolve(memo);
return;
}
Promise.cast(iter(arr.shift())).then(function (res) {
memo.push(res);
next();
}, reject);
};
next();
});
}
function pluginFn(grunt) {
// Helper
function executeNode(args) {
return new Promise(function (resolve, reject) {
grunt.util.spawn({
cmd: 'node',
args: args
}, function (error, result, code) {
var ret = {
code: code,
output: String(result)
};
resolve(ret);
});
});
}
/////////////////////////////////////////////////////////////////////
// tsc handling.
////////////////////////////////////////////////////////////////////
function resolveTypeScriptBinPath(currentPath, depth) {
var targetPath = path.resolve(__dirname, (new Array(depth + 1)).join("../../"), "../node_modules/typescript/bin");
if (path.resolve(currentPath, "node_modules/typescript/bin").length > targetPath.length) {
return null;
function resolveTypeScriptBinPath() {
var ownRoot = path.resolve(path.dirname((module).filename), '..');
var userRoot = path.resolve(ownRoot, '..', '..');
var binSub = path.join('node_modules', 'typescript', 'bin');
if (fs.existsSync(path.join(userRoot, binSub))) {
// Using project override
return path.join(userRoot, binSub);
}
if (fs.existsSync(path.resolve(targetPath, "typescript.js"))) {
return targetPath;
}
return path.join(ownRoot, binSub);
}
return resolveTypeScriptBinPath(currentPath, ++depth);
}
function getTsc(binPath) {
return '"' + binPath + '/' + 'tsc"';
var pkg = JSON.parse(fs.readFileSync(path.resolve(binPath, '..', 'package.json')).toString());
grunt.log.writeln('Using tsc v' + pkg.version);
return path.join(binPath, 'tsc');
}
var eol = grunt.util.linefeed;
var exec = shell.exec;
var cwd = path.resolve(".");
var tsc = getTsc(resolveTypeScriptBinPath(cwd, 0));
// Blindly runs the tsc task using provided options
function compileAllFiles(files, target, task) {
var cmd = files.join(' ');
var args = files.slice(0);
// boolean options
if (task.sourceMap)
cmd = cmd + ' --sourcemap';
if (task.declaration)
cmd = cmd + ' --declaration';
if (task.removeComments)
cmd = cmd + ' --removeComments';
if (task.noImplicitAny)
cmd = cmd + ' --noImplicitAny';
if (task.noResolve)
cmd = cmd + ' --noResolve';
if (task.sourceMap) {
args.push('--sourcemap');
}
if (task.declaration) {
args.push('--declaration');
}
if (task.removeComments) {
args.push('--removeComments');
}
if (task.noImplicitAny) {
args.push('--noImplicitAny');
}
if (task.noResolve) {
args.push('--noResolve');
}
// string options
cmd = cmd + ' --target ' + task.target.toUpperCase();
cmd = cmd + ' --module ' + task.module.toLowerCase();
args.push('--target', task.target.toUpperCase());
args.push('--module', task.module.toLowerCase());
// Target options:
if (target.out) {
cmd = cmd + ' --out ' + target.out;
args.push('--out', target.out);
}

@@ -111,16 +196,19 @@ if (target.outDir) {

}
cmd = cmd + ' --outDir ' + target.outDir;
args.push('--outDir', target.outDir);
}
if (task.sourceRoot) {
cmd = cmd + ' --sourceRoot ' + task.sourceRoot;
args.push('--sourceRoot', task.sourceRoot);
}
if (task.mapRoot) {
cmd = cmd + ' --mapRoot ' + task.mapRoot;
args.push('--mapRoot', task.mapRoot);
}
// Locate a compiler
var tsc = getTsc(resolveTypeScriptBinPath());
// To debug the tsc command
if (task.verbose) {
console.log(cmd.yellow);
console.log(args.join(' ').yellow);
} else {
grunt.log.verbose.writeln(cmd.yellow);
grunt.log.verbose.writeln(args.join(' ').yellow);
}

@@ -130,7 +218,20 @@

// Reason: passing all the files on the command line causes TSC to go in an infinite loop.
var tempfilename = 'tscommand.tmp.txt';
var tscExecCommand = 'node ' + tsc + ' @' + tempfilename;
fs.writeFileSync(tempfilename, cmd);
var tempfilename = getTempFile('tscommand');
if (!tempfilename) {
throw (new Error('cannot create temp file'));
}
return exec(tscExecCommand);
fs.writeFileSync(tempfilename, args.join(' '));
// Execute command
return executeNode([tsc, '@' + tempfilename]).then(function (result) {
fs.unlinkSync(tempfilename);
grunt.log.writeln(result.output);
return Promise.cast(result);
}, function (err) {
fs.unlinkSync(tempfilename);
throw err;
});
}

@@ -161,2 +262,3 @@

var signatureSectionPosition = 0;
var i;

@@ -172,3 +274,3 @@ // Read the original file if it exists

for (var i = 0; i < lines.length; i++) {
for (i = 0; i < lines.length; i++) {
var line = _str.trim(lines[i]);

@@ -178,3 +280,3 @@

if (_str.include(line, ourSignatureStart)) {
//Wait for the end signature:
// Wait for the end signature:
signatureSectionPosition = i;

@@ -188,4 +290,5 @@ inSignatureSection = true;

}
if (inSignatureSection)
if (inSignatureSection) {
continue;
}

@@ -232,6 +335,6 @@ // store the line

// Return whether the file was changed
if (lines.length == updatedFileLines.length) {
if (lines.length === updatedFileLines.length) {
var updated = false;
for (var i = 0; i < lines.length; i++) {
if (lines[i] != updatedFileLines[i]) {
for (i = 0; i < lines.length; i++) {
if (lines[i] !== updatedFileLines[i]) {
updated = true;

@@ -260,2 +363,3 @@ }

var sortedGeneratedFiles = _.sortBy(generatedFiles);
function isGeneratedFile(filename) {

@@ -270,4 +374,4 @@ return _.indexOf(sortedGeneratedFiles, filename, true) !== -1;

var referenceIntro = '/// <reference path="';
var referenceEnd = '" />';
// var referenceEnd = '" />';
// The section of unordered files

@@ -286,3 +390,3 @@ var ourSignatureStart = '//grunt-start';

if (_str.include(line, ourSignatureStart)) {
//Wait for the end signature:
// Wait for the end signature:
loopState = 1 /* unordered */;

@@ -337,8 +441,10 @@ }

function sharedStart(array) {
if (array.length == 0)
throw "Cannot find common root of empty array.";
if (array.length === 0) {
throw 'Cannot find common root of empty array.';
}
var A = array.slice(0).sort(), firstWord = A[0], lastWord = A[A.length - 1];
if (firstWord === lastWord)
if (firstWord === lastWord) {
return firstWord;
else {
} else {
var i = -1;

@@ -349,3 +455,4 @@ do {

var lastWordChar = lastWord.charAt(i);
} while(firstWordChar == lastWordChar);
} while(firstWordChar === lastWordChar);
return firstWord.substring(0, i);

@@ -377,3 +484,3 @@ }

} else {
grunt.warn("No files in reference file: " + referenceFile);
grunt.warn('No files in reference file: ' + referenceFile);
}

@@ -432,3 +539,3 @@ if (files.before.length > 0) {

//remove ts extension '.ts':
// remove ts extension '.ts':
file = file.substr(0, file.length - 3);

@@ -440,3 +547,3 @@

// Prepend "./" to prevent "basePath" requirejs setting from interferring:
file = "./" + file;
file = './' + file;

@@ -447,3 +554,4 @@ return file;

}
grunt.log.verbose.writeln("Making files relative to outDir...");
grunt.log.verbose.writeln('Making files relative to outDir...');
files.before = makeRelativeToOutDir(files.before);

@@ -516,3 +624,3 @@ files.generated = makeRelativeToOutDir(files.generated);

////////////////////////////////////////////////////////////////////
//html -> js processing functions:
// html -> js processing functions:
// Originally from karma-html2js-preprocessor

@@ -523,3 +631,3 @@ // Refactored nicely in html2js grunt task

var escapeContent = function (content, quoteChar) {
if (typeof quoteChar === "undefined") { quoteChar = "'"; }
if (typeof quoteChar === "undefined") { quoteChar = '\''; }
var quoteRegexp = new RegExp('\\' + quoteChar, 'g');

@@ -532,6 +640,6 @@ var nlReplace = '';

function stripBOM(str) {
return 0xFEFF == str.charCodeAt(0) ? str.substring(1) : str;
return 0xFEFF === str.charCodeAt(0) ? str.substring(1) : str;
}
var htmlTemplate = _.template("module <%= modulename %> { export var <%= varname %> = '<%= content %>' } ");
var htmlTemplate = _.template('module <%= modulename %> { export var <%= varname %> = \'<%= content %>\' } ');

@@ -550,3 +658,3 @@ // Compile an HTML file to a TS file

// Write the content to a file
var outputfile = filename + ".ts";
var outputfile = filename + '.ts';

@@ -562,4 +670,5 @@ fs.writeFileSync(outputfile, fileContent);

function generateTemplateCache(src, dest, basePath) {
if (!src.length)
if (!src.length) {
return;
}

@@ -606,2 +715,7 @@ // Resolve the relative path from basePath to each src file

// make async
var done = currenttask.async();
var watch;
// setup default options

@@ -638,3 +752,3 @@ var options = currenttask.options({

} else {
console.warn(('The --removeComments value of "' + options.removeComments + '" ' + 'supercedes the --comments value of ' + options.comments + '"').magenta);
console.warn(('The --removeComments value of "' + options.removeComments + '" ' + 'supercedes the --comments value of "' + options.comments + '"').magenta);
}

@@ -644,16 +758,14 @@ }

// Was the whole process successful
var success = true;
var watch;
// Some interesting logs:
//http://gruntjs.com/api/inside-tasks#inside-multi-tasks
//console.log(this)
//console.log(this.files[0]); // An array of target files ( only one in our case )
//console.log(this.files[0].src); // a getter for a resolved list of files
//console.log(this.files[0].orig.src); // The original glob / array / !array / <% array %> for files. Can be very fancy :)
// http://gruntjs.com/api/inside-tasks#inside-multi-tasks
// console.log(this)
// console.log(this.files[0]); // An array of target files ( only one in our case )
// console.log(this.files[0].src); // a getter for a resolved list of files
// console.log(this.files[0].orig.src); // The original glob / array / !array / <% array %> for files. Can be very fancy :)
// NOTE: to access the specified src files we use
// currenttaks.data as that is the raw (non interpolated) string that we reinterpolate ourselves in case the file system as changed since this task was started
// currenttaks.data as that is the raw (non interpolated) string that we reinterpolate ourselves,
// in case the file system as changed since this task was started
// this.files[0] is actually a single in our case as we gave examples of one source / out per target
this.files.forEach(function (target) {
// Run compiler
asyncSeries(this.files, function (target) {
// Create a reference file?

@@ -668,3 +780,3 @@ var reference = target.reference;

function isReferenceFile(filename) {
return path.resolve(filename) == referenceFile;
return path.resolve(filename) === referenceFile;
}

@@ -681,3 +793,3 @@

function isOutFile(filename) {
return path.resolve(filename) == outFile_d_ts;
return path.resolve(filename) === outFile_d_ts;
}

@@ -694,14 +806,11 @@

var lastCompile = 0;
// Compiles all the files
// Uses the blind tsc compile task
// logs errors
// Time the whole process
var starttime;
var endtime;
function runCompilation(files, target, options) {
// Don't run it yet
grunt.log.writeln('Compiling...'.yellow);
// Time the task and go
starttime = new Date().getTime();
// The files to compile

@@ -721,18 +830,21 @@ var filesToCompile = files;

// Time the compiler process
var starttime = new Date().getTime();
var endtime;
// Compile the files
var result = compileAllFiles(filesToCompile, target, options);
return compileAllFiles(filesToCompile, target, options).then(function (result) {
// End the timer
lastCompile = endtime = new Date().getTime();
// End the timer
endtime = new Date().getTime();
// Evaluate the result
if (result.code != 0) {
var msg = "Compilation failed";
grunt.log.error(msg.red);
return false;
} else {
var time = (endtime - starttime) / 1000;
grunt.log.writeln(('Success: ' + time.toFixed(2) + 's for ' + files.length + ' typescript files').green);
return true;
}
// Evaluate the result
if (!result || result.code) {
grunt.log.error('Compilation failed'.red);
return false;
} else {
var time = (endtime - starttime) / 1000;
grunt.log.writeln(('Success: ' + time.toFixed(2) + 's for ' + files.length + ' typescript files').green);
return true;
}
});
}

@@ -798,11 +910,12 @@

// compile, If there are any files to compile!
// Compile, if there are any files to compile!
if (files.length > 0) {
success = runCompilation(files, target, options);
// Create the loader if specified & compiliation succeeded
if (success && !!amdloaderPath) {
var referenceOrder = getReferencesInOrder(referenceFile, referencePath, generatedHtmlFiles);
updateAmdLoader(referenceFile, referenceOrder, amdloaderFile, amdloaderPath, target.outDir);
}
return runCompilation(files, target, options).then(function (success) {
// Create the loader if specified & compiliation succeeded
if (success && !!amdloaderPath) {
var referenceOrder = getReferencesInOrder(referenceFile, referencePath, generatedHtmlFiles);
updateAmdLoader(referenceFile, referenceOrder, amdloaderFile, amdloaderPath, target.outDir);
}
return success;
});
} else {

@@ -812,13 +925,10 @@ grunt.log.writeln('No files to compile'.red);

}
// Nothing to do
return Promise.resolve(true);
}
// Initial compilation:
filterFilesAndCompile();
// Watch a folder?
watch = target.watch;
if (!!watch) {
// make async
var done = currenttask.async();
// A debounced version of compile

@@ -830,9 +940,10 @@ var debouncedCompile = _.debounce(filterFilesAndCompile, 150);

// Only ts and html :
if (!endsWith(filepath.toLowerCase(), '.ts') && !endsWith(filepath.toLowerCase(), '.html'))
if (!endsWith(filepath.toLowerCase(), '.ts') && !endsWith(filepath.toLowerCase(), '.html')) {
return;
}
// Do not run if just ran, behaviour same as grunt-watch
// These are the files our run modified
if ((new Date().getTime() - endtime) <= 100) {
//grunt.log.writeln((' ///' + ' >>' + filepath).grey);
if ((new Date().getTime() - lastCompile) <= 100) {
// grunt.log.writeln((' ///' + ' >>' + filepath).grey);
return;

@@ -867,7 +978,9 @@ }

}
});
if (!watch) {
return success;
}
return filterFilesAndCompile();
}).then(function (res) {
// Ignore res? (either logs or throws)
if (!watch) {
done();
}
}, done);
});

@@ -874,0 +987,0 @@ }

@@ -1,5 +0,2 @@

/// <reference path="../defs/node/node.d.ts"/>
/// <reference path="../defs/grunt/gruntjs.d.ts"/>
/// <reference path="../defs/underscore/underscore.d.ts"/>
/// <reference path="../defs/underscore.string/underscore.string.d.ts"/>
/// <reference path="../defs/tsd.d.ts"/>

@@ -11,2 +8,12 @@ /*

// Typescript imports
import _ = require('underscore');
import _str = require('underscore.string');
import path = require('path');
import fs = require('fs');
// plain vanilla imports
var pathSeperator = path.sep;
var Promise: typeof Promise = require('es6-promise').Promise;
interface ICompileResult {

@@ -108,7 +115,7 @@ code: number;

*/
it: R
it: R;
/**
* Time in milliseconds.
*/
time: number
time: number;
} {

@@ -124,13 +131,81 @@ var starttime = new Date().getTime();

// Typescript imports
import _ = require('underscore');
import _str = require('underscore.string');
import path = require('path');
import fs = require('fs');
// plain vanilla imports
var shell = require('shelljs');
var pathSeperator = path.sep;
/**
* Get a random hex value
*
* @returns {string} hex string
*/
function getRandomHex(length: number = 16): string {
var name: string = '';
do {
name += Math.round(Math.random() * Math.pow(16, 8)).toString(16);
}
while (name.length < length);
return name.substr(0, length);
}
/**
* Get a unique temp file
*
* @returns {string} unique-ish path to file in given directory.
* @throws when it cannot create a temp file in the specified directory
*/
function getTempFile(prefix?: string, dir: string = ''): string {
prefix = (prefix ? prefix + '-' : '');
var attempts = 100;
do {
var name: string = prefix + getRandomHex(8) + '.tmp.txt';
var dest: string = path.join(dir, name);
if (!fs.existsSync(dest)) {
return dest;
}
attempts--;
}
while (attempts > 0);
throw 'Cannot create temp file in ' + dir;
}
/**
* Run a map operation async in series (simplified)
*/
function asyncSeries<U, W>(arr: U[], iter: (item: U) => Promise<W>): Promise<W[]> {
arr = arr.slice(0);
var memo: W[] = [];
// Run one at a time
return new Promise((resolve, reject) => {
var next = () => {
if (arr.length === 0) {
resolve(memo);
return;
}
Promise.cast(iter(arr.shift())).then((res: W) => {
memo.push(res);
next();
}, reject);
};
next();
});
}
function pluginFn(grunt: IGrunt) {
// Helper
function executeNode(args: string[]): Promise<ICompileResult> {
return new Promise((resolve, reject) => {
grunt.util.spawn({
cmd: 'node',
args: args
}, (error, result, code) => {
var ret: ICompileResult = {
code: code,
output: String(result)
};
resolve(ret);
});
});
}
/////////////////////////////////////////////////////////////////////

@@ -140,46 +215,52 @@ // tsc handling.

function resolveTypeScriptBinPath(currentPath, depth): string {
var targetPath = path.resolve(__dirname,
(new Array(depth + 1)).join("../../"),
"../node_modules/typescript/bin");
if (path.resolve(currentPath, "node_modules/typescript/bin").length > targetPath.length) {
return null;
function resolveTypeScriptBinPath(): string {
var ownRoot = path.resolve(path.dirname((module).filename), '..');
var userRoot = path.resolve(ownRoot, '..', '..');
var binSub = path.join('node_modules', 'typescript', 'bin');
if (fs.existsSync(path.join(userRoot, binSub))) {
// Using project override
return path.join(userRoot, binSub);
}
if (fs.existsSync(path.resolve(targetPath, "typescript.js"))) {
return targetPath;
}
return path.join(ownRoot, binSub);
}
return resolveTypeScriptBinPath(currentPath, ++depth);
}
function getTsc(binPath: string): string {
return '"' + binPath + '/' + 'tsc"';
var pkg = JSON.parse(fs.readFileSync(path.resolve(binPath, '..', 'package.json')).toString());
grunt.log.writeln('Using tsc v' + pkg.version);
return path.join(binPath, 'tsc');
}
var eol = grunt.util.linefeed;
var exec = shell.exec;
var cwd = path.resolve(".");
var tsc = getTsc(resolveTypeScriptBinPath(cwd, 0));
// Blindly runs the tsc task using provided options
function compileAllFiles(files: string[], target: ITargetOptions, task: ITaskOptions): ICompileResult {
function compileAllFiles(files: string[], target: ITargetOptions, task: ITaskOptions): Promise<ICompileResult> {
var cmd: string = files.join(' ');
var args: string[] = files.slice(0);
// boolean options
if (task.sourceMap)
cmd = cmd + ' --sourcemap';
if (task.declaration)
cmd = cmd + ' --declaration';
if (task.removeComments)
cmd = cmd + ' --removeComments';
if (task.noImplicitAny)
cmd = cmd + ' --noImplicitAny';
if (task.noResolve)
cmd = cmd + ' --noResolve';
if (task.sourceMap) {
args.push('--sourcemap');
}
if (task.declaration) {
args.push('--declaration');
}
if (task.removeComments) {
args.push('--removeComments');
}
if (task.noImplicitAny) {
args.push('--noImplicitAny');
}
if (task.noResolve) {
args.push('--noResolve');
}
// string options
cmd = cmd + ' --target ' + task.target.toUpperCase();
cmd = cmd + ' --module ' + task.module.toLowerCase();
args.push('--target', task.target.toUpperCase());
args.push('--module', task.module.toLowerCase());
// Target options:
if (target.out) {
cmd = cmd + ' --out ' + target.out;
args.push('--out', target.out);
}

@@ -190,26 +271,42 @@ if (target.outDir) {

}
cmd = cmd + ' --outDir ' + target.outDir;
args.push('--outDir', target.outDir);
}
if (task.sourceRoot) {
cmd = cmd + ' --sourceRoot ' + task.sourceRoot;
args.push('--sourceRoot', task.sourceRoot);
}
if (task.mapRoot) {
cmd = cmd + ' --mapRoot ' + task.mapRoot;
args.push('--mapRoot', task.mapRoot);
}
// Locate a compiler
var tsc = getTsc(resolveTypeScriptBinPath());
// To debug the tsc command
if (task.verbose) {
console.log(cmd.yellow);
console.log(args.join(' ').yellow);
}
else {
grunt.log.verbose.writeln(cmd.yellow);
grunt.log.verbose.writeln(args.join(' ').yellow);
}
// Create a temp last command file and use that to guide tsc.
// Create a temp last command file and use that to guide tsc.
// Reason: passing all the files on the command line causes TSC to go in an infinite loop.
var tempfilename = 'tscommand.tmp.txt';
var tscExecCommand = 'node ' + tsc + ' @' + tempfilename;
fs.writeFileSync(tempfilename, cmd);
var tempfilename = getTempFile('tscommand');
if (!tempfilename) {
throw(new Error('cannot create temp file'));
}
return exec(tscExecCommand);
fs.writeFileSync(tempfilename, args.join(' '));
// Execute command
return executeNode([tsc , '@' + tempfilename]).then((result: ICompileResult) => {
fs.unlinkSync(tempfilename);
grunt.log.writeln(result.output);
return Promise.cast(result);
}, (err) => {
fs.unlinkSync(tempfilename);
throw err;
});
}

@@ -241,2 +338,3 @@

var signatureSectionPosition = 0;
var i;

@@ -252,3 +350,3 @@ // Read the original file if it exists

for (var i = 0; i < lines.length; i++) {
for (i = 0; i < lines.length; i++) {

@@ -259,3 +357,3 @@ var line = _str.trim(lines[i]);

if (_str.include(line, ourSignatureStart)) {
//Wait for the end signature:
// Wait for the end signature:
signatureSectionPosition = i;

@@ -269,3 +367,5 @@ inSignatureSection = true;

}
if (inSignatureSection) continue;
if (inSignatureSection) {
continue;
}

@@ -310,6 +410,6 @@ // store the line

// Return whether the file was changed
if (lines.length == updatedFileLines.length) {
if (lines.length === updatedFileLines.length) {
var updated = false;
for (var i = 0; i < lines.length; i++) {
if (lines[i] != updatedFileLines[i]) {
for (i = 0; i < lines.length; i++) {
if (lines[i] !== updatedFileLines[i]) {
updated = true;

@@ -341,2 +441,3 @@ }

var sortedGeneratedFiles = _.sortBy(generatedFiles);
function isGeneratedFile(filename: string): boolean {

@@ -351,3 +452,3 @@ return _.indexOf(sortedGeneratedFiles, filename, true) !== -1;

var referenceIntro = '/// <reference path="';
var referenceEnd = '" />';
// var referenceEnd = '" />';

@@ -368,3 +469,3 @@ // The section of unordered files

if (_str.include(line, ourSignatureStart)) {
//Wait for the end signature:
// Wait for the end signature:
loopState = ReferenceOrder.unordered;

@@ -413,7 +514,12 @@ }

function sharedStart(array: string[]): string {
if (array.length == 0) throw "Cannot find common root of empty array.";
if (array.length === 0) {
throw 'Cannot find common root of empty array.';
}
var A = array.slice(0).sort(),
firstWord = A[0],
lastWord = A[A.length - 1];
if (firstWord === lastWord) return firstWord;
if (firstWord === lastWord) {
return firstWord;
}
else {

@@ -425,3 +531,4 @@ var i = -1;

var lastWordChar = lastWord.charAt(i);
} while (firstWordChar == lastWordChar);
} while (firstWordChar === lastWordChar);
return firstWord.substring(0, i);

@@ -453,3 +560,3 @@ }

else {
grunt.warn("No files in reference file: " + referenceFile);
grunt.warn('No files in reference file: ' + referenceFile);
}

@@ -492,3 +599,3 @@ if (files.before.length > 0) {

//remove ts extension '.ts':
// remove ts extension '.ts':
file = file.substr(0, file.length - 3);

@@ -500,3 +607,3 @@

// Prepend "./" to prevent "basePath" requirejs setting from interferring:
file = "./" + file;
file = './' + file;

@@ -507,3 +614,4 @@ return file;

}
grunt.log.verbose.writeln("Making files relative to outDir...");
grunt.log.verbose.writeln('Making files relative to outDir...');
files.before = makeRelativeToOutDir(files.before);

@@ -581,7 +689,7 @@ files.generated = makeRelativeToOutDir(files.generated);

/////////////////////////////////////////////////////////////////////
// HTML -> TS
/////////////////////////////////////////////////////////////////////
// HTML -> TS
////////////////////////////////////////////////////////////////////
//html -> js processing functions:
// html -> js processing functions:
// Originally from karma-html2js-preprocessor

@@ -591,3 +699,3 @@ // Refactored nicely in html2js grunt task

// Modified nlReplace to be an empty string
var escapeContent = function (content: string, quoteChar= "'"): string {
var escapeContent = function (content: string, quoteChar= '\''): string {
var quoteRegexp = new RegExp('\\' + quoteChar, 'g');

@@ -600,3 +708,3 @@ var nlReplace = '';

function stripBOM(str) {
return 0xFEFF == str.charCodeAt(0)
return 0xFEFF === str.charCodeAt(0)
? str.substring(1)

@@ -606,5 +714,5 @@ : str;

var htmlTemplate = _.template("module <%= modulename %> { export var <%= varname %> = '<%= content %>' } ");
var htmlTemplate = _.template('module <%= modulename %> { export var <%= varname %> = \'<%= content %>\' } ');
// Compile an HTML file to a TS file
// Compile an HTML file to a TS file
// Return the filename. This filename will be required by reference.ts

@@ -620,4 +728,4 @@ function compileHTML(filename: string): string {

// Write the content to a file
var outputfile = filename + ".ts";
// Write the content to a file
var outputfile = filename + '.ts';

@@ -628,3 +736,3 @@ fs.writeFileSync(outputfile, fileContent);

/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// AngularJS templateCache

@@ -636,6 +744,7 @@ ////////////////////////////////////////////////////////////////////

function generateTemplateCache(src: string[], dest: string, basePath: string) {
if (!src.length) {
return;
}
if (!src.length) return;
// Resolve the relative path from basePath to each src file
// Resolve the relative path from basePath to each src file
var relativePaths: string[] = _.map(src, (anHtmlFile) => 'text!' + makeReferencePath(basePath, anHtmlFile));

@@ -670,8 +779,8 @@ var fileNames: string[] = _.map(src, (anHtmlFile) => path.basename(anHtmlFile));

/////////////////////////////////////////////////////////////////////
// The grunt task
/////////////////////////////////////////////////////////////////////
// The grunt task
////////////////////////////////////////////////////////////////////
// Note: this function is called once for each target
// so task + target options are a bit blurred inside this function
// so task + target options are a bit blurred inside this function
grunt.registerMultiTask('ts', 'Compile TypeScript files', function() {

@@ -681,3 +790,8 @@

// setup default options
// make async
var done: grunt.task.AsyncResultCatcher = currenttask.async();
var watch;
// setup default options
var options = currenttask.options<ITaskOptions>({

@@ -715,3 +829,3 @@ allowBool: false,

console.warn(('The --removeComments value of "' + options.removeComments + '" ' +
'supercedes the --comments value of ' + options.comments + '"').magenta)
'supercedes the --comments value of "' + options.comments + '"').magenta);
}

@@ -721,21 +835,19 @@ }

// Was the whole process successful
var success = true;
var watch;
// Some interesting logs:
// http://gruntjs.com/api/inside-tasks#inside-multi-tasks
// console.log(this)
// console.log(this.files[0]); // An array of target files ( only one in our case )
// console.log(this.files[0].src); // a getter for a resolved list of files
// console.log(this.files[0].orig.src); // The original glob / array / !array / <% array %> for files. Can be very fancy :)
// Some interesting logs:
//http://gruntjs.com/api/inside-tasks#inside-multi-tasks
//console.log(this)
//console.log(this.files[0]); // An array of target files ( only one in our case )
//console.log(this.files[0].src); // a getter for a resolved list of files
//console.log(this.files[0].orig.src); // The original glob / array / !array / <% array %> for files. Can be very fancy :)
// NOTE: to access the specified src files we use
// currenttaks.data as that is the raw (non interpolated) string that we reinterpolate ourselves in case the file system as changed since this task was started
// currenttaks.data as that is the raw (non interpolated) string that we reinterpolate ourselves,
// in case the file system as changed since this task was started
// this.files[0] is actually a single in our case as we gave examples of one source / out per target
this.files.forEach(function (target: ITargetOptions) {
// Run compiler
asyncSeries(this.files, (target: ITargetOptions) => {
// Create a reference file?
// Create a reference file?
var reference = target.reference;

@@ -746,9 +858,9 @@ var referenceFile;

referenceFile = path.resolve(reference);
referencePath = path.dirname(referenceFile)
referencePath = path.dirname(referenceFile);
}
function isReferenceFile(filename: string) {
return path.resolve(filename) == referenceFile;
return path.resolve(filename) === referenceFile;
}
// Create an output file?
// Create an output file?
var out = target.out;

@@ -762,6 +874,6 @@ var outFile;

function isOutFile(filename: string): boolean {
return path.resolve(filename) == outFile_d_ts;
return path.resolve(filename) === outFile_d_ts;
}
// Create an amd loader?
// Create an amd loader?
var amdloader = target.amdloader;

@@ -775,14 +887,12 @@ var amdloaderFile;

// Compiles all the files
var lastCompile = 0;
// Compiles all the files
// Uses the blind tsc compile task
// logs errors
// Time the whole process
var starttime;
var endtime;
function runCompilation(files: string[], target: ITargetOptions, options: ITaskOptions) {
function runCompilation(files: string[], target: ITargetOptions, options: ITaskOptions): Promise<boolean> {
// Don't run it yet
grunt.log.writeln('Compiling...'.yellow);
// Time the task and go
starttime = new Date().getTime();
// The files to compile

@@ -794,3 +904,3 @@ var filesToCompile = files;

if (!!referencePath && target.out) {
filesToCompile = [referenceFile]
filesToCompile = [referenceFile];
}

@@ -801,30 +911,33 @@

// Time the compiler process
var starttime = new Date().getTime();
var endtime;
// Compile the files
var result = compileAllFiles(filesToCompile, target, options);
return compileAllFiles(filesToCompile, target, options).then((result: ICompileResult) => {
// End the timer
lastCompile = endtime = new Date().getTime();
// End the timer
endtime = new Date().getTime();
// Evaluate the result
if (result.code != 0) {
var msg = "Compilation failed"/*+result.output*/;
grunt.log.error(msg.red);
return false;
}
else {
var time = (endtime - starttime) / 1000;
grunt.log.writeln(('Success: ' + time.toFixed(2) + 's for ' + files.length + ' typescript files').green);
return true;
}
// Evaluate the result
if (!result || result.code) {
grunt.log.error('Compilation failed'.red);
return false;
}
else {
var time = (endtime - starttime) / 1000;
grunt.log.writeln(('Success: ' + time.toFixed(2) + 's for ' + files.length + ' typescript files').green);
return true;
}
});
}
// Find out which files to compile
// Then calls the compile function on those files
// Then calls the compile function on those files
// Also this funciton is debounced
function filterFilesAndCompile() {
function filterFilesAndCompile(): Promise<boolean> {
// Html files:
// Note:
// compile html files before reference file creation. Which is done in runCompilation
// compile html files before globbing the file system again
// Html files:
// Note:
// compile html files before reference file creation. Which is done in runCompilation
// compile html files before globbing the file system again
var generatedHtmlFiles = [];

@@ -835,4 +948,4 @@ if (currenttask.data.html) {

}
// The template cache files do not go into generated files.
// You are free to generate a `ts OR js` file, both should just work
// The template cache files do not go into generated files.
// You are free to generate a `ts OR js` file, both should just work
if (currenttask.data.templateCache) {

@@ -872,3 +985,3 @@ if (!currenttask.data.templateCache.src || !currenttask.data.templateCache.dest || !currenttask.data.templateCache.baseUrl) {

var result = timeIt(() => {
return updateReferenceFile(files, generatedHtmlFiles, referenceFile, referencePath)
return updateReferenceFile(files, generatedHtmlFiles, referenceFile, referencePath);
});

@@ -880,11 +993,12 @@ if (result.it === true) {

// compile, If there are any files to compile!
// Compile, if there are any files to compile!
if (files.length > 0) {
success = runCompilation(files, target, options);
// Create the loader if specified & compiliation succeeded
if (success && !!amdloaderPath) {
var referenceOrder: IReferences = getReferencesInOrder(referenceFile, referencePath, generatedHtmlFiles);
updateAmdLoader(referenceFile, referenceOrder, amdloaderFile, amdloaderPath, target.outDir);
}
return runCompilation(files, target, options).then((success: boolean) => {
// Create the loader if specified & compiliation succeeded
if (success && !!amdloaderPath) {
var referenceOrder: IReferences = getReferencesInOrder(referenceFile, referencePath, generatedHtmlFiles);
updateAmdLoader(referenceFile, referenceOrder, amdloaderFile, amdloaderPath, target.outDir);
}
return success;
});
}

@@ -895,31 +1009,28 @@ else {

}
// Nothing to do
return Promise.resolve(true);
}
// Initial compilation:
filterFilesAndCompile();
// Watch a folder?
// Watch a folder?
watch = target.watch;
if (!!watch) {
// make async
var done: grunt.task.AsyncResultCatcher = currenttask.async();
// A debounced version of compile
// A debounced version of compile
var debouncedCompile = _.debounce(filterFilesAndCompile, 150);
// local event to handle file event
// local event to handle file event
function handleFileEvent(filepath: string, displaystr: string) {
// Only ts and html :
if (!endsWith(filepath.toLowerCase(), '.ts') && !endsWith(filepath.toLowerCase(), '.html'))
// Only ts and html :
if (!endsWith(filepath.toLowerCase(), '.ts') && !endsWith(filepath.toLowerCase(), '.html')) {
return;
}
// Do not run if just ran, behaviour same as grunt-watch
// These are the files our run modified
if ((new Date().getTime() - endtime) <= 100) {
//grunt.log.writeln((' ///' + ' >>' + filepath).grey);
// Do not run if just ran, behaviour same as grunt-watch
// These are the files our run modified
if ((new Date().getTime() - lastCompile) <= 100) {
// grunt.log.writeln((' ///' + ' >>' + filepath).grey);
return;
}
// Log and run the debounced version.
// Log and run the debounced version.
grunt.log.writeln((displaystr + ' >>' + filepath).yellow);

@@ -929,10 +1040,10 @@ debouncedCompile();

// get path
// get path
var watchpath = path.resolve(watch);
// create a file watcher for path
// create a file watcher for path
var chokidar = require('chokidar');
var watcher = chokidar.watch(watchpath, { ignoreInitial: true, persistent: true });
// Log what we are doing
// Log what we are doing
grunt.log.writeln(('Watching all TypeScript / Html files under : ' + watchpath).cyan);

@@ -946,10 +1057,12 @@

}
return filterFilesAndCompile();
});
if (!watch) {
return success;
}
}).then((res: boolean[]) => {
// Ignore res? (either logs or throws)
if (!watch) {
done();
}
}, done);
});
}
export = pluginFn;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc