Skip to content

Commit 42e2d69

Browse files
author
Marius Seritan
committed
Copied over from ember-cli-typify
1 parent 04dfe87 commit 42e2d69

22 files changed

+322
-22
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@
1515
/libpeerconnection.log
1616
npm-debug.log*
1717
testem.log
18+
yarn.lock

README.md

+20-16
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
11
# ember-cli-typescript
22

3-
This README outlines the details of collaborating on this Ember addon.
3+
Enable typescript preprocessing on Ember 2.x apps.
44

5-
## Installation
65

7-
* `git clone <repository-url>` this repository
8-
* `cd ember-cli-typescript`
9-
* `npm install`
10-
* `bower install`
6+
## One time setup
117

12-
## Running
8+
To use install dependencies
139

14-
* `ember serve`
15-
* Visit your app at [http://localhost:4200](http://localhost:4200).
10+
npm install --save-dev [email protected] # Older versions are not supported
11+
npm install --save-dev ember-cli-typescript
12+
npm install --save-dev @types/ember
1613

17-
## Running Tests
14+
Create a tsconfig.json file:
1815

19-
* `npm test` (Runs `ember try:each` to test your addon against multiple Ember versions)
20-
* `ember test`
21-
* `ember test --server`
16+
ember generate ember-cli-typescript
2217

23-
## Building
18+
## Incremental adoption
2419

25-
* `ember build`
20+
Rename the files you want to check from `.js` to `.ts`.
2621

27-
For more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/).
22+
## VSCode setup
23+
24+
Create the file `.vscode/settings.json` with the following content:
25+
26+
```json
27+
// Place your settings in this file to overwrite default and user settings.
28+
{
29+
"typescript.tsdk" : "node_modules/typescript/lib"
30+
}
31+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export default config;
2+
3+
/**
4+
* Type declarations for
5+
* import config from './config/environment'
6+
*
7+
* For now these need to be managed by the developer
8+
* since different ember addons can materialize new entries.
9+
*/
10+
declare namespace config {
11+
export var environment: any;
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES6",
4+
"allowJs": true,
5+
"moduleResolution": "node",
6+
"noEmitOnError": true,
7+
"noEmit": true,
8+
"baseUrl": ".",
9+
"paths": {
10+
"npm:*": ["local-types/*"],
11+
"*": ["local-types/*"]
12+
}
13+
},
14+
"include": [
15+
"app/**/*"
16+
]
17+
}

blueprints/ember-cli-typify/index.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
var path = require('path');
2+
3+
module.exports = {
4+
description: 'Initialize files needed for typescript compilation',
5+
6+
files: function() {
7+
return [
8+
path.join(this.path, 'files', 'tsconfig.json'),
9+
path.join(this.path, 'files', 'app', 'config', 'environment.d.ts')
10+
];
11+
},
12+
13+
mapFile: function() {
14+
var result = this._super.mapFile.apply(this, arguments);
15+
if (result.indexOf('/tsconfig.json')>-1) {
16+
return 'tsconfig.json';
17+
} else if (result.indexOf('/app/')>-1) {
18+
var pos = result.indexOf('/app/');
19+
return result.substring(pos+1);
20+
}
21+
},
22+
23+
normalizeEntityName: function() {
24+
// Entity name is optional right now, creating this hook avoids an error.
25+
}
26+
}
27+

debug.sh

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node --inspect --debug-brk node_modules/.bin/ember build

index.js

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
11
/* jshint node: true */
2+
23
'use strict';
4+
var path = require('path');
5+
var process = require('process');
6+
var TsPreprocessor = require('./lib/typescript-preprocessor');
37

48
module.exports = {
5-
name: 'ember-cli-typescript'
9+
name: 'ember-cli-typescript',
10+
11+
12+
included: function(app) {
13+
this._super.included.apply(this, arguments);
14+
this.app = app;
15+
16+
},
17+
18+
blueprintsPath: function() {
19+
return path.join(__dirname, 'blueprints');
20+
},
21+
22+
setupPreprocessorRegistry: function(type, registry) {
23+
try {
24+
var plugin = new TsPreprocessor({includeExtensions: ['.ts','.js']});
25+
registry.add('js', plugin);
26+
} catch ( ex ) {
27+
console.log( "Missing or invalid tsconfig.json, please fix or run `ember generate ember-cli-typescript`." );
28+
console.log( ' ' + ex.toString());
29+
}
30+
}
31+
632
};

lib/typescript-preprocessor.js

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
var tsc = require('broccoli-typescript-compiler').typescript;
2+
var fs = require('fs');
3+
var debug = require('debug')('ember-cli-typescript');
4+
var ts = require('typescript');
5+
var stew = require('broccoli-stew');
6+
var find = stew.find;
7+
var MergeTrees = require("broccoli-merge-trees");
8+
var Funnel = require("broccoli-funnel");
9+
10+
function TypeScriptPreprocessor(options) {
11+
debug('creating new instance with options ', options);
12+
this.name = 'ember-cli-typescript';
13+
this.ext = 'ts';
14+
this.options = JSON.parse(JSON.stringify(options));
15+
}
16+
17+
function readConfig(configFile) {
18+
var result = ts.readConfigFile(configFile, ts.sys.readFile);
19+
if (result.error) {
20+
var message = ts.flattenDiagnosticMessageText(result.error.messageText, "\n");
21+
throw new Error(message);
22+
}
23+
return result.config;
24+
}
25+
26+
/**
27+
* Return the paths which contain type information.
28+
*/
29+
function typePaths(config) {
30+
var out = [
31+
"node_modules/@types",
32+
];
33+
var paths = (config.compilerOptions && config.compilerOptions.paths) || {};
34+
Object.keys(paths).forEach( function eachEntry(k) {
35+
// paths may contain a /*, eliminate it
36+
paths[k].forEach(function eachPath(a) {
37+
var p = a.split("/\*")[0];
38+
if (out.indexOf(p) < 0) {
39+
out.push(p);
40+
}
41+
});
42+
});
43+
debug("type paths", out);
44+
return out;
45+
}
46+
47+
TypeScriptPreprocessor.prototype.toTree = function(inputNode, inputPath, outputPath) {
48+
var config = readConfig("./tsconfig.json");
49+
// "include" setting is meant for the IDE integration,
50+
// broccoli manages its own input files.
51+
if (config.include) {
52+
delete config.include;
53+
}
54+
config.include = ["**/*"];
55+
56+
/*
57+
* Create a funnel with the type files used by the typescript compiler.
58+
*
59+
*/
60+
var types = find(process.cwd(), {
61+
include: typePaths(config).map(function(a) { return a + '/**/*'})
62+
});
63+
64+
/*
65+
* Passthrough all the javascript files existing
66+
* in the source/test folders.
67+
*/
68+
var passthrough = new Funnel(inputNode, {
69+
exclude: ["**/*.ts"],
70+
annotation: "TypeScript passthrough"
71+
});
72+
73+
/*
74+
* Files to run through the typescript compiler.
75+
*/
76+
var filter = new MergeTrees( [types, new Funnel(inputNode, {
77+
include: ["**/*.ts"],
78+
annotation: "TypeScript input"
79+
})]);
80+
81+
/*
82+
* Put everything together.
83+
*/
84+
return new MergeTrees([
85+
passthrough,
86+
tsc(filter, {tsconfig: config})
87+
], {
88+
overwrite: true,
89+
annotation: "TypeScript passthrough + ouput"
90+
});
91+
92+
};
93+
94+
95+
module.exports = TypeScriptPreprocessor;

package.json

+16-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ember-cli-typescript",
33
"version": "0.0.0",
4-
"description": "The default blueprint for ember-cli addons.",
4+
"description": "Allow ember apps to use typescript files.",
55
"keywords": [
66
"ember-addon"
77
],
@@ -11,7 +11,7 @@
1111
"doc": "doc",
1212
"test": "tests"
1313
},
14-
"repository": "",
14+
"repository": "https://github.com/emberwatch/ember-cli-typescript.git",
1515
"scripts": {
1616
"build": "ember build",
1717
"start": "ember server",
@@ -35,18 +35,29 @@
3535
"ember-cli-sri": "^2.1.0",
3636
"ember-cli-test-loader": "^1.1.0",
3737
"ember-cli-uglify": "^1.2.0",
38-
"ember-data": "^2.10.0",
3938
"ember-disable-prototype-extensions": "^1.1.0",
4039
"ember-export-application-global": "^1.0.5",
4140
"ember-load-initializers": "^0.5.1",
4241
"ember-resolver": "^2.0.3",
43-
"ember-welcome-page": "^1.0.3",
4442
"loader.js": "^4.0.10"
4543
},
4644
"engines": {
4745
"node": ">= 0.12.0"
4846
},
47+
"dependencies": {
48+
"@types/ember": "^2.7.34",
49+
"broccoli-typescript-compiler": "^1.0.1",
50+
"typescript": "^2.1.0",
51+
"broccoli-funnel": "^1.0.6",
52+
"broccoli-merge-trees": "^1.1.4",
53+
"broccoli-plugin": "^1.2.1",
54+
"debug": "^2.2.0",
55+
"ember-cli-babel": "^5.1.7"
56+
},
4957
"ember-addon": {
50-
"configPath": "tests/dummy/config"
58+
"configPath": "tests/dummy/config",
59+
"before": [
60+
"ember-cli-babel"
61+
]
5162
}
5263
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Ember from 'ember';
2+
3+
import * as constants from '../lib/some-const';
4+
5+
export default Ember.Component.extend({
6+
poke: Ember.computed.equal('ha', constants.CHANGE)
7+
});
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
import Ember from 'ember';
3+
4+
export default Ember.Component.extend({
5+
someValue: 'from component'
6+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import Ember from 'ember';
2+
3+
function compute() : {value:string} {
4+
return {value: 'from component'};
5+
}
6+
7+
export default Ember.Component.extend({
8+
someValue: compute().value
9+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import Ember from 'ember';
2+
3+
export default Ember.Controller.extend({
4+
// Just a very roundabout way of using some ES6 features
5+
value: ((test = 'Test') => `${test} ${'Value'}`)()
6+
});

tests/dummy/app/lib/some-const.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const SPEED_OF_LIGHT=299792458;
2+
export const CHANGE=true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<h1>Hello</h1>
2+
3+
This is code from ember-cli-typescript's test application.
4+
5+
{{ts-component}}
6+
7+
{{js-importing-ts}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<div style="border: 2px solid black;width: 100%; background-color: azure; margin-top: 20px; padding: 0 0 20px 20px">
2+
<p style="margin-top: 0px; border-bottom: chocolate 1px solid">js-importing-ts.hbs</p>
3+
{{poke}}
4+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div style="border: 2px solid black;width: 100%; background-color: azure; margin-top: 20px; padding: 0 0 20px 20px">
2+
<p style="margin-top: 0px; border-bottom: chocolate 1px solid">ts-component.hbs</p>
3+
{{#if someValue}}
4+
Component defines <b>someValue</b> property as: {{someValue}}
5+
{{else}}
6+
<span style="color:red">Missing <b>someValue</b> property, expected to be defined by the component.</span>
7+
{{/if}}
8+
</div>

tests/integration/components/dummy.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/*
2+
Need at least one ts file to avoid error
3+
"No inputs were found in config file 'tsconfig.json'."
4+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { moduleForComponent, test } from 'ember-qunit';
2+
import hbs from 'htmlbars-inline-precompile';
3+
4+
moduleForComponent('js-importing-ts', 'Integration | Component | js importing ts', {
5+
integration: true
6+
});
7+
8+
test('it renders', function(assert) {
9+
// Set any properties with this.set('myProperty', 'value');
10+
// Handle any actions with this.on('myAction', function(val) { ... });
11+
12+
this.render(hbs`{{js-importing-ts}}`);
13+
14+
assert.equal(this.$().text().trim(), 'js-importing-ts.hbs\nfalse');
15+
16+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { moduleForComponent, test } from 'ember-qunit';
2+
import hbs from 'htmlbars-inline-precompile';
3+
4+
moduleForComponent('ts-component', 'Integration | Component | ts component', {
5+
integration: true
6+
});
7+
8+
test('it renders', function(assert) {
9+
// Set any properties with this.set('myProperty', 'value');
10+
// Handle any actions with this.on('myAction', function(val) { ... });
11+
12+
this.render(hbs`{{ts-component}}`);
13+
14+
assert.equal(this.$().text().replace(/\s+/g,' ').trim(), 'ts-component.hbs Component defines someValue property as: from component');
15+
16+
});

tests/unit/dummy.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/*
2+
Need at least one ts file to avoid error
3+
"No inputs were found in config file 'tsconfig.json'."
4+
*/

0 commit comments

Comments
 (0)