From f25c4ab81b5dba847bc9f8c5d266a19f7cc627fa Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 21 Feb 2018 15:08:56 +0530 Subject: [PATCH] print formats, momentjs, markdown, nunjucks --- .eslintrc | 3 +- client/desk/formmodal.js | 4 +- client/desk/formpage.js | 13 +-- client/desk/index.js | 54 ++++++----- client/desk/printpage.js | 43 +++++++++ client/index.js | 4 +- client/style/style.scss | 10 ++ client/ui/modal.js | 2 +- client/view/controls/date.js | 21 ++++- client/view/controls/table.js | 2 +- client/view/form.js | 7 ++ client/view/list.js | 36 +++++-- config/rollup.config.app.js | 2 +- index.js | 9 +- model/document.js | 11 ++- models/doctype/PrintFormat/PrintFormat.js | 1 + .../doctype/SystemSettings/SystemSettings.js | 27 +++--- package.json | 6 +- utils/format.js | 18 +++- yarn.lock | 94 ++++++++++++++++++- 20 files changed, 289 insertions(+), 78 deletions(-) diff --git a/.eslintrc b/.eslintrc index c5eb518a..b8039f12 100644 --- a/.eslintrc +++ b/.eslintrc @@ -19,7 +19,8 @@ "describe": true, "before": true, "after": true, - "it": true + "it": true, + "io": true }, "rules": { diff --git a/client/desk/formmodal.js b/client/desk/formmodal.js index b77a75d2..e6d5c5f8 100644 --- a/client/desk/formmodal.js +++ b/client/desk/formmodal.js @@ -8,6 +8,7 @@ module.exports = class FormModal extends Modal { } async showWith(doctype, name) { + if (!name) name = doctype; this.show(); await this.setDoc(doctype, name); } @@ -17,7 +18,8 @@ module.exports = class FormModal extends Modal { this.makeForm(); } await this.form.setDoc(doctype, name); - this.modal.querySelector('input').focus(); + let input = this.modal.querySelector('input') || this.modal.querySelector('select'); + input && input.focus(); } makeForm() { diff --git a/client/desk/formpage.js b/client/desk/formpage.js index 29e4bf26..82607e49 100644 --- a/client/desk/formpage.js +++ b/client/desk/formpage.js @@ -13,14 +13,11 @@ module.exports = class FormPage extends Page { doctype: doctype, parent: this.body, container: this, - actions: ['submit', 'delete', 'duplicate', 'settings'] + actions: ['submit', 'delete', 'duplicate', 'settings', 'print'] }); this.on('show', async (params) => { await this.showDoc(params.doctype, params.name); - if (frappe.desk.center && !frappe.desk.center.activePage) { - frappe.desk.showListPage(doctype); - } }); // if name is different after saving, change the route @@ -41,15 +38,9 @@ module.exports = class FormPage extends Page { async showDoc(doctype, name) { try { await this.form.setDoc(doctype, name); - this.setActiveListRow(name); + frappe.desk.setActiveDoc(this.form.doc); } catch (e) { this.renderError(e.status_code, e.message); } } - - setActiveListRow(name) { - if (frappe.desk.pages.lists[this.doctype]) { - frappe.desk.pages.lists[this.doctype].list.setActiveListRow(name); - } - } } diff --git a/client/desk/index.js b/client/desk/index.js index a03d208d..d573e07d 100644 --- a/client/desk/index.js +++ b/client/desk/index.js @@ -2,11 +2,13 @@ const frappe = require('frappejs'); // const Search = require('./search'); const Router = require('frappejs/common/router'); const Page = require('frappejs/client/view/page'); -const FormPage = require('frappejs/client/desk/formpage'); -const ListPage = require('frappejs/client/desk/listpage'); -// const Navbar = require('./navbar'); + +const views = {}; +views.Form = require('frappejs/client/desk/formpage'); +views.List = require('frappejs/client/desk/listpage'); +views.Print = require('frappejs/client/desk/printpage'); +views.FormModal = require('frappejs/client/desk/formmodal'); const DeskMenu = require('./menu'); -const FormModal = require('frappejs/client/desk/formmodal'); module.exports = class Desk { constructor(columns=2) { @@ -20,9 +22,8 @@ module.exports = class Desk { this.makeColumns(columns); this.pages = { - lists: {}, - forms: {}, - formModals: {} + formModals: {}, + List: {} }; this.routeItems = {}; @@ -69,12 +70,15 @@ module.exports = class Desk { }) frappe.router.add('list/:doctype', async (params) => { - await this.showListPage(params.doctype); + await this.showViewPage('List', params.doctype); }); frappe.router.add('edit/:doctype/:name', async (params) => { - let page = this.getFormPage(params.doctype); - await page.show(params); + await this.showViewPage('Form', params.doctype, params); + }) + + frappe.router.add('print/:doctype/:name', async (params) => { + await this.showViewPage('Print', params.doctype, params); }) frappe.router.add('new/:doctype', async (params) => { @@ -94,29 +98,31 @@ module.exports = class Desk { } - async showListPage(doctype) { - if (!this.pages.lists[doctype]) { - this.pages.lists[doctype] = new ListPage(doctype); - } - await this.pages.lists[doctype].show(doctype); - return this.pages.lists[doctype]; - } - - getFormPage(doctype) { - if (!this.pages.forms[doctype]) { - this.pages.forms[doctype] = new FormPage(doctype); - } - return this.pages.forms[doctype]; + async showViewPage(view, doctype, params) { + if (!params) params = doctype; + if (!this.pages[view]) this.pages[view] = {}; + if (!this.pages[view][doctype]) this.pages[view][doctype] = new views[view](doctype); + await this.pages[view][doctype].show(params); } async showFormModal(doctype, name) { if (!this.pages.formModals[doctype]) { - this.pages.formModals[doctype] = new FormModal(doctype); + this.pages.formModals[doctype] = new views.FormModal(doctype); } await this.pages.formModals[doctype].showWith(doctype, name); return this.pages.formModals[doctype]; } + async setActiveDoc(doc) { + this.activeDoc = doc; + if (frappe.desk.center && !frappe.desk.center.activePage) { + await frappe.desk.showViewPage('List', doc.doctype); + } + if (frappe.desk.pages.List[doc.doctype]) { + frappe.desk.pages.List[doc.doctype].list.setActiveListRow(doc.name); + } + } + setActive(item) { let className = 'list-group-item-secondary'; let activeItem = this.sidebarList.querySelector('.' + className); diff --git a/client/desk/printpage.js b/client/desk/printpage.js index e69de29b..dce03267 100644 --- a/client/desk/printpage.js +++ b/client/desk/printpage.js @@ -0,0 +1,43 @@ +const Page = require('frappejs/client/view/page'); +const frappe = require('frappejs'); +const nunjucks = require('nunjucks/browser/nunjucks'); + +nunjucks.configure({ autoescape: false }); + +module.exports = class PrintPage extends Page { + constructor(doctype) { + let meta = frappe.getMeta(doctype); + super({title: `View ${meta.name}`}); + this.meta = meta; + this.doctype = doctype; + + this.on('show', async (params) => { + this.name = params.name; + if (this.meta.print) { + // render + this.renderTemplate(); + } else { + this.renderError('No Print Settings'); + } + }); + + this.addButton(frappe._('Edit'), 'primary', () => { + frappe.router.setRoute('edit', this.doctype, this.name) + }); + } + + async renderTemplate() { + this.printFormat = await frappe.getDoc('PrintFormat', this.meta.print.printFormat); + let doc = await frappe.getDoc(this.doctype, this.name); + let context = {doc: doc, frappe: frappe}; + + frappe.desk.setActiveDoc(doc); + + try { + this.body.innerHTML = ``; + } catch (e) { + this.renderError('Template Error', e); + throw e; + } + } +} diff --git a/client/index.js b/client/index.js index bf7e4a2a..e5bd3efd 100644 --- a/client/index.js +++ b/client/index.js @@ -17,7 +17,9 @@ module.exports = { this.socket = io.connect('http://localhost:8000'); // eslint-disable-line frappe.db.bindSocketClient(this.socket); - frappe.flags.cache_docs = true; + frappe.flags.cacheDocs = true; + + await frappe.getSingle('SystemSettings'); frappe.desk = new Desk(columns); await frappe.login(); diff --git a/client/style/style.scss b/client/style/style.scss index 0efc7eec..005b018c 100644 --- a/client/style/style.scss +++ b/client/style/style.scss @@ -9,6 +9,7 @@ $spacer-1: 0.25rem; $spacer-2: 0.5rem; $spacer-3: 1rem; $spacer-4: 2rem; +$spacer-5: 3rem; $page-width: 500px; @@ -192,3 +193,12 @@ mark { } } +.print-page { + padding: $spacer-5; + line-height: 1.8; + + td, th { + padding: $spacer-2; + } +} + diff --git a/client/ui/modal.js b/client/ui/modal.js index e3209d36..5806ffc2 100644 --- a/client/ui/modal.js +++ b/client/ui/modal.js @@ -1,5 +1,5 @@ const $ = require('jquery'); -const bootstrap = require('bootstrap'); +const bootstrap = require('bootstrap'); // eslint-disable-line const Observable = require('frappejs/utils/observable'); module.exports = class Modal extends Observable { diff --git a/client/view/controls/date.js b/client/view/controls/date.js index cee65487..f71f764e 100644 --- a/client/view/controls/date.js +++ b/client/view/controls/date.js @@ -1,14 +1,31 @@ const flatpickr = require('flatpickr'); const BaseControl = require('./base'); +const frappe = require('frappejs'); class DateControl extends BaseControl { make() { + let dateFormat = { + 'yyyy-mm-dd': 'Y-m-d', + 'dd/mm/yyyy': 'd/m/Y', + 'dd-mm-yyyy': 'd-m-Y', + 'mm/dd/yyyy': 'm/d/Y', + 'mm-dd-yyyy': 'm-d-Y' + } + let altFormat = dateFormat[frappe.SystemSettings.dateFormat]; + super.make(); this.input.setAttribute('type', 'text'); - flatpickr.default(this.input, { - dateFormat: "Y-m-d" + this.flatpickr = flatpickr.default(this.input, { + altInput: true, + altFormat: altFormat, + dateFormat:'Y-m-d' }); } + + setInputValue(value) { + super.setInputValue(value); + this.flatpickr.setDate(value); + } }; module.exports = DateControl; \ No newline at end of file diff --git a/client/view/controls/table.js b/client/view/controls/table.js index 89931498..3d19aac5 100644 --- a/client/view/controls/table.js +++ b/client/view/controls/table.js @@ -89,7 +89,7 @@ class TableControl extends BaseControl { control.parentControl = this; control.doc = this.doc[this.fieldname][rowIndex]; control.set_focus(); - return control.setInputValue(value); + return control.setInputValue(control.doc[column.id]); }, setValue: async (value, rowIndex, column) => { control.handleChange(); diff --git a/client/view/form.js b/client/view/form.js index 1d8b3b92..583690cc 100644 --- a/client/view/form.js +++ b/client/view/form.js @@ -49,6 +49,13 @@ module.exports = class BaseForm extends Observable { }) } + if (this.meta.print && this.actions.includes('print')) { + let menu = this.container.getDropdown(frappe._('Menu')); + menu.addItem(frappe._("Print"), async (e) => { + await frappe.router.setRoute('print', this.doctype, this.doc.name); + }); + } + if (!this.meta.isSingle && this.actions.includes('delete')) { let menu = this.container.getDropdown(frappe._('Menu')); menu.addItem(frappe._("Delete"), async (e) => { diff --git a/client/view/list.js b/client/view/list.js index fa447f6b..96ab26a7 100644 --- a/client/view/list.js +++ b/client/view/list.js @@ -124,7 +124,11 @@ module.exports = class BaseList { } async showItem(name) { - await frappe.router.setRoute('edit', this.doctype, name); + if (this.meta.print) { + await frappe.router.setRoute('print', this.doctype, name); + } else { + await frappe.router.setRoute('edit', this.doctype, name); + } } getCheckedRowNames() { @@ -188,14 +192,29 @@ module.exports = class BaseList { } bindKeys() { - keyboard.bindKey(this.body, 'up', async (e) => await this.move('up')); - keyboard.bindKey(this.body, 'down', async (e) => await this.move('down')) + keyboard.bindKey(this.body, 'up', () => this.move('up')); + keyboard.bindKey(this.body, 'down', () => this.move('down')) keyboard.bindKey(this.body, 'right', () => { if (frappe.desk.body.activePage) { frappe.desk.body.activePage.body.querySelector('input').focus(); } - }) + }); + + keyboard.bindKey(this.body, 'n', (e) => { + frappe.router.setRoute('new', this.doctype); + e.preventDefault(); + }); + + keyboard.bindKey(this.body, 'x', async (e) => { + let activeListRow = this.getActiveListRow(); + if (activeListRow && activeListRow.docName) { + e.preventDefault(); + await frappe.db.delete(this.doctype, activeListRow.docName); + frappe.desk.body.activePage.hide(); + } + }); + } async move(direction) { @@ -225,15 +244,14 @@ module.exports = class BaseList { } setActiveListRow(name) { - let activeListRow = this.body.querySelector('.list-row.active'); + let activeListRow = this.getActiveListRow(); if (activeListRow) { activeListRow.classList.remove('active'); } if (!name) { // get name from active page - name = frappe.desk.body.activePage && frappe.desk.body.activePage.form.doc - && frappe.desk.body.activePage.form.doc.name; + name = frappe.desk.activeDoc && frappe.desk.activeDoc.name; } if (name) { @@ -245,5 +263,7 @@ module.exports = class BaseList { } } - + getActiveListRow() { + return this.body.querySelector('.list-row.active'); + } }; \ No newline at end of file diff --git a/config/rollup.config.app.js b/config/rollup.config.app.js index be076100..71657f4c 100644 --- a/config/rollup.config.app.js +++ b/config/rollup.config.app.js @@ -4,7 +4,7 @@ module.exports = { file: './dist/js/bundle.js', format: 'iife', name: 'desk', - globals: ['io'] // for socketio client, which is imported directly + globals: ['io', 'nunjucks'] // for socketio client, which is imported directly }, plugins: [ require('rollup-plugin-commonjs')(), diff --git a/index.js b/index.js index ecac3598..fa96f172 100644 --- a/index.js +++ b/index.js @@ -21,7 +21,7 @@ module.exports = { this.views = {}; this.docs = {}; this.flags = { - cache_docs: false + cacheDocs: false } }, @@ -40,7 +40,7 @@ module.exports = { }, addToCache(doc) { - if (!this.flags.cache_docs) return; + if (!this.flags.cacheDocs) return; // add to `docs` cache if (doc.doctype && doc.name) { @@ -48,6 +48,11 @@ module.exports = { this.docs[doc.doctype] = {}; } this.docs[doc.doctype][doc.name] = doc; + + // singles available as first level objects too + if (doc.doctype === doc.name) { + this[doc.name] = doc; + } } }, diff --git a/model/document.js b/model/document.js index 86a95a48..e35bbea9 100644 --- a/model/document.js +++ b/model/document.js @@ -75,10 +75,10 @@ module.exports = class BaseDocument extends Observable { setDefaults() { for (let field of this.meta.fields) { - if (field.fieldtype === 'Date') { - this[field.fieldname] = (new Date()).toISOString().substr(0, 10); - } else if (!this[field.fieldname]) { - if(field.default) { + if (this[field.fieldname]===null || this[field.fieldname]===undefined) { + if (field.fieldtype === 'Date') { + this[field.fieldname] = (new Date()).toISOString().substr(0, 10); + } else if(field.default) { this[field.fieldname] = field.default; } } @@ -141,6 +141,9 @@ module.exports = class BaseDocument extends Observable { let data = await frappe.db.get(this.doctype, this.name); if (data.name) { this.syncValues(data); + if (this.meta.isSingle) { + this.setDefaults(); + } } else { throw new frappe.errors.NotFound(`Not Found: ${this.doctype} ${this.name}`); } diff --git a/models/doctype/PrintFormat/PrintFormat.js b/models/doctype/PrintFormat/PrintFormat.js index 746f7fc6..124f58d6 100644 --- a/models/doctype/PrintFormat/PrintFormat.js +++ b/models/doctype/PrintFormat/PrintFormat.js @@ -1,5 +1,6 @@ module.exports = { name: "PrintFormat", + label: "Print Format", doctype: "DocType", isSingle: 0, isChild: 0, diff --git a/models/doctype/SystemSettings/SystemSettings.js b/models/doctype/SystemSettings/SystemSettings.js index 3b07b440..970a6d58 100644 --- a/models/doctype/SystemSettings/SystemSettings.js +++ b/models/doctype/SystemSettings/SystemSettings.js @@ -1,21 +1,24 @@ module.exports = { - "name": "SystemSettings", - "doctype": "DocType", - "isSingle": 1, - "isChild": 0, - "keywordFields": [], - "fields": [ + name: "SystemSettings", + label: "System Settings", + doctype: "DocType", + isSingle: 1, + isChild: 0, + keywordFields: [], + fields: [ { - "fieldname": "dateFormat", - "label": "Date Format", - "fieldtype": "Select", - "options": [ + fieldname: "dateFormat", + label: "Date Format", + fieldtype: "Select", + options: [ "dd/mm/yyyy", "mm/dd/yyyy", "dd-mm-yyyy", - "mm-dd-yyyy" + "mm-dd-yyyy", + "yyyy-mm-dd" ], - "required": 1 + default: "yyyy-mm-dd", + required: 1 } ] } \ No newline at end of file diff --git a/package.json b/package.json index f68777c0..846ed84b 100644 --- a/package.json +++ b/package.json @@ -12,23 +12,21 @@ "awesomplete": "^1.1.2", "body-parser": "^1.18.2", "bootstrap": "^4.0.0", - "bufferutil": "^3.0.3", "clusterize.js": "^0.18.0", "codemirror": "^5.35.0", "commander": "^2.13.0", "express": "^4.16.2", "flatpickr": "^4.3.2", "jquery": "^3.3.1", + "moment": "^2.20.1", "mysql": "^2.15.0", "node-fetch": "^1.7.3", "nunjucks": "^3.1.0", "popper.js": "^1.12.9", - "rollup-plugin-ignore": "^1.0.3", + "showdown": "^1.8.6", "socket.io": "^2.0.4", - "socket.io-client": "^2.0.4", "sortablejs": "^1.7.0", "sqlite3": "^3.1.13", - "utf-8-validate": "^4.0.0", "walk": "^2.3.9" }, "repository": { diff --git a/utils/format.js b/utils/format.js index 11d493e1..4638367a 100644 --- a/utils/format.js +++ b/utils/format.js @@ -1,13 +1,23 @@ const number_format = require('./number_format'); +const markdown = new (require('showdown').Converter)(); +const moment = require('moment'); +const frappe = require('frappejs'); module.exports = { format(value, field) { + if (typeof field === 'string') { + field = {fieldtype: field}; + } + if (field.fieldtype==='Currency') { value = number_format.format_number(value); - } else if (field.fieldtype==='Date') { - if (value instanceof Date) { - value = value.toISOString().substr(0, 10); - } + + } else if (field.fieldtype === 'Text') { + value = markdown.makeHtml(value); + + } else if (field.fieldtype === 'Date') { + value = moment(value).format(frappe.SystemSettings.dateFormat.toUpperCase()); + } else { if (value===null || value===undefined) { value = ''; diff --git a/yarn.lock b/yarn.lock index ba0df5eb..aa64449e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -533,7 +533,7 @@ camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" -camelcase@^4.0.0: +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -646,6 +646,14 @@ cliui@^3.0.3, cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" +cliui@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc" + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + clone@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" @@ -1478,6 +1486,12 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + flat-cache@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" @@ -2436,6 +2450,13 @@ loader-utils@^0.2.16: json5 "^0.5.0" object-assign "^4.0.1" +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + lodash.assign@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" @@ -2527,6 +2548,12 @@ media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + meow@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" @@ -2636,6 +2663,10 @@ mocha@^4.1.0: mkdirp "0.5.1" supports-color "4.4.0" +moment@^2.20.1: + version "2.20.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -2912,6 +2943,14 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -2927,6 +2966,22 @@ p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" +p-limit@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -2983,6 +3038,10 @@ path-exists@^2.0.0: dependencies: pinkie-promise "^2.0.0" +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -4190,6 +4249,12 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" +showdown@^1.8.6: + version "1.8.6" + resolved "https://registry.yarnpkg.com/showdown/-/showdown-1.8.6.tgz#91ea4ee3b7a5448aaca6820a4e27e690c6ad771c" + dependencies: + yargs "^10.0.3" + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -4749,6 +4814,10 @@ which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + which@1, which@^1.2.9: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" @@ -4855,6 +4924,29 @@ yargs-parser@^5.0.0: dependencies: camelcase "^3.0.0" +yargs-parser@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" + dependencies: + camelcase "^4.1.0" + +yargs@^10.0.3: + version "10.1.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5" + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^8.1.0" + yargs@^3.32.0: version "3.32.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"