Unverified Commit 928b1723 authored by Bradley Hilton's avatar Bradley Hilton
Browse files

Friendlier invalid json message and revamp the test server code, fixes #2

parent 0fd6b71f
......@@ -46,3 +46,7 @@ jspm_packages
## Ignore distribution folder
dist/
## dev env items
.server-dist/
.server-data/
import * as fs from 'fs';
import * as path from 'path';
import { RocketletManager } from 'temporary-rocketlets-server/manager';
import { Rocketlet } from 'temporary-rocketlets-ts-definition/Rocketlet';
import { ServerRocketletStorage } from './storage';
export class Orchestrator {
private storage: ServerRocketletStorage;
private manager: RocketletManager;
constructor() {
this.storage = new ServerRocketletStorage();
this.manager = new RocketletManager(this.storage);
}
public loadAndUpdate(): Promise<boolean> {
// throw new Error('Not implemented.');
return this.manager.load().then(() => {
return Promise.all(fs.readdirSync('dist')
.filter((file) => file.endsWith('.zip') && fs.statSync(path.join('dist', file)).isFile())
.map((file) => fs.readFileSync(path.join('dist', file), 'base64'))
.map((zip) => this.manager.add(zip).catch((err: Error) => {
if (err.message === 'Rocketlet already exists.') {
return this.manager.update(zip);
} else {
throw err;
}
})));
}).then(() => {
this.manager.get().forEach((rl) => console.log('Successfully has been loaded:', rl.getName()));
return true;
});
}
}
import { Orchestrator } from './orchestrator';
import * as bodyParser from 'body-parser';
import * as express from 'express';
const orch = new Orchestrator();
const app = express();
app.use(bodyParser.json());
app.get('/', function _indexHandler(req, res) {
res.json({ message: 'Coming soon ;)' });
});
app.post('/event', (req, res) => {
console.log(req.body, req.body.msg);
res.json({ success: true });
});
app.listen(3003, function _appListen() {
console.log('Example app listening on port 3003!');
console.log('http://localhost:3003/');
orch.loadAndUpdate().catch((err) => console.warn(err));
});
import * as Datastore from 'nedb';
import { IRocketletStorageItem, RocketletStorage } from 'temporary-rocketlets-server/storage';
export class ServerRocketletStorage extends RocketletStorage {
private db: Datastore;
constructor() {
super('nedb');
this.db = new Datastore({ filename: '.server-data/rocketlets.nedb', autoload: true });
this.db.ensureIndex({ fieldName: 'id', unique: true });
}
public create(item: IRocketletStorageItem): Promise<IRocketletStorageItem> {
return new Promise((resolve, reject) => {
item.createdAt = new Date();
item.updatedAt = new Date();
// tslint:disable-next-line
this.db.findOne({ $or: [{ id: item.id }, { 'info.nameSlug': item.info.nameSlug }] }, (err: Error, doc: IRocketletStorageItem) => {
if (err) {
reject(err);
} else if (doc) {
reject(new Error('Rocketlet already exists.'));
} else {
this.db.insert(item, (err2: Error, doc2: IRocketletStorageItem) => {
if (err2) {
reject(err2);
} else {
resolve(doc2);
}
});
}
});
});
}
public retrieveOne(id: string): Promise<IRocketletStorageItem> {
return new Promise((resolve, reject) => {
this.db.findOne({ id }, (err: Error, doc: IRocketletStorageItem) => {
if (err) {
reject(err);
} else {
resolve(doc);
}
});
});
}
public retrieveAll(): Promise<Array<IRocketletStorageItem>> {
return new Promise((resolve, reject) => {
this.db.find({}, (err: Error, docs: Array<IRocketletStorageItem>) => {
if (err) {
reject(err);
} else {
resolve(docs);
}
});
});
}
public update(item: IRocketletStorageItem): Promise<IRocketletStorageItem> {
return new Promise((resolve, reject) => {
this.db.update({ id: item.id }, { $set: item }, (err: Error) => {
if (err) {
reject(err);
} else {
console.log('Updated:', item.info.name);
return this.retrieveOne(item.id);
}
});
});
}
public remove(id: string): Promise<{ success: boolean}> {
return new Promise((resolve, reject) => {
this.db.remove({ id }, (err: Error) => {
if (err) {
reject(err);
} else {
resolve({ success: true });
}
});
});
}
}
{
"compileOnSave": false,
"compilerOptions": {
"sourceMap": true,
"target": "es5",
"module": "commonjs",
"declaration": true,
"noImplicitAny": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"lib": ["es2017"],
"outDir": "dist"
},
"atom": {
"rewriteTsconfig": false
}
}
# temporary-rocketlets-dev-environment
Development environment for getting started developing Rocketlets.
## getting started
## Getting Started
Extremely simple.
`npm start`
```
git clone git@github.com:graywolf336/temporary-rocketlets-dev-environment.git
npm install
npm start
```
This will watch the `rocketlets` directory for changes and run everything.
## Environment Layout Explained
In trying to make this a smooth development environment there were a few decisions made.
First up, unless you're extending the development environment, the only folder you should be concerned about is `rocketlets` and `dist`.
The other folders are for making the development environment a pleasure to work with (hopefully).
The `.server` directory is the "mock" server with storage, this is where the code lives which mocks up the Rocket.Chat server.
......@@ -23,7 +23,7 @@ const rocketletsPath = './rocketlets';
const tsp = tsc.createProject('tsconfig.json');
gulp.task('clean-generated', function _cleanTypescript() {
return del(['./dist/**/*.*']);
return del(['./dist/**/*', './.server-dist/**/*']);
});
gulp.task('lint-ts', function _lintTypescript() {
......@@ -41,11 +41,21 @@ gulp.task('compile-ts', ['clean-generated', 'lint-ts'], function _compileTypescr
.pipe(gulp.dest('dist'));
});
gulp.task('compile-server-ts', ['clean-generated'], function _compileServerTypescript() {
const project = tsc.createProject('.server/tsconfig.json');
return project.src()
.pipe(sourcemaps.init())
.pipe(project())
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('.server-dist'));
});
let server;
gulp.task('run-server', ['lint-no-exit-ts', 'package-for-develop'], function _runTheServer() {
gulp.task('run-server', ['lint-no-exit-ts', 'compile-server-ts', 'package-for-develop'], function _runTheServer() {
if (server) server.kill();
server = spawn('node', ['index.js'], { stdio: 'inherit' });
server = spawn('node', ['.server-dist/server.js'], { stdio: 'inherit' });
server.on('close', (code) => {
if (code === 8) {
gulp.log('Error detected, waiting for changes....');
......@@ -57,8 +67,8 @@ process.on('exit', () => {
if (server) server.kill();
});
gulp.task('default', ['clean-generated', 'lint-no-exit-ts', 'package-for-develop', 'run-server'], function _watchCodeAndRun() {
gulp.watch('rocketlets/**/*.ts', ['clean-generated', 'lint-no-exit-ts', 'package-for-develop', 'run-server']);
gulp.task('default', ['clean-generated', 'lint-no-exit-ts', 'compile-server-ts', 'package-for-develop', 'run-server'], function _watchCodeAndRun() {
gulp.watch(['rocketlets/**/*', '.server/**/*.ts'], ['clean-generated', 'lint-no-exit-ts', 'compile-server-ts', 'package-for-develop', 'run-server']);
});
//Packaging related items
......@@ -86,7 +96,7 @@ function _packageTheRocketlets(callback) {
item.valid = file.jsonSchemaResult.valid;
if (!item.valid) {
gutil.log(gutil.colors.red(figures.cross), gutil.colors.cyan(item.folder + path.sep + 'rocketlet.json'));
gutil.log(gutil.colors.red(figures.cross), gutil.colors.cyan(item.folder + path.sep + 'rocketlet.json'), 'has', gutil.colors.red('failed to validate'));
}
}
......
const rlserver = require('temporary-rocketlets-server');
const bodyParser = require('body-parser');
const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();
const manager = new rlserver.RocketletManager();
function _loadRocketlets() {
if (!fs.existsSync('dist')) {
console.warn('The "dist" folder does not exist.');
return;
}
fs.readdirSync('dist')
.filter((file) => fs.statSync(path.join('dist', file)).isFile() && file.endsWith('.zip'))
.map((zip) => fs.readFileSync(path.join('dist', zip), 'base64'))
.forEach((content) => manager.add(content));
}
app.use(bodyParser.json());
app.get('/', function (req, res) {
res.json({
'POST: /event': {
msg: 'string'
}
});
});
app.post('/event', (req, res) => {
console.log(req.body, req.body.msg);
res.json({ success: true });
});
app.listen(3003, function _appListen() {
console.log('Example app listening on port 3003!');
console.log('http://localhost:3003/');
_loadRocketlets();
});
......@@ -15,12 +15,48 @@
"integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=",
"dev": true
},
"@types/body-parser": {
"version": "1.16.4",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.16.4.tgz",
"integrity": "sha512-y8GxleWZ4ep0GG9IFMg+HpZWqLPjAjqc65cAopXPAWONWGCWGT0FCPVlXbUEBOPWpYtFrvlp2D7EJJnrqLUnEQ==",
"dev": true
},
"@types/express": {
"version": "4.0.36",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.0.36.tgz",
"integrity": "sha512-bT9q2eqH/E72AGBQKT50dh6AXzheTqigGZ1GwDiwmx7vfHff0bZOrvUWjvGpNWPNkRmX1vDF6wonG6rlpBHb1A==",
"dev": true
},
"@types/express-serve-static-core": {
"version": "4.0.48",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.0.48.tgz",
"integrity": "sha512-+W+fHO/hUI6JX36H8FlgdMHU3Dk4a/Fn08fW5qdd7MjPP/wJlzq9fkCrgaH0gES8vohVeqwefHwPa4ylVKyYIg==",
"dev": true
},
"@types/mime": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.1.tgz",
"integrity": "sha512-rek8twk9C58gHYqIrUlJsx8NQMhlxqHzln9Z9ODqiNgv3/s+ZwIrfr+djqzsnVM12xe9hL98iJ20lj2RvCBv6A==",
"dev": true
},
"@types/nedb": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/@types/nedb/-/nedb-1.8.3.tgz",
"integrity": "sha1-5vIdpJJxR0kghLu8nfu8gVMQ4Is=",
"dev": true
},
"@types/node": {
"version": "8.0.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.7.tgz",
"integrity": "sha512-fuCPLPe4yY0nv6Z1rTLFCEC452jl0k7i3gF/c8hdEKpYtEpt6Sk67hTGbxx8C0wmifFGPvKYd/O8CvS6dpgxMQ==",
"dev": true
},
"@types/serve-static": {
"version": "1.7.31",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.7.31.tgz",
"integrity": "sha1-FUVt6NmNa0z/Mb5savdJKuY/Uho=",
"dev": true
},
"accepts": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
......@@ -178,6 +214,12 @@
"integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
"dev": true
},
"ast-types": {
"version": "0.8.15",
"resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.8.15.tgz",
"integrity": "sha1-ju8IJ/BN/w7IhXupJavj/qYZTlI=",
"dev": true
},
"async": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
......@@ -226,6 +268,12 @@
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"base62": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/base62/-/base62-0.1.1.tgz",
"integrity": "sha1-e0F0wvlESXU7EcJlHAg9qEGnsIQ=",
"dev": true
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
......@@ -239,6 +287,12 @@
"integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=",
"dev": true
},
"binary-search-tree": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/binary-search-tree/-/binary-search-tree-0.2.5.tgz",
"integrity": "sha1-fbs7IQ/coIJFDa0jNMMErzm9x4Q=",
"dev": true
},
"body-parser": {
"version": "1.17.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz",
......@@ -648,6 +702,20 @@
"integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
"dev": true
},
"es3ify": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/es3ify/-/es3ify-0.1.4.tgz",
"integrity": "sha1-rZ+l3xrjTz8x4SEbWBiy1RB439E=",
"dev": true,
"dependencies": {
"esprima-fb": {
"version": "3001.1.0-dev-harmony-fb",
"resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-3001.0001.0000-dev-harmony-fb.tgz",
"integrity": "sha1-t303q8046gt3Qmu4vCkizmtCZBE=",
"dev": true
}
}
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
......@@ -680,6 +748,12 @@
"integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
"dev": true
},
"esmangle-evaluator": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/esmangle-evaluator/-/esmangle-evaluator-1.0.1.tgz",
"integrity": "sha1-Yg2GbvSGGzMR91dm1SqFcrs8YzY=",
"dev": true
},
"espree": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/espree/-/espree-3.4.3.tgz",
......@@ -784,6 +858,32 @@
"integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=",
"dev": true
},
"falafel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/falafel/-/falafel-1.2.0.tgz",
"integrity": "sha1-wY0k71CRF0pJfzGM0ksCaiXN2rQ=",
"dev": true,
"dependencies": {
"acorn": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz",
"integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=",
"dev": true
},
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
"dev": true
},
"object-keys": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
"integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
"dev": true
}
}
},
"fancy-log": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz",
......@@ -908,6 +1008,12 @@
"integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
"dev": true
},
"foreach": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
"integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
"dev": true
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
......@@ -1558,6 +1664,12 @@
"integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0=",
"dev": true
},
"immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=",
"dev": true
},
"imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
......@@ -1588,6 +1700,38 @@
"integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
"dev": true
},
"inline-process-browser": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/inline-process-browser/-/inline-process-browser-1.0.0.tgz",
"integrity": "sha1-RqYbFT3TybFiSxoAYm7bT39BTyI=",
"dev": true,
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
"dev": true
},
"readable-stream": {
"version": "1.0.34",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
"dev": true
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
"dev": true
},
"through2": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
"integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
"dev": true
}
}
},
"inquirer": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.1.1.tgz",
......@@ -1887,6 +2031,26 @@
}
}
},
"jstransform": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/jstransform/-/jstransform-3.0.0.tgz",
"integrity": "sha1-olkats7o2XvzvoMNv6IxO4fNZAs=",
"dev": true,
"dependencies": {
"esprima-fb": {
"version": "3001.1.0-dev-harmony-fb",
"resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-3001.0001.0000-dev-harmony-fb.tgz",
"integrity": "sha1-t303q8046gt3Qmu4vCkizmtCZBE=",
"dev": true
},
"source-map": {
"version": "0.1.31",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.31.tgz",
"integrity": "sha1-n3BNDWnZ4TioG63267T94z0VHGE=",
"dev": true
}
}
},
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
......@@ -1905,6 +2069,12 @@
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"dev": true
},
"lie": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.0.2.tgz",
"integrity": "sha1-/9oh17uibzd8rYZdNkmy/Izjn+o=",
"dev": true
},
"liftoff": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz",
......@@ -1931,6 +2101,12 @@
}
}
},
"localforage": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.5.0.tgz",
"integrity": "sha1-a5lOGbVmEfqF3zmS3zl6xKtm6BU=",
"dev": true
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
......@@ -2287,6 +2463,20 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
"nedb": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/nedb/-/nedb-1.8.0.tgz",
"integrity": "sha1-DjUCzYLABNU1WkPJ5VV3vXvZHYg=",
"dev": true,
"dependencies": {
"async": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
"integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
"dev": true
}
}
},
"negotiator": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
......@@ -2567,6 +2757,12 @@
"integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
"dev": true
},
"private": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz",
"integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=",
"dev": true
},
"process-nextick-args": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
......@@ -2661,6 +2857,20 @@
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
"dev": true
},
"recast": {
"version": "0.10.43",
"resolved": "https://registry.npmjs.org/recast/-/recast-0.10.43.tgz",
"integrity": "sha1-uV1Q9tYHYaX2JS4V2AZ4FoSRzn8=",
"dev": true,
"dependencies": {
"esprima-fb": {
"version": "15001.1001.0-dev-harmony-fb",
"resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz",
"integrity": "sha1-Q761fsJujPI3092LM+QlM1d/Jlk=",
"dev": true
}
}
},