Skip to content
This repository has been archived by the owner on Mar 26, 2018. It is now read-only.

Commit

Permalink
feat(app): add support for --typescript option
Browse files Browse the repository at this point in the history
Uses grunt-tsd to retrieve an initial set of typescript definitions.
Adds templates for typescript versions of angular items.

Based upon commit 'refs/pull/539/head' of github.com:yeoman/generator-angular
  • Loading branch information
awk authored and eddiemonge committed Jul 24, 2015
1 parent 8a9a8af commit e579df9
Show file tree
Hide file tree
Showing 24 changed files with 478 additions and 18 deletions.
19 changes: 19 additions & 0 deletions app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ var Generator = module.exports = function Generator(args, options) {
this.env.options.coffee = this.options.coffee;
}

if (typeof this.env.options.typescript === 'undefined') {
this.option('typescript', {
desc: 'Generate TypeScript instead of JavaScript'
});

// attempt to detect if user is using TS or not
// if cml arg provided, use that; else look for the existence of ts
if (!this.options.typescript &&
this.expandFiles(path.join(this.appPath, '/scripts/**/*.ts'), {}).length > 0) {
this.options.typescript = true;
}

this.env.options.typescript = this.options.typescript;
}

this.hookFor('angular:common', {
args: args
});
Expand Down Expand Up @@ -303,10 +318,14 @@ Generator.prototype.createIndexHtml = function createIndexHtml() {

Generator.prototype.packageFiles = function packageFiles() {
this.coffee = this.env.options.coffee;
this.typescript = this.env.options.typescript;
this.template('root/_bower.json', 'bower.json');
this.template('root/_bowerrc', '.bowerrc');
this.template('root/_package.json', 'package.json');
this.template('root/_Gruntfile.js', 'Gruntfile.js');
if (this.typescript) {
this.template('root/_tsd.json', 'tsd.json');
}
this.template('root/README.md', 'README.md');
};

Expand Down
3 changes: 3 additions & 0 deletions main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ util.inherits(Generator, ScriptBase);

Generator.prototype.createAppFile = function createAppFile() {
this.angularModules = this.env.options.angularDeps;
this.ngCookies = this.env.options.ngCookies;
this.ngResource = this.env.options.ngResource;
this.ngSanitize = this.env.options.ngSanitize;
this.ngRoute = this.env.options.ngRoute;
this.appTemplate('app', 'scripts/app');
};
41 changes: 37 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ angular.module('myMod').config(function ($provide) {
## Options
In general, these options can be applied to any generator, though they only affect generators that produce scripts.

### CoffeeScript
For generators that output scripts, the `--coffee` option will output CoffeeScript instead of JavaScript.
### CoffeeScript and TypeScript
For generators that output scripts, the `--coffee` option will output CoffeeScript instead of JavaScript, and `--typescript` will output TypeScript instead of JavaScript.

For example:
```bash
Expand All @@ -202,9 +202,42 @@ angular.module('myMod')
.controller 'UserCtrl', ($scope) ->
```

A project can mix CoffeScript and JavaScript files.
For example:
```bash
yo angular:controller user --typescript
```

Produces `app/scripts/controller/user.ts`:
```typescript
/// <reference path="../app.ts" />

'use strict';

module demoApp {
export interface IUserScope extends ng.IScope {
awesomeThings: any[];
}

export class UserCtrl {

constructor (private $scope:IUserScope) {
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
}
}
}

angular.module('demoApp')
.controller('UserCtrl', demoApp.UserCtrl);
```


A project can mix TypeScript, CoffeScript, and JavaScript files.

To output JavaScript files, even if CoffeeScript files exist (the default is to output CoffeeScript files if the generator finds any in the project), use `--coffee=false`.
To output JavaScript files, even if CoffeeScript (or TypeScript) files exist (the default is to output CoffeeScript files if the generator finds any in the project), use `--coffee=false` and/or `--typescript=false`.

### Minification Safe

Expand Down
7 changes: 5 additions & 2 deletions route/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ var Generator = module.exports = function Generator() {
required: false
});

var coffee = this.env.options.coffee;
var typescript = this.env.options.typescript;
var bower = require(path.join(process.cwd(), 'bower.json'));
var match = require('fs').readFileSync(path.join(
this.env.options.appPath,
'scripts/app.' + (this.env.options.coffee ? 'coffee' : 'js')
'scripts/app.' + (coffee ? 'coffee' : typescript ? 'ts': 'js')
), 'utf-8').match(/\.when/);

if (
Expand Down Expand Up @@ -52,10 +54,11 @@ Generator.prototype.rewriteAppJs = function () {
this.uri = this.options.uri;
}

var typescript = this.env.options.typescript;
var config = {
file: path.join(
this.env.options.appPath,
'scripts/app.' + (coffee ? 'coffee' : 'js')
'scripts/app.' + (coffee ? 'coffee' : typescript ? 'ts': 'js')
),
needle: '.otherwise',
splicable: [
Expand Down
19 changes: 19 additions & 0 deletions script-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ var Generator = module.exports = function Generator() {

this.env.options.testPath = this.env.options.testPath || bowerJson.testPath || 'test/spec';

this.env.options.typescript = this.options.typescript;
if (typeof this.env.options.typescript === 'undefined') {
this.option('typescript');

// attempt to detect if user is using TS or not
// if cml arg provided, use that; else look for the existence of ts
if (!this.options.typescript &&
this.expandFiles(path.join(this.env.options.appPath, '/scripts/**/*.ts'), {}).length > 0) {
this.options.typescript = true;
}

this.env.options.typescript = this.options.typescript;
}

this.env.options.coffee = this.options.coffee;
if (typeof this.env.options.coffee === 'undefined') {
this.option('coffee');
Expand All @@ -56,6 +70,11 @@ var Generator = module.exports = function Generator() {
this.scriptSuffix = '.coffee';
}

if (this.env.options.typescript) {
sourceRoot = '/templates/typescript';
this.scriptSuffix = '.ts';
}

this.sourceRoot(path.join(__dirname, sourceRoot));
};

Expand Down
3 changes: 2 additions & 1 deletion templates/common/app/.buildignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
*.coffee
*.coffee
*.ts
68 changes: 58 additions & 10 deletions templates/common/root/_Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ module.exports = function (grunt) {
coffeeTest: {
files: ['test/spec/{,*/}*.{coffee,litcoffee,coffee.md}'],
tasks: ['newer:coffee:test', 'karma']
},<% } else if (typescript) { %>
typescript: {
files: ['<%%= yeoman.app %>/scripts/{,*/}*.ts'],
tasks: ['typescript:base']
},
typescriptTest: {
files: ['test/spec/{,*/}*.ts'],
tasks: ['typescript:test', 'karma']
},<% } else { %>
js: {
files: ['<%%= yeoman.app %>/scripts/{,*/}*.js'],
Expand Down Expand Up @@ -73,7 +81,7 @@ module.exports = function (grunt) {
},
files: [
'<%%= yeoman.app %>/{,*/}*.html',
'.tmp/styles/{,*/}*.css',<% if (coffee) { %>
'.tmp/styles/{,*/}*.css',<% if (coffee || typescript) { %>
'.tmp/scripts/{,*/}*.js',<% } %>
'<%%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
Expand Down Expand Up @@ -139,10 +147,10 @@ module.exports = function (grunt) {
},
all: {
src: [
'Gruntfile.js'<% if (!coffee) { %>,
'Gruntfile.js'<% if (!coffee && !typescript) { %>,
'<%%= yeoman.app %>/scripts/{,*/}*.js'<% } %>
]
}<% if (!coffee) { %>,
}<% if (!coffee && !typescript) { %>,
test: {
options: {
jshintrc: 'test/.jshintrc'
Expand Down Expand Up @@ -248,7 +256,41 @@ module.exports = function (grunt) {
src: ['<%%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
ignorePath: /(\.\.\/){1,2}bower_components\//
}<% } %>
},<% if (coffee) { %>
}, <% if (typescript) { %>
// Compiles TypeScript to JavaScript
typescript: {
base: {
src: ['<%%= yeoman.app %>/scripts/{,*/}*.ts'],
dest: '.tmp/scripts',
options: {
module: 'amd', //or commonjs
target: 'es5', //or es3
'base_path': '<%%= yeoman.app %>/scripts', //quoting base_path to get around jshint warning.
sourcemap: true,
declaration: true
}
},
test: {
src: ['test/spec/{,*/}*.ts', 'test/e2e/{,*/}*.ts'],
dest: '.tmp/spec',
options: {
module: 'amd', //or commonjs
target: 'es5', //or es3
sourcemap: true,
declaration: true
}
}
},
tsd: {
refresh: {
options: {
// execute a command
command: 'reinstall',
config: 'tsd.json'
}
}
},
<% } %><% if (coffee) { %>

// Compiles CoffeeScript to JavaScript
coffee: {
Expand Down Expand Up @@ -496,17 +538,20 @@ module.exports = function (grunt) {
// Run some tasks in parallel to speed up the build process
concurrent: {
server: [<% if (coffee) { %>
'coffee:dist',<% } %><% if (compass) { %>
'coffee:dist',<% } %><% if (typescript) { %>
'typescript:base',<% } %><% if (compass) { %>
'compass:server'<% } else { %>
'copy:styles'<% } %>
],
test: [<% if (coffee) { %>
'coffee',<% } %><% if (compass) { %>
'coffee',<% } %><% if (typescript) { %>
'typescript',<% } %><% if (compass) { %>
'compass'<% } else { %>
'copy:styles'<% } %>
],
dist: [<% if (coffee) { %>
'coffee',<% } %><% if (compass) { %>
'coffee',<% } %><% if (typescript) { %>
'typescript',<% } %><% if (compass) { %>
'compass:dist',<% } else { %>
'copy:styles',<% } %>
'imagemin',
Expand Down Expand Up @@ -534,7 +579,8 @@ module.exports = function (grunt) {

grunt.task.run([
'clean:server',
'wiredep',
'wiredep',<% if (typescript) { %>
'tsd:refresh',<% } %>
'concurrent:server',
'postcss:server',
'connect:livereload',
Expand All @@ -549,7 +595,8 @@ module.exports = function (grunt) {

grunt.registerTask('test', [
'clean:server',
'wiredep',
'wiredep',<% if (typescript) { %>
'tsd:refresh',<% } %>
'concurrent:test',
'postcss',
'connect:test',
Expand All @@ -558,7 +605,8 @@ module.exports = function (grunt) {

grunt.registerTask('build', [
'clean:dist',
'wiredep',
'wiredep',<% if (typescript) { %>
'tsd:refresh',<% } %>
'useminPrepare',
'concurrent:dist',
'postcss',
Expand Down
4 changes: 3 additions & 1 deletion templates/common/root/_package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
"grunt-newer": "^1.1.0",
"grunt-ng-annotate": "^0.9.2",
"grunt-postcss": "^0.5.5",
"grunt-svgmin": "^2.0.0",
"grunt-svgmin": "^2.0.0",<% if (typescript) { %>
"grunt-tsd": "^0.1.0",
"grunt-typescript": "^0.6.2",<% } %>
"grunt-usemin": "^3.0.0",
"grunt-wiredep": "^2.0.0",
"jit-grunt": "^0.9.1",
Expand Down
33 changes: 33 additions & 0 deletions templates/common/root/_tsd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"version": "v4",
"repo": "borisyankov/DefinitelyTyped",
"ref": "master",
"path": "typings",
"bundle": "typings/tsd.d.ts",
"installed": {
"jquery/jquery.d.ts": {
"commit": "f3244190e20af6901e865f4cc58127d19216baa1"
},
"angularjs/angular.d.ts": {
"commit": "f3244190e20af6901e865f4cc58127d19216baa1"
},
"angularjs/angular-resource.d.ts": {
"commit": "aadd63ecae3feb76ea2d4be80511e266b5c2c4a7"
},
"angularjs/angular-route.d.ts": {
"commit": "f23cd55e319a0f67362ca0dbc4cf3e2ec1339f4e"
},
"angularjs/angular-mocks.d.ts": {
"commit": "f23cd55e319a0f67362ca0dbc4cf3e2ec1339f4e"
},
"angularjs/angular-cookies.d.ts": {
"commit": "f23cd55e319a0f67362ca0dbc4cf3e2ec1339f4e"
},
"angularjs/angular-sanitize.d.ts": {
"commit": "f23cd55e319a0f67362ca0dbc4cf3e2ec1339f4e"
},
"jasmine/jasmine.d.ts": {
"commit": "f23cd55e319a0f67362ca0dbc4cf3e2ec1339f4e"
}
}
}
19 changes: 19 additions & 0 deletions templates/typescript/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/// <reference path="../../typings/angularjs/angular.d.ts" /><% if (ngCookies) { %>
/// <reference path="../../typings/angularjs/angular-cookies.d.ts" /><% } %><% if (ngResource) { %>
/// <reference path="../../typings/angularjs/angular-resource.d.ts" /><% } %><% if (ngSanitize) { %>
/// <reference path="../../typings/angularjs/angular-sanitize.d.ts" /><% } %><% if (ngRoute) { %>
/// <reference path="../../typings/angularjs/angular-route.d.ts" /><% } %>

'use strict';

angular.module('<%= scriptAppName %>', [<%= angularModules %>])<% if (ngRoute) { %>
.config(($routeProvider:ng.route.IRouteProvider) => {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
})<% } %>;
23 changes: 23 additions & 0 deletions templates/typescript/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/// <reference path="../app.ts" />

'use strict';

module <%= scriptAppName %> {
export interface I<%= classedName %>Scope extends ng.IScope {
awesomeThings: any[];
}

export class <%= classedName %>Ctrl {

constructor (private $scope: I<%= classedName %>Scope) {
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
}
}
}

angular.module('<%= scriptAppName %>')
.controller('<%= classedName %>Ctrl', <%= scriptAppName %>.<%= classedName %>Ctrl);
Loading

0 comments on commit e579df9

Please sign in to comment.