<commit_before>import FormattedValueRaw from '!raw-loader!../../tocco-ui/src/FormattedValue/FormattedValue'
import FormattedValueExample from '../../tocco-ui/src/FormattedValue/example'
import FormattedValueExampleRaw from '!raw-loader!../../tocco-ui/src/FormattedValue/example'

import EditableValueRaw from '!raw-loader!../../tocco-ui/src/EditableValue/EditableValue'
import EditableValueExample from '../../tocco-ui/src/EditableValue/example'
import EditableValueExampleRaw from '!raw-loader!../../tocco-ui/src/EditableValue/example'

import TableRaw from '!raw-loader!../../tocco-ui/src/Table/Table'
import TableExample from '../../tocco-ui/src/Table/example'
import TableExampleRaw from '!raw-loader!../../tocco-ui/src/Table/example'

import LoadMaskRaw from '!raw-loader!../../tocco-ui/src/LoadMask/LoadMask'
import LoadMaskExample from '../../tocco-ui/src/LoadMask/example'
import LoadMaskExampleRaw from '!raw-loader!../../tocco-ui/src/LoadMask/example'

import ButtonRaw from '!raw-loader!../../tocco-ui/src/Button/Button'
import ButtonExample from '../../tocco-ui/src/Button/example'
import ButtonExampleRaw from '!raw-loader!../../tocco-ui/src/Button/example'

import ButtonGroupRaw from '!raw-loader!../../tocco-ui/src/ButtonGroup/ButtonGroup'
import ButtonGroupExample from '../../tocco-ui/src/ButtonGroup/example'
import ButtonGroupExampleRaw from '!raw-loader!../../tocco-ui/src/ButtonGroup/example'

import MenuRaw from '!raw-loader!../../tocco-ui/src/Menu/Menu'
import MenuExample from '../../tocco-ui/src/Menu/example'
import MenuExampleRaw from '!raw-loader!../../tocco-ui/src/Menu/example'

import IconRaw from '!raw-loader!../../tocco-ui/src/Icon/Icon'
import IconExample from '../../tocco-ui/src/Icon/example'
import IconExampleRaw from '!raw-loader!../../tocco-ui/src/Icon/example'

import TypographyRaw from '!raw-loader!../../tocco-ui/src/Typography/Typography'
import TypographyExample from '../../tocco-ui/src/Typography/example'
import TypographyExampleRaw from '!raw-loader!../../tocco-ui/src/Typography/example'

import LinkRaw from '!raw-loader!../../tocco-ui/src/Link/Link'
import LinkExample from '../../tocco-ui/src/Link/example'
import LinkExampleRaw from '!raw-loader!../../tocco-ui/src/Link/example'

import ButtonLinkRaw from '!raw-loader!../../tocco-ui/src/ButtonLink/ButtonLink'
import ButtonLinkExample from '../../tocco-ui/src/ButtonLink/example'
import ButtonLinkExampleRaw from '!raw-loader!../../tocco-ui/src/ButtonLink/example'

import PanelRaw from '!raw-loader!../../tocco-ui/src/Panel/Panel'
import PanelExample from '../../tocco-ui/src/Panel/example'
import PanelExampleRaw from '!raw-loader!../../tocco-ui/src/Panel/example'

import SignalBoxRaw from '!raw-loader!../../tocco-ui/src/SignalBox/SignalBox'
import SignalBoxExample from '../../tocco-ui/src/SignalBox/example'
import SignalBoxExampleRaw from '!raw-loader!../../tocco-ui/src/SignalBox/example'

import SignalListRaw from '!raw-loader!../../tocco-ui/src/SignalList/SignalList'
import SignalListExample from '../../tocco-ui/src/SignalList/example'
import SignalListExampleRaw from '!raw-loader!../../tocco-ui/src/SignalList/example'

import PreviewRaw from '!raw-loader!../../tocco-ui/src/Preview/Preview'
import PreviewExample from '../../tocco-ui/src/Preview/example'
import PreviewExampleRaw from '!raw-loader!../../tocco-ui/src/Preview/example'

import UploadRaw from '!raw-loader!../../tocco-ui/src/Upload/Upload'
import UploadExample from '../../tocco-ui/src/Upload/example'
import UploadExampleRaw from '!raw-loader!../../tocco-ui/src/Upload/example'

import SearchBoxRaw from '!raw-loader!../../tocco-ui/src/SearchBox/SearchBox'
import SearchBoxExample from '../../tocco-ui/src/SearchBox/example'
import SearchBoxExampleRaw from '!raw-loader!../../tocco-ui/src/SearchBox/example'

import FormFieldRaw from '!raw-loader!../../tocco-ui/src/FormField/FormField'
import FormFieldExample from '../../tocco-ui/src/FormField/example'
import FormFieldExampleRaw from '!raw-loader!../../tocco-ui/src/FormField/example'

import PaginationRaw from '!raw-loader!../../tocco-ui/src/Pagination/Pagination'
import PaginationExample from '../../tocco-ui/src/Pagination/example'
import PaginationExampleRaw from '!raw-loader!../../tocco-ui/src/Pagination/example'

import LayoutBoxRaw from '!raw-loader!../../tocco-ui/src/LayoutBox/LayoutBox'
import LayoutBoxExample from '../../tocco-ui/src/LayoutBox/example'
import LayoutBoxExampleRaw from '!raw-loader!../../tocco-ui/src/LayoutBox/example'

import ErrorLoggingExample from './toccoUtilExamples/errorLogging/example'
import ErrorLoggingExampleRaw from '!raw-loader!./toccoUtilExamples/errorLogging/example'

import NotifierExample from './toccoUtilExamples/notifier/example'
import NotifierExampleRaw from '!raw-loader!./toccoUtilExamples/notifier/example'

const categories = {
  CONTENT: 'Content',
  FORMS: 'Form Controls',
  LAYOUT: 'Layout',
  UTIL: 'Tocco-Util'
}

export default [
  {
    category: categories.CONTENT,
    components: [
      {
        name: 'FormattedValue',
        raw: FormattedValueRaw,
        example: {
          component: FormattedValueExample,
          raw: FormattedValueExampleRaw
        }
      },
      {
        name: 'EditableValue',
        raw: EditableValueRaw,
        example: {
          component: EditableValueExample,
          raw: EditableValueExampleRaw
        }
      },
      {
        name: 'Table',
        raw: TableRaw,
        example: {
          component: TableExample,
          raw: TableExampleRaw
        }
      },
      {
        name: 'Pagination',
        raw: PaginationRaw,
        example: {
          component: PaginationExample,
          raw: PaginationExampleRaw
        }
      },
      {
        name: 'LoadMask',
        raw: LoadMaskRaw,
        example: {
          component: LoadMaskExample,
          raw: LoadMaskExampleRaw
        }
      },
      {
        name: 'Preview',
        raw: PreviewRaw,
        example: {
          component: PreviewExample,
          raw: PreviewExampleRaw
        }
      },
      {
        name: 'Upload',
        raw: UploadRaw,
        example: {
          component: UploadExample,
          raw: UploadExampleRaw
        }
      },
      {
        name: 'Icon',
        raw: IconRaw,
        example: {
          component: IconExample,
          raw: IconExampleRaw
        }
      },
      {
        name: 'Typography',
        raw: TypographyRaw,
        example: {
          component: TypographyExample,
          raw: TypographyExampleRaw
        }
      },
      {
        name: 'SignalList',
        raw: SignalListRaw,
        example: {
          component: SignalListExample,
          raw: SignalListExampleRaw
        }
      },
      {
        name: 'SignalBox',
        raw: SignalBoxRaw,
        example: {
          component: SignalBoxExample,
          raw: SignalBoxExampleRaw
        }
      },
      {
        name: 'Link',
        raw: LinkRaw,
        example: {
          component: LinkExample,
          raw: LinkExampleRaw
        }
      },
      {
        name: 'ButtonLink',
        raw: ButtonLinkRaw,
        example: {
          component: ButtonLinkExample,
          raw: ButtonLinkExampleRaw
        }
      },
      {
        name: 'Menu',
        raw: MenuRaw,
        example: {
          component: MenuExample,
          raw: MenuExampleRaw
        }
      },
      {
        name: 'Panel',
        raw: PanelRaw,
        example: {
          component: PanelExample,
          raw: PanelExampleRaw
        }
      }]
  },
  {
    category: categories.FORMS,
    components: [
      {
        name: 'Button',
        raw: ButtonRaw,
        example: {
          component: ButtonExample,
          raw: ButtonExampleRaw
        }
      },
      {
        name: 'ButtonGroup',
        raw: ButtonGroupRaw,
        example: {
          component: ButtonGroupExample,
          raw: ButtonGroupExampleRaw
        }
      },
      {
        name: 'SearchBox',
        raw: SearchBoxRaw,
        example: {
          component: SearchBoxExample,
          raw: SearchBoxExampleRaw
        }
      },
      {
        name: 'FormField',
        raw: FormFieldRaw,
        example: {
          component: FormFieldExample,
          raw: FormFieldExampleRaw
        }
      }]
  },
  {
    category: categories.LAYOUT,
    components: [
      {
        name: 'Box Layouts',
        raw: LayoutBoxRaw,
        example: {
          component: LayoutBoxExample,
          raw: LayoutBoxExampleRaw
        }
      }
    ]
  },
  {
    category: categories.UTIL,
    components: [
      {
        name: 'Error Logging',
        description: 'Example to log Errors in an application',
        example: {
          component: ErrorLoggingExample,
          raw: ErrorLoggingExampleRaw
        }
      },
      {
        name: 'Notifications',
        description: 'To show various notifications to the user',
        example: {
          component: NotifierExample,
          raw: NotifierExampleRaw
        }
      }
    ]
  }
]
<commit_msg>refactor(tocco-ui-showcase): group and sort examples<commit_after>import ButtonRaw from '!raw-loader!../../tocco-ui/src/Button/Button'
import ButtonExample from '../../tocco-ui/src/Button/example'
import ButtonExampleRaw from '!raw-loader!../../tocco-ui/src/Button/example'

import ButtonGroupRaw from '!raw-loader!../../tocco-ui/src/ButtonGroup/ButtonGroup'
import ButtonGroupExample from '../../tocco-ui/src/ButtonGroup/example'
import ButtonGroupExampleRaw from '!raw-loader!../../tocco-ui/src/ButtonGroup/example'

import ButtonLinkRaw from '!raw-loader!../../tocco-ui/src/ButtonLink/ButtonLink'
import ButtonLinkExample from '../../tocco-ui/src/ButtonLink/example'
import ButtonLinkExampleRaw from '!raw-loader!../../tocco-ui/src/ButtonLink/example'

import EditableValueRaw from '!raw-loader!../../tocco-ui/src/EditableValue/EditableValue'
import EditableValueExample from '../../tocco-ui/src/EditableValue/example'
import EditableValueExampleRaw from '!raw-loader!../../tocco-ui/src/EditableValue/example'

import ErrorLoggingExample from './toccoUtilExamples/errorLogging/example'
import ErrorLoggingExampleRaw from '!raw-loader!./toccoUtilExamples/errorLogging/example'

import FormattedValueRaw from '!raw-loader!../../tocco-ui/src/FormattedValue/FormattedValue'
import FormattedValueExample from '../../tocco-ui/src/FormattedValue/example'
import FormattedValueExampleRaw from '!raw-loader!../../tocco-ui/src/FormattedValue/example'

import FormFieldRaw from '!raw-loader!../../tocco-ui/src/FormField/FormField'
import FormFieldExample from '../../tocco-ui/src/FormField/example'
import FormFieldExampleRaw from '!raw-loader!../../tocco-ui/src/FormField/example'

import IconRaw from '!raw-loader!../../tocco-ui/src/Icon/Icon'
import IconExample from '../../tocco-ui/src/Icon/example'
import IconExampleRaw from '!raw-loader!../../tocco-ui/src/Icon/example'

import LayoutBoxRaw from '!raw-loader!../../tocco-ui/src/LayoutBox/LayoutBox'
import LayoutBoxExample from '../../tocco-ui/src/LayoutBox/example'
import LayoutBoxExampleRaw from '!raw-loader!../../tocco-ui/src/LayoutBox/example'

import LinkRaw from '!raw-loader!../../tocco-ui/src/Link/Link'
import LinkExample from '../../tocco-ui/src/Link/example'
import LinkExampleRaw from '!raw-loader!../../tocco-ui/src/Link/example'

import LoadMaskRaw from '!raw-loader!../../tocco-ui/src/LoadMask/LoadMask'
import LoadMaskExample from '../../tocco-ui/src/LoadMask/example'
import LoadMaskExampleRaw from '!raw-loader!../../tocco-ui/src/LoadMask/example'

import MenuRaw from '!raw-loader!../../tocco-ui/src/Menu/Menu'
import MenuExample from '../../tocco-ui/src/Menu/example'
import MenuExampleRaw from '!raw-loader!../../tocco-ui/src/Menu/example'

import NotifierExample from './toccoUtilExamples/notifier/example'
import NotifierExampleRaw from '!raw-loader!./toccoUtilExamples/notifier/example'

import PaginationRaw from '!raw-loader!../../tocco-ui/src/Pagination/Pagination'
import PaginationExample from '../../tocco-ui/src/Pagination/example'
import PaginationExampleRaw from '!raw-loader!../../tocco-ui/src/Pagination/example'

import PanelRaw from '!raw-loader!../../tocco-ui/src/Panel/Panel'
import PanelExample from '../../tocco-ui/src/Panel/example'
import PanelExampleRaw from '!raw-loader!../../tocco-ui/src/Panel/example'

import PreviewRaw from '!raw-loader!../../tocco-ui/src/Preview/Preview'
import PreviewExample from '../../tocco-ui/src/Preview/example'
import PreviewExampleRaw from '!raw-loader!../../tocco-ui/src/Preview/example'

import SearchBoxRaw from '!raw-loader!../../tocco-ui/src/SearchBox/SearchBox'
import SearchBoxExample from '../../tocco-ui/src/SearchBox/example'
import SearchBoxExampleRaw from '!raw-loader!../../tocco-ui/src/SearchBox/example'

import SignalBoxRaw from '!raw-loader!../../tocco-ui/src/SignalBox/SignalBox'
import SignalBoxExample from '../../tocco-ui/src/SignalBox/example'
import SignalBoxExampleRaw from '!raw-loader!../../tocco-ui/src/SignalBox/example'

import SignalListRaw from '!raw-loader!../../tocco-ui/src/SignalList/SignalList'
import SignalListExample from '../../tocco-ui/src/SignalList/example'
import SignalListExampleRaw from '!raw-loader!../../tocco-ui/src/SignalList/example'

import TableRaw from '!raw-loader!../../tocco-ui/src/Table/Table'
import TableExample from '../../tocco-ui/src/Table/example'
import TableExampleRaw from '!raw-loader!../../tocco-ui/src/Table/example'

import TypographyRaw from '!raw-loader!../../tocco-ui/src/Typography/Typography'
import TypographyExample from '../../tocco-ui/src/Typography/example'
import TypographyExampleRaw from '!raw-loader!../../tocco-ui/src/Typography/example'

import UploadRaw from '!raw-loader!../../tocco-ui/src/Upload/Upload'
import UploadExample from '../../tocco-ui/src/Upload/example'
import UploadExampleRaw from '!raw-loader!../../tocco-ui/src/Upload/example'

const categories = {
  DISPLAY_DATA: 'Display Data',
  EDIT_DATA: 'Edit Data',
  LAYOUT: 'Layout',
  MESSAGE: 'Message',
  NAVIGATION: 'Navigation'
}

export default [{
  category: categories.DISPLAY_DATA,
  components: [{
    name: 'FormattedValue',
    raw: FormattedValueRaw,
    example: {
      component: FormattedValueExample,
      raw: FormattedValueExampleRaw
    }
  }, {
    name: 'Preview',
    raw: PreviewRaw,
    example: {
      component: PreviewExample,
      raw: PreviewExampleRaw
    }
  }, {
    name: 'Typography',
    raw: TypographyRaw,
    example: {
      component: TypographyExample,
      raw: TypographyExampleRaw
    }
  }, {
    name: 'Icon',
    raw: IconRaw,
    example: {
      component: IconExample,
      raw: IconExampleRaw
    }
  }, {
    name: 'Table',
    raw: TableRaw,
    example: {
      component: TableExample,
      raw: TableExampleRaw
    }
  }]
}, {
  category: categories.EDIT_DATA,
  components: [{
    name: 'EditableValue',
    raw: EditableValueRaw,
    example: {
      component: EditableValueExample,
      raw: EditableValueExampleRaw
    }
  }, {
    name: 'FormField',
    raw: FormFieldRaw,
    example: {
      component: FormFieldExample,
      raw: FormFieldExampleRaw
    }
  }, {
    name: 'Upload',
    raw: UploadRaw,
    example: {
      component: UploadExample,
      raw: UploadExampleRaw
    }
  }]
}, {
  category: categories.NAVIGATION,
  components: [{
    name: 'Link',
    raw: LinkRaw,
    example: {
      component: LinkExample,
      raw: LinkExampleRaw
    }
  }, {
    name: 'Button',
    raw: ButtonRaw,
    example: {
      component: ButtonExample,
      raw: ButtonExampleRaw
    }
  }, {
    name: 'ButtonLink',
    raw: ButtonLinkRaw,
    example: {
      component: ButtonLinkExample,
      raw: ButtonLinkExampleRaw
    }
  }, {
    name: 'ButtonGroup',
    raw: ButtonGroupRaw,
    example: {
      component: ButtonGroupExample,
      raw: ButtonGroupExampleRaw
    }
  }, {
    name: 'Menu',
    raw: MenuRaw,
    example: {
      component: MenuExample,
      raw: MenuExampleRaw
    }
  }, {
    name: 'SearchBox',
    raw: SearchBoxRaw,
    example: {
      component: SearchBoxExample,
      raw: SearchBoxExampleRaw
    }
  }, {
    name: 'Pagination',
    raw: PaginationRaw,
    example: {
      component: PaginationExample,
      raw: PaginationExampleRaw
    }
  }]
}, {
  category: categories.LAYOUT,
  components: [{
    name: 'Panel',
    raw: PanelRaw,
    example: {
      component: PanelExample,
      raw: PanelExampleRaw
    }
  }, {
    name: 'Box Layouts',
    raw: LayoutBoxRaw,
    example: {
      component: LayoutBoxExample,
      raw: LayoutBoxExampleRaw
    }
  }, {
    name: 'LoadMask',
    raw: LoadMaskRaw,
    example: {
      component: LoadMaskExample,
      raw: LoadMaskExampleRaw
    }
  }]
}, {
  category: categories.MESSAGE,
  components: [{
    name: 'SignalList',
    raw: SignalListRaw,
    example: {
      component: SignalListExample,
      raw: SignalListExampleRaw
    }
  }, {
    name: 'SignalBox',
    raw: SignalBoxRaw,
    example: {
      component: SignalBoxExample,
      raw: SignalBoxExampleRaw
    }
  }, {
    name: 'Notifications',
    description: 'To show various notifications to the user',
    example: {
      component: NotifierExample,
      raw: NotifierExampleRaw
    }
  }, {
    name: 'Error Logging',
    description: 'Example to log Errors in an application',
    example: {
      component: ErrorLoggingExample,
      raw: ErrorLoggingExampleRaw
    }
  }]
}]
<|endoftext|>


<commit_before>var url = require('url')
var dashButton = require('node-dash-button');
var request = require('request')

function DasherButton(button) {
  var options = {headers: button.headers, body: button.body, json: button.json}
  var debug = button.debug || false;
  this.dashButton = dashButton(button.address, button.interface, button.timeout, button.protocol)
  var buttonList = {};
  this.dashButton.on("detected", function() {

    if(!buttonList.hasOwnProperty(button.address)){
        buttonList[button.address] = 1;
    } else {
        buttonList[button.address]++;
    }
    console.log(button.name + " pressed. Count: " +  buttonList[button.address]);
    if (debug){
      console.log("Debug mode, skipping request.");
      console.log(button);
    } else {
      doRequest(button.url, button.method, options)
    }
  })

  console.log(button.name + " added.")
}

function doRequest(requestUrl, method, options, callback) {
  options = options || {}
  options.query = options.query || {}
  options.json = options.json || false
  options.headers = options.headers || {}

  var reqOpts = {
    url: url.parse(requestUrl),
    method: method || 'GET',
    qs: options.query,
    body: options.body,
    json: options.json,
    headers: options.headers
  }

  request(reqOpts, function onResponse(error, response, body) {
    if (error) {
      console.log("there was an error");
      console.log(error);
    }
    if (response) {
      if (response.statusCode === 401) {
        console.log("Not authenticated");
        console.log(error);
      }
      if (response.statusCode < 200 || response.statusCode > 299) {
        console.log("Unsuccessful status code");
        console.log(error);
      }
    } else {
      console.log("Response undefined");
    }
    if (callback) {
      callback(error, response, body)
    }
  })
}

module.exports = DasherButton
<commit_msg>Update dasher.js<commit_after>var url = require('url')
var dashButton = require('node-dash-button');
var request = require('request')

function doLog(message) {
  console.log('[' + (new Date().toISOString()) + '] ' + message);
}

function DasherButton(button) {
  var options = {headers: button.headers, body: button.body, json: button.json}
  var debug = button.debug || false;
  this.dashButton = dashButton(button.address, button.interface, button.timeout, button.protocol)
  var buttonList = {};
  this.dashButton.on("detected", function() {

    if(!buttonList.hasOwnProperty(button.address)){
        buttonList[button.address] = 1;
    } else {
        buttonList[button.address]++;
    }
    doLog(button.name + " pressed. Count: " +  buttonList[button.address]);
    if (debug){
      doLog("Debug mode, skipping request.");
      console.log(button);
    } else {
      doRequest(button.url, button.method, options)
    }
  })

  doLog(button.name + " added.")
}

function doRequest(requestUrl, method, options, callback) {
  options = options || {}
  options.query = options.query || {}
  options.json = options.json || false
  options.headers = options.headers || {}

  var reqOpts = {
    url: url.parse(requestUrl),
    method: method || 'GET',
    qs: options.query,
    body: options.body,
    json: options.json,
    headers: options.headers
  }

  request(reqOpts, function onResponse(error, response, body) {
    if (error) {
      doLog("there was an error");
      doLog(error);
    }
    if (response) {
      if (response.statusCode === 401) {
        doLog("Not authenticated");
        doLog(error);
      }
      if (response.statusCode < 200 || response.statusCode > 299) {
        doLog("Unsuccessful status code");
        doLog(error);
      }
    } else {
      doLog("Response undefined");
    }
    if (callback) {
      callback(error, response, body)
    }
  })
}

module.exports = DasherButton
<|endoftext|>


<commit_before>Template._stats.helpers({
  statistics: function(){
    var user = Session.get('userObject'),
        completedBets = Bets.find({ status: 'complete' }).count(),
        wins = Bets.find({ $and: [{ winner: user }, {status: 'complete'}]}).count(),
        points = Points.findOne({ wonBy: user }),

        losses = completedBets - wins;

    return [wins, losses]
  }
});
<commit_msg>fixed logic to display accurate stats<commit_after>Template._stats.helpers({
  statistics: function(){
    var user = Session.get('user'),
        completedBets = Bets.find({ $and: [{ status: 'complete' }, { bettors: user }]}).count(),
        paidBets = Bets.find({ $and: [{ status: 'paid' }, { bettors: user }]}).count(),
        wins = Bets.find({ winner: user }).count(),
        points = Points.findOne({ wonBy: user }),
        losses = (paidBets + completedBets) - wins;

        console.log("WINS: " + wins);
        console.log("PAID BETS: " + paidBets);
        console.log("COMPLETED: " + completedBets);

    return [wins, losses]
  }
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const program = require('commander');
const cosmiconfig = require('cosmiconfig');
const explorer = cosmiconfig('bolt');
const configStore = require('@bolt/build-utils/config-store');
const log = require('@bolt/build-utils/log');
const { readYamlFileSync } = require('@bolt/build-utils/yaml');
const { getPort } = require('@bolt/build-utils/get-port');
const configSchema = readYamlFileSync(
  path.join(__dirname, './utils/config.schema.yml'),
);
const packageJson = require('./package.json');

let userConfig;

// global `bolt` cli options & meta
program
  .version(packageJson.version)
  .option(
    '-C, --config-file <path>',
    'Pass in a specific config file instead of default of ".boltrc.js/json".',
  )
  .option('--prod', configSchema.properties.prod.description)
  .option(
    '-v, --verbosity <amount>',
    configSchema.properties.verbosity.description,
    parseInt,
  )
  .parse(process.argv);

if (program.configFile) {
  const configFilePath = path.join(process.cwd(), program.configFile);
  if (!fs.existsSync(configFilePath)) {
    console.error(`Error, config file does not exist: ${configFilePath}`);
    process.exit(1);
  }
  const configFile = require(configFilePath);
  userConfig = {
    ...configFile,
    configFileUsed: configFilePath,
  };
} else {
  try {
    const searchedFor = explorer.searchSync();
    userConfig = {
      ...searchedFor.config,
      configFileUsed: searchedFor.filepath,
    };
  } catch (error) {
    log.errorAndExit('Could not find config in a .boltrc file', error);
  }
}

(async () => {
  await configStore.init(userConfig).then(async () => {
    // Now that config is initilized, we can start requiring other things
    const { buildBoltManifest } = require('@bolt/build-utils/manifest');
    const log = require('@bolt/build-utils/log');

    // store a copy of the original config before modifying with defaults + auto values. This allows us to point out if a config option was manually vs automatically set.
    let originalConfig;
    /**
     * Update config with all options flags
     * @param {Object} options
     * @param programInstance - The commander `program`
     * @returns {Object} config - Final updated config
     */
    async function updateConfig(options, programInstance) {
      await configStore.updateConfig(async config => {
        originalConfig = config;

        config.verbosity =
          typeof program.verbosity === 'undefined'
            ? config.verbosity
            : program.verbosity;

        config.openServerAtStart =
          typeof options.open === 'undefined'
            ? config.openServerAtStart
            : options.open;

        config.renderingService =
          typeof options.renderingService === 'undefined'
            ? process.env.TRAVIS
              ? false
              : config.renderingService
            : options.renderingService;

        config.env = process.env.NODE_ENV
          ? process.env.NODE_ENV
          : typeof options.env === 'undefined'
          ? config.env
          : options.env;

        //check port not only when setting defaults but in boltrc.js too
        config.port = await getPort(config.port);

        config.webpackStats =
          typeof options.webpackStats === 'undefined'
            ? config.webpackStats
            : options.webpackStats;

        config.webpackDevServer =
          typeof options.webpackDevServer === 'undefined'
            ? config.webpackDevServer
            : options.webpackDevServer;

        config.mode =
          typeof options.mode === 'undefined' ? config.mode : options.mode;

        config.quick =
          typeof options.quick === 'undefined' ? config.quick : options.quick;

        config.watch =
          typeof options.watch === 'undefined' ? config.watch : options.watch;

        config.prod =
          typeof program.prod === 'undefined' ? config.prod : program.prod;

        // automatically set enableSSR to true in prod mode and false in dev mode, unless manually set.
        config.enableSSR = false;

        config.i18n =
          typeof options.i18n === 'undefined' ? !config.prod : options.i18n;

        // If i18n is disabled, ignore and remove lang config settings
        if (config.lang && config.i18n === false) {
          // Remove any lang-specific settings for local dev to speed things up.
          delete config['lang'];
        }

        return config;
      });

      const config = await configStore.getConfig();

      log.dim(`Verbosity: ${config.verbosity}`);
      log.dim(`Prod: ${config.prod}`);
      log.dim(`i18n: ${config.i18n}`);
      log.dim(
        `enableSSR: ${config.enableSSR} ${
          originalConfig.enableSSR ? '(manually set)' : '(auto set)'
        }`,
      );
      log.dim(`Rendering Mode: ${config.mode}`);
      if (config.verbosity > 2) {
        log.dim(`Opening browser: ${config.openServerAtStart}`);
        log.dim(`Quick mode: ${config.quick}`);
        log.dim(`buildDir: ${config.buildDir}`);
        log.dim(`dataDir: ${config.dataDir}`);
        log.dim(`wwwDir: ${config.wwwDir}`);
      }

      // Basically at this point, the cli is bootstrapped and ready to go.
      // Let's build the core bolt manifest
      await buildBoltManifest();
      return config;
    }

    await log.intro();

    program
      .option(
        '--no-ssr',
        'Manually disables server side rendering (vs auto enable in prod mode)',
      )
      .option(
        '--ssr',
        'Manually enabless server side rendering in all enviornments (vs by default only enabling automatically in prod mode)',
      );

    // `bolt build`
    program
      .command('build')
      .description('Build it')
      .option(
        '--webpack-stats',
        configSchema.properties.webpackStats.description,
      )
      .option('-I, --i18n', configSchema.properties.i18n.description)
      .option('-Q, --quick', configSchema.properties.quick.description)
      .action(async options => {
        log.info(
          `Starting build (${options.parallel ? 'parallel' : 'serial'})`,
        );
        await updateConfig(options, program);
        require('./tasks/task-collections').build();
      });

    // `bolt prep`
    program
      .command('prep')
      .description('Prepwork before building')
      .action(async options => {
        log.info('Starting prep work.');
        await updateConfig(options, program);
        require('./tasks/task-collections').buildPrep();
      });

    // `bolt prep`
    program
      .command('criticalcss')
      .description('Generate Critical CSS')
      .action(async options => {
        log.info('Starting critical CSS');
        await updateConfig(options, program);
        require('./tasks/task-collections').criticalcss();
      });

    program
      .command('serve')
      .description('Spin up local server')
      .option(
        '-O, --open',
        configSchema.properties.openServerAtStart.description,
      )
      .option(
        '--webpack-dev-server',
        configSchema.properties.webpackDevServer.description,
      )
      .option('--watch', configSchema.properties.watch.description)
      .action(async options => {
        if (options.watch === undefined) {
          options.watch = true;
        }
        await updateConfig(options, program);
        require('./tasks/task-collections').serve();
      });

    program.command('watch').action(async options => {
      options.watch = true;
      await updateConfig(options, program);
      require('./tasks/task-collections').watch();
    });

    program.command('clean').action(async options => {
      await updateConfig(options, program);
      require('./tasks/task-collections').clean();
    });

    program
      .command('start')
      .option(
        '-O, --open',
        configSchema.properties.openServerAtStart.description,
      )
      .option('-I, --i18n', configSchema.properties.i18n.description)
      .option('-Q, --quick', configSchema.properties.quick.description)
      .option(
        '--webpack-dev-server',
        configSchema.properties.webpackDevServer.description,
      )
      .option('--watch', configSchema.properties.watch.description)
      .action(async options => {
        if (options.watch === undefined) {
          options.watch = true;
        }
        await updateConfig(options, program);
        require('./tasks/task-collections').start();
      });

    // `bolt lint`
    program
      .command('lint')
      .description("A linter... that doesn't work!")
      .action(async options => {
        await updateConfig(options, program);
      });

    program
      .command('img')
      .alias('images')
      .description('Image process')
      .action(async options => {
        await updateConfig(options, program);
        require('./tasks/task-collections').images();
      });

    program
      .command('webpack')
      .alias('wp')
      .description('WebPack Compile')
      .option(
        '--webpack-stats',
        configSchema.properties.webpackStats.description,
      )
      .action(async options => {
        await updateConfig(options, program);
        try {
          await require('./tasks/webpack-tasks').compile();
        } catch (error) {
          log.errorAndExit('WebPack failed', error);
        }
      });

    program
      .command('pattern-lab')
      .alias('pl')
      .description('Pattern Lab Compile')
      .action(async options => {
        await updateConfig(options, program);
        try {
          await require('./tasks/pattern-lab-tasks').compile();
        } catch (error) {
          log.errorAndExit('Pattern Lab failed', error);
        }
      });

    program
      .command('static')
      .description('Static Site Compile')
      .action(async options => {
        await updateConfig(options, program);
        try {
          await require('./tasks/task-collections').buildPrep();
          await require('./tasks/static-tasks').compile();
        } catch (error) {
          log.errorAndExit('Static Site Generation failed', error);
        }
      });

    // This will tell you all that got `require()`-ed
    // We want to only load what we need - that's why not all `require` statements are at top
    // log.info('All that got `require()`-ed');
    // console.log(Object.keys(require.cache).filter(x => !x.includes('node_modules')));
    // log.info('END: All that got `require()`-ed');

    // cli init ~ must go at bottom
    program.parse(process.argv);
  });
})().catch(err => {
  console.error(err);
});
<commit_msg>fix(build): error on yarn build:noisy; fix integer cast for verbosity arg<commit_after>#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const program = require('commander');
const cosmiconfig = require('cosmiconfig');
const explorer = cosmiconfig('bolt');
const configStore = require('@bolt/build-utils/config-store');
const log = require('@bolt/build-utils/log');
const { readYamlFileSync } = require('@bolt/build-utils/yaml');
const { getPort } = require('@bolt/build-utils/get-port');
const configSchema = readYamlFileSync(
  path.join(__dirname, './utils/config.schema.yml'),
);
const packageJson = require('./package.json');

let userConfig;

const parseIntWithRadix = string => parseInt(string, 10);

// global `bolt` cli options & meta
program
  .version(packageJson.version)
  .option(
    '-C, --config-file <path>',
    'Pass in a specific config file instead of default of ".boltrc.js/json".',
  )
  .option('--prod', configSchema.properties.prod.description)
  .option(
    '-v, --verbosity <amount>',
    configSchema.properties.verbosity.description,
    parseIntWithRadix,
  )
  .parse(process.argv);

if (program.configFile) {
  const configFilePath = path.join(process.cwd(), program.configFile);
  if (!fs.existsSync(configFilePath)) {
    console.error(`Error, config file does not exist: ${configFilePath}`);
    process.exit(1);
  }
  const configFile = require(configFilePath);
  userConfig = {
    ...configFile,
    configFileUsed: configFilePath,
  };
} else {
  try {
    const searchedFor = explorer.searchSync();
    userConfig = {
      ...searchedFor.config,
      configFileUsed: searchedFor.filepath,
    };
  } catch (error) {
    log.errorAndExit('Could not find config in a .boltrc file', error);
  }
}

(async () => {
  await configStore.init(userConfig).then(async () => {
    // Now that config is initilized, we can start requiring other things
    const { buildBoltManifest } = require('@bolt/build-utils/manifest');
    const log = require('@bolt/build-utils/log');

    // store a copy of the original config before modifying with defaults + auto values. This allows us to point out if a config option was manually vs automatically set.
    let originalConfig;
    /**
     * Update config with all options flags
     * @param {Object} options
     * @param programInstance - The commander `program`
     * @returns {Object} config - Final updated config
     */
    async function updateConfig(options, programInstance) {
      await configStore.updateConfig(async config => {
        originalConfig = config;

        config.verbosity =
          typeof program.verbosity === 'undefined'
            ? config.verbosity
            : parseInt(program.verbosity, 10);

        config.openServerAtStart =
          typeof options.open === 'undefined'
            ? config.openServerAtStart
            : options.open;

        config.renderingService =
          typeof options.renderingService === 'undefined'
            ? process.env.TRAVIS
              ? false
              : config.renderingService
            : options.renderingService;

        config.env = process.env.NODE_ENV
          ? process.env.NODE_ENV
          : typeof options.env === 'undefined'
          ? config.env
          : options.env;

        //check port not only when setting defaults but in boltrc.js too
        config.port = await getPort(config.port);

        config.webpackStats =
          typeof options.webpackStats === 'undefined'
            ? config.webpackStats
            : options.webpackStats;

        config.webpackDevServer =
          typeof options.webpackDevServer === 'undefined'
            ? config.webpackDevServer
            : options.webpackDevServer;

        config.mode =
          typeof options.mode === 'undefined' ? config.mode : options.mode;

        config.quick =
          typeof options.quick === 'undefined' ? config.quick : options.quick;

        config.watch =
          typeof options.watch === 'undefined' ? config.watch : options.watch;

        config.prod =
          typeof program.prod === 'undefined' ? config.prod : program.prod;

        // automatically set enableSSR to true in prod mode and false in dev mode, unless manually set.
        config.enableSSR = false;

        config.i18n =
          typeof options.i18n === 'undefined' ? !config.prod : options.i18n;

        // If i18n is disabled, ignore and remove lang config settings
        if (config.lang && config.i18n === false) {
          // Remove any lang-specific settings for local dev to speed things up.
          delete config['lang'];
        }

        return config;
      });

      const config = await configStore.getConfig();

      log.dim(`Verbosity: ${config.verbosity}`);
      log.dim(`Prod: ${config.prod}`);
      log.dim(`i18n: ${config.i18n}`);
      log.dim(
        `enableSSR: ${config.enableSSR} ${
          originalConfig.enableSSR ? '(manually set)' : '(auto set)'
        }`,
      );
      log.dim(`Rendering Mode: ${config.mode}`);
      if (config.verbosity > 2) {
        log.dim(`Opening browser: ${config.openServerAtStart}`);
        log.dim(`Quick mode: ${config.quick}`);
        log.dim(`buildDir: ${config.buildDir}`);
        log.dim(`dataDir: ${config.dataDir}`);
        log.dim(`wwwDir: ${config.wwwDir}`);
      }

      // Basically at this point, the cli is bootstrapped and ready to go.
      // Let's build the core bolt manifest
      await buildBoltManifest();
      return config;
    }

    await log.intro();

    program
      .option(
        '--no-ssr',
        'Manually disables server side rendering (vs auto enable in prod mode)',
      )
      .option(
        '--ssr',
        'Manually enabless server side rendering in all enviornments (vs by default only enabling automatically in prod mode)',
      );

    // `bolt build`
    program
      .command('build')
      .description('Build it')
      .option(
        '--webpack-stats',
        configSchema.properties.webpackStats.description,
      )
      .option('-I, --i18n', configSchema.properties.i18n.description)
      .option('-Q, --quick', configSchema.properties.quick.description)
      .action(async options => {
        log.info(
          `Starting build (${options.parallel ? 'parallel' : 'serial'})`,
        );
        await updateConfig(options, program);
        require('./tasks/task-collections').build();
      });

    // `bolt prep`
    program
      .command('prep')
      .description('Prepwork before building')
      .action(async options => {
        log.info('Starting prep work.');
        await updateConfig(options, program);
        require('./tasks/task-collections').buildPrep();
      });

    // `bolt prep`
    program
      .command('criticalcss')
      .description('Generate Critical CSS')
      .action(async options => {
        log.info('Starting critical CSS');
        await updateConfig(options, program);
        require('./tasks/task-collections').criticalcss();
      });

    program
      .command('serve')
      .description('Spin up local server')
      .option(
        '-O, --open',
        configSchema.properties.openServerAtStart.description,
      )
      .option(
        '--webpack-dev-server',
        configSchema.properties.webpackDevServer.description,
      )
      .option('--watch', configSchema.properties.watch.description)
      .action(async options => {
        if (options.watch === undefined) {
          options.watch = true;
        }
        await updateConfig(options, program);
        require('./tasks/task-collections').serve();
      });

    program.command('watch').action(async options => {
      options.watch = true;
      await updateConfig(options, program);
      require('./tasks/task-collections').watch();
    });

    program.command('clean').action(async options => {
      await updateConfig(options, program);
      require('./tasks/task-collections').clean();
    });

    program
      .command('start')
      .option(
        '-O, --open',
        configSchema.properties.openServerAtStart.description,
      )
      .option('-I, --i18n', configSchema.properties.i18n.description)
      .option('-Q, --quick', configSchema.properties.quick.description)
      .option(
        '--webpack-dev-server',
        configSchema.properties.webpackDevServer.description,
      )
      .option('--watch', configSchema.properties.watch.description)
      .action(async options => {
        if (options.watch === undefined) {
          options.watch = true;
        }
        await updateConfig(options, program);
        require('./tasks/task-collections').start();
      });

    // `bolt lint`
    program
      .command('lint')
      .description("A linter... that doesn't work!")
      .action(async options => {
        await updateConfig(options, program);
      });

    program
      .command('img')
      .alias('images')
      .description('Image process')
      .action(async options => {
        await updateConfig(options, program);
        require('./tasks/task-collections').images();
      });

    program
      .command('webpack')
      .alias('wp')
      .description('WebPack Compile')
      .option(
        '--webpack-stats',
        configSchema.properties.webpackStats.description,
      )
      .action(async options => {
        await updateConfig(options, program);
        try {
          await require('./tasks/webpack-tasks').compile();
        } catch (error) {
          log.errorAndExit('WebPack failed', error);
        }
      });

    program
      .command('pattern-lab')
      .alias('pl')
      .description('Pattern Lab Compile')
      .action(async options => {
        await updateConfig(options, program);
        try {
          await require('./tasks/pattern-lab-tasks').compile();
        } catch (error) {
          log.errorAndExit('Pattern Lab failed', error);
        }
      });

    program
      .command('static')
      .description('Static Site Compile')
      .action(async options => {
        await updateConfig(options, program);
        try {
          await require('./tasks/task-collections').buildPrep();
          await require('./tasks/static-tasks').compile();
        } catch (error) {
          log.errorAndExit('Static Site Generation failed', error);
        }
      });

    // This will tell you all that got `require()`-ed
    // We want to only load what we need - that's why not all `require` statements are at top
    // log.info('All that got `require()`-ed');
    // console.log(Object.keys(require.cache).filter(x => !x.includes('node_modules')));
    // log.info('END: All that got `require()`-ed');

    // cli init ~ must go at bottom
    program.parse(process.argv);
  });
})().catch(err => {
  console.error(err);
});
<|endoftext|>


<commit_before>const Eris = require("eris"),
    Logger = require("./Logger"),
    MessageHandler = require("./MessageHandler"),
    reload = require("require-reload")(require);

class Nagato extends Eris.Client {
    constructor(options) {
        super(options.Token, options.Eris);

        this.admins = options.Admins;

        this.messageHandlerOptions = options.MessageHandler;
        if(!this.messageHandlerOptions.allowedBots) this.messageHandlerOptions.allowedBots = [];

        this.help = options.Help;
        if (!this.help.helpCommands) this.help.helpCommands = ["help"];

        this.log = new Logger(options.Logger);
        this.messageHandler = new MessageHandler(this);

        this.on("ready", () => {
            this.messageHandler.start();
            this.log.info("Bot is now Ready and Connected to Discord");
        });

        this.on("error", (error, id) => {
            this.log.error(`Error: Shard ${id} - ${error.stack}`);
        });

        this.on("warn", (message, id) => {
            this.log.warn(`Warning: Shard ${id} - ${message}`);
        });

        this.on("debug", (message, id) => {
            this.log.debug(`Debug: ${id != null ? "Shard " + id + " - " : ""}${message}`);
        })

        this.on("shardReady", (id) => {
            this.log.info(`Shard ${id} is Now Ready`)
        });

        this.on("shardDisconnect", (error, id) => {
            this.log.warn(`Shard ${id} has Disconnected` + (error ? ": " + error.message : ""));
        });

        this.on("shardResume", (id) => {
            this.log.warn(`Shard ${id} has Resumed`);
        });

        this.on("disconnect", () => {
            this.log.error("Bot has now Disconnected from Discord");
        });
    }

    loadCommands(commandsFolder) {
        new(reload("./Utils/CommandLoader"))(this, commandsFolder).load().then((response) => {
            this.commands = response.commands;
            this.commandAliases = response.commandAliases;
        }).catch(err => this.log.error(err));
    }

    reloadCommands(commandsFolder) {
        reload.emptyCache("./Utils/CommandLoader");
        this.commands = undefined;
        this.commandAliases = undefined;
        new(reload("./Utils/CommandLoader"))(this, commandsFolder).load().then((response) => {
            this.commands = response.commands;
            this.commandAliases = response.commandAliases;
        }).catch(err => this.log.error(err));
    }

    loadEvents(eventsFolder) {
        new(reload("./Utils/EventLoader"))(this, eventsFolder).load().then((response) => {
            this.events = response;
            for (var event in this.events) {
                this.events[event].load();
            }
        }).catch(err => this.log.error(err));
    }

    reloadEvents(eventsFolder) {
        reload.emptyCache("./Utils/EventLoader");
        for (var event in this.events) {
            this.events[event].remove();
        }
        this.events = undefined;
        new(reload("./Utils/EventLoader"))(this, eventsFolder).load().then((response) => {
            this.events = response;
            for (var event in this.events) {
                this.events[event].load();
            }
        }).catch(err => this.log.error(err));
    }
}

module.exports = Nagato;<commit_msg>Cleanup and changing reload to empty cache<commit_after>const Eris = require("eris"),
    Logger = require("./Logger"),
    MessageHandler = require("./MessageHandler"),
    reload = require("require-reload")(require).emptyCache;

class Nagato extends Eris.Client {
    constructor(options) {
        super(options.Token, options.Eris);

        this.admins = options.Admins;

        this.messageHandlerOptions = options.MessageHandler;
        if(!this.messageHandlerOptions.allowedBots) this.messageHandlerOptions.allowedBots = [];

        this.help = options.Help;
        if (!this.help.helpCommands) this.help.helpCommands = ["help"];

        this.log = new Logger(options.Logger);
        this.messageHandler = new MessageHandler(this);

        this.on("ready", () => {
            this.messageHandler.start();
            this.log.info("Bot is now Ready and Connected to Discord");
        });

        this.on("warn", (message, id) => {
            this.log.warn(`Warning: Shard ${id} - ${message}`);
        });

        this.on("error", (error, id) => {
            this.log.error(`Error: Shard ${id} - ${error.stack}`);
        });

        this.on("debug", (message, id) => {
            this.log.debug(`Debug: ${id != null ? "Shard " + id + " - " : ""}${message}`);
        })

        this.on("shardReady", (id) => {
            this.log.info(`Shard ${id} is Now Ready`)
        });

        this.on("shardDisconnect", (error, id) => {
            this.log.warn(`Shard ${id} has Disconnected` + (error ? ": " + error.message : ""));
        });

        this.on("shardResume", (id) => {
            this.log.warn(`Shard ${id} has Resumed`);
        });

        this.on("disconnect", () => {
            this.log.error("Bot has now Disconnected from Discord");
        });
    }

    loadCommands(commandsFolder) {
        new(require("./Utils/CommandLoader"))(this, commandsFolder).load().then((response) => {
            this.commands = response.commands;
            this.commandAliases = response.commandAliases;
        }).catch(err => this.log.error(err));
    }

    reloadCommands(commandsFolder) {
        reload("./Utils/CommandLoader");
        this.commands = undefined;
        this.commandAliases = undefined;
        new(require("./Utils/CommandLoader"))(this, commandsFolder).load().then((response) => {
            this.commands = response.commands;
            this.commandAliases = response.commandAliases;
        }).catch(err => this.log.error(err));
    }

    loadEvents(eventsFolder) {
        new(require("./Utils/EventLoader"))(this, eventsFolder).load().then((response) => {
            this.events = response;
            for (var event in this.events) {
                this.events[event].load();
            }
        }).catch(err => this.log.error(err));
    }

    reloadEvents(eventsFolder) {
        reload("./Utils/EventLoader");
        for (var event in this.events) {
            this.events[event].remove();
        }
        this.events = undefined;
        new(require("./Utils/EventLoader"))(this, eventsFolder).load().then((response) => {
            this.events = response;
            for (var event in this.events) {
                this.events[event].load();
            }
        }).catch(err => this.log.error(err));
    }
}

module.exports = Nagato;<|endoftext|>


<commit_before>/*
  It's module for run migration for every module which has dir "/migrations"
  in module root folder. Every files in dir must be
  [timestamp_miliseconds]__[name].js (example: 1538478025618__hitl_messages.js)
*/

import path from 'path'
import { existsSync, readdirSync } from 'fs'

const getMigrationDirIfExist = (dirList, { root }) => {
  const migrationPath = path.resolve(root, './migrations')

  return existsSync(migrationPath) ? [...dirList, migrationPath] : dirList
}

const runUp = async (knex, dir) => {
  const dirFiles = readdirSync(dir)
    .filter(file => /^\d+__.+\.js$/.test(file))
    .sort()

  for (let index = 0; index < dirFiles.length; index++) {
    const migration = require(path.resolve(dir, dirFiles[index]))

    migration.up && (await migration.up(knex))
  }
}

module.exports = async (db, moduleDefinitions = []) => {
  const migrationsDirList = moduleDefinitions.reduce(getMigrationDirIfExist, [])
  const knex = await db.get()

  return {
    up: () => Promise.all(migrationsDirList.map(dir => runUp(knex, dir))),
    /*
      TODO: write it only with changes in "botpress CL"
      maybe it will be make this command: botpress migrate:[up||down] [module_name]
    */
    down: () => ({}) // TODO: write it only with changes in "botpress CL"
  }
}
<commit_msg>fix(core): fix rerunning module migrations<commit_after>/*
  It's module for run migration for every module which has dir "/migrations"
  in module root folder. Every files in dir must be
  [timestamp_miliseconds]__[name].js (example: 1538478025618__hitl_messages.js)
*/

import path from 'path'
import { existsSync, readdirSync } from 'fs'
import helpers from './helpers'

const getMigrationDirIfExist = (dirList, { root }) => {
  const migrationPath = path.resolve(root, './migrations')

  return existsSync(migrationPath) ? [...dirList, migrationPath] : dirList
}

const runUp = async (knex, dir) => {
  const passedMigrations = (await knex('knex_module_migrations').select('name')).map(({ name }) => name)
  const dirFiles = readdirSync(dir)
    .filter(file => /^\d+__.+\.js$/.test(file) && !passedMigrations.includes(file))
    .sort()

  for (let index = 0; index < dirFiles.length; index++) {
    const name = dirFiles[index]
    const migration = require(path.resolve(dir, name))

    migration.up && (await migration.up(knex))
    await knex('knex_module_migrations').insert({ name, migration_time: new Date() })
  }
}

module.exports = async (db, moduleDefinitions = []) => {
  const migrationsDirList = moduleDefinitions.reduce(getMigrationDirIfExist, [])
  const knex = await db.get()

  await helpers(knex).createTableIfNotExists('knex_module_migrations', table => {
    table.increments('id').primary()
    table.string('name')
    table.timestamp('migration_time')
  })

  return {
    up: () => Promise.all(migrationsDirList.map(dir => runUp(knex, dir))),
    /*
      TODO: write it only with changes in "botpress CL"
      maybe it will be make this command: botpress migrate:[up||down] [module_name]
    */
    down: () => ({}) // TODO: write it only with changes in "botpress CL"
  }
}
<|endoftext|>


<commit_before>import last from 'lodash/last';
import isEqual from 'lodash/isEqual';

class AggregationPipeline {
  static stages = [
    'addFields',
    'bucket',
    'bucketAuto',
    'collStats',
    'count',
    'currentOp',
    'facet',
    'geoNear',
    'graphLookup',
    'group',
    'indexStats',
    'limit',
    'listLocalSessions',
    'listSessions',
    'lookup',
    'match',
    'out',
    'project',
    'redact',
    'replaceRoot',
    'sample',
    'skip',
    'sort',
    'sortByCount',
    'unwind',
  ];

  constructor(repository, startPipeline = [], options = {}) {
    this.repository = repository;
    this.stack = [];
    this.options = options;

    this.merge(startPipeline);

    // check if using Proxy is a better alternative
    this.constructor.stages.forEach(stage => {
      if (!this[stage]) {
        this[stage] = value => this.push({ [`$${stage}`]: value });
      }
    });
  }

  setOptions(options) {
    if (typeof options === 'function') {
      this.options = options(this.options);
    } else {
      Object.assign(this.options, options);
    }

    return this;
  }

  unshift(...operations) {
    operations.reverse().forEach(operation => {
      this.stack.unshift(...(Array.isArray(operation) ? operation : [operation]));
    });

    return this;
  }

  push(...operations) {
    operations.forEach(operation => {
      this.stack.push(...(Array.isArray(operation) ? operation : [operation]));
    });

    return this;
  }

  merge(pipeline) {
    return this.push(Array.isArray(pipeline) ? pipeline : pipeline.stack);
  }

  match = query =>
    typeof query !== 'object' || !Object.keys(query).length ? this : this.push({ $match: query });

  project = fields =>
    this.push({
      $project: Array.isArray(fields)
        ? fields.reduce(
            (acc, field) => ({
              ...acc,
              ...(typeof field === 'string' ? { [field]: 1 } : field),
            }),
            {},
          )
        : fields,
    });

  lookup = (
    relation,
    { as = relation, match = false, projectOne = true, ignoreIfExists = false, ...rest } = {},
  ) => {
    if (typeof relation === 'object') {
      return this.push({
        $lookup: relation,
      });
    }

    if (!this.repository.hasRelation(relation)) {
      throw new Error(
        `Missing "${relation}" relation in the "${this.repository.constructor.name}" repository!`,
      );
    }

    const { type } = this.repository.getRelation(relation);

    if (ignoreIfExists && this.hasLookup(relation, { as, ...rest })) {
      return this;
    }

    this.push({
      $lookup: this.repository.relationToLookup(relation, { as, ...rest }),
    });

    if (match) {
      this.match({
        [as]: {
          $elemMatch: match,
        },
      });
    }

    if (type === 'one' && projectOne) {
      this.addFields({
        [as]: {
          $arrayElemAt: [`$${as}`, 0],
        },
      });
    }

    return this;
  };

  hasLookup = (relation, options = {}) =>
    !!this.stack.find(
      stage =>
        stage.$lookup &&
        isEqual(stage.$lookup, this.repository.relationToLookup(relation, options)),
    );

  sort = fields =>
    this.push({
      $sort: Object.keys(fields).reduce(
        (acc, field) => ({
          ...acc,
          [field]:
            fields[field] === 1 ||
            (typeof fields[field] === 'string' && fields[field].toLowerCase() === 'asc')
              ? 1
              : -1,
        }),
        {},
      ),
    });

  slice = (start, end) => this.push(this.skip(start), this.limit(end - start));

  count = (outputField = 'count') => this.push({ $count: outputField });

  one = () => this.limit(1);

  clone = pipeline => new this.constructor(this.repository, pipeline || [...this.stack]);

  toCursor = () =>
    this.repository.aggregate({
      pipeline: this.stack,
      options: this.options,
    });

  toArray = async () => (await this.toCursor()).toArray();

  toResult = async () => {
    const lastStage = last(this.stack);
    const result = await this.toArray();

    if (!lastStage) {
      return result;
    }

    if (lastStage.$count) {
      return result.length > 0 ? result[0][lastStage.$count] : 0;
    }

    if (lastStage.$limit && lastStage.$limit === 1) {
      return result.length > 0 ? result[0] : null;
    }

    return result;
  };

  watch = (options = {}) => this.repository.collection.watch(this.stack, options);

  watchChanges = (onChange, ...args) => {
    const changeStream = this.watch(...args);
    changeStream.on('change', onChange);
    return changeStream;
  };

  on = (operation, cb, options = {}) => {
    const operationType = operation === 'create' ? 'insert' : operation;
    const changeStream = this.match({
      operationType,
    }).watchChanges(change => cb(change.fullDocument, change), {
      fullDocument: 'updateLookup',
      ...options,
    });

    return () => changeStream.close();
  };
}

export default AggregationPipeline;
<commit_msg>[oors-mongodb] AggregationPipeline result functions will accept options<commit_after>import last from 'lodash/last';
import isEqual from 'lodash/isEqual';

class AggregationPipeline {
  static stages = [
    'addFields',
    'bucket',
    'bucketAuto',
    'collStats',
    'count',
    'currentOp',
    'facet',
    'geoNear',
    'graphLookup',
    'group',
    'indexStats',
    'limit',
    'listLocalSessions',
    'listSessions',
    'lookup',
    'match',
    'out',
    'project',
    'redact',
    'replaceRoot',
    'sample',
    'skip',
    'sort',
    'sortByCount',
    'unwind',
  ];

  constructor(repository, startPipeline = [], options = {}) {
    this.repository = repository;
    this.stack = [];
    this.options = options;

    this.merge(startPipeline);

    // check if using Proxy is a better alternative
    this.constructor.stages.forEach(stage => {
      if (!this[stage]) {
        this[stage] = value => this.push({ [`$${stage}`]: value });
      }
    });
  }

  setOptions(options) {
    if (typeof options === 'function') {
      this.options = options(this.options);
    } else {
      Object.assign(this.options, options);
    }

    return this;
  }

  unshift(...operations) {
    operations.reverse().forEach(operation => {
      this.stack.unshift(...(Array.isArray(operation) ? operation : [operation]));
    });

    return this;
  }

  push(...operations) {
    operations.forEach(operation => {
      this.stack.push(...(Array.isArray(operation) ? operation : [operation]));
    });

    return this;
  }

  merge(pipeline) {
    return this.push(Array.isArray(pipeline) ? pipeline : pipeline.stack);
  }

  match = query =>
    typeof query !== 'object' || !Object.keys(query).length ? this : this.push({ $match: query });

  project = fields =>
    this.push({
      $project: Array.isArray(fields)
        ? fields.reduce(
            (acc, field) => ({
              ...acc,
              ...(typeof field === 'string' ? { [field]: 1 } : field),
            }),
            {},
          )
        : fields,
    });

  lookup = (
    relation,
    { as = relation, match = false, projectOne = true, ignoreIfExists = false, ...rest } = {},
  ) => {
    if (typeof relation === 'object') {
      return this.push({
        $lookup: relation,
      });
    }

    if (!this.repository.hasRelation(relation)) {
      throw new Error(
        `Missing "${relation}" relation in the "${this.repository.constructor.name}" repository!`,
      );
    }

    const { type } = this.repository.getRelation(relation);

    if (ignoreIfExists && this.hasLookup(relation, { as, ...rest })) {
      return this;
    }

    this.push({
      $lookup: this.repository.relationToLookup(relation, { as, ...rest }),
    });

    if (match) {
      this.match({
        [as]: {
          $elemMatch: match,
        },
      });
    }

    if (type === 'one' && projectOne) {
      this.addFields({
        [as]: {
          $arrayElemAt: [`$${as}`, 0],
        },
      });
    }

    return this;
  };

  hasLookup = (relation, options = {}) =>
    !!this.stack.find(
      stage =>
        stage.$lookup &&
        isEqual(stage.$lookup, this.repository.relationToLookup(relation, options)),
    );

  sort = fields =>
    this.push({
      $sort: Object.keys(fields).reduce(
        (acc, field) => ({
          ...acc,
          [field]:
            fields[field] === 1 ||
            (typeof fields[field] === 'string' && fields[field].toLowerCase() === 'asc')
              ? 1
              : -1,
        }),
        {},
      ),
    });

  slice = (start, end) => this.push(this.skip(start), this.limit(end - start));

  count = (outputField = 'count') => this.push({ $count: outputField });

  one = () => this.limit(1);

  clone = pipeline => new this.constructor(this.repository, pipeline || [...this.stack]);

  toCursor = (options = {}) =>
    this.repository.aggregate({
      pipeline: this.stack,
      options: this.options,
      ...options,
    });

  toArray = async options => (await this.toCursor(options)).toArray();

  toResult = async options => {
    const lastStage = last(this.stack);
    const result = await this.toArray(options);

    if (!lastStage) {
      return result;
    }

    if (lastStage.$count) {
      return result.length > 0 ? result[0][lastStage.$count] : 0;
    }

    if (lastStage.$limit && lastStage.$limit === 1) {
      return result.length > 0 ? result[0] : null;
    }

    return result;
  };

  watch = (options = {}) => this.repository.collection.watch(this.stack, options);

  watchChanges = (onChange, ...args) => {
    const changeStream = this.watch(...args);
    changeStream.on('change', onChange);
    return changeStream;
  };

  on = (operation, cb, options = {}) => {
    const operationType = operation === 'create' ? 'insert' : operation;
    const changeStream = this.match({
      operationType,
    }).watchChanges(change => cb(change.fullDocument, change), {
      fullDocument: 'updateLookup',
      ...options,
    });

    return () => changeStream.close();
  };
}

export default AggregationPipeline;
<|endoftext|>


<commit_before>(function ($) {
    'use strict';
    $.fn.getLiarText = function () {
        var $clt = this,
            mcutype = $clt.data('liartype'),
            value = $clt.find(':text,input[type=number],input[type=email]').val() || $clt.find('textarea').val() || '';
        if (mcutype === 'select2') {
            value = $clt.find('select').find("option:selected").text() || '';
        } else if (mcutype === 'checkgroup') {
            value = [];
            $clt.find(':checkbox:checked,:radio:checked').each(function (i, ele) {

                value[i] = ele.parentElement.textContent;

                if (value[i] == undefined) {
                    value[i] = ele.parentElement.innerText;
                }
            });
        } else if (mcutype === 'date') {
            value = value.replace(/\//ig, '');
        } else if (mcutype === 'label') {
            value = $clt.text();
        } else if (mcutype === 'hiddenbox') {
            value = $clt.children('.span').text();
        }

        return value;
    };

    $.fn.getLiarVal = function () {
        var $clt = this,
            mcutype = $clt.data('liartype'),
            value = $clt.find(':text,input[type=number],input[type=email]').val() || $clt.find('textarea').val() || '';

        if (mcutype === 'select2') {
            value = $clt.find('select').val() || '';
        } else if (mcutype === 'checkgroup') {
            value = [];
            $clt.find(':checkbox:checked,:radio:checked').each(function (i, ele) {
                value[i] = ele.value;
            });
        } else if (mcutype === 'date') {
            value = value.replace(/\//ig, '');
        } else if (mcutype === 'label') {
            value = $clt.text();
        }

        return value;
    };

    $.fn.setLiarVal = function (val) {
        var $clt = this,
            mcutype = $clt.data('liartype');

        val = val === undefined ? '' : val;

        if (mcutype === 'select2') {
            $clt.find('select').select2('val', val);
        } else if (mcutype === 'select') {
            $clt.find('select').val(val);
        }
        else if (mcutype === 'checkgroup') {
            $clt.find(':checkbox,:radio').prop('checked', 0);
            if ($.isArray(val)) {
                $.each(val, function (i, v) {
                    $clt.find(':checkbox[value="' + v + '"],:radio[value="' + v + '"]').prop('checked', 1);
                });
            } else {
                val = val.indexOf('.') === val.length - 1 ? val.substring(0, val.length - 1) : val;
                if (!!val && val != "") {
                    $clt.find(':checkbox[value="' + val + '"],:radio[value="' + val + '"]').prop('checked', 1);
                }
            }
        } else if (mcutype === 'date') {
            $clt.find(':text').val(val.length === 8 ? val.substring(0, 4) + '/' + val.substring(4, 6) + '/' + val.substring(6, 8) : val);
        } else if (mcutype === 'label') {
            $clt.text(val);
        } else {
            $clt.find(':text,input[type=number],input[type=email], textarea').val(val);
        }

        return this;
    };

    $.fn.setLiarText = function (val) {
        var $clt = this,
            mcutype = $clt.data('liartype');

        val = val === undefined ? '' : val;

        if (mcutype === 'select2') {

        } else if (mcutype === 'checkgroup') {

        } else if (mcutype === 'date') {
            $clt.find(':text').val(val.length === 8 ? val.substring(0, 4) + '/' + val.substring(4, 6) + '/' + val.substring(6, 8) : val);
        } else if (mcutype === 'label') {
            $clt.text(val);
        } else {
            $clt.find(':text,input[type=number],input[type=email], textarea').val(val);
        }

        return this;
    };

    $.fn.enable = function (b) {
        if (!!b) b = true;
        return this.each(function () {
            this.disabled = !b;
        });
    };

    $.fn.ifElse = function (condition, ifCb, elseCb) {
        if (condition == undefined) return this;
        return this.each(condition == '' || !!condition ? $.isFunction(ifCb) ? ifCb : $.noop : $.isFunction(elseCb) ? elseCb : $.noop);
    };

    $.fn.enableLiar = function (clearVal) {
        return this.find(':input').enable(1);
    };

    $.fn.disableLiar = function (clearVal) {
        return this.find(':input').enable(0);
    };

})(jQuery);<commit_msg>update<commit_after>(function ($) {
    'use strict';
    $.fn.getLiarText = function () {
        var $clt = this,
            liartype = $clt.data('liartype'),
            value = $clt.find(':text,input[type=number],input[type=email]').val() || $clt.find('textarea').val() || '';
        if (liartype === 'select2') {
            value = $clt.find('select').find("option:selected").text() || '';
        } else if (liartype === 'checkgroup') {
            value = [];
            $clt.find(':checkbox:checked,:radio:checked').each(function (i, ele) {

                value[i] = ele.parentElement.textContent;

                if (value[i] == undefined) {
                    value[i] = ele.parentElement.innerText;
                }
            });
        } else if (liartype === 'date') {
            value = value.replace(/\//ig, '');
        } else if (liartype === 'label') {
            value = $clt.text();
        } else if (liartype === 'hiddenbox') {
            value = $clt.children('.span').text();
        }

        return value;
    };

    $.fn.getLiarVal = function () {
        var $clt = this,
            liartype = $clt.data('liartype'),
            value = $clt.find(':text,input[type=number],input[type=email]').val() || $clt.find('textarea').val() || '';

        if (liartype === 'select2') {
            value = $clt.find('select').val() || '';
        } else if (liartype === 'checkgroup') {
            value = [];
            $clt.find(':checkbox:checked,:radio:checked').each(function (i, ele) {
                value[i] = ele.value;
            });
        } else if (liartype === 'date') {
            value = value.replace(/\//ig, '');
        } else if (liartype === 'label') {
            value = $clt.text();
        }

        return value;
    };

    $.fn.setLiarVal = function (val) {
        var $clt = this,
            liartype = $clt.data('liartype');

        val = val === undefined ? '' : val;

        if (liartype === 'select2') {
            $clt.find('select').select2('val', val);
        } else if (liartype === 'select') {
            $clt.find('select').val(val);
        }
        else if (liartype === 'checkgroup') {
            $clt.find(':checkbox,:radio').prop('checked', 0);
            if ($.isArray(val)) {
                $.each(val, function (i, v) {
                    $clt.find(':checkbox[value="' + v + '"],:radio[value="' + v + '"]').prop('checked', 1);
                });
            } else {
                val = val.indexOf('.') === val.length - 1 ? val.substring(0, val.length - 1) : val;
                if (!!val && val != "") {
                    $clt.find(':checkbox[value="' + val + '"],:radio[value="' + val + '"]').prop('checked', 1);
                }
            }
        } else if (liartype === 'date') {
            $clt.find(':text').val(val.length === 8 ? val.substring(0, 4) + '/' + val.substring(4, 6) + '/' + val.substring(6, 8) : val);
        } else if (liartype === 'label') {
            $clt.text(val);
        } else {
            $clt.find(':text,input[type=number],input[type=email], textarea').val(val);
        }

        return this;
    };

    $.fn.setLiarText = function (val) {
        var $clt = this,
            liartype = $clt.data('liartype');

        val = val === undefined ? '' : val;

        if (liartype === 'select2') {

        } else if (liartype === 'checkgroup') {

        } else if (liartype === 'date') {
            $clt.find(':text').val(val.length === 8 ? val.substring(0, 4) + '/' + val.substring(4, 6) + '/' + val.substring(6, 8) : val);
        } else if (liartype === 'label') {
            $clt.text(val);
        } else {
            $clt.find(':text,input[type=number],input[type=email], textarea').val(val);
        }

        return this;
    };

    $.fn.enable = function (b) {
        if (!!b) b = true;
        return this.each(function () {
            this.disabled = !b;
        });
    };

    $.fn.ifElse = function (condition, ifCb, elseCb) {
        if (condition == undefined) return this;
        return this.each(condition == '' || !!condition ? $.isFunction(ifCb) ? ifCb : $.noop : $.isFunction(elseCb) ? elseCb : $.noop);
    };

    $.fn.enableLiar = function (clearVal) {
        return this.find(':input').enable(1);
    };

    $.fn.disableLiar = function (clearVal) {
        return this.find(':input').enable(0);
    };

})(jQuery);<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.csv',
  name: 'Outputer',

  documentation: 'CSV Outputer.',

  properties: [
    {
      class: 'String',
      name: 'buf_',
      value: ''
    },
    {
      class: 'Boolean',
      name: 'includeQuotes',
      help: 'If true, values are quoted with the `"` char',
      value: true
    },
    {
      class: 'String',
      name: 'delimiter',
      value: ','
    },
    {
      class: 'String',
      name: 'nestedObjectSeperator',
      value: '__'
    },
    {
      class: 'StringArray',
      name: 'nestedObjectNames'
    },
    {
      class: 'String',
      name: 'nlStr',
      value: '\n'
    },
    {
      class: 'String',
      name: 'undefinedStr',
      value: ''
    },
    {
      class: 'Boolean',
      name: 'outputHeaderRow',
      value: true
    },
    {
      class: 'Function',
      name: 'propertyPredicate',
      value: function(o, p) { return ! p.transient; }
    },
    {
      class: 'Boolean',
      name: 'sortObjectKeys',
      value: false
    }
  ],

  methods: [
    function out() {
      for ( var i = 0 ; i < arguments.length ; i++ ) {
        this.buf_ += arguments[i];
      }

      return this;
    },

    function outputHeader(o) {
      if ( ! this.outputHeaderRow ) return;

      this.outputPropertyFilteredName(o);
      this.removeTrailingComma().out(this.nlStr);
    },

    function removeTrailingComma() {
      // Removes trailing comma
      if ( this.buf_.charAt(this.buf_.length - 1) == ',' ) this.buf_ = this.buf_.slice(0, -1);
      return this;
    },

    function stringify(o) {
      // Outputs object headers
      this.outputHeader(o);
      var ret = this.buf_;
      this.reset(); // reset to avoid retaining garbage

      // Outputs object values
      this.output(o);
      this.removeTrailingComma().out(this.nlStr);
      ret += this.buf_;
      this.reset();

      return ret;
    },

    function externalProperty(o, p) {
      if ( ! this.propertyPredicate(o, p) ) return false;
      if ( p.isDefaultValue(o[p.name]) ) return false;

      return true;
    },

    function outputHeaderTitle(o) {
      this.out('"').writePrefix().out(o).out('"').out(this.delimiter);
    },

    {
      name: 'outputPropertyFilteredName',
      code: foam.mmethod({
        // Is there a `switch` like fall through so the function call isn't unecessarily repeated?
        Undefined: function(o) { this.outputHeaderTitle(o); },
        Null:      function(o) { this.outputHeaderTitle(o); },
        String:    function(o) { this.outputHeaderTitle(o); },
        Number:    function(o) { this.outputHeaderTitle(o); },
        Boolean:   function(o) { this.outputHeaderTitle(o); },
        Date:      function(o) { this.outputHeaderTitle(o); },
        FObject:   function(o) {
          // Gets and recurses through object properties
          var ps = o.cls_.getAxiomsByClass(foam.core.Property);

          for ( var i = 0 ; i < ps.length ; i++ ) {
            this.outputPropertyName(o, ps[i]);
          }
        },
        Array: function(o) { /* Ignore arrays in CSV */ },
        Function: function(o) { /* Ignore functions in CSV */ },
        Object: function(o) {
          // TODO: How to test?
          if ( o.outputCSV ) {
            o.outputCSV(this);
          } else {
            if ( this.sortObjectKeys ) {
              this.outputSortedObjectKeyValues_(o);
            } else {
              this.outputObjectKeyValues_(o);
            }
          }
        }
      })
    },

    function outputPropertyName(o, p) {
      if ( ! this.externalProperty(o, p) ) return;

      // Checks if property is enum, or object with properties of its own
      // TODO: Is this correct way to check if object has relevant sub-properties
      if ( foam.core.AbstractEnum.isInstance( o[p.name] ) ) {
        this.outputPropertyFilteredName(p.name + "__ordinal");
      } else if ( p.of ) {
        this.start(p.name);
        this.outputPropertyFilteredName(o[p.name]);
        this.end();
      } else {
        this.outputPropertyFilteredName(p.name);
      }
    },

    function outputProperty(o, p) {
      if ( ! this.externalProperty(o, p) ) return;

      this.output(o[p.name]);
      this.out(this.delimiter);
    },

    function reset() {
      this.buf_ = '';
      return this;
    },

    // Starts a nested object, 1 more `__` with object name
    function start(objectName) {
      this.nestedObjectNames.push(objectName);
      return this;
    },

    function writePrefix() {
      for ( var i = 0 ; i < this.nestedObjectNames.length ; i++ ) {
        this.out(this.nestedObjectNames[i] + this.nestedObjectSeperator);
      }

      return this;
    },

    // End a nested object, 1 fewer `__` within object name
    function end() {
      this.nestedObjectNames.pop();
      return this;
    },

    // TODO: Copied from foam.core.json (move to common library)
    function escape(str) {
      return str
        .replace(/\\/g, '\\\\')
        .replace(/"/g, '\\"')
        .replace(/[\x00-\x1f]/g, function(c) {
          return "\\u00" + ((c.charCodeAt(0) < 0x10) ?
              '0' + c.charCodeAt(0).toString(16) :
              c.charCodeAt(0).toString(16));
        });
    },

    function outputObjectKeyValue_(key, value, first) {
      if ( ! first ) this.out(',');
      this.output(value);
    },

    function outputObjectKeyValues_(o) {
      var first = true;
      for ( var key in o ) {
        this.outputObjectKeyValue_(key, o[key], first);
        first = false;
      }
    },

    function outputSortedObjectKeyValues_(o) {
      var key, keys = [];

      for ( key in o ) keys.push(key);
      keys.sort();

      var first = true;
      for ( var i = 0 ; i < keys.length; i++ ) {
        key = keys[i];
        this.outputObjectKeyValue_(key, o[key], first);
        first = false;
      }
    },

    function outputPrimitive(val) {
      this.out(this.includeQuotes ? ('"' + val + '"') : val);
      return this;
    },

    {
      name: 'output',
      code: foam.mmethod({
        Undefined: function(o) { this.outputPrimitive(this.undefinedStr); },
        Null:      function(o) { this.outputPrimitive(null); },
        String:    function(o) { this.outputPrimitive(this.escape(o)); },
        Number:    function(o) { this.outputPrimitive(o); },
        Boolean:   function(o) { this.outputPrimitive(o); },
        Date:      function(o) { this.outputPrimitive(o); },
        FObject:   function(o) {
          if ( o.outputCSV ) {
            o.outputCSV(this)
            return;
          }

          // Outputs only the ordinal of ENUM
          if ( foam.core.AbstractEnum.isInstance(o) ) {
            this.outputPrimitive(o.ordinal).out(this.delimiter);
          } else {
            var ps = o.cls_.getAxiomsByClass(foam.core.Property);

            for ( var i = 0 ; i < ps.length ; i++ ) {
              this.outputProperty(o, ps[i]);
            }
          }

          this.removeTrailingComma();
        },
        Array: function(o) { /* Ignore arrays in CSV */ },
        Function: function(o) { /* Ignore functions in CSV */ },
        Object: function(o) {
          // TODO: How to test?
          if ( o.outputCSV ) {
            o.outputCSV(this);
          } else {
            if ( this.sortObjectKeys ) {
              this.outputSortedObjectKeyValues_(o);
            } else {
              this.outputObjectKeyValues_(o);
            }
          }
        }
      })
    },

    function objectify(className, s) {
      if ( ! s ) throw 'Invalid CSV Input'
      var lines = s.split('\n');

      if ( lines.length == 0 ) throw 'Insufficient CSV Input'

      // Trims quotes and splits CSV row into array
      var props = lines[0].slice(1, -1).split('","');
      var values = lines[1].slice(1, -1).split('","'); // Account for array of values (TODO?)

      // Calls for the creation of a new model
      return this.createModel(props, values, className);
    },

    function createModel(props, values, className) {
      foam.assert(props.length == values.length,
        'Invalid CSV Input, header and value rows must be the same number of cells');

      var cls = foam.lookup(className);

      // Checks if ENUM
      if ( props[0] == 'ordinal' ) {
        return cls.create({ ordinal: values[0] })
      }

      var model = cls.create();

      for ( var i = 0 ; i < props.length ; ++i ) {
        var p = props[i];
        var v = values[i];

        // Adds nested prop
        if ( p.includes('__') ) {
          p = p.split('__');
          foam.assert(p.length >= 2, 'Invalid CSV object nesting, properties of inner objects are identified by `__`');
          var prefix = p[0] + '__';

          for ( var j = i ; j <= props.length ; ++j ) {
            // If last element, or prefix no longer matches prop
            if ( ( j == props.length ) || ( ! props[j].startsWith(prefix) ) ) {
              // Creates a new model for the inner object
              var prop = model.cls_.getAxiomByName(p[0]);
              prop.set(model, createModel(props.slice(i, j).map(nestedProp => nestedProp.slice(prefix.length)),
                                        values.slice(i, j), prop.of.id));

              i = j - 1;
              break;
            }
          }
        // Adds regular prop
      } else {
          var prop = model.cls_.getAxiomByName(p);
          prop.set(model, v);
        }
      }

      return model;
    }
  ]
});

foam.LIB({
  name: 'foam.csv',

  constants: {
    Compact: foam.csv.Outputer.create(),
  },

  methods: [
    function stringify(o) {
      return foam.csv.Compact.stringify(o);
    },

    function objectify(className, s) {
      return foam.csv.Compact.objectify(className, s);
    }
  ]
});
<commit_msg>Updated escape to only escape " char<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.csv',
  name: 'Outputer',

  documentation: 'CSV Outputer.',

  properties: [
    {
      class: 'String',
      name: 'buf_',
      value: ''
    },
    {
      class: 'Boolean',
      name: 'includeQuotes',
      help: 'If true, values are quoted with the `"` char',
      value: true
    },
    {
      class: 'String',
      name: 'delimiter',
      value: ','
    },
    {
      class: 'String',
      name: 'nestedObjectSeperator',
      value: '__'
    },
    {
      class: 'StringArray',
      name: 'nestedObjectNames'
    },
    {
      class: 'String',
      name: 'nlStr',
      value: '\n'
    },
    {
      class: 'String',
      name: 'undefinedStr',
      value: ''
    },
    {
      class: 'Boolean',
      name: 'outputHeaderRow',
      value: true
    },
    {
      class: 'Function',
      name: 'propertyPredicate',
      value: function(o, p) { return ! p.transient; }
    },
    {
      class: 'Boolean',
      name: 'sortObjectKeys',
      value: false
    }
  ],

  methods: [
    function out() {
      for ( var i = 0 ; i < arguments.length ; i++ ) {
        this.buf_ += arguments[i];
      }

      return this;
    },

    function outputHeader(o) {
      if ( ! this.outputHeaderRow ) return;

      this.outputPropertyFilteredName(o);
      this.removeTrailingComma().out(this.nlStr);
    },

    function removeTrailingComma() {
      // Removes trailing comma
      if ( this.buf_.charAt(this.buf_.length - 1) == ',' ) this.buf_ = this.buf_.slice(0, -1);
      return this;
    },

    function stringify(o) {
      // Outputs object headers
      this.outputHeader(o);
      var ret = this.buf_;
      this.reset(); // reset to avoid retaining garbage

      // Outputs object values
      this.output(o);
      this.removeTrailingComma().out(this.nlStr);
      ret += this.buf_;
      this.reset();

      return ret;
    },

    function externalProperty(o, p) {
      if ( ! this.propertyPredicate(o, p) ) return false;
      if ( p.isDefaultValue(o[p.name]) ) return false;

      return true;
    },

    function outputHeaderTitle(o) {
      this.out('"').writePrefix().out(o).out('"').out(this.delimiter);
    },

    {
      name: 'outputPropertyFilteredName',
      code: foam.mmethod({
        // Is there a `switch` like fall through so the function call isn't unecessarily repeated?
        Undefined: function(o) { this.outputHeaderTitle(o); },
        Null:      function(o) { this.outputHeaderTitle(o); },
        String:    function(o) { this.outputHeaderTitle(o); },
        Number:    function(o) { this.outputHeaderTitle(o); },
        Boolean:   function(o) { this.outputHeaderTitle(o); },
        Date:      function(o) { this.outputHeaderTitle(o); },
        FObject:   function(o) {
          // Gets and recurses through object properties
          var ps = o.cls_.getAxiomsByClass(foam.core.Property);

          for ( var i = 0 ; i < ps.length ; i++ ) {
            this.outputPropertyName(o, ps[i]);
          }
        },
        Array: function(o) { /* Ignore arrays in CSV */ },
        Function: function(o) { /* Ignore functions in CSV */ },
        Object: function(o) {
          // TODO: How to test?
          if ( o.outputCSV ) {
            o.outputCSV(this);
          } else {
            if ( this.sortObjectKeys ) {
              this.outputSortedObjectKeyValues_(o);
            } else {
              this.outputObjectKeyValues_(o);
            }
          }
        }
      })
    },

    function outputPropertyName(o, p) {
      if ( ! this.externalProperty(o, p) ) return;

      // Checks if property is enum, or object with properties of its own
      // TODO: Is this correct way to check if object has relevant sub-properties
      if ( foam.core.AbstractEnum.isInstance( o[p.name] ) ) {
        this.outputPropertyFilteredName(p.name + "__ordinal");
      } else if ( p.of ) {
        this.start(p.name);
        this.outputPropertyFilteredName(o[p.name]);
        this.end();
      } else {
        this.outputPropertyFilteredName(p.name);
      }
    },

    function outputProperty(o, p) {
      if ( ! this.externalProperty(o, p) ) return;

      this.output(o[p.name]);
      this.out(this.delimiter);
    },

    function reset() {
      this.buf_ = '';
      return this;
    },

    // Starts a nested object, 1 more `__` with object name
    function start(objectName) {
      this.nestedObjectNames.push(objectName);
      return this;
    },

    function writePrefix() {
      for ( var i = 0 ; i < this.nestedObjectNames.length ; i++ ) {
        this.out(this.nestedObjectNames[i] + this.nestedObjectSeperator);
      }

      return this;
    },

    // End a nested object, 1 fewer `__` within object name
    function end() {
      this.nestedObjectNames.pop();
      return this;
    },

    function escape(str) {
      return str
        .replace(/"/g, '\\"');
    },

    function outputObjectKeyValue_(key, value, first) {
      if ( ! first ) this.out(',');
      this.output(value);
    },

    function outputObjectKeyValues_(o) {
      var first = true;
      for ( var key in o ) {
        this.outputObjectKeyValue_(key, o[key], first);
        first = false;
      }
    },

    function outputSortedObjectKeyValues_(o) {
      var key, keys = [];

      for ( key in o ) keys.push(key);
      keys.sort();

      var first = true;
      for ( var i = 0 ; i < keys.length; i++ ) {
        key = keys[i];
        this.outputObjectKeyValue_(key, o[key], first);
        first = false;
      }
    },

    function outputPrimitive(val) {
      this.out(this.includeQuotes ? ('"' + val + '"') : val);
      return this;
    },

    {
      name: 'output',
      code: foam.mmethod({
        Undefined: function(o) { this.outputPrimitive(this.undefinedStr); },
        Null:      function(o) { this.outputPrimitive(null); },
        String:    function(o) { this.outputPrimitive(this.escape(o)); },
        Number:    function(o) { this.outputPrimitive(o); },
        Boolean:   function(o) { this.outputPrimitive(o); },
        Date:      function(o) { this.outputPrimitive(o); },
        FObject:   function(o) {
          if ( o.outputCSV ) {
            o.outputCSV(this)
            return;
          }

          // Outputs only the ordinal of ENUM
          if ( foam.core.AbstractEnum.isInstance(o) ) {
            this.outputPrimitive(o.ordinal).out(this.delimiter);
          } else {
            var ps = o.cls_.getAxiomsByClass(foam.core.Property);

            for ( var i = 0 ; i < ps.length ; i++ ) {
              this.outputProperty(o, ps[i]);
            }
          }

          this.removeTrailingComma();
        },
        Array: function(o) { /* Ignore arrays in CSV */ },
        Function: function(o) { /* Ignore functions in CSV */ },
        Object: function(o) {
          // TODO: How to test?
          if ( o.outputCSV ) {
            o.outputCSV(this);
          } else {
            if ( this.sortObjectKeys ) {
              this.outputSortedObjectKeyValues_(o);
            } else {
              this.outputObjectKeyValues_(o);
            }
          }
        }
      })
    },

    function objectify(className, s) {
      if ( ! s ) throw 'Invalid CSV Input'
      var lines = s.split('\n');

      if ( lines.length == 0 ) throw 'Insufficient CSV Input'

      // Trims quotes and splits CSV row into array
      var props = lines[0].slice(1, -1).split('","');
      var values = lines[1].slice(1, -1).split('","'); // Account for array of values (TODO?)

      // Calls for the creation of a new model
      return this.createModel(props, values, className);
    },

    function createModel(props, values, className) {
      foam.assert(props.length == values.length,
        'Invalid CSV Input, header and value rows must be the same number of cells');

      var cls = foam.lookup(className);

      // Checks if ENUM
      if ( props[0] == 'ordinal' ) {
        return cls.create({ ordinal: values[0] })
      }

      var model = cls.create();

      for ( var i = 0 ; i < props.length ; ++i ) {
        var p = props[i];
        var v = values[i];

        // Adds nested prop
        if ( p.includes('__') ) {
          p = p.split('__');
          foam.assert(p.length >= 2, 'Invalid CSV object nesting, properties of inner objects are identified by `__`');
          var prefix = p[0] + '__';

          for ( var j = i ; j <= props.length ; ++j ) {
            // If last element, or prefix no longer matches prop
            if ( ( j == props.length ) || ( ! props[j].startsWith(prefix) ) ) {
              // Creates a new model for the inner object
              var prop = model.cls_.getAxiomByName(p[0]);
              prop.set(model, createModel(props.slice(i, j).map(nestedProp => nestedProp.slice(prefix.length)),
                                        values.slice(i, j), prop.of.id));

              i = j - 1;
              break;
            }
          }
        // Adds regular prop
      } else {
          var prop = model.cls_.getAxiomByName(p);
          prop.set(model, v);
        }
      }

      return model;
    }
  ]
});

foam.LIB({
  name: 'foam.csv',

  constants: {
    Compact: foam.csv.Outputer.create(),
  },

  methods: [
    function stringify(o) {
      return foam.csv.Compact.stringify(o);
    },

    function objectify(className, s) {
      return foam.csv.Compact.objectify(className, s);
    }
  ]
});
<|endoftext|>