diff --git a/db/changes/10340-summer/00-ACL.sql b/db/changes/10340-summer/00-ACL.sql index 768892d53..04e050add 100644 --- a/db/changes/10340-summer/00-ACL.sql +++ b/db/changes/10340-summer/00-ACL.sql @@ -2,7 +2,13 @@ DELETE FROM `salix`.`ACL` WHERE id = 189; DELETE FROM `salix`.`ACL` WHERE id = 188; UPDATE `salix`.`ACL` tdms SET tdms.accessType = '*' WHERE tdms.id = 165; + INSERT INTO salix.ACL (model, principalId, property, accessType) - VALUES ('InvoiceInTax','administrative', '*', '*'); -INSERT INTO salix.ACL (model, principalId, property, accessType) - VALUES ('InvoiceInLog','administrative', '*', 'READ'); \ No newline at end of file + VALUES ('InvoiceInTax','administrative', '*', '*'), + VALUES ('InvoiceInLog','administrative', '*', 'READ'); + +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('InvoiceOut', 'createManualInvoice', 'WRITE', 'ALLOW', 'ROLE', 'invoicing'), + ('InvoiceOut', 'globalInvoicing', 'WRITE', 'ALLOW', 'ROLE', 'invoicing'); + diff --git a/db/changes/10340-summer/00-invoiceFromClient.sql b/db/changes/10340-summer/00-invoiceFromClient.sql new file mode 100644 index 000000000..d198e873d --- /dev/null +++ b/db/changes/10340-summer/00-invoiceFromClient.sql @@ -0,0 +1,21 @@ +drop procedure `vn`.`invoiceFromClient`; + +DELIMITER $$ +$$ +create + definer = root@`%` procedure `vn`.`invoiceFromClient`(IN vMaxTicketDate datetime, IN vClientFk INT, IN vCompanyFk INT) +BEGIN + DECLARE vMinTicketDate DATE DEFAULT TIMESTAMPADD(YEAR, -3, CURDATE()); + SET vMaxTicketDate = util.dayend(vMaxTicketDate); + + DROP TEMPORARY TABLE IF EXISTS `ticketToInvoice`; + CREATE TEMPORARY TABLE `ticketToInvoice` + (PRIMARY KEY (`id`)) + ENGINE = MEMORY + SELECT id FROM ticket t + WHERE t.clientFk = vClientFk + AND t.refFk IS NULL + AND t.companyFk = vCompanyFk + AND (t.shipped BETWEEN vMinTicketDate AND vMaxTicketDate); +END;;$$ +DELIMITER ; diff --git a/db/changes/10340-summer/00-invoiceOut_newFromClient.sql b/db/changes/10340-summer/00-invoiceOut_newFromClient.sql new file mode 100644 index 000000000..b4d4f916b --- /dev/null +++ b/db/changes/10340-summer/00-invoiceOut_newFromClient.sql @@ -0,0 +1,45 @@ +drop procedure `vn`.`invoiceOut_newFromClient`; + +DELIMITER $$ +$$ +create + definer = root@`%` procedure `vn`.`invoiceOut_newFromClient`(IN vClientFk int, IN vSerial char(2), IN vMaxShipped date, + IN vCompanyFk int, IN vTaxArea varchar(25), + IN vRef varchar(25), OUT vInvoiceId int) +BEGIN +/** + * Factura los tickets de un cliente hasta una fecha dada + * @param vClientFk Id del cliente a facturar + * @param vSerial Serie de factura + * @param vMaxShipped Fecha hasta la cual cogera tickets para facturar + * @param vCompanyFk Id de la empresa desde la que se factura + * @param vTaxArea Tipo de iva en relacion a la empresa y al cliente, NULL por defecto + * @param vRef Referencia de la factura en caso que se quiera forzar, NULL por defecto + * @return vInvoiceId factura + */ + + DECLARE vIsRefEditable BOOLEAN; + + IF vRef IS NOT NULL THEN + SELECT isRefEditable INTO vIsRefEditable + FROM invoiceOutSerial + WHERE code = vSerial; + + IF NOT vIsRefEditable THEN + CALL util.throw('serial non editable'); + END IF; + END IF; + + CALL invoiceFromClient(vMaxShipped, vClientFk, vCompanyFk); + CALL invoiceOut_new(vSerial, CURDATE(), vTaxArea, vInvoiceId); + + UPDATE invoiceOut + SET `ref` = vRef + WHERE id = vInvoiceId + AND vRef IS NOT NULL; + + IF vSerial <> 'R' AND NOT ISNULL(vInvoiceId) AND vInvoiceId <> 0 THEN + CALL invoiceOutBooking(vInvoiceId); + END IF; +END;;$$ +DELIMITER ; diff --git a/db/changes/10340-summer/00-invoiceOut_newFromTicket.sql b/db/changes/10340-summer/00-invoiceOut_newFromTicket.sql new file mode 100644 index 000000000..15be3d83c --- /dev/null +++ b/db/changes/10340-summer/00-invoiceOut_newFromTicket.sql @@ -0,0 +1,38 @@ +drop procedure `vn`.`invoiceOut_newFromTicket`; + +DELIMITER $$ +$$ +create + definer = root@`%` procedure `vn`.`invoiceOut_newFromTicket`(IN vTicketFk int, IN vSerial char(2), IN vTaxArea varchar(25), + IN vRef varchar(25), OUT vInvoiceId int) +BEGIN +/** + * Factura un ticket + * @param vTicketFk Id del ticket + * @param vSerial Serie de factura + * @param vTaxArea Area de la factura en caso de querer forzarlo, + * en la mayoria de los casos poner NULL + * @return vInvoiceId + */ + DECLARE vIsRefEditable BOOLEAN; + CALL invoiceFromTicket(vTicketFk); + CALL invoiceOut_new(vSerial, CURDATE(), vTaxArea, vInvoiceId); + + IF vRef IS NOT NULL THEN + SELECT isRefEditable INTO vIsRefEditable + FROM invoiceOutSerial + WHERE code = vSerial; + IF NOT vIsRefEditable THEN + CALL util.throw('serial non editable'); + END IF; + + UPDATE invoiceOut + SET `ref` = vRef + WHERE id = vInvoiceId; + END IF; + + IF vSerial <> 'R' AND NOT ISNULL(vInvoiceId) AND vInvoiceId <> 0 THEN + CALL invoiceOutBooking(vInvoiceId); + END IF; +END;;$$ +DELIMITER ; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 65d68ab21..867a830df 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -127,11 +127,12 @@ INSERT INTO `vn`.`warehouseAlias`(`id`, `name`) INSERT INTO `vn`.`warehouse`(`id`, `name`, `code`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`, `hasStowaway`, `hasDms`, `hasComission`, `aliasFk`, `countryFk`) VALUES - (1, 'Warehouse One', 'ALG', 1, 1, 1, 1, 1, 1, 1, 2, 1), - (2, 'Warehouse Two', NULL, 1, 1, 1, 1, 0, 0, 1, 2, 13), - (3, 'Warehouse Three', NULL, 1, 1, 1, 1, 0, 0, 0, 2, 1), - (4, 'Warehouse Four', NULL, 1, 1, 1, 1, 0, 0, 0, 2, 1), - (5, 'Warehouse Five', NULL, 1, 1, 1, 1, 0, 0, 0, 2, 1); + (1, 'Warehouse One', 'ALG', 1, 1, 1, 1, 1, 1, 1, 2, 1), + (2, 'Warehouse Two', NULL, 1, 1, 1, 1, 0, 0, 1, 2, 13), + (3, 'Warehouse Three', NULL, 1, 1, 1, 1, 0, 0, 0, 2, 1), + (4, 'Warehouse Four', NULL, 1, 1, 1, 1, 0, 0, 0, 2, 1), + (5, 'Warehouse Five', NULL, 1, 1, 1, 1, 0, 0, 0, 2, 1), + (13, 'Inventory', NULL, 1, 1, 1, 0, 0, 0, 0, 2, 1); INSERT INTO `vn`.`sector`(`id`, `description`, `warehouseFk`, `isPreviousPreparedByPacking`, `code`, `pickingPlacement`, `path`) VALUES diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index a561a08cf..d7929237f 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -915,6 +915,19 @@ export default { invoiceOutIndex: { topbarSearch: 'vn-searchbar', searchResult: 'vn-invoice-out-index vn-card > vn-table > div > vn-tbody > a.vn-tr', + createInvoice: 'vn-invoice-out-index > div > vn-vertical > vn-button > button vn-icon[icon="add"]', + createManualInvoice: 'vn-item[name="manualInvoice"]', + createGlobalInvoice: 'vn-item[name="globalInvoice"]', + manualInvoiceForm: '.vn-invoice-out-manual', + manualInvoiceTicket: 'vn-autocomplete[ng-model="$ctrl.invoice.ticketFk"]', + manualInvoiceClient: 'vn-autocomplete[ng-model="$ctrl.invoice.clientFk"]', + manualInvoiceSerial: 'vn-autocomplete[ng-model="$ctrl.invoice.serial"]', + manualInvoiceTaxArea: 'vn-autocomplete[ng-model="$ctrl.invoice.taxArea"]', + saveInvoice: 'button[response="accept"]', + globalInvoiceForm: '.vn-invoice-out-global-invoicing', + globalInvoiceDate: '[ng-model="$ctrl.invoice.invoiceDate"]', + globalInvoiceFromClient: '[ng-model="$ctrl.invoice.fromClientId"]', + globalInvoiceToClient: '[ng-model="$ctrl.invoice.toClientId"]', }, invoiceOutDescriptor: { moreMenu: 'vn-invoice-out-descriptor vn-icon-button[icon=more_vert]', diff --git a/e2e/paths/09-invoice-out/03_manualInvoice.spec.js b/e2e/paths/09-invoice-out/03_manualInvoice.spec.js new file mode 100644 index 000000000..396f84bfb --- /dev/null +++ b/e2e/paths/09-invoice-out/03_manualInvoice.spec.js @@ -0,0 +1,65 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +describe('InvoiceOut manual invoice path', () => { + let browser; + let page; + + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('administrative', 'invoiceOut'); + }); + + afterAll(async() => { + await browser.close(); + }); + + it('should open the manual invoice form', async() => { + await page.waitToClick(selectors.invoiceOutIndex.createInvoice); + await page.waitToClick(selectors.invoiceOutIndex.createManualInvoice); + await page.waitForSelector(selectors.invoiceOutIndex.manualInvoiceForm); + }); + + it('should create an invoice from a ticket', async() => { + await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTicket, '7'); + await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceSerial, 'Global nacional'); + await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTaxArea, 'national'); + await page.waitToClick(selectors.invoiceOutIndex.saveInvoice); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('Data saved!'); + }); + + it(`should have been redirected to the created invoice summary`, async() => { + await page.waitForState('invoiceOut.card.summary'); + }); + + it(`should navigate back to the invoiceOut index`, async() => { + await page.waitToClick(selectors.globalItems.applicationsMenuButton); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); + await page.waitToClick(selectors.globalItems.invoiceOutButton); + await page.waitForSelector(selectors.invoiceOutIndex.topbarSearch); + await page.waitForState('invoiceOut.index'); + }); + + it('should now open the manual invoice form', async() => { + await page.waitToClick(selectors.invoiceOutIndex.createInvoice); + await page.waitToClick(selectors.invoiceOutIndex.createManualInvoice); + await page.waitForSelector(selectors.invoiceOutIndex.manualInvoiceForm); + }); + + it('should create an invoice from a client', async() => { + await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceClient, 'Charles Xavier'); + await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceSerial, 'Global nacional'); + await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTaxArea, 'national'); + await page.waitToClick(selectors.invoiceOutIndex.saveInvoice); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('Data saved!'); + }); + + it(`should have been redirected to the created invoice summary`, async() => { + await page.waitForState('invoiceOut.card.summary'); + }); +}); diff --git a/e2e/paths/09-invoice-out/04_globalInvoice.spec.js b/e2e/paths/09-invoice-out/04_globalInvoice.spec.js new file mode 100644 index 000000000..b62c889db --- /dev/null +++ b/e2e/paths/09-invoice-out/04_globalInvoice.spec.js @@ -0,0 +1,51 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +describe('InvoiceOut global invoice path', () => { + let browser; + let page; + + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('administrative', 'invoiceOut'); + await page.waitToClick('[icon="search"]'); + await page.waitForTimeout(1000); // index search needs time to return results + }); + + afterAll(async() => { + await browser.close(); + }); + + let invoicesBefore; + + it('should count the amount of invoices listed before globla invoces are made', async() => { + invoicesBefore = await page.countElement(selectors.invoiceOutIndex.searchResult); + + expect(invoicesBefore).toBeGreaterThanOrEqual(4); + }); + + it('should open the global invoice form', async() => { + await page.waitToClick(selectors.invoiceOutIndex.createInvoice); + await page.waitToClick(selectors.invoiceOutIndex.createGlobalInvoice); + await page.waitForSelector(selectors.invoiceOutIndex.globalInvoiceForm); + }); + + it('should create a global invoice for charles xavier today', async() => { + await page.pickDate(selectors.invoiceOutIndex.globalInvoiceDate); + await page.autocompleteSearch(selectors.invoiceOutIndex.globalInvoiceFromClient, 'Petter Parker'); + await page.autocompleteSearch(selectors.invoiceOutIndex.globalInvoiceToClient, 'Petter Parker'); + await page.waitToClick(selectors.invoiceOutIndex.saveInvoice); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('Data saved!'); + }); + + it('should count the amount of invoices listed after globla invocing', async() => { + await page.waitToClick('[icon="search"]'); + await page.waitForTimeout(1000); // index search needs time to return results + const currentInvoices = await page.countElement(selectors.invoiceOutIndex.searchResult); + + expect(currentInvoices).toBeGreaterThan(invoicesBefore); + }); +}); diff --git a/front/package-lock.json b/front/package-lock.json index f49a67194..b62e8179e 100644 --- a/front/package-lock.json +++ b/front/package-lock.json @@ -14,6 +14,7 @@ "angular-animate": "^1.7.8", "angular-translate": "^2.18.1", "angular-translate-loader-partial": "^2.18.1", + "croppie": "^2.6.5", "js-yaml": "^3.13.1", "mg-crud": "^1.1.2", "oclazyload": "^0.6.3", @@ -77,6 +78,11 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/croppie": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/croppie/-/croppie-2.6.5.tgz", + "integrity": "sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ==" + }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -200,6 +206,11 @@ "sprintf-js": "~1.0.2" } }, + "croppie": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/croppie/-/croppie-2.6.5.tgz", + "integrity": "sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ==" + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", diff --git a/front/package.json b/front/package.json index 3ef90bf41..89088cd7a 100644 --- a/front/package.json +++ b/front/package.json @@ -14,6 +14,7 @@ "angular-animate": "^1.7.8", "angular-translate": "^2.18.1", "angular-translate-loader-partial": "^2.18.1", + "croppie": "^2.6.5", "js-yaml": "^3.13.1", "mg-crud": "^1.1.2", "oclazyload": "^0.6.3", diff --git a/front/salix/components/upload-photo/croppie.scss b/front/salix/components/upload-photo/croppie.scss new file mode 100644 index 000000000..1d736f896 --- /dev/null +++ b/front/salix/components/upload-photo/croppie.scss @@ -0,0 +1,252 @@ +@import "./variables"; + + +.croppie-container { + width: 100%; + height: 100%; +} + +.croppie-container .cr-image { + z-index: -1; + position: absolute; + top: 0; + left: 0; + transform-origin: 0 0; + max-height: none; + max-width: none; +} + +.croppie-container .cr-boundary { + border: 2px solid $color-primary; + position: relative; + overflow: hidden; + margin: 0 auto; + z-index: 1; + width: 100%; + height: 100%; +} + +.croppie-container .cr-viewport, +.croppie-container .cr-resizer { + position: absolute; + border: 2px solid #fff; + margin: auto; + top: 0; + bottom: 0; + right: 0; + left: 0; + box-shadow: 0 0 2000px 2000px rgba(0, 0, 0, 0.5); + z-index: 0; +} + +.croppie-container .cr-resizer { + z-index: 2; + box-shadow: none; + pointer-events: none; +} + +.croppie-container .cr-resizer-vertical, +.croppie-container .cr-resizer-horisontal { + position: absolute; + pointer-events: all; +} + +.croppie-container .cr-resizer-vertical::after, +.croppie-container .cr-resizer-horisontal::after { + display: block; + position: absolute; + box-sizing: border-box; + border: 1px solid black; + background: #fff; + width: 10px; + height: 10px; + content: ''; +} + +.croppie-container .cr-resizer-vertical { + bottom: -5px; + cursor: row-resize; + width: 100%; + height: 10px; +} + +.croppie-container .cr-resizer-vertical::after { + left: 50%; + margin-left: -5px; +} + +.croppie-container .cr-resizer-horisontal { + right: -5px; + cursor: col-resize; + width: 10px; + height: 100%; +} + +.croppie-container .cr-resizer-horisontal::after { + top: 50%; + margin-top: -5px; +} + +.croppie-container .cr-original-image { + display: none; +} + +.croppie-container .cr-vp-circle { + border-radius: 50%; +} + +.croppie-container .cr-overlay { + z-index: 1; + position: absolute; + cursor: move; + touch-action: none; +} + +.croppie-container .cr-slider-wrap { + margin: 15px auto; + text-align: center; +} + +.croppie-result { + position: relative; + overflow: hidden; +} + +.croppie-result img { + position: absolute; +} + +.croppie-container .cr-image, +.croppie-container .cr-overlay, +.croppie-container .cr-viewport { + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); +} + +/*************************************/ +/***** STYLING RANGE INPUT ***********/ +/*************************************/ +/*http://brennaobrien.com/blog/2014/05/style-input-type-range-in-every-browser.html */ +/*************************************/ + +.cr-slider { + -webkit-appearance: none; +/*removes default webkit styles*/ + /*border: 1px solid white; *//*fix for FF unable to apply focus style bug */ + width: 300px; +/*required for proper track sizing in FF*/ + max-width: 100%; + padding-top: 8px; + padding-bottom: 8px; + background-color: transparent; +} + +.cr-slider::-webkit-slider-runnable-track { + width: 100%; + height: 3px; + background: rgba(0, 0, 0, 0.2); + border: 0; +} + +.cr-slider::-webkit-slider-thumb { + -webkit-appearance: none; + border: none; + height: 16px; + width: 16px; + border-radius: 50%; + background: $color-primary; + margin-top: -6px; +} + +.cr-slider:focus { + outline: none; +} +/* +.cr-slider:focus::-webkit-slider-runnable-track { +background: #ccc; +} +*/ + +.cr-slider::-moz-range-track { + width: 100%; + height: 3px; + background: rgba(0, 0, 0, 0.5); + border: 0; + border-radius: 3px; +} + +.cr-slider::-moz-range-thumb { + border: none; + height: 16px; + width: 16px; + border-radius: 50%; + background: #ddd; + margin-top: -6px; +} + +/*hide the outline behind the border*/ +.cr-slider:-moz-focusring { + outline: 1px solid white; + outline-offset: -1px; +} + +.cr-slider::-ms-track { + width: 100%; + height: 5px; + background: transparent; +/*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */ + border-color: transparent;/*leave room for the larger thumb to overflow with a transparent border */ + border-width: 6px 0; + color: transparent;/*remove default tick marks*/ +} +.cr-slider::-ms-fill-lower { + background: rgba(0, 0, 0, 0.5); + border-radius: 10px; +} +.cr-slider::-ms-fill-upper { + background: rgba(0, 0, 0, 0.5); + border-radius: 10px; +} +.cr-slider::-ms-thumb { + border: none; + height: 16px; + width: 16px; + border-radius: 50%; + background: #ddd; + margin-top:1px; +} +.cr-slider:focus::-ms-fill-lower { + background: rgba(0, 0, 0, 0.5); +} +.cr-slider:focus::-ms-fill-upper { + background: rgba(0, 0, 0, 0.5); +} +/*******************************************/ + +/***********************************/ +/* Rotation Tools */ +/***********************************/ +.cr-rotate-controls { + position: absolute; + bottom: 5px; + left: 5px; + z-index: 1; +} +.cr-rotate-controls button { + border: 0; + background: none; +} +.cr-rotate-controls i:before { + display: inline-block; + font-style: normal; + font-weight: 900; + font-size: 22px; +} +.cr-rotate-l i:before { + content: '↺'; +} +.cr-rotate-r i:before { + content: '↻'; +} diff --git a/front/salix/components/upload-photo/index.html b/front/salix/components/upload-photo/index.html index c36eb7fe1..09b36d531 100644 --- a/front/salix/components/upload-photo/index.html +++ b/front/salix/components/upload-photo/index.html @@ -1,36 +1,62 @@ + message="Edit photo"> - -
-
- - - - - - - - - - - - + + + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + +
diff --git a/front/salix/components/upload-photo/index.js b/front/salix/components/upload-photo/index.js index 924a6a8a4..4a0180946 100644 --- a/front/salix/components/upload-photo/index.js +++ b/front/salix/components/upload-photo/index.js @@ -1,24 +1,74 @@ import ngModule from '../../module'; import Component from 'core/lib/component'; +import Croppie from 'croppie'; import './style.scss'; +import './croppie.scss'; /** * Small card with basing entity information and actions. */ export default class UploadPhoto extends Component { + constructor($element, $) { + super($element, $); + + this.viewportTypes = [ + { + code: 'normal', + description: this.$t('Normal'), + viewport: { + width: 400, + height: 400 + }, + output: { + width: 1200, + height: 1200 + } + + }, + { + code: 'panoramic', + description: this.$t('Panoramic'), + viewport: { + width: 675, + height: 450 + }, + output: { + width: 1350, + height: 900 + } + } + ]; + this.viewportType = 'normal'; + this.getAllowedContentTypes(); + } + /** * Opens the dialog and sets the default data * @param {*} collection - Collection name * @param {*} id - Entity id */ show(collection, id) { + this.editor = null; this.newPhoto = { id: id, collection: collection, fileName: id }; this.$.dialog.show(); - this.getAllowedContentTypes(); + } + + get viewportSelection() { + return this._viewportSelection; + } + + set viewportSelection(value) { + this._viewportSelection = value; + + if (value && this.newPhoto.files) { + this.displayEditor(); + const files = this.newPhoto.files; + this.updatePhotoPreview(files); + } } getAllowedContentTypes() { @@ -41,12 +91,39 @@ export default class UploadPhoto extends Component { */ updatePhotoPreview(value) { if (value && value[0]) { + if (!this.editor) + this.displayEditor(); + const reader = new FileReader(); - reader.onload = e => this.$.photo.src = e.target.result; + reader.onload = e => this.editor.bind({url: e.target.result}); reader.readAsDataURL(value[0]); } } + displayEditor() { + const viewportType = this.viewportSelection; + const viewport = viewportType.viewport; + const boundaryWidth = viewport.width + 200; + const boundaryHeight = viewport.height + 200; + + const container = document.getElementById('photoContainer'); + if (this.editor) this.editor.destroy(); + this.editor = new Croppie(container, { + viewport: {width: viewport.width, height: viewport.height}, + boundary: {width: boundaryWidth, height: boundaryHeight}, + enableOrientation: true, + showZoomer: true + }); + } + + rotateLeft() { + this.editor.rotate(90); + } + + rotateRight() { + this.editor.rotate(-90); + } + /** * Dialog response handler * @@ -57,12 +134,22 @@ export default class UploadPhoto extends Component { if (!this.newPhoto.files) throw new Error(`Select an image`); - this.makeRequest(); + const viewportType = this.viewportSelection; + const output = viewportType.output; + const options = { + type: 'blob', + size: { + width: output.width, + height: output.height + } + }; + return this.editor.result(options) + .then(blob => this.newPhoto.blob = blob) + .then(() => this.makeRequest()); } catch (e) { this.vnApp.showError(this.$t(e.message)); return false; } - return true; } /** @@ -79,10 +166,13 @@ export default class UploadPhoto extends Component { params: this.newPhoto, headers: {'Content-Type': undefined}, timeout: this.canceler.promise, - transformRequest: files => { + transformRequest: ([file]) => { const formData = new FormData(); - for (let i = 0; i < files.length; i++) - formData.append(files[i].name, files[i]); + const now = new Date(); + const timestamp = now.getTime(); + const fileName = `${file.name}_${timestamp}`; + + formData.append('blob', this.newPhoto.blob, fileName); return formData; }, diff --git a/front/salix/components/upload-photo/index.spec.js b/front/salix/components/upload-photo/index.spec.js index 0ae7a5425..e8ac05fd4 100644 --- a/front/salix/components/upload-photo/index.spec.js +++ b/front/salix/components/upload-photo/index.spec.js @@ -6,7 +6,9 @@ describe('Salix', () => { let $scope; let $httpBackend; - beforeEach(ngModule('salix')); + beforeEach(ngModule('salix', $translateProvider => { + $translateProvider.translations('en', {}); + })); beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => { $scope = $rootScope.$new(); @@ -14,12 +16,58 @@ describe('Salix', () => { const $element = angular.element(''); controller = $componentController('vnUploadPhoto', {$element, $scope}); controller.newPhoto = {}; + controller.$t = m => m; })); afterEach(() => { $scope.$destroy(); }); + describe('viewportSelection()', () => { + it('should call to displayEditor() and updatePhotoPreview() methods', () => { + controller.displayEditor = jest.fn(); + controller.updatePhotoPreview = jest.fn(); + + const files = [{name: 'test.jpg'}]; + controller.newPhoto.files = files; + + controller.viewportSelection = {code: 'normal'}; + + expect(controller.displayEditor).toHaveBeenCalledWith(); + expect(controller.updatePhotoPreview).toHaveBeenCalledWith(files); + }); + }); + + describe('displayEditor()', () => { + it('should define the editor property', () => { + controller.viewportSelection = { + code: 'normal', + description: 'Normal', + viewport: { + width: 400, + height: 400 + }, + output: { + width: 1200, + height: 1200 + } + }; + const element = document.createElement('div'); + + jest.spyOn(document, 'getElementById').mockReturnValue(element); + + controller.displayEditor(); + + const editor = controller.editor; + + expect(editor).toBeDefined(); + expect(editor.options.viewport.width).toEqual(400); + expect(editor.options.viewport.width).toEqual(400); + expect(editor.options.boundary.width).toEqual(600); + expect(editor.options.boundary.height).toEqual(600); + }); + }); + describe('onUploadAccept()', () => { it('should throw an error message containing "Select an image"', () => { jest.spyOn(controller.vnApp, 'showError'); @@ -29,13 +77,33 @@ describe('Salix', () => { expect(controller.vnApp.showError).toHaveBeenCalledWith('Select an image'); }); - it('should call to the makeRequest() method', () => { + it('should call to the makeRequest() method', done => { + controller.editor = { + result: () => {} + }; + jest.spyOn(controller, 'makeRequest'); + jest.spyOn(controller.editor, 'result').mockReturnValue(new Promise(resolve => resolve('blobFile'))); + + controller.viewportSelection = { + code: 'normal', + description: 'Normal', + viewport: { + width: 400, + height: 400 + }, + output: { + width: 1200, + height: 1200 + } + }; controller.newPhoto.files = [0]; - controller.onUploadAccept(); - - expect(controller.makeRequest).toHaveBeenCalledWith(); + controller.onUploadAccept().then(() => { + expect(controller.newPhoto.blob).toEqual('blobFile'); + expect(controller.makeRequest).toHaveBeenCalledWith(); + done(); + }).catch(done.fail); }); }); @@ -44,7 +112,11 @@ describe('Salix', () => { jest.spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller, 'emit'); + $httpBackend.expectGET('ImageContainers/allowedContentTypes').respond(200, ['image/jpg']); + controller.newPhoto.files = [{name: 'hola'}]; + controller.newPhoto.blob = new Blob([]); + $httpBackend.expectRoute('POST', 'Images/upload').respond(200); controller.makeRequest(); $httpBackend.flush(); diff --git a/front/salix/components/upload-photo/locale/es.yml b/front/salix/components/upload-photo/locale/es.yml index d2e696ba9..bba3a985a 100644 --- a/front/salix/components/upload-photo/locale/es.yml +++ b/front/salix/components/upload-photo/locale/es.yml @@ -1,3 +1,6 @@ -Upload new photo: Subir una nueva foto +Edit photo: Editar foto Select an image: Selecciona una imagen -File name: Nombre del fichero \ No newline at end of file +File name: Nombre del fichero +Rotate left: Girar a la izquierda +Rotate right: Girar a la derecha +Panoramic: Panorámico \ No newline at end of file diff --git a/front/salix/components/upload-photo/style.scss b/front/salix/components/upload-photo/style.scss index 609364a2c..52e58208c 100644 --- a/front/salix/components/upload-photo/style.scss +++ b/front/salix/components/upload-photo/style.scss @@ -1,26 +1,11 @@ @import "./variables"; .upload-photo { - .photo { - position: relative; - margin: 0 auto; - text-align: center; - & > div { - border: 3px solid $color-primary; - max-width: 256px; - max-height: 256px; - border-radius: 50%; - overflow: hidden - } - - & > div > img[ng-src] { - width: 256px; - height: 256px; - display: block - } + & > vn-horizontal { + align-items: initial; } - + & > vn-spinner { display: block; height: 40px; @@ -28,10 +13,13 @@ } vn-input-file { - max-width: 256px; div.control { overflow: hidden } } + + .form { + align-items: initial; + } } diff --git a/loopback/locale/en.json b/loopback/locale/en.json index d77b0c26d..02443a066 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -105,9 +105,13 @@ "Client assignment has changed": "I did change the salesperson ~*\"<{{previousWorkerName}}>\"*~ by *\"<{{currentWorkerName}}>\"* from the client [{{clientName}} ({{clientId}})]({{{url}}})", "None": "None", "error densidad = 0": "error densidad = 0", - "nickname": "nickname", "This document already exists on this ticket": "This document already exists on this ticket", + "serial non editable": "This serial doesn't allow to set a reference", + "nickname": "nickname", "State": "State", "regular": "regular", - "reserved": "reserved" + "reserved": "reserved", + "Global invoicing failed": "[Global invoicing] Wasn't able to invoice some of the clients", + "A ticket with a negative base can't be invoiced": "A ticket with a negative base can't be invoiced", + "This client is not invoiceable": "This client is not invoiceable" } \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index fe0027657..36eebe224 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -195,5 +195,15 @@ "This document already exists on this ticket": "Este documento ya existe en el ticket", "Some of the selected tickets are not billable": "Algunos de los tickets seleccionados no son facturables", "You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes", - "INACTIVE_PROVIDER": "INACTIVE_PROVIDER" + "INACTIVE_PROVIDER": "INACTIVE_PROVIDER", + "This client is not invoiceable": "Este cliente no es facturable", + "serial non editable": "Esta serie no permite asignar la referencia", + "Max shipped required": "La fecha límite es requerida", + "Can't invoice to future": "No se puede facturar a futuro", + "Can't invoice to past": "No se puede facturar a pasado", + "This ticket is already invoiced": "Este ticket ya está facturado", + "A ticket with an amount of zero can't be invoiced": "No se puede facturar un ticket con importe cero", + "A ticket with a negative base can't be invoiced": "No se puede facturar un ticket con una base negativa", + "Global invoicing failed": "[Facturación global] No se han podido facturar algunos clientes", + "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes" } \ No newline at end of file diff --git a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js new file mode 100644 index 000000000..561f559fd --- /dev/null +++ b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js @@ -0,0 +1,183 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('createManualInvoice', { + description: 'Make a manual invoice', + accessType: 'WRITE', + accepts: [ + { + arg: 'clientFk', + type: 'any', + description: 'The invoiceable client id' + }, + { + arg: 'ticketFk', + type: 'any', + description: 'The invoiceable ticket id' + }, + { + arg: 'maxShipped', + type: 'date', + description: 'The maximum shipped date' + }, + { + arg: 'serial', + type: 'string', + description: 'The invoice serial' + }, + { + arg: 'taxArea', + type: 'string', + description: 'The invoice tax area' + }, + { + arg: 'reference', + type: 'string', + description: 'The invoice reference' + } + ], + returns: { + type: 'object', + root: true + }, + http: { + path: '/createManualInvoice', + verb: 'POST' + } + }); + + Self.createManualInvoice = async(ctx, options) => { + const models = Self.app.models; + const args = ctx.args; + + let tx; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + const ticketId = args.ticketFk; + let clientId = args.clientFk; + let maxShipped = args.maxShipped; + let companyId; + let query; + try { + if (ticketId) { + const ticket = await models.Ticket.findById(ticketId, null, myOptions); + const company = await models.Company.findById(ticket.companyFk, null, myOptions); + + clientId = ticket.clientFk; + maxShipped = ticket.shipped; + companyId = ticket.companyFk; + + // Validates invoiced ticket + if (ticket.refFk) + throw new UserError('This ticket is already invoiced'); + + // Validates ticket amount + if (ticket.totalWithVat == 0) + throw new UserError(`A ticket with an amount of zero can't be invoiced`); + + // Validates ticket nagative base + const hasNegativeBase = await getNegativeBase(ticketId, myOptions); + if (hasNegativeBase && company.code == 'VNL') + throw new UserError(`A ticket with a negative base can't be invoiced`); + } else { + if (!maxShipped) + throw new UserError(`Max shipped required`); + + const company = await models.Ticket.findOne({ + fields: ['companyFk'], + where: { + clientFk: clientId, + shipped: {lte: maxShipped} + } + }, myOptions); + companyId = company.companyFk; + } + + // Validate invoiceable client + const isClientInvoiceable = await isInvoiceable(clientId, myOptions); + if (!isClientInvoiceable) + throw new UserError(`This client is not invoiceable`); + + // Can't invoice tickets into future + const tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + + if (maxShipped >= tomorrow) + throw new UserError(`Can't invoice to future`); + + const maxInvoiceDate = await getMaxIssued(args.serial, companyId, myOptions); + if (new Date() < maxInvoiceDate) + throw new UserError(`Can't invoice to past`); + + if (ticketId) { + query = `CALL invoiceOut_newFromTicket(?, ?, ?, ?, @newInvoiceId)`; + await Self.rawSql(query, [ + ticketId, + args.serial, + args.taxArea, + args.reference + ], myOptions); + } else { + query = `CALL invoiceOut_newFromClient(?, ?, ?, ?, ?, ?, @newInvoiceId)`; + await Self.rawSql(query, [ + clientId, + args.serial, + maxShipped, + companyId, + args.taxArea, + args.reference + ], myOptions); + } + + const [newInvoice] = await Self.rawSql(`SELECT @newInvoiceId id`, null, myOptions); + + if (tx) await tx.commit(); + + if (newInvoice.id) + await Self.createPdf(ctx, newInvoice.id); + + return newInvoice; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; + + async function isInvoiceable(clientId, options) { + const models = Self.app.models; + const query = `SELECT (hasToInvoice AND isTaxDataChecked) AS invoiceable + FROM client + WHERE id = ?`; + const [result] = await models.InvoiceOut.rawSql(query, [clientId], options); + + return result.invoiceable; + } + + async function getNegativeBase(ticketId, options) { + const models = Self.app.models; + const query = 'SELECT vn.hasSomeNegativeBase(?) AS base'; + const [result] = await models.InvoiceOut.rawSql(query, [ticketId], options); + + return result.base; + } + + async function getMaxIssued(serial, companyId, options) { + const models = Self.app.models; + const query = `SELECT MAX(issued) AS issued + FROM invoiceOut + WHERE serial = ? AND companyFk = ?`; + const [maxIssued] = await models.InvoiceOut.rawSql(query, + [serial, companyId], options); + const maxInvoiceDate = maxIssued && maxIssued.issued || new Date(); + + return maxInvoiceDate; + } +}; diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index 6e596db62..678e7dda5 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -58,24 +58,33 @@ module.exports = Self => { } }); - const invoiceYear = invoiceOut.created.getFullYear().toString(); - const container = await models.InvoiceContainer.container(invoiceYear); + const created = invoiceOut.created; + const year = created.getFullYear().toString(); + const month = created.getMonth().toString(); + const day = created.getDate().toString(); + + const container = await models.InvoiceContainer.container(year); const rootPath = container.client.root; const fileName = `${invoiceOut.ref}.pdf`; - fileSrc = path.join(rootPath, invoiceYear, fileName); + const src = path.join(rootPath, year, month, day); + fileSrc = path.join(src, fileName); + + await fs.mkdir(src, {recursive: true}); + + if (tx) await tx.commit(); const writeStream = fs.createWriteStream(fileSrc); writeStream.on('open', () => { response.pipe(writeStream); }); - writeStream.on('finish', async function() { - writeStream.end(); + return new Promise(resolve => { + writeStream.on('finish', () => { + writeStream.end(); + + resolve(invoiceOut); + }); }); - - if (tx) await tx.commit(); - - return invoiceOut; } catch (e) { if (tx) await tx.rollback(); if (fs.existsSync(fileSrc)) diff --git a/modules/invoiceOut/back/methods/invoiceOut/delete.js b/modules/invoiceOut/back/methods/invoiceOut/delete.js index 96b5e652e..d8b9d309b 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/delete.js +++ b/modules/invoiceOut/back/methods/invoiceOut/delete.js @@ -34,13 +34,14 @@ module.exports = Self => { try { const invoiceOut = await Self.findById(id, {}, myOptions); - const tickets = await Self.app.models.Ticket.find({where: {refFk: invoiceOut.ref}}, myOptions); + const tickets = await Self.app.models.Ticket.find({ + where: {refFk: invoiceOut.ref} + }, myOptions); const promises = []; - tickets.forEach(ticket => { + for (let ticket of tickets) promises.push(ticket.updateAttribute('refFk', null, myOptions)); - }); await Promise.all(promises); diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js index 3c9924fc3..983647982 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/download.js +++ b/modules/invoiceOut/back/methods/invoiceOut/download.js @@ -1,4 +1,5 @@ const fs = require('fs-extra'); +const path = require('path'); module.exports = Self => { Self.remoteMethod('download', { @@ -33,24 +34,31 @@ module.exports = Self => { } }); - Self.download = async function(id) { - let file; - let env = process.env.NODE_ENV; - let [invoice] = await Self.rawSql(`SELECT invoiceOut_getPath(?) path`, [id]); + Self.download = async function(id, options) { + const models = Self.app.models; + const myOptions = {}; - if (env && env != 'development') { - file = { - path: `/var/lib/salix/pdfs/${invoice.path}`, - contentType: 'application/pdf', - name: `${id}.pdf` - }; - } else { - file = { - path: `${process.cwd()}/README.md`, - contentType: 'text/plain', - name: `README.md` - }; - } + if (typeof options == 'object') + Object.assign(myOptions, options); + + const invoiceOut = await models.InvoiceOut.findById(id, null, myOptions); + + const created = invoiceOut.created; + const year = created.getFullYear().toString(); + const month = created.getMonth().toString(); + const day = created.getDate().toString(); + + const container = await models.InvoiceContainer.container(year); + const rootPath = container.client.root; + const src = path.join(rootPath, year, month, day); + const fileName = `${invoiceOut.ref}.pdf`; + const fileSrc = path.join(src, fileName); + + const file = { + path: fileSrc, + contentType: 'application/pdf', + name: `${id}.pdf` + }; await fs.access(file.path); let stream = fs.createReadStream(file.path); diff --git a/modules/invoiceOut/back/methods/invoiceOut/globalInvoicing.js b/modules/invoiceOut/back/methods/invoiceOut/globalInvoicing.js new file mode 100644 index 000000000..5989e941b --- /dev/null +++ b/modules/invoiceOut/back/methods/invoiceOut/globalInvoicing.js @@ -0,0 +1,263 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('globalInvoicing', { + description: 'Make a global invoice', + accessType: 'WRITE', + accepts: [ + { + arg: 'invoiceDate', + type: 'date', + description: 'The invoice date' + }, + { + arg: 'maxShipped', + type: 'date', + description: 'The maximum shipped date' + }, + { + arg: 'fromClientId', + type: 'number', + description: 'The minimum client id' + }, + { + arg: 'toClientId', + type: 'number', + description: 'The maximum client id' + }, + { + arg: 'companyFk', + type: 'number', + description: 'The company id to invoice' + } + ], + returns: { + type: 'object', + root: true + }, + http: { + path: '/globalInvoicing', + verb: 'POST' + } + }); + + Self.globalInvoicing = async(ctx, options) => { + const args = ctx.args; + const invoicesIds = []; + const failedClients = []; + + let tx; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + let query; + try { + query = ` + SELECT MAX(issued) issued + FROM vn.invoiceOut io + JOIN vn.time t ON t.dated = io.issued + WHERE io.serial = 'A' + AND t.year = YEAR(?) + AND io.companyFk = ?`; + const [maxIssued] = await Self.rawSql(query, [ + args.invoiceDate, + args.companyFk + ], myOptions); + + const maxSerialDate = maxIssued.issued || args.invoiceDate; + if (args.invoiceDate < maxSerialDate) + args.invoiceDate = maxSerialDate; + + if (args.invoiceDate < args.maxShipped) + args.maxShipped = args.invoiceDate; + + const minShipped = new Date(); + minShipped.setFullYear(minShipped.getFullYear() - 1); + + // Packaging liquidation + const vIsAllInvoiceable = false; + const clientsWithPackaging = await getClientsWithPackaging(ctx, myOptions); + for (let client of clientsWithPackaging) { + await Self.rawSql('CALL packageInvoicing(?, ?, ?, ?, @newTicket)', [ + client.id, + args.invoiceDate, + args.companyFk, + vIsAllInvoiceable + ], myOptions); + } + + const invoiceableClients = await getInvoiceableClients(ctx, myOptions); + + if (!invoiceableClients.length) return; + + for (let client of invoiceableClients) { + try { + if (client.hasToInvoiceByAddress) { + await Self.rawSql('CALL ticketToInvoiceByAddress(?, ?, ?, ?)', [ + minShipped, + args.maxShipped, + client.addressFk, + args.companyFk + ], myOptions); + } else { + await Self.rawSql('CALL invoiceFromClient(?, ?, ?)', [ + args.maxShipped, + client.id, + args.companyFk + ], myOptions); + } + + // Make invoice + const isSpanishCompany = await getIsSpanishCompany(args.companyFk, myOptions); + + // Validates ticket nagative base + const hasAnyNegativeBase = await getNegativeBase(myOptions); + if (hasAnyNegativeBase && isSpanishCompany) + continue; + + query = `SELECT invoiceSerial(?, ?, ?) AS serial`; + const [invoiceSerial] = await Self.rawSql(query, [ + client.id, + args.companyFk, + 'G' + ], myOptions); + const serialLetter = invoiceSerial.serial; + + query = `CALL invoiceOut_new(?, ?, NULL, @invoiceId)`; + await Self.rawSql(query, [ + serialLetter, + args.invoiceDate + ], myOptions); + + const [newInvoice] = await Self.rawSql(`SELECT @invoiceId id`, null, myOptions); + if (newInvoice.id) { + await Self.rawSql('CALL invoiceOutBooking(?)', [newInvoice.id], myOptions); + + invoicesIds.push(newInvoice.id); + } + } catch (e) { + failedClients.push({ + id: client.id, + stacktrace: e + }); + continue; + } + } + + if (failedClients.length > 0) + await notifyFailures(ctx, failedClients, myOptions); + + if (tx) await tx.commit(); + + // Print invoices PDF + for (let invoiceId of invoicesIds) + await Self.createPdf(ctx, invoiceId); + + return invoicesIds; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; + + async function getNegativeBase(options) { + const models = Self.app.models; + const query = 'SELECT hasAnyNegativeBase() AS base'; + const [result] = await models.InvoiceOut.rawSql(query, null, options); + + return result && result.base; + } + + async function getIsSpanishCompany(companyId, options) { + const models = Self.app.models; + const query = `SELECT COUNT(*) AS total + FROM supplier s + JOIN country c ON c.id = s.countryFk + AND c.code = 'ES' + WHERE s.id = ?`; + const [supplierCompany] = await models.InvoiceOut.rawSql(query, [ + companyId + ], options); + + return supplierCompany && supplierCompany.total; + } + + async function getClientsWithPackaging(ctx, options) { + const models = Self.app.models; + const args = ctx.args; + const query = `SELECT DISTINCT clientFk AS id + FROM ticket t + JOIN ticketPackaging tp ON t.id = tp.ticketFk + WHERE t.shipped BETWEEN '2017-11-21' AND ? + AND t.clientFk BETWEEN ? AND ?`; + return models.InvoiceOut.rawSql(query, [ + args.maxShipped, + args.fromClientId, + args.toClientId + ], options); + } + + async function getInvoiceableClients(ctx, options) { + const models = Self.app.models; + const args = ctx.args; + const minShipped = new Date(); + minShipped.setFullYear(minShipped.getFullYear() - 1); + + const query = `SELECT + c.id, + SUM(IFNULL(s.quantity * s.price * (100-s.discount)/100, 0) + IFNULL(ts.quantity * ts.price,0)) AS sumAmount, + c.hasToInvoiceByAddress, + c.email, + c.isToBeMailed, + a.id addressFk + FROM ticket t + LEFT JOIN sale s ON s.ticketFk = t.id + LEFT JOIN ticketService ts ON ts.ticketFk = t.id + JOIN address a ON a.id = t.addressFk + JOIN client c ON c.id = t.clientFk + WHERE ISNULL(t.refFk) AND c.id BETWEEN ? AND ? + AND t.shipped BETWEEN ? AND util.dayEnd(?) + AND t.companyFk = ? AND c.hasToInvoice + AND c.isTaxDataChecked + GROUP BY c.id, IF(c.hasToInvoiceByAddress,a.id,TRUE) HAVING sumAmount > 0`; + + return models.InvoiceOut.rawSql(query, [ + args.fromClientId, + args.toClientId, + minShipped, + args.maxShipped, + args.companyFk + ], options); + } + + async function notifyFailures(ctx, failedClients, options) { + const models = Self.app.models; + const userId = ctx.req.accessToken.userId; + const $t = ctx.req.__; // $translate + + const worker = await models.EmailUser.findById(userId, null, options); + const subject = $t('Global invoicing failed'); + let body = $t(`Wasn't able to invoice the following clients`) + ':

'; + + for (client of failedClients) { + body += `ID: ${client.id} +
${client.stacktrace}

`; + } + + await Self.rawSql(` + INSERT INTO vn.mail (sender, replyTo, sent, subject, body) + VALUES (?, ?, FALSE, ?, ?)`, [ + worker.email, + worker.email, + subject, + body + ], options); + } +}; diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/createManualInvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/createManualInvoice.spec.js new file mode 100644 index 000000000..f1c1bbab8 --- /dev/null +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/createManualInvoice.spec.js @@ -0,0 +1,145 @@ +const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); + +describe('InvoiceOut createManualInvoice()', () => { + const userId = 1; + const ticketId = 16; + const clientId = 1106; + const activeCtx = { + accessToken: {userId: userId}, + }; + const ctx = {req: activeCtx}; + + it('should throw an error trying to invoice again', async() => { + spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true))); + + const tx = await models.InvoiceOut.beginTransaction({}); + const options = {transaction: tx}; + + let error; + try { + ctx.args = { + ticketFk: ticketId, + serial: 'T', + taxArea: 'CEE' + }; + await models.InvoiceOut.createManualInvoice(ctx, options); + await models.InvoiceOut.createManualInvoice(ctx, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toContain('This ticket is already invoiced'); + }); + + it('should throw an error for a ticket with an amount of zero', async() => { + spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true))); + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + + const tx = await models.InvoiceOut.beginTransaction({}); + const options = {transaction: tx}; + + let error; + try { + const ticket = await models.Ticket.findById(ticketId, null, options); + await ticket.updateAttributes({ + totalWithVat: 0 + }, options); + + ctx.args = { + ticketFk: ticketId, + serial: 'T', + taxArea: 'CEE' + }; + await models.InvoiceOut.createManualInvoice(ctx, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toContain(`A ticket with an amount of zero can't be invoiced`); + }); + + it('should throw an error when the clientFk property is set without the max shipped date', async() => { + spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true))); + + const tx = await models.InvoiceOut.beginTransaction({}); + const options = {transaction: tx}; + + let error; + try { + ctx.args = { + clientFk: clientId, + serial: 'T', + taxArea: 'CEE' + }; + await models.InvoiceOut.createManualInvoice(ctx, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toContain(`Max shipped required`); + }); + + it('should throw an error for a non-invoiceable client', async() => { + spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true))); + + const tx = await models.InvoiceOut.beginTransaction({}); + const options = {transaction: tx}; + + let error; + try { + const client = await models.Client.findById(clientId, null, options); + await client.updateAttributes({ + isTaxDataChecked: false + }, options); + + ctx.args = { + ticketFk: ticketId, + serial: 'T', + taxArea: 'CEE' + }; + await models.InvoiceOut.createManualInvoice(ctx, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toContain(`This client is not invoiceable`); + }); + + it('should create a manual invoice', async() => { + spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true))); + + const tx = await models.InvoiceOut.beginTransaction({}); + const options = {transaction: tx}; + + try { + ctx.args = { + ticketFk: ticketId, + serial: 'T', + taxArea: 'CEE' + }; + const result = await models.InvoiceOut.createManualInvoice(ctx, options); + + expect(result.id).toEqual(jasmine.any(Number)); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/createPdf.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/createPdf.spec.js index 60dd5576d..2f503d11c 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/createPdf.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/createPdf.spec.js @@ -1,5 +1,6 @@ const models = require('vn-loopback/server/server').models; const got = require('got'); +const fs = require('fs-extra'); describe('InvoiceOut createPdf()', () => { const userId = 1; @@ -18,9 +19,27 @@ describe('InvoiceOut createPdf()', () => { on: () => {}, }; spyOn(got, 'stream').and.returnValue(response); + spyOn(models.InvoiceContainer, 'container').and.returnValue({ + client: {root: '/path'} + }); + spyOn(fs, 'mkdir').and.returnValue(true); + spyOn(fs, 'createWriteStream').and.returnValue({ + on: (event, cb) => cb(), + end: () => {} + }); - const result = await models.InvoiceOut.createPdf(ctx, invoiceId); + const tx = await models.InvoiceOut.beginTransaction({}); + const options = {transaction: tx}; - expect(result.hasPdf).toBe(true); + try { + const result = await models.InvoiceOut.createPdf(ctx, invoiceId, options); + + expect(result.hasPdf).toBe(true); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js index 2d9056708..c053adde1 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/download.spec.js @@ -1,10 +1,17 @@ const models = require('vn-loopback/server/server').models; +const fs = require('fs-extra'); describe('InvoiceOut download()', () => { it('should return the downloaded fine name', async() => { + spyOn(models.InvoiceContainer, 'container').and.returnValue({ + client: {root: '/path'} + }); + spyOn(fs, 'createReadStream').and.returnValue(new Promise(resolve => resolve('streamObject'))); + spyOn(fs, 'access').and.returnValue(true); + const result = await models.InvoiceOut.download(1); - expect(result[1]).toEqual('text/plain'); - expect(result[2]).toEqual('filename="README.md"'); + expect(result[1]).toEqual('application/pdf'); + expect(result[2]).toEqual('filename="1.pdf"'); }); }); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/globalInvoicing.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/globalInvoicing.spec.js new file mode 100644 index 000000000..e0ed6c91c --- /dev/null +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/globalInvoicing.spec.js @@ -0,0 +1,40 @@ +const models = require('vn-loopback/server/server').models; + +describe('InvoiceOut globalInvoicing()', () => { + const userId = 1; + const companyFk = 442; + const clientId = 1101; + const invoicedTicketId = 8; + const invoiceSerial = 'A'; + const activeCtx = { + accessToken: {userId: userId}, + }; + const ctx = {req: activeCtx}; + + it('should make a global invoicing', async() => { + spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true))); + + const tx = await models.InvoiceOut.beginTransaction({}); + const options = {transaction: tx}; + + try { + ctx.args = { + invoiceDate: new Date(), + maxShipped: new Date(), + fromClientId: clientId, + toClientId: clientId, + companyFk: companyFk + }; + const result = await models.InvoiceOut.globalInvoicing(ctx, options); + const ticket = await models.Ticket.findById(invoicedTicketId, null, options); + + expect(result.length).toBeGreaterThan(0); + expect(ticket.refFk).toContain(invoiceSerial); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/invoiceOut/back/model-config.json b/modules/invoiceOut/back/model-config.json index e144ce80e..d52f79477 100644 --- a/modules/invoiceOut/back/model-config.json +++ b/modules/invoiceOut/back/model-config.json @@ -2,7 +2,25 @@ "InvoiceOut": { "dataSource": "vn" }, + "InvoiceOutSerial": { + "dataSource": "vn" + }, "InvoiceContainer": { "dataSource": "invoiceStorage" + }, + "TaxArea": { + "dataSource": "vn" + }, + "TaxClass": { + "dataSource": "vn" + }, + "TaxClassCode": { + "dataSource": "vn" + }, + "TaxCode": { + "dataSource": "vn" + }, + "TaxType": { + "dataSource": "vn" } } diff --git a/modules/invoiceOut/back/models/invoice-out-serial.json b/modules/invoiceOut/back/models/invoice-out-serial.json new file mode 100644 index 000000000..912269fd7 --- /dev/null +++ b/modules/invoiceOut/back/models/invoice-out-serial.json @@ -0,0 +1,38 @@ +{ + "name": "InvoiceOutSerial", + "base": "VnModel", + "options": { + "mysql": { + "table": "invoiceOutSerial" + } + }, + "properties": { + "code": { + "type": "string", + "id": true, + "description": "Identifier" + }, + "description": { + "type": "string" + }, + "isTaxed": { + "type": "boolean" + }, + "isCEE": { + "type": "boolean" + } + }, + "relations": { + "taxArea": { + "type": "belongsTo", + "model": "TaxArea", + "foreignKey": "taxAreaFk" + } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] +} \ No newline at end of file diff --git a/modules/invoiceOut/back/models/invoiceOut.js b/modules/invoiceOut/back/models/invoice-out.js similarity index 76% rename from modules/invoiceOut/back/models/invoiceOut.js rename to modules/invoiceOut/back/models/invoice-out.js index 7c6503d8e..3b2822ada 100644 --- a/modules/invoiceOut/back/models/invoiceOut.js +++ b/modules/invoiceOut/back/models/invoice-out.js @@ -6,4 +6,6 @@ module.exports = Self => { require('../methods/invoiceOut/delete')(Self); require('../methods/invoiceOut/book')(Self); require('../methods/invoiceOut/createPdf')(Self); + require('../methods/invoiceOut/createManualInvoice')(Self); + require('../methods/invoiceOut/globalInvoicing')(Self); }; diff --git a/modules/invoiceOut/back/models/invoiceOut.json b/modules/invoiceOut/back/models/invoice-out.json similarity index 100% rename from modules/invoiceOut/back/models/invoiceOut.json rename to modules/invoiceOut/back/models/invoice-out.json diff --git a/modules/invoiceOut/back/models/tax-area.json b/modules/invoiceOut/back/models/tax-area.json new file mode 100644 index 000000000..0aa00d194 --- /dev/null +++ b/modules/invoiceOut/back/models/tax-area.json @@ -0,0 +1,22 @@ +{ + "name": "TaxArea", + "base": "VnModel", + "options": { + "mysql": { + "table": "taxArea" + } + }, + "properties": { + "code": { + "type": "string", + "id": true, + "description": "Identifier" + } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] +} \ No newline at end of file diff --git a/modules/item/back/models/tax-class-code.json b/modules/invoiceOut/back/models/tax-class-code.json similarity index 100% rename from modules/item/back/models/tax-class-code.json rename to modules/invoiceOut/back/models/tax-class-code.json diff --git a/modules/item/back/models/tax-class.json b/modules/invoiceOut/back/models/tax-class.json similarity index 100% rename from modules/item/back/models/tax-class.json rename to modules/invoiceOut/back/models/tax-class.json diff --git a/modules/item/back/models/tax-code.json b/modules/invoiceOut/back/models/tax-code.json similarity index 100% rename from modules/item/back/models/tax-code.json rename to modules/invoiceOut/back/models/tax-code.json diff --git a/modules/item/back/models/tax-type.json b/modules/invoiceOut/back/models/tax-type.json similarity index 100% rename from modules/item/back/models/tax-type.json rename to modules/invoiceOut/back/models/tax-type.json diff --git a/modules/invoiceOut/front/index.js b/modules/invoiceOut/front/index.js index 9843e188b..3bb6d54d2 100644 --- a/modules/invoiceOut/front/index.js +++ b/modules/invoiceOut/front/index.js @@ -7,3 +7,5 @@ import './summary'; import './card'; import './descriptor'; import './descriptor-popover'; +import './index/manual'; +import './index/global-invoicing'; diff --git a/modules/invoiceOut/front/index/global-invoicing/index.html b/modules/invoiceOut/front/index/global-invoicing/index.html new file mode 100644 index 000000000..9fd412d0e --- /dev/null +++ b/modules/invoiceOut/front/index/global-invoicing/index.html @@ -0,0 +1,70 @@ + + Create global invoice + + + + + + +
+ + + Invoicing in progress... + +
+ + + + + + + + + {{::id}} - {{::name}} + + + {{::id}} - {{::name}} + + + + + + +
+ + + + \ No newline at end of file diff --git a/modules/invoiceOut/front/index/global-invoicing/index.js b/modules/invoiceOut/front/index/global-invoicing/index.js new file mode 100644 index 000000000..5e522f23d --- /dev/null +++ b/modules/invoiceOut/front/index/global-invoicing/index.js @@ -0,0 +1,81 @@ +import ngModule from '../../module'; +import Dialog from 'core/components/dialog'; +import './style.scss'; + +class Controller extends Dialog { + constructor($element, $, $transclude) { + super($element, $, $transclude); + + this.isInvoicing = false; + this.invoice = { + maxShipped: new Date() + }; + } + + $onInit() { + this.getMinClientId(); + this.getMaxClientId(); + } + + getMinClientId() { + this.getClientId('min') + .then(res => this.invoice.fromClientId = res.data.id); + } + + getMaxClientId() { + this.getClientId('max') + .then(res => this.invoice.toClientId = res.data.id); + } + + getClientId(func) { + const order = func == 'min' ? 'ASC' : 'DESC'; + const params = { + filter: { + order: 'id ' + order, + limit: 1 + } + }; + return this.$http.get('Clients/findOne', {params}); + } + + get companyFk() { + return this.invoice.companyFk; + } + + set companyFk(value) { + this.invoice.companyFk = value; + } + + responseHandler(response) { + try { + if (response !== 'accept') + return super.responseHandler(response); + + if (!this.invoice.invoiceDate || !this.invoice.maxShipped) + throw new Error('Invoice date and the max date should be filled'); + + if (!this.invoice.fromClientId || !this.invoice.toClientId) + throw new Error('Choose a valid clients range'); + + this.isInvoicing = true; + return this.$http.post(`InvoiceOuts/globalInvoicing`, this.invoice) + .then(() => super.responseHandler(response)) + .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))) + .finally(() => this.isInvoicing = false); + } catch (e) { + this.vnApp.showError(this.$t(e.message)); + this.isInvoicing = false; + return false; + } + } +} + +Controller.$inject = ['$element', '$scope', '$transclude']; + +ngModule.vnComponent('vnInvoiceOutGlobalInvoicing', { + slotTemplate: require('./index.html'), + controller: Controller, + bindings: { + companyFk: ' { + describe('Component vnInvoiceOutGlobalInvoicing', () => { + let controller; + let $httpBackend; + let $httpParamSerializer; + + beforeEach(ngModule('invoiceOut')); + + beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => { + $httpBackend = _$httpBackend_; + $httpParamSerializer = _$httpParamSerializer_; + let $scope = $rootScope.$new(); + const $element = angular.element(''); + const $transclude = { + $$boundTransclude: { + $$slots: [] + } + }; + controller = $componentController('vnInvoiceOutGlobalInvoicing', {$element, $scope, $transclude}); + })); + + describe('getMinClientId()', () => { + it('should set the invoice fromClientId property', () => { + const filter = { + order: 'id ASC', + limit: 1 + }; + + const serializedParams = $httpParamSerializer({filter}); + $httpBackend.expectGET(`Clients/findOne?${serializedParams}`).respond(200, {id: 1101}); + + controller.getMinClientId(); + $httpBackend.flush(); + + expect(controller.invoice.fromClientId).toEqual(1101); + }); + }); + + describe('getMaxClientId()', () => { + it('should set the invoice toClientId property', () => { + const filter = { + order: 'id DESC', + limit: 1 + }; + + const serializedParams = $httpParamSerializer({filter}); + $httpBackend.expectGET(`Clients/findOne?${serializedParams}`).respond(200, {id: 1112}); + + controller.getMaxClientId(); + $httpBackend.flush(); + + expect(controller.invoice.toClientId).toEqual(1112); + }); + }); + + describe('responseHandler()', () => { + it('should throw an error when invoiceDate or maxShipped properties are not filled in', () => { + jest.spyOn(controller.vnApp, 'showError'); + + controller.invoice = { + fromClientId: 1101, + toClientId: 1101 + }; + + controller.responseHandler('accept'); + + expect(controller.vnApp.showError).toHaveBeenCalledWith(`Invoice date and the max date should be filled`); + }); + + it('should throw an error when fromClientId or toClientId properties are not filled in', () => { + jest.spyOn(controller.vnApp, 'showError'); + + controller.invoice = { + invoiceDate: new Date(), + maxShipped: new Date() + }; + + controller.responseHandler('accept'); + + expect(controller.vnApp.showError).toHaveBeenCalledWith(`Choose a valid clients range`); + }); + + it('should make an http POST query and then call to the showSuccess() method', () => { + jest.spyOn(controller.vnApp, 'showSuccess'); + + controller.invoice = { + invoiceDate: new Date(), + maxShipped: new Date(), + fromClientId: 1101, + toClientId: 1101 + }; + + $httpBackend.expect('POST', `InvoiceOuts/globalInvoicing`).respond({id: 1}); + controller.responseHandler('accept'); + $httpBackend.flush(); + + expect(controller.vnApp.showSuccess).toHaveBeenCalled(); + }); + }); + }); +}); diff --git a/modules/invoiceOut/front/index/global-invoicing/locale/es.yml b/modules/invoiceOut/front/index/global-invoicing/locale/es.yml new file mode 100644 index 000000000..51e165e2a --- /dev/null +++ b/modules/invoiceOut/front/index/global-invoicing/locale/es.yml @@ -0,0 +1,9 @@ +Create global invoice: Crear factura global +Some fields are required: Algunos campos son obligatorios +Max date: Fecha límite +Invoicing in progress...: Facturación en progreso... +Invoice date: Fecha de factura +From client: Desde el cliente +To client: Hasta el cliente +Invoice date and the max date should be filled: La fecha de factura y la fecha límite deben rellenarse +Choose a valid clients range: Selecciona un rango válido de clientes \ No newline at end of file diff --git a/modules/invoiceOut/front/index/global-invoicing/style.scss b/modules/invoiceOut/front/index/global-invoicing/style.scss new file mode 100644 index 000000000..d0bd9e214 --- /dev/null +++ b/modules/invoiceOut/front/index/global-invoicing/style.scss @@ -0,0 +1,17 @@ +@import "variables"; + +.vn-invoice-out-global-invoicing { + tpl-body { + width: 500px; + + .progress { + font-weight: bold; + text-align: center; + font-size: 1.5rem; + color: $color-primary; + vn-horizontal { + justify-content: center + } + } + } +} \ No newline at end of file diff --git a/modules/invoiceOut/front/index/index.html b/modules/invoiceOut/front/index/index.html index 8685990a4..d970bd15a 100644 --- a/modules/invoiceOut/front/index/index.html +++ b/modules/invoiceOut/front/index/index.html @@ -57,6 +57,31 @@ +
+ + + + + + + Manual invoicing + + + Global invoicing + + + +
@@ -65,3 +90,10 @@ + + + + \ No newline at end of file diff --git a/modules/invoiceOut/front/index/locale/es.yml b/modules/invoiceOut/front/index/locale/es.yml index eb22e1779..1460b90d8 100644 --- a/modules/invoiceOut/front/index/locale/es.yml +++ b/modules/invoiceOut/front/index/locale/es.yml @@ -3,4 +3,6 @@ Issued: Fecha factura Due date: Fecha vencimiento Has PDF: PDF disponible Minimum: Minimo -Maximum: Máximo \ No newline at end of file +Maximum: Máximo +Global invoicing: Facturación global +Manual invoicing: Facturación manual diff --git a/modules/invoiceOut/front/index/manual/index.html b/modules/invoiceOut/front/index/manual/index.html new file mode 100644 index 000000000..3148d3f94 --- /dev/null +++ b/modules/invoiceOut/front/index/manual/index.html @@ -0,0 +1,83 @@ + + Create manual invoice + + + + + + +
+ + + Invoicing in progress... + +
+ + + + {{::id}} - {{::nickname}} + + + Or + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/modules/invoiceOut/front/index/manual/index.js b/modules/invoiceOut/front/index/manual/index.js new file mode 100644 index 000000000..ed50e37da --- /dev/null +++ b/modules/invoiceOut/front/index/manual/index.js @@ -0,0 +1,51 @@ +import ngModule from '../../module'; +import Dialog from 'core/components/dialog'; +import './style.scss'; + +class Controller extends Dialog { + constructor($element, $, $transclude) { + super($element, $, $transclude); + + this.isInvoicing = false; + this.invoice = { + maxShipped: new Date() + }; + } + + responseHandler(response) { + try { + if (response !== 'accept') + return super.responseHandler(response); + + if (this.invoice.clientFk && !this.invoice.maxShipped) + throw new Error('Client and the max shipped should be filled'); + + if (!this.invoice.serial || !this.invoice.taxArea) + throw new Error('Some fields are required'); + + this.isInvoicing = true; + return this.$http.post(`InvoiceOuts/createManualInvoice`, this.invoice) + .then(res => { + this.$state.go('invoiceOut.card.summary', {id: res.data.id}); + super.responseHandler(response); + }) + .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))) + .finally(() => this.isInvoicing = false); + } catch (e) { + this.vnApp.showError(this.$t(e.message)); + this.isInvoicing = false; + return false; + } + } +} + +Controller.$inject = ['$element', '$scope', '$transclude']; + +ngModule.vnComponent('vnInvoiceOutManual', { + slotTemplate: require('./index.html'), + controller: Controller, + bindings: { + ticketFk: ' { + describe('Component vnInvoiceOutManual', () => { + let controller; + let $httpBackend; + + beforeEach(ngModule('invoiceOut')); + + beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => { + $httpBackend = _$httpBackend_; + let $scope = $rootScope.$new(); + const $element = angular.element(''); + const $transclude = { + $$boundTransclude: { + $$slots: [] + } + }; + controller = $componentController('vnInvoiceOutManual', {$element, $scope, $transclude}); + })); + + describe('responseHandler()', () => { + it('should throw an error when clientFk property is set and the maxShipped is not filled', () => { + jest.spyOn(controller.vnApp, 'showError'); + + controller.invoice = { + clientFk: 1101, + serial: 'T', + taxArea: 'B' + }; + + controller.responseHandler('accept'); + + expect(controller.vnApp.showError).toHaveBeenCalledWith(`Client and the max shipped should be filled`); + }); + + it('should throw an error when some required fields are not filled in', () => { + jest.spyOn(controller.vnApp, 'showError'); + + controller.invoice = { + ticketFk: 1101 + }; + + controller.responseHandler('accept'); + + expect(controller.vnApp.showError).toHaveBeenCalledWith(`Some fields are required`); + }); + + it('should make an http POST query and then call to the parent showSuccess() method', () => { + jest.spyOn(controller.vnApp, 'showSuccess'); + + controller.invoice = { + ticketFk: 1101, + serial: 'T', + taxArea: 'B' + }; + + $httpBackend.expect('POST', `InvoiceOuts/createManualInvoice`).respond({id: 1}); + controller.responseHandler('accept'); + $httpBackend.flush(); + + expect(controller.vnApp.showSuccess).toHaveBeenCalled(); + }); + }); + }); +}); diff --git a/modules/invoiceOut/front/index/manual/locale/es.yml b/modules/invoiceOut/front/index/manual/locale/es.yml new file mode 100644 index 000000000..370e823d0 --- /dev/null +++ b/modules/invoiceOut/front/index/manual/locale/es.yml @@ -0,0 +1,6 @@ +Create manual invoice: Crear factura manual +Some fields are required: Algunos campos son obligatorios +Client and max shipped fields should be filled: Los campos de cliente y fecha límite deben rellenarse +Max date: Fecha límite +Serial: Serie +Invoicing in progress...: Facturación en progreso... \ No newline at end of file diff --git a/modules/invoiceOut/front/index/manual/style.scss b/modules/invoiceOut/front/index/manual/style.scss new file mode 100644 index 000000000..18e6f3513 --- /dev/null +++ b/modules/invoiceOut/front/index/manual/style.scss @@ -0,0 +1,17 @@ +@import "variables"; + +.vn-invoice-out-manual { + tpl-body { + width: 500px; + + .progress { + font-weight: bold; + text-align: center; + font-size: 1.5rem; + color: $color-primary; + vn-horizontal { + justify-content: center + } + } + } +} \ No newline at end of file diff --git a/modules/item/back/model-config.json b/modules/item/back/model-config.json index 9f101f9c7..ab680b696 100644 --- a/modules/item/back/model-config.json +++ b/modules/item/back/model-config.json @@ -65,18 +65,6 @@ "Tag": { "dataSource": "vn" }, - "TaxClass": { - "dataSource": "vn" - }, - "TaxClassCode": { - "dataSource": "vn" - }, - "TaxCode": { - "dataSource": "vn" - }, - "TaxType": { - "dataSource": "vn" - }, "FixedPrice": { "dataSource": "vn" } diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js index d8c2dc5c9..ce7380568 100644 --- a/modules/ticket/back/methods/ticket/makeInvoice.js +++ b/modules/ticket/back/methods/ticket/makeInvoice.js @@ -100,13 +100,14 @@ module.exports = function(Self) { }, myOptions); } - if (serial != 'R' && invoiceId) { + if (serial != 'R' && invoiceId) await Self.rawSql('CALL invoiceOutBooking(?)', [invoiceId], myOptions); - await models.InvoiceOut.createPdf(ctx, invoiceId, myOptions); - } if (tx) await tx.commit(); + if (serial != 'R' && invoiceId) + await models.InvoiceOut.createPdf(ctx, invoiceId); + return {invoiceFk: invoiceId, serial: serial}; } catch (e) { if (tx) await tx.rollback(); diff --git a/package-lock.json b/package-lock.json index 914666bcb..d3b0502b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -101,7 +101,6 @@ "loopback": { "name": "vn-loopback", "version": "1.0.0", - "integrity": "sha1-S06UTBRgMQ2KQ8X6J7DX5bbSnEI=", "license": "GPL-3.0" }, "node_modules/@babel/code-frame": { @@ -144,10 +143,6 @@ }, "engines": { "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" } }, "node_modules/@babel/generator": { @@ -190,9 +185,6 @@ "@babel/helper-validator-option": "^7.12.17", "browserslist": "^4.14.5", "semver": "^6.3.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-class-features-plugin": { @@ -206,9 +198,6 @@ "@babel/helper-optimise-call-expression": "^7.12.13", "@babel/helper-replace-supers": "^7.13.0", "@babel/helper-split-export-declaration": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { @@ -219,9 +208,6 @@ "dependencies": { "@babel/helper-annotate-as-pure": "^7.12.13", "regexpu-core": "^4.7.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-define-polyfill-provider": { @@ -238,9 +224,6 @@ "lodash.debounce": "^4.0.8", "resolve": "^1.14.2", "semver": "^6.1.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0-0" } }, "node_modules/@babel/helper-explode-assignable-expression": { @@ -449,9 +432,6 @@ "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-remap-async-to-generator": "^7.13.0", "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-class-properties": { @@ -462,9 +442,6 @@ "dependencies": { "@babel/helper-create-class-features-plugin": "^7.13.0", "@babel/helper-plugin-utils": "^7.13.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-dynamic-import": { @@ -475,9 +452,6 @@ "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-export-namespace-from": { @@ -488,9 +462,6 @@ "dependencies": { "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-json-strings": { @@ -501,9 +472,6 @@ "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { @@ -514,9 +482,6 @@ "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { @@ -527,9 +492,6 @@ "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-numeric-separator": { @@ -540,9 +502,6 @@ "dependencies": { "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { @@ -556,9 +515,6 @@ "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-transform-parameters": "^7.13.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-optional-catch-binding": { @@ -569,9 +525,6 @@ "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-optional-chaining": { @@ -583,9 +536,6 @@ "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-private-methods": { @@ -596,9 +546,6 @@ "dependencies": { "@babel/helper-create-class-features-plugin": "^7.13.0", "@babel/helper-plugin-utils": "^7.13.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-unicode-property-regex": { @@ -612,9 +559,6 @@ }, "engines": { "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-async-generators": { @@ -624,9 +568,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-bigint": { @@ -636,9 +577,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-class-properties": { @@ -648,9 +586,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-dynamic-import": { @@ -660,9 +595,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-export-namespace-from": { @@ -672,9 +604,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-import-meta": { @@ -684,9 +613,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-json-strings": { @@ -696,9 +622,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { @@ -708,9 +631,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { @@ -720,9 +640,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-numeric-separator": { @@ -732,9 +649,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-object-rest-spread": { @@ -744,9 +658,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { @@ -756,9 +667,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-optional-chaining": { @@ -768,9 +676,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-top-level-await": { @@ -780,9 +685,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-arrow-functions": { @@ -792,9 +694,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-async-to-generator": { @@ -806,9 +705,6 @@ "@babel/helper-module-imports": "^7.12.13", "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-remap-async-to-generator": "^7.13.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { @@ -818,9 +714,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-block-scoping": { @@ -830,9 +723,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-classes": { @@ -848,9 +738,6 @@ "@babel/helper-replace-supers": "^7.13.0", "@babel/helper-split-export-declaration": "^7.12.13", "globals": "^11.1.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-computed-properties": { @@ -860,9 +747,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-destructuring": { @@ -872,9 +756,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-dotall-regex": { @@ -885,9 +766,6 @@ "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.12.13", "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-duplicate-keys": { @@ -897,9 +775,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { @@ -910,9 +785,6 @@ "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-for-of": { @@ -922,9 +794,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-function-name": { @@ -935,9 +804,6 @@ "dependencies": { "@babel/helper-function-name": "^7.12.13", "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-literals": { @@ -947,9 +813,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-member-expression-literals": { @@ -959,9 +822,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-amd": { @@ -973,9 +833,6 @@ "@babel/helper-module-transforms": "^7.13.0", "@babel/helper-plugin-utils": "^7.13.0", "babel-plugin-dynamic-import-node": "^2.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-commonjs": { @@ -988,9 +845,6 @@ "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-simple-access": "^7.12.13", "babel-plugin-dynamic-import-node": "^2.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-systemjs": { @@ -1004,9 +858,6 @@ "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-validator-identifier": "^7.12.11", "babel-plugin-dynamic-import-node": "^2.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-umd": { @@ -1017,9 +868,6 @@ "dependencies": { "@babel/helper-module-transforms": "^7.13.0", "@babel/helper-plugin-utils": "^7.13.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { @@ -1029,9 +877,6 @@ "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-transform-new-target": { @@ -1041,9 +886,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-object-super": { @@ -1054,9 +896,6 @@ "dependencies": { "@babel/helper-plugin-utils": "^7.12.13", "@babel/helper-replace-supers": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-parameters": { @@ -1066,9 +905,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-property-literals": { @@ -1078,9 +914,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-regenerator": { @@ -1090,9 +923,6 @@ "dev": true, "dependencies": { "regenerator-transform": "^0.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-reserved-words": { @@ -1102,9 +932,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-shorthand-properties": { @@ -1114,9 +941,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-spread": { @@ -1127,9 +951,6 @@ "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-sticky-regex": { @@ -1139,9 +960,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-template-literals": { @@ -1151,9 +969,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-typeof-symbol": { @@ -1163,9 +978,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-escapes": { @@ -1175,9 +987,6 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-regex": { @@ -1188,9 +997,6 @@ "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.12.13", "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/preset-env": { @@ -1267,9 +1073,6 @@ "babel-plugin-polyfill-regenerator": "^0.1.2", "core-js-compat": "^3.9.0", "semver": "^6.3.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/preset-modules": { @@ -1283,9 +1086,6 @@ "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/register": { @@ -1299,9 +1099,6 @@ "make-dir": "^2.1.0", "pirates": "^4.0.0", "source-map-support": "^0.5.16" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/runtime": { @@ -1413,9 +1210,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { @@ -1604,9 +1398,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@jest/console/node_modules/chalk": { @@ -1620,9 +1411,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/console/node_modules/color-convert": { @@ -1713,9 +1501,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@jest/core/node_modules/chalk": { @@ -1729,9 +1514,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/core/node_modules/color-convert": { @@ -1771,9 +1553,6 @@ }, "bin": { "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@jest/core/node_modules/supports-color": { @@ -1882,9 +1661,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@jest/reporters/node_modules/chalk": { @@ -1898,9 +1674,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/reporters/node_modules/color-convert": { @@ -2041,9 +1814,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@jest/transform/node_modules/chalk": { @@ -2057,9 +1827,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/transform/node_modules/color-convert": { @@ -2136,9 +1903,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@jest/types/node_modules/chalk": { @@ -2152,9 +1916,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/types/node_modules/color-convert": { @@ -2808,10 +2569,7 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } + "dev": true }, "node_modules/acorn-walk": { "version": "7.2.0", @@ -2842,29 +2600,19 @@ "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ajv-errors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true, - "peerDependencies": { - "ajv": ">=5.0.0" - } + "dev": true }, "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } + "dev": true }, "node_modules/amdefine": { "version": "1.0.1", @@ -2952,9 +2700,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-gray": { @@ -3560,7 +3305,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "bin": { "uuid": "bin/uuid" } @@ -3612,9 +3356,6 @@ }, "engines": { "node": ">= 10.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/babel-jest/node_modules/ansi-styles": { @@ -3627,9 +3368,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/babel-jest/node_modules/chalk": { @@ -3643,9 +3381,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/babel-jest/node_modules/color-convert": { @@ -3700,10 +3435,6 @@ }, "engines": { "node": ">= 8.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" } }, "node_modules/babel-loader/node_modules/find-cache-dir": { @@ -3718,9 +3449,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, "node_modules/babel-loader/node_modules/make-dir": { @@ -3733,9 +3461,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/babel-loader/node_modules/pkg-dir": { @@ -3799,9 +3524,6 @@ "@babel/compat-data": "^7.13.0", "@babel/helper-define-polyfill-provider": "^0.1.5", "semver": "^6.1.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-polyfill-corejs3": { @@ -3812,9 +3534,6 @@ "dependencies": { "@babel/helper-define-polyfill-provider": "^0.1.5", "core-js-compat": "^3.8.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-polyfill-regenerator": { @@ -3824,9 +3543,6 @@ "dev": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.1.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, "node_modules/babel-preset-current-node-syntax": { @@ -3847,9 +3563,6 @@ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/babel-preset-jest": { @@ -3863,9 +3576,6 @@ }, "engines": { "node": ">= 10.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/bach": { @@ -3984,21 +3694,7 @@ "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "node_modules/batch": { "version": "0.6.1", @@ -4073,6 +3769,16 @@ "node": ">=0.10.0" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/bl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", @@ -4401,21 +4107,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "dev": true }, "node_modules/browserify-zlib": { "version": "0.2.0", @@ -4443,10 +4135,6 @@ }, "engines": { "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" } }, "node_modules/bser": { @@ -4615,9 +4303,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cacheable-request/node_modules/lowercase-keys": { @@ -4647,9 +4332,6 @@ "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/callsites": { @@ -4711,11 +4393,7 @@ "version": "1.0.30001237", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001237.tgz", "integrity": "sha512-pDHgRndit6p1NR2GhzMbQ6CkRrp4VKuSsqbcLeOQppYPKOYkKT/6ZvZDvKJUqcmtyWIAHuZq3SVS2vc1egCZzw==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } + "dev": true }, "node_modules/canonical-json": { "version": "0.0.4", @@ -4781,7 +4459,6 @@ "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", "dev": true, "dependencies": { "anymatch": "^2.0.0", @@ -4800,25 +4477,6 @@ "fsevents": "^1.2.7" } }, - "node_modules/chokidar/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, "node_modules/chokidar/node_modules/glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -5440,12 +5098,7 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.9.1.tgz", "integrity": "sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } + "dev": true }, "node_modules/core-js-compat": { "version": "3.9.1", @@ -5455,10 +5108,6 @@ "dependencies": { "browserslist": "^4.16.3", "semver": "7.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" } }, "node_modules/core-js-compat/node_modules/semver": { @@ -5473,12 +5122,7 @@ "node_modules/core-js-pure": { "version": "3.9.1", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.9.1.tgz", - "integrity": "sha512-laz3Zx0avrw9a4QEIdmIblnVuJz8W51leY9iLThatCsFawWxC3sE4guASC78JbCin+DkwMpCdp1AVAuzL/GN7A==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } + "integrity": "sha512-laz3Zx0avrw9a4QEIdmIblnVuJz8W51leY9iLThatCsFawWxC3sE4guASC78JbCin+DkwMpCdp1AVAuzL/GN7A==" }, "node_modules/core-util-is": { "version": "1.0.2", @@ -5618,9 +5262,6 @@ }, "engines": { "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" } }, "node_modules/css-loader/node_modules/schema-utils": { @@ -5648,9 +5289,6 @@ "domhandler": "^4.2.0", "domutils": "^2.6.0", "nth-check": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" } }, "node_modules/css-select/node_modules/dom-serializer": { @@ -5662,22 +5300,13 @@ "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, "node_modules/css-select/node_modules/domelementtype": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] + "dev": true }, "node_modules/css-select/node_modules/domhandler": { "version": "4.2.0", @@ -5689,9 +5318,6 @@ }, "engines": { "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" } }, "node_modules/css-select/node_modules/domutils": { @@ -5703,19 +5329,13 @@ "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" } }, "node_modules/css-select/node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } + "dev": true }, "node_modules/css-what": { "version": "5.0.1", @@ -5724,9 +5344,6 @@ "dev": true, "engines": { "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" } }, "node_modules/cssesc": { @@ -5847,19 +5464,14 @@ } }, "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } } }, "node_modules/decamelize": { @@ -5895,9 +5507,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/deep-equal": { @@ -5912,9 +5521,6 @@ "object-is": "^1.0.1", "object-keys": "^1.1.1", "regexp.prototype.flags": "^1.2.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/deep-extend": { @@ -6324,21 +5930,12 @@ "node_modules/dom-serializer/node_modules/domelementtype": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", - "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] + "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==" }, "node_modules/dom-serializer/node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, "node_modules/domain-browser": { "version": "1.2.0", @@ -6542,7 +6139,6 @@ "version": "2.7.4", "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", - "hasInstallScript": true, "engines": { "node": ">=0.10.0" } @@ -6589,9 +6185,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, "node_modules/emoji-regex": { @@ -6733,9 +6326,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es-to-primitive": { @@ -6750,9 +6340,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es5-ext": { @@ -6994,9 +6581,6 @@ }, "engines": { "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-config-google": { @@ -7006,9 +6590,6 @@ "dev": true, "engines": { "node": ">=0.10.0" - }, - "peerDependencies": { - "eslint": ">=5.4.0" } }, "node_modules/eslint-plugin-jasmine": { @@ -7044,9 +6625,6 @@ }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { @@ -7086,9 +6664,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/eslint/node_modules/chalk": { @@ -7102,9 +6677,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/eslint/node_modules/color-convert": { @@ -7135,9 +6707,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/has-flag": { @@ -7195,9 +6764,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/yallist": { @@ -7380,9 +6946,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/execa/node_modules/get-stream": { @@ -7394,9 +6957,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/execa/node_modules/is-stream": { @@ -7510,9 +7070,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/expect/node_modules/color-convert": { @@ -7732,9 +7289,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/extract-zip/node_modules/pump": { @@ -7891,9 +7445,6 @@ }, "engines": { "node": ">= 4.3 < 5.0.0 || >= 5.10" - }, - "peerDependencies": { - "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0" } }, "node_modules/file-loader/node_modules/schema-utils": { @@ -7917,6 +7468,13 @@ "node": ">=6" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "node_modules/filed-mimefix": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/filed-mimefix/-/filed-mimefix-0.1.3.tgz", @@ -8190,9 +7748,6 @@ }, "bin": { "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/flatted": { @@ -8216,19 +7771,8 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], "engines": { "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } } }, "node_modules/for-in": { @@ -8276,10 +7820,7 @@ "node_modules/formidable": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", - "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==", - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" - } + "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==" }, "node_modules/forwarded": { "version": "0.1.2", @@ -8374,17 +7915,21 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, "hasInstallScript": true, "optional": true, "os": [ "darwin" ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 4.0" } }, "node_modules/fstream": { @@ -8557,9 +8102,6 @@ "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-package-type": { @@ -8624,9 +8166,6 @@ }, "engines": { "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { @@ -9220,9 +8759,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/gulp-nodemon/node_modules/anymatch": { @@ -9264,9 +8800,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gulp-nodemon/node_modules/braces": { @@ -9334,9 +8867,6 @@ "dev": true, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gulp-nodemon/node_modules/color-convert": { @@ -9428,6 +8958,19 @@ "node": ">=8" } }, + "node_modules/gulp-nodemon/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/gulp-nodemon/node_modules/get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -9450,9 +8993,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gulp-nodemon/node_modules/got": { @@ -9524,9 +9064,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gulp-nodemon/node_modules/is-npm": { @@ -9587,9 +9124,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gulp-nodemon/node_modules/make-dir/node_modules/semver": { @@ -9615,7 +9149,6 @@ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", "dev": true, - "hasInstallScript": true, "dependencies": { "chokidar": "^3.2.2", "debug": "^3.2.6", @@ -9633,10 +9166,6 @@ }, "engines": { "node": ">=8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" } }, "node_modules/gulp-nodemon/node_modules/package-json": { @@ -9769,9 +9298,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gulp-nodemon/node_modules/to-regex-range": { @@ -9829,9 +9355,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" } }, "node_modules/gulp-nodemon/node_modules/url-parse-lax": { @@ -9885,7 +9408,6 @@ "version": "3.0.8", "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", - "deprecated": "gulp-util is deprecated - replace it, following the guidelines at https://medium.com/gulpjs/gulp-util-ca3b1f9f9ac5", "dev": true, "dependencies": { "array-differ": "^1.0.0", @@ -10082,7 +9604,6 @@ "version": "5.1.5", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -10134,10 +9655,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "dev": true }, "node_modules/has-flag": { "version": "3.0.0", @@ -10166,9 +9684,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-unicode": { @@ -10256,21 +9771,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "dev": true }, "node_modules/hash-stream-validation": { "version": "0.2.4", @@ -10574,9 +10075,6 @@ }, "engines": { "node": ">=6.9" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" } }, "node_modules/htmlparser2": { @@ -11003,9 +10501,6 @@ }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-fresh/node_modules/resolve-from": { @@ -11242,9 +10737,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-arrayish": { @@ -11257,10 +10749,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "dev": true }, "node_modules/is-binary-path": { "version": "1.0.1", @@ -11284,9 +10773,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-buffer": { @@ -11301,9 +10787,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-ci": { @@ -11325,9 +10808,6 @@ "dev": true, "dependencies": { "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-data-descriptor": { @@ -11361,9 +10841,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-descriptor": { @@ -11391,9 +10868,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-extendable": { @@ -11421,9 +10895,6 @@ "dev": true, "engines": { "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-fullwidth-code-point": { @@ -11487,9 +10958,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-npm": { @@ -11520,9 +10988,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-number/node_modules/kind-of": { @@ -11621,9 +11086,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-relative": { @@ -11666,9 +11128,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-symbol": { @@ -11681,9 +11140,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-typedarray": { @@ -11845,9 +11301,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/istanbul-lib-report/node_modules/supports-color": { @@ -11902,7 +11355,6 @@ "version": "0.26.3", "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", - "deprecated": "Jade has been renamed to pug, please install the latest version of pug instead of jade", "dependencies": { "commander": "0.6.1", "mkdirp": "0.3.0" @@ -11923,7 +11375,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", "engines": { "node": "*" } @@ -12089,9 +11540,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-cli/node_modules/chalk": { @@ -12105,9 +11553,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-cli/node_modules/cliui": { @@ -12280,14 +11725,6 @@ }, "engines": { "node": ">= 10.14.2" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } } }, "node_modules/jest-config/node_modules/ansi-styles": { @@ -12300,9 +11737,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-config/node_modules/chalk": { @@ -12316,9 +11750,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-config/node_modules/color-convert": { @@ -12385,9 +11816,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-diff/node_modules/chalk": { @@ -12401,9 +11829,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-diff/node_modules/color-convert": { @@ -12483,9 +11908,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-each/node_modules/chalk": { @@ -12499,9 +11921,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-each/node_modules/color-convert": { @@ -12627,6 +12046,19 @@ "node": ">= 8" } }, + "node_modules/jest-haste-map/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/jest-jasmine2": { "version": "26.6.3", "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", @@ -12666,9 +12098,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-jasmine2/node_modules/chalk": { @@ -12682,9 +12111,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-jasmine2/node_modules/color-convert": { @@ -12889,9 +12315,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-matcher-utils/node_modules/chalk": { @@ -12905,9 +12328,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-matcher-utils/node_modules/color-convert": { @@ -12979,9 +12399,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-message-util/node_modules/chalk": { @@ -12995,9 +12412,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-message-util/node_modules/color-convert": { @@ -13059,14 +12473,6 @@ "dev": true, "engines": { "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } } }, "node_modules/jest-regex-util": { @@ -13121,9 +12527,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-resolve/node_modules/chalk": { @@ -13137,9 +12540,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-resolve/node_modules/color-convert": { @@ -13222,9 +12622,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-runner/node_modules/chalk": { @@ -13238,9 +12635,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-runner/node_modules/color-convert": { @@ -13333,9 +12727,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-runtime/node_modules/chalk": { @@ -13349,9 +12740,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-runtime/node_modules/cliui": { @@ -13547,9 +12935,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-snapshot/node_modules/chalk": { @@ -13563,9 +12948,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-snapshot/node_modules/color-convert": { @@ -13667,9 +13049,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-util/node_modules/chalk": { @@ -13683,9 +13062,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-util/node_modules/color-convert": { @@ -13754,9 +13130,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-validate/node_modules/camelcase": { @@ -13766,9 +13139,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-validate/node_modules/chalk": { @@ -13782,9 +13152,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-validate/node_modules/color-convert": { @@ -13854,9 +13221,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-watcher/node_modules/chalk": { @@ -13870,9 +13234,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-watcher/node_modules/color-convert": { @@ -14035,14 +13396,6 @@ }, "engines": { "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } } }, "node_modules/jsdom/node_modules/acorn": { @@ -14146,7 +13499,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "optionalDependencies": { + "dependencies": { "graceful-fs": "^4.1.6" } }, @@ -14677,10 +14030,6 @@ "dev": true, "engines": { "node": ">= 0.6.0" - }, - "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/loglevel" } }, "node_modules/long": { @@ -14842,9 +14191,6 @@ "integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==", "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sindresorhus/invert-kv?sponsor=1" } }, "node_modules/loopback-connector-mysql/node_modules/lcid": { @@ -14882,9 +14228,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/loopback-connector-mysql/node_modules/strong-globalize": { @@ -14914,11 +14257,6 @@ }, "engines": { "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } } }, "node_modules/loopback-connector-remote": { @@ -14944,9 +14282,6 @@ "integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==", "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sindresorhus/invert-kv?sponsor=1" } }, "node_modules/loopback-connector/node_modules/lcid": { @@ -14984,9 +14319,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/loopback-connector/node_modules/strong-globalize": { @@ -15223,7 +14555,6 @@ "version": "6.4.11", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.4.11.tgz", "integrity": "sha512-BVZBDi+aJV4O38rxsUh164Dk1NCqgh6Cm0rQSb9SK/DHGll/DrCMnycVDD7msJgZCnmVa8ASo8EZzR7jsgTukQ==", - "hasInstallScript": true, "engines": { "node": ">=6.0.0" } @@ -15675,7 +15006,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", - "deprecated": "Package renamed as '@messageformat/core', see messageformat.github.io for more details. 'messageformat' will eventually provide a polyfill for Intl.MessageFormat, once it's been defined by Unicode & ECMA.", "dependencies": { "make-plural": "^4.3.0", "messageformat-formatters": "^2.0.1", @@ -15696,11 +15026,11 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", + "dependencies": { + "minimist": "^1.2.0" + }, "bin": { "make-plural": "bin/make-plural" - }, - "optionalDependencies": { - "minimist": "^1.2.0" } }, "node_modules/methods": { @@ -15832,9 +15162,6 @@ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/minimalistic-assert": { @@ -16022,7 +15349,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", - "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue", "dependencies": { "lru-cache": "2", "sigmund": "~1.0.0" @@ -16040,7 +15366,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", "dependencies": { "minimist": "0.0.8" }, @@ -16678,7 +16003,6 @@ "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", "dev": true, - "hasInstallScript": true, "dependencies": { "async-foreach": "^0.1.3", "chalk": "^1.1.1", @@ -16822,9 +16146,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/node.extend": { @@ -16880,7 +16201,6 @@ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", "dev": true, - "hasInstallScript": true, "dependencies": { "chokidar": "^2.1.8", "debug": "^3.2.6", @@ -17015,9 +16335,6 @@ "dev": true, "dependencies": { "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" } }, "node_modules/number-is-nan": { @@ -17085,10 +16402,7 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "dev": true }, "node_modules/object-is": { "version": "1.1.5", @@ -17101,9 +16415,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-keys": { @@ -17140,9 +16451,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.defaults": { @@ -17172,9 +16480,6 @@ }, "engines": { "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.map": { @@ -17256,9 +16561,6 @@ }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/opn": { @@ -17510,9 +16812,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-finally": { @@ -17540,9 +16839,6 @@ }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { @@ -17696,9 +16992,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parse-node-version": { @@ -17898,9 +17191,6 @@ "dev": true, "engines": { "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pify": { @@ -18148,10 +17438,6 @@ }, "engines": { "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" } }, "node_modules/postcss-modules-extract-imports": { @@ -18290,9 +17576,6 @@ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/prebuild-install/node_modules/pump": { @@ -18374,9 +17657,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/pretty-format/node_modules/color-convert": { @@ -18558,7 +17838,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-7.1.0.tgz", "integrity": "sha512-lqOLzqCKdh7yUAHvK6LxgOpQrL8Bv1/jvS8MLDXxcNms2rlM3E8p/Wlwc7efbRZ0twxTzUeqjN5EqrTwxOwc9g==", - "hasInstallScript": true, "dependencies": { "debug": "^4.1.0", "devtools-protocol": "0.0.847576", @@ -18620,9 +17899,6 @@ }, "bin": { "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/qs": { @@ -18637,7 +17913,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "deprecated": "The", "engines": { "node": ">=0.4.x" } @@ -18722,9 +17997,6 @@ }, "engines": { "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.3.0" } }, "node_modules/raw-loader/node_modules/schema-utils": { @@ -18816,9 +18088,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/read-pkg-up/node_modules/type-fest": { @@ -19118,9 +18387,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/regexpp": { @@ -19130,9 +18396,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/regexpu-core": { @@ -19274,22 +18537,13 @@ "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, "node_modules/renderkid/node_modules/domelementtype": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] + "dev": true }, "node_modules/renderkid/node_modules/domhandler": { "version": "4.2.0", @@ -19301,9 +18555,6 @@ }, "engines": { "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" } }, "node_modules/renderkid/node_modules/domutils": { @@ -19315,32 +18566,19 @@ "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" } }, "node_modules/renderkid/node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } + "dev": true }, "node_modules/renderkid/node_modules/htmlparser2": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.0.0", @@ -19417,7 +18655,6 @@ "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -19454,16 +18691,12 @@ }, "engines": { "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" } }, "node_modules/request-promise-native": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", "dev": true, "dependencies": { "request-promise-core": "1.1.4", @@ -19472,9 +18705,6 @@ }, "engines": { "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" } }, "node_modules/request-promise-native/node_modules/tough-cookie": { @@ -19552,7 +18782,7 @@ "resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz", "integrity": "sha1-LhsY2RPDuqcqWk03O28Tjd0sMr0=", "dependencies": { - "js-yaml": "" + "js-yaml": "^4.0.0" } }, "node_modules/require-yaml/node_modules/argparse": { @@ -19561,9 +18791,9 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/require-yaml/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", "dependencies": { "argparse": "^2.0.1" }, @@ -19585,9 +18815,6 @@ "dependencies": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-cwd": { @@ -19640,7 +18867,6 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", "dev": true }, "node_modules/responselike": { @@ -19744,7 +18970,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", "dev": true, "dependencies": { "@cnakazawa/watch": "^1.0.3", @@ -20002,9 +19227,6 @@ "lodash": "^4.0.0", "scss-tokenizer": "^0.2.3", "yargs": "^13.3.2" - }, - "bin": { - "sassgraph": "bin/sassgraph" } }, "node_modules/sass-graph/node_modules/ansi-regex": { @@ -20191,9 +19413,6 @@ }, "engines": { "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^3.0.0 || ^4.0.0" } }, "node_modules/sass-loader/node_modules/pify": { @@ -20253,10 +19472,6 @@ }, "engines": { "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" } }, "node_modules/scss-tokenizer": { @@ -20598,7 +19813,6 @@ "version": "0.27.2", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.27.2.tgz", "integrity": "sha512-w3FVoONPG/x5MXCc3wsjOS+b9h3CI60qkus6EPQU4dkT0BDm0PyGhDCK6KhtfT3/vbeOMOXAKFNSw+I3QGWkMA==", - "hasInstallScript": true, "dependencies": { "array-flatten": "^3.0.0", "color": "^3.1.3", @@ -20613,9 +19827,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://opencollective.com/libvips" } }, "node_modules/sharp/node_modules/array-flatten": { @@ -20710,40 +19921,12 @@ "node_modules/simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "node_modules/simple-get": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.0.tgz", "integrity": "sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", @@ -20790,9 +19973,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/slice-ansi/node_modules/ansi-styles": { @@ -20805,9 +19985,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/slice-ansi/node_modules/color-convert": { @@ -21035,9 +20212,6 @@ "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/soap/node_modules/strip-bom": { @@ -21336,11 +20510,6 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, "engines": { "node": ">=0.10.0" } @@ -21567,9 +20736,6 @@ "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { @@ -21580,9 +20746,6 @@ "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/strip-ansi": { @@ -21644,9 +20807,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strong-error-handler": { @@ -21941,9 +21101,6 @@ "integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==", "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sindresorhus/invert-kv?sponsor=1" } }, "node_modules/strong-remoting/node_modules/lcid": { @@ -21981,9 +21138,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strong-remoting/node_modules/strong-error-handler": { @@ -22176,20 +21330,6 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -22211,21 +21351,7 @@ "node_modules/swagger-client/node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "node_modules/swagger-client/node_modules/punycode": { "version": "1.3.2", @@ -22238,9 +21364,6 @@ "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", "engines": { "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/swagger-client/node_modules/url": { @@ -22255,8 +21378,7 @@ "node_modules/swagger-ui": { "version": "2.2.10", "resolved": "https://registry.npmjs.org/swagger-ui/-/swagger-ui-2.2.10.tgz", - "integrity": "sha1-sl56IWZOXZC/OR2zDbCN5B6FLXs=", - "deprecated": "No longer maintained, please upgrade to swagger-ui@3." + "integrity": "sha1-sl56IWZOXZC/OR2zDbCN5B6FLXs=" }, "node_modules/symbol-tree": { "version": "3.2.4", @@ -22289,10 +21411,6 @@ "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/table/node_modules/is-fullwidth-code-point": { @@ -22393,20 +21511,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -22557,9 +21661,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/terser": { @@ -22597,9 +21698,6 @@ }, "engines": { "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" } }, "node_modules/terser-webpack-plugin/node_modules/is-wsl": { @@ -22780,8 +21878,7 @@ "node_modules/to-iso-string": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", - "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", - "deprecated": "to-iso-string has been deprecated, use @segment/to-iso-string instead." + "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=" }, "node_modules/to-object-path": { "version": "0.3.0", @@ -22981,9 +22078,6 @@ }, "bin": { "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" } }, "node_modules/tough-cookie": { @@ -23103,9 +22197,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/type-is": { @@ -23200,20 +22291,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -23593,7 +22670,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", "dev": true }, "node_modules/url": { @@ -23709,7 +22785,6 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "bin": { "uuid": "bin/uuid" } @@ -24045,6 +23120,7 @@ "dependencies": { "anymatch": "~3.1.1", "braces": "~3.0.2", + "fsevents": "~2.3.1", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -24053,9 +23129,6 @@ }, "engines": { "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.1" } }, "node_modules/watchpack/node_modules/fill-range": { @@ -24071,6 +23144,19 @@ "node": ">=8" } }, + "node_modules/watchpack/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/watchpack/node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -24173,18 +23259,6 @@ }, "engines": { "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - }, - "webpack-command": { - "optional": true - } } }, "node_modules/webpack-cli": { @@ -24210,9 +23284,6 @@ }, "engines": { "node": ">=6.11.5" - }, - "peerDependencies": { - "webpack": "4.x.x" } }, "node_modules/webpack-cli/node_modules/ansi-regex": { @@ -24550,9 +23621,6 @@ }, "engines": { "node": ">= 6" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" } }, "node_modules/webpack-dev-server": { @@ -24600,14 +23668,6 @@ }, "engines": { "node": ">= 6.11.5" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } } }, "node_modules/webpack-dev-server/node_modules/ansi-regex": { @@ -25288,9 +24348,6 @@ "is-number-object": "^1.0.4", "is-string": "^1.0.5", "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-module": { @@ -25468,18 +24525,6 @@ "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==", "engines": { "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } } }, "node_modules/x-xss-protection": { @@ -25516,6 +24561,14 @@ "node": ">=0.4.0" } }, + "node_modules/xml-crypto/node_modules/xmldom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz", + "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", @@ -25557,8 +24610,9 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz", "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==", + "dev": true, "engines": { - "node": ">=10.0.0" + "node": ">=0.1" } }, "node_modules/xpath": { @@ -28051,8 +27105,7 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "7.2.0", @@ -28083,15 +27136,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true, - "requires": {} + "dev": true }, "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} + "dev": true }, "amdefine": { "version": "1.0.1", @@ -29021,6 +28072,16 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", @@ -29629,17 +28690,6 @@ "upath": "^1.1.1" }, "dependencies": { - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -30494,9 +29544,9 @@ "dev": true }, "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { "ms": "2.1.2" } @@ -31550,8 +30600,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.11.0.tgz", "integrity": "sha512-z541Fs5TFaY7/35v/z100InQ2f3V2J7e3u/0yKrnImgsHjh6JWgSRngfC/mZepn/+XN16jUydt64k//kxXc1fw==", - "dev": true, - "requires": {} + "dev": true }, "eslint-plugin-jasmine": { "version": "2.10.1", @@ -32171,6 +31220,13 @@ "resolved": "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz", "integrity": "sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==" }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "filed-mimefix": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/filed-mimefix/-/filed-mimefix-0.1.3.tgz", @@ -32532,11 +31588,15 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, - "optional": true + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } }, "fstream": { "version": "1.0.12", @@ -33399,6 +32459,13 @@ "to-regex-range": "^5.0.1" } }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -35859,6 +34926,13 @@ "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true } } }, @@ -36199,8 +35273,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} + "dev": true }, "jest-regex-util": { "version": "26.0.0", @@ -41450,7 +40523,7 @@ "resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz", "integrity": "sha1-LhsY2RPDuqcqWk03O28Tjd0sMr0=", "requires": { - "js-yaml": "" + "js-yaml": "^4.0.0" }, "dependencies": { "argparse": { @@ -41459,9 +40532,9 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", "requires": { "argparse": "^2.0.1" } @@ -45136,6 +44209,13 @@ "to-regex-range": "^5.0.1" } }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -46254,8 +45334,7 @@ "ws": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz", - "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==", - "requires": {} + "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==" }, "x-xss-protection": { "version": "1.3.0", @@ -46280,6 +45359,13 @@ "requires": { "xmldom": "0.5.0", "xpath": "0.0.27" + }, + "dependencies": { + "xmldom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz", + "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==" + } } }, "xml-name-validator": { @@ -46316,7 +45402,8 @@ "xmldom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz", - "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==" + "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==", + "dev": true }, "xpath": { "version": "0.0.27",