Skip to content

Commit

Permalink
refactor: use streams for Logger
Browse files Browse the repository at this point in the history
deps: update outdated packages

fix: do not check if log file exists before boot

chore: update cli templates to reflect api changes
zacharygolba committed Jun 12, 2016
1 parent 4341f5c commit 2512e85
Showing 44 changed files with 562 additions and 351 deletions.
1 change: 1 addition & 0 deletions build/config.js
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ import { join as joinPath } from 'path';

export default {
external: readdirSync(joinPath(__dirname, '../node_modules')),
sourceMap: true,

banner:
'require(\'source-map-support\').install();\n' +
3 changes: 3 additions & 0 deletions build/config.test.js
Original file line number Diff line number Diff line change
@@ -6,6 +6,9 @@ import { readdirSync } from 'fs';
import { join as joinPath } from 'path';

export default {
banner: 'require(\'source-map-support\').install();\n',
sourceMap: true,

entry: [
joinPath(__dirname, '../test/index.js'),
joinPath(__dirname, '../test/unit/**/*.js'),
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@
"babel-plugin-transform-flow-strip-types": "6.8.0",
"babel-plugin-transform-object-rest-spread": "6.8.0",
"chai": "3.5.0",
"documentation": "4.0.0-beta4",
"documentation": "4.0.0-beta5",
"flow-bin": "0.26.0",
"isomorphic-fetch": "2.2.1",
"mocha": "2.5.3",
38 changes: 22 additions & 16 deletions src/packages/cli/commands/create.js
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ import Ora from 'ora';
import { green } from 'chalk';

import fs from '../../fs';
import template from '../../template';

import exec from '../../../utils/exec';
import driverFor from '../utils/driver-for';
@@ -19,6 +20,9 @@ import readmeTemplate from '../templates/readme';
import licenseTemplate from '../templates/license';
import gitignoreTemplate from '../templates/gitignore';

/**
* @private
*/
export default async function create(name, database) {
const driver = driverFor(database);
const project = `${process.env.PWD}/${name}`;
@@ -113,22 +117,24 @@ export default async function create(name, database) {
)
]);

console.log(`
${green('create')} app/index.js
${green('create')} app/routes.js
${green('create')} bin/app.js
${green('create')} config/environments/development.js
${green('create')} config/environments/test.js
${green('create')} config/environments/production.js
${green('create')} config/database.js
${green('create')} db/migrate
${green('create')} db/seed.js
${green('create')} README.md
${green('create')} LICENSE
${green('create')} package.json
${green('create')} .babelrc
${green('create')} .gitignore
`.substr(1).trim());
const logOutput = template`
${green('create')} app/index.js
${green('create')} app/routes.js
${green('create')} bin/app.js
${green('create')} config/environments/development.js
${green('create')} config/environments/test.js
${green('create')} config/environments/production.js
${green('create')} config/database.js
${green('create')} db/migrate
${green('create')} db/seed.js
${green('create')} README.md
${green('create')} LICENSE
${green('create')} package.json
${green('create')} .babelrc
${green('create')} .gitignore
`;

console.log(logOutput.substr(0, logOutput.length - 1));

await Promise.all([
generate('serializer', 'application', project),
3 changes: 3 additions & 0 deletions src/packages/cli/commands/db-create.js
Original file line number Diff line number Diff line change
@@ -4,6 +4,9 @@ import { connect } from '../../database';

const { env: { PWD, NODE_ENV = 'development' } } = process;

/**
* @private
*/
export default async function dbCreate() {
const {
database: {
3 changes: 3 additions & 0 deletions src/packages/cli/commands/db-drop.js
Original file line number Diff line number Diff line change
@@ -4,6 +4,9 @@ import loader from '../../loader';

const { env: { PWD, NODE_ENV = 'development' } } = process;

/**
* @private
*/
export default async function dbDrop() {
const {
database: {
3 changes: 3 additions & 0 deletions src/packages/cli/commands/db-migrate.js
Original file line number Diff line number Diff line change
@@ -4,6 +4,9 @@ import loader from '../../loader';

const { env: { PWD } } = process;

/**
* @private
*/
export default async function dbMigrate() {
const { database: config } = loader(PWD, 'config');
const migrations = loader(PWD, 'migrations');
3 changes: 3 additions & 0 deletions src/packages/cli/commands/db-rollback.js
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@ import loader from '../../loader';

const { env: { PWD } } = process;

/**
* @private
*/
export default async function dbRollback() {
const { database: config } = loader(PWD, 'config');
const migrations = loader(PWD, 'migrations');
3 changes: 3 additions & 0 deletions src/packages/cli/commands/db-seed.js
Original file line number Diff line number Diff line change
@@ -4,6 +4,9 @@ import loader from '../../loader';

const { env: { PWD } } = process;

/**
* @private
*/
export default async function dbSeed() {
const { database: config } = loader(PWD, 'config');
const seed = loader(PWD, 'seed');
6 changes: 6 additions & 0 deletions src/packages/cli/commands/destroy.js
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@ import fs, { rmrf, exists } from '../../fs';

const { env: { PWD } } = process;

/**
* @private
*/
export async function destroyType(type, name) {
let path;

@@ -35,6 +38,9 @@ export async function destroyType(type, name) {
}
}

/**
* @private
*/
export default async function destroy(type, name) {
if (type === 'resource') {
const routes = (await fs.readFileAsync(`${PWD}/app/routes.js`, 'utf8'))
20 changes: 14 additions & 6 deletions src/packages/cli/commands/generate.js
Original file line number Diff line number Diff line change
@@ -15,6 +15,9 @@ import indent from '../utils/indent';

const { env: { PWD } } = process;

/**
* @private
*/
export async function generateType(type, name, pwd, attrs = []) {
const rl = createInterface({
input: process.stdin,
@@ -101,33 +104,38 @@ export async function generateType(type, name, pwd, attrs = []) {
console.log(`${red('remove')} ${oldPath}`);
}

await fs.writeFileAsync(`${pwd}/${path}`, `${data}\n`, 'utf8');
await fs.writeFileAsync(`${pwd}/${path}`, data, 'utf8');
console.log(`${green('create')} ${path}`);
} else {
await fs.writeFileAsync(`${pwd}/${path}`, `${data}\n`, 'utf8');
await fs.writeFileAsync(`${pwd}/${path}`, data, 'utf8');
console.log(`${yellow('overwrite')} ${path}`);
}
} else {
console.log(`${yellow('skip')} ${path}`);
}
} else {
await fs.writeFileAsync(`${pwd}/${path}`, `${data}\n`, 'utf8');
await fs.writeFileAsync(`${pwd}/${path}`, data, 'utf8');
console.log(`${green('create')} ${path}`);
}

rl.close();
}

/**
* @private
*/
export default async function generate(type, name, pwd = PWD, attrs = []) {
if (type === 'resource') {
const routes = (await fs.readFileAsync(`${pwd}/app/routes.js`, 'utf8'))
.split('\n')
.reduce((str, line, index, array) => {
const closeIndex = array.lastIndexOf('};');
const closeIndex = array.lastIndexOf('}');

if (index <= closeIndex) {
if (line.length && index <= closeIndex) {
str += `${line}\n`;
} if (index + 1 === closeIndex) {
}

if (index + 1 === closeIndex) {
str += `${indent(2)}resource('${pluralize(name)}');\n`;
}

4 changes: 2 additions & 2 deletions src/packages/cli/commands/serve.js
Original file line number Diff line number Diff line change
@@ -35,9 +35,9 @@ export default async function serve(

const { maxWorkers: count } = cluster;

logger.log(`Starting Lux Server with ${cyan(`${count}`)} worker processes`);
logger.info(`Starting Lux Server with ${cyan(`${count}`)} worker processes`);

cluster.once('ready', () => {
logger.log(`Lux Server listening on port: ${cyan(`${port}`)}`);
logger.info(`Lux Server listening on port: ${cyan(`${port}`)}`);
});
}
7 changes: 6 additions & 1 deletion src/packages/cli/commands/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export default async function test() {
// @flow

/**
* @private
*/
export default async function test(): Promise<void> {
console.log('Coming Soon!');
}
3 changes: 3 additions & 0 deletions src/packages/cli/constants.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/**
* @private
*/
export const VALID_DATABASES = [
'postgres',
'sqlite',
3 changes: 3 additions & 0 deletions src/packages/cli/index.js
Original file line number Diff line number Diff line change
@@ -21,6 +21,9 @@ import {
dbRollback
} from './commands/index';

/**
* @private
*/
export default function CLI() {
const {
argv,
20 changes: 13 additions & 7 deletions src/packages/cli/templates/application.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
// @flow
import { classify } from 'inflection';

export default (name) => {
import template from '../../template';

/**
* @private
*/
export default (name: string): string => {
name = classify(name.replace('-', '_'));

return `
import Lux from 'lux-framework';
return template`
import { Application } from 'lux-framework';
class ${name} extends Lux {
class ${name} extends Application {
}
}
export default ${name};
`.substr(1).trim();
export default ${name};
`;
};
43 changes: 23 additions & 20 deletions src/packages/cli/templates/babel-rc.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
export default (name) => {
return `
{
"plugins": [
"transform-es2015-modules-commonjs",
"transform-decorators-legacy",
"transform-class-properties",
"transform-es2015-classes",
"transform-es2015-destructuring",
"transform-es2015-parameters",
"transform-es2015-spread",
"transform-decorators",
"syntax-trailing-function-commas",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-exponentiation-operator"
]
}
`.substr(1).trim();
};
// @flow
import template from '../../template';

/**
* @private
*/
export default (): string => template`
{
"plugins": [
"external-helpers-2",
"syntax-trailing-function-commas",
"transform-decorators-legacy",
"transform-class-properties",
"transform-decorators",
"transform-es2015-destructuring",
"transform-es2015-parameters",
"transform-es2015-spread",
"transform-object-rest-spread",
"transform-async-to-generator",
"transform-exponentiation-operator"
]
}
`;
20 changes: 13 additions & 7 deletions src/packages/cli/templates/config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
export default (name, env) => {
// @flow
import template from '../../template';

/**
* @private
*/
export default (name: string, env: string): string => {
const isProdENV = env === 'production';
let keyPrefix = `${name}`;

if (!isProdENV) {
keyPrefix += `::${env}`;
}

return `
export default {
log: ${!isProdENV},
domain: 'http://localhost:4000'
};
`.substr(1).trim();
return template`
export default {
log: ${!isProdENV},
domain: 'http://localhost:4000'
};
`;
};
30 changes: 20 additions & 10 deletions src/packages/cli/templates/controller.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
// @flow
import { classify, camelize, pluralize } from 'inflection';

import template from '../../template';

import indent from '../utils/indent';
import underscore from '../../../utils/underscore';

export default (name, attrs = []) => {
/**
* @private
*/
export default (name: string, attrs: Array<string>): string => {
name = classify(underscore(name));

if (!attrs) {
attrs = [];
}

if (name !== 'Application') {
name = pluralize(name);
}
@@ -19,24 +29,24 @@ export default (name, attrs = []) => {
str += (indent(2) + `params = [\n`);
}

str += (indent(4) + `'${camelize(underscore(attr), true)}'`);
str += (indent(8) + `'${camelize(underscore(attr), true)}'`);

if (index === array.length - 1) {
str += `\n${indent(2)}];`;
str += `\n${indent(6)}];`;
} else {
str += ',\n';
}

return str;
}, '');

return `
import { Controller } from 'lux-framework';
return template`
import { Controller } from 'lux-framework';
class ${name}Controller extends Controller {
${body}
}
class ${name}Controller extends Controller {
${body}
}
export default ${name}Controller;
`.substr(1).trim();
export default ${name}Controller;
`;
};
12 changes: 10 additions & 2 deletions src/packages/cli/templates/database.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
// @flow
import indent from '../utils/indent';

export default (name, driver = 'sqlite3') => {
/**
* @private
*/
export default (name: string, driver: string): string => {
let username;
let template = 'export default {\n';

name = name.replace('-', '_');

if (!driver) {
driver = 'sqlite3';
}

if (driver === 'pg') {
username = 'postgres';
} else if (driver !== 'pg' && driver !== 'sqlite3') {
@@ -46,7 +54,7 @@ export default (name, driver = 'sqlite3') => {
}
});

template += '\n};';
template += '\n};\n';

return template;
};
19 changes: 11 additions & 8 deletions src/packages/cli/templates/empty-migration.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
export default () => {
return `
export function up(schema) {
// @flow
import template from '../../template';

}
/**
* @private
*/
export default (): string => template`
export function up(schema) {
export function down(schema) {
}
}
export function down(schema) {
`.substr(1).trim();
};
}
`;
28 changes: 16 additions & 12 deletions src/packages/cli/templates/gitignore.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
export default () => {
return `
# See http://help.github.com/ignore-files/ for more about ignoring files.
// @flow
import template from '../../template';

# dependencies
/node_modules
/**
* @private
*/
export default (): string => template`
# See http://help.github.com/ignore-files/ for more about ignoring files.
# logs
/log
npm-debug.log
# dependencies
/node_modules
# misc
*.DS_Store
`.substr(1).trim();
};
# logs
/log
npm-debug.log
# misc
*.DS_Store
`;
46 changes: 25 additions & 21 deletions src/packages/cli/templates/license.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
export default () => {
return `
The MIT License (MIT)
// @flow
import template from '../../template';

Copyright (c) 2016
/**
* @private
*/
export default (): string => template`
The MIT License (MIT)
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:
Copyright (c) 2016
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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 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.
`.substr(1).trim();
};
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.
`;
11 changes: 0 additions & 11 deletions src/packages/cli/templates/migration.js

This file was deleted.

106 changes: 61 additions & 45 deletions src/packages/cli/templates/model-migration.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,68 @@
// @flow
import { pluralize } from 'inflection';

import template from '../../template';

import indent from '../utils/indent';
import underscore from '../../../utils/underscore';

export default (name, attrs = []) => {
/**
* @private
*/
export default (name: string, attrs: Array<string> | string): string => {
const table = pluralize(underscore(name));
let indices = ['id'];

attrs = attrs
.filter(attr => /^(\w|-)+:(\w|-)+$/g.test(attr))
.map(attr => attr.split(':'))
.filter(([, type]) => !/^has-(one|many)$/g.test(type))
.map(([column, type]) => {
column = underscore(column);

if (type === 'belongs-to') {
type = 'integer';
column = `${column}_id`;

indices.push(column);
}

return [column, type];
})
.map(([column, type], index) => {
return (index ? '' : '\n') + indent(4) + `table.${type}('${column}');`;
})
.join('\n');

indices.push('created_at', 'updated_at');

indices = '\n' + indices
.map(column => indent(6) + `'${column}'`)
.join(',\n') + '\n' + indent(4);

return `
export function up(schema) {
return schema.createTable('${table}', table => {
table.increments('id');${attrs}
table.timestamps();
table.index([${indices}]);
});
}
export function down(schema) {
return schema.dropTable('${table}');
}
`.substr(1).trim();
let indices: Array<string> | string = ['id'];

if (!attrs) {
attrs = [];
}

if (Array.isArray(attrs)) {
attrs = attrs
.filter(attr => /^(\w|-)+:(\w|-)+$/g.test(attr))
.map(attr => attr.split(':'))
.filter(([, type]) => !/^has-(one|many)$/g.test(type))
.map(([column, type]) => {
column = underscore(column);

if (type === 'belongs-to') {
type = 'integer';
column = `${column}_id`;

if (Array.isArray(indices)) {
indices.push(column);
}
}

return [column, type];
})
.map(([column, type], index) => {
return `${indent(index > 0 ? 8 : 0)}table.${type}('${column}');`;
})
.join('\n');
}

if (Array.isArray(indices)) {
indices.push('created_at', 'updated_at');

indices = '\n' + indices
.map(column => indent(10) + `'${column}'`)
.join(',\n') + '\n' + indent(8);
}

return template`
export function up(schema) {
return schema.createTable('${table}', table => {
table.increments('id');
${attrs}
table.timestamps();
table.index([${indices}]);
});
}
export function down(schema) {
return schema.dropTable('${table}');
}
`;
};
48 changes: 29 additions & 19 deletions src/packages/cli/templates/model.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
// @flow
import { classify, camelize } from 'inflection';

import template from '../../template';

import indent from '../utils/indent';
import entries from '../../../utils/entries';
import underscore from '../../../utils/underscore';

export default (name, attrs = []) => {
/**
* @private
*/
export default (name: string, attrs: Array<string>): string => {
name = classify(underscore(name));

if (!attrs) {
attrs = [];
}

const body = entries(
attrs
.filter(attr => /^(\w|-)+:(\w|-)+$/g.test(attr))
@@ -22,29 +32,29 @@ export default (name, attrs = []) => {
belongsTo = [
...belongsTo,

indent(4) + `${related}: {\n` +
indent(6) + `inverse: '${inverse}'\n` +
indent(4) + '}'
indent(8) + `${related}: {\n` +
indent(10) + `inverse: '${inverse}'\n` +
indent(8) + '}'
];
break;

case 'has-one':
hasOne = [
...hasOne,

indent(4) + `${related}: {\n` +
indent(6) + `inverse: '${inverse}'\n` +
indent(4) + '}'
indent(8) + `${related}: {\n` +
indent(10) + `inverse: '${inverse}'\n` +
indent(8) + '}'
];
break;

case 'has-many':
hasMany = [
...hasMany,

indent(4) + `${related}: {\n` +
indent(6) + `inverse: '${inverse}'\n` +
indent(4) + '}'
indent(8) + `${related}: {\n` +
indent(10) + `inverse: '${inverse}'\n` +
indent(8) + '}'
];
break;
}
@@ -63,20 +73,20 @@ export default (name, attrs = []) => {
str += '\n\n';
}

str += `${indent(2)}static ${key} = {\n${value}\n${indent(2)}};`;
str += `${indent(index === 0 ? 2 : 6)}static ${key} = ` +
`{\n${value}\n${indent(6)}};`;
}

return str;
}, '');

return `
import { Model } from 'lux-framework';
return template`
import { Model } from 'lux-framework';
class ${name} extends Model {
${body}
}
export default ${name};
class ${name} extends Model {
${body}
}
`.substr(1).trim();
export default ${name};
`;
};
64 changes: 37 additions & 27 deletions src/packages/cli/templates/package-json.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
import { version as VERSION } from '../../../../package.json';
// @flow
import { version } from '../../../../package.json';

export default (name) => {
return `
{
"name": "${name}",
"version": "0.0.1",
"description": "",
"main": "bin/app.js",
"scripts": {
"start": "lux serve",
"test": "lux test"
},
"author": "",
"license": "MIT",
"dependencies": {
"babel-core": "6.9.0",
"babel-eslint": "6.0.4",
"babel-plugin-transform-decorators-legacy": "1.3.4",
"babel-plugin-transform-runtime": "6.9.0",
"babel-preset-es2015": "6.9.0",
"babel-preset-stage-1": "6.5.0",
"babel-runtime": "6.9.0",
"knex": "0.11.4",
"lux-framework": "${VERSION}"
import template from '../../template';

const VERSION: string = version;

/**
* @private
*/
export default (name: string): string => template`
{
"name": "${name}",
"version": "0.0.1",
"description": "",
"scripts": {
"start": "lux serve",
"test": "lux test"
},
"author": "",
"license": "MIT",
"dependencies": {
"babel-core": "6.9.1",
"babel-plugin-external-helpers-2": "6.3.13",
"babel-plugin-syntax-trailing-function-commas": "6.8.0",
"babel-plugin-transform-async-to-generator": "6.8.0",
"babel-plugin-transform-class-properties": "6.9.1",
"babel-plugin-transform-decorators": "6.8.0",
"babel-plugin-transform-decorators-legacy": "1.3.4",
"babel-plugin-transform-es2015-destructuring": "6.9.0",
"babel-plugin-transform-es2015-parameters": "6.9.0",
"babel-plugin-transform-es2015-spread": "6.8.0",
"babel-plugin-transform-exponentiation-operator": "6.8.0",
"babel-plugin-transform-object-rest-spread": "6.8.0",
"knex": "0.11.5",
"lux-framework": "${VERSION}"
}
}
}
`.substr(1).trim();
};
`;
36 changes: 20 additions & 16 deletions src/packages/cli/templates/readme.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
export default (name) => {
return `
# ${name}
// @flow
import template from '../../template';

## Installation
/**
* @private
*/
export default (name: string): string => template`
# ${name}
* \`git clone https://github.com/<this-repository>\`
* \`cd ${name}\`
* \`npm install\`
## Installation
## Running / Development
* \`git clone https://github.com/<this-repository>\`
* \`cd ${name}\`
* \`npm install\`
* \`lux serve\`
## Running / Development
## Testing
* \`lux serve\`
* \`lux test\`
## Testing
## Further Reading / Useful Links
* [Lux](https://github.com/postlight/lux/)
* [Chai](http://chaijs.com/) / [Mocha](http://mochajs.org/)
`.substr(1).trim();
};
* \`lux test\`
## Further Reading / Useful Links
* [Lux](https://github.com/postlight/lux/)
* [Chai](http://chaijs.com/) / [Mocha](http://mochajs.org/)
`;
16 changes: 10 additions & 6 deletions src/packages/cli/templates/routes.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
export default () => {
return `
export default (route, resource) => {
// @flow
import template from '../../template';

};
`.substr(1).trim();
};
/**
* @private
*/
export default (): string => template`
export default function routes(route, resource) {
}
`;
16 changes: 10 additions & 6 deletions src/packages/cli/templates/seed.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
export default () => {
return `
export default async () => {
// @flow
import template from '../../template';

};
`.substr(1).trim();
};
/**
* @private
*/
export default (): string => template`
export default async function seed() {
}
`;
40 changes: 28 additions & 12 deletions src/packages/cli/templates/serializer.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
// @flow
import { classify, camelize, pluralize } from 'inflection';

import template from '../../template';

import indent from '../utils/indent';
import entries from '../../../utils/entries';
import underscore from '../../../utils/underscore';

export default (name, attrs = []) => {
/**
* @private
*/
export default (name: string, attrs: Array<string>): string => {
name = classify(underscore(name));

if (!attrs) {
attrs = [];
}

if (name !== 'Application') {
name = pluralize(name);
}

const body = entries(
attrs
.filter(attr => /^(\w|-)+:(\w|-)+$/g.test(attr))
.filter(attr => /^(\w|-)+:(\w|-)+$/g)
.map(attr => attr.split(':'))
.reduce(({ attributes, hasOne, hasMany }, [attr, type]) => {
attr = `${indent(4)}'${camelize(underscore(attr), true)}'`;
attr = `${indent(8)}'${camelize(underscore(attr), true)}'`;

switch (type) {
case 'belongs-to':
@@ -37,7 +47,12 @@ export default (name, attrs = []) => {
hasOne,
hasMany
};
}, { attributes: [], belongsTo: [], hasOne: [], hasMany: [] })
}, {
attributes: [],
belongsTo: [],
hasOne: [],
hasMany: []
})
).reduce((str, [key, value], index) => {
if (value.length) {
value = value.join(',\n');
@@ -46,19 +61,20 @@ export default (name, attrs = []) => {
str += '\n\n';
}

str += `${indent(2)}${key} = [\n${value}\n${indent(2)}];`;
str += `${indent(index === 0 ? 2 : 6)}${key} = ` +
`[\n${value}\n${indent(6)}];`;
}

return str;
}, '');

return `
import { Serializer } from 'lux-framework';
return template`
import { Serializer } from 'lux-framework';
class ${name}Serializer extends Serializer {
${body}
}
class ${name}Serializer extends Serializer {
${body}
}
export default ${name}Serializer;
`.substr(1).trim();
export default ${name}Serializer;
`;
};
3 changes: 2 additions & 1 deletion src/packages/cli/utils/indent.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export default function indent(amount = 1) {
// @flow
export default function indent(amount: number = 1): string {
return ' '.repeat(amount);
}
7 changes: 6 additions & 1 deletion src/packages/compiler/index.js
Original file line number Diff line number Diff line change
@@ -112,6 +112,11 @@ export async function compile(
return await bundle.write({
dest: path.join(dir, 'dist/bundle.js'),
format: 'cjs',
useStrict: false
sourceMap: true,
useStrict: false,

banner:
`require('${path.join(__dirname, '../node_modules/source-map-support')}` +
`').install();\n`
});
}
10 changes: 5 additions & 5 deletions src/packages/database/model/index.js
Original file line number Diff line number Diff line change
@@ -152,7 +152,7 @@ class Model {
const { constructor: { logger } } = this;

query.on('query', () => {
setImmediate(() => logger.log(sql`${query.toString()}`));
setImmediate(() => logger.info(sql`${query.toString()}`));
});
}

@@ -198,7 +198,7 @@ class Model {
} = this;

query.on('query', () => {
setImmediate(() => logger.log(sql`${query.toString()}`));
setImmediate(() => logger.info(sql`${query.toString()}`));
});
}

@@ -279,7 +279,7 @@ class Model {
const { logger } = this;

query.on('query', () => {
setImmediate(() => logger.log(sql`${query.toString()}`));
setImmediate(() => logger.info(sql`${query.toString()}`));
});
}

@@ -303,7 +303,7 @@ class Model {
const { logger } = this;

query.on('query', () => {
setImmediate(() => logger.log(sql`${query.toString()}`));
setImmediate(() => logger.info(sql`${query.toString()}`));
});
}

@@ -433,7 +433,7 @@ class Model {
const { logger } = this;

records.on('query', () => {
setImmediate(() => logger.log(sql`${records.toString()}`));
setImmediate(() => logger.info(sql`${records.toString()}`));
});
}

2 changes: 1 addition & 1 deletion src/packages/database/model/utils/fetch-has-many.js
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ export default async function fetchHasMany(model, related, records) {
const { logger } = model;

query.on('query', () => {
setImmediate(() => logger.log(sql`${query.toString()}`));
setImmediate(() => logger.info(sql`${query.toString()}`));
});
}

30 changes: 30 additions & 0 deletions src/packages/logger/ansi-remover/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// @flow
import ansiregex from 'ansi-regex';
import { Transform } from 'stream';

const pattern = ansiregex();

/**
* @private
*/
class AnsiRemover extends Transform {
constructor(options: {} = {}): AnsiRemover {
super(options);
return this;
}

_transform(
data: ?Buffer | ?string,
encoding: string,
done: () => void
): void {
if (data instanceof Buffer) {
data = new Buffer(data.toString().replace(pattern, ''), 'utf8');
this.push(data);
}

done(null);
}
}

export default AnsiRemover;
71 changes: 26 additions & 45 deletions src/packages/logger/index.js
Original file line number Diff line number Diff line change
@@ -3,20 +3,11 @@ import moment from 'moment';
import { dim, red, yellow } from 'chalk';
import { isMaster, isWorker } from 'cluster';

import write from './utils/write';
import initialize from './initialize';

import bound from '../../decorators/bound';
import memoize from '../../decorators/memoize';
import type { PassThrough } from 'stream';

const {
stderr,
stdout,

env: {
NODE_ENV = 'development'
}
} = process;
const { env: { NODE_ENV = 'development' } } = process;

/**
*
@@ -27,6 +18,16 @@ class Logger {
*/
path: string;

/**
*
*/
stdout: PassThrough;

/**
*
*/
stderr: PassThrough;

/**
*
*/
@@ -39,26 +40,12 @@ class Logger {
path: string,
enabled: boolean,
} = {}): Promise<Logger> {
Object.defineProperties(this, {
path: {
value: path,
writable: false,
enumerable: false,
configurable: false
},

enabled: {
value: Boolean(enabled),
writable: false,
enumerable: true,
configurable: false
}
return initialize(this, isMaster, {
path,
enabled
});

return initialize(this, isMaster);
}

@memoize
get file(): string {
return `${this.path}/log/${NODE_ENV}.log`;
}
@@ -67,25 +54,22 @@ class Logger {
return moment().format('M/D/YY h:m:ss A');
}

@bound
log(msg: string): void {
info(msg: string): void {
if (this.enabled) {
if (isWorker && typeof process.send === 'function') {
process.send({
data: msg,
type: 'info',
message: 'log'
});
} else if (isMaster) {
msg = `${dim(`[${this.timestamp}]`)} ${msg}\n\n`;
} else if (isMaster && this.stdout) {
const chunk = new Buffer(`${dim(`[${this.timestamp}]`)} ${msg}\n\n`);

stdout.write(msg);
setImmediate(write, this.file, msg);
this.stdout.push(chunk);
}
}
}

@bound
error(msg: string): void {
if (this.enabled) {
if (isWorker && typeof process.send === 'function') {
@@ -94,16 +78,14 @@ class Logger {
type: 'error',
message: 'log'
});
} else if (isMaster) {
msg = `${red(`[${this.timestamp}]`)} ${msg}\n\n`;
} else if (isMaster && this.stderr) {
const chunk = new Buffer(`${red(`[${this.timestamp}]`)} ${msg}\n\n`);

stderr.write(msg);
setImmediate(write, this.file, msg);
this.stderr.push(chunk);
}
}
}

@bound
warn(msg: string): void {
if (this.enabled) {
if (isWorker && typeof process.send === 'function') {
@@ -112,11 +94,10 @@ class Logger {
type: 'warn',
message: 'log'
});
} else if (isMaster) {
msg = `${yellow(`\n\n[${this.timestamp}] Warning:`)} ${msg}\n\n`;
} else if (isMaster && this.stderr) {
const chunk = new Buffer(`${yellow(`[${this.timestamp}]`)} ${msg}\n\n`);

stderr.write(msg);
setImmediate(write, this.file, msg);
this.stderr.push(chunk);
}
}
}
@@ -134,7 +115,7 @@ class Logger {
return this.error(data);

case 'info':
return this.log(data);
return this.info(data);

case 'warn':
return this.warn(data);
67 changes: 58 additions & 9 deletions src/packages/logger/initialize.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// @flow
import { PassThrough } from 'stream';
import { createWriteStream } from 'fs';
import { join as joinPath } from 'path';

import AnsiRemover from './ansi-remover';
import fs, { exists } from '../fs';

import type Logger from './index';
@@ -10,25 +13,71 @@ const { env: { NODE_ENV = 'development' } } = process;
/**
* @private
*/
export default async function initialize(
instance: Logger,
isMaster: boolean
): Promise<Logger> {
export default async function initialize(instance: Logger, isMaster: boolean, {
path,
enabled
}: {
path: string,
enabled: boolean
}): Promise<Logger> {
const stdout = new PassThrough();
const stderr = new PassThrough();

Object.defineProperties(instance, {
path: {
value: path,
writable: false,
enumerable: false,
configurable: false
},

stdout: {
value: stdout,
writable: false,
enumerable: false,
configurable: false
},

stderr: {
value: stderr,
writable: false,
enumerable: false,
configurable: false
},

enabled: {
value: Boolean(enabled),
writable: false,
enumerable: true,
configurable: false
}
});

if (isMaster) {
const { path } = instance;
const logsDir = joinPath(path, 'log');
const logPath = joinPath(logsDir, `${NODE_ENV}.log`);
const ansiRemover = new AnsiRemover();
let doesExist = await exists(logsDir);

if (!doesExist) {
await fs.mkdirAsync(logsDir);
}

doesExist = await exists(logPath);
const writeStream = createWriteStream(logPath);

if (!doesExist) {
await fs.writeFileAsync(logPath, '', 'utf8');
}
stdout
.pipe(process.stdout, { end: false });

stdout
.pipe(ansiRemover, { end: false })
.pipe(writeStream, { end: false });

stderr
.pipe(process.stdout, { end: false });

stderr
.pipe(ansiRemover, { end: false })
.pipe(writeStream, { end: false });
}

return instance;
18 changes: 0 additions & 18 deletions src/packages/logger/utils/write.js

This file was deleted.

6 changes: 3 additions & 3 deletions src/packages/pm/cluster/index.js
Original file line number Diff line number Diff line change
@@ -95,7 +95,7 @@ class Cluster extends EventEmitter {
const handleExit = (code: ?number) => {
worker.removeListener('message', handleMessage);

this.logger.log(
this.logger.info(
`Removing worker process: ${red(`${worker.process.pid}`)}`
);

@@ -104,7 +104,7 @@ class Cluster extends EventEmitter {
};

const handleError = () => {
this.logger.log(
this.logger.info(
`Removing worker process: ${red(`${worker.process.pid}`)}`
);

@@ -126,7 +126,7 @@ class Cluster extends EventEmitter {
break;

case 'ready':
this.logger.log(
this.logger.info(
`Adding worker process: ${green(`${worker.process.pid}`)}`
);

2 changes: 1 addition & 1 deletion src/packages/server/index.js
Original file line number Diff line number Diff line change
@@ -102,7 +102,7 @@ class Server {
statusColor = 'red';
}

this.logger.log(line`
this.logger.info(line`
${cyan(`${method}`)} ${url.pathname} -> Finished after
${new Date().getTime() - startTime.getTime()} ms with
${chalk[statusColor].call(null, `${statusCode}`)}
24 changes: 20 additions & 4 deletions src/packages/template/index.js
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
import insertValues from './utils/insert-values';

const bodyPattern = /^\n([\s\S]+)\s{2}$/gm;
const trailingWhitespace = /\s+$/;

/**
* @private
@@ -10,12 +11,27 @@ export default function template(
strings: Array<string>,
...values: Array<mixed>
): string {
const [body] = insertValues(strings, ...values).match(bodyPattern) || [];
const compiled = insertValues(strings, ...values);
let [body] = compiled.match(bodyPattern) || [];
let indentLevel = /^\s{0,4}(.+)$/g;

return body ? body.split('\n')
if (!body) {
body = compiled;
indentLevel = /^\s{0,2}(.+)$/g;
}

return body.split('\n')
.slice(1)
.map(line => line.substr(4))
.join('\n') : '';
.map(line => {
line = line.replace(indentLevel, '$1');

if (trailingWhitespace.test(line)) {
line = line.replace(trailingWhitespace, '');
}

return line;
})
.join('\n');
}

export { default as insertValues } from './utils/insert-values';
6 changes: 3 additions & 3 deletions src/packages/template/utils/insert-values.js
Original file line number Diff line number Diff line change
@@ -7,9 +7,9 @@ export default function insertValues(
strings: Array<string>,
...values: Array<mixed>
): string {
return strings.reduce((result, part, idx) => {
return values.length ? strings.reduce((result, part, idx) => {
const value = values[idx];

return result + part + (value ? value : '');
}, '');
return result + part + (typeof value !== 'undefined' ? value : '');
}, '') : strings.join('');
}
10 changes: 5 additions & 5 deletions test/test-app/package.json
Original file line number Diff line number Diff line change
@@ -10,22 +10,22 @@
"author": "",
"license": "MIT",
"dependencies": {
"babel-core": "6.9.0",
"babel-core": "6.9.1",
"babel-eslint": "6.0.4",
"babel-plugin-external-helpers-2": "6.3.13",
"babel-plugin-syntax-trailing-function-commas": "6.8.0",
"babel-plugin-transform-async-to-generator": "6.8.0",
"babel-plugin-transform-class-properties": "6.9.0",
"babel-plugin-transform-class-properties": "6.9.1",
"babel-plugin-transform-decorators": "6.8.0",
"babel-plugin-transform-decorators-legacy": "1.3.4",
"babel-plugin-transform-es2015-destructuring": "6.9.0",
"babel-plugin-transform-es2015-parameters": "6.9.0",
"babel-plugin-transform-es2015-spread": "6.8.0",
"babel-plugin-transform-exponentiation-operator": "6.8.0",
"babel-plugin-transform-object-rest-spread": "6.8.0",
"knex": "0.11.4",
"mysql2": "1.0.0-rc.1",
"pg": "4.5.5",
"knex": "0.11.5",
"mysql2": "1.0.0-rc.2",
"pg": "4.5.6",
"sqlite3": "3.1.4"
}
}

0 comments on commit 2512e85

Please sign in to comment.