Commit ddc61021 authored by Tim's avatar Tim

first commit

parents
# Example Contributing Guidelines
This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information.
* **I'm submitting a ...**
[ ] bug report
[ ] feature request
[ ] question about the decisions made in the repository
[ ] question about how to use this project
* **Summary**
* **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)
* **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...)
* **What is the current behavior?** (You can also link to an open issue here)
* **What is the new behavior (if this is a feature change)?**
* **Other information**:
node_modules
build
test
src/**.js
coverage
.nyc_output
*.log
src
config
examples
test
tsconfig.json
tslint.json
.travis.yml
.github
build/temp
build/docs
coverage
.nyc_output
*.log
sudo: false
language: node_js
node_js:
- 8
- 6
- 4
after_success:
- yarn send-coverage
# Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
<a name="1.4.1"></a>
## [1.4.1](https://github.com/bitjson/typescript-starter/compare/v1.4.0...v1.4.1) (2017-06-27)
<a name="1.4.0"></a>
# [1.4.0](https://github.com/bitjson/typescript-starter/compare/v1.3.0...v1.4.0) (2017-03-02)
### Features
* **gh-pages:** add package script for publishing docs to gh-pages ([1dfe830](https://github.com/bitjson/typescript-starter/commit/1dfe830)), closes [#14](https://github.com/bitjson/typescript-starter/issues/14)
* **publish:** add one-step publish process ([7b9b857](https://github.com/bitjson/typescript-starter/commit/7b9b857)), closes [#15](https://github.com/bitjson/typescript-starter/issues/15)
<a name="1.3.0"></a>
# [1.3.0](https://github.com/bitjson/typescript-starter/compare/v1.2.2...v1.3.0) (2017-03-01)
### Bug Fixes
* **hash.js:** correctly pre-build hash.js for the browser ([1fe0b10](https://github.com/bitjson/typescript-starter/commit/1fe0b10))
* **watch:** exclude build/**/*.spec.js from ava to avoid double execution ([e365656](https://github.com/bitjson/typescript-starter/commit/e365656))
### Features
* **browser:** add browser build, tests, and sample sha256 library method ([01f67d1](https://github.com/bitjson/typescript-starter/commit/01f67d1))
* **watch:** use concurrently for the watch task ([7fa64b8](https://github.com/bitjson/typescript-starter/commit/7fa64b8)), closes [#11](https://github.com/bitjson/typescript-starter/issues/11)
<a name="1.2.2"></a>
## [1.2.2](https://github.com/bitjson/typescript-starter/compare/v1.2.1...v1.2.2) (2017-02-17)
### Bug Fixes
* **tsconfig:** set rootDir option when outDir option is used ([3577caa](https://github.com/bitjson/typescript-starter/commit/3577caa)), closes [#9](https://github.com/bitjson/typescript-starter/issues/9)
<a name="1.2.1"></a>
## [1.2.1](https://github.com/bitjson/typescript-starter/compare/v1.2.0...v1.2.1) (2017-02-14)
<a name="1.2.0"></a>
# [1.2.0](https://github.com/bitjson/node-typescript-starter/compare/v1.1.1...v1.2.0) (2017-02-14)
### Features
* **github:** add sample GitHub issue template, PR template, and contributing guidelines ([9c95249](https://github.com/bitjson/node-typescript-starter/commit/9c95249))
* **watch:** add unified watch task with multiview ([973966e](https://github.com/bitjson/node-typescript-starter/commit/973966e))
<a name="1.1.1"></a>
## [1.1.1](https://github.com/bitjson/node-typescript-starter/compare/v1.1.0...v1.1.1) (2017-02-13)
<a name="1.1.0"></a>
# 1.1.0 (2017-02-13)
### Features
* **examples:** improve browser usage example ([c8199e7](https://github.com/bitjson/node-typescript-starter/commit/c8199e7))
* **starter:** add changelogs and examples ([5f18048](https://github.com/bitjson/node-typescript-starter/commit/5f18048))
MIT License
Copyright (c) 2017 Jason Dreyzehner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# frets-styles-generator
Genreates a typescript class from a given input css file.
Uses postcss under the hood.
Includes a watch flag.
Used in conjunction with FRETS and/or a hyperscript implementation like maquette.
// this script watches the tests exported by typescript, copies them to the test directories, and modifies the require("PKG.NAME") statements to test each build
const cpx = require("cpx");
const separator = require("path").sep;
const Transform = require("stream").Transform;
const pkg = require('../../package');
const req = (path) => 'require("' + path + '")';
const pathUp = (levels) => Array.from(Array(levels), () => '../').join('');
// replace instances of pkg.name with the proper route to the build being tested
const makeTransform = (filePath, buildPath) => {
const buildPathParts = buildPath.split(separator);
// filePath includes build/main (-2), test/BUILD is 2 deep (+2),
// remove filename (-1). Total is length - 2
const pathToRoot = pathUp(filePath.split(separator).length - 1);
const placeholder = req(pkg.name);
return new Transform({
transform(chunk, encoding, done) {
const str = chunk.toString();
const parts = str.split(placeholder)
const newPath = req(pathToRoot + buildPath)
const result = parts.join(newPath);
this.push(result);
done();
}
});
}
// copy, then watch for changes to the tests
const testsFromRoot = 'build/main/**/*.spec.js';
const watchMode = process.argv.indexOf('-w') !== -1 ? true : false;
const browserTests = process.argv.indexOf('--no-browser') !== -1 ? true : false;
const task = watchMode ? cpx.watch : cpx.copy;
task(testsFromRoot, 'test/main', {
transform: (filePath) => makeTransform(filePath, pkg.main)
});
if (!browserTests) {
task(testsFromRoot, 'test/browser', {
transform: (filePath) => makeTransform(filePath, pkg.browser.replace('.js', '.cjs.js'))
});
}
// rollup.config.js
import commonjs from 'rollup-plugin-commonjs';
import nodeResolve from 'rollup-plugin-node-resolve';
import alias from 'rollup-plugin-alias';
const substituteModulePaths = {
'crypto': 'build/module/adapters/crypto.browser.js',
'maquette': 'node_modules/maquette/dist/maquette.js',
'hash.js': 'build/temp/hash.js'
}
export default {
entry: 'build/module/index.js',
sourceMap: true,
plugins: [
alias(substituteModulePaths),
nodeResolve({
browser: true
}),
commonjs()
]
}
{
"extends": "../../tsconfig",
"compilerOptions": {
"outDir": "../../build/module",
"rootDir": "../../src",
"module": "es6",
"declaration": false
}
}
{
"compilerOptions": {
"strictNullChecks": true
}
}
{
"compilerOptions": {
"strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny" : true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true
}
}
This diff is collapsed.
{
"name": "typescript-starter-example-browser",
"version": "1.0.0",
"license": "MIT",
"scripts": {
"start": "http-server -c-1 ./build/ -o",
"build": "rollup -c && cpy src/index.html build/"
},
"devDependencies": {
"cpy-cli": "^1.0.1",
"http-server": "^0.9.0",
"rollup": "^0.41.4",
"rollup-plugin-node-resolve": "^2.0.0",
"rollup-plugin-typescript": "^0.8.1",
"typescript": "^2.2.0"
},
"dependencies": {
"typescript-starter": "^1.2.1"
},
"private": true
}
// rollup.config.js
import typescript from 'rollup-plugin-typescript';
import nodeResolve from 'rollup-plugin-node-resolve';
const pkg = require('./package');
export default {
entry: 'src/test.ts',
moduleId: pkg.name,
moduleName: 'BrowserTest',
// entry: 'dist/es/index.js',
dest: 'build/test.js',
format: 'iife',
sourceMap: true,
plugins: [
typescript({
typescript: require('typescript') // use local version
}),
nodeResolve({
module: true,
jsnext: true,
browser: true,
extensions: [ '.js', '.json' ],
preferBuiltins: false
})
]
}
<html>
<head>
<script src="test.js"></script>
</head>
<body>
</body>
</html>
// Note: we're not using the double method, so it should be excluded from the bundle
import { power, asyncABC } from 'typescript-starter'
let output = ''
function log (str: string) {
console.log(str)
output += str + '\n'
}
function logAndAlert (data: string[]) {
log('✔ asyncABC returned: ' + data)
window.alert(output)
}
log('Output:')
if (power(3,4) === 81) {
log('✔ power(3,4) === 81')
} else {
log('The "power" method seems to be broken.')
}
asyncABC().then( abc => logAndAlert(abc) )
{
"extends": "../../tsconfig",
"compilerOptions": {
"outDir": "build",
"rootDir": "src",
"module": "es6",
"declaration": false,
"removeComments": true,
"lib": [
"dom"
]
},
"include": [
"src/*.ts"
]
}
{
"name": "typescript-starter-example-node-typescript",
"version": "1.0.0",
"license": "MIT",
"scripts": {
"start": "node build/test.js",
"build": "tsc"
},
"devDependencies": {
"@types/node": "^7.0.5",
"typescript": "^2.1.6"
},
"dependencies": {
"typescript-starter": "^1.2.1"
},
"private": true
}
// Typescript should resolve this using the same algorithm as Node.js.
// See examples/node-vanilla for more info.
import { double, power, asyncABC } from 'typescript-starter'
import * as assert from 'assert'
assert(double(6) === 12)
console.log('✔ double(6) === 12')
assert(power(3,4) === 81)
console.log('✔ power(3,4) === 81')
asyncABC().then( abc => console.log('✔ asyncABC returned:', abc) )
{
"extends": "../../tsconfig",
"compilerOptions": {
"outDir": "build",
"rootDir": "src"
},
"include": [
"src/*.ts"
]
}
{
"name": "typescript-starter-example-node-vanilla",
"version": "1.0.0",
"license": "MIT",
"scripts": {
"start": "node test.js"
},
"dependencies": {
"typescript-starter": "^1.2.1"
},
"private": true
}
// Node.js should resolve this to the root of the repo. Since the path returns a
// directory, node will look for the `main` property in `package.json`, which
// should point to the `main` build.
var starter = require('typescript-starter');
// now we can use the library
var assert = require('assert');
assert(starter.double(6) === 12);
console.log("✔ starter.double(6) === 12");
assert(starter.power(3,4) === 81);
console.log("✔ starter.power(3,4) === 81");
starter.asyncABC().then( abc => console.log("✔ asyncABC returned:", abc) );
# Usage Examples
This directory (`/examples`) can be deleted when forking this project. It contains some simple examples of how forks of `typescript-starter` can be used by other projects. (Usually you'll want to provide these instructions in your root `readme.md`.)
## Node (Vanilla)
This shows the simplest use case – a quick, hacked-together Node.js project with no type safety, and no pre-processing. This is the way most of the Node.js ecosystem currently expects to import a node modules.
```bash
cd examples/node-vanilla
# install and run the example
npm install
npm run
```
## Node (Typescript)
This is for larger and more established Node.js projects which use Typescript for type safety. You'll notice that the type declarations and inline documentation from `typescript-starter` are accessible to [Typescript-compatible editors](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support) like [vscode](https://code.visualstudio.com/).
```bash
cd examples/node-typescript
# install the dependencies
npm install
# type-check and build the example
npm run build
# run the example
npm start
```
## Browser (tree-shaking with Rollup)
This project imports the `power` and `asyncABC` functions from the ES6 output of `typescript-starter`, without importing the `double` function. This allows for the `double` method to be completely excluded from output via [Rollup's tree-shaking](http://rollupjs.org/), making the final javascript bundle potentially much smaller, even before using a minifier like [Uglify](https://github.com/mishoo/UglifyJS2).
To demonstrate, this example doesn't minify or remove comments. You can see where some javascript has been excluded from the bundle.
```bash
cd examples/browser
# install the dependencies
npm install
# build the javascript bundle
npm run build
# start a server and open the test in a browser
npm start
```
This diff is collapsed.
{
"name": "frets-styles-generator",
"version": "0.1.0",
"description": "Tool that genreates a typescript class for FRETS based on a CSS file",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
"module": "build/module/index.js",
"repository": "https://gitlab.com/FRETS/frets.git",
"author": "Tim Bendt <biz@timbly.com>",
"license": "MIT",
"bin": {
"frets-styles-generator": "dist/build-style-type.js"
},
"scripts": {
"info": "npm-scripts-info",
"build": "trash build && yarn build:main",
"build:main": "tsc -p tsconfig.json",
"build:tests": "trash test && node config/exports/build-tests.js",
"lint": "tslint --project . --type-check src/**/*.ts",
"unit": "yarn build && yarn build:tests && nyc ava",
"check-coverage": "nyc check-coverage --lines 100 --functions 100 --branches 100",
"test": "yarn lint && yarn unit && yarn check-coverage",
"watch": "yarn build && yarn build:tests -- --no-browser && concurrently -r --kill-others 'npm run --silent build:main -- -w' 'npm run --silent build:tests -- -w --no-browser' 'sleepms 2000 && ava --watch'",
"cov": "yarn unit && yarn html-coverage && opn coverage/index.html",
"html-coverage": "nyc report --reporter=html",
"send-coverage": "nyc report --reporter=lcov > coverage.lcov && codecov",
"docs": "yarn docs:html && opn build/docs/index.html",
"docs:html": "typedoc src/index.ts --excludePrivate --mode file --theme minimal --out build/docs",
"docs:json": "typedoc --mode file --json build/docs/typedoc.json src/index.ts",
"docs:publish": "yarn docs:html && gh-pages -d build/docs",
"changelog": "standard-version",
"release": "yarn reset && yarn test && yarn docs:publish && yarn changelog",
"reset": "git clean -dfx && git reset --hard && yarn"
},
"scripts-info": {
"info": "Display information about the scripts",
"build": "(Trash and re)build the library",
"lint": "Lint all typescript source files",
"unit": "Build the library and run unit tests",
"test": "Lint, build, and test the library",
"watch": "Watch source files, rebuild library on changes, rerun relevant tests",
"cov": "Run tests, generate the HTML coverage report, and open it in a browser",
"docs": "Generate HTML API documentation and open it in a browser",
"docs:publish": "Generate HTML API documentation and push it to GitHub Pages",
"docs:json": "Generate API documentation in typedoc JSON format",
"changelog": "Bump package.json version, update CHANGELOG.md, tag a release",
"reset": "Delete all untracked files and reset the repo to the last commit",
"release": "Clean, build, test, publish docs, and prepare release (a one-step publish process)"
},
"engines": {
"node": ">=4.5"
},
"devDependencies": {
"@types/node": "^8.0.4",
"ava": "^0.21.0",
"codecov": "^2.2.0",
"concurrently": "^3.4.0",
"cpx": "^1.5.0",
"gh-pages": "^1.0.0",
"mkdirp": "^0.5.1",
"npm-scripts-info": "^0.3.6",
"nyc": "^11.0.3",
"opn-cli": "^3.1.0",
"sleep-ms": "^2.0.1",
"standard-version": "^4.0.0",
"trash-cli": "^1.4.0",
"tslint": "^5.4.3",
"tslint-config-standard": "^6.0.1",
"typedoc": "^0.8.0",
"typescript": "^2.4.1"
},
"keywords": [
"async",
"ava",
"await",
"boilerplate",
"conventional-changelog",
"ES6",
"ES7",
"library",
"javascript-modules",
"node",
"nyc",
"rollup",
"starter",
"template",
"tree-shaking",
"tslint",
"typedoc",
"typescript",
"typings"
],
"nyc": {
"exclude": [
"**/*.spec.js",
"build/browser/**"
]
},
"ava": {
"source": [
"test/**/*.js",
"build/**/*.js",
"!build/**/*.spec.js"
]
},
"dependencies": {
"tslib": "^1.6.0",
"commander": "^2.12.2",
"postcss-import": "^11.0.0",
"postcss": "^6.0.13",
"camel-case": "^3.0.0"
}
}
#! /usr/bin/env node
// let fs = require("fs");
// let postcssConfig = require("./postcss.config");
import * as fs from "fs";
import * as postcss from "postcss";
let importer = require("postcss-import");
let camelcase = require("camel-case");
let program = require("commander");
let isWatching = false;
let usedClasses: string[] = [];
let classProperties: string[] = [];
let protectedGetters = Object.getOwnPropertyNames(Object.getPrototypeOf(new String())).concat(["input", "button", "div", "select", "textarea", "label", "div", "$"]);
// console.log(protectedGetters.join(", "));
program
.version("0.1.2")
.usage("[options] inputFile outputFile")
.option("-w, --watch", "watch the file for changes")
// .option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
.parse(process.argv);
const inputFile = program.args[0];
const outputFile = program.args[1];
const watchMode = program.watch;
readFile(inputFile, outputFile);
function readFile(input: string, output: string) {
console.log("reading " + input);
fs.readFile(input || "./src/base.css", (err: NodeJS.ErrnoException, data: Buffer) => {
if (err) {
throw new Error("Couldn't read input file: " + input);
}
postcss([importer({root: "./src/"})]).process(data.toString())
.then((result: postcss.Result) => {
usedClasses = [];
classProperties = [];
if (result && result.root) {
result.root.walkRules((rule: postcss.Rule) => {
if (rule.selector.startsWith(".") &&
!rule.selector.includes(":")) {
const dotless = rule.selector.substr(1); // .replace("-", "_").replace("-", "_");
let classname = camelcase(dotless);
if (classname.includes(".") ||
dotless.includes(":") ||
dotless.includes(">") ||
dotless.includes("+")) {
return;
}
if ( protectedGetters.indexOf(classname) >= 0) {
classname = classname[0].toUpperCase() + classname.substr(1);
}
if (usedClasses.indexOf(classname) >= 0) {
return;
}
usedClasses.push(classname);
classProperties.push(`get ${classname}() { return this.add("${dotless}"); }`);
}
});
}
const typeScriptClass =
`
import * as Maquette from "maquette";
export class BaseStyles {
public chain: string[];
public conditions: boolean[] = [];
public classProps: any = {};
private writeConditionIndex: number = 0;
private readConditionIndex: number = 0;
private classObjectMode: boolean = false;
constructor(selector: string) {
this.chain = new Array<string>();
if (selector.length > 0) {
this.chain.push(selector);
}
return this;
}
public when = (condition: boolean): BaseStyles => {
this.classObjectMode = true;
this.conditions[this.writeConditionIndex] = condition;
return this;
}
public andWhen = (condition: boolean): BaseStyles => {
this.classObjectMode = true;
this.writeConditionIndex++;
this.readConditionIndex++;
return this.when(condition);