Skip to content
This repository has been archived by the owner on Feb 22, 2020. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
solocommand committed Nov 8, 2018
1 parent d085e5b commit 0b1c038
Show file tree
Hide file tree
Showing 17 changed files with 4,335 additions and 0 deletions.
9 changes: 9 additions & 0 deletions packages/accounts/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
extends: 'airbnb-base',
plugins: [
'import'
],
rules: {
'no-underscore-dangle': [ 'error', { allow: ['_id'] } ],
},
};
1 change: 1 addition & 0 deletions packages/accounts/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ typings/

# next.js build output
.next
.DS_Store
15 changes: 15 additions & 0 deletions packages/accounts/Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
node {
try {
stage('Checkout') {
checkout scm
}

stage('Test') {
sh 'yarn ci'
}

} catch (e) {
slackSend color: 'bad', message: "Failed testing ${env.JOB_NAME} #${env.BUILD_NUMBER} (<${env.BUILD_URL}|View>)"
throw e
}
}
24 changes: 24 additions & 0 deletions packages/accounts/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: '3.5'
networks:
nativex:
name: nativex

services:
accounts:
tty: true
image: node:10.13
entrypoint: "yarn run:dev"
working_dir: /app
volumes:
- .:/app:cached
- nm_accounts:/app/node_modules:cached
restart: on-failure
environment:
MONGOOSE_DEBUG: ${MONGOOSE_DEBUG-false}
MONGO_DSN: ${MONGO_DSN-mongodb://mongo:27017/fortnight}
NATS_DSN: ${NATS_DSN-nats://nats:4222}
NODE_ENV: development
networks: [ nativex ]

volumes:
nm_accounts: {}
43 changes: 43 additions & 0 deletions packages/accounts/gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const gulp = require('gulp');
const { spawn } = require('child_process');

const watchedPaths = [
'src/**/*.js',
];

let node;

gulp.task('serve', ['lint'], function (cb) {
if (node) node.kill();

node = spawn('node', ['src/index.js'], { stdio: 'inherit' });
node.on('close', function (code) {
if (code === 8) {
cb(code);
console.log('Error detected, waiting for changes...');
}
});
cb();
});

gulp.task('watch', function () {
gulp.watch(watchedPaths, ['serve']);
});

gulp.task('lint', function (cb) {
const lint = spawn('./node_modules/.bin/eslint', ['--cache', 'src'], { stdio: 'inherit' });
lint.on('close', function (code) {
if (code === 8) {
cb(code);
gulp.log('Error detected, waiting for changes...');
}
cb();
});
});

gulp.task('default', ['watch', 'serve']);

// clean up if an error goes unhandled.
process.on('exit', function () {
if (node) node.kill();
});
68 changes: 68 additions & 0 deletions packages/accounts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"name": "accounts",
"version": "1.0.0",
"description": "Accounts service",
"main": "src/index.js",
"author": "Josh Worden <[email protected]>",
"license": "MIT",
"devDependencies": {
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"eslint": "^5.8.0",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-plugin-import": "^2.14.0",
"gulp": "^3.9.1",
"mocha": "^5.2.0",
"mocha-junit-reporter": "^1.18.0",
"nyc": "^13.1.0",
"sinon": "^7.1.1",
"supertest": "^3.3.0"
},
"cmd": {
"gulp": "node_modules/.bin/gulp",
"lint": "node_modules/.bin/eslint src/**/*.js",
"mocha": "node_modules/.bin/mocha",
"nyc": "node_modules/.bin/nyc",
"test": {
"run": "docker-compose -p nxtestaccounts -f test/docker-compose.yml run",
"down": "docker-compose -p nxtestaccounts -f test/docker-compose.yml down"
}
},
"scripts": {
"run:ci": "yarn -s; $npm_package_cmd_nyc $npm_package_cmd_lint; $npm_package_cmd_mocha --reporter mocha-junit-reporter --reporter-options mochaFile=./coverage/test-results.xml",
"run:coverage": "yarn -s; $npm_package_cmd_nyc $npm_package_cmd_lint; $npm_package_cmd_mocha --reporter spec",
"run:dev": "yarn -s; $npm_package_cmd_gulp",
"run:test": "yarn -s; $npm_package_cmd_lint; $npm_package_cmd_mocha --reporter spec",
"start": "docker-compose -p nativex up --quiet-pull",
"stop": "docker-compose -p nativex down",
"ci": "$npm_package_cmd_test_run --entrypoint yarn accounts run:ci",
"coverage": "$npm_package_cmd_test_run --entrypoint yarn accounts run:coverage",
"test": "$npm_package_cmd_test_run accounts",
"posttest": "$npm_package_cmd_test_down",
"postci": "$npm_package_cmd_test_down",
"postcoverage": "$npm_package_cmd_test_down"
},
"dependencies": {
"envalid": "^4.1.4",
"moleculer": "^0.13.4",
"mongoose": "^5.3.10",
"nats": "^1.0.1",
"slug": "^0.9.2",
"unique-push-id": "^1.0.2",
"uuid": "^3.3.2",
"validator": "^10.8.0"
},
"nyc": {
"check-coverage": false,
"per-file": true,
"reporter": [
"text",
"cobertura"
],
"all": true,
"cache": false,
"include": [
"src/**/*.js"
]
}
}
23 changes: 23 additions & 0 deletions packages/accounts/src/account.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const Account = require('./model');

module.exports = {
list({ params = {} }) {
return Account.find(params);
},
async retrieve({ params = {} }) {
return Account.findOne(params);
},
create({ params = {} }) {
return Account.create(params);
},
async update({ params = {} }) {
const { id, payload } = params;
const account = await Account.findOne({ _id: id });
if (!account) throw new Error('Account not found!');
const { name, settings } = payload;
account.name = name;
account.set('settings.reservePct', settings.reservePct);
account.set('settings.requiredCreatives', settings.requiredCreatives);
return account.save();
},
};
32 changes: 32 additions & 0 deletions packages/accounts/src/env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const { isURL } = require('validator');

const {
cleanEnv,
makeValidator,
bool,
str,
} = require('envalid');

const mongodsn = makeValidator((v) => {
const opts = { protocols: ['mongodb'], require_tld: false, require_protocol: true };
if (isURL(v, opts)) return v;
throw new Error('Expected a Mongo DSN string with mongodb://');
});

const natsdsn = makeValidator((v) => {
const opts = { protocols: ['nats'], require_tld: false, require_protocol: true };
if (isURL(v, opts)) return v;
throw new Error('Expected a NATS DSN string with nats://');
});

module.exports = cleanEnv(process.env, {
MONGOOSE_DEBUG: bool({ desc: 'Whether to enable Mongoose debugging.', default: false }),
MONGO_DSN: mongodsn({ desc: 'The MongoDB DSN to connect to.' }),
NATS_DSN: natsdsn({ desc: 'The NATS DSN to connect to.' }),
NATS_LOGLEVEL: str({
desc: 'The log level to use for NATS messages',
choices: ['fatal', 'error', 'warn', 'info', 'debug', 'trace'],
default: 'warn',
devDefault: 'info',
}),
});
29 changes: 29 additions & 0 deletions packages/accounts/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const { ServiceBroker } = require('moleculer');
const { NATS_DSN, NATS_LOGLEVEL } = require('./env');
const { name, version } = require('../package.json');
const actions = require('./account');
const mongoose = require('./mongoose');

const broker = new ServiceBroker({
namespace: 'native-x',
transporter: NATS_DSN,
logLevel: NATS_LOGLEVEL,
logFormatter: 'simple',
});

broker.createService({
name,
version,
actions,
});

const start = async () => {
await mongoose;
await broker.start();
process.stdout.write('INFO - Account service started.\n');
};

start().catch(e => setImmediate(() => {
broker.logger.fatal(e);
throw e;
}));
4 changes: 4 additions & 0 deletions packages/accounts/src/model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const mongoose = require('./mongoose');
const schema = require('./schema');

module.exports = mongoose.model('account', schema);
15 changes: 15 additions & 0 deletions packages/accounts/src/mongoose.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const mongoose = require('mongoose');
const { MONGO_DSN, MONGOOSE_DEBUG } = require('./env');

mongoose.set('debug', Boolean(MONGOOSE_DEBUG));

const connection = mongoose.createConnection(MONGO_DSN, {
useNewUrlParser: true,
ignoreUndefined: true,
});

// eslint-disable-next-line no-console
connection.on('error', () => console.error.bind(console, '\n\nconnection error:\n'));
connection.once('open', () => process.stdout.write(`INFO - MongoDB connected to '${MONGO_DSN}'\n`));

module.exports = connection;
82 changes: 82 additions & 0 deletions packages/accounts/src/schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const { Schema } = require('mongoose');
const slug = require('slug');
const uuid = require('uuid/v4');
const pushId = require('unique-push-id');
const { isProduction } = require('./env');

const sessionSchema = new Schema({
globalSecret: {
type: String,
default() {
return `${pushId()}.${uuid()}`;
},
},
namespace: {
type: String,
default() {
return uuid();
},
},
expiration: {
type: Number,
default: 86400,
min: 10,
max: 31536000,
},
});

const schema = new Schema({
name: {
type: String,
required: true,
trim: true,
},
key: {
type: String,
maxlength: 54,
lowercase: true,
unique: true,
set(v) {
return slug(v);
},
},
settings: {
reservePct: {
type: Number,
default: 0,
min: 0,
max: 100,
},
cname: {
type: String,
default() {
return `${this.key}.stories.native-x.io`;
},
},
bcc: String,
session: {
type: sessionSchema,
default() {
return {};
},
},
},
}, { timestamps: true });

schema.virtual('uri').get(function getUri() {
if (!isProduction) {
return `https://${this.key}.native-x.io`;
}
return 'http://localhost:8100';
});

schema.virtual('storyUri').get(function getStoryUri() {
if (!isProduction) {
return `https://${this.settings.cname}`;
}
return 'http://localhost:3105';
});

schema.set('toJSON', { virtuals: true });

module.exports = schema;
6 changes: 6 additions & 0 deletions packages/accounts/test/bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
global.chai = require('chai');
global.request = require('supertest');
global.sinon = require('sinon');
global.expect = chai.expect;

chai.use(require('chai-as-promised'));
22 changes: 22 additions & 0 deletions packages/accounts/test/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: '3.5'
services:
nats:
image: nats:latest
mongo:
image: mongo:3.6
command: --quiet
accounts:
tty: true
image: node:10.13
entrypoint: "yarn run:test"
working_dir: /app
volumes:
- ../:/app:cached
- node_modules:/app/node_modules:cached
restart: "no"
environment:
MONGO_DSN: mongodb://mongo:27017/fortnight
NATS_DSN: nats://nats:4222
NODE_ENV: test
volumes:
node_modules: {}
3 changes: 3 additions & 0 deletions packages/accounts/test/mocha.opts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--recursive
--timeout 2000
--require ./test/bootstrap.js
Loading

0 comments on commit 0b1c038

Please sign in to comment.