Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 26 additions & 34 deletions configuration.js → classes/Configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,42 @@ const fs = require('fs-extra');
const path = require('path');
const inquirer = require('inquirer');
const Ajv = require('ajv');
const ajv = new Ajv({verbose: true, extendRefs: true});
var metaSchema = require('ajv/lib/refs/json-schema-draft-04.json');
metaSchema.$id = metaSchema.id;
delete metaSchema.id
ajv.addMetaSchema(metaSchema);
const ajv = new Ajv({verbose: true});
const yargs = require('yargs');
const axios = require('axios');

const logger = require('./logger');

function readSchema (filename) {
return fs.readJsonSync(path.join(__dirname, `../config/schema/${filename}.schema.json`));
}

class Configuration {
constructor(rootPath, argv) {

this.rootPath = rootPath;

this._validateAppStructure();

this.manifest = require(path.resolve(this.rootPath, 'manifest.json'));

// checks
this._validateAppStructure();
this._validateManifest();
this._validateCustomObjects();
this._validateScripts();

this.bbugrcPath = path.join(process.cwd(), '.bbugrc');

// login
this.host = argv.host;
this.port = argv.port;
this.email = argv.email;
this.password = argv.password;
this.host = argv.host;

// install
this.clientId = '302e48d75f4b55016aaf2c81f5ddf80f039e3f863277';
this.companyId = argv.companyId && argv.companyId.toString();
this.port = argv.port;
this.appId = this.manifest.unique_name;

// webpack
this.dev = argv.dev;
this.name = this.manifest.unique_name;
this.appId = '302e48d75f4b55016aaf2c81f5ddf80f039e3f863277';

// app config
this.bbugrcPath = path.join(process.cwd(), '.bbugrc');
this.configSchema = fs.readJsonSync(path.join(process.cwd(), 'config.json'), { throws: false });
}

Expand All @@ -48,7 +51,7 @@ class Configuration {
}

_validateManifest(){
const schema = fs.readJsonSync(path.join(__dirname, './schema/manifest.schema.json'));
const schema = readSchema('manifest');
const valid = ajv.validate(schema, this.manifest);
if (!valid) {
logger.fatal('manifest.json validation error');
Expand All @@ -58,24 +61,13 @@ class Configuration {
}

_validateCustomObjects() {
this._validate('object/manifest.schema.json', 'objects', 'manifest.json');
this._validate('object/fields.schema.json', 'objects', 'fields.json');
this._validate('object/relations.schema.json', 'objects', 'relations.json');
}

_validateScripts() {
this._validate('script/manifest.schema.json', 'script_packs', 'manifest.json');
}

_validate(schemaFile, type, file) {
const schema = fs.readJsonSync(path.join(__dirname, 'node_modules', '@bookingbug', 'app-manifest', schemaFile));
if (this.manifest[type]) {
this.manifest[type].forEach((folder) => {
const filePath = path.join(process.cwd(), folder, file);
const fields = fs.readJsonSync(filePath);
const schema = readSchema('custom-object-fields');
if (this.manifest.objects) {
this.manifest.objects.forEach((object) => {
const fields = fs.readJsonSync(path.join(process.cwd(), object, 'fields.json'));
const valid = ajv.validate(schema, fields);
if (!valid) {
logger.fatal(`${filePath} validation error`);
logger.fatal(`${object}/fields.json validation error`);
logger.fatal(ajv.errorsText());
process.exit(0);
}
Expand All @@ -84,7 +76,7 @@ class Configuration {
}

isDev(){
this.dev === true;
return this.dev === true;
}

_mapSchemaToQuestions(schema) {
Expand Down
11 changes: 11 additions & 0 deletions classes/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const chalk = require('chalk')

function indent (message) {
return message.trim().replace(/^/mg, ' ').replace(/^\s+/, '')
}

const logger = {}
logger.info = (message) => console.log(`${chalk.blue('[INFO]')} ${indent(message)}`)
logger.warn = (message) => console.warn(chalk.yellow(`[WARN] ${indent(message)}`))
logger.fatal = (message) => console.error(chalk.red(`[FATAL] ${indent(message)}`))
module.exports = logger
File renamed without changes.
4 changes: 2 additions & 2 deletions new-options.json → config/options/new-options.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": {
"describe": "Name used to identify app",
"appId": {
"describe": "Application ID (unique_name)",
"type": "string"
},
"author": {
Expand Down
49 changes: 49 additions & 0 deletions config/schema/custom-object-fields.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"allOf": [
{
"$ref": "http://json-schema.org/draft-07/schema#"
}
],
"definitions": {
"objectField": {
"type": "object",
"required": [
"key",
"type"
],
"properties": {
"key": {
"type": "string",
"description": "object field key",
"example": "myfield"
},
"type": {
"$ref": "http://json-schema.org/draft-07/schema#/definitions/simpleTypes"
},
"length": {
"type": "integer",
"description": "The max length of a string field",
"example": "30"
},
"default": {
"description": "The default value of the field",
"example": "value"
},
"required": {
"type": "boolean",
"description": "If the feild is required when being created",
"example": true
},
"drops": {
"type": "boolean",
"description": "If this field is available in liquid drops",
"example": true
}
}
}
},
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/objectField"
}
}
82 changes: 82 additions & 0 deletions config/schema/manifest.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Representation of an App manifest for BB",
"type": "object",
"required": [
"bbAppManifestVersion",
"version",
"name",
"unique_name"
],
"properties": {
"bbAppManifestVersion": {
"type": "string",
"description": "BookignBug App manifest version",
"exmaple": "1.0"
},
"name": {
"type":"string",
"description":"The name of the app",
"example":"Test App"
},
"unique_name": {
"type":"string",
"description":"The unique name of the app, this must have no spaces",
"example":"TestApp"
},
"description": {
"type":"string",
"description":"A description of your app in markdown",
"example":"My test app"
},
"version": {
"type":"string",
"description":"An app version number",
"example":"1.0"
},
"author": {
"type":"string",
"description":"The name of the author or authors",
"example":"John Doe"
},
"licence": {
"type":"string",
"description":"A Licence message",
"example":"GPLv3"
},
"tags": {
"type":"string",
"description":"A comma seperated list of tags for the app",
"example":""
},
"panels": {
"type":"array",
"uniqueItems": true,
"description":"",
"items": {
"type": "string"
}
},
"scripts": {
"type":"array",
"uniqueItems": true,
"description":"",
"items": {
"type": "string"
}
},
"objects": {
"type":"array",
"uniqueItems": true,
"description":"",
"items": {
"type": "string"
}
},
"config": {
"type":"boolean",
"description":"If there is a config block/schema for this app to be asked on install",
"example": true
}
}
}
44 changes: 0 additions & 44 deletions initialize.js

This file was deleted.

7 changes: 0 additions & 7 deletions logger.js

This file was deleted.

21 changes: 10 additions & 11 deletions index.js → main.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#!/usr/bin/env node

const install = require('./install');
const initialize = require('./initialize');
const tail = require('./tail');
const logger = require('./logger');
const uninstall = require('./uninstall');
const install = require('./services/install');
const initialize = require('./services/initialize');
const tail = require('./services/tail');
const logger = require('./classes/logger');
const uninstall = require('./services/uninstall');

const newOptions = require('./new-options.json');
const defaultOptions = require('./default-options.json');
const newOptions = require('./config/options/new-options.json');
const loginOptions = require('./config/options/login-options.json');

const yargs = require('yargs');
const fs = require('fs-extra');
Expand All @@ -28,17 +28,16 @@ const tailBuilder = (tailYargs) => {
describe: 'Name of script',
type: 'string'
})
.options(defaultOptions)
.options(loginOptions)
}

const config = fs.readJsonSync(path.join(process.cwd(), '.bbugrc'), {throws: false}) || {};

yargs
.usage('Usage: $0 <command>')
.command(['$0', 'install'], 'Package and install app', defaultOptions, install)
.command(['$0', 'install'], 'Package and install app', loginOptions, install)
.command('uninstall', 'Uninstall a app', loginOptions, uninstall)
.command('new <dir>', 'Initialize a new app', newBuilder, initialize)
.command('tail', 'Show script logs', tailBuilder, tail)
.command('uninstall', 'Uninstall a app', defaultOptions, uninstall)
.config(config)
.argv;

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"name": "@bookingbug/bbug-apps-cli",
"version": "0.0.1",
"description": "BookingBug Apps CLI",
"main": "index.js",
"bin": "./index.js",
"main": "main.js",
"bin": "./main.js",
"pkg": {
"assets": "schema/*"
"assets": "config/schema/*"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
Expand All @@ -31,6 +31,7 @@
"babel-plugin-transform-optional-catch-binding": "~7.0.0-alpha.16",
"babel-preset-env": "~1.7.0",
"chalk": "~2.4.1",
"chokidar": "^2.0.4",
"clean-webpack-plugin": "~0.1.19",
"css-loader": "~1.0.1",
"fast-sass-loader": "~1.4.6",
Expand Down
4 changes: 2 additions & 2 deletions authenticate.js → services/authenticate.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const util = require('util');
const writeFile = util.promisify(fs.writeFile);
const axios = require('axios');

const logger = require('./logger');
const logger = require('../classes/logger');

async function promptForCompany(companies, configuration, cb) {
const questions = [{
Expand Down Expand Up @@ -36,7 +36,7 @@ async function authenticate(configuration) {
baseURL: `${protocol}://${configuration.host}:${configuration.port}`,
data: data,
headers: {
'App-Id': configuration.appId,
'App-Id': configuration.clientId,
'Content-Type': 'application/json',
'Content-Length': data.length
},
Expand Down
Loading