From 7d1f3615b5541339e44d5077eaa805fb686d80af Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 14 Dec 2017 10:07:04 +0000 Subject: [PATCH 01/69] fix navigation docs issues --- docs/images/navigation-01.png | Bin 33283 -> 25301 bytes docs/images/navigation-02.png | Bin 31178 -> 28120 bytes docs/images/navigation-03.png | Bin 77214 -> 32887 bytes docs/navigation.md | 33 +++++++++++++++------------------ 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/docs/images/navigation-01.png b/docs/images/navigation-01.png index 55d205fef8968de9ad38b57c19e61f7de773b448..51fff38660d0cbb57859bb066abb6669187375f9 100644 GIT binary patch delta 21907 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 E4+wCP)c^nh literal 33283 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 Yus4KWE!PMCe&B$iuBlF$mUHBP0l`Joc>n+a literal 31178 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 literal 77214 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

o}Pl9B7#mX)KYMe_s7r@?TR8{!EpU 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 UikWwTCkB6}#^#4}4mn@`4+RTMKmY&$ diff --git a/docs/navigation.md b/docs/navigation.md index e1c656b3a..4a283a272 100644 --- a/docs/navigation.md +++ b/docs/navigation.md @@ -61,7 +61,7 @@ To change the `title` and `label` of navigation links edit the values under `BRO ```json "APP" : { ... - BROWSE: { + "BROWSE": { "PERSONAL": { "TITLE": "Personal Files", "SIDENAV_LINK": { @@ -80,21 +80,19 @@ For more information about internationalization see [Internationalization (i18n) To add custom navigation link for the application, first we need to create a component. -```src/app/components/custom-page/custom-page.component.ts``` +`src/app/components/custom-page/custom-page.component.ts` -```javascript +```js +import { Component } from '@angular/core'; - import { Component } from '@angular/core'; - - @Component({ - template: ` -

{{ title }}

+@Component({ +template: ` +

{{ title }}

` - }) - export class CustomPage { +}) +export class CustomPage { title = 'My Custom Page' - } - +} ``` Register the component in ```app.module.ts``` @@ -107,9 +105,9 @@ Register the component in ```app.module.ts``` @NgModule({ ... declarations: [ - ..., - CustomPage - ] + ..., + CustomPage + ], ... }) @@ -118,12 +116,11 @@ Register the component in ```app.module.ts``` In the `app.config.json` define a link entry which will point to the custom page ```json - { ..., "navigation": [ "main": [ ... ], - "secondary: [ ... ], + "secondary": [ ... ], "custom": [ { "icon": "work", @@ -141,7 +138,7 @@ In the `app.config.json` define a link entry which will point to the custom page Map the `/custom-route` in `app.routes.ts` as a child of `LayoutComponent` definition. -```json +```js import { CustomPage } from './components/custom-page/custom-page.component.ts'; From 926cae95cc2dc9424306d7e1186b08a434940b8a Mon Sep 17 00:00:00 2001 From: suzanadirla Date: Thu, 14 Dec 2017 12:11:00 +0200 Subject: [PATCH 02/69] update documentation (#142) * update documentation changed start command used a tags for links nested inside table and p tags, because Github did not render them correctly * set link to navigation on side-nav.md --- README.md | 2 +- docs/README.md | 2 +- docs/configuration.md | 4 ++-- docs/doc-list.md | 6 +++--- docs/side-nav.md | 3 +-- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d8e014825..e1e1bdc9b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This project was generated with [Angular CLI](https://github.com/angular/angular ## Development server -Run `ng start` for a dev server. Navigate to `http://localhost:3000/` (opens by default). +Run `npm start` for a dev server. Navigate to `http://localhost:3000/` (opens by default). The app will automatically reload if you change any of the source files. ## Code scaffolding diff --git a/docs/README.md b/docs/README.md index b139bd934..dd04a4138 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,7 +22,7 @@ This application uses the latest releases from Alfresco: - [Alfresco Community Edition 201707](https://www.alfresco.com/products/community/download)
The latest version of the Alfresco Content platform is required diff --git a/docs/configuration.md b/docs/configuration.md index c07b42711..bdf2ad0f0 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -111,7 +111,7 @@ By default, the application ships with the following rules already predefined: ```

-You can get more details on the supported rules in the following article: [Upload Service](https://github.com/Alfresco/alfresco-ng2-components/blob/master/docs/upload.service.md). +You can get more details on the supported rules in the following article: Upload Service.

### Pagination settings @@ -137,5 +137,5 @@ You can change the default settings of the pagination that gets applied to all t You can store any information in the application configuration file, and access it at runtime by using the `AppConfigService` service provided by ADF.

-Please refer to the [AppConfigService](https://github.com/Alfresco/alfresco-ng2-components/blob/master/docs/app-config.service.md) documentation to get more details on Application Configuration features and API available. +Please refer to the AppConfigService documentation to get more details on Application Configuration features and API available.

diff --git a/docs/doc-list.md b/docs/doc-list.md index 49f698bac..8fe776bc7 100644 --- a/docs/doc-list.md +++ b/docs/doc-list.md @@ -84,7 +84,7 @@ actions are automatically hidden when the user does not have permission. View - Opens the selected file using the [Preview](https://github.com/Alfresco/alfresco-content-app/tree/development/src/app/components/preview) component, + Opens the selected file using the Preview component, where the file cannot be displayed natively in a browser a PDF rendition is obtained from the repository. Not applicable @@ -110,7 +110,7 @@ actions are automatically hidden when the user does not have permission. Copy Files and folders can be copied to another location in the content repository using the - [content-node-selector](https://alfresco.github.io/adf-component-catalog/components/ContentNodeSelectorComponent.html) component; + content-node-selector component; once the copy action has completed the user is notified and can undo the action (which permanently deletes the created copies). @@ -118,7 +118,7 @@ actions are automatically hidden when the user does not have permission. Move Files and folders can be moved to another location in the content repository using the - [content-node-selector](https://alfresco.github.io/adf-component-catalog/components/ContentNodeSelectorComponent.html) component; + content-node-selector component; once the move action has completed the user is notified and can undo the action (which moves the items back to the original location). diff --git a/docs/side-nav.md b/docs/side-nav.md index 6a5b3480d..98ac4258d 100644 --- a/docs/side-nav.md +++ b/docs/side-nav.md @@ -24,5 +24,4 @@ and uploads can be canceled which will stop uploads in progress or permanently d The navigation links are configurable via the [app.config.json](https://github.com/Alfresco/alfresco-content-app/blob/master/src/app.config.json). Default configuration creates two sections. -See [How to work with the side navigation](/) for more information about configuring the side navigation. - +See [Navigation](/navigation) for more information about configuring the side navigation. From a25e6220471869fadf794089a71dfe11b07f6c48 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 14 Dec 2017 12:56:21 +0000 Subject: [PATCH 03/69] [ACA-1061] update project version (#145) [ACA-1061] update project version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 334a7cba8..223ae2c09 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "alfresco-content-app", - "version": "0.1.0", + "version": "1.0.0", "license": "LGPL-3.0", "scripts": { "ng": "ng", From b193a30aa8a60457aeda13eb93fd9f4b9c83cd46 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 14 Dec 2017 15:25:50 +0000 Subject: [PATCH 04/69] move e2e to a separate repo --- e2e/components/component.ts | 43 -- e2e/components/components.ts | 32 -- e2e/components/data-table/data-table.ts | 196 ------- .../dialog/create-edit-folder-dialog.ts | 108 ---- e2e/components/header/header.ts | 42 -- e2e/components/header/user-info.ts | 64 --- e2e/components/login/login.ts | 75 --- e2e/components/menu/menu.ts | 73 --- e2e/components/pagination/pagination.ts | 75 --- e2e/components/sidenav/sidenav.ts | 68 --- e2e/components/toolbar/toolbar-actions.ts | 68 --- e2e/components/toolbar/toolbar-breadcrumb.ts | 63 --- e2e/components/toolbar/toolbar.ts | 42 -- e2e/configs.ts | 78 --- e2e/pages/browsing-page.ts | 40 -- e2e/pages/login-page.ts | 74 --- e2e/pages/logout-page.ts | 43 -- e2e/pages/page.ts | 79 --- e2e/pages/pages.ts | 28 - e2e/suites/actions/create-folder.test.ts | 279 --------- e2e/suites/actions/edit-folder.test.ts | 190 ------- e2e/suites/actions/permanently-delete.test.ts | 113 ---- e2e/suites/actions/restore.test.ts | 147 ----- .../toolbar-multiple-selection.test.ts | 535 ------------------ .../actions/toolbar-single-selection.test.ts | 535 ------------------ e2e/suites/application/page-titles.test.ts | 133 ----- e2e/suites/authentication/login.test.ts | 179 ------ e2e/suites/authentication/logout.test.ts | 74 --- e2e/suites/list-views/empty-list.test.ts | 109 ---- e2e/suites/list-views/favorites.test.ts | 157 ----- e2e/suites/list-views/file-libraries.test.ts | 131 ----- e2e/suites/list-views/personal-files.test.ts | 159 ------ e2e/suites/list-views/recent-files.test.ts | 149 ----- e2e/suites/list-views/shared-files.test.ts | 155 ----- e2e/suites/list-views/trash.test.ts | 188 ------ e2e/suites/navigation/side-navigation.test.ts | 129 ----- e2e/suites/pagination/pag-favorites.test.ts | 186 ------ .../pagination/pag-personal-files.test.ts | 183 ------ .../pagination/pag-recent-files.test.ts | 189 ------- .../pagination/pag-shared-files.test.ts | 193 ------- e2e/suites/pagination/pag-trash.test.ts | 184 ------ .../apis/favorites/favorites-api.ts | 86 --- .../apis/nodes/node-body-create.ts | 38 -- .../apis/nodes/node-content-tree.ts | 85 --- .../repo-client/apis/nodes/nodes-api.ts | 104 ---- .../apis/people/people-api-models.ts | 43 -- .../repo-client/apis/people/people-api.ts | 60 -- e2e/utilities/repo-client/apis/repo-api.ts | 71 --- .../apis/shared-links/shared-links-api.ts | 50 -- .../apis/sites/sites-api-models.ts | 42 -- .../repo-client/apis/sites/sites-api.ts | 111 ---- .../repo-client/apis/trashcan/trashcan-api.ts | 54 -- .../repo-client/repo-client-models.ts | 46 -- e2e/utilities/repo-client/repo-client.ts | 57 -- .../reporters/console/console-logger.ts | 79 --- e2e/utilities/reporters/console/console.ts | 90 --- .../rest-client/rest-client-models.ts | 63 --- e2e/utilities/rest-client/rest-client.ts | 89 --- e2e/utilities/utils.ts | 44 -- package.json | 1 - protractor.conf.js | 6 - yarn.lock | 225 +++++--- 62 files changed, 135 insertions(+), 6897 deletions(-) delete mode 100644 e2e/components/component.ts delete mode 100644 e2e/components/components.ts delete mode 100644 e2e/components/data-table/data-table.ts delete mode 100644 e2e/components/dialog/create-edit-folder-dialog.ts delete mode 100644 e2e/components/header/header.ts delete mode 100644 e2e/components/header/user-info.ts delete mode 100644 e2e/components/login/login.ts delete mode 100644 e2e/components/menu/menu.ts delete mode 100644 e2e/components/pagination/pagination.ts delete mode 100644 e2e/components/sidenav/sidenav.ts delete mode 100644 e2e/components/toolbar/toolbar-actions.ts delete mode 100644 e2e/components/toolbar/toolbar-breadcrumb.ts delete mode 100644 e2e/components/toolbar/toolbar.ts delete mode 100644 e2e/configs.ts delete mode 100644 e2e/pages/browsing-page.ts delete mode 100644 e2e/pages/login-page.ts delete mode 100644 e2e/pages/logout-page.ts delete mode 100644 e2e/pages/page.ts delete mode 100644 e2e/pages/pages.ts delete mode 100644 e2e/suites/actions/create-folder.test.ts delete mode 100644 e2e/suites/actions/edit-folder.test.ts delete mode 100644 e2e/suites/actions/permanently-delete.test.ts delete mode 100644 e2e/suites/actions/restore.test.ts delete mode 100644 e2e/suites/actions/toolbar-multiple-selection.test.ts delete mode 100644 e2e/suites/actions/toolbar-single-selection.test.ts delete mode 100644 e2e/suites/application/page-titles.test.ts delete mode 100644 e2e/suites/authentication/login.test.ts delete mode 100644 e2e/suites/authentication/logout.test.ts delete mode 100644 e2e/suites/list-views/empty-list.test.ts delete mode 100644 e2e/suites/list-views/favorites.test.ts delete mode 100644 e2e/suites/list-views/file-libraries.test.ts delete mode 100644 e2e/suites/list-views/personal-files.test.ts delete mode 100644 e2e/suites/list-views/recent-files.test.ts delete mode 100644 e2e/suites/list-views/shared-files.test.ts delete mode 100644 e2e/suites/list-views/trash.test.ts delete mode 100644 e2e/suites/navigation/side-navigation.test.ts delete mode 100644 e2e/suites/pagination/pag-favorites.test.ts delete mode 100644 e2e/suites/pagination/pag-personal-files.test.ts delete mode 100644 e2e/suites/pagination/pag-recent-files.test.ts delete mode 100644 e2e/suites/pagination/pag-shared-files.test.ts delete mode 100644 e2e/suites/pagination/pag-trash.test.ts delete mode 100644 e2e/utilities/repo-client/apis/favorites/favorites-api.ts delete mode 100644 e2e/utilities/repo-client/apis/nodes/node-body-create.ts delete mode 100644 e2e/utilities/repo-client/apis/nodes/node-content-tree.ts delete mode 100644 e2e/utilities/repo-client/apis/nodes/nodes-api.ts delete mode 100644 e2e/utilities/repo-client/apis/people/people-api-models.ts delete mode 100644 e2e/utilities/repo-client/apis/people/people-api.ts delete mode 100644 e2e/utilities/repo-client/apis/repo-api.ts delete mode 100644 e2e/utilities/repo-client/apis/shared-links/shared-links-api.ts delete mode 100644 e2e/utilities/repo-client/apis/sites/sites-api-models.ts delete mode 100644 e2e/utilities/repo-client/apis/sites/sites-api.ts delete mode 100644 e2e/utilities/repo-client/apis/trashcan/trashcan-api.ts delete mode 100644 e2e/utilities/repo-client/repo-client-models.ts delete mode 100644 e2e/utilities/repo-client/repo-client.ts delete mode 100644 e2e/utilities/reporters/console/console-logger.ts delete mode 100644 e2e/utilities/reporters/console/console.ts delete mode 100644 e2e/utilities/rest-client/rest-client-models.ts delete mode 100644 e2e/utilities/rest-client/rest-client.ts delete mode 100644 e2e/utilities/utils.ts diff --git a/e2e/components/component.ts b/e2e/components/component.ts deleted file mode 100644 index 24d7f1cb1..000000000 --- a/e2e/components/component.ts +++ /dev/null @@ -1,43 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { ElementFinder, element, by, ExpectedConditions as EC, browser } from 'protractor'; -import { BROWSER_WAIT_TIMEOUT } from '../configs'; - -export abstract class Component { - component: ElementFinder; - - constructor(selector: string, ancestor?: ElementFinder) { - const locator = by.css(selector); - - this.component = ancestor - ? ancestor.element(locator) - : element(locator); - } - - wait() { - return browser.wait(EC.presenceOf(this.component), BROWSER_WAIT_TIMEOUT); - } -} diff --git a/e2e/components/components.ts b/e2e/components/components.ts deleted file mode 100644 index 70992f11d..000000000 --- a/e2e/components/components.ts +++ /dev/null @@ -1,32 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -export * from './login/login'; -export * from './header/header'; -export * from './header/user-info'; -export * from './data-table/data-table'; -export * from './pagination/pagination'; -export * from './sidenav/sidenav'; -export * from './toolbar/toolbar'; diff --git a/e2e/components/data-table/data-table.ts b/e2e/components/data-table/data-table.ts deleted file mode 100644 index ea809fcf3..000000000 --- a/e2e/components/data-table/data-table.ts +++ /dev/null @@ -1,196 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { ElementFinder, ElementArrayFinder, promise, by, browser, ExpectedConditions as EC, protractor } from 'protractor'; -import { BROWSER_WAIT_TIMEOUT } from '../../configs'; -import { Component } from '../component'; - -export class DataTable extends Component { - private static selectors = { - root: 'adf-datatable', - - head: 'table > thead', - columnHeader: 'tr > th', - sortedColumnHeader: ` - th.adf-data-table__header--sorted-asc, - th.adf-data-table__header--sorted-desc - `, - - body: 'table > tbody', - row: 'tr', - selectedRow: 'tr.is-selected', - cell: 'td', - locationLink: 'app-location-link', - - emptyListContainer: 'td.adf-no-content-container', - emptyFolderDragAndDrop: '.adf-empty-list_template .adf-empty-folder', - - emptyListTitle: 'div .empty-list__title', - emptyListText: 'div .empty-list__text' - }; - - head: ElementFinder = this.component.element(by.css(DataTable.selectors.head)); - body: ElementFinder = this.component.element(by.css(DataTable.selectors.body)); - cell = by.css(DataTable.selectors.cell); - locationLink = by.css(DataTable.selectors.locationLink); - emptyList: ElementFinder = this.component.element(by.css(DataTable.selectors.emptyListContainer)); - emptyFolderDragAndDrop: ElementFinder = this.component.element(by.css(DataTable.selectors.emptyFolderDragAndDrop)); - emptyListTitle: ElementFinder = this.component.element(by.css(DataTable.selectors.emptyListTitle)); - emptyListText: ElementArrayFinder = this.component.all(by.css(DataTable.selectors.emptyListText)); - - constructor(ancestor?: ElementFinder) { - super(DataTable.selectors.root, ancestor); - } - - // Wait methods (waits for elements) - waitForHeader() { - return browser.wait(EC.presenceOf(this.head), BROWSER_WAIT_TIMEOUT); - } - - waitForEmptyState() { - return browser.wait(EC.presenceOf(this.emptyList), BROWSER_WAIT_TIMEOUT); - } - - // Header/Column methods - getColumnHeaders(): ElementArrayFinder { - const locator = by.css(DataTable.selectors.columnHeader); - return this.head.all(locator); - } - - getNthColumnHeader(nth: number): ElementFinder { - return this.getColumnHeaders().get(nth - 1); - } - - getColumnHeaderByLabel(label: string): ElementFinder { - const locator = by.cssContainingText(DataTable.selectors.columnHeader, label); - return this.head.element(locator); - } - - getSortedColumnHeader(): ElementFinder { - const locator = by.css(DataTable.selectors.sortedColumnHeader); - return this.head.element(locator); - } - - sortByColumn(columnName: string): promise.Promise { - const column = this.getColumnHeaderByLabel(columnName); - const click = browser.actions().mouseMove(column).click(); - - return click.perform(); - } - - // Rows methods - getRows(): ElementArrayFinder { - return this.body.all(by.css(DataTable.selectors.row)); - } - - getSelectedRows(): ElementArrayFinder { - return this.body.all(by.css(DataTable.selectors.selectedRow)); - } - - getNthRow(nth: number): ElementFinder { - return this.getRows().get(nth - 1); - } - - getRowByName(name: string): ElementFinder { - return this.body.element(by.cssContainingText(`.adf-data-table-cell`, name)); - } - - countRows(): promise.Promise { - return this.getRows().count(); - } - - // Navigation/selection methods - doubleClickOnItemName(name: string): promise.Promise { - const dblClick = browser.actions() - .mouseMove(this.getRowByName(name)) - .click() - .click(); - - return dblClick.perform(); - } - - clickOnItemName(name: string): promise.Promise { - return this.getRowByName(name).click(); - } - - selectMultipleItems(names: string[]): promise.Promise { - return browser.actions().sendKeys(protractor.Key.COMMAND).perform() - .then(() => { - names.forEach(name => { - this.clickOnItemName(name); - }); - }) - .then(() => browser.actions().sendKeys(protractor.Key.NULL).perform()); - } - - clearSelection() { - this.getSelectedRows().count() - .then(count => { - if (count !== 0) { browser.refresh().then(() => this.waitForHeader()); } - }); - } - - getItemLocation(name: string) { - const rowLocator = by.cssContainingText(DataTable.selectors.row, name); - return this.body.element(rowLocator).element(this.locationLink); - } - - clickItemLocation(name: string) { - return this.getItemLocation(name).click(); - } - - // empty state methods - isEmptyList(): promise.Promise { - return this.emptyList.isPresent(); - } - - isEmptyWithDragAndDrop(): promise.Promise { - return this.emptyFolderDragAndDrop.isDisplayed(); - } - - getEmptyDragAndDropText(): promise.Promise { - return this.isEmptyWithDragAndDrop() - .then(() => { - return this.emptyFolderDragAndDrop.getText(); - }) - .catch(() => ''); - } - - getEmptyStateTitle(): promise.Promise { - return this.isEmptyList() - .then(() => { - return this.emptyListTitle.getText(); - }) - .catch(() => ''); - } - - getEmptyStateText(): promise.Promise { - return this.isEmptyList() - .then(() => { - return this.emptyListText.getText(); - }) - .catch(() => ''); - } -} diff --git a/e2e/components/dialog/create-edit-folder-dialog.ts b/e2e/components/dialog/create-edit-folder-dialog.ts deleted file mode 100644 index a6d7f29e0..000000000 --- a/e2e/components/dialog/create-edit-folder-dialog.ts +++ /dev/null @@ -1,108 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { ElementFinder, by, browser, protractor, ExpectedConditions as EC, promise } from 'protractor'; -import { BROWSER_WAIT_TIMEOUT } from '../../configs'; -import { Component } from '../component'; - -export class CreateOrEditFolderDialog extends Component { - private static selectors = { - root: 'adf-folder-dialog', - - title: '.mat-dialog-title', - nameInput: '.mat-input-element[placeholder="Name" i]', - descriptionTextArea: '.mat-input-element[placeholder="Description" i]', - button: '.mat-dialog-actions button', - validationMessage: '.mat-hint span' - }; - - title: ElementFinder = this.component.element(by.css(CreateOrEditFolderDialog.selectors.title)); - nameInput: ElementFinder = this.component.element(by.css(CreateOrEditFolderDialog.selectors.nameInput)); - descriptionTextArea: ElementFinder = this.component.element(by.css(CreateOrEditFolderDialog.selectors.descriptionTextArea)); - createButton: ElementFinder = this.component.element(by.cssContainingText(CreateOrEditFolderDialog.selectors.button, 'Create')); - cancelButton: ElementFinder = this.component.element(by.cssContainingText(CreateOrEditFolderDialog.selectors.button, 'Cancel')); - updateButton: ElementFinder = this.component.element(by.cssContainingText(CreateOrEditFolderDialog.selectors.button, 'Update')); - validationMessage: ElementFinder = this.component.element(by.css(CreateOrEditFolderDialog.selectors.validationMessage)); - - constructor(ancestor?: ElementFinder) { - super(CreateOrEditFolderDialog.selectors.root, ancestor); - } - - waitForDialogToOpen() { - return browser.wait(EC.presenceOf(this.title), BROWSER_WAIT_TIMEOUT); - } - - waitForDialogToClose() { - return browser.wait(EC.stalenessOf(this.title), BROWSER_WAIT_TIMEOUT); - } - - getTitle(): promise.Promise { - return this.title.getText(); - } - - isValidationMessageDisplayed(): promise.Promise { - return this.validationMessage.isDisplayed(); - } - - getValidationMessage(): promise.Promise { - return this.isValidationMessageDisplayed() - .then(() => this.validationMessage.getText()) - .catch(() => ''); - } - - enterName(name: string): promise.Promise { - return this.nameInput.clear() - .then(() => this.nameInput.sendKeys(name)) - .then(() => this); - } - - enterDescription(description: string): promise.Promise { - return this.descriptionTextArea.clear() - .then(() => { - browser.actions().click(this.descriptionTextArea).sendKeys(description).perform(); - }) - .then(() => this); - } - - deleteNameWithBackspace(): promise.Promise { - return this.nameInput.clear() - .then(() => { - return this.nameInput.sendKeys(' ', protractor.Key.CONTROL, 'a', protractor.Key.NULL, protractor.Key.BACK_SPACE); - }); - } - - clickCreate() { - return this.createButton.click(); - } - - clickCancel() { - return this.cancelButton.click() - .then(() => this.waitForDialogToClose()); - } - - clickUpdate() { - return this.updateButton.click(); - } -} diff --git a/e2e/components/header/header.ts b/e2e/components/header/header.ts deleted file mode 100644 index be8d271d4..000000000 --- a/e2e/components/header/header.ts +++ /dev/null @@ -1,42 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { ElementFinder, by } from 'protractor'; -import { Component } from '../component'; -import { UserInfo } from './user-info'; - -export class Header extends Component { - private locators = { - logoLink: by.css('.app-menu__title'), - userInfo: by.css('app-current-user') - }; - - logoLink: ElementFinder = this.component.element(this.locators.logoLink); - userInfo: UserInfo = new UserInfo(this.component); - - constructor(ancestor?: ElementFinder) { - super('app-header', ancestor); - } -} diff --git a/e2e/components/header/user-info.ts b/e2e/components/header/user-info.ts deleted file mode 100644 index da110f0a9..000000000 --- a/e2e/components/header/user-info.ts +++ /dev/null @@ -1,64 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { ElementFinder, ElementArrayFinder, element, by, promise } from 'protractor'; -import { Menu } from '../menu/menu'; -import { Component } from '../component'; - -export class UserInfo extends Component { - private locators = { - avatar: by.css('.current-user__avatar'), - fullName: by.css('.current-user__full-name'), - menuItems: by.css('[mat-menu-item]') - }; - - fullName: ElementFinder = this.component.element(this.locators.fullName); - avatar: ElementFinder = this.component.element(this.locators.avatar); - - menu: Menu = new Menu(); - - constructor(ancestor?: ElementFinder) { - super('app-current-user', ancestor); - } - - openMenu(): promise.Promise { - const { menu, avatar } = this; - - return avatar.click() - .then(() => menu.wait()) - .then(() => menu); - } - - get name(): promise.Promise { - return this.fullName.getText(); - } - - signOut(): promise.Promise { - return this.openMenu() - .then(menu => { - menu.clickMenuItem('Sign out'); - }); - } -} diff --git a/e2e/components/login/login.ts b/e2e/components/login/login.ts deleted file mode 100644 index 307059de3..000000000 --- a/e2e/components/login/login.ts +++ /dev/null @@ -1,75 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { by, ElementFinder, promise } from 'protractor'; -import { Component } from '../component'; - -export class LoginComponent extends Component { - static selector = 'adf-login'; - - private locators = { - usernameInput: by.css('input#username'), - passwordInput: by.css('input#password'), - submitButton: by.css('button#login-button'), - errorMessage: by.css('.login-error-message') - }; - - usernameInput: ElementFinder = this.component.element(this.locators.usernameInput); - passwordInput: ElementFinder = this.component.element(this.locators.passwordInput); - submitButton: ElementFinder = this.component.element(this.locators.submitButton); - errorMessage: ElementFinder = this.component.element(this.locators.errorMessage); - - constructor(ancestor?: ElementFinder) { - super(LoginComponent.selector, ancestor); - } - - enterUsername(username: string): LoginComponent { - const { usernameInput } = this; - - usernameInput.clear(); - usernameInput.sendKeys(username); - - return this; - } - - enterPassword(password: string): LoginComponent { - const { passwordInput } = this; - - passwordInput.clear(); - passwordInput.sendKeys(password); - - return this; - } - - enterCredentials(username: string, password: string) { - this.enterUsername(username).enterPassword(password); - - return this; - } - - submit(): promise.Promise { - return this.submitButton.click(); - } -} diff --git a/e2e/components/menu/menu.ts b/e2e/components/menu/menu.ts deleted file mode 100644 index 1f94354ec..000000000 --- a/e2e/components/menu/menu.ts +++ /dev/null @@ -1,73 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { ElementFinder, ElementArrayFinder, by, browser, ExpectedConditions as EC, promise } from 'protractor'; -import { BROWSER_WAIT_TIMEOUT } from '../../configs'; -import { Component } from '../component'; - -export class Menu extends Component { - private static selectors = { - root: '.mat-menu-panel', - item: 'button.mat-menu-item' - }; - - items: ElementArrayFinder = this.component.all(by.css(Menu.selectors.item)); - - constructor(ancestor?: ElementFinder) { - super(Menu.selectors.root, ancestor); - } - - wait() { - return browser.wait(EC.visibilityOf(this.items.get(0)), BROWSER_WAIT_TIMEOUT); - } - - getNthItem(nth: number): ElementFinder { - return this.items.get(nth - 1); - } - - getItemByLabel(label: string): ElementFinder { - return this.component.element(by.cssContainingText(Menu.selectors.item, label)); - } - - getItemTooltip(label: string): promise.Promise { - return this.getItemByLabel(label).getAttribute('title'); - } - - getItemsCount(): promise.Promise { - return this.items.count(); - } - - clickNthItem(nth: number): promise.Promise { - return this.getNthItem(nth).click(); - } - - clickMenuItem(label: string): promise.Promise { - return this.getItemByLabel(label).click(); - } - - isMenuItemPresent(title: string): promise.Promise { - return this.component.element(by.cssContainingText(Menu.selectors.item, title)).isPresent(); - } -} diff --git a/e2e/components/pagination/pagination.ts b/e2e/components/pagination/pagination.ts deleted file mode 100644 index 7c52e3312..000000000 --- a/e2e/components/pagination/pagination.ts +++ /dev/null @@ -1,75 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { ElementFinder, ElementArrayFinder, promise, by, browser, ExpectedConditions as EC } from 'protractor'; -import { BROWSER_WAIT_TIMEOUT } from '../../configs'; -import { Menu } from '../menu/menu'; -import { Component } from '../component'; - -export class Pagination extends Component { - private static selectors = { - root: 'adf-pagination', - range: '.adf-pagination__range', - maxItems: '.adf-pagination__max-items', - currentPage: '.adf-pagination__current-page', - totalPages: '.adf-pagination__total-pages', - - previousButton: '.adf-pagination__previous-button', - nextButton: '.adf-pagination__next-button', - maxItemsButton: '.adf-pagination__max-items + button[mat-icon-button]', - pagesButton: '.adf-pagination__current-page + button[mat-icon-button]' - }; - - range: ElementFinder = this.component.element(by.css(Pagination.selectors.range)); - maxItems: ElementFinder = this.component.element(by.css(Pagination.selectors.maxItems)); - currentPage: ElementFinder = this.component.element(by.css(Pagination.selectors.currentPage)); - totalPages: ElementFinder = this.component.element(by.css(Pagination.selectors.totalPages)); - previousButton: ElementFinder = this.component.element(by.css(Pagination.selectors.previousButton)); - nextButton: ElementFinder = this.component.element(by.css(Pagination.selectors.nextButton)); - maxItemsButton: ElementFinder = this.component.element(by.css(Pagination.selectors.maxItemsButton)); - pagesButton: ElementFinder = this.component.element(by.css(Pagination.selectors.pagesButton)); - - menu: Menu = new Menu(); - - constructor(ancestor?: ElementFinder) { - super(Pagination.selectors.root, ancestor); - } - - openMaxItemsMenu(): promise.Promise { - const { menu, maxItemsButton } = this; - - return maxItemsButton.click() - .then(() => menu.wait()) - .then(() => menu); - } - - openCurrentPageMenu(): promise.Promise { - const { menu, pagesButton } = this; - - return this.pagesButton.click() - .then(() => menu.wait()) - .then(() => menu); - } -} diff --git a/e2e/components/sidenav/sidenav.ts b/e2e/components/sidenav/sidenav.ts deleted file mode 100644 index 406a5f8bb..000000000 --- a/e2e/components/sidenav/sidenav.ts +++ /dev/null @@ -1,68 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { ElementFinder, ElementArrayFinder, by, promise } from 'protractor'; -import { Menu } from '../menu/menu'; -import { Component } from '../component'; - -export class Sidenav extends Component { - private static selectors = { - root: 'app-sidenav', - link: '.sidenav-menu__item-link', - activeLink: '.sidenav-menu__item-link--active', - newButton: '.sidenav__section--new__button' - }; - - links: ElementArrayFinder = this.component.all(by.css(Sidenav.selectors.link)); - activeLink: ElementFinder = this.component.element(by.css(Sidenav.selectors.activeLink)); - newButton: ElementArrayFinder = this.component.all(by.css(Sidenav.selectors.newButton)); - - menu: Menu = new Menu(); - - constructor(ancestor?: ElementFinder) { - super(Sidenav.selectors.root, ancestor); - } - - openNewMenu(): promise.Promise { - const { menu, newButton } = this; - - return newButton.click() - .then(() => menu.wait()) - .then(() => menu); - } - - isActiveByLabel(label: string): promise.Promise { - return this.getLinkByLabel(label).getAttribute('class') - .then(className => className.includes(Sidenav.selectors.activeLink.replace('.', ''))); - } - - getLinkByLabel(label: string): ElementFinder { - return this.component.element(by.cssContainingText(Sidenav.selectors.link, label)); - } - - navigateToLinkByLabel(label: string): promise.Promise { - return this.getLinkByLabel(label).click(); - } -} diff --git a/e2e/components/toolbar/toolbar-actions.ts b/e2e/components/toolbar/toolbar-actions.ts deleted file mode 100644 index 5998cdedf..000000000 --- a/e2e/components/toolbar/toolbar-actions.ts +++ /dev/null @@ -1,68 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { ElementFinder, ElementArrayFinder, by, promise } from 'protractor'; -import { Menu } from '../menu/menu'; -import { Component } from '../component'; - -export class ToolbarActions extends Component { - private static selectors = { - root: 'adf-toolbar', - button: '.mat-icon-button' - }; - - menu: Menu = new Menu(); - buttons: ElementArrayFinder = this.component.all(by.css(ToolbarActions.selectors.button)); - - constructor(ancestor?: ElementFinder) { - super(ToolbarActions.selectors.root, ancestor); - } - - isEmpty(): promise.Promise { - return this.buttons.count().then(count => (count === 0)); - } - - isButtonPresent(title: string): promise.Promise { - return this.component.element(by.css(`${ToolbarActions.selectors.button}[title="${title}"]`)).isPresent(); - } - - getButtonByLabel(label: string): ElementFinder { - return this.component.element(by.cssContainingText(ToolbarActions.selectors.button, label)); - } - - getButtonByTitleAttribute(title: string): ElementFinder { - return this.component.element(by.css(`${ToolbarActions.selectors.button}[title="${title}"]`)); - } - - openMoreMenu(): promise.Promise { - const { menu } = this; - const moreButton = this.getButtonByTitleAttribute('More actions'); - - return moreButton - .click() - .then(() => menu.wait()) - .then(() => menu); - } -} diff --git a/e2e/components/toolbar/toolbar-breadcrumb.ts b/e2e/components/toolbar/toolbar-breadcrumb.ts deleted file mode 100644 index 872782a6d..000000000 --- a/e2e/components/toolbar/toolbar-breadcrumb.ts +++ /dev/null @@ -1,63 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { ElementFinder, ElementArrayFinder, by, promise } from 'protractor'; -import { Menu } from '../menu/menu'; -import { Component } from '../component'; - -export class ToolbarBreadcrumb extends Component { - private static selectors = { - root: 'adf-breadcrumb', - item: '.adf-breadcrumb-item' - }; - - items: ElementArrayFinder = this.component.all(by.css(ToolbarBreadcrumb.selectors.item)); - - constructor(ancestor?: ElementFinder) { - super(ToolbarBreadcrumb.selectors.root, ancestor); - } - - getNthItem(nth: number): ElementFinder { - return this.items.get(nth - 1); - } - - getItemsCount(): promise.Promise { - return this.items.count(); - } - - getFirstItemName(): promise.Promise { - return this.items.get(0).getAttribute('title'); - } - - getCurrentItem(): promise.Promise { - return this.getItemsCount() - .then(count => this.getNthItem(count)); - } - - getCurrentItemName(): promise.Promise { - return this.getCurrentItem() - .then(node => node.getAttribute('title')); - } -} diff --git a/e2e/components/toolbar/toolbar.ts b/e2e/components/toolbar/toolbar.ts deleted file mode 100644 index ed0bbe4d5..000000000 --- a/e2e/components/toolbar/toolbar.ts +++ /dev/null @@ -1,42 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { ElementFinder, ElementArrayFinder, by } from 'protractor'; -import { Component } from '../component'; -import { ToolbarActions } from './toolbar-actions'; -import { ToolbarBreadcrumb } from './toolbar-breadcrumb'; - -export class Toolbar extends Component { - private static selectors = { - root: '.inner-layout__header' - }; - - actions: ToolbarActions = new ToolbarActions(this.component); - breadcrumb: ToolbarBreadcrumb = new ToolbarBreadcrumb(this.component); - - constructor(ancestor?: ElementFinder) { - super(Toolbar.selectors.root, ancestor); - } -} diff --git a/e2e/configs.ts b/e2e/configs.ts deleted file mode 100644 index f0f304335..000000000 --- a/e2e/configs.ts +++ /dev/null @@ -1,78 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -export const BROWSER_RESOLUTION_WIDTH = 1200; -export const BROWSER_RESOLUTION_HEIGHT = 800; - -export const BROWSER_WAIT_TIMEOUT = 20000; - -// Application configs -export const APP_HOST = 'http://localhost:3000'; - -// Repository configs -export const REPO_API_HOST = 'http://localhost:8080'; -export const REPO_API_TENANT = '-default-'; - -// Admin details -export const ADMIN_USERNAME = 'admin'; -export const ADMIN_PASSWORD = 'admin'; -export const ADMIN_FULL_NAME = 'Administrator'; - -// Application Routes -export const APP_ROUTES = { - FAVORITES: '/favorites', - FILE_LIBRARIES: '/libraries', - LOGIN: '/login', - LOGOUT: '/logout', - PERSONAL_FILES: '/personal-files', - RECENT_FILES: '/recent-files', - SHARED_FILES: '/shared', - TRASHCAN: '/trashcan' -}; - -// Sidebar labels -export const SIDEBAR_LABELS = { - PERSONAL_FILES: 'Personal Files', - FILE_LIBRARIES: 'File Libraries', - SHARED_FILES: 'Shared', - RECENT_FILES: 'Recent Files', - FAVORITES: 'Favorites', - TRASH: 'Trash' -}; - -// Site visibility -export const SITE_VISIBILITY = { - PUBLIC: 'PUBLIC', - MODERATED: 'MODERATED', - PRIVATE: 'PRIVATE' -}; - -// Site roles -export const SITE_ROLES = { - SITE_CONSUMER: 'SiteConsumer', - SITE_COLLABORATOR: 'SiteCollaborator', - SITE_CONTRIBUTOR: 'SiteContributor', - SITE_MANAGER: 'SiteManager' -}; diff --git a/e2e/pages/browsing-page.ts b/e2e/pages/browsing-page.ts deleted file mode 100644 index 033859939..000000000 --- a/e2e/pages/browsing-page.ts +++ /dev/null @@ -1,40 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { promise } from 'protractor'; -import { Header, DataTable, Pagination, Toolbar, Sidenav } from '../components/components'; -import { Page } from './page'; - -export class BrowsingPage extends Page { - header = new Header(this.app); - sidenav = new Sidenav(this.app); - toolbar = new Toolbar(this.app); - dataTable = new DataTable(this.app); - pagination = new Pagination(this.app); - - signOut(): promise.Promise { - return this.header.userInfo.signOut(); - } -} diff --git a/e2e/pages/login-page.ts b/e2e/pages/login-page.ts deleted file mode 100644 index 0a64257b0..000000000 --- a/e2e/pages/login-page.ts +++ /dev/null @@ -1,74 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -import { browser, ExpectedConditions as EC, promise } from 'protractor'; -import { LoginComponent } from '../components/components'; -import { Page } from './page'; -import { Utils } from '../utilities/utils'; - -import { - ADMIN_USERNAME, - ADMIN_PASSWORD, - BROWSER_WAIT_TIMEOUT, - APP_ROUTES -} from '../configs'; - -export class LoginPage extends Page { - login: LoginComponent = new LoginComponent(this.app); - - /** @override */ - constructor() { - super(APP_ROUTES.LOGIN); - } - - /** @override */ - load(): promise.Promise { - return super.load().then(() => { - const { submitButton } = this.login; - const hasSubmitButton = EC.presenceOf(submitButton); - - return browser.wait(hasSubmitButton, BROWSER_WAIT_TIMEOUT) - .then(() => Utils.clearLocalStorage()) - .then(() => browser.manage().deleteAllCookies()); - }); - } - - loginWith(username: string, password?: string): promise.Promise { - const pass = password || username; - return this.login.enterCredentials(username, pass).submit() - .then(() => super.waitForApp()); - } - - loginWithAdmin(): promise.Promise { - return this.loginWith(ADMIN_USERNAME, ADMIN_PASSWORD); - } - - tryLoginWith(username: string, password?: string): promise.Promise { - const pass = password || username; - return this.login.enterCredentials(username, pass).submit() - .then(() => { - browser.wait(EC.presenceOf(this.login.errorMessage), BROWSER_WAIT_TIMEOUT); - }); - } -} diff --git a/e2e/pages/logout-page.ts b/e2e/pages/logout-page.ts deleted file mode 100644 index e250a9627..000000000 --- a/e2e/pages/logout-page.ts +++ /dev/null @@ -1,43 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { promise } from 'protractor'; -import { Page } from './page'; -import { APP_ROUTES } from '../configs'; -import { Utils } from '../utilities/utils'; - -export class LogoutPage extends Page { - /** @override */ - constructor() { - super(APP_ROUTES.LOGIN); - } - - /** @override */ - load(): promise.Promise { - return Utils.clearLocalStorage() - .then(() => Utils.clearSessionStorage()) - .then(() => super.load()); - } -} diff --git a/e2e/pages/page.ts b/e2e/pages/page.ts deleted file mode 100644 index 2ac3b031b..000000000 --- a/e2e/pages/page.ts +++ /dev/null @@ -1,79 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, element, by, ElementFinder, promise, ExpectedConditions as EC } from 'protractor'; -import { BROWSER_WAIT_TIMEOUT } from './../configs'; - -export abstract class Page { - private static USE_HASH_STRATEGY = false; - - private locators = { - app: by.css('app-root'), - layout: by.css('app-layout'), - overlay: by.css('.cdk-overlay-container'), - snackBar: by.css('simple-snack-bar'), - snackBarAction: by.css('.mat-simple-snackbar-action') - }; - - public app: ElementFinder = element(this.locators.app); - public layout: ElementFinder = element(this.locators.layout); - public overlay: ElementFinder = element(this.locators.overlay); - public snackBar: ElementFinder = element(this.locators.snackBar); - - constructor(public url: string = '') {} - - get title(): promise.Promise { - return browser.getTitle(); - } - - load(relativeUrl: string = ''): promise.Promise { - const hash = Page.USE_HASH_STRATEGY ? '/#' : ''; - const path = `${hash}${this.url}${relativeUrl}`; - - return browser.get(path); - } - - waitForApp() { - return browser.wait(EC.presenceOf(this.layout), BROWSER_WAIT_TIMEOUT); - } - - refresh(): promise.Promise { - return browser.refresh(); - } - - isSnackBarDisplayed(): promise.Promise { - return this.snackBar.isDisplayed(); - } - - getSnackBarMessage(): promise.Promise { - return this.isSnackBarDisplayed() - .then(() => this.snackBar.getText()) - .catch(() => ''); - } - - getSnackBarAction(): ElementFinder { - return this.snackBar.element(this.locators.snackBarAction); - } -} diff --git a/e2e/pages/pages.ts b/e2e/pages/pages.ts deleted file mode 100644 index ce52fea89..000000000 --- a/e2e/pages/pages.ts +++ /dev/null @@ -1,28 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -export * from './browsing-page'; -export * from './login-page'; -export * from './logout-page'; diff --git a/e2e/suites/actions/create-folder.test.ts b/e2e/suites/actions/create-folder.test.ts deleted file mode 100644 index b26b47686..000000000 --- a/e2e/suites/actions/create-folder.test.ts +++ /dev/null @@ -1,279 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { protractor, browser, by, ElementFinder } from 'protractor'; - -import { SIDEBAR_LABELS, BROWSER_WAIT_TIMEOUT, SITE_VISIBILITY, SITE_ROLES } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { CreateOrEditFolderDialog } from '../../components/dialog/create-edit-folder-dialog'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('Create folder', () => { - const username = `user-${Utils.random()}`; - - const parent = `parent-${Utils.random()}`; - const folderName1 = `folder-${Utils.random()}`; - const folderName2 = `folder-${Utils.random()}`; - const folderDescription = 'description of my folder'; - const duplicateFolderName = `folder-${Utils.random()}`; - const nameWithSpaces = ` folder-${Utils.random()} `; - - const siteName = `site-private-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const personalFilesPage = new BrowsingPage(); - const createDialog = new CreateOrEditFolderDialog(); - const { dataTable } = personalFilesPage; - - function openCreateDialog(): any { - return personalFilesPage.sidenav.openNewMenu() - .then(menu => menu.clickMenuItem('Create folder')) - .then(() => createDialog.waitForDialogToOpen()); - } - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE)) - .then(() => apis.admin.nodes.createFolders([ folderName1 ], `Sites/${siteName}/documentLibrary`)) - .then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER)) - .then(() => apis.user.nodes.createFolders([ duplicateFolderName ], parent)) - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterEach(done => { - browser.actions().sendKeys(protractor.Key.ESCAPE).perform().then(done); - }); - - afterAll(done => { - Promise - .all([ - apis.admin.sites.deleteSite(siteName), - apis.user.nodes.deleteNodes([ parent ]), - logoutPage.load() - ]) - .then(done); - }); - - it('option is enabled when having enough permissions', () => { - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => personalFilesPage.sidenav.openNewMenu()) - .then(menu => { - const isEnabled = menu.getItemByLabel('Create folder').isEnabled(); - expect(isEnabled).toBe(true, 'Create folder is not enabled'); - }); - }); - - it('creates new folder with name', () => { - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => openCreateDialog()) - .then(() => createDialog.enterName(folderName1)) - .then(() => createDialog.clickCreate()) - .then(() => createDialog.waitForDialogToClose()) - .then(() => dataTable.waitForHeader()) - .then(() => { - const isPresent = dataTable.getRowByName(folderName1).isPresent(); - expect(isPresent).toBe(true, 'Folder not displayed in list view'); - }); - }); - - it('creates new folder with name and description', () => { - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => openCreateDialog()) - .then(() => createDialog.enterName(folderName2)) - .then(() => createDialog.enterDescription(folderDescription)) - .then(() => createDialog.clickCreate()) - .then(() => createDialog.waitForDialogToClose()) - .then(() => dataTable.waitForHeader()) - .then(() => { - const isPresent = dataTable.getRowByName(folderName2).isPresent(); - expect(isPresent).toBe(true, 'Folder not displayed in list view'); - }) - .then(() => { - expect(apis.user.nodes.getNodeDescription(folderName2)).toEqual(folderDescription); - }); - }); - - it('enabled option tooltip', () => { - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => personalFilesPage.sidenav.openNewMenu()) - .then(menu => browser.actions().mouseMove(menu.getItemByLabel('Create folder')).perform() - .then(() => menu)) - .then(menu => { - expect(menu.getItemTooltip('Create folder')).toContain('Create new folder'); - }); - }); - - it('option is disabled when not enough permissions', () => { - const fileLibrariesPage = new BrowsingPage(); - - fileLibrariesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES) - .then(() => fileLibrariesPage.dataTable.doubleClickOnItemName(siteName)) - .then(() => fileLibrariesPage.dataTable.doubleClickOnItemName(folderName1)) - .then(() => fileLibrariesPage.sidenav.openNewMenu()) - .then(menu => { - const isEnabled = menu.getItemByLabel('Create folder').isEnabled(); - expect(isEnabled).toBe(false, 'Create folder is not disabled'); - }); - }); - - it('disabled option tooltip', () => { - const fileLibrariesPage = new BrowsingPage(); - - fileLibrariesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES) - .then(() => fileLibrariesPage.dataTable.doubleClickOnItemName(siteName)) - .then(() => fileLibrariesPage.dataTable.doubleClickOnItemName(folderName1)) - .then(() => fileLibrariesPage.sidenav.openNewMenu()) - .then(menu => browser.actions().mouseMove(menu.getItemByLabel('Create folder')).perform() - .then(() => menu)) - .then(menu => { - const tooltip = menu.getItemTooltip('Create folder'); - expect(tooltip).toContain(`You can't create a folder here`); - }); - }); - - it('dialog UI elements', () => { - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => openCreateDialog()) - .then(() => { - const dialogTitle = createDialog.getTitle(); - const isFolderNameDisplayed = createDialog.nameInput.isDisplayed(); - const isDescriptionDisplayed = createDialog.descriptionTextArea.isDisplayed(); - const isCreateEnabled = createDialog.createButton.isEnabled(); - const isCancelEnabled = createDialog.cancelButton.isEnabled(); - - expect(dialogTitle).toMatch('Create new folder'); - expect(isFolderNameDisplayed).toBe(true, 'Name input is not displayed'); - expect(isDescriptionDisplayed).toBe(true, 'Description field is not displayed'); - expect(isCreateEnabled).toBe(false, 'Create button is not disabled'); - expect(isCancelEnabled).toBe(true, 'Cancel button is not enabled'); - }); - }); - - it('with empty folder name', () => { - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => openCreateDialog()) - .then(() => createDialog.deleteNameWithBackspace()) - .then(() => { - const isCreateEnabled = createDialog.createButton.isEnabled(); - const validationMessage = createDialog.getValidationMessage(); - - expect(isCreateEnabled).toBe(false, 'Create button is enabled'); - expect(validationMessage).toMatch('Folder name is required'); - }); - }); - - it('with folder name ending with a dot "."', () => { - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => openCreateDialog()) - .then(() => createDialog.enterName('folder-name.')) - .then(dialog => { - const isCreateEnabled = dialog.createButton.isEnabled(); - const validationMessage = dialog.getValidationMessage(); - - expect(isCreateEnabled).toBe(false, 'Create button is not disabled'); - expect(validationMessage).toMatch(`Folder name can't end with a period .`); - }); - }); - - it('with folder name containing special characters', () => { - const namesWithSpecialChars = [ 'a*a', 'a"a', 'aa', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a' ]; - - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => openCreateDialog()) - .then(() => namesWithSpecialChars.forEach(name => { - createDialog.enterName(name); - - const isCreateEnabled = createDialog.createButton.isEnabled(); - const validationMessage = createDialog.getValidationMessage(); - - expect(isCreateEnabled).toBe(false, 'Create button is not disabled'); - expect(validationMessage).toContain(`Folder name can't contain these characters`); - })); - }); - - it('with folder name containing only spaces', () => { - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => openCreateDialog()) - .then(() => createDialog.enterName(' ')) - .then(dialog => { - const isCreateEnabled = dialog.createButton.isEnabled(); - const validationMessage = dialog.getValidationMessage(); - - expect(isCreateEnabled).toBe(false, 'Create button is not disabled'); - expect(validationMessage).toMatch(`Folder name can't contain only spaces`); - }); - }); - - it('cancel folder creation', () => { - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => openCreateDialog()) - .then(() => createDialog.enterName('test')) - .then(() => createDialog.enterDescription('test description')) - .then(() => createDialog.clickCancel()) - .then(() => { - expect(createDialog.component.isPresent()).not.toBe(true, 'dialog is not closed'); - }); - }); - - it('duplicate folder name', () => { - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => openCreateDialog()) - .then(() => createDialog.enterName(duplicateFolderName)) - .then(() => createDialog.clickCreate()) - .then(() => personalFilesPage.getSnackBarMessage()) - .then(message => { - expect(message).toEqual(`There's already a folder with this name. Try a different name.`); - expect(createDialog.component.isPresent()).toBe(true, 'dialog is not present'); - }); - }); - - it('trim ending spaces from folder name', () => { - personalFilesPage.dataTable.doubleClickOnItemName(parent) - .then(() => openCreateDialog()) - .then(() => createDialog.enterName(nameWithSpaces)) - .then(() => createDialog.clickCreate()) - .then(() => createDialog.waitForDialogToClose()) - .then(() => dataTable.waitForHeader()) - .then(() => { - const isPresent = dataTable.getRowByName(nameWithSpaces.trim()).isPresent(); - expect(isPresent).toBe(true, 'Folder not displayed in list view'); - }); - }); -}); diff --git a/e2e/suites/actions/edit-folder.test.ts b/e2e/suites/actions/edit-folder.test.ts deleted file mode 100644 index 7a8826620..000000000 --- a/e2e/suites/actions/edit-folder.test.ts +++ /dev/null @@ -1,190 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { protractor, element, browser, by, ElementFinder, promise } from 'protractor'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { SIDEBAR_LABELS, SITE_VISIBILITY, SITE_ROLES } from '../../configs'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; -import { CreateOrEditFolderDialog } from '../../components/dialog/create-edit-folder-dialog'; -import { Utils } from '../../utilities/utils'; - -describe('Edit folder', () => { - const username = `user-${Utils.random()}`; - - const parent = `parent-${Utils.random()}`; - const folderName = `folder-${Utils.random()}`; - const folderDescription = 'my folder description'; - - const folderNameToEdit = `folder-${Utils.random()}`; - const duplicateFolderName = `folder-${Utils.random()}`; - - const folderNameEdited = `folder-${Utils.random()}`; - const folderDescriptionEdited = 'my folder description edited'; - - const siteName = `site-private-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const personalFilesPage = new BrowsingPage(); - const editDialog = new CreateOrEditFolderDialog(); - const { dataTable } = personalFilesPage; - const editButton = personalFilesPage.toolbar.actions.getButtonByTitleAttribute('Edit'); - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE)) - .then(() => apis.admin.nodes.createFolders([ folderName ], `Sites/${siteName}/documentLibrary`)) - .then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER)) - - .then(() => apis.user.nodes.createNodeWithProperties( folderName, '', folderDescription, parent )) - .then(() => apis.user.nodes.createFolders([ folderNameToEdit, duplicateFolderName ], parent)) - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES) - .then(() => dataTable.waitForHeader()) - .then(() => dataTable.doubleClickOnItemName(parent)) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterEach(done => { - browser.actions().sendKeys(protractor.Key.ESCAPE).perform().then(done); - }); - - afterAll(done => { - Promise - .all([ - apis.admin.sites.deleteSite(siteName), - apis.user.nodes.deleteNodes([ parent ]), - logoutPage.load() - ]) - .then(done); - }); - - it('dialog UI defaults', () => { - dataTable.clickOnItemName(folderName) - .then(() => editButton.click()) - .then(() => { - expect(editDialog.getTitle()).toEqual('Edit folder'); - expect(editDialog.nameInput.getAttribute('value')).toBe(folderName); - expect(editDialog.descriptionTextArea.getAttribute('value')).toBe(folderDescription); - expect(editDialog.updateButton.isEnabled()).toBe(true, 'upload button is not enabled'); - expect(editDialog.cancelButton.isEnabled()).toBe(true, 'cancel button is not enabled'); - }); - }); - - it('properties are modified when pressing OK', () => { - dataTable.clickOnItemName(folderNameToEdit) - .then(() => editButton.click()) - .then(() => editDialog.waitForDialogToOpen()) - .then(() => editDialog.enterName(folderNameEdited)) - .then(() => editDialog.enterDescription(folderDescriptionEdited)) - .then(() => editDialog.clickUpdate()) - .then(() => editDialog.waitForDialogToClose()) - .then(() => dataTable.waitForHeader()) - .then(() => { - const isPresent = dataTable.getRowByName(folderNameEdited).isPresent(); - expect(isPresent).toBe(true, 'Folder not displayed in list view'); - }) - .then(() => { - expect(apis.user.nodes.getNodeDescription(folderNameEdited)).toEqual(folderDescriptionEdited); - }); - }); - - it('with empty folder name', () => { - dataTable.clickOnItemName(folderName) - .then(() => editButton.click()) - .then(() => editDialog.deleteNameWithBackspace()) - .then(() => { - expect(editDialog.updateButton.isEnabled()).toBe(false, 'upload button is not enabled'); - expect(editDialog.getValidationMessage()).toMatch('Folder name is required'); - }); - }); - - it('with name with special characters', () => { - const namesWithSpecialChars = [ 'a*a', 'a"a', 'aa', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a' ]; - - dataTable.clickOnItemName(folderName) - .then(() => editButton.click()) - .then(() => namesWithSpecialChars.forEach(name => { - editDialog.enterName(name); - - expect(editDialog.updateButton.isEnabled()).toBe(false, 'upload button is not disabled'); - expect(editDialog.getValidationMessage()).toContain(`Folder name can't contain these characters`); - })); - }); - - it('with name ending with a dot', () => { - dataTable.clickOnItemName(folderName) - .then(() => editButton.click()) - .then(() => editDialog.nameInput.sendKeys('.')) - .then(() => { - expect(editDialog.updateButton.isEnabled()).toBe(false, 'upload button is not enabled'); - expect(editDialog.getValidationMessage()).toMatch(`Folder name can't end with a period .`); - }); - }); - - it('Cancel button', () => { - dataTable.clickOnItemName(folderName) - .then(() => editButton.click()) - .then(() => editDialog.clickCancel()) - .then(() => { - expect(editDialog.component.isPresent()).not.toBe(true, 'dialog is not closed'); - }); - }); - - it('with duplicate folder name', () => { - dataTable.clickOnItemName(folderName) - .then(() => editButton.click()) - .then(() => editDialog.enterName(duplicateFolderName)) - .then(() => editDialog.clickUpdate()) - .then(() => personalFilesPage.getSnackBarMessage()) - .then(message => { - expect(message).toEqual(`There's already a folder with this name. Try a different name.`); - expect(editDialog.component.isPresent()).toBe(true, 'dialog is not present'); - }); - }); - - it('trim ending spaces', () => { - dataTable.clickOnItemName(folderName) - .then(() => editButton.click()) - .then(() => editDialog.nameInput.sendKeys(' ')) - .then(() => editDialog.clickUpdate()) - .then(() => editDialog.waitForDialogToClose()) - .then(() => { - expect(personalFilesPage.snackBar.isPresent()).not.toBe(true, 'notification appears'); - expect(dataTable.getRowByName(folderName).isPresent()).toBe(true, 'Folder not displayed in list view'); - }); - }); -}); diff --git a/e2e/suites/actions/permanently-delete.test.ts b/e2e/suites/actions/permanently-delete.test.ts deleted file mode 100644 index 7cf88a95f..000000000 --- a/e2e/suites/actions/permanently-delete.test.ts +++ /dev/null @@ -1,113 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, protractor, promise } from 'protractor'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; -import { Utils } from '../../utilities/utils'; - -describe('Permanently delete from Trash', () => { - const username = `user-${Utils.random()}`; - - const file1 = `file-${Utils.random()}.txt`; - const file2 = `file-${Utils.random()}.txt`; - let filesIds; - - const folder1 = `folder-${Utils.random()}`; - const folder2 = `folder-${Utils.random()}`; - let foldersIds; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const trashPage = new BrowsingPage(); - const { dataTable } = trashPage; - const { toolbar } = trashPage; - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => apis.user.nodes.createFiles([ file1, file2 ])) - .then(resp => filesIds = resp.data.list.entries.map(entries => entries.entry.id)) - .then(() => apis.user.nodes.createFolders([ folder1, folder2 ])) - .then(resp => foldersIds = resp.data.list.entries.map(entries => entries.entry.id)) - - .then(() => apis.user.nodes.deleteNodesById(filesIds, false)) - .then(() => apis.user.nodes.deleteNodesById(foldersIds, false)) - - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - trashPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - Promise.all([ - apis.admin.trashcan.emptyTrash(), - logoutPage.load() - ]) - .then(done); - }); - - it('delete file', () => { - dataTable.clickOnItemName(file1) - .then(() => toolbar.actions.getButtonByTitleAttribute('Permanently delete').click()) - .then(() => trashPage.getSnackBarMessage()) - .then(text => { - expect(text).toBe(`${file1} deleted`); - expect(dataTable.getRowByName(file1).isPresent()).toBe(false, 'Item was not deleted'); - }); - }); - - it('delete folder', () => { - dataTable.clickOnItemName(folder1) - .then(() => toolbar.actions.getButtonByTitleAttribute('Permanently delete').click()) - .then(() => trashPage.getSnackBarMessage()) - .then(text => { - expect(text).toBe(`${folder1} deleted`); - expect(dataTable.getRowByName(folder1).isPresent()).toBe(false, 'Item was not deleted'); - }); - }); - - it('delete multiple items', () => { - dataTable.selectMultipleItems([ file2, folder2 ]) - .then(() => toolbar.actions.getButtonByTitleAttribute('Permanently delete').click()) - .then(() => trashPage.getSnackBarMessage()) - .then(text => { - expect(text).toBe(`2 items deleted`); - expect(dataTable.getRowByName(file2).isPresent()).toBe(false, 'Item was not deleted'); - expect(dataTable.getRowByName(folder2).isPresent()).toBe(false, 'Item was not deleted'); - }); - }); -}); diff --git a/e2e/suites/actions/restore.test.ts b/e2e/suites/actions/restore.test.ts deleted file mode 100644 index 179408cb5..000000000 --- a/e2e/suites/actions/restore.test.ts +++ /dev/null @@ -1,147 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, protractor, promise } from 'protractor'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; -import { Utils } from '../../utilities/utils'; - -describe('Restore from Trash', () => { - const username = `user-${Utils.random()}`; - - const file1 = `file-${Utils.random()}.txt`; - const file2 = `file-${Utils.random()}.txt`; - const file3 = `file-${Utils.random()}.txt`; - let filesIds; - - const folder1 = `folder-${Utils.random()}`; - const folder2 = `folder-${Utils.random()}`; - let foldersIds; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const trashPage = new BrowsingPage(); - const personalFilesPage = new BrowsingPage(); - const { dataTable } = trashPage; - const { toolbar } = trashPage; - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => apis.user.nodes.createFiles([ file1, file2, file3 ])) - .then(resp => filesIds = resp.data.list.entries.map(entries => entries.entry.id)) - .then(() => apis.user.nodes.createFolders([ folder1, folder2 ])) - .then(resp => foldersIds = resp.data.list.entries.map(entries => entries.entry.id)) - - .then(() => apis.user.nodes.deleteNodesById(filesIds, false)) - .then(() => apis.user.nodes.deleteNodesById(foldersIds, false)) - - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - trashPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - Promise.all([ - apis.user.nodes.deleteNodesById(filesIds), - apis.user.nodes.deleteNodesById(foldersIds), - apis.admin.trashcan.emptyTrash(), - logoutPage.load() - ]) - .then(done); - }); - - it('restore file', () => { - dataTable.clickOnItemName(file1) - .then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click()) - .then(() => trashPage.getSnackBarMessage()) - .then(text => { - expect(text).toContain(`${file1} restored`); - expect(text).toContain(`View`); - expect(dataTable.getRowByName(file1).isPresent()).toBe(false, 'Item was not removed from list'); - }) - .then(() => personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)) - .then(() => personalFilesPage.dataTable.waitForHeader()) - .then(() => { - expect(personalFilesPage.dataTable.getRowByName(file1).isPresent()).toBe(true, 'Item not displayed in list'); - }); - }); - - it('restore folder', () => { - dataTable.clickOnItemName(folder1) - .then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click()) - .then(() => trashPage.getSnackBarMessage()) - .then(text => { - expect(text).toContain(`${folder1} restored`); - expect(text).toContain(`View`); - expect(dataTable.getRowByName(folder1).isPresent()).toBe(false, 'Item was not removed from list'); - }) - .then(() => personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)) - .then(() => personalFilesPage.dataTable.waitForHeader()) - .then(() => { - expect(personalFilesPage.dataTable.getRowByName(folder1).isPresent()).toBe(true, 'Item not displayed in list'); - }); - }); - - it('restore multiple items', () => { - dataTable.selectMultipleItems([ file2, folder2 ]) - .then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click()) - .then(() => trashPage.getSnackBarMessage()) - .then(text => { - expect(text).toContain(`Restore successful`); - expect(text).not.toContain(`View`); - expect(dataTable.getRowByName(file2).isPresent()).toBe(false, 'Item was not removed from list'); - expect(dataTable.getRowByName(folder2).isPresent()).toBe(false, 'Item was not removed from list'); - }) - .then(() => personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)) - .then(() => personalFilesPage.dataTable.waitForHeader()) - .then(() => { - expect(personalFilesPage.dataTable.getRowByName(file2).isPresent()).toBe(true, 'Item not displayed in list'); - expect(personalFilesPage.dataTable.getRowByName(folder2).isPresent()).toBe(true, 'Item not displayed in list'); - }); - }); - - it('View from notification', () => { - dataTable.clickOnItemName(file3) - .then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click()) - .then(() => trashPage.getSnackBarAction().click()) - .then(() => personalFilesPage.dataTable.waitForHeader()) - .then(() => { - expect(personalFilesPage.sidenav.isActiveByLabel('Personal Files')).toBe(true, 'Personal Files sidebar link not active'); - expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - }); - }); -}); diff --git a/e2e/suites/actions/toolbar-multiple-selection.test.ts b/e2e/suites/actions/toolbar-multiple-selection.test.ts deleted file mode 100644 index 7a0f00ab8..000000000 --- a/e2e/suites/actions/toolbar-multiple-selection.test.ts +++ /dev/null @@ -1,535 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, protractor, promise } from 'protractor'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; -import { Utils } from '../../utilities/utils'; - -describe('Toolbar actions - multiple selection : ', () => { - const user1 = `user-${Utils.random()}`; - const user2 = `user-${Utils.random()}`; - - const file1 = `file-${Utils.random()}.txt`; - let file1Id; - const file2 = `file-${Utils.random()}.txt`; - let file2Id; - - const folder1 = `folder-${Utils.random()}`; - let folder1Id; - const folder2 = `folder-${Utils.random()}`; - let folder2Id; - - const fileForDelete1 = `file-${Utils.random()}.txt`; let fileForDelete1Id; - const fileForDelete2 = `file-${Utils.random()}.txt`; let fileForDelete2Id; - const folderForDelete1 = `folder-${Utils.random()}`; let folderForDelete1Id; - const folderForDelete2 = `folder-${Utils.random()}`; let folderForDelete2Id; - - const siteName = `site-private-${Utils.random()}`; - const file1Admin = `file-${Utils.random()}.txt`; - const file2Admin = `file-${Utils.random()}.txt`; - const folder1Admin = `folder-${Utils.random()}`; - const folder2Admin = `folder-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(user1, user1) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const page = new BrowsingPage(); - const { dataTable } = page; - const { toolbar } = page; - - beforeAll(done => { - apis.admin.people.createUser(user1) - .then(() => apis.user.nodes.createFiles([ file1 ]).then(resp => file1Id = resp.data.entry.id)) - .then(() => apis.user.nodes.createFiles([ file2 ]).then(resp => file2Id = resp.data.entry.id)) - .then(() => apis.user.nodes.createFolders([ folder1 ]).then(resp => folder1Id = resp.data.entry.id)) - .then(() => apis.user.nodes.createFolders([ folder2 ]).then(resp => folder2Id = resp.data.entry.id)) - .then(() => apis.user.nodes.createFiles([ fileForDelete1 ]).then(resp => fileForDelete1Id = resp.data.entry.id)) - .then(() => apis.user.nodes.createFiles([ fileForDelete2 ]).then(resp => fileForDelete2Id = resp.data.entry.id)) - .then(() => apis.user.nodes.createFolders([ folderForDelete1 ]).then(resp => folderForDelete1Id = resp.data.entry.id)) - .then(() => apis.user.nodes.createFolders([ folderForDelete2 ]).then(resp => folderForDelete2Id = resp.data.entry.id)) - - .then(() => apis.user.shared.shareFileById(file1Id)) - .then(() => apis.user.shared.shareFileById(file2Id)) - - .then(() => apis.user.favorites.addFavoriteById('file', file1Id)) - .then(() => apis.user.favorites.addFavoriteById('file', file2Id)) - .then(() => apis.user.favorites.addFavoriteById('folder', folder1Id)) - .then(() => apis.user.favorites.addFavoriteById('folder', folder2Id)) - - .then(() => apis.user.nodes.deleteNodeById(fileForDelete1Id, false)) - .then(() => apis.user.nodes.deleteNodeById(fileForDelete2Id, false)) - .then(() => apis.user.nodes.deleteNodeById(folderForDelete1Id, false)) - .then(() => apis.user.nodes.deleteNodeById(folderForDelete2Id, false)) - - .then(done); - }); - - afterAll(done => { - Promise.all([ - apis.user.nodes.deleteNodeById(file1Id), - apis.user.nodes.deleteNodeById(file2Id), - apis.user.nodes.deleteNodeById(folder1Id), - apis.user.nodes.deleteNodeById(folder2Id), - - apis.user.trashcan.permanentlyDelete(fileForDelete1Id), - apis.user.trashcan.permanentlyDelete(fileForDelete2Id), - apis.user.trashcan.permanentlyDelete(folderForDelete1Id), - apis.user.trashcan.permanentlyDelete(folderForDelete2Id), - - logoutPage.load() - ]) - .then(done); - }); - - xit(''); - - describe('Personal Files', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(user1)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('correct actions appear when multiple files are selected', () => { - dataTable.selectMultipleItems([file1, file2]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - - it('correct actions appear when multiple folders are selected', () => { - dataTable.selectMultipleItems([folder1, folder2]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - - it('correct actions appear when both files and folders are selected', () => { - dataTable.selectMultipleItems([file1, file2, folder1, folder2]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - }); - - describe('File Libraries', () => { - beforeAll(done => { - apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC) - .then(() => apis.admin.people.createUser(user2)) - .then(() => apis.admin.sites.addSiteMember(siteName, user1, SITE_ROLES.SITE_MANAGER)) - .then(() => apis.admin.sites.addSiteMember(siteName, user2, SITE_ROLES.SITE_CONSUMER)) - .then(() => apis.admin.nodes.createFiles([ file1Admin, file2Admin ], `Sites/${siteName}/documentLibrary`)) - .then(() => apis.admin.nodes.createFolders([ folder1Admin, folder2Admin ], `Sites/${siteName}/documentLibrary`)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES) - .then(() => dataTable.waitForHeader()) - .then(() => dataTable.doubleClickOnItemName(siteName)) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - apis.admin.sites.deleteSite(siteName).then(done); - }); - - xit(''); - - describe('user is Manager', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(user1)) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('correct actions appear when multiple files are selected', () => { - dataTable.selectMultipleItems([file1Admin, file2Admin]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - - it('correct actions appear when multiple folders are selected', () => { - dataTable.selectMultipleItems([folder1Admin, folder2Admin]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - - it('correct actions appear when both files and folders are selected', () => { - dataTable.selectMultipleItems([file1Admin, file2Admin, folder1Admin, folder2Admin]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - }); - - describe('user is Consumer', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(user2)) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('correct actions appear when multiple files are selected', () => { - dataTable.selectMultipleItems([file1Admin, file2Admin]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - - it('correct actions appear when multiple folders are selected', () => { - dataTable.selectMultipleItems([folder1Admin, folder2Admin]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - - it('correct actions appear when both files and folders are selected', () => { - dataTable.selectMultipleItems([file1Admin, file2Admin, folder1Admin, folder2Admin]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - }); - }); - - describe('Shared Files', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(user1)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('correct actions appear when multiple files are selected', () => { - dataTable.selectMultipleItems([file1, file2]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - }); - - describe('Recent Files', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(user1)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('correct actions appear when multiple files are selected', () => { - dataTable.selectMultipleItems([file1, file2]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - }); - - describe('Favorites', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(user1)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('correct actions appear when multiple files are selected', () => { - dataTable.selectMultipleItems([file1, file2]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - - it('correct actions appear when multiple folders are selected', () => { - dataTable.selectMultipleItems([folder1, folder2]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - - it('correct actions appear when both files and folders are selected', () => { - dataTable.selectMultipleItems([file1, file2, folder1, folder2]) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files'); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`); - }) - .then(() => browser.$('body').click()) - .then(() => dataTable.clearSelection()); - }); - }); - - describe('Trash', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(user1)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('correct actions appear when multiple files are selected', () => { - dataTable.selectMultipleItems([fileForDelete1, fileForDelete2]) - .then(() => { - expect(toolbar.actions.isButtonPresent('Permanently delete')) - .toBe(true, 'Permanently delete is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed for selected files'); - }) - .then(() => dataTable.clearSelection()); - }); - - it('correct actions appear when multiple folders are selected', () => { - dataTable.selectMultipleItems([folderForDelete1, folderForDelete2]) - .then(() => { - expect(toolbar.actions.isButtonPresent('Permanently delete')) - .toBe(true, 'Permanently delete is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed for selected files'); - }) - .then(() => dataTable.clearSelection()); - }); - - it('correct actions appear when both files and folders are selected', () => { - dataTable.selectMultipleItems([fileForDelete1, fileForDelete2, folderForDelete1, folderForDelete2]) - .then(() => { - expect(toolbar.actions.isButtonPresent('Permanently delete')) - .toBe(true, 'Permanently delete is displayed for selected files'); - expect(toolbar.actions.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed for selected files'); - }) - .then(() => dataTable.clearSelection()); - }); - }); -}); diff --git a/e2e/suites/actions/toolbar-single-selection.test.ts b/e2e/suites/actions/toolbar-single-selection.test.ts deleted file mode 100644 index 9721ef5d0..000000000 --- a/e2e/suites/actions/toolbar-single-selection.test.ts +++ /dev/null @@ -1,535 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, protractor, promise } from 'protractor'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; -import { Utils } from '../../utilities/utils'; - -describe('Toolbar actions - single selection : ', () => { - const username = `user-${Utils.random()}`; - const username2 = `user-${Utils.random()}`; - - const fileUser = `file-${Utils.random()}.txt`; - let fileUserId; - - const folderUser = `folder-${Utils.random()}`; - let folderUserId; - - const fileForDelete = `file-${Utils.random()}.txt`; - let fileForDeleteId; - - const folderForDelete = `folder-${Utils.random()}`; - let folderForDeleteId; - - const siteName = `site-private-${Utils.random()}`; - const fileAdmin = `file-${Utils.random()}.txt`; - const folderAdmin = `folder-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const page = new BrowsingPage(); - const { dataTable, toolbar } = page; - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => apis.user.nodes.createFiles([ fileUser ])) - .then(resp => fileUserId = resp.data.entry.id) - .then(() => apis.user.nodes.createFiles([ fileForDelete ])) - .then(resp => fileForDeleteId = resp.data.entry.id) - .then(() => apis.user.nodes.createFolders([ folderForDelete ])) - .then(resp => folderForDeleteId = resp.data.entry.id) - .then(() => apis.user.nodes.createFolders([ folderUser ])) - .then(resp => folderUserId = resp.data.entry.id) - .then(() => apis.user.shared.shareFileById(fileUserId)) - .then(() => apis.user.favorites.addFavoriteById('file', fileUserId)) - .then(() => apis.user.favorites.addFavoriteById('folder', folderUserId)) - .then(done); - }); - - afterAll(done => { - Promise.all([ - apis.user.nodes.deleteNodeById(fileUserId), - apis.user.nodes.deleteNodeById(folderUserId), - logoutPage.load() - ]) - .then(done); - }); - - xit(''); - - describe('Personal Files', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('actions are not displayed when no item is selected', () => { - expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('actions are displayed when a file is selected', () => { - dataTable.clickOnItemName(fileUser) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); - }); - }); - - it('actions are displayed when a folder is selected', () => { - dataTable.clickOnItemName(folderUser) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${folderUser}`); - }); - }); - - it('correct actions appear when a file is selected', () => { - dataTable.clickOnItemName(fileUser) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileUser}`); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileUser}`); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileUser}`); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileUser}`); - }) - .then(() => browser.$('body').click()); - }); - - it('correct actions appear when a folder is selected', () => { - dataTable.clickOnItemName(folderUser) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, `View is displayed for ${folderUser}`); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not enabled for ${folderUser}`); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(true, `Edit is not displayed for ${folderUser}`); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${folderUser}`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${folderUser}`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${folderUser}`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${folderUser}`); - }) - .then(() => browser.$('body').click()); - }); - }); - - describe('File Libraries', () => { - beforeAll(done => { - apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC) - .then(() => apis.admin.people.createUser(username2)) - .then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_MANAGER)) - .then(() => apis.admin.sites.addSiteMember(siteName, username2, SITE_ROLES.SITE_CONSUMER)) - .then(() => apis.admin.nodes.createFiles([ fileAdmin ], `Sites/${siteName}/documentLibrary`)) - .then(() => apis.admin.nodes.createFolders([ folderAdmin ], `Sites/${siteName}/documentLibrary`)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES) - .then(() => dataTable.waitForHeader()) - .then(() => dataTable.doubleClickOnItemName(siteName)) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - apis.admin.sites.deleteSite(siteName).then(done); - }); - - xit(''); - - describe('user is Manager', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('actions are not displayed when no item is selected', () => { - expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('actions are displayed when a file is selected', () => { - dataTable.clickOnItemName(fileAdmin) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileAdmin}`); - }); - }); - - it('actions are displayed when a folder is selected', () => { - dataTable.clickOnItemName(folderAdmin) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${folderAdmin}`); - }); - }); - - it('correct actions appear when a file is selected', () => { - dataTable.clickOnItemName(fileAdmin) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileAdmin}`); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileAdmin}`); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileAdmin}`); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileAdmin}`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${fileAdmin}`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${fileAdmin}`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileAdmin}`); - }) - .then(() => browser.$('body').click()); - }); - - it('correct actions appear when a folder is selected', () => { - dataTable.clickOnItemName(folderAdmin) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, `View is displayed for ${folderAdmin}`); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not enabled for ${folderAdmin}`); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(true, `Edit is not displayed for ${folderAdmin}`); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${folderAdmin}`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${folderAdmin}`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${folderAdmin}`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${folderAdmin}`); - }) - .then(() => browser.$('body').click()); - }); - }); - - describe('user is Consumer', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(username2)) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('actions are not displayed when no item is selected', () => { - expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('actions are displayed when a file is selected', () => { - dataTable.clickOnItemName(fileAdmin) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileAdmin}`); - }); - }); - - it('actions are displayed when a folder is selected', () => { - dataTable.clickOnItemName(folderAdmin) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${folderAdmin}`); - }); - }); - - it('correct actions appear when a file is selected', () => { - dataTable.clickOnItemName(fileAdmin) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileAdmin}`); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileAdmin}`); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileAdmin}`); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileAdmin}`); - expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for ${fileAdmin}`); - expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for ${fileAdmin}`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileAdmin}`); - }) - .then(() => browser.$('body').click()); - }); - - it('correct actions appear when a folder is selected', () => { - dataTable.clickOnItemName(folderAdmin) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, `View is displayed for ${folderAdmin}`); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not enabled for ${folderAdmin}`); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${folderAdmin}`); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${folderAdmin}`); - expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for ${folderAdmin}`); - expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for ${folderAdmin}`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${folderAdmin}`); - }) - .then(() => browser.$('body').click()); - }); - }); - }); - - describe('Shared Files', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('actions are not displayed when no item is selected', () => { - expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('actions are displayed when a file is selected', () => { - dataTable.clickOnItemName(fileUser) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); - }); - }); - - it('correct actions appear when a file is selected', () => { - dataTable.clickOnItemName(fileUser) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileUser}`); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileUser}`); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileUser}`); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileUser}`); - }) - .then(() => browser.$('body').click()); - }); - }); - - describe('Recent Files', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('actions are not displayed when no item is selected', () => { - expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('actions are displayed when a file is selected', () => { - dataTable.clickOnItemName(fileUser) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); - }); - }); - - it('correct actions appear when a file is selected', () => { - dataTable.clickOnItemName(fileUser) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileUser}`); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileUser}`); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileUser}`); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileUser}`); - }) - .then(() => browser.$('body').click()); - }); - }); - - describe('Favorites', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('actions are not displayed when no item is selected', () => { - expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('actions are displayed when a file is selected', () => { - dataTable.clickOnItemName(fileUser) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`); - }); - }); - - it('actions are displayed when a folder is selected', () => { - dataTable.clickOnItemName(folderUser) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${folderUser}`); - }); - }); - - it('correct actions appear when a file is selected', () => { - dataTable.clickOnItemName(fileUser) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileUser}`); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileUser}`); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileUser}`); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${fileUser}`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileUser}`); - }) - .then(() => browser.$('body').click()); - }); - - it('correct actions appear when a folder is selected', () => { - dataTable.clickOnItemName(folderUser) - .then(() => { - expect(toolbar.actions.isButtonPresent('View')).toBe(false, `View is displayed for ${folderUser}`); - expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not enabled for ${folderUser}`); - expect(toolbar.actions.isButtonPresent('Edit')).toBe(true, `Edit is not displayed for ${folderUser}`); - }) - .then(() => toolbar.actions.openMoreMenu()) - .then(menu => { - expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${folderUser}`); - expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${folderUser}`); - expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${folderUser}`); - expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${folderUser}`); - }) - .then(() => browser.$('body').click()); - }); - }); - - describe('Trash', () => { - beforeAll(done => { - apis.user.nodes.deleteNodeById(fileForDeleteId, false) - .then(() => apis.user.nodes.deleteNodeById(folderForDeleteId, false)) - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - Promise.all([ - apis.user.trashcan.permanentlyDelete(fileForDeleteId), - apis.user.trashcan.permanentlyDelete(folderForDeleteId), - logoutPage.load() - ]) - .then(done); - }); - - it('actions are not displayed when no item is selected', () => { - expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`); - }); - - it('actions are displayed when a file is selected', () => { - dataTable.clickOnItemName(fileForDelete) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileForDelete}`); - }); - }); - - it('actions are displayed when a folder is selected', () => { - dataTable.clickOnItemName(folderForDelete) - .then(() => { - expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${folderForDelete}`); - }); - }); - - it('correct actions appear when a file is selected', () => { - dataTable.clickOnItemName(fileForDelete) - .then(() => { - expect(toolbar.actions.isButtonPresent('Permanently delete')) - .toBe(true, `Permanently delete is not displayed for ${fileForDelete}`); - expect(toolbar.actions.isButtonPresent('Restore')).toBe(true, `Restore is not displayed for ${fileForDelete}`); - }); - }); - - it('correct actions appear when a folder is selected', () => { - dataTable.clickOnItemName(folderForDelete) - .then(() => { - expect(toolbar.actions.isButtonPresent('Permanently delete')) - .toBe(true, `Permanently delete is displayed for ${folderForDelete}`); - expect(toolbar.actions.isButtonPresent('Restore')).toBe(true, `Restore is not enabled for ${folderForDelete}`); - }); - }); - }); -}); diff --git a/e2e/suites/application/page-titles.test.ts b/e2e/suites/application/page-titles.test.ts deleted file mode 100644 index 69ee99f2e..000000000 --- a/e2e/suites/application/page-titles.test.ts +++ /dev/null @@ -1,133 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser } from 'protractor'; - -import { SIDEBAR_LABELS } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; - -describe('Page titles', () => { - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const page = new BrowsingPage(); - - xit(''); - - describe('on Login / Logout pages', () => { - it('on Login page', () => { - loginPage.load() - .then(() => { - expect(browser.getTitle()).toContain('Sign in'); - }); - }); - - it('after logout', () => { - loginPage.load() - .then(() => loginPage.loginWithAdmin()) - .then(() => page.signOut()) - .then(() => { - expect(browser.getTitle()).toContain('Sign in'); - }); - }); - - it('when pressing Back after Logout', () => { - loginPage.load() - .then(() => loginPage.loginWithAdmin()) - .then(() => page.signOut()) - .then(() => browser.navigate().back()) - .then(() => { - expect(browser.getTitle()).toContain('Sign in'); - }); - }); - }); - - describe('on list views', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWithAdmin()) - .then(done); - }); - - afterAll(done => { - logoutPage.load() - .then(done); - }); - - it('Personal Files page', () => { - const label = SIDEBAR_LABELS.PERSONAL_FILES; - - page.sidenav.navigateToLinkByLabel(label) - .then(() => { - expect(browser.getTitle()).toContain(label); - }); - }); - - it('File Libraries page', () => { - const label = SIDEBAR_LABELS.FILE_LIBRARIES; - - page.sidenav.navigateToLinkByLabel(label) - .then(() => { - expect(browser.getTitle()).toContain(label); - }); - }); - - it('Shared Files page', () => { - const label = SIDEBAR_LABELS.SHARED_FILES; - - page.sidenav.navigateToLinkByLabel(label) - .then(() => { - expect(browser.getTitle()).toContain(label); - }); - }); - - it('Recent Files page', () => { - const label = SIDEBAR_LABELS.RECENT_FILES; - - page.sidenav.navigateToLinkByLabel(label) - .then(() => { - expect(browser.getTitle()).toContain(label); - }); - }); - - it('Favorites page', () => { - const label = SIDEBAR_LABELS.FAVORITES; - - page.sidenav.navigateToLinkByLabel(label) - .then(() => { - expect(browser.getTitle()).toContain(label); - }); - }); - - it('Trash page', () => { - const label = SIDEBAR_LABELS.TRASH; - - page.sidenav.navigateToLinkByLabel(label) - .then(() => { - expect(browser.getTitle()).toContain(label); - }); - }); - }); -}); diff --git a/e2e/suites/authentication/login.test.ts b/e2e/suites/authentication/login.test.ts deleted file mode 100644 index 50f976259..000000000 --- a/e2e/suites/authentication/login.test.ts +++ /dev/null @@ -1,179 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser } from 'protractor'; - -import { APP_ROUTES } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; - -describe('Login', () => { - const peopleApi = new RepoClient().people; - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - - const testUser = `user-${Utils.random()}@alfness`; - - const russianUser = { - username: `пользвате${Utils.random()}`, - password: '密碼中國' - }; - - const johnDoe = { - username: `user-${Utils.random()}`, - get password() { return this.username; }, - firstName: 'John', - lastName: 'Doe' - }; - - beforeAll(done => { - Promise - .all([ - peopleApi.createUser(testUser), - peopleApi.createUser(russianUser.username, russianUser.password), - peopleApi.createUser(johnDoe.username, johnDoe.password, { - firstName: johnDoe.firstName, - lastName: johnDoe.lastName - }) - ]) - .then(done); - }); - - beforeEach(done => { - loginPage.load().then(done); - }); - - afterEach(done => { - logoutPage.load() - .then(() => Utils.clearLocalStorage()) - .then(done); - }); - - xit(''); - - describe('with valid credentials', () => { - it('navigate to "Personal Files"', () => { - const { username } = johnDoe; - - loginPage.loginWith(username) - .then(() => { - expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - }); - }); - - it(`displays user's name in header`, () => { - const { userInfo } = new BrowsingPage(APP_ROUTES.PERSONAL_FILES).header; - const { username, firstName, lastName } = johnDoe; - - loginPage.loginWith(username) - .then(() => { - expect(userInfo.name).toEqual(`${firstName} ${lastName}`); - }); - }); - - it(`logs in with user having username containing "@"`, () => { - loginPage - .loginWith(testUser) - .then(() => { - expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - }); - }); - - it('logs in with user with non-latin characters', () => { - const { username, password } = russianUser; - - loginPage - .loginWith(username, password) - .then(() => { - expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - }); - }); - - it('redirects to Home Page when navigating to the Login page while already logged in', () => { - const { username } = johnDoe; - - loginPage - .loginWith(username) - .then(() => browser.get(APP_ROUTES.LOGIN) - .then(() => { - expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - }) - ); - }); - - it('redirects to Personal Files when pressing browser Back while already logged in ', () => { - const { username } = johnDoe; - - loginPage - .loginWith(username) - .then(() => browser.navigate().back()) - .then(() => { - expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - }); - }); - }); - - describe('with invalid credentials', () => { - const { login: loginComponent } = loginPage; - const { submitButton, errorMessage } = loginComponent; - - it('disabled submit button when no credentials are entered', () => { - expect(submitButton.isEnabled()).toBe(false); - }); - - it('disabled submit button when password is empty', () => { - loginComponent.enterUsername('any-username'); - - expect(submitButton.isEnabled()).toBe(false); - }); - - it('disabled submit button when username is empty', () => { - loginPage.login.enterPassword('any-password'); - - expect(submitButton.isEnabled()).toBe(false); - }); - - it('shows error when entering nonexistent user', () => { - loginPage - .tryLoginWith('nonexistent-user', 'any-password') - .then(() => { - expect(browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN); - expect(errorMessage.isDisplayed()).toBe(true); - }); - }); - - it('shows error when entering invalid password', () => { - const { username } = johnDoe; - - loginPage - .tryLoginWith(username, 'incorrect-password') - .then(() => { - expect(browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN); - expect(errorMessage.isDisplayed()).toBe(true); - }); - }); - }); -}); diff --git a/e2e/suites/authentication/logout.test.ts b/e2e/suites/authentication/logout.test.ts deleted file mode 100644 index 4e4a78212..000000000 --- a/e2e/suites/authentication/logout.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser } from 'protractor'; - -import { APP_ROUTES, BROWSER_WAIT_TIMEOUT } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; - -describe('Logout', () => { - const page = new BrowsingPage(); - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - - const peopleApi = new RepoClient().people; - - const johnDoe = `user-${Utils.random()}`; - - beforeAll((done) => { - peopleApi - .createUser(johnDoe) - .then(done); - }); - - beforeEach((done) => { - loginPage.load() - .then(() => loginPage.loginWith(johnDoe)) - .then(done); - }); - - afterEach((done) => { - logoutPage.load() - .then(() => Utils.clearLocalStorage()) - .then(done); - }); - - it('redirects to Login page, on sign out', () => { - page.signOut() - .then(() => { - expect(browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN); - }); - }); - - it('redirects to Login page when pressing browser Back after logout', () => { - page.signOut() - .then(() => browser.navigate().back()) - .then(() => { - expect(browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN); - }); - }); -}); diff --git a/e2e/suites/list-views/empty-list.test.ts b/e2e/suites/list-views/empty-list.test.ts deleted file mode 100644 index 5e20cb87f..000000000 --- a/e2e/suites/list-views/empty-list.test.ts +++ /dev/null @@ -1,109 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('Empty list views', () => { - const username = `user-${Utils.random()}`; - const password = username; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, password) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const page = new BrowsingPage(); - const { dataTable } = page; - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('empty Personal Files', () => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES) - .then(() => { - expect(dataTable.isEmptyList()).toBe(true, 'list is not empty'); - expect(dataTable.getEmptyDragAndDropText()).toContain('Drag and drop'); - }); - }); - - it('empty File Libraries', () => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES) - .then(() => { - expect(dataTable.isEmptyList()).toBe(true, 'list is not empty'); - expect(dataTable.getEmptyStateTitle()).toContain(`You aren't a member of any File Libraries yet`); - expect(dataTable.getEmptyStateText()).toContain('Join sites to upload, view, and share files.'); - }); - }); - - it('empty Shared Files', () => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES) - .then(() => { - expect(dataTable.isEmptyList()).toBe(true, 'list is not empty'); - expect(dataTable.getEmptyStateTitle()).toContain('No shared files or folders'); - expect(dataTable.getEmptyStateText()).toContain('Items you share using the Share option are shown here.'); - }); - }); - - it('empty Recent Files', () => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES) - .then(() => { - expect(dataTable.isEmptyList()).toBe(true, 'list is not empty'); - expect(dataTable.getEmptyStateTitle()).toContain('No recent files'); - expect(dataTable.getEmptyStateText()).toContain('Items you upload or edit in the last 30 days are shown here.'); - }); - }); - - it('empty Favorites', () => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES) - .then(() => { - expect(dataTable.isEmptyList()).toBe(true, 'list is not empty'); - expect(dataTable.getEmptyStateTitle()).toContain('No favorite files or folders'); - expect(dataTable.getEmptyStateText()).toContain('Favorite items that you want to easily find later.'); - }); - }); - - it('empty Trash', () => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH) - .then(() => { - expect(dataTable.isEmptyList()).toBe(true, 'list is not empty'); - expect(dataTable.getEmptyStateTitle()).toContain('Trash is empty'); - expect(dataTable.getEmptyStateText()).toContain('Items you delete are moved to the Trash.'); - expect(dataTable.getEmptyStateText()).toContain('Empty Trash to permanently delete items.'); - }); - }); -}); diff --git a/e2e/suites/list-views/favorites.test.ts b/e2e/suites/list-views/favorites.test.ts deleted file mode 100644 index 8073b7d96..000000000 --- a/e2e/suites/list-views/favorites.test.ts +++ /dev/null @@ -1,157 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, by } from 'protractor'; - -import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('Favorites', () => { - const username = `user-${Utils.random()}`; - const password = username; - - const siteName = `site-${Utils.random()}`; - const folderName = `folder-${Utils.random()}`; - const fileName1 = `file-${Utils.random()}.txt`; - const fileName2 = `file-${Utils.random()}.txt`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, password) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const favoritesPage = new BrowsingPage(); - const { dataTable } = favoritesPage; - const { breadcrumb } = favoritesPage.toolbar; - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC)) - .then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_MANAGER)) - .then(() => apis.admin.nodes.createFiles([ fileName1 ], `Sites/${siteName}/documentLibrary`) - .then(resp => apis.user.favorites.addFavoriteById('file', resp.data.entry.id))) - .then(() => apis.user.nodes.createFolders([ folderName ]) - .then(resp => apis.user.favorites.addFavoriteById('folder', resp.data.entry.id))) - .then(() => apis.user.nodes.createFiles([ fileName2 ], folderName) - .then(resp => apis.user.favorites.addFavoriteById('file', resp.data.entry.id))) - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - favoritesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - Promise.all([ - apis.admin.sites.deleteSite(siteName), - apis.user.nodes.deleteNodes([ folderName ]), - logoutPage.load() - ]) - .then(done); - }); - - it('has the correct columns', () => { - const labels = [ 'Name', 'Location', 'Size', 'Modified', 'Modified by' ]; - const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label)); - - expect(dataTable.getColumnHeaders().count()).toBe(5 + 1, 'Incorrect number of columns'); - - elements.forEach((element, index) => { - expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`); - }); - }); - - it('displays the favorite files and folders', () => { - expect(dataTable.countRows()).toEqual(3, 'Incorrect number of items displayed'); - expect(dataTable.getRowByName(fileName1).isPresent()).toBe(true, `${fileName1} not displayed`); - expect(dataTable.getRowByName(fileName2).isPresent()).toBe(true, `${fileName2} not displayed`); - expect(dataTable.getRowByName(folderName).isPresent()).toBe(true, `${folderName} not displayed`); - }); - - it('Location column displays the parent folder of the files', () => { - const itemsLocations = { - [fileName1]: siteName, - [fileName2]: folderName, - [folderName]: 'Personal Files' - }; - - dataTable.getRows() - .map((row) => { - return row.all(dataTable.cell).map(cell => cell.getText()); - }) - .then((rowCells) => { - return rowCells.reduce((acc, cell) => { - acc[cell[1]] = cell[2]; - return acc; - }, {}); - }) - .then((favoritesList) => { - Object.keys(itemsLocations).forEach((item) => { - expect(favoritesList[item]).toEqual(itemsLocations[item]); - }); - }); - }); - - it('Location column redirect - item in user Home', () => { - dataTable.clickItemLocation(folderName) - .then(() => breadcrumb.getCurrentItemName()) - .then(name => { - expect(name).toBe('Personal Files'); - }); - }); - - it('Location column redirect - file in folder', () => { - dataTable.clickItemLocation(fileName2) - .then(() => breadcrumb.getCurrentItemName()) - .then(name => { - expect(name).toBe(folderName); - }) - .then(() => breadcrumb.getFirstItemName()) - .then(name => { - expect(name).toBe('Personal Files'); - }); - }); - - it('Location column redirect - file in site', () => { - dataTable.clickItemLocation(fileName1) - .then(() => breadcrumb.getCurrentItemName()) - .then(name => { - expect(name).toBe(siteName); - }) - .then(() => breadcrumb.getFirstItemName()) - .then(name => { - expect(name).toBe('File Libraries'); - }); - }); - -}); diff --git a/e2e/suites/list-views/file-libraries.test.ts b/e2e/suites/list-views/file-libraries.test.ts deleted file mode 100644 index 89ac75a5b..000000000 --- a/e2e/suites/list-views/file-libraries.test.ts +++ /dev/null @@ -1,131 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, by } from 'protractor'; - -import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('File Libraries', () => { - const username = `user-${Utils.random()}`; - const password = username; - - const sitePrivate = `private-${Utils.random()}`; - const siteModerated = `moderated-${Utils.random()}`; - const sitePublic = `public-${Utils.random()}`; - - const adminSite = `admin-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, password) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const fileLibrariesPage = new BrowsingPage(APP_ROUTES.FILE_LIBRARIES); - const { dataTable } = fileLibrariesPage; - - beforeAll(done => { - Promise - .all([ - apis.admin.people.createUser(username), - apis.admin.sites.createSite(sitePublic, SITE_VISIBILITY.PUBLIC), - apis.admin.sites.createSite(siteModerated, SITE_VISIBILITY.MODERATED), - apis.admin.sites.createSite(sitePrivate, SITE_VISIBILITY.PRIVATE), - apis.admin.sites.createSite(adminSite, SITE_VISIBILITY.PUBLIC) - ]) - .then(() => apis.admin.sites.addSiteMember(sitePublic, username, SITE_ROLES.SITE_CONSUMER)) - .then(() => apis.admin.sites.addSiteMember(siteModerated, username, SITE_ROLES.SITE_MANAGER)) - .then(() => apis.admin.sites.addSiteMember(sitePrivate, username, SITE_ROLES.SITE_CONTRIBUTOR)) - - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - fileLibrariesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - Promise.all([ - apis.admin.sites.deleteSite(sitePublic), - apis.admin.sites.deleteSite(siteModerated), - apis.admin.sites.deleteSite(sitePrivate), - apis.admin.sites.deleteSite(adminSite), - logoutPage.load() - ]) - .then(done); - }); - - it('has the correct columns', () => { - const labels = [ 'Title', 'Status' ]; - const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label)); - - expect(dataTable.getColumnHeaders().count()).toBe(2 + 1, 'Incorrect number of columns'); - - elements.forEach((element, index) => { - expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`); - }); - }); - - it('User can see only the sites he is a member of', () => { - const sitesCount = dataTable.countRows(); - - const expectedSites = { - [sitePrivate]: SITE_VISIBILITY.PRIVATE, - [siteModerated]: SITE_VISIBILITY.MODERATED, - [sitePublic]: SITE_VISIBILITY.PUBLIC - }; - - expect(sitesCount).toEqual(3, 'Incorrect number of sites displayed'); - expect(dataTable.getRowByName(adminSite).isPresent()).toBe(false, 'Incorrect site appears in list'); - - dataTable.getRows() - .map((row) => { - return row.all(by.css('td')).map(cell => cell.getText()); - }) - .then((rowCells) => { - return rowCells.reduce((acc, cell) => { - acc[cell[1]] = cell[2].toUpperCase(); - return acc; - }, {}); - }) - .then((sitesList) => { - Object.keys(expectedSites).forEach((site) => { - expect(sitesList[site]).toEqual(expectedSites[site]); - }); - }); - }); - - // it('Site ID is displayed when two sites have the same name', () => { - // // cannot be implemented until ACA-987 is fixed - // }); -}); diff --git a/e2e/suites/list-views/personal-files.test.ts b/e2e/suites/list-views/personal-files.test.ts deleted file mode 100644 index 7a26d04eb..000000000 --- a/e2e/suites/list-views/personal-files.test.ts +++ /dev/null @@ -1,159 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser } from 'protractor'; - -import { SIDEBAR_LABELS } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient } from '../../utilities/repo-client/repo-client'; - -describe('Personal Files', () => { - const username = `user-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const personalFilesPage = new BrowsingPage(); - const { dataTable } = personalFilesPage; - - const adminFolder = `admin-folder-${Utils.random()}`; - - const userFolder = `user-folder-${Utils.random()}`; - const userFile = `file-${Utils.random()}.txt`; - - beforeAll(done => { - Promise - .all([ - apis.admin.people.createUser(username), - apis.admin.nodes.createFolders([ adminFolder ]) - ]) - .then(() => apis.user.nodes.createFolders([ userFolder ])) - .then(() => apis.user.nodes.createFiles([ userFile ], userFolder)) - .then(done); - }); - - afterAll(done => { - Promise - .all([ - apis.admin.nodes.deleteNodes([ adminFolder ]), - apis.user.nodes.deleteNodes([ userFolder ]) - ]) - .then(done); - }); - - xit(''); - - describe(`Admin user's personal files`, () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWithAdmin()) - .then(done); - }); - - beforeEach(done => { - personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('has "Data Dictionary" folder', () => { - expect(dataTable.getRowByName('Data Dictionary').isPresent()).toBe(true); - }); - - it('has created content', () => { - expect(dataTable.getRowByName(adminFolder).isPresent()).toBe(true); - }); - }); - - describe(`Regular user's personal files`, () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('has the correct columns', () => { - const labels = [ 'Name', 'Size', 'Modified', 'Modified by' ]; - const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label)); - - expect(dataTable.getColumnHeaders().count()).toBe(4 + 1, 'Incorrect number of columns'); - - elements.forEach((element, index) => { - expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`); - }); - }); - - it('has default sorted column', () => { - expect(dataTable.getSortedColumnHeader().getText()).toBe('Modified'); - }); - - it('has user created content', () => { - expect(dataTable.getRowByName(userFolder).isPresent()) - .toBe(true); - }); - - it('navigates to folder', () => { - const getNodeIdPromise = apis.user.nodes - .getNodeByPath(`/${userFolder}`) - .then(response => response.data.entry.id); - - const navigatePromise = dataTable - .doubleClickOnItemName(userFolder) - .then(() => dataTable.waitForHeader()); - - Promise - .all([ - getNodeIdPromise, - navigatePromise - ]) - .then(([ nodeId ]) => { - expect(browser.getCurrentUrl()) - .toContain(nodeId, 'Node ID is not in the URL'); - - expect(dataTable.getRowByName(userFile).isPresent()) - .toBe(true, 'user file is missing'); - }); - }); - }); -}); diff --git a/e2e/suites/list-views/recent-files.test.ts b/e2e/suites/list-views/recent-files.test.ts deleted file mode 100644 index 6ce587ec5..000000000 --- a/e2e/suites/list-views/recent-files.test.ts +++ /dev/null @@ -1,149 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, by } from 'protractor'; - -import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('Recent Files', () => { - const username = `user-${Utils.random()}`; - const password = username; - - const folderName = `folder-${Utils.random()}`; - let folderId; - const fileName1 = `file-${Utils.random()}.txt`; - - const fileName2 = `file-${Utils.random()}.txt`; - let file2Id; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, password) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const recentFilesPage = new BrowsingPage(); - const { dataTable } = recentFilesPage; - const { breadcrumb } = recentFilesPage.toolbar; - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => apis.user.nodes.createFolders([ folderName ])) - .then(resp => folderId = resp.data.entry.id) - .then(() => apis.user.nodes.createFiles([ fileName1 ], folderName)) - - .then(() => apis.user.nodes.createFiles([ fileName2 ])) - .then(resp => file2Id = resp.data.entry.id) - - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - recentFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES) - .then(() => dataTable.isEmptyList()) - .then(empty => { - if (empty) { - browser.sleep(5000); - recentFilesPage.refresh(); - } - }) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - Promise.all([ - apis.user.nodes.deleteNodesById([ folderId, file2Id ]), - logoutPage.load() - ]) - .then(done); - }); - - it('has the correct columns', () => { - const labels = [ 'Name', 'Location', 'Size', 'Modified' ]; - const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label)); - - expect(dataTable.getColumnHeaders().count()).toBe(4 + 1, 'Incorrect number of columns'); - - elements.forEach((element, index) => { - expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`); - }); - }); - - it('displays the files added by the current user in the last 30 days', () => { - expect(dataTable.countRows()).toEqual(2, 'Incorrect number of sites displayed'); - expect(dataTable.getRowByName(fileName1).isPresent()).toBe(true, `${fileName1} not displayed`); - expect(dataTable.getRowByName(fileName2).isPresent()).toBe(true, `${fileName2} not displayed`); - }); - - it('Location column displays the parent folder of the file', () => { - const itemsLocations = { - [fileName2]: 'Personal Files', - [fileName1]: folderName - }; - - dataTable.getRows() - .map((row) => { - return row.all(dataTable.cell).map(cell => cell.getText()); - }) - .then((rowCells) => { - return rowCells.reduce((acc, cell) => { - acc[cell[1]] = cell[2]; - return acc; - }, {}); - }) - .then((recentList) => { - Object.keys(itemsLocations).forEach((item) => { - expect(recentList[item]).toEqual(itemsLocations[item]); - }); - }); - }); - - it('Location column redirect - file in user Home', () => { - dataTable.clickItemLocation(fileName1) - .then(() => breadcrumb.getCurrentItemName()) - .then(name => { - expect(name).toBe(folderName); - }) - .then(() => breadcrumb.getFirstItemName()) - .then(name => { - expect(name).toBe('Personal Files'); - }); - }); - - it('Location column redirect - file in folder', () => { - dataTable.clickItemLocation(fileName2) - .then(() => breadcrumb.getCurrentItemName()) - .then(name => { - expect(name).toBe('Personal Files'); - }); - }); -}); diff --git a/e2e/suites/list-views/shared-files.test.ts b/e2e/suites/list-views/shared-files.test.ts deleted file mode 100644 index c4bb2cddc..000000000 --- a/e2e/suites/list-views/shared-files.test.ts +++ /dev/null @@ -1,155 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, by } from 'protractor'; - -import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('Shared Files', () => { - const username = `user-${Utils.random()}`; - const password = username; - - const siteName = `site-${Utils.random()}`; - const fileAdmin = `file-${Utils.random()}.txt`; - - const folderUser = `folder-${Utils.random()}`; - const fileUser = `file-${Utils.random()}.txt`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, password) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const sharedFilesPage = new BrowsingPage(); - const { dataTable } = sharedFilesPage; - const { breadcrumb } = sharedFilesPage.toolbar; - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC)) - .then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER)) - .then(() => apis.admin.nodes.createFiles([ fileAdmin ], `Sites/${siteName}/documentLibrary`)) - .then(resp => apis.admin.shared.shareFileById(resp.data.entry.id)) - - .then(() => apis.user.nodes.createFolders([ folderUser ])) - .then(() => apis.user.nodes.createFiles([ fileUser ], folderUser)) - .then(resp => apis.user.shared.shareFileById(resp.data.entry.id)) - - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - sharedFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES) - .then(() => dataTable.isEmptyList()) - .then(empty => { - if (empty) { - browser.sleep(5000); - sharedFilesPage.refresh(); - } - }) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - Promise.all([ - apis.admin.sites.deleteSite(siteName), - apis.user.nodes.deleteNodes([ folderUser ]), - logoutPage.load() - ]) - .then(done); - }); - - it('has the correct columns', () => { - const labels = [ 'Name', 'Location', 'Size', 'Modified', 'Modified by', 'Shared by' ]; - const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label)); - - expect(dataTable.getColumnHeaders().count()).toBe(6 + 1, 'Incorrect number of columns'); - - elements.forEach((element, index) => { - expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`); - }); - }); - - it('displays the files shared by everyone', () => { - expect(dataTable.countRows()).toEqual(2, 'Incorrect number of items displayed'); - expect(dataTable.getRowByName(fileAdmin).isPresent()).toBe(true, `${fileAdmin} not displayed`); - expect(dataTable.getRowByName(fileUser).isPresent()).toBe(true, `${fileUser} not displayed`); - }); - - it('Location column displays the parent folder of the file', () => { - const itemsLocations = { - [fileAdmin]: siteName, - [fileUser]: folderUser - }; - - dataTable.getRows() - .map((row) => { - return row.all(dataTable.cell).map(cell => cell.getText()); - }) - .then((rowCells) => { - return rowCells.reduce((acc, cell) => { - acc[cell[1]] = cell[2]; - return acc; - }, {}); - }) - .then((recentList) => { - Object.keys(itemsLocations).forEach((item) => { - expect(recentList[item]).toEqual(itemsLocations[item]); - }); - }); - }); - - it('Location column redirect - file in user Home', () => { - dataTable.clickItemLocation(fileUser) - .then(() => breadcrumb.getCurrentItemName()) - .then(name => { - expect(name).toBe(folderUser); - }) - .then(() => breadcrumb.getFirstItemName()) - .then(name => { - expect(name).toBe('Personal Files'); - }); - }); - - it('Location column redirect - file in site', () => { - dataTable.clickItemLocation(fileAdmin) - .then(() => breadcrumb.getCurrentItemName()) - .then(name => { - expect(name).toBe(siteName); - }) - .then(() => breadcrumb.getFirstItemName()) - .then(name => { - expect(name).toBe('File Libraries'); - }); - }); -}); diff --git a/e2e/suites/list-views/trash.test.ts b/e2e/suites/list-views/trash.test.ts deleted file mode 100644 index 7c4969bc4..000000000 --- a/e2e/suites/list-views/trash.test.ts +++ /dev/null @@ -1,188 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, by } from 'protractor'; - -import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('Trash', () => { - const username = `user-${Utils.random()}`; - - const siteName = `site-${Utils.random()}`; - const fileSite = `file-${Utils.random()}.txt`; - let fileSiteId; - - const folderAdmin = `folder-${Utils.random()}`; - let folderAdminId; - const fileAdmin = `file-${Utils.random()}.txt`; - let fileAdminId; - - const folderUser = `folder-${Utils.random()}`; - let folderUserId; - const fileUser = `file-${Utils.random()}.txt`; - let fileUserId; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const trashPage = new BrowsingPage(); - const { dataTable } = trashPage; - const { breadcrumb } = trashPage.toolbar; - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => apis.admin.nodes.createFiles([ fileAdmin ]) - .then(resp => fileAdminId = resp.data.entry.id)) - .then(() => apis.admin.nodes.createFolders([ folderAdmin ]) - .then(resp => folderAdminId = resp.data.entry.id)) - .then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC)) - .then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_MANAGER)) - .then(() => apis.admin.nodes.createFiles([ fileSite ], `Sites/${siteName}/documentLibrary`) - .then(resp => fileSiteId = resp.data.entry.id)) - .then(() => apis.user.nodes.createFiles([ fileUser ]) - .then(resp => fileUserId = resp.data.entry.id)) - .then(() => apis.user.nodes.createFolders([ folderUser ]) - .then(resp => folderUserId = resp.data.entry.id)) - - .then(() => apis.admin.nodes.deleteNodesById([ fileAdminId, folderAdminId ], false)) - .then(() => apis.user.nodes.deleteNodesById([ fileSiteId, fileUserId, folderUserId ], false)) - - .then(done); - }); - - afterAll(done => { - Promise.all([ - apis.admin.sites.deleteSite(siteName), - apis.admin.trashcan.emptyTrash() - ]) - .then(done); - }); - - xit(''); - - describe('as admin', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWithAdmin()) - .then(done); - }); - - beforeEach(done => { - trashPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('has the correct columns', () => { - const labels = [ 'Name', 'Location', 'Size', 'Deleted', 'Deleted by' ]; - const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label)); - - expect(dataTable.getColumnHeaders().count()).toBe(5 + 1, 'Incorrect number of columns'); - - elements.forEach((element, index) => { - expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`); - }); - }); - - it('displays the files and folders deleted by everyone', () => { - expect(dataTable.countRows()).toEqual(5, 'Incorrect number of deleted items displayed'); - - expect(dataTable.getRowByName(fileAdmin).isPresent()).toBe(true, `${fileAdmin} not displayed`); - expect(dataTable.getRowByName(folderAdmin).isPresent()).toBe(true, `${folderAdmin} not displayed`); - expect(dataTable.getRowByName(fileUser).isPresent()).toBe(true, `${fileUser} not displayed`); - expect(dataTable.getRowByName(folderUser).isPresent()).toBe(true, `${folderUser} not displayed`); - expect(dataTable.getRowByName(fileSite).isPresent()).toBe(true, `${fileSite} not displayed`); - }); - }); - - describe('as user', () => { - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - trashPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('has the correct columns', () => { - const labels = [ 'Name', 'Location', 'Size', 'Deleted', 'Deleted by' ]; - const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label)); - - expect(dataTable.getColumnHeaders().count()).toBe(5 + 1, 'Incorrect number of columns'); - - elements.forEach((element, index) => { - expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`); - }); - }); - - it('displays the files and folders deleted by the user', () => { - expect(dataTable.countRows()).toEqual(3, 'Incorrect number of deleted items displayed'); - - expect(dataTable.getRowByName(fileSite).isPresent()).toBe(true, `${fileSite} not displayed`); - expect(dataTable.getRowByName(fileUser).isPresent()).toBe(true, `${fileUser} not displayed`); - expect(dataTable.getRowByName(folderUser).isPresent()).toBe(true, `${folderUser} not displayed`); - expect(dataTable.getRowByName(fileAdmin).isPresent()).toBe(false, `${fileAdmin} is displayed`); - }); - - it('Location column redirect - file in user Home', () => { - dataTable.clickItemLocation(fileUser) - .then(() => breadcrumb.getCurrentItemName()) - .then(name => { - expect(name).toBe('Personal Files'); - }); - }); - - it('Location column redirect - file in site', () => { - dataTable.clickItemLocation(fileSite) - .then(() => breadcrumb.getCurrentItemName()) - .then(name => { - expect(name).toBe(siteName); - }) - .then(() => breadcrumb.getFirstItemName()) - .then(name => { - expect(name).toBe('File Libraries'); - }); - }); - }); -}); diff --git a/e2e/suites/navigation/side-navigation.test.ts b/e2e/suites/navigation/side-navigation.test.ts deleted file mode 100644 index 569c0fc5b..000000000 --- a/e2e/suites/navigation/side-navigation.test.ts +++ /dev/null @@ -1,129 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser } from 'protractor'; - -import { APP_ROUTES, SIDEBAR_LABELS } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; - -describe('Side navigation', () => { - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const page = new BrowsingPage(); - - beforeAll(done => { - loginPage.load() - .then(() => loginPage.loginWithAdmin()) - .then(done); - }); - - beforeEach(done => { - page.dataTable.wait().then(done); - }); - - afterAll(done => { - logoutPage.load().then(done); - }); - - it('has "Personal Files" as default', () => { - expect(browser.getCurrentUrl()) - .toContain(APP_ROUTES.PERSONAL_FILES); - - expect(page.sidenav.isActiveByLabel('Personal Files')) - .toBe(true, 'Active link'); - }); - - it('navigates to "File Libraries"', () => { - const { sidenav, dataTable } = page; - - sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES) - .then(() => dataTable.wait()) - .then(() => browser.getCurrentUrl()) - .then(url => { - expect(url).toContain(APP_ROUTES.FILE_LIBRARIES); - expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)).toBe(true); - }); - }); - - it('navigates to "Personal Files"', () => { - const { sidenav, dataTable } = page; - - sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES) - .then(() => dataTable.wait()) - .then(() => browser.getCurrentUrl()) - .then(url => { - expect(url).toContain(APP_ROUTES.PERSONAL_FILES); - expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.PERSONAL_FILES)).toBe(true); - }); - }); - - it('navigates to "Shared Files"', () => { - const { sidenav, dataTable } = page; - - sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES) - .then(() => dataTable.wait()) - .then(() => browser.getCurrentUrl()) - .then(url => { - expect(url).toContain(APP_ROUTES.SHARED_FILES); - expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.SHARED_FILES)).toBe(true); - }); - }); - - it('navigates to "Recent Files"', () => { - const { sidenav, dataTable } = page; - - sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES) - .then(() => dataTable.wait()) - .then(() => browser.getCurrentUrl()) - .then(url => { - expect(url).toContain(APP_ROUTES.RECENT_FILES); - expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.RECENT_FILES)).toBe(true); - }); - }); - - it('navigates to "Favorites"', () => { - const { sidenav, dataTable } = page; - - sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES) - .then(() => dataTable.wait()) - .then(() => browser.getCurrentUrl()) - .then(url => { - expect(url).toContain(APP_ROUTES.FAVORITES); - expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.FAVORITES)).toBe(true); - }); - }); - - it('navigates to "Trash"', () => { - const { sidenav, dataTable } = page; - - sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH) - .then(() => dataTable.wait()) - .then(() => browser.getCurrentUrl()) - .then(url => { - expect(url).toContain(APP_ROUTES.TRASHCAN); - expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.TRASH)).toBe(true); - }); - }); -}); diff --git a/e2e/suites/pagination/pag-favorites.test.ts b/e2e/suites/pagination/pag-favorites.test.ts deleted file mode 100644 index 18c86311d..000000000 --- a/e2e/suites/pagination/pag-favorites.test.ts +++ /dev/null @@ -1,186 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, protractor, promise } from 'protractor'; -import { SIDEBAR_LABELS, SITE_VISIBILITY } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('Pagination on Favorites', () => { - const username = `user-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - const { nodes: nodesApi, favorites: favoritesApi } = apis.user; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const page = new BrowsingPage(); - const { dataTable, pagination } = page; - - const parent = `parent-${Utils.random()}`; - const files = Array(101) - .fill('file') - .map((name, index): string => `${name}-${index + 1}.txt`); - let filesIds; - - function resetToDefaultPageSize(): promise.Promise { - return pagination.openMaxItemsMenu() - .then(menu => menu.clickMenuItem('25')) - .then(() => dataTable.waitForHeader()); - } - - function resetToDefaultPageNumber(): promise.Promise { - return pagination.openCurrentPageMenu() - .then(menu => menu.clickMenuItem('1')) - .then(() => dataTable.waitForHeader()); - } - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => nodesApi.createFiles(files, parent)) - .then(resp => filesIds = resp.data.list.entries.map(entries => entries.entry.id)) - - .then(() => favoritesApi.addFavoritesByIds('file', filesIds)) - - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterEach(done => { - browser.actions().sendKeys(protractor.Key.ESCAPE).perform().then(done); - }); - - afterAll(done => { - Promise.all([ - nodesApi.deleteNodes([ parent ]), - logoutPage.load() - ]) - .then(done); - }); - - it('default values', () => { - expect(pagination.range.getText()).toContain('1-25 of 101'); - expect(pagination.maxItems.getText()).toContain('25'); - expect(pagination.currentPage.getText()).toContain('Page 1'); - expect(pagination.totalPages.getText()).toContain('of 5'); - expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled'); - expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled'); - }); - - it('page sizes', () => { - pagination.openMaxItemsMenu() - .then(menu => { - const [ first, second, third ] = [1, 2, 3] - .map(nth => menu.getNthItem(nth).getText()); - expect(first).toBe('25'); - expect(second).toBe('50'); - expect(third).toBe('100'); - }); - }); - - it('change the page size', () => { - pagination.openMaxItemsMenu() - .then(menu => menu.clickMenuItem('50')) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.maxItems.getText()).toContain('50'); - expect(pagination.totalPages.getText()).toContain('of 3'); - }) - - .then(() => resetToDefaultPageSize()); - }); - - it('current page menu items', () => { - pagination.openCurrentPageMenu() - .then(menu => { - expect(menu.getItemsCount()).toBe(5); - }); - }); - - it('change the current page from menu', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(3)) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('51-75 of 101'); - expect(pagination.currentPage.getText()).toContain('Page 3'); - expect(pagination.previousButton.isEnabled()).toBe(true, 'Previous button is not enabled'); - expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled'); - expect(dataTable.getRowByName('file-40.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('navigate to next page', () => { - pagination.nextButton.click() - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('26-50 of 101'); - expect(dataTable.getRowByName('file-70.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('navigate to previous page', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(2)) - .then(() => dataTable.waitForHeader()) - .then(() => pagination.previousButton.click()) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('1-25 of 101'); - expect(dataTable.getRowByName('file-88.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('last page', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(5)) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page'); - expect(pagination.currentPage.getText()).toContain('Page 5'); - expect(pagination.nextButton.isEnabled()).toBe(false, 'Next button is enabled'); - }); - }); -}); diff --git a/e2e/suites/pagination/pag-personal-files.test.ts b/e2e/suites/pagination/pag-personal-files.test.ts deleted file mode 100644 index aed53568d..000000000 --- a/e2e/suites/pagination/pag-personal-files.test.ts +++ /dev/null @@ -1,183 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, protractor, promise } from 'protractor'; -import { SIDEBAR_LABELS, SITE_VISIBILITY } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('Pagination on Personal Files', () => { - const username = `user-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - const { nodes: nodesApi } = apis.user; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const page = new BrowsingPage(); - const { dataTable, pagination } = page; - - const parent = `parent-${Utils.random()}`; - const files = Array(101) - .fill('file') - .map((name, index): string => `${name}-${index + 1}.txt`); - - function resetToDefaultPageSize(): promise.Promise { - return pagination.openMaxItemsMenu() - .then(menu => menu.clickMenuItem('25')) - .then(() => dataTable.waitForHeader()); - } - - function resetToDefaultPageNumber(): promise.Promise { - return pagination.openCurrentPageMenu() - .then(menu => menu.clickMenuItem('1')) - .then(() => dataTable.waitForHeader()); - } - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => nodesApi.createFiles(files, parent)) - - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES) - .then(() => dataTable.waitForHeader()) - .then(() => dataTable.doubleClickOnItemName(parent)) - .then(done); - }); - - afterEach(done => { - browser.actions().sendKeys(protractor.Key.ESCAPE).perform().then(done); - }); - - afterAll(done => { - Promise.all([ - nodesApi.deleteNodes([ parent ]), - logoutPage.load() - ]) - .then(done); - }); - - it('default values', () => { - expect(pagination.range.getText()).toContain('1-25 of 101'); - expect(pagination.maxItems.getText()).toContain('25'); - expect(pagination.currentPage.getText()).toContain('Page 1'); - expect(pagination.totalPages.getText()).toContain('of 5'); - expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled'); - expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled'); - }); - - it('page sizes', () => { - pagination.openMaxItemsMenu() - .then(menu => { - const [ first, second, third ] = [1, 2, 3] - .map(nth => menu.getNthItem(nth).getText()); - expect(first).toBe('25'); - expect(second).toBe('50'); - expect(third).toBe('100'); - }); - }); - - it('change the page size', () => { - pagination.openMaxItemsMenu() - .then(menu => menu.clickMenuItem('50')) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.maxItems.getText()).toContain('50'); - expect(pagination.totalPages.getText()).toContain('of 3'); - }) - - .then(() => resetToDefaultPageSize()); - }); - - it('current page menu items', () => { - pagination.openCurrentPageMenu() - .then(menu => { - expect(menu.getItemsCount()).toBe(5); - }); - }); - - it('change the current page from menu', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(3)) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('51-75 of 101'); - expect(pagination.currentPage.getText()).toContain('Page 3'); - expect(pagination.previousButton.isEnabled()).toBe(true, 'Previous button is not enabled'); - expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled'); - expect(dataTable.getRowByName('file-60.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('navigate to next page', () => { - pagination.nextButton.click() - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('26-50 of 101'); - expect(dataTable.getRowByName('file-30.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('navigate to previous page', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(2)) - .then(() => dataTable.waitForHeader()) - .then(() => pagination.previousButton.click()) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('1-25 of 101'); - expect(dataTable.getRowByName('file-12.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('last page', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(5)) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page'); - expect(pagination.currentPage.getText()).toContain('Page 5'); - expect(pagination.nextButton.isEnabled()).toBe(false, 'Next button is enabled'); - }); - }); -}); diff --git a/e2e/suites/pagination/pag-recent-files.test.ts b/e2e/suites/pagination/pag-recent-files.test.ts deleted file mode 100644 index 7a1089e12..000000000 --- a/e2e/suites/pagination/pag-recent-files.test.ts +++ /dev/null @@ -1,189 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, protractor, promise } from 'protractor'; -import { SIDEBAR_LABELS, SITE_VISIBILITY } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('Pagination on Recent Files', () => { - const username = `user-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - const { nodes: nodesApi } = apis.user; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const page = new BrowsingPage(); - const { dataTable, pagination } = page; - - const parent = `parent-${Utils.random()}`; - const files = Array(101) - .fill('file') - .map((name, index): string => `${name}-${index + 1}.txt`); - - function resetToDefaultPageSize(): promise.Promise { - return pagination.openMaxItemsMenu() - .then(menu => menu.clickMenuItem('25')) - .then(() => dataTable.waitForHeader()); - } - - function resetToDefaultPageNumber(): promise.Promise { - return pagination.openCurrentPageMenu() - .then(menu => menu.clickMenuItem('1')) - .then(() => dataTable.waitForHeader()); - } - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => nodesApi.createFiles(files, parent)) - - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES) - .then(() => dataTable.isEmptyList()) - .then(empty => { - if (empty) { - browser.sleep(3000); - page.refresh(); - } - }) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterEach(done => { - browser.actions().sendKeys(protractor.Key.ESCAPE).perform().then(done); - }); - - afterAll(done => { - Promise.all([ - nodesApi.deleteNodes([ parent ]), - logoutPage.load() - ]) - .then(done); - }); - - it('default values', () => { - expect(pagination.range.getText()).toContain('1-25 of 101'); - expect(pagination.maxItems.getText()).toContain('25'); - expect(pagination.currentPage.getText()).toContain('Page 1'); - expect(pagination.totalPages.getText()).toContain('of 5'); - expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled'); - expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled'); - }); - - it('page sizes', () => { - pagination.openMaxItemsMenu() - .then(menu => { - const [ first, second, third ] = [1, 2, 3] - .map(nth => menu.getNthItem(nth).getText()); - expect(first).toBe('25'); - expect(second).toBe('50'); - expect(third).toBe('100'); - }); - }); - - it('change the page size', () => { - pagination.openMaxItemsMenu() - .then(menu => menu.clickMenuItem('50')) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.maxItems.getText()).toContain('50'); - expect(pagination.totalPages.getText()).toContain('of 3'); - }) - - .then(() => resetToDefaultPageSize()); - }); - - it('current page menu items', () => { - pagination.openCurrentPageMenu() - .then(menu => { - expect(menu.getItemsCount()).toBe(5); - }); - }); - - it('change the current page from menu', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(3)) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('51-75 of 101'); - expect(pagination.currentPage.getText()).toContain('Page 3'); - expect(pagination.previousButton.isEnabled()).toBe(true, 'Previous button is not enabled'); - expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled'); - expect(dataTable.getRowByName('file-40.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('navigate to next page', () => { - pagination.nextButton.click() - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('26-50 of 101'); - expect(dataTable.getRowByName('file-70.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('navigate to previous page', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(2)) - .then(() => dataTable.waitForHeader()) - .then(() => pagination.previousButton.click()) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('1-25 of 101'); - expect(dataTable.getRowByName('file-88.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('last page', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(5)) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page'); - expect(pagination.currentPage.getText()).toContain('Page 5'); - expect(pagination.nextButton.isEnabled()).toBe(false, 'Next button is enabled'); - }); - }); -}); diff --git a/e2e/suites/pagination/pag-shared-files.test.ts b/e2e/suites/pagination/pag-shared-files.test.ts deleted file mode 100644 index ac6faca9c..000000000 --- a/e2e/suites/pagination/pag-shared-files.test.ts +++ /dev/null @@ -1,193 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, protractor, promise } from 'protractor'; -import { SIDEBAR_LABELS, SITE_VISIBILITY } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('Pagination on Shared Files', () => { - const username = `user-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - const { nodes: nodesApi, shared: sharedApi } = apis.user; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const page = new BrowsingPage(); - const { dataTable, pagination } = page; - - const parent = `parent-${Utils.random()}`; - const files = Array(101) - .fill('file') - .map((name, index): string => `${name}-${index + 1}.txt`); - let filesIds; - - function resetToDefaultPageSize(): promise.Promise { - return pagination.openMaxItemsMenu() - .then(menu => menu.clickMenuItem('25')) - .then(() => dataTable.waitForHeader()); - } - - function resetToDefaultPageNumber(): promise.Promise { - return pagination.openCurrentPageMenu() - .then(menu => menu.clickMenuItem('1')) - .then(() => dataTable.waitForHeader()); - } - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => nodesApi.createFiles(files, parent)) - .then(resp => filesIds = resp.data.list.entries.map(entries => entries.entry.id)) - - .then(() => sharedApi.shareFilesByIds(filesIds)) - - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES) - .then(() => dataTable.isEmptyList()) - .then(empty => { - if (empty) { - browser.sleep(6000); - page.refresh(); - } - }) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterEach(done => { - browser.actions().sendKeys(protractor.Key.ESCAPE).perform().then(done); - }); - - afterAll(done => { - Promise.all([ - nodesApi.deleteNodes([ parent ]), - logoutPage.load() - ]) - .then(done); - }); - - it('default values', () => { - expect(pagination.range.getText()).toContain('1-25 of 101'); - expect(pagination.maxItems.getText()).toContain('25'); - expect(pagination.currentPage.getText()).toContain('Page 1'); - expect(pagination.totalPages.getText()).toContain('of 5'); - expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled'); - expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled'); - }); - - it('page sizes', () => { - pagination.openMaxItemsMenu() - .then(menu => { - const [ first, second, third ] = [1, 2, 3] - .map(nth => menu.getNthItem(nth).getText()); - expect(first).toBe('25'); - expect(second).toBe('50'); - expect(third).toBe('100'); - }); - }); - - it('change the page size', () => { - pagination.openMaxItemsMenu() - .then(menu => menu.clickMenuItem('50')) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.maxItems.getText()).toContain('50'); - expect(pagination.totalPages.getText()).toContain('of 3'); - }) - - .then(() => resetToDefaultPageSize()); - }); - - it('current page menu items', () => { - pagination.openCurrentPageMenu() - .then(menu => { - expect(menu.getItemsCount()).toBe(5); - }); - }); - - it('change the current page from menu', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(3)) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('51-75 of 101'); - expect(pagination.currentPage.getText()).toContain('Page 3'); - expect(pagination.previousButton.isEnabled()).toBe(true, 'Previous button is not enabled'); - expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled'); - expect(dataTable.getRowByName('file-40.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('navigate to next page', () => { - pagination.nextButton.click() - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('26-50 of 101'); - expect(dataTable.getRowByName('file-70.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('navigate to previous page', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(2)) - .then(() => dataTable.waitForHeader()) - .then(() => pagination.previousButton.click()) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('1-25 of 101'); - expect(dataTable.getRowByName('file-88.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('last page', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(5)) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page'); - expect(pagination.currentPage.getText()).toContain('Page 5'); - expect(pagination.nextButton.isEnabled()).toBe(false, 'Next button is enabled'); - }); - }); -}); diff --git a/e2e/suites/pagination/pag-trash.test.ts b/e2e/suites/pagination/pag-trash.test.ts deleted file mode 100644 index 4f318877c..000000000 --- a/e2e/suites/pagination/pag-trash.test.ts +++ /dev/null @@ -1,184 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, protractor, promise } from 'protractor'; -import { SIDEBAR_LABELS, SITE_VISIBILITY } from '../../configs'; -import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; -import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; - -describe('Pagination on Trash', () => { - const username = `user-${Utils.random()}`; - - const apis = { - admin: new RepoClient(), - user: new RepoClient(username, username) - }; - const { nodes: nodesApi, trashcan: trashApi } = apis.user; - - const loginPage = new LoginPage(); - const logoutPage = new LogoutPage(); - const page = new BrowsingPage(); - const { dataTable, pagination } = page; - - const filesForDelete = Array(101) - .fill('file') - .map((name, index): string => `${name}-${index + 1}.txt`); - let filesDeletedIds; - - function resetToDefaultPageSize(): promise.Promise { - return pagination.openMaxItemsMenu() - .then(menu => menu.clickMenuItem('25')) - .then(() => dataTable.waitForHeader()); - } - - function resetToDefaultPageNumber(): promise.Promise { - return pagination.openCurrentPageMenu() - .then(menu => menu.clickMenuItem('1')) - .then(() => dataTable.waitForHeader()); - } - - beforeAll(done => { - apis.admin.people.createUser(username) - .then(() => nodesApi.createFiles(filesForDelete)) - .then(resp => filesDeletedIds = resp.data.list.entries.map(entries => entries.entry.id)) - .then(() => nodesApi.deleteNodesById(filesDeletedIds, false)) - - .then(() => loginPage.load()) - .then(() => loginPage.loginWith(username)) - .then(done); - }); - - beforeEach(done => { - page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH) - .then(() => dataTable.waitForHeader()) - .then(done); - }); - - afterEach(done => { - browser.actions().sendKeys(protractor.Key.ESCAPE).perform().then(done); - }); - - afterAll(done => { - Promise.all([ - trashApi.emptyTrash(), - logoutPage.load() - ]) - .then(done); - }); - - it('default values', () => { - expect(pagination.range.getText()).toContain('1-25 of 101'); - expect(pagination.maxItems.getText()).toContain('25'); - expect(pagination.currentPage.getText()).toContain('Page 1'); - expect(pagination.totalPages.getText()).toContain('of 5'); - expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled'); - expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled'); - }); - - it('page sizes', () => { - pagination.openMaxItemsMenu() - .then(menu => { - const [ first, second, third ] = [1, 2, 3] - .map(nth => menu.getNthItem(nth).getText()); - expect(first).toBe('25'); - expect(second).toBe('50'); - expect(third).toBe('100'); - }); - }); - - it('change the page size', () => { - pagination.openMaxItemsMenu() - .then(menu => menu.clickMenuItem('50')) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.maxItems.getText()).toContain('50'); - expect(pagination.totalPages.getText()).toContain('of 3'); - }) - - .then(() => resetToDefaultPageSize()); - }); - - it('current page menu items', () => { - pagination.openCurrentPageMenu() - .then(menu => { - expect(menu.getItemsCount()).toBe(5); - }); - }); - - it('change the current page from menu', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(3)) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('51-75 of 101'); - expect(pagination.currentPage.getText()).toContain('Page 3'); - expect(pagination.previousButton.isEnabled()).toBe(true, 'Previous button is not enabled'); - expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled'); - expect(dataTable.getRowByName('file-40.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('navigate to next page', () => { - pagination.nextButton.click() - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('26-50 of 101'); - expect(dataTable.getRowByName('file-70.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('navigate to previous page', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(2)) - .then(() => dataTable.waitForHeader()) - .then(() => pagination.previousButton.click()) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(pagination.range.getText()).toContain('1-25 of 101'); - expect(dataTable.getRowByName('file-88.txt').isPresent()) - .toBe(true, 'File not found on page'); - }) - - .then(() => resetToDefaultPageNumber()); - }); - - it('last page', () => { - pagination.openCurrentPageMenu() - .then(menu => menu.clickNthItem(5)) - .then(() => dataTable.waitForHeader()) - .then(() => { - expect(dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page'); - expect(pagination.currentPage.getText()).toContain('Page 5'); - expect(pagination.nextButton.isEnabled()).toBe(false, 'Next button is enabled'); - }); - }); -}); diff --git a/e2e/utilities/repo-client/apis/favorites/favorites-api.ts b/e2e/utilities/repo-client/apis/favorites/favorites-api.ts deleted file mode 100644 index dd1cd7b47..000000000 --- a/e2e/utilities/repo-client/apis/favorites/favorites-api.ts +++ /dev/null @@ -1,86 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { promise } from 'protractor'; -import { RepoApi } from '../repo-api'; -import { NodesApi } from '../nodes/nodes-api'; -import { RepoClient } from './../../repo-client'; - -export class FavoritesApi extends RepoApi { - - addFavorite(api: RepoClient, nodeType: string, name: string): Promise { - return api.nodes.getNodeByPath(name) - .then((response) => { - const { id } = response.data.entry; - return ([{ - target: { - [nodeType]: { - guid: id - } - } - }]); - }) - .then((data) => { - return this.post(`/people/-me-/favorites`, { data }); - }) - .catch(this.handleError); - } - - addFavoriteById(nodeType: string, id: string): Promise { - const data = [{ - target: { - [nodeType]: { - guid: id - } - } - }]; - return this.post(`/people/-me-/favorites`, { data }) - .catch(this.handleError); - } - - addFavoritesByIds(nodeType: string, ids: string[]): Promise { - return ids.reduce((previous, current) => ( - previous.then(() => this.addFavoriteById(nodeType, current)) - ), Promise.resolve()); - } - - getFavorite(api: RepoClient, name: string): Promise { - return api.nodes.getNodeByPath(name) - .then((response) => { - const { id } = response.data.entry; - return this.get(`/people/-me-/favorites/${id}`); - }) - .catch((response) => Promise.resolve(response)); - } - - removeFavorite(api: RepoClient, nodeType: string, name: string): Promise { - return api.nodes.getNodeByPath(name) - .then((response) => { - const { id } = response.data.entry; - return this.delete(`/people/-me-/favorites/${id}`); - }) - .catch(this.handleError); - } -} diff --git a/e2e/utilities/repo-client/apis/nodes/node-body-create.ts b/e2e/utilities/repo-client/apis/nodes/node-body-create.ts deleted file mode 100644 index 31c369d34..000000000 --- a/e2e/utilities/repo-client/apis/nodes/node-body-create.ts +++ /dev/null @@ -1,38 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -export const NODE_TYPE_FILE = 'cm:content'; -export const NODE_TYPE_FOLDER = 'cm:folder'; -export const NODE_TITLE = 'cm:title'; -export const NODE_DESCRIPTION = 'cm:description'; - -export class NodeBodyCreate { - constructor( - public name: string, - public nodeType: string, - public relativePath: string = '/', - public properties?: any[] - ) {} -} diff --git a/e2e/utilities/repo-client/apis/nodes/node-content-tree.ts b/e2e/utilities/repo-client/apis/nodes/node-content-tree.ts deleted file mode 100644 index 45516429b..000000000 --- a/e2e/utilities/repo-client/apis/nodes/node-content-tree.ts +++ /dev/null @@ -1,85 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { NodeBodyCreate, NODE_TYPE_FILE, NODE_TYPE_FOLDER, NODE_TITLE, NODE_DESCRIPTION } from './node-body-create'; - -export interface NodeContentTree { - name?: string; - files?: string[]; - folders?: (string|NodeContentTree)[]; - title?: string; - description?: string; -} - -export function flattenNodeContentTree(content: NodeContentTree, relativePath: string = '/'): NodeBodyCreate[] { - const { name, files, folders, title, description } = content; - let data: NodeBodyCreate[] = []; - let properties: any; - - properties = { - [NODE_TITLE]: title, - [NODE_DESCRIPTION]: description - }; - - if (name) { - data = data.concat([{ - nodeType: NODE_TYPE_FOLDER, - name, - relativePath, - properties - }]); - - relativePath = (relativePath === '/') - ? `/${name}` - : `${relativePath}/${name}`; - } - - if (folders) { - const foldersData: NodeBodyCreate[] = folders - .map((folder: (string|NodeContentTree)): NodeBodyCreate[] => { - const folderData: NodeContentTree = (typeof folder === 'string') - ? { name: folder } - : folder; - - return flattenNodeContentTree(folderData, relativePath); - }) - .reduce((nodesData: NodeBodyCreate[], folderData: NodeBodyCreate[]) => nodesData.concat(folderData), []); - - data = data.concat(foldersData); - } - - if (files) { - const filesData: NodeBodyCreate[] = files - .map((filename: string): NodeBodyCreate => ({ - nodeType: NODE_TYPE_FILE, - name: filename, - relativePath - })); - - data = data.concat(filesData); - } - - return data; -} diff --git a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts b/e2e/utilities/repo-client/apis/nodes/nodes-api.ts deleted file mode 100644 index 410cebc92..000000000 --- a/e2e/utilities/repo-client/apis/nodes/nodes-api.ts +++ /dev/null @@ -1,104 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { RepoApi } from '../repo-api'; -import { NodeBodyCreate, NODE_TYPE_FILE, NODE_TYPE_FOLDER } from './node-body-create'; -import { NodeContentTree, flattenNodeContentTree } from './node-content-tree'; - -export class NodesApi extends RepoApi { - // nodes - getNodeByPath(relativePath: string = '/'): Promise { - return this - .get(`/nodes/-my-`, { parameters: { relativePath } }) - .catch(this.handleError); - } - - getNodeById(id: string): Promise { - return this - .get(`/nodes/${id}`) - .catch(this.handleError); - } - - getNodeDescription(name: string): Promise { - return this.getNodeByPath(name) - .then(response => response.data.entry.properties['cm:description']) - .catch(() => Promise.resolve('')); - } - - deleteNodeById(id: string, permanent: boolean = true): Promise { - return this - .delete(`/nodes/${id}?permanent=${permanent}`) - .catch(this.handleError); - } - - deleteNodeByPath(path: string, permanent: boolean = true): Promise { - return this - .getNodeByPath(path) - .then((response: any): string => response.data.entry.id) - .then((id: string): any => this.deleteNodeById(id, permanent)) - .catch(this.handleError); - } - - deleteNodes(names: string[], relativePath: string = '', permanent: boolean = true): Promise { - return names.reduce((previous, current) => ( - previous.then(() => this.deleteNodeByPath(`${relativePath}/${current}`, permanent)) - ), Promise.resolve()); - } - - deleteNodesById(ids: string[], permanent: boolean = true): Promise { - return ids.reduce((previous, current) => ( - previous.then(() => this.deleteNodeById(current, permanent)) - ), Promise.resolve()); - } - - // children - getNodeChildren(nodeId: string): Promise { - return this - .get(`/nodes/${nodeId}/children`) - .catch(this.handleError); - } - - createChildren(data: NodeBodyCreate[]): Promise { - return this - .post(`/nodes/-my-/children`, { data }) - .catch(this.handleError); - } - - createContent(content: NodeContentTree, relativePath: string = '/'): Promise { - return this.createChildren(flattenNodeContentTree(content, relativePath)); - } - - createNodeWithProperties(name: string, title?: string, description?: string, relativePath: string = '/'): Promise { - return this.createContent({ name, title, description }, relativePath); - } - - createFolders(names: string[], relativePath: string = '/'): Promise { - return this.createContent({ folders: names }, relativePath); - } - - createFiles(names: string[], relativePath: string = '/'): Promise { - return this.createContent({ files: names }, relativePath); - } -} diff --git a/e2e/utilities/repo-client/apis/people/people-api-models.ts b/e2e/utilities/repo-client/apis/people/people-api-models.ts deleted file mode 100644 index d00dc7dd4..000000000 --- a/e2e/utilities/repo-client/apis/people/people-api-models.ts +++ /dev/null @@ -1,43 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -export class Person { - id?: string; - password?: string; - firstName?: string; - lastName?: string; - email?: string; - properties?: any; - - constructor(username: string, password: string, details: Person) { - this.id = username; - this.password = password || username; - this.firstName = username; - this.lastName = username; - this.email = `${username}@alfresco.com`; - - Object.assign(this, details); - } -} diff --git a/e2e/utilities/repo-client/apis/people/people-api.ts b/e2e/utilities/repo-client/apis/people/people-api.ts deleted file mode 100644 index b13811080..000000000 --- a/e2e/utilities/repo-client/apis/people/people-api.ts +++ /dev/null @@ -1,60 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { RepoApi } from '../repo-api'; -import { Person } from './people-api-models'; - -export class PeopleApi extends RepoApi { - getUser(username: string) { - return this - .get(`/people/${username}`) - .catch(this.handleError); - } - - updateUser(username: string, details?: Person): Promise { - if (details.id) { - delete details.id; - } - - return this - .put(`/people/${username}`, { data: details }) - .catch(this.handleError); - } - - createUser(username: string, password?: string, details?: Person): Promise { - const person: Person = new Person(username, password, details); - const onSuccess = (response) => response; - const onError = (response) => { - return (response.statusCode === 409) - ? Promise.resolve(this.updateUser(username, person)) - : Promise.reject(response); - }; - - return this - .post(`/people`, { data: person }) - .then(onSuccess, onError) - .catch(this.handleError); - } -} diff --git a/e2e/utilities/repo-client/apis/repo-api.ts b/e2e/utilities/repo-client/apis/repo-api.ts deleted file mode 100644 index 0a7993f9c..000000000 --- a/e2e/utilities/repo-client/apis/repo-api.ts +++ /dev/null @@ -1,71 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { RestClient, RestClientArgs, RestClientResponse } from '../../rest-client/rest-client'; -import { RepoClientAuth, RepoClientConfig } from '../repo-client-models'; - -export abstract class RepoApi { - private client: RestClient; - private defaults: RepoClientConfig = new RepoClientConfig(); - - constructor( - auth: RepoClientAuth = new RepoClientAuth(), - private config?: RepoClientConfig - ) { - const { username, password } = auth; - - this.client = new RestClient(username, password); - } - - private createEndpointUri(endpoint: string): string { - const { defaults, config } = this; - const { host, tenant } = Object.assign(defaults, config); - - return `${host}/alfresco/api/${tenant}/public/alfresco/versions/1${endpoint}`; - } - - protected handleError(response: RestClientResponse) { - const { request: { method, path, data }, data: error } = response; - - console.log(`ERROR on ${method}\n${path}\n${data}`); - console.log(error); - } - - protected get(endpoint: string, args: RestClientArgs = {}) { - return this.client.get(this.createEndpointUri(endpoint), args); - } - - protected post(endpoint: string, args: RestClientArgs = {}) { - return this.client.post(this.createEndpointUri(endpoint), args); - } - - protected put(endpoint: string, args: RestClientArgs = {}) { - return this.client.put(this.createEndpointUri(endpoint), args); - } - - protected delete(endpoint: string, args: RestClientArgs = {}) { - return this.client.delete(this.createEndpointUri(endpoint), args); - } -} diff --git a/e2e/utilities/repo-client/apis/shared-links/shared-links-api.ts b/e2e/utilities/repo-client/apis/shared-links/shared-links-api.ts deleted file mode 100644 index 537aef7a5..000000000 --- a/e2e/utilities/repo-client/apis/shared-links/shared-links-api.ts +++ /dev/null @@ -1,50 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { RepoApi } from '../repo-api'; -import { NodesApi } from '../nodes/nodes-api'; -import { RepoClient } from './../../repo-client'; - -export class SharedLinksApi extends RepoApi { - - shareFileById(id: string): Promise { - const data = [{ nodeId: id }]; - - return this.post(`/shared-links`, { data }) - .catch(this.handleError); - } - - shareFilesByIds(ids: string[]): Promise { - return ids.reduce((previous, current) => ( - previous.then(() => this.shareFileById(current)) - ), Promise.resolve()); - } - - getSharedLinks(): Promise { - return this.get(`/shared-links`) - .catch(this.handleError); - } - -} diff --git a/e2e/utilities/repo-client/apis/sites/sites-api-models.ts b/e2e/utilities/repo-client/apis/sites/sites-api-models.ts deleted file mode 100644 index f6729c1d7..000000000 --- a/e2e/utilities/repo-client/apis/sites/sites-api-models.ts +++ /dev/null @@ -1,42 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { SITE_VISIBILITY } from '../../../../configs'; - -export class Site { - title?: string; - visibility?: string = SITE_VISIBILITY.PUBLIC; - id?: string; - description?: string; - - constructor(title: string, visibility: string, details: Site) { - this.title = title; - this.visibility = visibility; - this.id = title; - this.description = `${title} description`; - - Object.assign(this, details); - } -} diff --git a/e2e/utilities/repo-client/apis/sites/sites-api.ts b/e2e/utilities/repo-client/apis/sites/sites-api.ts deleted file mode 100644 index acf25c04b..000000000 --- a/e2e/utilities/repo-client/apis/sites/sites-api.ts +++ /dev/null @@ -1,111 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { RepoApi } from '../repo-api'; -import { Site } from './sites-api-models'; - -export class SitesApi extends RepoApi { - getSite(id: string) { - return this - .get(`/sites/${id}`) - .catch(this.handleError); - } - - updateSite(id: string, details?: Site): Promise { - if (details.id) { - delete details.id; - } - - return this - .put(`/sites/${id}`, { data: details }) - .catch(this.handleError); - } - - createOrUpdateSite(title: string, visibility: string, details?: Site): Promise { - const site: Site = new Site(title, visibility, details); - const onSuccess = (response) => response; - const onError = (response) => { - return (response.statusCode === 409) - ? Promise.resolve(this.updateSite(site.id, site)) - : Promise.reject(response); - }; - - return this - .post(`/sites`, { data: site }) - .then(onSuccess, onError) - .catch(this.handleError); - } - - createSite(title: string, visibility: string, details?: Site): Promise { - const site: Site = new Site(title, visibility, details); - return this - .post(`/sites`, { data: site }) - .catch(this.handleError); - } - - createSites(titles: string[], visibility: string): Promise { - return titles.reduce((previous, current) => ( - previous.then(() => this.createSite(current, visibility)) - ), Promise.resolve()); - } - - deleteSite(id: string, permanent: boolean = true): Promise { - return this - .delete(`/sites/${id}?permanent=${permanent}`) - .catch(this.handleError); - } - - deleteSites(ids: string[], permanent: boolean = true): Promise { - return ids.reduce((previous, current) => ( - previous.then(() => this.deleteSite(current)) - ), Promise.resolve()); - } - - updateSiteMember(siteId: string, userId: string, role: string): Promise { - return this - .put(`/sites/${siteId}/members/${userId}`, { data: { role } }) - .catch(this.handleError); - } - - addSiteMember(siteId: string, userId: string, role: string): Promise { - const onSuccess = (response) => response; - const onError = (response) => { - return (response.statusCode === 409) - ? Promise.resolve(this.updateSiteMember(siteId, userId, role)) - : Promise.reject(response); - }; - - return this - .post(`/sites/${siteId}/members`, { data: { role, id: userId } }) - .then(onSuccess, onError) - .catch(this.handleError); - } - - deleteSiteMember(siteId: string, userId: string): Promise { - return this - .delete(`/sites/${siteId}/members/${userId}`) - .catch(this.handleError); - } -} diff --git a/e2e/utilities/repo-client/apis/trashcan/trashcan-api.ts b/e2e/utilities/repo-client/apis/trashcan/trashcan-api.ts deleted file mode 100644 index 935fc19b5..000000000 --- a/e2e/utilities/repo-client/apis/trashcan/trashcan-api.ts +++ /dev/null @@ -1,54 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { RepoApi } from '../repo-api'; - -export class TrashcanApi extends RepoApi { - permanentlyDelete(id: string): Promise { - return this - .delete(`/deleted-nodes/${id}`) - .catch(this.handleError); - } - - getDeletedNodes(): Promise { - return this - .get(`/deleted-nodes?maxItems=1000`) - .catch(this.handleError); - } - - emptyTrash(): Promise { - return this.getDeletedNodes() - .then(resp => { - return resp.data.list.entries.map(entries => entries.entry.id); - }) - .then(ids => { - return ids.reduce((previous, current) => ( - previous.then(() => this.permanentlyDelete(current)) - ), Promise.resolve()); - }) - .catch(this.handleError); - } - -} diff --git a/e2e/utilities/repo-client/repo-client-models.ts b/e2e/utilities/repo-client/repo-client-models.ts deleted file mode 100644 index 46222947b..000000000 --- a/e2e/utilities/repo-client/repo-client-models.ts +++ /dev/null @@ -1,46 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { - ADMIN_USERNAME, - ADMIN_PASSWORD, - REPO_API_HOST, - REPO_API_TENANT -} from '../../configs'; - -export class RepoClientAuth { - static DEFAULT_USERNAME: string = ADMIN_USERNAME; - static DEFAULT_PASSWORD: string = ADMIN_PASSWORD; - - constructor( - public username: string = RepoClientAuth.DEFAULT_USERNAME, - public password: string = RepoClientAuth.DEFAULT_PASSWORD - ) {} -} - -export class RepoClientConfig { - host?: string = REPO_API_HOST; - tenant?: string = REPO_API_TENANT; -} diff --git a/e2e/utilities/repo-client/repo-client.ts b/e2e/utilities/repo-client/repo-client.ts deleted file mode 100644 index 8ffe00b95..000000000 --- a/e2e/utilities/repo-client/repo-client.ts +++ /dev/null @@ -1,57 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { RepoClientAuth, RepoClientConfig } from './repo-client-models'; - -import { PeopleApi } from './apis/people/people-api'; -import { NodesApi } from './apis/nodes/nodes-api'; -import { SitesApi } from './apis/sites/sites-api'; -import { FavoritesApi } from './apis/favorites/favorites-api'; -import { SharedLinksApi } from './apis/shared-links/shared-links-api'; -import { TrashcanApi } from './apis/trashcan/trashcan-api'; - -export class RepoClient { - public people: PeopleApi = new PeopleApi(this.auth, this.config); - public nodes: NodesApi = new NodesApi(this.auth, this.config); - public sites: SitesApi = new SitesApi(this.auth, this.config); - public favorites: FavoritesApi = new FavoritesApi(this.auth, this.config); - public shared: SharedLinksApi = new SharedLinksApi(this.auth, this.config); - public trashcan: TrashcanApi = new TrashcanApi(this.auth, this.config); - - constructor( - private username: string = RepoClientAuth.DEFAULT_USERNAME, - private password: string = RepoClientAuth.DEFAULT_PASSWORD, - private config?: RepoClientConfig - ) {} - - private get auth(): RepoClientAuth { - const { username, password } = this; - return { username, password }; - } -} - -export * from './apis/nodes/node-body-create'; -export * from './apis/nodes/node-content-tree'; -export * from './apis/nodes/nodes-api'; diff --git a/e2e/utilities/reporters/console/console-logger.ts b/e2e/utilities/reporters/console/console-logger.ts deleted file mode 100644 index 8b82d83da..000000000 --- a/e2e/utilities/reporters/console/console-logger.ts +++ /dev/null @@ -1,79 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -/* tslint:disable */ -const chalk = require('chalk'); -/* tslint:enable */ - -export const log = { - i: 0, - - get indentation(): string { - return new Array(this.i).fill(' ').join(''); - }, - - indent() { - this.i++; - return this; - }, - - dedent() { - this.i--; - return this; - }, - - log(message: string = '', options: any = { ignoreIndentation: false }) { - const indentation = (!options.ignoreIndentation) - ? this.indentation - : ''; - - console.log(`${indentation}${message}`); - - return this; - }, - - blank() { - return this.log(); - }, - - info(message: string = '', options: any = { bold: false, title: false }) { - const { bold } = options; - const style = (bold ? chalk.bold : chalk).gray; - - return this.log(style(message), options); - }, - - success(message: string = '', options: any = { bold: false }) { - const style = options.bold ? chalk.bold.green : chalk.green; - - return this.log(style(message), options); - }, - - error(message: string = '', options: any = { bold: false }) { - const style = options.bold ? chalk.bold.red : chalk.red; - - return this.log(style(message), options); - } -}; diff --git a/e2e/utilities/reporters/console/console.ts b/e2e/utilities/reporters/console/console.ts deleted file mode 100644 index 7985e52c5..000000000 --- a/e2e/utilities/reporters/console/console.ts +++ /dev/null @@ -1,90 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { log } from './console-logger'; - -const errors = []; - -export const consoleReporter = { - jasmineStarted(suiteInfo) { - log.blank().info( - `Running ${suiteInfo.totalSpecsDefined} tests`, - { bold: true, title: true } - ).blank(); - }, - - suiteStarted(suite) { - log.info(suite.description).indent(); - }, - - specDone: (spec) => { - const { - status, - description, - failedExpectations - } = spec; - - if (status === 'passed') { - log.success(`∙ ${description}`); - } - - if (status === 'failed') { - log.error(`✕ ${description}`, { bold: true }); - - errors.push(spec); - - failedExpectations.forEach((failed) => { - log.error(` ${failed.message}`); - }); - } - }, - - suiteDone: (result) => { - log.dedent(); - }, - - jasmineDone: (result) => { - if (!!errors.length) { - log .blank() - .blank() - .info(`${errors.length} failing tests`, { bold: true, title: true }); - - errors.forEach(error => { - log .blank() - .error(`✕ ${error.fullName}`, { bold: true }); - - error.failedExpectations.forEach(failed => { - log .info(`${failed.message}`) - .blank() - .error(`${failed.stack}`); - }); - }); - } else { - log.success(`All tests passed!`, { bold: true }); - } - - log.blank().blank(); - } -}; diff --git a/e2e/utilities/rest-client/rest-client-models.ts b/e2e/utilities/rest-client/rest-client-models.ts deleted file mode 100644 index 89e3c9916..000000000 --- a/e2e/utilities/rest-client/rest-client-models.ts +++ /dev/null @@ -1,63 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -interface RequestConfig { - timeout?: number; - noDelay?: boolean; - keepAlive?: boolean; - keepAliveDelay?: number; -} - -interface ResponseConfig { - timeout?: number; -} - -interface ResponseRequest { - method: string; - path: string; - data: string; -} - -export interface NodeRestClient { - get(uri: string, callback: Function): Function; - post(uri: string, callback: Function): Function; - put(uri: string, callback: Function): Function; - delete(uri: string, callback: Function): Function; -} - -export interface RestClientArgs { - data?: any; - parameters?: any; - headers?: any; - requestConfig?: RequestConfig; - responseConfig?: ResponseConfig; -} - -export interface RestClientResponse { - request: ResponseRequest; - data: any; - statusMessage: string; - statusCode: number; -} diff --git a/e2e/utilities/rest-client/rest-client.ts b/e2e/utilities/rest-client/rest-client.ts deleted file mode 100644 index 45b4c1ca8..000000000 --- a/e2e/utilities/rest-client/rest-client.ts +++ /dev/null @@ -1,89 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { Client } from 'node-rest-client'; -import { NodeRestClient, RestClientArgs, RestClientResponse } from './rest-client-models'; - -export * from './rest-client-models'; - -export class RestClient { - private static DEFAULT_HEADERS = { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }; - - private client: NodeRestClient; - - constructor(user: string, password: string) { - this.client = (new Client({ user, password })); - } - - get(uri: string, args: RestClientArgs = {}): Promise { - return this.promisify('get', uri, args); - } - - post(uri: string, args: RestClientArgs = {}): Promise { - return this.promisify('post', uri, args); - } - - put(uri: string, args: RestClientArgs = {}): Promise { - return this.promisify('put', uri, args); - } - - delete(uri: string, args: RestClientArgs = {}): Promise { - return this.promisify('delete', uri, args); - } - - private createArgs(args: RestClientArgs = {}): RestClientArgs { - const data = JSON.stringify(args.data); - - return Object.assign({}, RestClient.DEFAULT_HEADERS, args, { data }); - } - - private promisify(fnName: string, uri: string, args: RestClientArgs): Promise { - const fn: Function = this.client[fnName]; - const fnArgs = [ encodeURI(uri), this.createArgs(args) ]; - - return new Promise((resolve, reject) => { - const fnCallback = (data, rawResponse) => { - const { - statusCode, statusMessage, - req: { method, path } - } = rawResponse; - - const response: RestClientResponse = { - data, statusCode, statusMessage, - request: { method, path, data: args.data } - }; - - (response.statusCode >= 400) - ? reject(response) - : resolve(response); - }; - - fn(...fnArgs, fnCallback); - }); - } -} diff --git a/e2e/utilities/utils.ts b/e2e/utilities/utils.ts deleted file mode 100644 index 368b7aa43..000000000 --- a/e2e/utilities/utils.ts +++ /dev/null @@ -1,44 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2017 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { browser, promise } from 'protractor'; - -export class Utils { - // generate a random value - static random(): string { - return Math.random().toString(36).substring(3, 10); - } - - // local storage - static clearLocalStorage(): promise.Promise { - return browser.executeScript('window.localStorage.clear();'); - } - - // session storage - static clearSessionStorage(): promise.Promise { - return browser.executeScript('window.sessionStorage.clear();'); - } - -} diff --git a/package.json b/package.json index 223ae2c09..3e582ae2a 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ "karma-coverage-istanbul-reporter": "^1.2.1", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", - "node-rest-client": "^3.1.0", "protractor": "^5.1.2", "rimraf": "2.6.2", "ts-node": "~3.2.0", diff --git a/protractor.conf.js b/protractor.conf.js index ba46ec01b..bc0ae870c 100644 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -14,12 +14,6 @@ exports.config = { allScriptsTimeout: 30000, specs: [ - './e2e/suites/authentication/*.test.ts', - './e2e/suites/list-views/*.test.ts', - './e2e/suites/application/page-titles.test.ts', - './e2e/suites/navigation/side-navigation.test.ts', - './e2e/suites/pagination/*.test.ts', - './e2e/suites/actions/*.test.ts' ], capabilities: { diff --git a/yarn.lock b/yarn.lock index 58008d198..afc2765ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -68,26 +68,27 @@ zone.js "0.8.14" "@angular-devkit/build-optimizer@~0.0.31": - version "0.0.33" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.0.33.tgz#d040f283ed7300b5be8bc970228b835ed02df42f" + version "0.0.36" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.0.36.tgz#e816ee9be22dbb777724f0281acfa72cfff184b7" dependencies: loader-utils "^1.1.0" source-map "^0.5.6" - typescript "^2.3.3" + typescript "~2.6.1" webpack-sources "^1.0.1" -"@angular-devkit/core@0.0.21": - version "0.0.21" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-0.0.21.tgz#e2ba4ac0a4e1156f884c083b15eb1c26ddfb2ba8" +"@angular-devkit/core@0.0.22": + version "0.0.22" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-0.0.22.tgz#e90f46bf7ff47d260a767959267bc65ffee39ef1" dependencies: source-map "^0.5.6" "@angular-devkit/schematics@~0.0.34": - version "0.0.37" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-0.0.37.tgz#d86ff93b14a44b766e72bcea1569b5d36063210e" + version "0.0.42" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-0.0.42.tgz#34eea7136455545c8abd21edf94a36870a073fea" dependencies: - "@angular-devkit/core" "0.0.21" + "@angular-devkit/core" "0.0.22" "@ngtools/json-schema" "^1.1.0" + "@schematics/schematics" "0.0.11" minimist "^1.2.0" rxjs "^5.5.2" @@ -216,8 +217,8 @@ resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-4.4.5.tgz#ccef139b8d3e1684b01afa35c6fbf2172e2bb676" "@angular/material-moment-adapter@^5.0.0-rc0": - version "5.0.0-rc0" - resolved "https://registry.yarnpkg.com/@angular/material-moment-adapter/-/material-moment-adapter-5.0.0-rc0.tgz#d0357aae1fef9e9181ee80ee444c2dfe9ce1df08" + version "5.0.1" + resolved "https://registry.yarnpkg.com/@angular/material-moment-adapter/-/material-moment-adapter-5.0.1.tgz#058371d4d60bb91555bc89e9044c9e6412bbda71" dependencies: tslib "^1.7.1" @@ -266,10 +267,14 @@ resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-8.0.0.tgz#751fd6b512d80f3a748d2de8dfc96dfefa29afe0" "@schematics/angular@~0.1.0": - version "0.1.7" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-0.1.7.tgz#2306aeec118ca185e180882eff54f5116de4ef05" + version "0.1.11" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-0.1.11.tgz#b5f15320bbb60969d66c76a8ef6545058ac81ece" dependencies: - "@angular-devkit/core" "0.0.21" + "@angular-devkit/core" "0.0.22" + +"@schematics/schematics@0.0.11": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@schematics/schematics/-/schematics-0.0.11.tgz#c8f70f270ed38f29b2873248126fd59abd635862" "@types/jasmine@*", "@types/jasmine@^2.5.53": version "2.8.2" @@ -282,8 +287,8 @@ "@types/jasmine" "*" "@types/node@^6.0.46", "@types/node@~6.0.60": - version "6.0.92" - resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.92.tgz#e7f721ae282772e12ba2579968c00d9cce422c5d" + version "6.0.94" + resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.94.tgz#70e509b07ed9f961c8f6f4a73a61d922be5029a7" "@types/q@^0.0.32": version "0.0.32" @@ -356,8 +361,8 @@ ajv@^4.9.1: json-stable-stringify "^1.0.1" ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5: - version "5.5.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.0.tgz#eb2840746e9dc48bd5e063a36e3fd400c5eab5a9" + version "5.5.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.1.tgz#b38bb8876d9e86bee994956a04e721e88b248eb2" dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" @@ -494,7 +499,7 @@ arraybuffer.slice@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca" -arrify@^1.0.0: +arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -706,13 +711,13 @@ block-stream@*: dependencies: inherits "~2.0.0" -blocking-proxy@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/blocking-proxy/-/blocking-proxy-0.0.5.tgz#462905e0dcfbea970f41aa37223dda9c07b1912b" +blocking-proxy@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/blocking-proxy/-/blocking-proxy-1.0.1.tgz#81d6fd1fe13a4c0d6957df7f91b75e98dac40cb2" dependencies: minimist "^1.2.0" -bluebird@^3.3.0, bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.1: +bluebird@^3.3.0, bluebird@^3.4.7, bluebird@^3.5.0: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -880,7 +885,7 @@ bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" -cacache@^10.0.0: +cacache@^10.0.0, cacache@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.1.tgz#3e05f6e616117d9b54665b1b20c8aeb93ea5d36f" dependencies: @@ -942,8 +947,8 @@ caniuse-api@^1.5.2: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000775" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000775.tgz#04bccdd0214edf25b97f61a096609f7ad6904333" + version "1.0.30000783" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000783.tgz#16b30d47266a4f515cc69ae0316b670c9603cdbe" caseless@~0.11.0: version "0.11.0" @@ -1292,23 +1297,27 @@ copy-concurrently@^1.0.0: run-queue "^1.0.0" copy-webpack-plugin@^4.1.1: - version "4.2.3" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.2.3.tgz#4a3c61089f3b635777f0f0af346c338b39d63755" + version "4.3.0" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.3.0.tgz#cfdf4d131c78d66917a1bb863f86630497aacf42" dependencies: - bluebird "^3.5.1" - glob "^7.1.2" + cacache "^10.0.1" + find-cache-dir "^1.0.0" + globby "^7.1.1" is-glob "^4.0.0" loader-utils "^0.2.15" lodash "^4.3.0" minimatch "^3.0.4" + p-limit "^1.0.0" + pify "^3.0.0" + serialize-javascript "^1.4.0" core-js@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" core-js@^2.2.0, core-js@^2.4.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" + version "2.5.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" core-js@~2.3.0: version "2.3.0" @@ -1560,7 +1569,7 @@ debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.6.6, debug@^2.6.8: dependencies: ms "2.0.0" -debug@2.2.0, debug@~2.2.0: +debug@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" dependencies: @@ -1681,6 +1690,13 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" +dir-glob@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + directory-encoder@^0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/directory-encoder/-/directory-encoder-0.7.2.tgz#59b4e2aa4f25422f6c63b527b462f5e2d0dd2c58" @@ -1783,8 +1799,8 @@ ejs@^2.5.7: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" electron-to-chromium@^1.2.7: - version "1.3.27" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz#78ecb8a399066187bb374eede35d9c70565a803d" + version "1.3.28" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.28.tgz#8dd4e6458086644e9f9f0a1cf32e2a1f9dffd9ee" elliptic@^6.0.0: version "6.4.0" @@ -1873,10 +1889,10 @@ entities@~1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" errno@^0.1.1, errno@^0.1.3, errno@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" + version "0.1.6" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.6.tgz#c386ce8a6283f14fc09563b71560908c9bf53026" dependencies: - prr "~0.0.0" + prr "~1.0.1" error-ex@^1.2.0: version "1.3.1" @@ -2145,10 +2161,14 @@ extract-text-webpack-plugin@3.0.0: schema-utils "^0.3.0" webpack-sources "^1.0.1" -extsprintf@1.3.0, extsprintf@^1.2.0: +extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + fast-deep-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" @@ -2257,12 +2277,6 @@ flush-write-stream@^1.0.0: inherits "^2.0.1" readable-stream "^2.0.4" -follow-redirects@>=1.2.0: - version "1.2.6" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.6.tgz#4dcdc7e4ab3dd6765a97ff89c3b4c258117c79bf" - dependencies: - debug "^3.1.0" - for-in@^0.1.3: version "0.1.8" resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" @@ -2352,8 +2366,8 @@ fs-extra@^0.26.5: rimraf "^2.2.8" fs-extra@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.2.tgz#f91704c53d1b461f893452b0c307d9997647ab6b" + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" dependencies: graceful-fs "^4.1.2" jsonfile "^4.0.0" @@ -2517,6 +2531,17 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + globule@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09" @@ -2821,6 +2846,10 @@ iferr@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" +ignore@^3.3.5: + version "3.3.7" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" + image-size@~0.5.0: version "0.5.5" resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" @@ -3039,8 +3068,8 @@ is-path-in-cwd@^1.0.0: is-path-inside "^1.0.0" is-path-inside@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" dependencies: path-is-inside "^1.0.1" @@ -3238,8 +3267,8 @@ jasminewd2@^2.1.0: resolved "https://registry.yarnpkg.com/jasminewd2/-/jasminewd2-2.2.0.tgz#e37cf0b17f199cce23bea71b2039395246b4ec4e" js-base64@^2.1.5, js-base64@^2.1.8, js-base64@^2.1.9: - version "2.3.2" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.3.2.tgz#a79a923666372b580f8e27f51845c6f7e8fbfbaf" + version "2.4.0" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa" js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" @@ -3367,8 +3396,8 @@ karma-jasmine-html-reporter@^0.2.2: karma-jasmine "^1.0.2" karma-jasmine@^1.0.2, karma-jasmine@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-1.1.0.tgz#22e4c06bf9a182e5294d1f705e3733811b810acf" + version "1.1.1" + resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-1.1.1.tgz#6fe840e75a11600c9d91e84b33c458e1c46a3529" karma-source-map-support@^1.2.0: version "1.2.0" @@ -3718,8 +3747,8 @@ miller-rabin@^4.0.0: brorand "^1.0.1" "mime-db@>= 1.30.0 < 2": - version "1.31.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.31.0.tgz#a49cd8f3ebf3ed1a482b60561d9105ad40ca74cb" + version "1.32.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.32.0.tgz#485b3848b01a3cda5f968b4882c0771e58e09414" mime-db@~1.30.0: version "1.30.0" @@ -3804,8 +3833,8 @@ moment-es6@1.0.0: moment "*" moment@*, moment@^2.10.6: - version "2.19.3" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.3.tgz#bdb99d270d6d7fda78cc0fbace855e27fe7da69f" + version "2.19.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.4.tgz#17e5e2c6ead8819c8ecfad83a0acccb312e94682" moment@2.15.2: version "2.15.2" @@ -3949,14 +3978,6 @@ node-pre-gyp@^0.6.39: tar "^2.2.1" tar-pack "^3.4.0" -node-rest-client@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/node-rest-client/-/node-rest-client-3.1.0.tgz#e0beb6dda7b20cc0b67a7847cf12c5fc419c37c3" - dependencies: - debug "~2.2.0" - follow-redirects ">=1.2.0" - xml2js ">=0.2.4" - node-sass@^4.3.0: version "4.7.2" resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.7.2.tgz#9366778ba1469eb01438a9e8592f4262bcb6794e" @@ -4168,7 +4189,7 @@ p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" -p-limit@^1.1.0: +p-limit@^1.0.0, p-limit@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" @@ -4299,6 +4320,12 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + pbkdf2@^3.0.3: version "3.0.14" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade" @@ -4686,13 +4713,13 @@ promise@^7.1.1: asap "~2.0.3" protractor@^5.1.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.2.0.tgz#d3f39b195e85f3539ad9d8cb6560a9d2b63297c4" + version "5.2.2" + resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.2.2.tgz#80eff170761455eff6e2f111088a03c438844a41" dependencies: "@types/node" "^6.0.46" "@types/q" "^0.0.32" "@types/selenium-webdriver" "~2.53.39" - blocking-proxy "0.0.5" + blocking-proxy "^1.0.0" chalk "^1.1.3" glob "^7.0.3" jasmine "^2.5.3" @@ -4712,9 +4739,9 @@ proxy-addr@~2.0.2: forwarded "~0.1.2" ipaddr.js "1.5.2" -prr@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" pseudomap@^1.0.2: version "1.0.2" @@ -4953,8 +4980,8 @@ regenerate@^1.2.1: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" regenerator-runtime@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" regex-cache@^0.4.2: version "0.4.4" @@ -5152,12 +5179,18 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rxjs@5.5.2, rxjs@^5.5.2: +rxjs@5.5.2: version "5.5.2" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.2.tgz#28d403f0071121967f18ad665563255d54236ac3" dependencies: symbol-observable "^1.0.1" +rxjs@^5.5.2: + version "5.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.5.tgz#e164f11d38eaf29f56f08c3447f74ff02dd84e97" + dependencies: + symbol-observable "1.0.1" + safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -5281,6 +5314,10 @@ send@0.16.1: range-parser "~1.2.0" statuses "~1.3.1" +serialize-javascript@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005" + serve-index@^1.7.2: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" @@ -5358,6 +5395,10 @@ silent-error@^1.0.0: dependencies: debug "^2.2.0" +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + sntp@1.x.x: version "1.0.9" resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" @@ -5724,6 +5765,10 @@ svgo@^0.7.0: sax "~1.2.1" whet.extend "~0.9.9" +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + symbol-observable@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32" @@ -5878,8 +5923,8 @@ tsickle@^0.24.0: source-map-support "^0.4.2" tslib@^1.7.1: - version "1.8.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.0.tgz#dc604ebad64bcbf696d613da6c954aa0e7ea1eb6" + version "1.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.1.tgz#6946af2d1d651a7b1863b531d6e5afa41aa44eac" tslint@~5.7.0: version "5.7.0" @@ -5931,24 +5976,24 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -typescript@^2.3.3: - version "2.6.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4" - typescript@~2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.4.2.tgz#f8395f85d459276067c988aa41837a8f82870844" +typescript@~2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4" + uglify-es@^3.1.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.2.0.tgz#fbbfb9dc465ec7e5065701b9720d0de977d0bc24" + version "3.2.2" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.2.2.tgz#15c62b7775002c81b7987a1c49ecd3f126cace73" dependencies: commander "~2.12.1" source-map "~0.6.1" uglify-js@3.2.x: - version "3.2.0" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.2.0.tgz#cb411ee4ca0e0cadbfe3a4e1a1da97e6fa0d19c1" + version "3.2.2" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.2.2.tgz#870e4b34ed733d179284f9998efd3293f7fd73f6" dependencies: commander "~2.12.1" source-map "~0.6.1" @@ -6215,8 +6260,8 @@ webpack-dev-middleware@^1.11.0, webpack-dev-middleware@~1.12.0: time-stamp "^2.0.0" webpack-dev-server@~2.9.3: - version "2.9.5" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.5.tgz#79336fba0087a66ae491f4869f6545775b18daa8" + version "2.9.7" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.7.tgz#100ad6a14775478924d417ca6dcfb9d52a98faed" dependencies: ansi-html "0.0.7" array-includes "^3.0.3" @@ -6260,8 +6305,8 @@ webpack-sources@^1.0.0, webpack-sources@^1.0.1: source-map "~0.6.1" webpack-subresource-integrity@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-1.0.1.tgz#1fc09d46497da66e46743a2a51d2cc385b9cb0ed" + version "1.0.3" + resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-1.0.3.tgz#c0606d40090b070cde428bec8df3603216e472eb" dependencies: webpack-core "^0.6.8" @@ -6394,7 +6439,7 @@ xml2js@0.4.4: sax "0.6.x" xmlbuilder ">=1.0.0" -xml2js@>=0.2.4, xml2js@^0.4.17: +xml2js@^0.4.17: version "0.4.19" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" dependencies: From 0a824dd75dcff850a9aa6310c6191d04b0da9aae Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 14 Dec 2017 17:03:46 +0000 Subject: [PATCH 05/69] fix "view" button (toolbar) --- src/app/components/favorites/favorites.component.html | 2 +- src/app/components/files/files.component.html | 2 +- src/app/components/files/files.component.ts | 8 ++++++++ .../components/recent-files/recent-files.component.html | 2 +- .../components/shared-files/shared-files.component.html | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/app/components/favorites/favorites.component.html b/src/app/components/favorites/favorites.component.html index 323786641..7c1f3b135 100644 --- a/src/app/components/favorites/favorites.component.html +++ b/src/app/components/favorites/favorites.component.html @@ -9,7 +9,7 @@ mat-icon-button *ngIf="canPreviewFile(documentList.selection)" title="{{ 'APP.ACTIONS.VIEW' | translate }}" - (click)="showPreview(documentList.selection[0]?.entry?.id)"> + (click)="onNodeDoubleClick(documentList.selection[0]?.entry)"> open_in_browser diff --git a/src/app/components/files/files.component.html b/src/app/components/files/files.component.html index 6461f7859..f28e822a2 100644 --- a/src/app/components/files/files.component.html +++ b/src/app/components/files/files.component.html @@ -11,7 +11,7 @@ mat-icon-button *ngIf="canPreviewFile(documentList.selection)" title="{{ 'APP.ACTIONS.VIEW' | translate }}" - (click)="showPreview(documentList.selection[0]?.entry?.id)"> + (click)="showPreview(documentList.selection[0]?.entry)"> open_in_browser diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index bf656c69b..8d3d7e729 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -155,6 +155,14 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { } } + showPreview(node: MinimalNodeEntryEntity) { + if (node) { + if (node.isFile) { + this.router.navigate(['/preview', node.id]); + } + } + } + onBreadcrumbNavigate(route: PathElementEntity) { // todo: review this approach once 5.2.3 is out if (this.nodePath && this.nodePath.length > 2) { diff --git a/src/app/components/recent-files/recent-files.component.html b/src/app/components/recent-files/recent-files.component.html index daaf8a436..185a49732 100644 --- a/src/app/components/recent-files/recent-files.component.html +++ b/src/app/components/recent-files/recent-files.component.html @@ -9,7 +9,7 @@ mat-icon-button *ngIf="canPreviewFile(documentList.selection)" title="{{ 'APP.ACTIONS.VIEW' | translate }}" - (click)="showPreview(documentList.selection[0]?.entry?.id)"> + (click)="onNodeDoubleClick(documentList.selection[0]?.entry)"> open_in_browser diff --git a/src/app/components/shared-files/shared-files.component.html b/src/app/components/shared-files/shared-files.component.html index e7eb1481d..2cfc02f49 100644 --- a/src/app/components/shared-files/shared-files.component.html +++ b/src/app/components/shared-files/shared-files.component.html @@ -9,7 +9,7 @@ mat-icon-button *ngIf="canPreviewFile(documentList.selection)" title="{{ 'APP.ACTIONS.VIEW' | translate }}" - (click)="showPreview(documentList.selection[0]?.entry?.nodeId)"> + (click)="onNodeDoubleClick(documentList.selection[0]?.entry)"> open_in_browser From 6dd711b06fda735c8f59dc17d8becd692395557a Mon Sep 17 00:00:00 2001 From: john-knowles <18680913+john-knowles@users.noreply.github.com> Date: Thu, 14 Dec 2017 21:10:16 +0000 Subject: [PATCH 06/69] Update doc-list.md (#148) Correct minor typo. --- docs/doc-list.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/doc-list.md b/docs/doc-list.md index 8fe776bc7..e87eaa3fb 100644 --- a/docs/doc-list.md +++ b/docs/doc-list.md @@ -13,7 +13,7 @@ The application has six different Document List views which share commonalities #### Personal Files -Personal Files retrieves all content from the logged in user's home area (`/User Homes//` in the repository); +Personal Files retrieves all content from the logged in user's home area (`/User Homes//`) in the repository; if the user is ‘admin’ who does not have a home folder then the repository root folder is shown. Personal Files is the [Files component](https://github.com/Alfresco/alfresco-content-app/tree/master/src/app/components/files), From 69d63533fd7fef4d0ee7d97ec660a8363339973a Mon Sep 17 00:00:00 2001 From: john-knowles <18680913+john-knowles@users.noreply.github.com> Date: Thu, 14 Dec 2017 21:15:37 +0000 Subject: [PATCH 07/69] Update doc-list.md (#151) Minor typo fix --- docs/doc-list.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/doc-list.md b/docs/doc-list.md index e87eaa3fb..27b8f4d19 100644 --- a/docs/doc-list.md +++ b/docs/doc-list.md @@ -32,8 +32,7 @@ using the [Nodes API](https://api-explorer.alfresco.com/api-explorer/#/nodes) is #### Shared Files The Shared Files view aggregates all files that have been shared using the QuickShare feature in the content repository. -The [Shared Files component](https://github.com/Alfresco/alfresco-content-app/tree/master/src/app/components/shared-files) -uses the [shared-links API](https://api-explorer.alfresco.com/api-explorer/#/shared-links) +The [Shared Files](https://github.com/Alfresco/alfresco-content-app/tree/master/src/app/components/shared-files) component uses the [shared-links API](https://api-explorer.alfresco.com/api-explorer/#/shared-links) and includes extra columns to display where the file is [located](https://github.com/Alfresco/alfresco-content-app/tree/master/src/app/components/location-link) in the content repository and who created the shared link. From 9a8d3422954c81f74c8ba679dd6f5c6262d01b12 Mon Sep 17 00:00:00 2001 From: john-knowles <18680913+john-knowles@users.noreply.github.com> Date: Thu, 14 Dec 2017 21:20:24 +0000 Subject: [PATCH 08/69] Update doc-list.md (#152) Fixing more url typos. --- docs/doc-list.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/doc-list.md b/docs/doc-list.md index 27b8f4d19..3764ec5e8 100644 --- a/docs/doc-list.md +++ b/docs/doc-list.md @@ -16,17 +16,17 @@ The application has six different Document List views which share commonalities Personal Files retrieves all content from the logged in user's home area (`/User Homes//`) in the repository; if the user is ‘admin’ who does not have a home folder then the repository root folder is shown. -Personal Files is the [Files component](https://github.com/Alfresco/alfresco-content-app/tree/master/src/app/components/files), +Personal Files is the [Files](https://github.com/Alfresco/alfresco-content-app/tree/master/src/app/components/files) component, using the [Nodes API](https://api-explorer.alfresco.com/api-explorer/#/nodes). #### File Libraries File Libraries retrieves all the sites that the user is a member of including what type of site it is: public, moderated or private. -File Libraries is the [Libraries component](https://github.com/Alfresco/alfresco-content-app/tree/master/src/app/components/libraries), +File Libraries is the [Libraries](https://github.com/Alfresco/alfresco-content-app/tree/master/src/app/components/libraries) component, using the [Sites API](https://api-explorer.alfresco.com/api-explorer/#/sites). When a user opens one of their sites then the content for the site's document library is shown. -To display the files and folders from a site (`/Sites//Document Library/`) the [Files component](https://github.com/Alfresco/alfresco-content-app/tree/master/src/app/components/files), +To display the files and folders from a site (`/Sites//Document Library/`) the [Files](https://github.com/Alfresco/alfresco-content-app/tree/master/src/app/components/files) component, using the [Nodes API](https://api-explorer.alfresco.com/api-explorer/#/nodes) is used. #### Shared Files From c0f226d9b004ca0cb27b3b931ba76c2c35bff53e Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 15 Dec 2017 14:22:36 +0000 Subject: [PATCH 09/69] add logo to readme --- README.md | 4 ++++ alfresco.png | Bin 0 -> 8205 bytes 2 files changed, 4 insertions(+) create mode 100644 alfresco.png diff --git a/README.md b/README.md index b993cc96e..769f9c32c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # Alfresco Example Content Application +

+ Alfresco +

+ ## Introduction The Alfresco Content Application is an example application built using diff --git a/alfresco.png b/alfresco.png new file mode 100644 index 0000000000000000000000000000000000000000..7f6326b0b376141cc757e4bc128590a6cf48508b GIT binary patch literal 8205 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 literal 0 HcmV?d00001 From dfb676a29b9a8861970304e1cb580a1deee508eb Mon Sep 17 00:00:00 2001 From: Bindu Wavell Date: Fri, 15 Dec 2017 12:40:55 -0700 Subject: [PATCH 10/69] Don't try to port map to 80 as it is < 1024 (#161) In the docker example we were proposing that folks map port 80 from the docker container to port 80 on localhost. Unless the user is running as root, they likely won't be able to bind to any port < 1024. As such, I am proposing we bind to the local port 8888. Could change it to 3000 to be in-line with the `docker compose` example; but to me the use cases are different so I like having different ports... --- docs/docker.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docker.md b/docs/docker.md index ac19fb4fe..fcddc4aca 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -35,10 +35,10 @@ docker image build -t content-app . To run the image locally, you can use the following command: ```sh -docker container run -p 80:80 --rm content-app +docker container run -p 8888:80 --rm content-app ``` -Navigate to "http://localhost" to access the running application. +Navigate to "http://localhost:8888" to access the running application. ## Docker Compose file From 92c147fae3fcc6d953524c392e3567979ba10a11 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 18 Dec 2017 13:33:18 +0000 Subject: [PATCH 11/69] Code coverage reports (#165) * travis settings update * travis update * enable coverage reports --- .travis.yml | 5 ++++- package.json | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9b68812ed..4eb7bfa76 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,4 +20,7 @@ install: script: - xvfb-run -a npm run test -- --single-run --no-progress --browser=ChromeNoSandbox - #- xvfb-run -a npm run e2e -- --no-progress --config=protractor-ci.conf.js + +# Send coverage data to codecov +after_success: + bash <(curl -s https://codecov.io/bash) -X gcov diff --git a/package.json b/package.json index 3e582ae2a..9f4fd5f20 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "build:prod": "npm run server-versions && ng build --prod", "build:dev": "npm run server-versions && ng build && node postbuild-dev.js", "build:tomcat": "npm run server-versions && ng build --base-href ./", - "test": "ng test", + "test": "ng test --code-coverage", "lint": "ng lint", "e2e": "ng e2e", "server-versions": "rimraf ./src/versions.json && npm list --depth=0 --json=true --prod=true > ./src/versions.json || exit 0" From 9428913900b698a58932f260b81ee2d4cd82425b Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Mon, 18 Dec 2017 16:19:31 +0200 Subject: [PATCH 12/69] ensure parameter node id is a folder instance (#166) --- src/app/components/files/files.component.spec.ts | 13 ++++++++++++- src/app/components/files/files.component.ts | 8 +++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts index 266be3433..884ee1a83 100644 --- a/src/app/components/files/files.component.spec.ts +++ b/src/app/components/files/files.component.spec.ts @@ -77,7 +77,7 @@ describe('FilesComponent', () => { })); beforeEach(() => { - node = { id: 'node-id' }; + node = { id: 'node-id', isFolder: true }; page = { list: { entries: ['a', 'b', 'c'], @@ -134,6 +134,17 @@ describe('FilesComponent', () => { expect(component.onFetchError).toHaveBeenCalled(); }); + + it('if should navigate to parent if node is not a folder', () => { + node.isFolder = false; + node.parentId = 'parent-id'; + spyOn(component, 'fetchNode').and.returnValue(Observable.of(node)); + spyOn(router, 'navigate'); + + fixture.detectChanges(); + + expect(router.navigate).toHaveBeenCalledWith([ '/personal-files', 'parent-id' ]); + }); }); describe('refresh on events', () => { diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index 8d3d7e729..96926da40 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -76,7 +76,13 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { this.isLoading = true; this.fetchNode(nodeId) - .do((node) => this.updateCurrentNode(node)) + .do((node) => { + if (node.isFolder) { + this.updateCurrentNode(node); + } else { + this.router.navigate(['/personal-files', node.parentId]); + } + }) .flatMap((node) => this.fetchNodes(node.id)) .subscribe( (page) => { From 5dea44c342edd7a57e34ce30eb2b3d4363a8eb86 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Mon, 18 Dec 2017 17:30:08 +0200 Subject: [PATCH 13/69] fixed name column when checkbox is present (#167) --- src/app/ui/overrides/_alfresco-document-list.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/ui/overrides/_alfresco-document-list.scss b/src/app/ui/overrides/_alfresco-document-list.scss index 6f97fa96f..c0acf6fe9 100644 --- a/src/app/ui/overrides/_alfresco-document-list.scss +++ b/src/app/ui/overrides/_alfresco-document-list.scss @@ -63,7 +63,8 @@ adf-document-list { border: none !important; } - td:first-of-type, th:first-of-type { + th:first-of-type, th.adf-data-table-cell--image, + td:first-of-type, td.adf-data-table-cell--image { padding-left: 24px; padding-right: 0; width: 10px; From cf7b781b6de89519f33c35dda9527fb1cf22b117 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 18 Dec 2017 17:17:48 +0000 Subject: [PATCH 14/69] Docker Hub integration (#168) --- .editorconfig | 3 +++ .travis.yml | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.editorconfig b/.editorconfig index 9b7352176..4a874ce23 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,3 +11,6 @@ trim_trailing_whitespace = true [*.md] max_line_length = off trim_trailing_whitespace = false + +[*.yml] +indent_size = 2 diff --git a/.travis.yml b/.travis.yml index 4eb7bfa76..1570c46bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ dist: trusty -sudo: false +sudo: required language: node_js node_js: @@ -9,9 +9,10 @@ cache: directories: - ./node_modules +services: + - docker before_install: - - export CHROME_BIN=chromium-browser - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" @@ -19,8 +20,17 @@ install: - npm install script: - - xvfb-run -a npm run test -- --single-run --no-progress --browser=ChromeNoSandbox + - npm run build:dev + - npm run test -- --single-run --no-progress --browser=ChromeNoSandbox # Send coverage data to codecov after_success: - bash <(curl -s https://codecov.io/bash) -X gcov + - bash <(curl -s https://codecov.io/bash) -X gcov + - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi) + - echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH" + - export TAG=`if [ "$BRANCH" == "master" ]; then echo "latest"; else echo $BRANCH ; fi` + - docker build -t $DOCKER_REPO:$TAG . + # Publish extra image based on Travis build number + - docker tag $DOCKER_REPO:$TAG $DOCKER_REPO:travis-$TRAVIS_BUILD_NUMBER + - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD" + - docker push $DOCKER_REPO From 60cba5b93b3cd367bee4a2ca3a27b38fa186677e Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 19 Dec 2017 09:51:57 +0000 Subject: [PATCH 15/69] update travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1570c46bf..23b773bb8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ install: - npm install script: - - npm run build:dev + - npm run build - npm run test -- --single-run --no-progress --browser=ChromeNoSandbox # Send coverage data to codecov From 887d8b811c28710112595dc16be915f04d847ed1 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 21 Dec 2017 13:55:40 +0000 Subject: [PATCH 16/69] headless chrome for unit tests (#169) --- .travis.yml | 6 +----- karma.conf.js | 11 ++++++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23b773bb8..f9a1b2411 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,16 +12,12 @@ cache: services: - docker -before_install: - - "export DISPLAY=:99.0" - - "sh -e /etc/init.d/xvfb start" - install: - npm install script: - npm run build - - npm run test -- --single-run --no-progress --browser=ChromeNoSandbox + - npm run test -- --single-run --no-progress # Send coverage data to codecov after_success: diff --git a/karma.conf.js b/karma.conf.js index 410aaa975..abe47fde7 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -38,11 +38,16 @@ module.exports = function (config) { colors: true, logLevel: config.LOG_INFO, autoWatch: true, - browsers: ['Chrome'], + browsers: ['ChromeHeadless'], customLaunchers: { - ChromeNoSandbox: { + ChromeHeadless: { base: 'Chrome', - flags: ['--no-sandbox'] + flags: [ + '--no-sandbox', + '--headless', + '--disable-gpu', + '--remote-debugging-port=9222' + ] } }, singleRun: false, From d768219bdbdf91006bb5972e1412d3185a938407 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Wed, 3 Jan 2018 11:38:31 +0200 Subject: [PATCH 17/69] preview files child route (#170) --- src/app/app.routes.ts | 84 ++++++++++++++----- .../favorites/favorites.component.spec.ts | 2 +- .../favorites/favorites.component.ts | 5 +- .../components/files/files.component.spec.ts | 5 +- src/app/components/files/files.component.ts | 7 +- .../components/preview/preview.component.html | 6 +- .../components/preview/preview.component.ts | 25 +++++- .../recent-files.component.spec.ts | 4 +- .../recent-files/recent-files.component.ts | 5 +- .../search/search.component.spec.ts | 5 +- src/app/components/search/search.component.ts | 2 +- .../shared-files.component.spec.ts | 2 +- .../shared-files/shared-files.component.ts | 5 +- 13 files changed, 115 insertions(+), 42 deletions(-) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 3a28d1cef..8c66ca552 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -41,13 +41,6 @@ import { PreviewComponent } from './components/preview/preview.component'; import { GenericErrorComponent } from './components/generic-error/generic-error.component'; export const APP_ROUTES: Routes = [ - { - path: 'preview/:nodeId', - component: PreviewComponent, - data: { - i18nTitle: 'APP.PREVIEW.TITLE' - } - }, { path: 'login', component: LoginComponent, @@ -66,10 +59,22 @@ export const APP_ROUTES: Routes = [ }, { path: 'favorites', - component: FavoritesComponent, - data: { - i18nTitle: 'APP.BROWSE.FAVORITES.TITLE' - } + children: [ + { + path: '', + component: FavoritesComponent, + data: { + i18nTitle: 'APP.BROWSE.FAVORITES.TITLE' + } + }, + { + path: 'preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } + } + ] }, { path: 'libraries', @@ -85,7 +90,15 @@ export const APP_ROUTES: Routes = [ data: { i18nTitle: 'APP.BROWSE.LIBRARIES.TITLE' } - }] + }, + { + path: ':id/preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } + } + ] }, { path: 'personal-files', @@ -102,21 +115,52 @@ export const APP_ROUTES: Routes = [ data: { i18nTitle: 'APP.BROWSE.PERSONAL.TITLE' } + }, + { + path: ':id/preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } }] }, { path: 'recent-files', - component: RecentFilesComponent, - data: { - i18nTitle: 'APP.BROWSE.RECENT.TITLE' - } + children: [ + { + path: '', + component: RecentFilesComponent, + data: { + i18nTitle: 'APP.BROWSE.RECENT.TITLE' + } + }, + { + path: 'preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } + } + ] }, { path: 'shared', - component: SharedFilesComponent, - data: { - i18nTitle: 'APP.BROWSE.SHARED.TITLE' - } + children: [ + { + path: '', + component: SharedFilesComponent, + data: { + i18nTitle: 'APP.BROWSE.SHARED.TITLE' + } + }, + { + path: 'preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } + } + ] }, { path: 'trashcan', diff --git a/src/app/components/favorites/favorites.component.spec.ts b/src/app/components/favorites/favorites.component.spec.ts index c121bd7ea..8a0c2a189 100644 --- a/src/app/components/favorites/favorites.component.spec.ts +++ b/src/app/components/favorites/favorites.component.spec.ts @@ -174,7 +174,7 @@ describe('Favorites Routed Component', () => { component.onNodeDoubleClick(node); - expect(router.navigate).toHaveBeenCalledWith(['/preview', node.id]); + expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', 'folder-node']); }); }); diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts index 99b858404..2626f5748 100644 --- a/src/app/components/favorites/favorites.component.ts +++ b/src/app/components/favorites/favorites.component.ts @@ -24,7 +24,7 @@ */ import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; -import { Router } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Rx'; import { MinimalNodeEntryEntity, MinimalNodeEntity, PathElementEntity, PathInfo } from 'alfresco-js-api'; @@ -46,6 +46,7 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr constructor( private router: Router, + private route: ActivatedRoute, private nodesApi: NodesApiService, private contentService: ContentService, private content: ContentManagementService, @@ -95,7 +96,7 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr } if (node.isFile) { - this.router.navigate(['/preview', node.id]); + this.router.navigate(['./preview', node.id], { relativeTo: this.route }); } } } diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts index 884ee1a83..70c7e4f75 100644 --- a/src/app/components/files/files.component.spec.ts +++ b/src/app/components/files/files.component.spec.ts @@ -143,7 +143,7 @@ describe('FilesComponent', () => { fixture.detectChanges(); - expect(router.navigate).toHaveBeenCalledWith([ '/personal-files', 'parent-id' ]); + expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['/personal-files', 'parent-id']); }); }); @@ -315,6 +315,7 @@ describe('FilesComponent', () => { it('opens preview if node is file', () => { spyOn(router, 'navigate').and.stub(); node.isFile = true; + node.isFolder = false; const event: any = { detail: { @@ -325,7 +326,7 @@ describe('FilesComponent', () => { }; component.onNodeDoubleClick(event); - expect(router.navigate).toHaveBeenCalledWith(['/preview', node.id]); + expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', node.id]); }); it('navigate if node is folder', () => { diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index 96926da40..7854a44e7 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -80,9 +80,10 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { if (node.isFolder) { this.updateCurrentNode(node); } else { - this.router.navigate(['/personal-files', node.parentId]); + this.router.navigate(['/personal-files', node.parentId], { replaceUrl: true }); } }) + .skipWhile(node => !node.isFolder) .flatMap((node) => this.fetchNodes(node.id)) .subscribe( (page) => { @@ -154,7 +155,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { event.preventDefault(); } else if (node.isFile) { - this.router.navigate(['/preview', node.id]); + this.router.navigate(['./preview', node.id], { relativeTo: this.route }); } } @@ -164,7 +165,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { showPreview(node: MinimalNodeEntryEntity) { if (node) { if (node.isFile) { - this.router.navigate(['/preview', node.id]); + this.router.navigate(['./preview', node.id], { relativeTo: this.route }); } } } diff --git a/src/app/components/preview/preview.component.html b/src/app/components/preview/preview.component.html index 2592514c9..536b6ebdc 100644 --- a/src/app/components/preview/preview.component.html +++ b/src/app/components/preview/preview.component.html @@ -1,3 +1,7 @@ - + + diff --git a/src/app/components/preview/preview.component.ts b/src/app/components/preview/preview.component.ts index 99d92bfe9..6c42b3416 100644 --- a/src/app/components/preview/preview.component.ts +++ b/src/app/components/preview/preview.component.ts @@ -26,6 +26,7 @@ import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { AlfrescoApiService } from '@alfresco/adf-core'; +import { MinimalNodeEntryEntity } from 'alfresco-js-api'; @Component({ selector: 'app-preview', @@ -37,12 +38,17 @@ import { AlfrescoApiService } from '@alfresco/adf-core'; }) export class PreviewComponent implements OnInit { + private node: MinimalNodeEntryEntity; + private previewLocation: string = null; + private routesSkipNavigation = [ '/shared', '/recent-files', '/favorites' ]; nodeId: string = null; constructor( private router: Router, private route: ActivatedRoute, - private apiService: AlfrescoApiService) {} + private apiService: AlfrescoApiService) { + this.previewLocation = this.router.url.substr(0, this.router.url.indexOf('/', 1)); + } ngOnInit() { this.route.params.subscribe(params => { @@ -50,16 +56,29 @@ export class PreviewComponent implements OnInit { if (id) { this.apiService.getInstance().nodes.getNodeInfo(id).then( (node) => { + this.node = node; + if (node && node.isFile) { this.nodeId = id; return; } - this.router.navigate(['/personal-files', id]); + this.router.navigate([this.previewLocation, id]); }, - () => this.router.navigate(['/personal-files', id]) + () => this.router.navigate([this.previewLocation, id]) ); } }); } + onShowChange(isVisible) { + const shouldSkipNavigation = this.routesSkipNavigation.includes(this.previewLocation); + + if (!isVisible) { + if ( !shouldSkipNavigation ) { + this.router.navigate([this.previewLocation, this.node.parentId ]); + } else { + this.router.navigate([this.previewLocation]); + } + } + } } diff --git a/src/app/components/recent-files/recent-files.component.spec.ts b/src/app/components/recent-files/recent-files.component.spec.ts index 890c5a6f9..7291b60b8 100644 --- a/src/app/components/recent-files/recent-files.component.spec.ts +++ b/src/app/components/recent-files/recent-files.component.spec.ts @@ -122,12 +122,12 @@ describe('RecentFiles Routed Component', () => { it('open preview if node is file', () => { spyOn(router, 'navigate').and.stub(); - const node: any = { isFile: true }; + const node: any = { id: 'node-id', isFile: true }; component.onNodeDoubleClick(node); fixture.detectChanges(); - expect(router.navigate).toHaveBeenCalledWith(['/preview', node.id]); + expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', node.id]); }); it('does not open preview if node is folder', () => { diff --git a/src/app/components/recent-files/recent-files.component.ts b/src/app/components/recent-files/recent-files.component.ts index 1e2617b36..c49048758 100644 --- a/src/app/components/recent-files/recent-files.component.ts +++ b/src/app/components/recent-files/recent-files.component.ts @@ -25,7 +25,7 @@ import { Subscription } from 'rxjs/Rx'; import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; -import { Router } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { MinimalNodeEntryEntity } from 'alfresco-js-api'; import { UserPreferencesService } from '@alfresco/adf-core'; import { DocumentListComponent } from '@alfresco/adf-content-services'; @@ -45,6 +45,7 @@ export class RecentFilesComponent extends PageComponent implements OnInit, OnDes constructor( private router: Router, + private route: ActivatedRoute, private content: ContentManagementService, preferences: UserPreferencesService) { super(preferences); @@ -67,7 +68,7 @@ export class RecentFilesComponent extends PageComponent implements OnInit, OnDes event.preventDefault(); } else if (node && node.isFile) { - this.router.navigate(['/preview', node.id]); + this.router.navigate(['./preview', node.id], { relativeTo: this.route }); } } diff --git a/src/app/components/search/search.component.spec.ts b/src/app/components/search/search.component.spec.ts index 946c4d268..910e25cb0 100644 --- a/src/app/components/search/search.component.spec.ts +++ b/src/app/components/search/search.component.spec.ts @@ -60,11 +60,12 @@ describe('SearchComponent', () => { describe('onItemClicked()', () => { it('opens preview if node is file', () => { spyOn(router, 'navigate').and.stub(); - const node = { entry: { isFile: true, id: 'node-id' } }; + const node = { entry: { isFile: true, id: 'node-id', parentId: 'parent-id' } }; component.onItemClicked(node); - expect(router.navigate).toHaveBeenCalledWith(['/preview', node.entry.id]); + expect(router.navigate['calls'].argsFor(0)[0]) + .toEqual([`/personal-files/${node.entry.parentId}/preview/`, node.entry.id]); }); it('navigates if node is folder', () => { diff --git a/src/app/components/search/search.component.ts b/src/app/components/search/search.component.ts index e4f14405e..10f1f5fec 100644 --- a/src/app/components/search/search.component.ts +++ b/src/app/components/search/search.component.ts @@ -41,7 +41,7 @@ export class SearchComponent { onItemClicked(node: MinimalNodeEntity) { if (node && node.entry) { if (node.entry.isFile) { - this.router.navigate(['/preview', node.entry.id]); + this.router.navigate([`/personal-files/${node.entry.parentId}/preview/`, node.entry.id]); } else if (node.entry.isFolder) { this.router.navigate([ '/personal-files', node.entry.id ]); } diff --git a/src/app/components/shared-files/shared-files.component.spec.ts b/src/app/components/shared-files/shared-files.component.spec.ts index 86df66efd..064b4a9cd 100644 --- a/src/app/components/shared-files/shared-files.component.spec.ts +++ b/src/app/components/shared-files/shared-files.component.spec.ts @@ -126,7 +126,7 @@ describe('SharedFilesComponent', () => { component.onNodeDoubleClick(link); tick(); - expect(router.navigate).toHaveBeenCalledWith(['/preview', node.entry.id]); + expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', node.entry.id]); })); it('does nothing if node is folder', fakeAsync(() => { diff --git a/src/app/components/shared-files/shared-files.component.ts b/src/app/components/shared-files/shared-files.component.ts index 70265c61a..5c4c2bc4d 100644 --- a/src/app/components/shared-files/shared-files.component.ts +++ b/src/app/components/shared-files/shared-files.component.ts @@ -24,7 +24,7 @@ */ import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core'; -import { Router } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Rx'; import { MinimalNodeEntity } from 'alfresco-js-api'; import { AlfrescoApiService, UserPreferencesService } from '@alfresco/adf-core'; @@ -45,6 +45,7 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes constructor( private router: Router, + private route: ActivatedRoute, private content: ContentManagementService, private apiService: AlfrescoApiService, preferences: UserPreferencesService) { @@ -68,7 +69,7 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes this.apiService.nodesApi.getNode(link.nodeId).then( (node: MinimalNodeEntity) => { if (node && node.entry && node.entry.isFile) { - this.router.navigate(['/preview', node.entry.id]); + this.router.navigate(['./preview', node.entry.id], { relativeTo: this.route }); } } ); From b6018facac5e066db42a914be299cb5e33150d4c Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 3 Jan 2018 10:05:54 +0000 Subject: [PATCH 18/69] Revert "preview files child route (#170)" (#171) This reverts commit d768219bdbdf91006bb5972e1412d3185a938407. --- src/app/app.routes.ts | 84 +++++-------------- .../favorites/favorites.component.spec.ts | 2 +- .../favorites/favorites.component.ts | 5 +- .../components/files/files.component.spec.ts | 5 +- src/app/components/files/files.component.ts | 7 +- .../components/preview/preview.component.html | 6 +- .../components/preview/preview.component.ts | 25 +----- .../recent-files.component.spec.ts | 4 +- .../recent-files/recent-files.component.ts | 5 +- .../search/search.component.spec.ts | 5 +- src/app/components/search/search.component.ts | 2 +- .../shared-files.component.spec.ts | 2 +- .../shared-files/shared-files.component.ts | 5 +- 13 files changed, 42 insertions(+), 115 deletions(-) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 8c66ca552..3a28d1cef 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -41,6 +41,13 @@ import { PreviewComponent } from './components/preview/preview.component'; import { GenericErrorComponent } from './components/generic-error/generic-error.component'; export const APP_ROUTES: Routes = [ + { + path: 'preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } + }, { path: 'login', component: LoginComponent, @@ -59,22 +66,10 @@ export const APP_ROUTES: Routes = [ }, { path: 'favorites', - children: [ - { - path: '', - component: FavoritesComponent, - data: { - i18nTitle: 'APP.BROWSE.FAVORITES.TITLE' - } - }, - { - path: 'preview/:nodeId', - component: PreviewComponent, - data: { - i18nTitle: 'APP.PREVIEW.TITLE' - } - } - ] + component: FavoritesComponent, + data: { + i18nTitle: 'APP.BROWSE.FAVORITES.TITLE' + } }, { path: 'libraries', @@ -90,15 +85,7 @@ export const APP_ROUTES: Routes = [ data: { i18nTitle: 'APP.BROWSE.LIBRARIES.TITLE' } - }, - { - path: ':id/preview/:nodeId', - component: PreviewComponent, - data: { - i18nTitle: 'APP.PREVIEW.TITLE' - } - } - ] + }] }, { path: 'personal-files', @@ -115,52 +102,21 @@ export const APP_ROUTES: Routes = [ data: { i18nTitle: 'APP.BROWSE.PERSONAL.TITLE' } - }, - { - path: ':id/preview/:nodeId', - component: PreviewComponent, - data: { - i18nTitle: 'APP.PREVIEW.TITLE' - } }] }, { path: 'recent-files', - children: [ - { - path: '', - component: RecentFilesComponent, - data: { - i18nTitle: 'APP.BROWSE.RECENT.TITLE' - } - }, - { - path: 'preview/:nodeId', - component: PreviewComponent, - data: { - i18nTitle: 'APP.PREVIEW.TITLE' - } - } - ] + component: RecentFilesComponent, + data: { + i18nTitle: 'APP.BROWSE.RECENT.TITLE' + } }, { path: 'shared', - children: [ - { - path: '', - component: SharedFilesComponent, - data: { - i18nTitle: 'APP.BROWSE.SHARED.TITLE' - } - }, - { - path: 'preview/:nodeId', - component: PreviewComponent, - data: { - i18nTitle: 'APP.PREVIEW.TITLE' - } - } - ] + component: SharedFilesComponent, + data: { + i18nTitle: 'APP.BROWSE.SHARED.TITLE' + } }, { path: 'trashcan', diff --git a/src/app/components/favorites/favorites.component.spec.ts b/src/app/components/favorites/favorites.component.spec.ts index 8a0c2a189..c121bd7ea 100644 --- a/src/app/components/favorites/favorites.component.spec.ts +++ b/src/app/components/favorites/favorites.component.spec.ts @@ -174,7 +174,7 @@ describe('Favorites Routed Component', () => { component.onNodeDoubleClick(node); - expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', 'folder-node']); + expect(router.navigate).toHaveBeenCalledWith(['/preview', node.id]); }); }); diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts index 2626f5748..99b858404 100644 --- a/src/app/components/favorites/favorites.component.ts +++ b/src/app/components/favorites/favorites.component.ts @@ -24,7 +24,7 @@ */ import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; -import { Router, ActivatedRoute } from '@angular/router'; +import { Router } from '@angular/router'; import { Subscription } from 'rxjs/Rx'; import { MinimalNodeEntryEntity, MinimalNodeEntity, PathElementEntity, PathInfo } from 'alfresco-js-api'; @@ -46,7 +46,6 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr constructor( private router: Router, - private route: ActivatedRoute, private nodesApi: NodesApiService, private contentService: ContentService, private content: ContentManagementService, @@ -96,7 +95,7 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr } if (node.isFile) { - this.router.navigate(['./preview', node.id], { relativeTo: this.route }); + this.router.navigate(['/preview', node.id]); } } } diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts index 70c7e4f75..884ee1a83 100644 --- a/src/app/components/files/files.component.spec.ts +++ b/src/app/components/files/files.component.spec.ts @@ -143,7 +143,7 @@ describe('FilesComponent', () => { fixture.detectChanges(); - expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['/personal-files', 'parent-id']); + expect(router.navigate).toHaveBeenCalledWith([ '/personal-files', 'parent-id' ]); }); }); @@ -315,7 +315,6 @@ describe('FilesComponent', () => { it('opens preview if node is file', () => { spyOn(router, 'navigate').and.stub(); node.isFile = true; - node.isFolder = false; const event: any = { detail: { @@ -326,7 +325,7 @@ describe('FilesComponent', () => { }; component.onNodeDoubleClick(event); - expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', node.id]); + expect(router.navigate).toHaveBeenCalledWith(['/preview', node.id]); }); it('navigate if node is folder', () => { diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index 7854a44e7..96926da40 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -80,10 +80,9 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { if (node.isFolder) { this.updateCurrentNode(node); } else { - this.router.navigate(['/personal-files', node.parentId], { replaceUrl: true }); + this.router.navigate(['/personal-files', node.parentId]); } }) - .skipWhile(node => !node.isFolder) .flatMap((node) => this.fetchNodes(node.id)) .subscribe( (page) => { @@ -155,7 +154,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { event.preventDefault(); } else if (node.isFile) { - this.router.navigate(['./preview', node.id], { relativeTo: this.route }); + this.router.navigate(['/preview', node.id]); } } @@ -165,7 +164,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { showPreview(node: MinimalNodeEntryEntity) { if (node) { if (node.isFile) { - this.router.navigate(['./preview', node.id], { relativeTo: this.route }); + this.router.navigate(['/preview', node.id]); } } } diff --git a/src/app/components/preview/preview.component.html b/src/app/components/preview/preview.component.html index 536b6ebdc..2592514c9 100644 --- a/src/app/components/preview/preview.component.html +++ b/src/app/components/preview/preview.component.html @@ -1,7 +1,3 @@ - - + diff --git a/src/app/components/preview/preview.component.ts b/src/app/components/preview/preview.component.ts index 6c42b3416..99d92bfe9 100644 --- a/src/app/components/preview/preview.component.ts +++ b/src/app/components/preview/preview.component.ts @@ -26,7 +26,6 @@ import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { AlfrescoApiService } from '@alfresco/adf-core'; -import { MinimalNodeEntryEntity } from 'alfresco-js-api'; @Component({ selector: 'app-preview', @@ -38,17 +37,12 @@ import { MinimalNodeEntryEntity } from 'alfresco-js-api'; }) export class PreviewComponent implements OnInit { - private node: MinimalNodeEntryEntity; - private previewLocation: string = null; - private routesSkipNavigation = [ '/shared', '/recent-files', '/favorites' ]; nodeId: string = null; constructor( private router: Router, private route: ActivatedRoute, - private apiService: AlfrescoApiService) { - this.previewLocation = this.router.url.substr(0, this.router.url.indexOf('/', 1)); - } + private apiService: AlfrescoApiService) {} ngOnInit() { this.route.params.subscribe(params => { @@ -56,29 +50,16 @@ export class PreviewComponent implements OnInit { if (id) { this.apiService.getInstance().nodes.getNodeInfo(id).then( (node) => { - this.node = node; - if (node && node.isFile) { this.nodeId = id; return; } - this.router.navigate([this.previewLocation, id]); + this.router.navigate(['/personal-files', id]); }, - () => this.router.navigate([this.previewLocation, id]) + () => this.router.navigate(['/personal-files', id]) ); } }); } - onShowChange(isVisible) { - const shouldSkipNavigation = this.routesSkipNavigation.includes(this.previewLocation); - - if (!isVisible) { - if ( !shouldSkipNavigation ) { - this.router.navigate([this.previewLocation, this.node.parentId ]); - } else { - this.router.navigate([this.previewLocation]); - } - } - } } diff --git a/src/app/components/recent-files/recent-files.component.spec.ts b/src/app/components/recent-files/recent-files.component.spec.ts index 7291b60b8..890c5a6f9 100644 --- a/src/app/components/recent-files/recent-files.component.spec.ts +++ b/src/app/components/recent-files/recent-files.component.spec.ts @@ -122,12 +122,12 @@ describe('RecentFiles Routed Component', () => { it('open preview if node is file', () => { spyOn(router, 'navigate').and.stub(); - const node: any = { id: 'node-id', isFile: true }; + const node: any = { isFile: true }; component.onNodeDoubleClick(node); fixture.detectChanges(); - expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', node.id]); + expect(router.navigate).toHaveBeenCalledWith(['/preview', node.id]); }); it('does not open preview if node is folder', () => { diff --git a/src/app/components/recent-files/recent-files.component.ts b/src/app/components/recent-files/recent-files.component.ts index c49048758..1e2617b36 100644 --- a/src/app/components/recent-files/recent-files.component.ts +++ b/src/app/components/recent-files/recent-files.component.ts @@ -25,7 +25,7 @@ import { Subscription } from 'rxjs/Rx'; import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; -import { Router, ActivatedRoute } from '@angular/router'; +import { Router } from '@angular/router'; import { MinimalNodeEntryEntity } from 'alfresco-js-api'; import { UserPreferencesService } from '@alfresco/adf-core'; import { DocumentListComponent } from '@alfresco/adf-content-services'; @@ -45,7 +45,6 @@ export class RecentFilesComponent extends PageComponent implements OnInit, OnDes constructor( private router: Router, - private route: ActivatedRoute, private content: ContentManagementService, preferences: UserPreferencesService) { super(preferences); @@ -68,7 +67,7 @@ export class RecentFilesComponent extends PageComponent implements OnInit, OnDes event.preventDefault(); } else if (node && node.isFile) { - this.router.navigate(['./preview', node.id], { relativeTo: this.route }); + this.router.navigate(['/preview', node.id]); } } diff --git a/src/app/components/search/search.component.spec.ts b/src/app/components/search/search.component.spec.ts index 910e25cb0..946c4d268 100644 --- a/src/app/components/search/search.component.spec.ts +++ b/src/app/components/search/search.component.spec.ts @@ -60,12 +60,11 @@ describe('SearchComponent', () => { describe('onItemClicked()', () => { it('opens preview if node is file', () => { spyOn(router, 'navigate').and.stub(); - const node = { entry: { isFile: true, id: 'node-id', parentId: 'parent-id' } }; + const node = { entry: { isFile: true, id: 'node-id' } }; component.onItemClicked(node); - expect(router.navigate['calls'].argsFor(0)[0]) - .toEqual([`/personal-files/${node.entry.parentId}/preview/`, node.entry.id]); + expect(router.navigate).toHaveBeenCalledWith(['/preview', node.entry.id]); }); it('navigates if node is folder', () => { diff --git a/src/app/components/search/search.component.ts b/src/app/components/search/search.component.ts index 10f1f5fec..e4f14405e 100644 --- a/src/app/components/search/search.component.ts +++ b/src/app/components/search/search.component.ts @@ -41,7 +41,7 @@ export class SearchComponent { onItemClicked(node: MinimalNodeEntity) { if (node && node.entry) { if (node.entry.isFile) { - this.router.navigate([`/personal-files/${node.entry.parentId}/preview/`, node.entry.id]); + this.router.navigate(['/preview', node.entry.id]); } else if (node.entry.isFolder) { this.router.navigate([ '/personal-files', node.entry.id ]); } diff --git a/src/app/components/shared-files/shared-files.component.spec.ts b/src/app/components/shared-files/shared-files.component.spec.ts index 064b4a9cd..86df66efd 100644 --- a/src/app/components/shared-files/shared-files.component.spec.ts +++ b/src/app/components/shared-files/shared-files.component.spec.ts @@ -126,7 +126,7 @@ describe('SharedFilesComponent', () => { component.onNodeDoubleClick(link); tick(); - expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', node.entry.id]); + expect(router.navigate).toHaveBeenCalledWith(['/preview', node.entry.id]); })); it('does nothing if node is folder', fakeAsync(() => { diff --git a/src/app/components/shared-files/shared-files.component.ts b/src/app/components/shared-files/shared-files.component.ts index 5c4c2bc4d..70265c61a 100644 --- a/src/app/components/shared-files/shared-files.component.ts +++ b/src/app/components/shared-files/shared-files.component.ts @@ -24,7 +24,7 @@ */ import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core'; -import { Router, ActivatedRoute } from '@angular/router'; +import { Router } from '@angular/router'; import { Subscription } from 'rxjs/Rx'; import { MinimalNodeEntity } from 'alfresco-js-api'; import { AlfrescoApiService, UserPreferencesService } from '@alfresco/adf-core'; @@ -45,7 +45,6 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes constructor( private router: Router, - private route: ActivatedRoute, private content: ContentManagementService, private apiService: AlfrescoApiService, preferences: UserPreferencesService) { @@ -69,7 +68,7 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes this.apiService.nodesApi.getNode(link.nodeId).then( (node: MinimalNodeEntity) => { if (node && node.entry && node.entry.isFile) { - this.router.navigate(['./preview', node.entry.id], { relativeTo: this.route }); + this.router.navigate(['/preview', node.entry.id]); } } ); From 00d14069c5100a926e181ebff3cdb82e4b163f2a Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 9 Jan 2018 16:00:19 +0000 Subject: [PATCH 19/69] [ACA-1066] Improved files preview (#173) * preview files child route * fix previewing root files (personal) --- src/app/app.routes.ts | 120 +++++++++++++----- .../favorites/favorites.component.spec.ts | 2 +- .../favorites/favorites.component.ts | 5 +- .../components/files/files.component.spec.ts | 5 +- src/app/components/files/files.component.ts | 7 +- .../components/preview/preview.component.html | 6 +- .../components/preview/preview.component.ts | 25 +++- .../recent-files.component.spec.ts | 4 +- .../recent-files/recent-files.component.ts | 5 +- .../search/search.component.spec.ts | 5 +- src/app/components/search/search.component.ts | 2 +- .../shared-files.component.spec.ts | 2 +- .../shared-files/shared-files.component.ts | 5 +- 13 files changed, 138 insertions(+), 55 deletions(-) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 3a28d1cef..2b88a3d27 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -41,13 +41,6 @@ import { PreviewComponent } from './components/preview/preview.component'; import { GenericErrorComponent } from './components/generic-error/generic-error.component'; export const APP_ROUTES: Routes = [ - { - path: 'preview/:nodeId', - component: PreviewComponent, - data: { - i18nTitle: 'APP.PREVIEW.TITLE' - } - }, { path: 'login', component: LoginComponent, @@ -66,10 +59,22 @@ export const APP_ROUTES: Routes = [ }, { path: 'favorites', - component: FavoritesComponent, - data: { - i18nTitle: 'APP.BROWSE.FAVORITES.TITLE' - } + children: [ + { + path: '', + component: FavoritesComponent, + data: { + i18nTitle: 'APP.BROWSE.FAVORITES.TITLE' + } + }, + { + path: 'preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } + } + ] }, { path: 'libraries', @@ -85,38 +90,87 @@ export const APP_ROUTES: Routes = [ data: { i18nTitle: 'APP.BROWSE.LIBRARIES.TITLE' } - }] + }, + { + path: ':id/preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } + } + ] }, { path: 'personal-files', - children: [{ - path: '', - component: FilesComponent, - data: { - i18nTitle: 'APP.BROWSE.PERSONAL.TITLE', - defaultNodeId: '-my-' + children: [ + { + path: '', + component: FilesComponent, + data: { + i18nTitle: 'APP.BROWSE.PERSONAL.TITLE', + defaultNodeId: '-my-' + } + }, + { + path: ':id', + component: FilesComponent, + data: { + i18nTitle: 'APP.BROWSE.PERSONAL.TITLE' + } + }, + { + path: 'preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } + }, + { + path: ':id/preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } } - }, { - path: ':id', - component: FilesComponent, - data: { - i18nTitle: 'APP.BROWSE.PERSONAL.TITLE' - } - }] + ] }, { path: 'recent-files', - component: RecentFilesComponent, - data: { - i18nTitle: 'APP.BROWSE.RECENT.TITLE' - } + children: [ + { + path: '', + component: RecentFilesComponent, + data: { + i18nTitle: 'APP.BROWSE.RECENT.TITLE' + } + }, + { + path: 'preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } + } + ] }, { path: 'shared', - component: SharedFilesComponent, - data: { - i18nTitle: 'APP.BROWSE.SHARED.TITLE' - } + children: [ + { + path: '', + component: SharedFilesComponent, + data: { + i18nTitle: 'APP.BROWSE.SHARED.TITLE' + } + }, + { + path: 'preview/:nodeId', + component: PreviewComponent, + data: { + i18nTitle: 'APP.PREVIEW.TITLE' + } + } + ] }, { path: 'trashcan', diff --git a/src/app/components/favorites/favorites.component.spec.ts b/src/app/components/favorites/favorites.component.spec.ts index c121bd7ea..8a0c2a189 100644 --- a/src/app/components/favorites/favorites.component.spec.ts +++ b/src/app/components/favorites/favorites.component.spec.ts @@ -174,7 +174,7 @@ describe('Favorites Routed Component', () => { component.onNodeDoubleClick(node); - expect(router.navigate).toHaveBeenCalledWith(['/preview', node.id]); + expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', 'folder-node']); }); }); diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts index 99b858404..2626f5748 100644 --- a/src/app/components/favorites/favorites.component.ts +++ b/src/app/components/favorites/favorites.component.ts @@ -24,7 +24,7 @@ */ import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; -import { Router } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Rx'; import { MinimalNodeEntryEntity, MinimalNodeEntity, PathElementEntity, PathInfo } from 'alfresco-js-api'; @@ -46,6 +46,7 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr constructor( private router: Router, + private route: ActivatedRoute, private nodesApi: NodesApiService, private contentService: ContentService, private content: ContentManagementService, @@ -95,7 +96,7 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr } if (node.isFile) { - this.router.navigate(['/preview', node.id]); + this.router.navigate(['./preview', node.id], { relativeTo: this.route }); } } } diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts index 884ee1a83..70c7e4f75 100644 --- a/src/app/components/files/files.component.spec.ts +++ b/src/app/components/files/files.component.spec.ts @@ -143,7 +143,7 @@ describe('FilesComponent', () => { fixture.detectChanges(); - expect(router.navigate).toHaveBeenCalledWith([ '/personal-files', 'parent-id' ]); + expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['/personal-files', 'parent-id']); }); }); @@ -315,6 +315,7 @@ describe('FilesComponent', () => { it('opens preview if node is file', () => { spyOn(router, 'navigate').and.stub(); node.isFile = true; + node.isFolder = false; const event: any = { detail: { @@ -325,7 +326,7 @@ describe('FilesComponent', () => { }; component.onNodeDoubleClick(event); - expect(router.navigate).toHaveBeenCalledWith(['/preview', node.id]); + expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', node.id]); }); it('navigate if node is folder', () => { diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index 96926da40..7854a44e7 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -80,9 +80,10 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { if (node.isFolder) { this.updateCurrentNode(node); } else { - this.router.navigate(['/personal-files', node.parentId]); + this.router.navigate(['/personal-files', node.parentId], { replaceUrl: true }); } }) + .skipWhile(node => !node.isFolder) .flatMap((node) => this.fetchNodes(node.id)) .subscribe( (page) => { @@ -154,7 +155,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { event.preventDefault(); } else if (node.isFile) { - this.router.navigate(['/preview', node.id]); + this.router.navigate(['./preview', node.id], { relativeTo: this.route }); } } @@ -164,7 +165,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { showPreview(node: MinimalNodeEntryEntity) { if (node) { if (node.isFile) { - this.router.navigate(['/preview', node.id]); + this.router.navigate(['./preview', node.id], { relativeTo: this.route }); } } } diff --git a/src/app/components/preview/preview.component.html b/src/app/components/preview/preview.component.html index 2592514c9..536b6ebdc 100644 --- a/src/app/components/preview/preview.component.html +++ b/src/app/components/preview/preview.component.html @@ -1,3 +1,7 @@ - + + diff --git a/src/app/components/preview/preview.component.ts b/src/app/components/preview/preview.component.ts index 99d92bfe9..6c42b3416 100644 --- a/src/app/components/preview/preview.component.ts +++ b/src/app/components/preview/preview.component.ts @@ -26,6 +26,7 @@ import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { AlfrescoApiService } from '@alfresco/adf-core'; +import { MinimalNodeEntryEntity } from 'alfresco-js-api'; @Component({ selector: 'app-preview', @@ -37,12 +38,17 @@ import { AlfrescoApiService } from '@alfresco/adf-core'; }) export class PreviewComponent implements OnInit { + private node: MinimalNodeEntryEntity; + private previewLocation: string = null; + private routesSkipNavigation = [ '/shared', '/recent-files', '/favorites' ]; nodeId: string = null; constructor( private router: Router, private route: ActivatedRoute, - private apiService: AlfrescoApiService) {} + private apiService: AlfrescoApiService) { + this.previewLocation = this.router.url.substr(0, this.router.url.indexOf('/', 1)); + } ngOnInit() { this.route.params.subscribe(params => { @@ -50,16 +56,29 @@ export class PreviewComponent implements OnInit { if (id) { this.apiService.getInstance().nodes.getNodeInfo(id).then( (node) => { + this.node = node; + if (node && node.isFile) { this.nodeId = id; return; } - this.router.navigate(['/personal-files', id]); + this.router.navigate([this.previewLocation, id]); }, - () => this.router.navigate(['/personal-files', id]) + () => this.router.navigate([this.previewLocation, id]) ); } }); } + onShowChange(isVisible) { + const shouldSkipNavigation = this.routesSkipNavigation.includes(this.previewLocation); + + if (!isVisible) { + if ( !shouldSkipNavigation ) { + this.router.navigate([this.previewLocation, this.node.parentId ]); + } else { + this.router.navigate([this.previewLocation]); + } + } + } } diff --git a/src/app/components/recent-files/recent-files.component.spec.ts b/src/app/components/recent-files/recent-files.component.spec.ts index 890c5a6f9..7291b60b8 100644 --- a/src/app/components/recent-files/recent-files.component.spec.ts +++ b/src/app/components/recent-files/recent-files.component.spec.ts @@ -122,12 +122,12 @@ describe('RecentFiles Routed Component', () => { it('open preview if node is file', () => { spyOn(router, 'navigate').and.stub(); - const node: any = { isFile: true }; + const node: any = { id: 'node-id', isFile: true }; component.onNodeDoubleClick(node); fixture.detectChanges(); - expect(router.navigate).toHaveBeenCalledWith(['/preview', node.id]); + expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', node.id]); }); it('does not open preview if node is folder', () => { diff --git a/src/app/components/recent-files/recent-files.component.ts b/src/app/components/recent-files/recent-files.component.ts index 1e2617b36..c49048758 100644 --- a/src/app/components/recent-files/recent-files.component.ts +++ b/src/app/components/recent-files/recent-files.component.ts @@ -25,7 +25,7 @@ import { Subscription } from 'rxjs/Rx'; import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; -import { Router } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { MinimalNodeEntryEntity } from 'alfresco-js-api'; import { UserPreferencesService } from '@alfresco/adf-core'; import { DocumentListComponent } from '@alfresco/adf-content-services'; @@ -45,6 +45,7 @@ export class RecentFilesComponent extends PageComponent implements OnInit, OnDes constructor( private router: Router, + private route: ActivatedRoute, private content: ContentManagementService, preferences: UserPreferencesService) { super(preferences); @@ -67,7 +68,7 @@ export class RecentFilesComponent extends PageComponent implements OnInit, OnDes event.preventDefault(); } else if (node && node.isFile) { - this.router.navigate(['/preview', node.id]); + this.router.navigate(['./preview', node.id], { relativeTo: this.route }); } } diff --git a/src/app/components/search/search.component.spec.ts b/src/app/components/search/search.component.spec.ts index 946c4d268..910e25cb0 100644 --- a/src/app/components/search/search.component.spec.ts +++ b/src/app/components/search/search.component.spec.ts @@ -60,11 +60,12 @@ describe('SearchComponent', () => { describe('onItemClicked()', () => { it('opens preview if node is file', () => { spyOn(router, 'navigate').and.stub(); - const node = { entry: { isFile: true, id: 'node-id' } }; + const node = { entry: { isFile: true, id: 'node-id', parentId: 'parent-id' } }; component.onItemClicked(node); - expect(router.navigate).toHaveBeenCalledWith(['/preview', node.entry.id]); + expect(router.navigate['calls'].argsFor(0)[0]) + .toEqual([`/personal-files/${node.entry.parentId}/preview/`, node.entry.id]); }); it('navigates if node is folder', () => { diff --git a/src/app/components/search/search.component.ts b/src/app/components/search/search.component.ts index e4f14405e..10f1f5fec 100644 --- a/src/app/components/search/search.component.ts +++ b/src/app/components/search/search.component.ts @@ -41,7 +41,7 @@ export class SearchComponent { onItemClicked(node: MinimalNodeEntity) { if (node && node.entry) { if (node.entry.isFile) { - this.router.navigate(['/preview', node.entry.id]); + this.router.navigate([`/personal-files/${node.entry.parentId}/preview/`, node.entry.id]); } else if (node.entry.isFolder) { this.router.navigate([ '/personal-files', node.entry.id ]); } diff --git a/src/app/components/shared-files/shared-files.component.spec.ts b/src/app/components/shared-files/shared-files.component.spec.ts index 86df66efd..064b4a9cd 100644 --- a/src/app/components/shared-files/shared-files.component.spec.ts +++ b/src/app/components/shared-files/shared-files.component.spec.ts @@ -126,7 +126,7 @@ describe('SharedFilesComponent', () => { component.onNodeDoubleClick(link); tick(); - expect(router.navigate).toHaveBeenCalledWith(['/preview', node.entry.id]); + expect(router.navigate['calls'].argsFor(0)[0]).toEqual(['./preview', node.entry.id]); })); it('does nothing if node is folder', fakeAsync(() => { diff --git a/src/app/components/shared-files/shared-files.component.ts b/src/app/components/shared-files/shared-files.component.ts index 70265c61a..5c4c2bc4d 100644 --- a/src/app/components/shared-files/shared-files.component.ts +++ b/src/app/components/shared-files/shared-files.component.ts @@ -24,7 +24,7 @@ */ import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core'; -import { Router } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Rx'; import { MinimalNodeEntity } from 'alfresco-js-api'; import { AlfrescoApiService, UserPreferencesService } from '@alfresco/adf-core'; @@ -45,6 +45,7 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes constructor( private router: Router, + private route: ActivatedRoute, private content: ContentManagementService, private apiService: AlfrescoApiService, preferences: UserPreferencesService) { @@ -68,7 +69,7 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes this.apiService.nodesApi.getNode(link.nodeId).then( (node: MinimalNodeEntity) => { if (node && node.entry && node.entry.isFile) { - this.router.navigate(['/preview', node.entry.id]); + this.router.navigate(['./preview', node.entry.id], { relativeTo: this.route }); } } ); From b780bd831b4217c196975d662e3a3e9ccc92f615 Mon Sep 17 00:00:00 2001 From: suzanadirla Date: Thu, 11 Jan 2018 19:21:54 +0200 Subject: [PATCH 20/69] upgrade to ADF 2.1.0-beta6 (#174) --- package.json | 30 +++++----- .../common/services/node-actions.service.ts | 56 ++++++++++++------- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/package.json b/package.json index 9f4fd5f20..19f9d976b 100644 --- a/package.json +++ b/package.json @@ -16,20 +16,20 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "2.0.0", - "@alfresco/adf-core": "2.0.0", - "@angular/animations": "5.0.0", - "@angular/cdk": "5.0.0-rc0", - "@angular/common": "5.0.0", - "@angular/compiler": "5.0.0", - "@angular/core": "5.0.0", - "@angular/flex-layout": "2.0.0-beta.10", - "@angular/forms": "5.0.0", - "@angular/http": "5.0.0", - "@angular/material": "5.0.0-rc0", - "@angular/platform-browser": "5.0.0", - "@angular/platform-browser-dynamic": "5.0.0", - "@angular/router": "5.0.0", + "@alfresco/adf-content-services": "2.1.0-beta6", + "@alfresco/adf-core": "2.1.0-beta6", + "@angular/animations": "5.1.1", + "@angular/cdk": "5.0.1", + "@angular/common": "5.1.1", + "@angular/compiler": "5.1.1", + "@angular/core": "5.1.1", + "@angular/flex-layout": "2.0.0-beta.12", + "@angular/forms": "5.1.1", + "@angular/http": "5.1.1", + "@angular/material": "5.0.1", + "@angular/platform-browser": "5.1.1", + "@angular/platform-browser-dynamic": "5.1.1", + "@angular/router": "5.1.1", "@ngx-translate/core": "8.0.0", "alfresco-js-api": "2.0.0", "core-js": "2.4.1", @@ -42,7 +42,7 @@ }, "devDependencies": { "@angular/cli": "1.5.0", - "@angular/compiler-cli": "5.0.0", + "@angular/compiler-cli": "5.1.1", "@angular/language-service": "4.4.5", "@types/jasmine": "^2.5.53", "@types/jasminewd2": "^2.0.2", diff --git a/src/app/common/services/node-actions.service.ts b/src/app/common/services/node-actions.service.ts index 17b2feb77..8d148933a 100644 --- a/src/app/common/services/node-actions.service.ts +++ b/src/app/common/services/node-actions.service.ts @@ -23,13 +23,13 @@ * along with Alfresco. If not, see . */ -import { EventEmitter, Injectable } from '@angular/core'; +import { Injectable } from '@angular/core'; import { MatDialog } from '@angular/material'; import { Observable, Subject } from 'rxjs/Rx'; -import { AlfrescoApiService, ContentService, NodesApiService, DataColumn, DataSorting } from '@alfresco/adf-core'; +import { AlfrescoApiService, ContentService, NodesApiService, DataColumn } from '@alfresco/adf-core'; import { DocumentListService, ContentNodeSelectorComponent, ContentNodeSelectorComponentData } from '@alfresco/adf-content-services'; -import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { MinimalNodeEntity, MinimalNodeEntryEntity, SitePaging } from 'alfresco-js-api'; @Injectable() export class NodeActionsService { @@ -121,7 +121,6 @@ export class NodeActionsService { }, observable.error.bind(observable) ); - this.dialog.closeAll(); }); } else { @@ -173,7 +172,7 @@ export class NodeActionsService { return entryParentId; } - getContentNodeSelection(action: string, contentEntities: MinimalNodeEntity[]): EventEmitter { + getContentNodeSelection(action: string, contentEntities: MinimalNodeEntity[]): Subject { const currentParentFolderId = this.getFirstParentId(contentEntities); let nodeEntryName = ''; @@ -181,17 +180,34 @@ export class NodeActionsService { nodeEntryName = `'${contentEntities[0].entry.name}' `; } + const customDropdown: SitePaging = { + list: { + entries: [ + { + entry: { + guid: '-my-', + title: 'APP.BROWSE.PERSONAL.SIDENAV_LINK.LABEL' + } + }, + { + entry: { + guid: '-mysites-', + title: 'APP.BROWSE.LIBRARIES.SIDENAV_LINK.LABEL' + } + } + ] + } + }; + const data: ContentNodeSelectorComponentData = { title: `${action} ${nodeEntryName}to ...`, currentFolderId: currentParentFolderId, actionName: action, dropdownHideMyFiles: true, - dropdownSiteList: [ - {title: 'APP.BROWSE.PERSONAL.SIDENAV_LINK.LABEL', guid: '-my-'}, - {title: 'APP.BROWSE.LIBRARIES.SIDENAV_LINK.LABEL', guid: '-mysites-'}], + dropdownSiteList: customDropdown, rowFilter: this.rowFilter.bind(this), imageResolver: this.imageResolver.bind(this), - select: new EventEmitter() + select: new Subject() }; const matDialogRef = this.dialog.open(ContentNodeSelectorComponent, { @@ -199,7 +215,9 @@ export class NodeActionsService { panelClass: 'adf-content-node-selector-dialog', width: '630px' }); - const destinationPicker = matDialogRef.componentInstance; + + // todo: add back the fix for [ACA-1054]: + /* const destinationPicker = matDialogRef.componentInstance; const initialSiteChanged = destinationPicker.siteChanged; destinationPicker.siteChanged = (chosenSite) => { @@ -210,21 +228,19 @@ export class NodeActionsService { } else { destinationPicker.documentList.data.setSorting(new DataSorting('name', 'asc')); } - }; + };*/ - const initialGetNextPageOfSearch = destinationPicker.getNextPageOfSearch; - destinationPicker.getNextPageOfSearch = (event) => { - destinationPicker.infiniteScroll = true; - destinationPicker.skipCount = event.skipCount; - - if (destinationPicker.searchTerm.length > 0) { - initialGetNextPageOfSearch.call(destinationPicker, event); - } - }; + data.select.subscribe({ + complete: this.close.bind(this) + }); return data.select; } + close() { + this.dialog.closeAll(); + } + copyNodeAction(nodeEntry, selectionId): Observable { if (nodeEntry.isFolder) { return this.copyFolderAction(nodeEntry, selectionId); From 3a7e11400645c8daf6307b3b434a441894cd86c2 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Mon, 15 Jan 2018 12:35:25 +0200 Subject: [PATCH 21/69] pagination configuration (#175) --- docs/configuration.md | 2 +- src/app.config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index bdf2ad0f0..030888735 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -121,7 +121,7 @@ You can change the default settings of the pagination that gets applied to all t ```json { ..., - "document-list": { + "pagination": { "supportedPageSizes": [ 25, 50, diff --git a/src/app.config.json b/src/app.config.json index 43cc289ec..99f2f0cd9 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -6,7 +6,7 @@ }, "headerColor": "#2196F3", "languagePicker": false, - "document-list": { + "pagination": { "supportedPageSizes": [ 25, 50, From e46f9c8a5ecc7f93a2529bc583096f3e6c50cffe Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Sat, 20 Jan 2018 18:34:35 +0000 Subject: [PATCH 22/69] codacy integration (#176) * codacy tool depencendy * setup travis converage integration * fix CLI dependency issue * travis setup --- .travis.yml | 2 +- package.json | 2 + yarn.lock | 286 +++++++++++++++++++++++++++++++++++---------------- 3 files changed, 199 insertions(+), 91 deletions(-) diff --git a/.travis.yml b/.travis.yml index f9a1b2411..4ad12144e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ install: script: - npm run build - - npm run test -- --single-run --no-progress + - npm run test -- --single-run --no-progress && cat ./coverage/lcov.info | ./node_modules/.bin/codacy-coverage && rm -rf ./coverage # Send coverage data to codecov after_success: diff --git a/package.json b/package.json index 19f9d976b..e0dcaca3b 100644 --- a/package.json +++ b/package.json @@ -41,12 +41,14 @@ "zone.js": "0.8.14" }, "devDependencies": { + "@angular-devkit/core": "^0.0.28", "@angular/cli": "1.5.0", "@angular/compiler-cli": "5.1.1", "@angular/language-service": "4.4.5", "@types/jasmine": "^2.5.53", "@types/jasminewd2": "^2.0.2", "@types/node": "~6.0.60", + "codacy-coverage": "^2.0.3", "codelyzer": "~3.2.0", "jasmine-core": "^2.6.2", "jasmine-reporters": "^2.2.1", diff --git a/yarn.lock b/yarn.lock index afc2765ba..4c4571e8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,26 +2,26 @@ # yarn lockfile v1 -"@alfresco/adf-content-services@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@alfresco/adf-content-services/-/adf-content-services-2.0.0.tgz#9e9b14549f1c4b9fda47441442f0f90a5763408c" +"@alfresco/adf-content-services@2.1.0-beta6": + version "2.1.0-beta6" + resolved "https://registry.yarnpkg.com/@alfresco/adf-content-services/-/adf-content-services-2.1.0-beta6.tgz#7a6e783c1b9beadf7a2f64895854e65b979e0bcf" dependencies: - "@alfresco/adf-core" "2.0.0" - "@angular/animations" "5.0.0" - "@angular/cdk" "5.0.0-rc0" - "@angular/common" "5.0.0" - "@angular/compiler" "5.0.0" - "@angular/core" "5.0.0" - "@angular/flex-layout" "2.0.0-beta.10" - "@angular/forms" "5.0.0" - "@angular/http" "5.0.0" - "@angular/material" "5.0.0-rc0" - "@angular/material-moment-adapter" "^5.0.0-rc0" - "@angular/platform-browser" "5.0.0" - "@angular/platform-browser-dynamic" "5.0.0" - "@angular/router" "5.0.0" + "@alfresco/adf-core" "2.1.0-beta6" + "@angular/animations" "5.1.1" + "@angular/cdk" "5.0.1" + "@angular/common" "5.1.1" + "@angular/compiler" "5.1.1" + "@angular/core" "5.1.1" + "@angular/flex-layout" "2.0.0-beta.12" + "@angular/forms" "5.1.1" + "@angular/http" "5.1.1" + "@angular/material" "5.0.1" + "@angular/material-moment-adapter" "5.0.0" + "@angular/platform-browser" "5.1.1" + "@angular/platform-browser-dynamic" "5.1.1" + "@angular/router" "5.1.1" "@ngx-translate/core" "8.0.0" - alfresco-js-api "2.0.0" + alfresco-js-api "2.1.0-beta1" chart.js "2.5.0" core-js "2.4.1" hammerjs "2.0.8" @@ -35,25 +35,25 @@ systemjs "0.19.27" zone.js "0.8.14" -"@alfresco/adf-core@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@alfresco/adf-core/-/adf-core-2.0.0.tgz#7ad6c756cd5f8f44b0a1f31e6f8114d7c8f67101" +"@alfresco/adf-core@2.1.0-beta6": + version "2.1.0-beta6" + resolved "https://registry.yarnpkg.com/@alfresco/adf-core/-/adf-core-2.1.0-beta6.tgz#b71ef1d930f2b411c6f09d9ebfd16ba05951bf70" dependencies: - "@angular/animations" "5.0.0" - "@angular/cdk" "5.0.0-rc0" - "@angular/common" "5.0.0" - "@angular/compiler" "5.0.0" - "@angular/core" "5.0.0" - "@angular/flex-layout" "2.0.0-beta.10" - "@angular/forms" "5.0.0" - "@angular/http" "5.0.0" - "@angular/material" "5.0.0-rc0" - "@angular/material-moment-adapter" "^5.0.0-rc0" - "@angular/platform-browser" "5.0.0" - "@angular/platform-browser-dynamic" "5.0.0" - "@angular/router" "5.0.0" + "@angular/animations" "5.1.1" + "@angular/cdk" "5.0.1" + "@angular/common" "5.1.1" + "@angular/compiler" "5.1.1" + "@angular/core" "5.1.1" + "@angular/flex-layout" "2.0.0-beta.12" + "@angular/forms" "5.1.1" + "@angular/http" "5.1.1" + "@angular/material" "5.0.1" + "@angular/material-moment-adapter" "5.0.0" + "@angular/platform-browser" "5.1.1" + "@angular/platform-browser-dynamic" "5.1.1" + "@angular/router" "5.1.1" "@ngx-translate/core" "8.0.0" - alfresco-js-api "2.0.0" + alfresco-js-api "2.1.0-beta1" chart.js "2.5.0" core-js "2.4.1" hammerjs "2.0.8" @@ -82,6 +82,15 @@ dependencies: source-map "^0.5.6" +"@angular-devkit/core@^0.0.28": + version "0.0.28" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-0.0.28.tgz#840b6efa728bc3e93a1c469e482cf1095c96561f" + dependencies: + ajv "~5.5.1" + chokidar "^1.7.0" + rxjs "^5.5.6" + source-map "^0.5.6" + "@angular-devkit/schematics@~0.0.34": version "0.0.42" resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-0.0.42.tgz#34eea7136455545c8abd21edf94a36870a073fea" @@ -92,15 +101,15 @@ minimist "^1.2.0" rxjs "^5.5.2" -"@angular/animations@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-5.0.0.tgz#b5ad199c67f93f759544477effe6679e154991fb" +"@angular/animations@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-5.1.1.tgz#007621f8bcac15560e160582eb2e91025b6b9106" dependencies: tslib "^1.7.1" -"@angular/cdk@5.0.0-rc0": - version "5.0.0-rc0" - resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-5.0.0-rc0.tgz#b7225af1d8d23c13ac14bbd3fe1c6b427eb71368" +"@angular/cdk@5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-5.0.1.tgz#c85e662fe2e1c58abde1dea0f0f18cdfcffc2066" dependencies: tslib "^1.7.1" @@ -167,48 +176,48 @@ optionalDependencies: node-sass "^4.3.0" -"@angular/common@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-5.0.0.tgz#f96d66a517b995d1ba9b28309f15c2e359675825" +"@angular/common@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-5.1.1.tgz#b6444cf6508f9b0b5fc4c9b3107b3e37be1336c9" dependencies: tslib "^1.7.1" -"@angular/compiler-cli@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-5.0.0.tgz#0ecbb937d84a4f8dd94f0c2a47b07d2e4694c853" +"@angular/compiler-cli@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-5.1.1.tgz#579e6846ed493e7202e36eb5cea00cb1a61c927c" dependencies: chokidar "^1.4.2" minimist "^1.2.0" reflect-metadata "^0.1.2" - tsickle "^0.24.0" + tsickle "^0.25.5" -"@angular/compiler@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-5.0.0.tgz#b9ffbf18c8a39d8b7dacec473193a90e24cc2bc9" +"@angular/compiler@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-5.1.1.tgz#7d7953229739e68de74ea821685e1d5569527ef3" dependencies: tslib "^1.7.1" -"@angular/core@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-5.0.0.tgz#4f976a225f7dddf34992f2cad824c9543a46f4c8" +"@angular/core@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-5.1.1.tgz#b6a6e2b2284f86279f096d857253f6643098d908" dependencies: tslib "^1.7.1" -"@angular/flex-layout@2.0.0-beta.10": - version "2.0.0-beta.10" - resolved "https://registry.yarnpkg.com/@angular/flex-layout/-/flex-layout-2.0.0-beta.10.tgz#704e0626d6a92defbef2434e138e30f801fb2ad6" +"@angular/flex-layout@2.0.0-beta.12": + version "2.0.0-beta.12" + resolved "https://registry.yarnpkg.com/@angular/flex-layout/-/flex-layout-2.0.0-beta.12.tgz#80970dc1d60f27fa41537659926f3238f759f343" dependencies: tslib "^1.7.1" -"@angular/forms@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-5.0.0.tgz#c7fddfa35396759ae9852920a30cdda8c41ed1de" +"@angular/forms@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-5.1.1.tgz#e38858a44e7b57b61f375087b76a79d6e2679b14" dependencies: tslib "^1.7.1" -"@angular/http@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@angular/http/-/http-5.0.0.tgz#0728a2be0cfbb078727c5eb87d4c85d53fec9a51" +"@angular/http@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@angular/http/-/http-5.1.1.tgz#45aa61ee61f212a34f958c444c999e8c9352ec23" dependencies: tslib "^1.7.1" @@ -216,33 +225,33 @@ version "4.4.5" resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-4.4.5.tgz#ccef139b8d3e1684b01afa35c6fbf2172e2bb676" -"@angular/material-moment-adapter@^5.0.0-rc0": +"@angular/material-moment-adapter@5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@angular/material-moment-adapter/-/material-moment-adapter-5.0.0.tgz#08c2832f99be590397f43891347d35c6b035a4ae" + dependencies: + tslib "^1.7.1" + +"@angular/material@5.0.1": version "5.0.1" - resolved "https://registry.yarnpkg.com/@angular/material-moment-adapter/-/material-moment-adapter-5.0.1.tgz#058371d4d60bb91555bc89e9044c9e6412bbda71" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-5.0.1.tgz#73ff8af76daf7c7ec56092a613637b21deb5d00e" dependencies: tslib "^1.7.1" -"@angular/material@5.0.0-rc0": - version "5.0.0-rc0" - resolved "https://registry.yarnpkg.com/@angular/material/-/material-5.0.0-rc0.tgz#d37e104a284b41084f91e7613ac119cfb627c56d" +"@angular/platform-browser-dynamic@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.1.1.tgz#4b7bd1cbdb3c93fdeb626b38fbd54286a73a76d0" dependencies: tslib "^1.7.1" -"@angular/platform-browser-dynamic@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.0.0.tgz#887e106c8b103b0415cf6156a425da6d83f4c89d" +"@angular/platform-browser@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-5.1.1.tgz#88a05132d822b760c9108a3eaf0da610f39c2ed9" dependencies: tslib "^1.7.1" -"@angular/platform-browser@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-5.0.0.tgz#c7038f7cde80705b62014897231e182eec976fed" - dependencies: - tslib "^1.7.1" - -"@angular/router@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-5.0.0.tgz#fe4b521a6738408bce30f93a53499140c93a4f76" +"@angular/router@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-5.1.1.tgz#378e69edd28edadaff7b09b6ee407aadf7164220" dependencies: tslib "^1.7.1" @@ -369,6 +378,15 @@ ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" +ajv@~5.5.1: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + alfresco-js-api@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/alfresco-js-api/-/alfresco-js-api-2.0.0.tgz#a019b01d48200c36f8a0ea229c416260365eed49" @@ -376,6 +394,13 @@ alfresco-js-api@2.0.0: event-emitter "0.3.4" superagent "3.4.1" +alfresco-js-api@2.1.0-beta1: + version "2.1.0-beta1" + resolved "https://registry.yarnpkg.com/alfresco-js-api/-/alfresco-js-api-2.1.0-beta1.tgz#7c7a07a108dce7eb771166eac57fc0e2b77e4b79" + dependencies: + event-emitter "0.3.4" + superagent "3.8.2" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -717,6 +742,10 @@ blocking-proxy@^1.0.0: dependencies: minimist "^1.2.0" +bluebird@^2.3, bluebird@^2.9.x: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" + bluebird@^3.3.0, bluebird@^3.4.7, bluebird@^3.5.0: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -965,7 +994,7 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" -chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -1107,6 +1136,18 @@ coa@~1.0.1: dependencies: q "^1.1.2" +codacy-coverage@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/codacy-coverage/-/codacy-coverage-2.0.3.tgz#5635af71391d2f55c3fc284f72a13c2250c47c76" + dependencies: + bluebird "^2.9.x" + commander "^2.x" + joi "^6.4.x" + lcov-parse "0.x" + lodash "^4.17.4" + log-driver "^1.x" + request-promise "^0.x" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -1178,6 +1219,10 @@ commander@2.12.x, commander@^2.9.0, commander@~2.12.1: version "2.12.2" resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" +commander@^2.x: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + common-tags@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.5.1.tgz#e2e39931a013cd02253defeed89a1ad615a27f07" @@ -1281,7 +1326,7 @@ cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" -cookiejar@^2.0.6: +cookiejar@^2.0.6, cookiejar@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.1.tgz#41ad57b1b555951ec171412a81942b1e8200d34a" @@ -2305,7 +2350,7 @@ forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" -form-data@^2.1.1, form-data@~2.3.1: +form-data@^2.1.1, form-data@^2.3.1, form-data@~2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" dependencies: @@ -2321,7 +2366,7 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" -formidable@^1.0.17: +formidable@^1.0.17, formidable@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.1.1.tgz#96b8886f7c3c3508b932d6bd70c4d3a88f35f1a9" @@ -3139,6 +3184,10 @@ isbinaryfile@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621" +isemail@1.x.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/isemail/-/isemail-1.2.0.tgz#be03df8cc3e29de4d2c5df6501263f1fa4595e9a" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -3266,6 +3315,15 @@ jasminewd2@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/jasminewd2/-/jasminewd2-2.2.0.tgz#e37cf0b17f199cce23bea71b2039395246b4ec4e" +joi@^6.4.x: + version "6.10.1" + resolved "https://registry.yarnpkg.com/joi/-/joi-6.10.1.tgz#4d50c318079122000fe5f16af1ff8e1917b77e06" + dependencies: + hoek "2.x.x" + isemail "1.x.x" + moment "2.x.x" + topo "1.x.x" + js-base64@^2.1.5, js-base64@^2.1.8, js-base64@^2.1.9: version "2.4.0" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa" @@ -3479,6 +3537,10 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" +lcov-parse@0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" + less-loader@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.0.5.tgz#ae155a7406cac6acd293d785587fcff0f478c4dd" @@ -3587,7 +3649,7 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^3.8.0: +lodash@^3.10.0, lodash@^3.8.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" @@ -3595,6 +3657,10 @@ lodash@^4.0.0, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.3, l version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +log-driver@^1.x: + version "1.2.5" + resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" + log4js@^0.6.31: version "0.6.38" resolved "https://registry.yarnpkg.com/log4js/-/log4js-0.6.38.tgz#2c494116695d6fb25480943d3fc872e662a522fd" @@ -3840,6 +3906,10 @@ moment@2.15.2: version "2.15.2" resolved "https://registry.yarnpkg.com/moment/-/moment-2.15.2.tgz#1bfdedf6a6e345f322fe956d5df5bd08a8ce84dc" +moment@2.x.x: + version "2.20.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" + moment@~2.18.0: version "2.18.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" @@ -4792,7 +4862,7 @@ qjobs@^1.1.4: version "1.1.5" resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.1.5.tgz#659de9f2cf8dcc27a1481276f205377272382e73" -qs@6.5.1, qs@^6.1.0, qs@~6.5.1: +qs@6.5.1, qs@^6.1.0, qs@^6.5.1, qs@~6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" @@ -5043,7 +5113,16 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@2, request@^2.78.0: +request-promise@^0.x: + version "0.4.3" + resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-0.4.3.tgz#3c8ddc82f06f8908d720aede1d6794258e22121c" + dependencies: + bluebird "^2.3" + chalk "^1.1.0" + lodash "^3.10.0" + request "^2.34" + +request@2, request@^2.34, request@^2.78.0: version "2.83.0" resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" dependencies: @@ -5191,6 +5270,12 @@ rxjs@^5.5.2: dependencies: symbol-observable "1.0.1" +rxjs@^5.5.6: + version "5.5.6" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.6.tgz#e31fb96d6fd2ff1fd84bcea8ae9c02d007179c02" + dependencies: + symbol-observable "1.0.1" + safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -5737,6 +5822,21 @@ superagent@3.4.1: qs "^6.1.0" readable-stream "^2.0.5" +superagent@3.8.2: + version "3.8.2" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.2.tgz#e4a11b9d047f7d3efeb3bbe536d9ec0021d16403" + dependencies: + component-emitter "^1.2.0" + cookiejar "^2.1.0" + debug "^3.1.0" + extend "^3.0.0" + form-data "^2.3.1" + formidable "^1.1.1" + methods "^1.1.1" + mime "^1.4.1" + qs "^6.5.1" + readable-stream "^2.0.5" + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -5863,6 +5963,12 @@ to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" +topo@1.x.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/topo/-/topo-1.1.0.tgz#e9d751615d1bb87dc865db182fa1ca0a5ef536d5" + dependencies: + hoek "2.x.x" + toposort@^1.0.0: version "1.0.6" resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec" @@ -5913,9 +6019,9 @@ tsconfig@^6.0.0: strip-bom "^3.0.0" strip-json-comments "^2.0.0" -tsickle@^0.24.0: - version "0.24.1" - resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.24.1.tgz#039343b205bf517a333b0703978892f80a7d848e" +tsickle@^0.25.5: + version "0.25.6" + resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.25.6.tgz#b595db16b236721824eeeda8bb262365b47ef334" dependencies: minimist "^1.2.0" mkdirp "^0.5.1" From 890db215c8f1c3a1091334b930755b3f542a4d41 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 22 Jan 2018 13:22:33 +0000 Subject: [PATCH 23/69] readme update --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 769f9c32c..a26f95c42 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ## Introduction The Alfresco Content Application is an example application built using -[Alfresco Application Development Framework (ADF)](https://github.com/Alfresco/alfresco-ng2-components) components and was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.4.7. +[Alfresco Application Development Framework (ADF)](https://github.com/Alfresco/alfresco-ng2-components) components and was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.5.0. ### Who is this example application for @@ -19,6 +19,14 @@ with a simple and easy to use interface for working with files stored in the Alf [Public documentation](https://alfresco.github.io/alfresco-content-app/) +### Raising issues and feature requests + +Log any issues in the ['ACA' JIRA project](https://issues.alfresco.com/jira/projects/ACA), +please include a clear description, steps to reproduce and screenshots where appropriate. + +All issues will be reviewed; bugs will be categorized if reproducible and enhancement/feature suggestions +will be considered against existing priorities if the use case serves a general-purpose need. + ## Development server Run `npm start` for a dev server. Navigate to `http://localhost:3000/` (opens by default). From b5e394bc079503248aba70c320f4a5e9c8e7cc4d Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 23 Jan 2018 16:47:44 +0000 Subject: [PATCH 24/69] [ACA-591] unsharing links (#177) * unsharing links * restore move/delete buttons, new icon for unshare --- src/app/common/common.module.ts | 4 +- .../directives/node-unshare.directive.ts | 62 +++++++++++++++++++ .../shared-files/shared-files.component.html | 9 +++ .../shared-files/shared-files.component.ts | 1 + src/assets/i18n/en.json | 3 +- 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 src/app/common/directives/node-unshare.directive.ts diff --git a/src/app/common/common.module.ts b/src/app/common/common.module.ts index c23ad7a14..40cbbb33b 100644 --- a/src/app/common/common.module.ts +++ b/src/app/common/common.module.ts @@ -37,6 +37,7 @@ import { NodeMoveDirective } from './directives/node-move.directive'; import { DownloadFileDirective } from './directives/node-download.directive'; import { NodeRestoreDirective } from './directives/node-restore.directive'; import { NodePermanentDeleteDirective } from './directives/node-permanent-delete.directive'; +import { NodeUnshareDirective } from './directives/node-unshare.directive'; import { ContentManagementService } from './services/content-management.service'; import { BrowsingFilesService } from './services/browsing-files.service'; @@ -59,7 +60,8 @@ export function declarations() { NodeMoveDirective, DownloadFileDirective, NodeRestoreDirective, - NodePermanentDeleteDirective + NodePermanentDeleteDirective, + NodeUnshareDirective  ]; } diff --git a/src/app/common/directives/node-unshare.directive.ts b/src/app/common/directives/node-unshare.directive.ts new file mode 100644 index 000000000..ca1a454ed --- /dev/null +++ b/src/app/common/directives/node-unshare.directive.ts @@ -0,0 +1,62 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2017 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Directive, HostListener, Input, ElementRef } from '@angular/core'; +import { AlfrescoApiService } from '@alfresco/adf-core'; +import { MinimalNodeEntity } from 'alfresco-js-api'; + +@Directive({ + selector: '[appUnshareNode]' +}) +export class NodeUnshareDirective { + + // tslint:disable-next-line:no-input-rename + @Input('appUnshareNode') + selection: MinimalNodeEntity[]; + + constructor( + private apiService: AlfrescoApiService, + private el: ElementRef) { + } + + @HostListener('click') + onClick() { + if (this.selection.length > 0) { + this.unshareLinks(this.selection); + } + } + + private async unshareLinks(links: MinimalNodeEntity[]) { + const promises = links.map(link => this.apiService.sharedLinksApi.deleteSharedLink(link.entry.id)); + await Promise.all(promises); + this.emitDone(); + } + + private emitDone() { + const e = new CustomEvent('links-unshared', { bubbles: true }); + this.el.nativeElement.dispatchEvent(e); + } + +} diff --git a/src/app/components/shared-files/shared-files.component.html b/src/app/components/shared-files/shared-files.component.html index 2cfc02f49..94c39c37a 100644 --- a/src/app/components/shared-files/shared-files.component.html +++ b/src/app/components/shared-files/shared-files.component.html @@ -56,6 +56,15 @@ {{ 'APP.ACTIONS.MOVE' | translate }} + + diff --git a/src/app/components/files/files.component.html b/src/app/components/files/files.component.html index e68c71787..2c52b116d 100644 --- a/src/app/components/files/files.component.html +++ b/src/app/components/files/files.component.html @@ -19,7 +19,7 @@ mat-icon-button *ngIf="hasSelection(documentList.selection)" title="{{ 'APP.ACTIONS.DOWNLOAD' | translate }}" - [app-download-node]="documentList.selection"> + [adfNodeDownload]="documentList.selection"> get_app diff --git a/src/app/components/recent-files/recent-files.component.html b/src/app/components/recent-files/recent-files.component.html index b51490ca8..25d6ec207 100644 --- a/src/app/components/recent-files/recent-files.component.html +++ b/src/app/components/recent-files/recent-files.component.html @@ -17,7 +17,7 @@ mat-icon-button *ngIf="hasSelection(documentList.selection)" title="{{ 'APP.ACTIONS.DOWNLOAD' | translate }}" - [app-download-node]="documentList.selection"> + [adfNodeDownload]="documentList.selection"> get_app diff --git a/src/app/components/shared-files/shared-files.component.html b/src/app/components/shared-files/shared-files.component.html index 9a813a5d8..649176b2b 100644 --- a/src/app/components/shared-files/shared-files.component.html +++ b/src/app/components/shared-files/shared-files.component.html @@ -17,7 +17,7 @@ mat-icon-button *ngIf="hasSelection(documentList.selection)" title="{{ 'APP.ACTIONS.DOWNLOAD' | translate }}" - [app-download-node]="documentList.selection"> + [adfNodeDownload]="documentList.selection"> get_app From 0d727a5ffd922fdc425af47bfa3f60ea455d7496 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Tue, 20 Feb 2018 14:05:08 +0200 Subject: [PATCH 35/69] [ACA-1134] Shared Files - get user preference sorting (#191) --- src/app/components/shared-files/shared-files.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/components/shared-files/shared-files.component.ts b/src/app/components/shared-files/shared-files.component.ts index c77a57780..7db5f6808 100644 --- a/src/app/components/shared-files/shared-files.component.ts +++ b/src/app/components/shared-files/shared-files.component.ts @@ -52,8 +52,8 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes preferences: UserPreferencesService) { super(preferences); - const sortingKey = preferences.get('shared.sorting.key') || 'modifiedAt'; - const sortingDirection = preferences.get('shared.sorting.direction') || 'desc'; + const sortingKey = preferences.get('shared-files.sorting.key') || 'modifiedAt'; + const sortingDirection = preferences.get('shared-files.sorting.direction') || 'desc'; this.sorting = [sortingKey, sortingDirection]; } From 5234a875e716fecd6a7953c72c6ca939cbf0ea20 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 21 Feb 2018 06:00:58 +0000 Subject: [PATCH 36/69] [ACA-1135] spike on deleting nodes from the viewer (#192) * delete/restore from the viewer * rename content management service events * test fixes * offload node delete/restore to content service * improve tests --- .../common/directives/node-copy.directive.ts | 2 +- .../directives/node-delete.directive.spec.ts | 4 +- .../directives/node-delete.directive.ts | 4 +- .../common/directives/node-move.directive.ts | 4 +- .../services/content-management.service.ts | 71 ++++++++++++++++++- .../favorites/favorites.component.spec.ts | 2 +- .../favorites/favorites.component.ts | 6 +- .../components/files/files.component.spec.ts | 6 +- src/app/components/files/files.component.ts | 6 +- .../components/preview/preview.component.html | 9 +++ .../preview/preview.component.spec.ts | 16 +++-- .../components/preview/preview.component.ts | 20 +++++- .../recent-files.component.spec.ts | 6 +- .../recent-files/recent-files.component.ts | 6 +- .../shared-files.component.spec.ts | 6 +- .../shared-files/shared-files.component.ts | 6 +- .../sidenav/sidenav.component.spec.ts | 13 ++-- .../trashcan/trashcan.component.spec.ts | 2 +- .../components/trashcan/trashcan.component.ts | 2 +- 19 files changed, 147 insertions(+), 44 deletions(-) diff --git a/src/app/common/directives/node-copy.directive.ts b/src/app/common/directives/node-copy.directive.ts index 5cb250cce..bd68d573f 100644 --- a/src/app/common/directives/node-copy.directive.ts +++ b/src/app/common/directives/node-copy.directive.ts @@ -122,7 +122,7 @@ export class NodeCopyDirective { Observable.forkJoin(...batch) .subscribe( () => { - this.content.deleteNode.next(null); + this.content.nodeDeleted.next(null); }, (error) => { let i18nMessageString = 'APP.MESSAGES.ERRORS.GENERIC'; diff --git a/src/app/common/directives/node-delete.directive.spec.ts b/src/app/common/directives/node-delete.directive.spec.ts index 323bc281e..e263a8e94 100644 --- a/src/app/common/directives/node-delete.directive.spec.ts +++ b/src/app/common/directives/node-delete.directive.spec.ts @@ -229,7 +229,7 @@ describe('NodeDeleteDirective', () => { }); it('signals files restored', () => { - spyOn(contentService.restoreNode, 'next'); + spyOn(contentService.nodeRestored, 'next'); spyOn(nodeApiService, 'restoreNode').and.callFake((id) => { if (id === '1') { return Observable.of(null); @@ -246,7 +246,7 @@ describe('NodeDeleteDirective', () => { fixture.detectChanges(); element.triggerEventHandler('click', null); - expect(contentService.restoreNode.next).toHaveBeenCalled(); + expect(contentService.nodeRestored.next).toHaveBeenCalled(); }); }); }); diff --git a/src/app/common/directives/node-delete.directive.ts b/src/app/common/directives/node-delete.directive.ts index 42017244d..90e3bcd4a 100644 --- a/src/app/common/directives/node-delete.directive.ts +++ b/src/app/common/directives/node-delete.directive.ts @@ -74,7 +74,7 @@ export class NodeDeleteDirective { .subscribe(() => this.restore(processedData.success)); if (processedData.someSucceeded) { - this.content.deleteNode.next(null); + this.content.nodeDeleted.next(null); } }); } @@ -103,7 +103,7 @@ export class NodeDeleteDirective { } if (processedData.someSucceeded) { - this.content.restoreNode.next(null); + this.content.nodeRestored.next(null); } } ); diff --git a/src/app/common/directives/node-move.directive.ts b/src/app/common/directives/node-move.directive.ts index 6bb4bcbfe..678792eda 100644 --- a/src/app/common/directives/node-move.directive.ts +++ b/src/app/common/directives/node-move.directive.ts @@ -64,7 +64,7 @@ export class NodeMoveDirective { const [ operationResult, moveResponse ] = result; this.toastMessage(operationResult, moveResponse); - this.content.moveNode.next(null); + this.content.nodeMoved.next(null); }, (error) => { this.toastMessage(error); @@ -190,7 +190,7 @@ export class NodeMoveDirective { }) .subscribe( () => { - this.content.moveNode.next(null); + this.content.nodeMoved.next(null); }, (error) => { diff --git a/src/app/common/services/content-management.service.ts b/src/app/common/services/content-management.service.ts index 477a0e970..125876f5c 100644 --- a/src/app/common/services/content-management.service.ts +++ b/src/app/common/services/content-management.service.ts @@ -25,10 +25,75 @@ import { Subject } from 'rxjs/Rx'; import { Injectable } from '@angular/core'; +import { AlfrescoApiService, NotificationService, TranslationService } from '@alfresco/adf-core'; +import { Node } from 'alfresco-js-api'; + @Injectable() export class ContentManagementService { - deleteNode = new Subject(); - moveNode = new Subject(); - restoreNode = new Subject(); + + nodeDeleted = new Subject(); + nodeMoved = new Subject(); + nodeRestored = new Subject(); + + constructor(private api: AlfrescoApiService, + private notification: NotificationService, + private translation: TranslationService) { + } + + nodeHasPermission(node: Node, permission: string): boolean { + if (node && permission) { + const allowableOperations = node.allowableOperations || []; + + if (allowableOperations.indexOf(permission) > -1) { + return true; + } + } + + return false; + } + + canDeleteNode(node: Node): boolean { + return this.nodeHasPermission(node, 'delete'); + } + + async deleteNode(node: Node) { + if (this.canDeleteNode(node)) { + try { + await this.api.nodesApi.deleteNode(node.id); + + this.notification + .openSnackMessageAction( + this.translation.instant('APP.MESSAGES.INFO.NODE_DELETION.SINGULAR', { name: node.name }), + this.translation.translate.instant('APP.ACTIONS.UNDO'), + 10000 + ) + .onAction() + .subscribe(() => { + this.restoreNode(node); + }); + + this.nodeDeleted.next(node.id); + } catch { + this.notification.openSnackMessage( + this.translation.instant('APP.MESSAGES.ERRORS.NODE_DELETION', { name: node.name }), + 10000 + ); + } + } + } + + async restoreNode(node: Node) { + if (node) { + try { + await this.api.nodesApi.restoreNode(node.id); + this.nodeRestored.next(node.id); + } catch { + this.notification.openSnackMessage( + this.translation.instant('APP.MESSAGES.ERRORS.NODE_RESTORE', { name: node.name }), + 3000 + ); + } + } + } } diff --git a/src/app/components/favorites/favorites.component.spec.ts b/src/app/components/favorites/favorites.component.spec.ts index 8a0c2a189..0e1cfa73e 100644 --- a/src/app/components/favorites/favorites.component.spec.ts +++ b/src/app/components/favorites/favorites.component.spec.ts @@ -114,7 +114,7 @@ describe('Favorites Routed Component', () => { spyOn(component, 'refresh'); fixture.detectChanges(); - contentService.moveNode.next(null); + contentService.nodeMoved.next(null); expect(component.refresh).toHaveBeenCalled(); }); diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts index e1f0131d7..b3dcd385a 100644 --- a/src/app/components/favorites/favorites.component.ts +++ b/src/app/components/favorites/favorites.component.ts @@ -62,10 +62,10 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr ngOnInit() { this.subscriptions = this.subscriptions.concat([ - this.content.deleteNode.subscribe(() => this.refresh()), - this.content.restoreNode.subscribe(() => this.refresh()), + this.content.nodeDeleted.subscribe(() => this.refresh()), + this.content.nodeRestored.subscribe(() => this.refresh()), this.contentService.folderEdit.subscribe(() => this.refresh()), - this.content.moveNode.subscribe(() => this.refresh()) + this.content.nodeMoved.subscribe(() => this.refresh()) ]); } diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts index 1cf5d10bf..1538f5978 100644 --- a/src/app/components/files/files.component.spec.ts +++ b/src/app/components/files/files.component.spec.ts @@ -194,19 +194,19 @@ describe('FilesComponent', () => { }); it('calls refresh deleteNode event', () => { - contentManagementService.deleteNode.next(); + contentManagementService.nodeDeleted.next(); expect(component.load).toHaveBeenCalled(); }); it('calls refresh moveNode event', () => { - contentManagementService.moveNode.next(); + contentManagementService.nodeMoved.next(); expect(component.load).toHaveBeenCalled(); }); it('calls refresh restoreNode event', () => { - contentManagementService.restoreNode.next(); + contentManagementService.nodeRestored.next(); expect(component.load).toHaveBeenCalled(); }); diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index b8d650ae1..febb2936c 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -107,9 +107,9 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { nodeActionsService.contentCopied.subscribe((nodes) => this.onContentCopied(nodes)), contentService.folderCreate.subscribe(() => this.load(false, this.pagination)), contentService.folderEdit.subscribe(() => this.load(false, this.pagination)), - contentManagementService.deleteNode.subscribe(() => this.load(false, this.pagination)), - contentManagementService.moveNode.subscribe(() => this.load(false, this.pagination)), - contentManagementService.restoreNode.subscribe(() => this.load(false, this.pagination)), + contentManagementService.nodeDeleted.subscribe(() => this.load(false, this.pagination)), + contentManagementService.nodeMoved.subscribe(() => this.load(false, this.pagination)), + contentManagementService.nodeRestored.subscribe(() => this.load(false, this.pagination)), uploadService.fileUploadComplete.subscribe(file => this.onFileUploadedEvent(file)), uploadService.fileUploadDeleted.subscribe((file) => this.onFileUploadedEvent(file)) ]); diff --git a/src/app/components/preview/preview.component.html b/src/app/components/preview/preview.component.html index 2a537f83c..77925f753 100644 --- a/src/app/components/preview/preview.component.html +++ b/src/app/components/preview/preview.component.html @@ -8,5 +8,14 @@ (showViewerChange)="onVisibilityChanged($event)" (navigateBefore)="onNavigateBefore()" (navigateNext)="onNavigateNext()"> + + + + diff --git a/src/app/components/preview/preview.component.spec.ts b/src/app/components/preview/preview.component.spec.ts index d3398145e..a181ac4a6 100644 --- a/src/app/components/preview/preview.component.spec.ts +++ b/src/app/components/preview/preview.component.spec.ts @@ -353,7 +353,9 @@ describe('PreviewComponent', () => { component.previewLocation = 'personal-files'; await component.displayNode('folder1'); - expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith('folder1'); + expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith( + 'folder1', { include: [ 'allowableOperations' ] } + ); expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']); }); @@ -368,7 +370,9 @@ describe('PreviewComponent', () => { component.previewLocation = 'personal-files'; await component.displayNode('folder1'); - expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith('folder1'); + expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith( + 'folder1', { include: [ 'allowableOperations' ] } + ); expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']); }); @@ -381,7 +385,9 @@ describe('PreviewComponent', () => { component.previewLocation = 'personal-files'; await component.displayNode('folder1'); - expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith('folder1'); + expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith( + 'folder1', { include: [ 'allowableOperations' ] } + ); expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']); }); @@ -399,7 +405,9 @@ describe('PreviewComponent', () => { component.previewLocation = 'personal-files'; await component.displayNode('folder1'); - expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith('folder1'); + expect(alfrescoApi.nodesApi.getNodeInfo).toHaveBeenCalledWith( + 'folder1', { include: [ 'allowableOperations' ] } + ); expect(router.navigate).toHaveBeenCalledWith(['personal-files', 'folder1']); }); diff --git a/src/app/components/preview/preview.component.ts b/src/app/components/preview/preview.component.ts index 72e9ec1bd..b671b39a3 100644 --- a/src/app/components/preview/preview.component.ts +++ b/src/app/components/preview/preview.component.ts @@ -27,6 +27,7 @@ import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { AlfrescoApiService, UserPreferencesService, ObjectUtils } from '@alfresco/adf-core'; import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { ContentManagementService } from '../../common/services/content-management.service'; @Component({ selector: 'app-preview', @@ -53,7 +54,8 @@ export class PreviewComponent implements OnInit { constructor(private router: Router, private route: ActivatedRoute, private apiService: AlfrescoApiService, - private preferences: UserPreferencesService) { + private preferences: UserPreferencesService, + private content: ContentManagementService) { } ngOnInit() { @@ -90,7 +92,9 @@ export class PreviewComponent implements OnInit { async displayNode(id: string) { if (id) { try { - this.node = await this.apiService.nodesApi.getNodeInfo(id); + this.node = await this.apiService.nodesApi.getNodeInfo(id, { + include: [ 'allowableOperations'] + }); if (this.node && this.node.isFile) { const nearest = await this.getNearestNodes(this.node.id, this.node.parentId); @@ -315,4 +319,16 @@ export class PreviewComponent implements OnInit { } return path; } + + canDeleteFile(): boolean { + return this.content.canDeleteNode(this.node); + } + + async deleteFile() { + try { + await this.content.deleteNode(this.node); + this.onVisibilityChanged(false); + } catch { + } + } } diff --git a/src/app/components/recent-files/recent-files.component.spec.ts b/src/app/components/recent-files/recent-files.component.spec.ts index 5310cefec..c90ad6164 100644 --- a/src/app/components/recent-files/recent-files.component.spec.ts +++ b/src/app/components/recent-files/recent-files.component.spec.ts @@ -92,7 +92,7 @@ describe('RecentFiles Routed Component', () => { it('should reload nodes on onDeleteNode event', () => { fixture.detectChanges(); - contentService.deleteNode.next(); + contentService.nodeDeleted.next(); expect(component.refresh).toHaveBeenCalled(); }); @@ -100,7 +100,7 @@ describe('RecentFiles Routed Component', () => { it('should reload on onRestoreNode event', () => { fixture.detectChanges(); - contentService.restoreNode.next(); + contentService.nodeRestored.next(); expect(component.refresh).toHaveBeenCalled(); }); @@ -108,7 +108,7 @@ describe('RecentFiles Routed Component', () => { it('should reload on move node event', () => { fixture.detectChanges(); - contentService.moveNode.next(); + contentService.nodeMoved.next(); expect(component.refresh).toHaveBeenCalled(); }); diff --git a/src/app/components/recent-files/recent-files.component.ts b/src/app/components/recent-files/recent-files.component.ts index e127a2f5a..63601861f 100644 --- a/src/app/components/recent-files/recent-files.component.ts +++ b/src/app/components/recent-files/recent-files.component.ts @@ -60,9 +60,9 @@ export class RecentFilesComponent extends PageComponent implements OnInit, OnDes ngOnInit() { this.subscriptions = this.subscriptions.concat([ - this.content.deleteNode.subscribe(() => this.refresh()), - this.content.moveNode.subscribe(() => this.refresh()), - this.content.restoreNode.subscribe(() => this.refresh()) + this.content.nodeDeleted.subscribe(() => this.refresh()), + this.content.nodeMoved.subscribe(() => this.refresh()), + this.content.nodeRestored.subscribe(() => this.refresh()) ]); } diff --git a/src/app/components/shared-files/shared-files.component.spec.ts b/src/app/components/shared-files/shared-files.component.spec.ts index 064b4a9cd..cca450e60 100644 --- a/src/app/components/shared-files/shared-files.component.spec.ts +++ b/src/app/components/shared-files/shared-files.component.spec.ts @@ -89,7 +89,7 @@ describe('SharedFilesComponent', () => { it('should refresh on deleteNode event', () => { fixture.detectChanges(); - contentService.deleteNode.next(); + contentService.nodeDeleted.next(); expect(component.refresh).toHaveBeenCalled(); }); @@ -97,7 +97,7 @@ describe('SharedFilesComponent', () => { it('should refresh on restoreNode event', () => { fixture.detectChanges(); - contentService.restoreNode.next(); + contentService.nodeRestored.next(); expect(component.refresh).toHaveBeenCalled(); }); @@ -105,7 +105,7 @@ describe('SharedFilesComponent', () => { it('should reload on move node event', () => { fixture.detectChanges(); - contentService.moveNode.next(); + contentService.nodeMoved.next(); expect(component.refresh).toHaveBeenCalled(); }); diff --git a/src/app/components/shared-files/shared-files.component.ts b/src/app/components/shared-files/shared-files.component.ts index 7db5f6808..c3b3a940c 100644 --- a/src/app/components/shared-files/shared-files.component.ts +++ b/src/app/components/shared-files/shared-files.component.ts @@ -60,9 +60,9 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes ngOnInit() { this.subscriptions = this.subscriptions.concat([ - this.content.deleteNode.subscribe(() => this.refresh()), - this.content.moveNode.subscribe(() => this.refresh()), - this.content.restoreNode.subscribe(() => this.refresh()) + this.content.nodeDeleted.subscribe(() => this.refresh()), + this.content.nodeMoved.subscribe(() => this.refresh()), + this.content.nodeRestored.subscribe(() => this.refresh()) ]); } diff --git a/src/app/components/sidenav/sidenav.component.spec.ts b/src/app/components/sidenav/sidenav.component.spec.ts index 99899f67c..9d2ed7dcb 100644 --- a/src/app/components/sidenav/sidenav.component.spec.ts +++ b/src/app/components/sidenav/sidenav.component.spec.ts @@ -23,13 +23,14 @@ * along with Alfresco. If not, see . */ +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { TestBed, async } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; -import { ContentService, AppConfigService } from '@alfresco/adf-core'; + +import { CoreModule, ContentService, AppConfigService } from '@alfresco/adf-core'; import { BrowsingFilesService } from '../../common/services/browsing-files.service'; import { SidenavComponent } from './sidenav.component'; -import { CommonModule } from './../../common/common.module'; describe('SidenavComponent', () => { let fixture; @@ -50,11 +51,15 @@ describe('SidenavComponent', () => { TestBed.configureTestingModule({ imports: [ RouterTestingModule, - CommonModule + CoreModule ], declarations: [ SidenavComponent - ] + ], + providers: [ + BrowsingFilesService + ], + schemas: [ NO_ERRORS_SCHEMA ] }) .compileComponents() .then(() => { diff --git a/src/app/components/trashcan/trashcan.component.spec.ts b/src/app/components/trashcan/trashcan.component.spec.ts index 370c243fa..912bd6f2f 100644 --- a/src/app/components/trashcan/trashcan.component.spec.ts +++ b/src/app/components/trashcan/trashcan.component.spec.ts @@ -84,7 +84,7 @@ describe('TrashcanComponent', () => { spyOn(component, 'refresh'); fixture.detectChanges(); - contentService.restoreNode.next(); + contentService.nodeRestored.next(); expect(component.refresh).toHaveBeenCalled(); }); diff --git a/src/app/components/trashcan/trashcan.component.ts b/src/app/components/trashcan/trashcan.component.ts index 8c2852965..53dcf03ea 100644 --- a/src/app/components/trashcan/trashcan.component.ts +++ b/src/app/components/trashcan/trashcan.component.ts @@ -48,7 +48,7 @@ export class TrashcanComponent implements OnInit, OnDestroy { } ngOnInit() { - this.subscriptions.push(this.contentManagementService.restoreNode.subscribe(() => this.refresh())); + this.subscriptions.push(this.contentManagementService.nodeRestored.subscribe(() => this.refresh())); } refresh(): void { From ed2f91ee7cd5613e420eef80b0f7f15637e1c3d4 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 21 Feb 2018 13:21:59 +0000 Subject: [PATCH 37/69] [ACA-1137] Spike - Improving speed of unit tests (#193) * improve tests * improve tests * improve tests * improve tests --- .../directives/node-copy.directive.spec.ts | 40 +++++++++++++++++-- .../common/directives/node-copy.directive.ts | 2 +- .../services/node-actions.service.spec.ts | 32 +++++++++++++-- .../preview/preview.component.spec.ts | 28 +++++++++++-- 4 files changed, 89 insertions(+), 13 deletions(-) diff --git a/src/app/common/directives/node-copy.directive.spec.ts b/src/app/common/directives/node-copy.directive.spec.ts index f56990b65..a09b5dc54 100644 --- a/src/app/common/directives/node-copy.directive.spec.ts +++ b/src/app/common/directives/node-copy.directive.spec.ts @@ -29,11 +29,20 @@ import { By } from '@angular/platform-browser'; import { Observable } from 'rxjs/Rx'; -import { TranslationService, NodesApiService, NotificationService } from '@alfresco/adf-core'; +import { + TranslationService, NodesApiService, NotificationService, AlfrescoApiService, TranslationMock, + AppConfigService, StorageService, CookieService, ContentService, AuthenticationService, + UserPreferencesService, LogService, ThumbnailService +} from '@alfresco/adf-core'; +import { TranslateModule } from '@ngx-translate/core'; +import { HttpClientModule } from '@angular/common/http'; -import { CommonModule } from '../common.module'; import { NodeActionsService } from '../services/node-actions.service'; import { NodeCopyDirective } from './node-copy.directive'; +import { ContentManagementService } from '../services/content-management.service'; +import { MatSnackBarModule, MatDialogModule, MatIconModule } from '@angular/material'; +import { DocumentListService } from '@alfresco/adf-content-services'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; @Component({ template: '
' @@ -54,10 +63,33 @@ describe('NodeCopyDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [ - CommonModule + NoopAnimationsModule, + HttpClientModule, + TranslateModule.forRoot(), + MatSnackBarModule, + MatDialogModule, + MatIconModule ], declarations: [ - TestComponent + TestComponent, + NodeCopyDirective + ], + providers: [ + AlfrescoApiService, + AuthenticationService, + AppConfigService, + StorageService, + ContentService, + UserPreferencesService, + LogService, + CookieService, + NotificationService, + NodesApiService, + NodeActionsService, + { provide: TranslationService, useClass: TranslationMock }, + ContentManagementService, + DocumentListService, + ThumbnailService ] }); diff --git a/src/app/common/directives/node-copy.directive.ts b/src/app/common/directives/node-copy.directive.ts index bd68d573f..656865820 100644 --- a/src/app/common/directives/node-copy.directive.ts +++ b/src/app/common/directives/node-copy.directive.ts @@ -104,7 +104,7 @@ export class NodeCopyDirective { } catch (err) { /* Do nothing, keep the original message */ } } - const undo = (numberOfCopiedItems > 0) ? this.translation.translate.instant('APP.ACTIONS.UNDO') : ''; + const undo = (numberOfCopiedItems > 0) ? this.translation.instant('APP.ACTIONS.UNDO') : ''; const withUndo = (numberOfCopiedItems > 0) ? '_WITH_UNDO' : ''; this.translation.get(i18nMessageString, { success: numberOfCopiedItems, failed: failedItems }).subscribe(message => { diff --git a/src/app/common/services/node-actions.service.spec.ts b/src/app/common/services/node-actions.service.spec.ts index 3b17c02a1..71749b605 100644 --- a/src/app/common/services/node-actions.service.spec.ts +++ b/src/app/common/services/node-actions.service.spec.ts @@ -24,15 +24,21 @@ */ import { TestBed, async } from '@angular/core/testing'; -import { MatDialog } from '@angular/material'; +import { MatDialog, MatDialogModule, MatIconModule } from '@angular/material'; import { OverlayModule } from '@angular/cdk/overlay'; import { Observable } from 'rxjs/Rx'; -import { AlfrescoApiService, NodesApiService, TranslationService } from '@alfresco/adf-core'; +import { + TranslationMock, AlfrescoApiService, NodesApiService, + TranslationService, ContentService, AuthenticationService, + UserPreferencesService, AppConfigService, StorageService, + CookieService, LogService, ThumbnailService +} from '@alfresco/adf-core'; import { DocumentListService } from '@alfresco/adf-content-services'; -import { CommonModule } from '../common.module'; import { NodeActionsService } from './node-actions.service'; import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { TranslateModule } from '@ngx-translate/core'; +import { HttpClientModule } from '@angular/common/http'; class TestNode { entry?: MinimalNodeEntryEntity; @@ -104,8 +110,26 @@ describe('NodeActionsService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [ - CommonModule, + MatDialogModule, + MatIconModule, + HttpClientModule, + TranslateModule.forRoot(), OverlayModule + ], + providers: [ + AlfrescoApiService, + NodesApiService, + { provide: TranslationService, useClass: TranslationMock }, + AuthenticationService, + UserPreferencesService, + AppConfigService, + CookieService, + LogService, + ThumbnailService, + StorageService, + ContentService, + DocumentListService, + NodeActionsService ] }); diff --git a/src/app/components/preview/preview.component.spec.ts b/src/app/components/preview/preview.component.spec.ts index a181ac4a6..e653a9194 100644 --- a/src/app/components/preview/preview.component.spec.ts +++ b/src/app/components/preview/preview.component.spec.ts @@ -23,14 +23,21 @@ * along with Alfresco. If not, see . */ +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import { TestBed, async, ComponentFixture } from '@angular/core/testing'; -import { AlfrescoApiService, UserPreferencesService } from '@alfresco/adf-core'; +import { + AlfrescoApiService, UserPreferencesService, TranslationService, TranslationMock, + AppConfigService, StorageService, CookieService, NotificationService +} from '@alfresco/adf-core'; +import { TranslateModule } from '@ngx-translate/core'; +import { HttpClientModule } from '@angular/common/http'; -import { CommonModule } from '../../common/common.module'; import { PreviewComponent } from './preview.component'; import { Observable } from 'rxjs/Rx'; +import { ContentManagementService } from '../../common/services/content-management.service'; +import { MatSnackBarModule } from '@angular/material'; describe('PreviewComponent', () => { @@ -44,12 +51,25 @@ describe('PreviewComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ + HttpClientModule, RouterTestingModule, - CommonModule + TranslateModule.forRoot(), + MatSnackBarModule + ], + providers: [ + { provide: TranslationService, useClass: TranslationMock }, + AlfrescoApiService, + AppConfigService, + StorageService, + CookieService, + NotificationService, + UserPreferencesService, + ContentManagementService ], declarations: [ PreviewComponent - ] + ], + schemas: [ NO_ERRORS_SCHEMA ] }) .compileComponents().then(() => { fixture = TestBed.createComponent(PreviewComponent); From 8e0bcad285eed3a2a79ef0be3ed219dcdf501cb9 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 21 Feb 2018 16:52:47 +0000 Subject: [PATCH 38/69] upgrade to latest ADF (alpha) (#194) * upgrade to latest ADF (alpha) * upgrade js-api * workaround for alfresco-js-api build error --- karma.conf.js | 5 +- package-lock.json | 178 ++++++----- package.json | 8 +- .../ui/overrides/_alfresco-document-list.scss | 12 +- yarn.lock | 291 ++++-------------- 5 files changed, 175 insertions(+), 319 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index abe47fde7..2f0d566e0 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -55,6 +55,9 @@ module.exports = function (config) { captureTimeout: 180000, browserDisconnectTimeout: 180000, browserDisconnectTolerance: 3, - browserNoActivityTimeout: 300000 + browserNoActivityTimeout: 300000, + + // workaround for alfresco-js-api builds + webpack: { node: { fs: 'empty', } } }); }; diff --git a/package-lock.json b/package-lock.json index 81bc6e17c..3dff40747 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,11 +5,11 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "2.2.0-beta3", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.2.0-beta3.tgz", - "integrity": "sha512-WKkGcIPjzJeBzVQJ/RW4L74loOPaE//ut2pnh5e1P5yYFizdQlME4cH9ZGjHfDJUNOPW04Iwg/s7kFK0L2cwIQ==", + "version": "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e.tgz", + "integrity": "sha512-v43EdXIwX+pzYWH4lpw3Ed2tNzktS4vO+6cusFkNQMAbO1gQdti8GHevBm5IURPixvRly5sHnMvHrfPv3HNv9w==", "requires": { - "@alfresco/adf-core": "2.2.0-beta3", + "@alfresco/adf-core": "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e", "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", "@angular/common": "5.1.1", @@ -23,8 +23,8 @@ "@angular/platform-browser": "5.1.1", "@angular/platform-browser-dynamic": "5.1.1", "@angular/router": "5.1.1", - "@ngx-translate/core": "8.0.0", - "alfresco-js-api": "2.2.0-beta3", + "@ngx-translate/core": "9.1.1", + "alfresco-js-api": "2.2.0-c8f6736c571c52038c46b490892f96616b31662c", "chart.js": "2.5.0", "core-js": "2.4.1", "hammerjs": "2.0.8", @@ -61,9 +61,9 @@ } }, "@alfresco/adf-core": { - "version": "2.2.0-beta3", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.2.0-beta3.tgz", - "integrity": "sha512-LjdACStQTgV5mYBB0qoprZmMGBDHFdYsAENljol58+qj0GjevV67zSg5u/Scr+PghJIEQ93/NxfhFY+ElpZ4FA==", + "version": "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e.tgz", + "integrity": "sha512-Cz562GbqIMx0IDxXyVGLYKRg6AX6B9XcDV5diuCoJbFHugxgJkYWevl4Rqp4lL/tJ+zi5Q8MqPi0ZlHDvtxybg==", "requires": { "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", @@ -78,8 +78,8 @@ "@angular/platform-browser": "5.1.1", "@angular/platform-browser-dynamic": "5.1.1", "@angular/router": "5.1.1", - "@ngx-translate/core": "8.0.0", - "alfresco-js-api": "2.2.0-beta3", + "@ngx-translate/core": "9.1.1", + "alfresco-js-api": "2.2.0-c8f6736c571c52038c46b490892f96616b31662c", "chart.js": "2.5.0", "core-js": "2.4.1", "hammerjs": "2.0.8", @@ -231,7 +231,7 @@ "ember-cli-string-utils": "1.1.0", "exports-loader": "0.6.4", "extract-text-webpack-plugin": "3.0.2", - "file-loader": "1.1.6", + "file-loader": "1.1.8", "fs-extra": "4.0.3", "glob": "7.1.2", "html-webpack-plugin": "2.30.1", @@ -437,9 +437,9 @@ } }, "@ngx-translate/core": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-8.0.0.tgz", - "integrity": "sha1-dR/WtRLYDzp0jS3o38lt/vopr+A=" + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-9.1.1.tgz", + "integrity": "sha1-rhA5KINrip4Gn9Li52+iGYzH5ig=" }, "@schematics/angular": { "version": "0.1.17", @@ -617,9 +617,9 @@ "dev": true }, "alfresco-js-api": { - "version": "2.2.0-beta3", - "resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-2.2.0-beta3.tgz", - "integrity": "sha512-LRI8SezrvsJt+fIU5w5OHzyZ8fI2FmLLM9aq+rvQ9cXOr1DExvAu2T8Tg1a4AYdZESP8JvZXNx1ZvmBVnW1T5A==", + "version": "2.2.0-c8f6736c571c52038c46b490892f96616b31662c", + "resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-2.2.0-c8f6736c571c52038c46b490892f96616b31662c.tgz", + "integrity": "sha512-zq4e230d6RZyWvOvDJT1+l0uhwC3xj0DEJu+5lCS5UkZkCDktVguRxxhhlwuq/RWXrRprUSVYCtgI2zcSNdWag==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" @@ -988,7 +988,7 @@ "dev": true, "requires": { "browserslist": "2.11.3", - "caniuse-lite": "1.0.30000809", + "caniuse-lite": "1.0.30000810", "normalize-range": "0.1.2", "num2fraction": "1.2.2", "postcss": "6.0.19", @@ -1124,7 +1124,7 @@ "babylon": "6.18.0", "debug": "2.6.9", "globals": "9.18.0", - "invariant": "2.2.2", + "invariant": "2.2.3", "lodash": "4.17.5" }, "dependencies": { @@ -1662,7 +1662,7 @@ "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", "dev": true, "requires": { - "caniuse-lite": "1.0.30000809", + "caniuse-lite": "1.0.30000810", "electron-to-chromium": "1.3.33" } }, @@ -1820,7 +1820,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000809", + "caniuse-db": "1.0.30000810", "lodash.memoize": "4.1.2", "lodash.uniq": "4.5.0" }, @@ -1831,22 +1831,22 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000809", + "caniuse-db": "1.0.30000810", "electron-to-chromium": "1.3.33" } } } }, "caniuse-db": { - "version": "1.0.30000809", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000809.tgz", - "integrity": "sha1-sLiENKWY9AtUbUak29g5sP95j00=", + "version": "1.0.30000810", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000810.tgz", + "integrity": "sha1-vSWDDEHvq2Qzmi44H0lnc0PIRQk=", "dev": true }, "caniuse-lite": { - "version": "1.0.30000809", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000809.tgz", - "integrity": "sha512-tLn4flj2upmMsko3larTkQh21Vp9pylnNPUOhw5+mubL+67U5Fpm4UG5AutzGBc+gBIPSsPFHDynsiMWp5m46g==", + "version": "1.0.30000810", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000810.tgz", + "integrity": "sha512-/0Q00Oie9C72P8zQHtFvzmkrMC3oOFUnMWjCy5F2+BE8lzICm91hQPhh0+XIsAFPKOe2Dh3pKgbRmU3EKxfldA==", "dev": true }, "caseless": { @@ -7255,7 +7255,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000809", + "caniuse-db": "1.0.30000810", "normalize-range": "0.1.2", "num2fraction": "1.2.2", "postcss": "5.2.18", @@ -7268,7 +7268,7 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000809", + "caniuse-db": "1.0.30000810", "electron-to-chromium": "1.3.33" } }, @@ -8356,7 +8356,7 @@ "on-finished": "2.3.0", "parseurl": "1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.2", + "proxy-addr": "2.0.3", "qs": "6.5.1", "range-parser": "1.2.0", "safe-buffer": "5.1.1", @@ -8472,13 +8472,36 @@ } }, "file-loader": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.6.tgz", - "integrity": "sha512-873ztuL+/hfvXbLDJ262PGO6XjERnybJu2gW1/5j8HUfxSiFJI9Hj/DhZ50ZGRUxBvuNiazb/cM2rh9pqrxP6Q==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.8.tgz", + "integrity": "sha512-gVsHTw9n5Sp6U5vm5MmwMyKx4uOnlmDMwtWhXMdUmQJ7w3FgGaIjqPF2k4c8KZYhRd0Ltlt6mofRTv/NfqCLuA==", "dev": true, "requires": { "loader-utils": "1.1.0", - "schema-utils": "0.3.0" + "schema-utils": "0.4.5" + }, + "dependencies": { + "ajv": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.1.1.tgz", + "integrity": "sha1-l41Zf7wrfQ5aXD3esUmmgvKr+g4=", + "dev": true, + "requires": { + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "schema-utils": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", + "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", + "dev": true, + "requires": { + "ajv": "6.1.1", + "ajv-keywords": "3.1.0" + } + } } }, "file-uri-to-path": { @@ -10667,9 +10690,9 @@ "dev": true }, "invariant": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz", + "integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==", "dev": true, "requires": { "loose-envify": "1.3.1" @@ -10688,9 +10711,9 @@ "dev": true }, "ipaddr.js": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", - "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", + "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=", "dev": true }, "is-absolute-url": { @@ -11402,7 +11425,7 @@ "mime": "1.6.0", "minimatch": "3.0.4", "optimist": "0.6.1", - "qjobs": "1.1.5", + "qjobs": "1.2.0", "range-parser": "1.2.0", "rimraf": "2.6.2", "safe-buffer": "5.1.1", @@ -12445,7 +12468,7 @@ "is-windows": "1.0.2", "kind-of": "6.0.2", "object.pick": "1.3.0", - "regex-not": "1.0.0", + "regex-not": "1.0.2", "snapdragon": "0.8.1", "to-regex": "3.0.1" }, @@ -14438,7 +14461,7 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000809", + "caniuse-db": "1.0.30000810", "electron-to-chromium": "1.3.33" } }, @@ -15613,13 +15636,13 @@ } }, "proxy-addr": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", - "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", + "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", "dev": true, "requires": { "forwarded": "0.1.2", - "ipaddr.js": "1.5.2" + "ipaddr.js": "1.6.0" } }, "proxy-agent": { @@ -15717,9 +15740,9 @@ "dev": true }, "qjobs": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.1.5.tgz", - "integrity": "sha1-ZZ3p8s+NzCehSBJ28gU3cnI4LnM=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", "dev": true }, "qs": { @@ -16059,23 +16082,13 @@ } }, "regex-not": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.0.tgz", - "integrity": "sha1-Qvg+OXcWIt+CawKvF2Ul1qXxV/k=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "extend-shallow": "2.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" } }, "regexpu-core": { @@ -16274,6 +16287,12 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -16324,6 +16343,15 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "0.1.15" + } + }, "sass-graph": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", @@ -17731,7 +17759,7 @@ "requires": { "define-property": "0.2.5", "extend-shallow": "2.0.1", - "regex-not": "1.0.0" + "regex-not": "1.0.2" }, "dependencies": { "define-property": { @@ -19095,7 +19123,7 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "3.1.6", + "micromatch": "3.1.8", "normalize-path": "2.1.1" } }, @@ -19187,7 +19215,7 @@ "define-property": "0.2.5", "extend-shallow": "2.0.1", "posix-character-classes": "0.1.1", - "regex-not": "1.0.0", + "regex-not": "1.0.2", "snapdragon": "0.8.1", "to-regex": "3.0.1" }, @@ -19249,7 +19277,7 @@ "expand-brackets": "2.1.4", "extend-shallow": "2.0.1", "fragment-cache": "0.2.1", - "regex-not": "1.0.0", + "regex-not": "1.0.2", "snapdragon": "0.8.1", "to-regex": "3.0.1" }, @@ -19412,9 +19440,9 @@ "dev": true }, "micromatch": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.6.tgz", - "integrity": "sha512-6hezhKgmSIRZeSCiVB84GOmH1Ajvo8XgnaEq/uPQ/wv0g+MQlaVonSEru7VMDZXzRWFoclakpADfInbg/5FGjw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.8.tgz", + "integrity": "sha512-/XeuOQqYg+B5kwjDWekXseSwGS7CzE0w9Gjo4Cjkf/uFitNh47NrZHAY2vp/oS2YQVfebPIdbEIvgdy+kIcAog==", "dev": true, "requires": { "arr-diff": "4.0.0", @@ -19427,7 +19455,7 @@ "kind-of": "6.0.2", "nanomatch": "1.2.9", "object.pick": "1.3.0", - "regex-not": "1.0.0", + "regex-not": "1.0.2", "snapdragon": "0.8.1", "to-regex": "3.0.1" } diff --git a/package.json b/package.json index a4415a542..c519bd575 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "2.2.0-beta3", - "@alfresco/adf-core": "2.2.0-beta3", + "@alfresco/adf-content-services": "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e", + "@alfresco/adf-core": "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e", "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", "@angular/common": "5.1.1", @@ -33,8 +33,8 @@ "@angular/router": "5.1.1", "@mat-datetimepicker/core": "1.0.1", "@mat-datetimepicker/moment": "1.0.1", - "@ngx-translate/core": "8.0.0", - "alfresco-js-api": "2.2.0-beta3", + "@ngx-translate/core": "9.1.1", + "alfresco-js-api": "2.2.0-c8f6736c571c52038c46b490892f96616b31662c", "core-js": "2.5.3", "hammerjs": "2.0.8", "moment-es6": "1.0.0", diff --git a/src/app/ui/overrides/_alfresco-document-list.scss b/src/app/ui/overrides/_alfresco-document-list.scss index c0acf6fe9..07d6fe29e 100644 --- a/src/app/ui/overrides/_alfresco-document-list.scss +++ b/src/app/ui/overrides/_alfresco-document-list.scss @@ -15,14 +15,14 @@ adf-document-list { .adf-data-table { border: none !important; - th, tr, td { + .adf-datatable-header, .adf-datatable-row, .adf-data-table-cell { color: $alfresco-secondary-text-color; &:focus { outline: none !important; } } - tbody tr { + .adf-datatable-body .adf-datatable-row { &:hover, &:focus { background-color: $alfresco-app-color--hue-1; } @@ -32,7 +32,7 @@ adf-document-list { } } - td, th { + .adf-data-table-cell, .adf-datatable-header { width: 100%; text-align: left; } @@ -63,8 +63,8 @@ adf-document-list { border: none !important; } - th:first-of-type, th.adf-data-table-cell--image, - td:first-of-type, td.adf-data-table-cell--image { + .adf-datatable-header:first-of-type, .adf-datatable-header.adf-data-table-cell--image, + .adf-data-table-cell:first-of-type, .adf-data-table-cell.adf-data-table-cell--image { padding-left: 24px; padding-right: 0; width: 10px; @@ -98,7 +98,7 @@ adf-document-list { .adf-data-table { height: 100%; - tr:hover, tr:focus { + .adf-datatable-row:hover, .adf-datatable-row:focus { background-color: unset; cursor: default; } diff --git a/yarn.lock b/yarn.lock index 80119c972..25fe4f4fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,11 @@ # yarn lockfile v1 -"@alfresco/adf-content-services@2.2.0-beta3": - version "2.2.0-beta3" - resolved "https://registry.yarnpkg.com/@alfresco/adf-content-services/-/adf-content-services-2.2.0-beta3.tgz#26151b855326f85870ae16636e35ac1df75f9432" +"@alfresco/adf-content-services@2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e": + version "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e" + resolved "https://registry.yarnpkg.com/@alfresco/adf-content-services/-/adf-content-services-2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e.tgz#18619e3d1b4552c9229fc36c7e467ef004c71d0c" dependencies: - "@alfresco/adf-core" "2.2.0-beta3" + "@alfresco/adf-core" "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e" "@angular/animations" "5.1.1" "@angular/cdk" "5.0.1" "@angular/common" "5.1.1" @@ -20,8 +20,8 @@ "@angular/platform-browser" "5.1.1" "@angular/platform-browser-dynamic" "5.1.1" "@angular/router" "5.1.1" - "@ngx-translate/core" "8.0.0" - alfresco-js-api "2.2.0-beta3" + "@ngx-translate/core" "9.1.1" + alfresco-js-api "2.2.0-c8f6736c571c52038c46b490892f96616b31662c" chart.js "2.5.0" core-js "2.4.1" hammerjs "2.0.8" @@ -36,9 +36,9 @@ tslib "^1.7.1" zone.js "0.8.14" -"@alfresco/adf-core@2.2.0-beta3": - version "2.2.0-beta3" - resolved "https://registry.yarnpkg.com/@alfresco/adf-core/-/adf-core-2.2.0-beta3.tgz#c529e1f49e4ed0701da0ad7b7c61288aaea485cf" +"@alfresco/adf-core@2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e": + version "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e" + resolved "https://registry.yarnpkg.com/@alfresco/adf-core/-/adf-core-2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e.tgz#6beed6b05d485d50b25e92ad477a263ec747a464" dependencies: "@angular/animations" "5.1.1" "@angular/cdk" "5.0.1" @@ -53,8 +53,8 @@ "@angular/platform-browser" "5.1.1" "@angular/platform-browser-dynamic" "5.1.1" "@angular/router" "5.1.1" - "@ngx-translate/core" "8.0.0" - alfresco-js-api "2.2.0-beta3" + "@ngx-translate/core" "9.1.1" + alfresco-js-api "2.2.0-c8f6736c571c52038c46b490892f96616b31662c" chart.js "2.5.0" core-js "2.4.1" hammerjs "2.0.8" @@ -274,9 +274,9 @@ tree-kill "^1.0.0" webpack-sources "^1.1.0" -"@ngx-translate/core@8.0.0": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-8.0.0.tgz#751fd6b512d80f3a748d2de8dfc96dfefa29afe0" +"@ngx-translate/core@9.1.1": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-9.1.1.tgz#ae103928836b8a9e069fd2e2e76fa2198cc7e628" "@schematics/angular@~0.1.17": version "0.1.17" @@ -412,9 +412,9 @@ ajv@^6.1.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" -alfresco-js-api@2.2.0-beta3: - version "2.2.0-beta3" - resolved "https://registry.yarnpkg.com/alfresco-js-api/-/alfresco-js-api-2.2.0-beta3.tgz#1bdc0a6df4482b5470553eef4743a1615f9da11d" +alfresco-js-api@2.2.0-c8f6736c571c52038c46b490892f96616b31662c: + version "2.2.0-c8f6736c571c52038c46b490892f96616b31662c" + resolved "https://registry.yarnpkg.com/alfresco-js-api/-/alfresco-js-api-2.2.0-c8f6736c571c52038c46b490892f96616b31662c.tgz#0f395db73ff2d2b41e5c24617e9defa8c52760f5" dependencies: event-emitter "0.3.4" superagent "3.8.2" @@ -599,10 +599,6 @@ asn1.js@^4.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" -asn1@0.1.11: - version "0.1.11" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7" - asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -611,10 +607,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" -assert-plus@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160" - assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" @@ -661,10 +653,6 @@ async@^2.1.2, async@^2.1.4, async@^2.1.5, async@^2.4.1, async@^2.5.0: dependencies: lodash "^4.14.0" -async@~0.9.0: - version "0.9.2" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" - async@~2.1.2: version "2.1.5" resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" @@ -701,10 +689,6 @@ autoprefixer@^7.2.3: postcss "^6.0.17" postcss-value-parser "^3.2.3" -aws-sign2@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.5.0.tgz#c57103f7a17fc037f02d7c2e64b602ea223f7d63" - aws-sign2@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" @@ -860,12 +844,6 @@ bitsyntax@~0.0.4: dependencies: buffer-more-ints "0.0.2" -bl@~0.9.0: - version "0.9.5" - resolved "https://registry.yarnpkg.com/bl/-/bl-0.9.5.tgz#c06b797af085ea00bc527afc8efcf11de2232054" - dependencies: - readable-stream "~1.0.26" - bl@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" @@ -930,12 +908,6 @@ boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" -boom@0.4.x: - version "0.4.2" - resolved "https://registry.yarnpkg.com/boom/-/boom-0.4.2.tgz#7a636e9ded4efcefb19cef4947a3c67dfaee911b" - dependencies: - hoek "0.9.x" - boom@2.x.x: version "2.10.1" resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" @@ -1262,12 +1234,12 @@ caniuse-api@^1.5.2: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000809" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000809.tgz#b0b88434a598f40b546d46a4dbd839b0ff798f4d" + version "1.0.30000810" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000810.tgz#bd25830c41efab64339a2e381f49677343c84509" caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805: - version "1.0.30000809" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000809.tgz#1e12c1344b8f74d56737ee2614bcedb648943479" + version "1.0.30000810" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000810.tgz#47585fffce0e9f3593a6feea4673b945424351d9" caseless@~0.11.0: version "0.11.0" @@ -1277,10 +1249,6 @@ caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" -caseless@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.6.0.tgz#8167c1ab8397fb5bb95f96d28e5a81c50f247ac4" - center-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" @@ -1477,13 +1445,6 @@ code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" -codecov.io@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/codecov.io/-/codecov.io-0.0.1.tgz#25ea2b095e1e9ea11872bdfa5842118130df78b1" - dependencies: - request "2.42.0" - urlgrey "0.4.0" - codelyzer@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-4.1.0.tgz#3117754538d8f5ffa36dff91d340573a836cf373" @@ -1572,12 +1533,6 @@ combined-stream@1.0.6, combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -combined-stream@~0.0.4: - version "0.0.7" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-0.0.7.tgz#0137e657baa5a7541c57ac37ac5fc07d73b4dc1f" - dependencies: - delayed-stream "0.0.5" - commander@2.14.x, commander@^2.12.1, commander@^2.9.0, commander@^2.x, commander@~2.14.1: version "2.14.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" @@ -1801,12 +1756,6 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cryptiles@0.2.x: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-0.2.2.tgz#ed91ff1f17ad13d3748288594f8a48a0d26f325c" - dependencies: - boom "0.4.x" - cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -1937,10 +1886,6 @@ csso@~2.3.1: clap "^1.0.9" source-map "^0.5.3" -ctype@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f" - cuint@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" @@ -2019,10 +1964,6 @@ deep-equal@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" -deep-equal@~0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.1.2.tgz#b246c2b80a570a47c11be1d9bd1070ec878b87ce" - deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" @@ -2067,10 +2008,6 @@ defined@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" -defined@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-0.0.0.tgz#f35eea7d705e933baf13b2f03b3f83d921403b3e" - degenerator@~1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" @@ -2102,10 +2039,6 @@ del@^3.0.0: pify "^3.0.0" rimraf "^2.2.8" -delayed-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-0.0.5.tgz#d4b1f43a93e8296dfe02694f4680bc37a313c73f" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -2274,10 +2207,6 @@ duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: dependencies: readable-stream "^2.0.2" -duplexer@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - duplexify@^3.4.2, duplexify@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e" @@ -2750,11 +2679,11 @@ faye-websocket@~0.11.0: websocket-driver ">=0.5.1" file-loader@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.6.tgz#7b9a8f2c58f00a77fddf49e940f7ac978a3ea0e8" + version "1.1.8" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.8.tgz#a62592ed732667d7482dc3268c381c7f0c913086" dependencies: loader-utils "^1.0.2" - schema-utils "^0.3.0" + schema-utils "^0.4.5" file-uri-to-path@1: version "1.0.0" @@ -2864,10 +2793,6 @@ foreach@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" -forever-agent@~0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.5.2.tgz#6d0e09c4921f94a27f63d3b49c5feff1ea4c5130" - forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -2880,14 +2805,6 @@ form-data@^2.3.1, form-data@~2.3.1: combined-stream "1.0.6" mime-types "^2.1.12" -form-data@~0.1.0: - version "0.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.1.4.tgz#91abd788aba9702b1aabfa8bc01031a2ac9e3b12" - dependencies: - async "~0.9.0" - combined-stream "~0.0.4" - mime "~1.2.11" - form-data@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.0.0.tgz#6f0aebadcc5da16c13e1ecc11137d85f9b883b25" @@ -3297,15 +3214,6 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" -hawk@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-1.1.1.tgz#87cd491f9b46e4e2aeaca335416766885d2d1ed9" - dependencies: - boom "0.4.x" - cryptiles "0.2.x" - hoek "0.9.x" - sntp "0.2.x" - hawk@3.1.3, hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -3343,10 +3251,6 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoek@0.9.x: - version "0.9.1" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-0.9.1.tgz#3d322462badf07716ea7eb85baf88079cddce505" - hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" @@ -3460,14 +3364,6 @@ http-proxy@^1.13.0, http-proxy@^1.16.2: eventemitter3 "1.x.x" requires-port "1.x.x" -http-signature@~0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-0.10.1.tgz#4fbdac132559aa8323121e540779c0a012b27e66" - dependencies: - asn1 "0.1.11" - assert-plus "^0.1.5" - ctype "0.5.3" - http-signature@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" @@ -3627,8 +3523,8 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" invariant@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + version "2.2.3" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.3.tgz#1a827dfde7dcbd7c323f0ca826be8fa7c5e9d688" dependencies: loose-envify "^1.0.0" @@ -3644,9 +3540,9 @@ ip@^1.1.0, ip@^1.1.2, ip@^1.1.4, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" -ipaddr.js@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0" +ipaddr.js@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b" is-absolute-url@^2.0.0: version "2.1.0" @@ -4118,7 +4014,7 @@ json-stable-stringify@~0.0.0: dependencies: jsonify "~0.0.0" -json-stringify-safe@5.0.x, json-stringify-safe@~5.0.0, json-stringify-safe@~5.0.1: +json-stringify-safe@5.0.x, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -4460,10 +4356,8 @@ lodash@^4.0.0, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, l resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" log-driver@^1.x: - version "1.2.6" - resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.6.tgz#ad0e660f56bbc59aeb2784d92854cdfdac55807b" - dependencies: - codecov.io "0.0.1" + version "1.2.7" + resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" log4js@^2.3.9: version "2.5.3" @@ -4653,8 +4547,8 @@ micromatch@^2.1.5, micromatch@^2.3.11: regex-cache "^0.4.2" micromatch@^3.1.4: - version "3.1.6" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.6.tgz#8d7c043b48156f408ca07a4715182b79b99420bf" + version "3.1.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.8.tgz#5c8caa008de588eebb395e8c0ad12c128f25fff1" dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -4687,10 +4581,6 @@ mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.16, mime-types@~2.1.17, dependencies: mime-db "~1.33.0" -mime-types@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-1.0.2.tgz#995ae1392ab8affcbfcb2641dd054e943c0d5dce" - mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" @@ -4699,10 +4589,6 @@ mime@^1.2.11, mime@^1.3.4, mime@^1.4.1, mime@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" -mime@~1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10" - mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -4977,7 +4863,7 @@ node-sass@^4.7.2: stdout-stream "^1.4.0" "true-case-path" "^1.0.2" -node-uuid@~1.4.0, node-uuid@~1.4.7: +node-uuid@~1.4.7: version "1.4.8" resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" @@ -5104,10 +4990,6 @@ number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -oauth-sign@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.4.0.tgz#f22956f31ea7151a821e5f2fb32c113cad8b9f69" - oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" @@ -5859,11 +5741,11 @@ protractor@~5.1.2: webdriver-manager "^12.0.6" proxy-addr@~2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec" + version "2.0.3" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" dependencies: forwarded "~0.1.2" - ipaddr.js "1.5.2" + ipaddr.js "1.6.0" proxy-agent@~2.0.0: version "2.0.0" @@ -5928,17 +5810,13 @@ q@^1.1.2, q@^1.4.1: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" qjobs@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.1.5.tgz#659de9f2cf8dcc27a1481276f205377272382e73" + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" qs@6.5.1, qs@^6.5.1, qs@~6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" -qs@~1.2.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-1.2.2.tgz#19b57ff24dc2a99ce1f8bdf6afcda59f8ef61f88" - qs@~6.2.0: version "6.2.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.3.tgz#1cfcb25c10a9b2b483053ff39f5dfc9233908cfe" @@ -6080,7 +5958,7 @@ read-pkg@^2.0.0: string_decoder "~1.0.3" util-deprecate "~1.0.1" -readable-stream@1.0, readable-stream@~1.0.26: +readable-stream@1.0: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" dependencies: @@ -6178,10 +6056,11 @@ regex-cache@^0.4.2: is-equal-shallow "^0.1.3" regex-not@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.0.tgz#42f83e39771622df826b02af176525d6a5f157f9" + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" dependencies: - extend-shallow "^2.0.1" + extend-shallow "^3.0.2" + safe-regex "^1.1.0" regexpu-core@^1.0.0: version "1.0.0" @@ -6273,27 +6152,6 @@ request@2, request@^2.0.0, request@^2.34, request@^2.74.0, request@^2.78.0: tunnel-agent "^0.6.0" uuid "^3.1.0" -request@2.42.0: - version "2.42.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.42.0.tgz#572bd0148938564040ac7ab148b96423a063304a" - dependencies: - bl "~0.9.0" - caseless "~0.6.0" - forever-agent "~0.5.0" - json-stringify-safe "~5.0.0" - mime-types "~1.0.1" - node-uuid "~1.4.0" - qs "~1.2.0" - tunnel-agent "~0.4.0" - optionalDependencies: - aws-sign2 "~0.5.0" - form-data "~0.1.0" - hawk "1.1.1" - http-signature "~0.10.0" - oauth-sign "~0.4.0" - stringstream "~0.0.4" - tough-cookie ">=0.12.0" - request@2.75.x: version "2.75.0" resolved "https://registry.yarnpkg.com/request/-/request-2.75.0.tgz#d2b8268a286da13eaa5d01adf5d18cc90f657d93" @@ -6421,11 +6279,9 @@ resolve@^1.1.3, resolve@^1.1.4, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.2: dependencies: path-parse "^1.0.5" -resumer@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" - dependencies: - through "~2.3.4" +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" right-align@^0.1.1: version "0.1.3" @@ -6468,6 +6324,12 @@ safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, s version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + sass-graph@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" @@ -6511,7 +6373,7 @@ schema-utils@^0.3.0: dependencies: ajv "^5.0.0" -schema-utils@^0.4.0, schema-utils@^0.4.2: +schema-utils@^0.4.0, schema-utils@^0.4.2, schema-utils@^0.4.5: version "0.4.5" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e" dependencies: @@ -6759,12 +6621,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^2.0.0" -sntp@0.2.x: - version "0.2.4" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-0.2.4.tgz#fb885f18b0f3aad189f824862536bceeec750900" - dependencies: - hoek "0.9.x" - sntp@1.x.x: version "1.0.9" resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" @@ -6969,12 +6825,6 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" -split@~0.2.10: - version "0.2.10" - resolved "https://registry.yarnpkg.com/split/-/split-0.2.10.tgz#67097c601d697ce1368f418f06cd201cf0521a57" - dependencies: - through "2" - sprintf-js@^1.0.3: version "1.1.1" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c" @@ -7038,12 +6888,6 @@ stream-combiner2@^1.1.1: duplexer2 "~0.1.0" readable-stream "^2.0.2" -stream-combiner@~0.0.2: - version "0.0.4" - resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" - dependencies: - duplexer "~0.1.1" - stream-each@^1.1.0: version "1.2.2" resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" @@ -7254,19 +7098,6 @@ tapable@^0.2.7: version "0.2.8" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" -tape@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/tape/-/tape-2.3.0.tgz#0dfeec709227fbcc9170abe7f046962b271431db" - dependencies: - deep-equal "~0.1.0" - defined "~0.0.0" - inherits "~2.0.1" - jsonify "~0.0.0" - resumer "~0.0.0" - split "~0.2.10" - stream-combiner "~0.0.2" - through "~2.3.4" - tar-pack@^3.4.0: version "3.4.1" resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" @@ -7295,7 +7126,7 @@ through2@^2.0.0: readable-stream "^2.1.5" xtend "~4.0.1" -through@2, "through@>=2.2.7 <3", through@X.X.X, through@~2.3.4: +"through@>=2.2.7 <3", through@X.X.X: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -7386,7 +7217,7 @@ toposort@^1.0.0: version "1.0.6" resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec" -tough-cookie@>=0.12.0, tough-cookie@~2.3.0, tough-cookie@~2.3.3: +tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" dependencies: @@ -7488,7 +7319,7 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tunnel-agent@~0.4.0, tunnel-agent@~0.4.1: +tunnel-agent@~0.4.1: version "0.4.3" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" @@ -7685,12 +7516,6 @@ url@^0.11.0, url@~0.11.0: punycode "1.3.2" querystring "0.2.0" -urlgrey@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.0.tgz#f065357040fb35c3b311d4e5dc36484d96dbea06" - dependencies: - tape "2.3.0" - use@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/use/-/use-2.0.2.tgz#ae28a0d72f93bf22422a18a2e379993112dec8e8" From 3cbb7fa065c181b4a017af5bdd896b728edde4f7 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Thu, 22 Feb 2018 22:24:31 +0200 Subject: [PATCH 39/69] route defined preference data prefix (#195) --- src/app/app.routes.ts | 21 +++++++++++++++++-- .../favorites/favorites.component.ts | 12 +++++++---- src/app/components/files/files.component.ts | 12 +++++++---- .../libraries/libraries.component.ts | 12 +++++++---- .../recent-files/recent-files.component.ts | 12 +++++++---- .../shared-files/shared-files.component.ts | 12 +++++++---- .../trashcan/trashcan.component.spec.ts | 3 ++- .../components/trashcan/trashcan.component.ts | 18 +++++++++++----- 8 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index ffd5f2d50..5f466094c 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -59,6 +59,9 @@ export const APP_ROUTES: Routes = [ }, { path: 'favorites', + data: { + preferencePrefix: 'favorites' + }, children: [ { path: '', @@ -80,6 +83,9 @@ export const APP_ROUTES: Routes = [ }, { path: 'libraries', + data: { + preferencePrefix: 'libraries' + }, children: [{ path: '', component: LibrariesComponent, @@ -90,7 +96,8 @@ export const APP_ROUTES: Routes = [ path: ':folderId', component: FilesComponent, data: { - i18nTitle: 'APP.BROWSE.LIBRARIES.TITLE' + i18nTitle: 'APP.BROWSE.LIBRARIES.TITLE', + preferencePrefix: 'libraries-files' } }, { @@ -106,6 +113,9 @@ export const APP_ROUTES: Routes = [ }, { path: 'personal-files', + data: { + preferencePrefix: 'personal-files' + }, children: [ { path: '', @@ -144,6 +154,9 @@ export const APP_ROUTES: Routes = [ }, { path: 'recent-files', + data: { + preferencePrefix: 'recent-files' + }, children: [ { path: '', @@ -165,6 +178,9 @@ export const APP_ROUTES: Routes = [ }, { path: 'shared', + data: { + preferencePrefix: 'shared-files' + }, children: [ { path: '', @@ -188,7 +204,8 @@ export const APP_ROUTES: Routes = [ path: 'trashcan', component: TrashcanComponent, data: { - i18nTitle: 'APP.BROWSE.TRASHCAN.TITLE' + i18nTitle: 'APP.BROWSE.TRASHCAN.TITLE', + preferencePrefix: 'trashcan' } }, { diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts index b3dcd385a..1d656df89 100644 --- a/src/app/components/favorites/favorites.component.ts +++ b/src/app/components/favorites/favorites.component.ts @@ -54,8 +54,8 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr preferences: UserPreferencesService) { super(preferences); - const sortingKey = preferences.get('favorites.sorting.key') || 'modifiedAt'; - const sortingDirection = preferences.get('favorites.sorting.direction') || 'desc'; + const sortingKey = preferences.get(`${this.prefix}.sorting.key`) || 'modifiedAt'; + const sortingDirection = preferences.get(`${this.prefix}.sorting.direction`) || 'desc'; this.sorting = [sortingKey, sortingDirection]; } @@ -118,7 +118,11 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr } onSortingChanged(event: CustomEvent) { - this.preferences.set('favorites.sorting.key', event.detail.key || 'modifiedAt'); - this.preferences.set('favorites.sorting.direction', event.detail.direction || 'desc'); + this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'modifiedAt'); + this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc'); + } + + private get prefix() { + return this.route.snapshot.data.preferencePrefix; } } diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index febb2936c..04e3032d0 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -64,8 +64,8 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { preferences: UserPreferencesService) { super(preferences); - const sortingKey = preferences.get('personal-files.sorting.key') || 'modifiedAt'; - const sortingDirection = preferences.get('personal-files.sorting.direction') || 'desc'; + const sortingKey = this.preferences.get(`${this.prefix}.sorting.key`) || 'modifiedAt'; + const sortingDirection = this.preferences.get(`${this.prefix}.sorting.direction`) || 'desc'; this.sorting = [sortingKey, sortingDirection]; } @@ -309,7 +309,11 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { } onSortingChanged(event: CustomEvent) { - this.preferences.set('personal-files.sorting.key', event.detail.key || 'modifiedAt'); - this.preferences.set('personal-files.sorting.direction', event.detail.direction || 'desc'); + this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'modifiedAt'); + this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc'); + } + + private get prefix() { + return this.route.snapshot.data.preferencePrefix; } } diff --git a/src/app/components/libraries/libraries.component.ts b/src/app/components/libraries/libraries.component.ts index 2c14279c4..8f3c503a2 100644 --- a/src/app/components/libraries/libraries.component.ts +++ b/src/app/components/libraries/libraries.component.ts @@ -46,8 +46,8 @@ export class LibrariesComponent extends PageComponent { preferences: UserPreferencesService) { super(preferences); - const sortingKey = preferences.get('libraries.sorting.key') || 'title'; - const sortingDirection = preferences.get('libraries.sorting.direction') || 'desc'; + const sortingKey = preferences.get(`${this.prefix}.sorting.key`) || 'title'; + const sortingDirection = preferences.get(`${this.prefix}.sorting.direction`) || 'desc'; this.sorting = [sortingKey, sortingDirection]; } @@ -98,7 +98,11 @@ export class LibrariesComponent extends PageComponent { } onSortingChanged(event: CustomEvent) { - this.preferences.set('libraries.sorting.key', event.detail.key || 'modifiedAt'); - this.preferences.set('libraries.sorting.direction', event.detail.direction || 'desc'); + this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'modifiedAt'); + this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc'); + } + + private get prefix() { + return this.route.snapshot.data.preferencePrefix; } } diff --git a/src/app/components/recent-files/recent-files.component.ts b/src/app/components/recent-files/recent-files.component.ts index 63601861f..69a64aa05 100644 --- a/src/app/components/recent-files/recent-files.component.ts +++ b/src/app/components/recent-files/recent-files.component.ts @@ -52,8 +52,8 @@ export class RecentFilesComponent extends PageComponent implements OnInit, OnDes preferences: UserPreferencesService) { super(preferences); - const sortingKey = preferences.get('recent-files.sorting.key') || 'modifiedAt'; - const sortingDirection = preferences.get('recent-files.sorting.direction') || 'desc'; + const sortingKey = preferences.get(`${this.prefix}.sorting.key`) || 'modifiedAt'; + const sortingDirection = preferences.get(`${this.prefix}.sorting.direction`) || 'desc'; this.sorting = [sortingKey, sortingDirection]; } @@ -90,7 +90,11 @@ export class RecentFilesComponent extends PageComponent implements OnInit, OnDes } onSortingChanged(event: CustomEvent) { - this.preferences.set('recent-files.sorting.key', event.detail.key || 'modifiedAt'); - this.preferences.set('recent-files.sorting.direction', event.detail.direction || 'desc'); + this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'modifiedAt'); + this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc'); + } + + private get prefix() { + return this.route.snapshot.data.preferencePrefix; } } diff --git a/src/app/components/shared-files/shared-files.component.ts b/src/app/components/shared-files/shared-files.component.ts index c3b3a940c..2c0eaaa52 100644 --- a/src/app/components/shared-files/shared-files.component.ts +++ b/src/app/components/shared-files/shared-files.component.ts @@ -52,8 +52,8 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes preferences: UserPreferencesService) { super(preferences); - const sortingKey = preferences.get('shared-files.sorting.key') || 'modifiedAt'; - const sortingDirection = preferences.get('shared-files.sorting.direction') || 'desc'; + const sortingKey = preferences.get(`${this.prefix}.sorting.key`) || 'modifiedAt'; + const sortingDirection = preferences.get(`${this.prefix}.sorting.direction`) || 'desc'; this.sorting = [sortingKey, sortingDirection]; } @@ -99,7 +99,11 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes } onSortingChanged(event: CustomEvent) { - this.preferences.set('shared-files.sorting.key', event.detail.key || 'modifiedAt'); - this.preferences.set('shared-files.sorting.direction', event.detail.direction || 'desc'); + this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'modifiedAt'); + this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc'); + } + + private get prefix() { + return this.route.snapshot.data.preferencePrefix; } } diff --git a/src/app/components/trashcan/trashcan.component.spec.ts b/src/app/components/trashcan/trashcan.component.spec.ts index 912bd6f2f..0ec8dc934 100644 --- a/src/app/components/trashcan/trashcan.component.spec.ts +++ b/src/app/components/trashcan/trashcan.component.spec.ts @@ -22,7 +22,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ - +import { RouterTestingModule } from '@angular/router/testing'; import { TestBed, async } from '@angular/core/testing'; import { CoreModule, AlfrescoApiService } from '@alfresco/adf-core'; import { TrashcanComponent } from './trashcan.component'; @@ -49,6 +49,7 @@ describe('TrashcanComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ + RouterTestingModule, CoreModule, CommonModule ], diff --git a/src/app/components/trashcan/trashcan.component.ts b/src/app/components/trashcan/trashcan.component.ts index 53dcf03ea..ccbf3a7b6 100644 --- a/src/app/components/trashcan/trashcan.component.ts +++ b/src/app/components/trashcan/trashcan.component.ts @@ -24,6 +24,7 @@ */ import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Rx'; import { Pagination } from 'alfresco-js-api'; import { UserPreferencesService } from '@alfresco/adf-core'; @@ -41,9 +42,12 @@ export class TrashcanComponent implements OnInit, OnDestroy { sorting = [ 'archivedAt', 'desc' ]; constructor(private contentManagementService: ContentManagementService, - private preferences: UserPreferencesService) { - const sortingKey = preferences.get('trashcan.sorting.key') || 'archivedAt'; - const sortingDirection = preferences.get('trashcan.sorting.direction') || 'desc'; + private preferences: UserPreferencesService, + private route: ActivatedRoute) { + + const sortingKey = preferences.get(`${this.prefix}.sorting.key`) || 'archivedAt'; + const sortingDirection = preferences.get(`${this.prefix}.sorting.direction`) || 'desc'; + this.sorting = [sortingKey, sortingDirection]; } @@ -65,7 +69,11 @@ export class TrashcanComponent implements OnInit, OnDestroy { } onSortingChanged(event: CustomEvent) { - this.preferences.set('trashcan.sorting.key', event.detail.key || 'archivedAt'); - this.preferences.set('trashcan.sorting.direction', event.detail.direction || 'desc'); + this.preferences.set(`${this.prefix}.sorting.key`, event.detail.key || 'archivedAt'); + this.preferences.set(`${this.prefix}.sorting.direction`, event.detail.direction || 'desc'); + } + + private get prefix() { + return this.route.snapshot.data.preferencePrefix; } } From 5a51567c0663900c8db078f7b6ec652a510d3dfe Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 23 Feb 2018 10:44:43 +0000 Subject: [PATCH 40/69] upgrade to latest ADF alpha (#196) --- package-lock.json | 78 +++++++++---------- package.json | 4 +- .../ui/overrides/_alfresco-document-list.scss | 13 +--- yarn.lock | 46 +++++------ 4 files changed, 68 insertions(+), 73 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3dff40747..62e723c8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,11 +5,11 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e.tgz", - "integrity": "sha512-v43EdXIwX+pzYWH4lpw3Ed2tNzktS4vO+6cusFkNQMAbO1gQdti8GHevBm5IURPixvRly5sHnMvHrfPv3HNv9w==", + "version": "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66.tgz", + "integrity": "sha512-7tiXcRoQM3q7XAtHFYal8ZR0v/mNQ6yCD/Brw6J21vkSEro4PSIKtpyUPCdh9uqxPOzshkXQ/PsdYJiLh01EdA==", "requires": { - "@alfresco/adf-core": "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e", + "@alfresco/adf-core": "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66", "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", "@angular/common": "5.1.1", @@ -61,9 +61,9 @@ } }, "@alfresco/adf-core": { - "version": "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e.tgz", - "integrity": "sha512-Cz562GbqIMx0IDxXyVGLYKRg6AX6B9XcDV5diuCoJbFHugxgJkYWevl4Rqp4lL/tJ+zi5Q8MqPi0ZlHDvtxybg==", + "version": "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66.tgz", + "integrity": "sha512-/38VJQX1d+C+fWyyVJIQb/M72nnDeVRbTeLfwc71+9ifdYegtYxHb97A5lQW0kVKD5lfbmub/SiUfdA6X4i1Kw==", "requires": { "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", @@ -225,13 +225,13 @@ "common-tags": "1.7.2", "copy-webpack-plugin": "4.4.1", "core-object": "3.1.5", - "css-loader": "0.28.9", + "css-loader": "0.28.10", "cssnano": "3.10.0", "denodeify": "1.2.1", "ember-cli-string-utils": "1.1.0", "exports-loader": "0.6.4", "extract-text-webpack-plugin": "3.0.2", - "file-loader": "1.1.8", + "file-loader": "1.1.9", "fs-extra": "4.0.3", "glob": "7.1.2", "html-webpack-plugin": "2.30.1", @@ -268,7 +268,7 @@ "webpack": "3.10.0", "webpack-dev-middleware": "1.12.2", "webpack-dev-server": "2.11.1", - "webpack-merge": "4.1.1", + "webpack-merge": "4.1.2", "webpack-sources": "1.1.0", "webpack-subresource-integrity": "1.0.4" }, @@ -1663,7 +1663,7 @@ "dev": true, "requires": { "caniuse-lite": "1.0.30000810", - "electron-to-chromium": "1.3.33" + "electron-to-chromium": "1.3.34" } }, "buffer": { @@ -1832,7 +1832,7 @@ "dev": true, "requires": { "caniuse-db": "1.0.30000810", - "electron-to-chromium": "1.3.33" + "electron-to-chromium": "1.3.34" } } } @@ -7075,9 +7075,9 @@ "dev": true }, "css-loader": { - "version": "0.28.9", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.9.tgz", - "integrity": "sha512-r3dgelMm/mkPz5Y7m9SeiGE46i2VsEU/OYbez+1llfxtv8b2y5/b5StaeEvPK3S5tlNQI+tDW/xDIhKJoZgDtw==", + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.10.tgz", + "integrity": "sha512-X1IJteKnW9Llmrd+lJ0f7QZHh9Arf+11S7iRcoT2+riig3BK0QaCaOtubAulMK6Itbo08W6d3l8sW21r+Jhp5Q==", "dev": true, "requires": { "babel-code-frame": "6.26.0", @@ -7269,7 +7269,7 @@ "dev": true, "requires": { "caniuse-db": "1.0.30000810", - "electron-to-chromium": "1.3.33" + "electron-to-chromium": "1.3.34" } }, "chalk": { @@ -7800,9 +7800,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.33", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.33.tgz", - "integrity": "sha1-vwBwPWKnxlI4E2V4w1LWxcBCpUU=", + "version": "1.3.34", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz", + "integrity": "sha1-2TSY9AORuwwWpgPYJBuZUUBBV+0=", "dev": true }, "elliptic": { @@ -8472,9 +8472,9 @@ } }, "file-loader": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.8.tgz", - "integrity": "sha512-gVsHTw9n5Sp6U5vm5MmwMyKx4uOnlmDMwtWhXMdUmQJ7w3FgGaIjqPF2k4c8KZYhRd0Ltlt6mofRTv/NfqCLuA==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.9.tgz", + "integrity": "sha512-6ql03hOSoJHBkTB+3De/f7NJse+JXkUwvAf3y4Q5rIcTD0kqJiE3btvLnDcZT+P4t1QYLb9dJ9EI4auzfo3wFA==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -8742,7 +8742,7 @@ "dev": true, "optional": true, "requires": { - "nan": "2.8.0", + "nan": "2.9.2", "node-pre-gyp": "0.6.39" }, "dependencies": { @@ -10230,7 +10230,7 @@ "ncname": "1.0.0", "param-case": "2.1.1", "relateurl": "0.2.7", - "uglify-js": "3.3.11" + "uglify-js": "3.3.12" } }, "html-webpack-plugin": { @@ -12447,9 +12447,9 @@ "dev": true }, "nan": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", - "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.9.2.tgz", + "integrity": "sha512-ltW65co7f3PQWBDbqVvaU1WtFJUsNW7sWWm4HINhbMQIyVyzIeyZ8toX5TC5eeooE6piZoaEh4cZkueSKG3KYw==", "dev": true, "optional": true }, @@ -12656,7 +12656,7 @@ "lodash.mergewith": "4.6.1", "meow": "3.7.0", "mkdirp": "0.5.1", - "nan": "2.8.0", + "nan": "2.9.2", "node-gyp": "3.6.2", "npmlog": "4.1.2", "request": "2.79.0", @@ -14462,7 +14462,7 @@ "dev": true, "requires": { "caniuse-db": "1.0.30000810", - "electron-to-chromium": "1.3.33" + "electron-to-chromium": "1.3.34" } }, "chalk": { @@ -18048,7 +18048,7 @@ "resolve": "1.5.0", "semver": "5.5.0", "tslib": "1.9.0", - "tsutils": "2.21.1" + "tsutils": "2.21.2" }, "dependencies": { "chalk": { @@ -18087,9 +18087,9 @@ "optional": true }, "tsutils": { - "version": "2.21.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.21.1.tgz", - "integrity": "sha512-heMkdeQ9iUc90ynfiNo5Y+GXrEEGy86KMvnSTfHO+Q40AuNQ1lZGXcv58fuU9XTUxI0V7YIN9xPN+CO9b1Gn3w==", + "version": "2.21.2", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.21.2.tgz", + "integrity": "sha512-iaIuyjIUeFLdD39MYdzqBuY7Zv6+uGxSwRH4mf+HuzsnznjFz0R2tGrAe0/JvtNh91WrN8UN/DZRFTZNDuVekA==", "dev": true, "requires": { "tslib": "1.9.0" @@ -18149,9 +18149,9 @@ "dev": true }, "uglify-js": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.11.tgz", - "integrity": "sha512-AKLsYcdV+sS5eAE4NtVXF6f2u/DCQynQm0jTGxF261+Vltu1dYNuHzjqDmk11gInj+H/zJIM2EAwXG3MzPb3VA==", + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.12.tgz", + "integrity": "sha512-4jxrTXlV0HaXTsNILfXW0eey7Qo8qHYM6ih5ZNh45erDWU2GHmKDmekwBTskDb12h+kdd2DBvdzqVb47YzNmTA==", "dev": true, "requires": { "commander": "2.14.1", @@ -19508,9 +19508,9 @@ } }, "webpack-merge": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.1.tgz", - "integrity": "sha512-geQsZ86YkXOVOjvPC5yv3JSNnL6/X3Kzh935AQ/gJNEYXEfJDQFu/sdFuktS9OW2JcH/SJec8TGfRdrpHshH7A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.2.tgz", + "integrity": "sha512-/0QYwW/H1N/CdXYA2PNPVbsxO3u2Fpz34vs72xm03SRfg6bMNGfMJIQEpQjKRvkG2JvT6oRJFpDtSrwbX8Jzvw==", "dev": true, "requires": { "lodash": "4.17.5" diff --git a/package.json b/package.json index c519bd575..1f0c480e1 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e", - "@alfresco/adf-core": "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e", + "@alfresco/adf-content-services": "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66", + "@alfresco/adf-core": "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66", "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", "@angular/common": "5.1.1", diff --git a/src/app/ui/overrides/_alfresco-document-list.scss b/src/app/ui/overrides/_alfresco-document-list.scss index 07d6fe29e..7b9042a8c 100644 --- a/src/app/ui/overrides/_alfresco-document-list.scss +++ b/src/app/ui/overrides/_alfresco-document-list.scss @@ -22,6 +22,10 @@ adf-document-list { } } + .adf-datatable-table-cell-header:focus { + outline: none !important; + } + .adf-datatable-body .adf-datatable-row { &:hover, &:focus { background-color: $alfresco-app-color--hue-1; @@ -37,15 +41,6 @@ adf-document-list { text-align: left; } - .adf-data-table__header--sorted-asc, - .adf-data-table__header--sorted-desc { - &:hover { - &:before { - color: inherit !important; - } - } - } - .app-location-link, .adf-location-cell { a { diff --git a/yarn.lock b/yarn.lock index 25fe4f4fc..afb2b317a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,11 @@ # yarn lockfile v1 -"@alfresco/adf-content-services@2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e": - version "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e" - resolved "https://registry.yarnpkg.com/@alfresco/adf-content-services/-/adf-content-services-2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e.tgz#18619e3d1b4552c9229fc36c7e467ef004c71d0c" +"@alfresco/adf-content-services@2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66": + version "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66" + resolved "https://registry.yarnpkg.com/@alfresco/adf-content-services/-/adf-content-services-2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66.tgz#df3f2c96d50993fb1b001e8579ff152949ff248e" dependencies: - "@alfresco/adf-core" "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e" + "@alfresco/adf-core" "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66" "@angular/animations" "5.1.1" "@angular/cdk" "5.0.1" "@angular/common" "5.1.1" @@ -36,9 +36,9 @@ tslib "^1.7.1" zone.js "0.8.14" -"@alfresco/adf-core@2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e": - version "2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e" - resolved "https://registry.yarnpkg.com/@alfresco/adf-core/-/adf-core-2.2.0-ec3b208b846713143f0ce2786ace108bd37a752e.tgz#6beed6b05d485d50b25e92ad477a263ec747a464" +"@alfresco/adf-core@2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66": + version "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66" + resolved "https://registry.yarnpkg.com/@alfresco/adf-core/-/adf-core-2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66.tgz#580f75587cf103c784507ee84e28a17072184f6f" dependencies: "@angular/animations" "5.1.1" "@angular/cdk" "5.0.1" @@ -1789,8 +1789,8 @@ css-color-names@0.0.4: resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" css-loader@^0.28.1: - version "0.28.9" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.9.tgz#68064b85f4e271d7ce4c48a58300928e535d1c95" + version "0.28.10" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.10.tgz#40282e79230f7bcb4e483efa631d670b735ebf42" dependencies: babel-code-frame "^6.26.0" css-selector-tokenizer "^0.7.0" @@ -2231,8 +2231,8 @@ ejs@^2.5.7: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30: - version "1.3.33" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.33.tgz#bf00703d62a7c65238136578c352d6c5c042a545" + version "1.3.34" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz#d93498f40391bb0c16a603d8241b9951404157ed" elliptic@^6.0.0: version "6.4.0" @@ -2679,8 +2679,8 @@ faye-websocket@~0.11.0: websocket-driver ">=0.5.1" file-loader@^1.1.5: - version "1.1.8" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.8.tgz#a62592ed732667d7482dc3268c381c7f0c913086" + version "1.1.9" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.9.tgz#cf152aedbcfb3d67038d0845efb7cf11a96e53de" dependencies: loader-utils "^1.0.2" schema-utils "^0.4.5" @@ -4351,7 +4351,7 @@ lodash@^3.10.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.0.0, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.5.0, lodash@~4.17.4: +lodash@^4.0.0, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.5.0, lodash@~4.17.4: version "4.17.5" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" @@ -4719,8 +4719,8 @@ multicast-dns@^6.0.1: thunky "^1.0.2" nan@^2.3.0, nan@^2.3.2: - version "2.8.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" + version "2.9.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.9.2.tgz#f564d75f5f8f36a6d9456cca7a6c4fe488ab7866" nanomatch@^1.2.9: version "1.2.9" @@ -7300,8 +7300,8 @@ tsscmp@~1.0.0: resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.5.tgz#7dc4a33af71581ab4337da91d85ca5427ebd9a97" tsutils@^2.12.1: - version "2.21.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.21.1.tgz#5b23c263233300ed7442b4217855cbc7547c296a" + version "2.21.2" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.21.2.tgz#902aa5987e1440c47673543d96752df8d44ab9c7" dependencies: tslib "^1.8.1" @@ -7360,8 +7360,8 @@ uglify-es@^3.3.4: source-map "~0.6.1" uglify-js@3.3.x: - version "3.3.11" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.11.tgz#e9d058b20715138bb4e8e5cae2ea581686bdaae3" + version "3.3.12" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.12.tgz#efd87c16a1f4c674a8a5ede571001ef634dcc883" dependencies: commander "~2.14.1" source-map "~0.6.1" @@ -7695,10 +7695,10 @@ webpack-dev-server@~2.11.0: yargs "6.6.0" webpack-merge@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.1.tgz#f1197a0a973e69c6fbeeb6d658219aa8c0c13555" + version "4.1.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.2.tgz#5d372dddd3e1e5f8874f5bf5a8e929db09feb216" dependencies: - lodash "^4.17.4" + lodash "^4.17.5" webpack-sources@^1.0.0, webpack-sources@^1.0.1, webpack-sources@^1.1.0: version "1.1.0" From bdaafe6b6cd55e385597153277f6cff2a55b586e Mon Sep 17 00:00:00 2001 From: suzanadirla Date: Fri, 23 Feb 2018 13:19:01 +0200 Subject: [PATCH 41/69] [ACA-1053] [Destination picker] User should not be able to copy / move items into a site outside of the documentLibrary [ADF-2077] (#197) --- src/app/common/services/node-actions.service.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/app/common/services/node-actions.service.ts b/src/app/common/services/node-actions.service.ts index 9edd073dc..d05832076 100644 --- a/src/app/common/services/node-actions.service.ts +++ b/src/app/common/services/node-actions.service.ts @@ -205,7 +205,7 @@ export class NodeActionsService { dropdownSiteList: customDropdown, rowFilter: this.rowFilter.bind(this), imageResolver: this.imageResolver.bind(this), - isSelectionValid: this.hasEntityCreatePermission.bind(this), + isSelectionValid: this.canCopyMoveInsideIt.bind(this), select: new Subject() }; @@ -247,10 +247,18 @@ export class NodeActionsService { return this.translation.instant(`NODE_SELECTOR.${action.toUpperCase()}_${keyPrefix}`, {name}); } + private canCopyMoveInsideIt(entry: MinimalNodeEntryEntity): boolean { + return this.hasEntityCreatePermission(entry) && !this.isSite(entry); + } + private hasEntityCreatePermission(entry: MinimalNodeEntryEntity): boolean { return this.contentService.hasPermission(entry, 'create'); } + private isSite(entry) { + return !!entry.guid || entry.nodeType === 'st:site' || entry.nodeType === 'st:sites'; + } + close() { this.dialog.closeAll(); } From 114455e5c9ffeee254a6646ae65cbd94d7fcce01 Mon Sep 17 00:00:00 2001 From: suzanadirla Date: Fri, 23 Feb 2018 16:55:48 +0200 Subject: [PATCH 42/69] [ACA-863][Destination picker] User can see the entire repository by using the breadcrumb instead of just his Personal Files (#198) added a breadcrumbTransform function to customize the display of the breadcrumb as needed used similar approach as on page breadcrumb --- .../common/services/node-actions.service.ts | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/app/common/services/node-actions.service.ts b/src/app/common/services/node-actions.service.ts index d05832076..318b44da4 100644 --- a/src/app/common/services/node-actions.service.ts +++ b/src/app/common/services/node-actions.service.ts @@ -206,6 +206,7 @@ export class NodeActionsService { rowFilter: this.rowFilter.bind(this), imageResolver: this.imageResolver.bind(this), isSelectionValid: this.canCopyMoveInsideIt.bind(this), + breadcrumbTransform: this.customizeBreadcrumb.bind(this), select: new Subject() }; @@ -263,6 +264,73 @@ export class NodeActionsService { this.dialog.closeAll(); } + // todo: review this approach once 5.2.3 is out + private customizeBreadcrumb(node: MinimalNodeEntryEntity) { + + if (node && node.path && node.path.elements) { + const elements = node.path.elements; + + if (elements.length > 1) { + if (elements[1].name === 'User Homes') { + elements.splice(0, 2); + + // make sure first item is 'Personal Files' + if (elements[0]) { + elements[0].name = this.translation.instant('APP.BROWSE.PERSONAL.TITLE'); + elements[0].id = '-my-'; + } else { + node.name = this.translation.instant('APP.BROWSE.PERSONAL.TITLE'); + } + + } else if (elements[1].name === 'Sites') { + this.normalizeSitePath(node); + } + + } else if (elements.length === 1) { + if (node.name === 'Sites') { + node.name = this.translation.instant('APP.BROWSE.LIBRARIES.TITLE'); + elements.splice(0, 1); + } + } + } + + return node; + } + + // todo: review this approach once 5.2.3 is out + private normalizeSitePath(node: MinimalNodeEntryEntity) { + const elements = node.path.elements; + + // remove 'Company Home' + elements.splice(0, 1); + + // replace first item with 'File Libraries' + elements[0].name = this.translation.instant('APP.BROWSE.LIBRARIES.TITLE'); + // elements[0].id = '-mysites-'; // commented this until navigation on custom sources is enabled on document-list + + if (this.isSiteContainer(node)) { + // rename 'documentLibrary' entry to the target site display name + // clicking on the breadcrumb entry loads the site content + node.name = elements[1].name; + + // remove the site entry + elements.splice(1, 1); + } else { + // remove 'documentLibrary' in the middle of the path + const docLib = elements.findIndex(el => el.name === 'documentLibrary'); + if (docLib > -1) { + elements.splice(docLib, 1); + } + } + } + + isSiteContainer(node: MinimalNodeEntryEntity): boolean { + if (node && node.aspectNames && node.aspectNames.length > 0) { + return node.aspectNames.indexOf('st:siteContainer') >= 0; + } + return false; + } + copyNodeAction(nodeEntry, selectionId): Observable { if (nodeEntry.isFolder) { return this.copyFolderAction(nodeEntry, selectionId); From 4d7b6d3271b7b5523f799c949bb401a653d8fbb4 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Fri, 23 Feb 2018 18:25:59 +0200 Subject: [PATCH 43/69] Browsing Files - unit tests granular dependencies (#199) --- .../favorites/favorites.component.spec.ts | 111 ++++++++++++++--- .../components/files/files.component.spec.ts | 115 ++++++++++++++++-- .../libraries/libraries.component.spec.ts | 85 +++++++++++-- .../recent-files.component.spec.ts | 90 ++++++++++++-- .../shared-files.component.spec.ts | 87 +++++++++++-- .../trashcan/trashcan.component.spec.ts | 87 +++++++++++-- 6 files changed, 514 insertions(+), 61 deletions(-) diff --git a/src/app/components/favorites/favorites.component.spec.ts b/src/app/components/favorites/favorites.component.spec.ts index 0e1cfa73e..9c695851e 100644 --- a/src/app/components/favorites/favorites.component.spec.ts +++ b/src/app/components/favorites/favorites.component.spec.ts @@ -23,14 +23,26 @@ * along with Alfresco. If not, see . */ -import { Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TestBed, async } from '@angular/core/testing'; import { Observable } from 'rxjs/Rx'; -import { CoreModule, NodesApiService, AlfrescoApiService, ContentService } from '@alfresco/adf-core'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; +import { HttpClientModule } from '@angular/common/http'; +import { TestBed, async } from '@angular/core/testing'; +import { + NotificationService, TranslationService, TranslationMock, + NodesApiService, AlfrescoApiService, ContentService, + UserPreferencesService, LogService, AppConfigService, + StorageService, CookieService, ThumbnailService, + AuthenticationService, TimeAgoPipe, NodeNameTooltipPipe, + NodeFavoriteDirective, DataTableComponent +} from '@alfresco/adf-core'; +import { DocumentListComponent } from '@alfresco/adf-content-services'; -import { CommonModule } from '../../common/common.module'; -import { LocationLinkComponent } from '../location-link/location-link.component'; +import { TranslateModule } from '@ngx-translate/core'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatMenuModule, MatSnackBarModule, MatIconModule } from '@angular/material'; +import { DocumentListService } from '@alfresco/adf-content-services'; import { ContentManagementService } from '../../common/services/content-management.service'; import { FavoritesComponent } from './favorites.component'; @@ -42,6 +54,7 @@ describe('Favorites Routed Component', () => { let alfrescoApi: AlfrescoApiService; let alfrescoContentService: ContentService; let contentService: ContentManagementService; + let preferenceService: UserPreferencesService; let router: Router; let page; let node; @@ -75,14 +88,39 @@ describe('Favorites Routed Component', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - CoreModule, - CommonModule, - RouterTestingModule + MatMenuModule, + NoopAnimationsModule, + HttpClientModule, + TranslateModule.forRoot(), + RouterTestingModule, + MatSnackBarModule, MatIconModule ], declarations: [ - LocationLinkComponent, + DataTableComponent, + TimeAgoPipe, + NodeNameTooltipPipe, + NodeFavoriteDirective, + DocumentListComponent, FavoritesComponent - ] + ], + providers: [ + { provide: ActivatedRoute, useValue: { + snapshot: { data: { preferencePrefix: 'prefix' } } + } } , + { provide: TranslationService, useClass: TranslationMock }, + AuthenticationService, + UserPreferencesService, + AppConfigService, StorageService, CookieService, + AlfrescoApiService, + LogService, + NotificationService, + ContentManagementService, + ContentService, + NodesApiService, + DocumentListService, + ThumbnailService + ], + schemas: [ NO_ERRORS_SCHEMA ] }) .compileComponents().then(() => { fixture = TestBed.createComponent(FavoritesComponent); @@ -92,6 +130,7 @@ describe('Favorites Routed Component', () => { alfrescoApi = TestBed.get(AlfrescoApiService); alfrescoContentService = TestBed.get(ContentService); contentService = TestBed.get(ContentManagementService); + preferenceService = TestBed.get(UserPreferencesService); router = TestBed.get(Router); }); })); @@ -101,23 +140,34 @@ describe('Favorites Routed Component', () => { }); describe('Events', () => { - it('should refresh on editing folder event', () => { + beforeEach(() => { spyOn(component, 'refresh'); fixture.detectChanges(); + }); + it('should refresh on editing folder event', () => { alfrescoContentService.folderEdit.next(null); expect(component.refresh).toHaveBeenCalled(); }); it('should refresh on move node event', () => { - spyOn(component, 'refresh'); - fixture.detectChanges(); - contentService.nodeMoved.next(null); expect(component.refresh).toHaveBeenCalled(); }); + + it('should refresh on node deleted event', () => { + contentService.nodeDeleted.next(null); + + expect(component.refresh).toHaveBeenCalled(); + }); + + it('should refresh on node restore event', () => { + contentService.nodeRestored.next(null); + + expect(component.refresh).toHaveBeenCalled(); + }); }); describe('Node navigation', () => { @@ -238,4 +288,35 @@ describe('Favorites Routed Component', () => { expect(component.documentList.reload).toHaveBeenCalled(); }); }); + + describe('onSortingChanged', () => { + it('should save sorting input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: { + key: 'some-name', + direction: 'some-direction' + } + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction'); + }); + + it('should save default sorting when no input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: {} + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'modifiedAt'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc'); + }); + }); }); diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts index 1538f5978..e45aa7d7d 100644 --- a/src/app/components/files/files.component.spec.ts +++ b/src/app/components/files/files.component.spec.ts @@ -24,16 +24,28 @@ */ import { Observable } from 'rxjs/Rx'; -import { Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { TestBed, async } from '@angular/core/testing'; -import { UploadService, NodesApiService, ContentService } from '@alfresco/adf-core'; - -import { CommonModule } from '../../common/common.module'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; +import { HttpClientModule } from '@angular/common/http'; +import { TranslateModule } from '@ngx-translate/core'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { + NotificationService, TranslationService, TranslationMock, + NodesApiService, AlfrescoApiService, ContentService, + UserPreferencesService, LogService, AppConfigService, + StorageService, CookieService, ThumbnailService, AuthenticationService, + TimeAgoPipe, NodeNameTooltipPipe, FileSizePipe, NodeFavoriteDirective, + DataTableComponent, UploadService +} from '@alfresco/adf-core'; +import { DocumentListComponent } from '@alfresco/adf-content-services'; +import { MatMenuModule, MatSnackBarModule, MatIconModule, MatDialogModule } from '@angular/material'; +import { DocumentListService } from '@alfresco/adf-content-services'; import { ContentManagementService } from '../../common/services/content-management.service'; import { BrowsingFilesService } from '../../common/services/browsing-files.service'; import { NodeActionsService } from '../../common/services/node-actions.service'; -import { GenericErrorComponent } from '../generic-error/generic-error.component'; + import { FilesComponent } from './files.component'; describe('FilesComponent', () => { @@ -48,17 +60,50 @@ describe('FilesComponent', () => { let router: Router; let browsingFilesService: BrowsingFilesService; let nodeActionsService: NodeActionsService; + let preferenceService: UserPreferencesService; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ + MatMenuModule, + NoopAnimationsModule, + HttpClientModule, + TranslateModule.forRoot(), RouterTestingModule, - CommonModule + MatSnackBarModule, MatIconModule, + MatDialogModule ], declarations: [ FilesComponent, - GenericErrorComponent - ] + DataTableComponent, + TimeAgoPipe, + NodeNameTooltipPipe, + NodeFavoriteDirective, + DocumentListComponent, + FileSizePipe + ], + providers: [ + { provide: ActivatedRoute, useValue: { + params: Observable.of({ folderId: 'someId' }), + snapshot: { data: { preferencePrefix: 'prefix' } } + } } , + { provide: TranslationService, useClass: TranslationMock }, + AuthenticationService, + UserPreferencesService, + AppConfigService, StorageService, CookieService, + AlfrescoApiService, + LogService, + NotificationService, + ContentManagementService, + ContentService, + NodesApiService, + DocumentListService, + ThumbnailService, + NodeActionsService, + UploadService, + BrowsingFilesService + ], + schemas: [ NO_ERRORS_SCHEMA ] }).compileComponents() .then(() => { @@ -72,6 +117,7 @@ describe('FilesComponent', () => { alfrescoContentService = TestBed.get(ContentService); browsingFilesService = TestBed.get(BrowsingFilesService); nodeActionsService = TestBed.get(NodeActionsService); + preferenceService = TestBed.get(UserPreferencesService); }); })); @@ -454,4 +500,55 @@ describe('FilesComponent', () => { expect(router.navigate).toHaveBeenCalledWith(['./'], jasmine.any(Object)); }); }); + + describe('isSiteContainer', () => { + it('should return false if node has no aspectNames', () => { + const mock = { aspectNames: [] }; + + expect(component.isSiteContainer(mock)).toBe(false); + }); + + it('should return false if node is not site container', () => { + const mock = { aspectNames: ['something-else'] }; + + expect(component.isSiteContainer(mock)).toBe(false); + }); + + it('should return true if node is a site container', () => { + const mock = { aspectNames: [ 'st:siteContainer' ] }; + + expect(component.isSiteContainer(mock)).toBe(true); + }); + }); + + describe('onSortingChanged', () => { + it('should save sorting input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: { + key: 'some-name', + direction: 'some-direction' + } + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction'); + }); + + it('should save default sorting when no input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: {} + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'modifiedAt'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc'); + }); + }); }); diff --git a/src/app/components/libraries/libraries.component.spec.ts b/src/app/components/libraries/libraries.component.spec.ts index 6498569a7..706054fbb 100644 --- a/src/app/components/libraries/libraries.component.spec.ts +++ b/src/app/components/libraries/libraries.component.spec.ts @@ -23,15 +23,26 @@ * along with Alfresco. If not, see . */ -import { Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { TestBed, async } from '@angular/core/testing'; import { Observable } from 'rxjs/Rx'; - -import { CoreModule , NodesApiService, AlfrescoApiService} from '@alfresco/adf-core'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; +import { HttpClientModule } from '@angular/common/http'; +import { + NotificationService, TranslationService, TranslationMock, + NodesApiService, AlfrescoApiService, ContentService, + UserPreferencesService, LogService, AppConfigService, + StorageService, CookieService, ThumbnailService, AuthenticationService, + TimeAgoPipe, NodeNameTooltipPipe, NodeFavoriteDirective, DataTableComponent +} from '@alfresco/adf-core'; +import { DocumentListComponent } from '@alfresco/adf-content-services'; +import { TranslateModule } from '@ngx-translate/core'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatMenuModule, MatSnackBarModule, MatIconModule } from '@angular/material'; +import { DocumentListService } from '@alfresco/adf-content-services'; import { ShareDataTableAdapter } from '@alfresco/adf-content-services'; -import { CommonModule } from '../../common/common.module'; import { LibrariesComponent } from './libraries.component'; describe('Libraries Routed Component', () => { @@ -40,6 +51,7 @@ describe('Libraries Routed Component', () => { let nodesApi: NodesApiService; let alfrescoApi: AlfrescoApiService; let router: Router; + let preferenceService: UserPreferencesService; let page; let node; @@ -62,13 +74,38 @@ describe('Libraries Routed Component', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - CoreModule, + MatMenuModule, + NoopAnimationsModule, + HttpClientModule, + TranslateModule.forRoot(), RouterTestingModule, - CommonModule + MatSnackBarModule, MatIconModule ], declarations: [ + DataTableComponent, + TimeAgoPipe, + NodeNameTooltipPipe, + NodeFavoriteDirective, + DocumentListComponent, LibrariesComponent - ] + ], + providers: [ + { provide: ActivatedRoute, useValue: { + snapshot: { data: { preferencePrefix: 'prefix' } } + } } , + { provide: TranslationService, useClass: TranslationMock }, + AuthenticationService, + UserPreferencesService, + AppConfigService, StorageService, CookieService, + AlfrescoApiService, + LogService, + NotificationService, + ContentService, + NodesApiService, + DocumentListService, + ThumbnailService + ], + schemas: [ NO_ERRORS_SCHEMA ] }) .compileComponents().then(() => { fixture = TestBed.createComponent(LibrariesComponent); @@ -77,6 +114,7 @@ describe('Libraries Routed Component', () => { nodesApi = TestBed.get(NodesApiService); alfrescoApi = TestBed.get(AlfrescoApiService); router = TestBed.get(Router); + preferenceService = TestBed.get(UserPreferencesService); }); })); @@ -191,4 +229,35 @@ describe('Libraries Routed Component', () => { expect(component.navigate).not.toHaveBeenCalled(); }); }); + + describe('onSortingChanged', () => { + it('should save sorting input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: { + key: 'some-name', + direction: 'some-direction' + } + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction'); + }); + + it('should save default sorting when no input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: {} + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'modifiedAt'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc'); + }); + }); }); diff --git a/src/app/components/recent-files/recent-files.component.spec.ts b/src/app/components/recent-files/recent-files.component.spec.ts index c90ad6164..09ed4bf0f 100644 --- a/src/app/components/recent-files/recent-files.component.spec.ts +++ b/src/app/components/recent-files/recent-files.component.spec.ts @@ -23,15 +23,25 @@ * along with Alfresco. If not, see . */ -import { Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { TestBed, async } from '@angular/core/testing'; - -import { CoreModule, AlfrescoApiService } from '@alfresco/adf-core'; - -import { CommonModule } from '../../common/common.module'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; +import { HttpClientModule } from '@angular/common/http'; +import { + NotificationService, TranslationService, TranslationMock, + NodesApiService, AlfrescoApiService, ContentService, + UserPreferencesService, LogService, AppConfigService, + StorageService, CookieService, ThumbnailService, AuthenticationService, + TimeAgoPipe, NodeNameTooltipPipe, NodeFavoriteDirective, DataTableComponent +} from '@alfresco/adf-core'; +import { DocumentListComponent } from '@alfresco/adf-content-services'; +import { TranslateModule } from '@ngx-translate/core'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatMenuModule, MatSnackBarModule, MatIconModule } from '@angular/material'; +import { DocumentListService } from '@alfresco/adf-content-services'; import { ContentManagementService } from '../../common/services/content-management.service'; -import { LocationLinkComponent } from '../location-link/location-link.component'; + import { RecentFilesComponent } from './recent-files.component'; describe('RecentFiles Routed Component', () => { @@ -40,6 +50,7 @@ describe('RecentFiles Routed Component', () => { let router: Router; let alfrescoApi: AlfrescoApiService; let contentService: ContentManagementService; + let preferenceService: UserPreferencesService; let page; let person; @@ -57,14 +68,39 @@ describe('RecentFiles Routed Component', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - CoreModule, + MatMenuModule, + NoopAnimationsModule, + HttpClientModule, + TranslateModule.forRoot(), RouterTestingModule, - CommonModule + MatSnackBarModule, MatIconModule ], declarations: [ - LocationLinkComponent, + DataTableComponent, + TimeAgoPipe, + NodeNameTooltipPipe, + NodeFavoriteDirective, + DocumentListComponent, RecentFilesComponent - ] + ], + providers: [ + { provide: ActivatedRoute, useValue: { + snapshot: { data: { preferencePrefix: 'prefix' } } + } } , + { provide: TranslationService, useClass: TranslationMock }, + AuthenticationService, + UserPreferencesService, + AppConfigService, StorageService, CookieService, + AlfrescoApiService, + LogService, + NotificationService, + ContentManagementService, + ContentService, + NodesApiService, + DocumentListService, + ThumbnailService + ], + schemas: [ NO_ERRORS_SCHEMA ] }) .compileComponents().then(() => { fixture = TestBed.createComponent(RecentFilesComponent); @@ -72,6 +108,7 @@ describe('RecentFiles Routed Component', () => { router = TestBed.get(Router); contentService = TestBed.get(ContentManagementService); + preferenceService = TestBed.get(UserPreferencesService); alfrescoApi = TestBed.get(AlfrescoApiService); }); })); @@ -150,4 +187,35 @@ describe('RecentFiles Routed Component', () => { expect(component.documentList.reload).toHaveBeenCalled(); }); }); + + describe('onSortingChanged', () => { + it('should save sorting input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: { + key: 'some-name', + direction: 'some-direction' + } + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction'); + }); + + it('should save default sorting when no input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: {} + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'modifiedAt'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc'); + }); + }); }); diff --git a/src/app/components/shared-files/shared-files.component.spec.ts b/src/app/components/shared-files/shared-files.component.spec.ts index cca450e60..554915ce1 100644 --- a/src/app/components/shared-files/shared-files.component.spec.ts +++ b/src/app/components/shared-files/shared-files.component.spec.ts @@ -23,15 +23,25 @@ * along with Alfresco. If not, see . */ -import { Router } from '@angular/router'; import { TestBed, async, fakeAsync, tick } from '@angular/core/testing'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; - -import { AlfrescoApiService } from '@alfresco/adf-core'; - -import { CommonModule } from '../../common/common.module'; +import { HttpClientModule } from '@angular/common/http'; +import { + NotificationService, TranslationService, TranslationMock, + NodesApiService, AlfrescoApiService, ContentService, + UserPreferencesService, LogService, AppConfigService, + StorageService, CookieService, ThumbnailService, AuthenticationService, + TimeAgoPipe, NodeNameTooltipPipe, NodeFavoriteDirective,DataTableComponent +} from '@alfresco/adf-core'; +import { DocumentListComponent } from '@alfresco/adf-content-services'; +import { TranslateModule } from '@ngx-translate/core'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatMenuModule, MatSnackBarModule, MatIconModule } from '@angular/material'; +import { DocumentListService } from '@alfresco/adf-content-services'; import { ContentManagementService } from '../../common/services/content-management.service'; -import { LocationLinkComponent } from '../location-link/location-link.component'; + import { SharedFilesComponent } from './shared-files.component'; describe('SharedFilesComponent', () => { @@ -40,6 +50,7 @@ describe('SharedFilesComponent', () => { let contentService: ContentManagementService; let nodeService; let alfrescoApi: AlfrescoApiService; + let preferenceService: UserPreferencesService; let router: Router; let page; @@ -56,13 +67,39 @@ describe('SharedFilesComponent', () => { TestBed .configureTestingModule({ imports: [ + MatMenuModule, + NoopAnimationsModule, + HttpClientModule, + TranslateModule.forRoot(), RouterTestingModule, - CommonModule + MatSnackBarModule, MatIconModule ], declarations: [ - LocationLinkComponent, + DataTableComponent, + TimeAgoPipe, + NodeNameTooltipPipe, + NodeFavoriteDirective, + DocumentListComponent, SharedFilesComponent - ] + ], + providers: [ + { provide: ActivatedRoute, useValue: { + snapshot: { data: { preferencePrefix: 'prefix' } } + } } , + { provide: TranslationService, useClass: TranslationMock }, + AuthenticationService, + UserPreferencesService, + AppConfigService, StorageService, CookieService, + AlfrescoApiService, + LogService, + NotificationService, + ContentManagementService, + ContentService, + NodesApiService, + DocumentListService, + ThumbnailService + ], + schemas: [ NO_ERRORS_SCHEMA ] }) .compileComponents() .then(() => { @@ -72,6 +109,7 @@ describe('SharedFilesComponent', () => { contentService = TestBed.get(ContentManagementService); alfrescoApi = TestBed.get(AlfrescoApiService); nodeService = alfrescoApi.getInstance().nodes; + preferenceService = TestBed.get(UserPreferencesService); router = TestBed.get(Router); }); @@ -160,4 +198,35 @@ describe('SharedFilesComponent', () => { expect(component.documentList.reload).toHaveBeenCalled(); }); }); + + describe('onSortingChanged', () => { + it('should save sorting input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: { + key: 'some-name', + direction: 'some-direction' + } + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction'); + }); + + it('should save default sorting when no input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: {} + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'modifiedAt'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc'); + }); + }); }); diff --git a/src/app/components/trashcan/trashcan.component.spec.ts b/src/app/components/trashcan/trashcan.component.spec.ts index 0ec8dc934..196d65ced 100644 --- a/src/app/components/trashcan/trashcan.component.spec.ts +++ b/src/app/components/trashcan/trashcan.component.spec.ts @@ -22,19 +22,34 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; +import { HttpClientModule } from '@angular/common/http'; import { TestBed, async } from '@angular/core/testing'; -import { CoreModule, AlfrescoApiService } from '@alfresco/adf-core'; -import { TrashcanComponent } from './trashcan.component'; -import { CommonModule } from '../../common/common.module'; -import { LocationLinkComponent } from '../location-link/location-link.component'; +import { + NotificationService, TranslationService, TranslationMock, + NodesApiService, AlfrescoApiService, ContentService, + UserPreferencesService, LogService, AppConfigService, + StorageService, CookieService, ThumbnailService, + AuthenticationService, TimeAgoPipe, NodeNameTooltipPipe, + NodeFavoriteDirective, DataTableComponent +} from '@alfresco/adf-core'; +import { DocumentListComponent } from '@alfresco/adf-content-services'; +import { TranslateModule } from '@ngx-translate/core'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatMenuModule, MatSnackBarModule, MatIconModule } from '@angular/material'; +import { DocumentListService } from '@alfresco/adf-content-services'; import { ContentManagementService } from '../../common/services/content-management.service'; +import { TrashcanComponent } from './trashcan.component'; + describe('TrashcanComponent', () => { let fixture; let component; let alfrescoApi: AlfrescoApiService; let contentService: ContentManagementService; + let preferenceService: UserPreferencesService; let page; beforeEach(() => { @@ -49,17 +64,39 @@ describe('TrashcanComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ + MatMenuModule, + NoopAnimationsModule, + HttpClientModule, + TranslateModule.forRoot(), RouterTestingModule, - CoreModule, - CommonModule + MatSnackBarModule, MatIconModule ], declarations: [ - LocationLinkComponent, + DataTableComponent, + TimeAgoPipe, + NodeNameTooltipPipe, + NodeFavoriteDirective, + DocumentListComponent, TrashcanComponent ], providers: [ - ContentManagementService - ] + { provide: ActivatedRoute, useValue: { + snapshot: { data: { preferencePrefix: 'prefix' } } + } } , + { provide: TranslationService, useClass: TranslationMock }, + AuthenticationService, + UserPreferencesService, + AppConfigService, StorageService, CookieService, + AlfrescoApiService, + LogService, + NotificationService, + ContentManagementService, + ContentService, + NodesApiService, + DocumentListService, + ThumbnailService + ], + schemas: [ NO_ERRORS_SCHEMA ] }) .compileComponents() .then(() => { @@ -68,6 +105,7 @@ describe('TrashcanComponent', () => { alfrescoApi = TestBed.get(AlfrescoApiService); contentService = TestBed.get(ContentManagementService); + preferenceService = TestBed.get(UserPreferencesService); component.documentList = { loadTrashcan: jasmine.createSpy('loadTrashcan'), @@ -102,4 +140,35 @@ describe('TrashcanComponent', () => { expect(component.documentList.resetSelection).toHaveBeenCalled(); }); }); + + describe('onSortingChanged', () => { + it('should save sorting input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: { + key: 'some-name', + direction: 'some-direction' + } + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'some-name'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'some-direction'); + }); + + it('should save default sorting when no input', () => { + spyOn(preferenceService, 'set'); + + const event = { + detail: {} + }; + + component.onSortingChanged(event); + + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.key', 'archivedAt'); + expect(preferenceService.set).toHaveBeenCalledWith('prefix.sorting.direction', 'desc'); + }); + }); }); From 9bbc11b0b0a050dcbcdff1ae535133605bb09ee7 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Sat, 24 Feb 2018 09:52:10 +0200 Subject: [PATCH 44/69] granular dependencies (#200) --- .../current-user.component.spec.ts | 27 ++++++++++--- .../header/header.component.spec.ts | 39 ++++++++++++------- .../layout/layout.component.spec.ts | 39 ++++++++++++------- .../libraries/libraries.component.spec.ts | 1 + .../components/login/login.component.spec.ts | 28 ++++++++++--- .../search/search.component.spec.ts | 10 ++--- .../sidenav/sidenav.component.spec.ts | 24 ++++++++++-- 7 files changed, 117 insertions(+), 51 deletions(-) diff --git a/src/app/components/current-user/current-user.component.spec.ts b/src/app/components/current-user/current-user.component.spec.ts index 9f3e76188..5adc0920a 100644 --- a/src/app/components/current-user/current-user.component.spec.ts +++ b/src/app/components/current-user/current-user.component.spec.ts @@ -23,11 +23,18 @@ * along with Alfresco. If not, see . */ +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { TestBed, async } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { Observable } from 'rxjs/Rx'; -import { MaterialModule } from '../../common/material.module'; -import { CoreModule, PeopleContentService } from '@alfresco/adf-core'; +import { HttpClientModule } from '@angular/common/http'; +import { TranslateModule } from '@ngx-translate/core'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatMenuModule } from '@angular/material'; +import { + TranslationService, TranslationMock, AlfrescoApiService, + AppConfigService, StorageService, PeopleContentService + } from '@alfresco/adf-core'; import { CurrentUserComponent } from './current-user.component'; @@ -44,13 +51,23 @@ describe('CurrentUserComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - MaterialModule, - CoreModule, + HttpClientModule, + TranslateModule.forRoot(), + NoopAnimationsModule, + MatMenuModule, RouterTestingModule ], declarations: [ CurrentUserComponent - ] + ], + providers: [ + { provide: TranslationService, useClass: TranslationMock }, + AlfrescoApiService, + AppConfigService, + StorageService, + PeopleContentService + ], + schemas: [ NO_ERRORS_SCHEMA ] }) .compileComponents() .then(() => { diff --git a/src/app/components/header/header.component.spec.ts b/src/app/components/header/header.component.spec.ts index fb1d51728..09770857c 100644 --- a/src/app/components/header/header.component.spec.ts +++ b/src/app/components/header/header.component.spec.ts @@ -23,15 +23,14 @@ * along with Alfresco. If not, see . */ +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; -import { CoreModule, AppConfigService, PeopleContentService } from '@alfresco/adf-core'; +import { AppConfigService, PeopleContentService } from '@alfresco/adf-core'; +import { HttpClientModule } from '@angular/common/http'; import { Observable } from 'rxjs/Rx'; -import { CommonModule } from './../../common/common.module'; import { HeaderComponent } from './header.component'; -import { SearchComponent } from '../search/search.component'; -import { CurrentUserComponent } from '../current-user/current-user.component'; describe('HeaderComponent', () => { let fixture; @@ -41,15 +40,17 @@ describe('HeaderComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [ - CoreModule, - RouterTestingModule, - CommonModule + HttpClientModule, + RouterTestingModule ], declarations: [ - HeaderComponent, - SearchComponent, - CurrentUserComponent - ] + HeaderComponent + ], + providers: [ + AppConfigService, + PeopleContentService + ], + schemas: [ NO_ERRORS_SCHEMA ] }) .overrideProvider(PeopleContentService, { useValue: { @@ -65,16 +66,24 @@ describe('HeaderComponent', () => { if (val === 'application.name') { return 'app-name'; } + + if (val === 'headerColor') { + return 'some-color'; + } + + if (val === 'application.logo') { + return ''; + } }); fixture.detectChanges(); }); - it('should get application name from configuration file', () => { - expect(appConfigService.get).toHaveBeenCalledWith('application.name'); - }); - it('it should set application name', () => { expect(component.appName).toBe('app-name'); }); + + it('it should set header background color', () => { + expect(component.backgroundColor).toBe('some-color'); + }); }); diff --git a/src/app/components/layout/layout.component.spec.ts b/src/app/components/layout/layout.component.spec.ts index 5bd92c25e..37b73bc4d 100644 --- a/src/app/components/layout/layout.component.spec.ts +++ b/src/app/components/layout/layout.component.spec.ts @@ -23,19 +23,22 @@ * along with Alfresco. If not, see . */ +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { RouterTestingModule } from '@angular/router/testing'; import { TestBed, ComponentFixture } from '@angular/core/testing'; import { MinimalNodeEntryEntity } from 'alfresco-js-api'; -import { CoreModule, ContentService, PeopleContentService, AppConfigService } from '@alfresco/adf-core'; +import { TranslateModule } from '@ngx-translate/core'; +import { HttpClientModule } from '@angular/common/http'; +import { + ContentService, PeopleContentService, AppConfigService, + AuthenticationService, UserPreferencesService, TranslationService, + TranslationMock, StorageService, AlfrescoApiService, CookieService, + LogService +} from '@alfresco/adf-core'; import { Observable } from 'rxjs/Observable'; import { BrowsingFilesService } from '../../common/services/browsing-files.service'; import { LayoutComponent } from './layout.component'; -import { CommonModule } from './../../common/common.module'; -import { HeaderComponent } from '../header/header.component'; -import { SidenavComponent } from '../sidenav/sidenav.component'; -import { SearchComponent } from '../search/search.component'; -import { CurrentUserComponent } from '../current-user/current-user.component'; describe('LayoutComponent', () => { let fixture: ComponentFixture; @@ -55,26 +58,32 @@ describe('LayoutComponent', () => { TestBed.configureTestingModule({ imports: [ - CoreModule, - RouterTestingModule, - CommonModule + HttpClientModule, + TranslateModule.forRoot(), + RouterTestingModule ], declarations: [ - LayoutComponent, - HeaderComponent, - SidenavComponent, - SearchComponent, - CurrentUserComponent + LayoutComponent ], providers: [ + { provide: TranslationService, useClass: TranslationMock }, + AlfrescoApiService, + StorageService, + CookieService, + LogService, + UserPreferencesService, + AuthenticationService, + ContentService, AppConfigService, + BrowsingFilesService, { provide: PeopleContentService, useValue: { getCurrentPerson: () => Observable.of({ entry: {} }) } } - ] + ], + schemas: [ NO_ERRORS_SCHEMA ] }); fixture = TestBed.createComponent(LayoutComponent); diff --git a/src/app/components/libraries/libraries.component.spec.ts b/src/app/components/libraries/libraries.component.spec.ts index 706054fbb..c34858680 100644 --- a/src/app/components/libraries/libraries.component.spec.ts +++ b/src/app/components/libraries/libraries.component.spec.ts @@ -120,6 +120,7 @@ describe('Libraries Routed Component', () => { beforeEach(() => { spyOn(alfrescoApi.sitesApi, 'getSites').and.returnValue((Promise.resolve(page))); + spyOn(alfrescoApi.peopleApi, 'getSiteMembership').and.returnValue((Promise.resolve({}))); }); describe('makeLibraryTooltip()', () => { diff --git a/src/app/components/login/login.component.spec.ts b/src/app/components/login/login.component.spec.ts index b0b923c82..b4aee669c 100644 --- a/src/app/components/login/login.component.spec.ts +++ b/src/app/components/login/login.component.spec.ts @@ -23,13 +23,19 @@ * along with Alfresco. If not, see . */ +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { RouterTestingModule } from '@angular/router/testing'; import { Router } from '@angular/router'; +import { HttpClientModule } from '@angular/common/http'; +import { TranslateModule } from '@ngx-translate/core'; import { Location } from '@angular/common'; import { TestBed, async } from '@angular/core/testing'; -import { AuthenticationService, UserPreferencesService } from '@alfresco/adf-core'; +import { + AuthenticationService, UserPreferencesService, TranslationService, + TranslationMock, AppConfigService, StorageService, AlfrescoApiService, + CookieService, LogService +} from '@alfresco/adf-core'; -import { CommonModule } from '../../common/common.module'; import { LoginComponent } from './login.component'; describe('LoginComponent', () => { @@ -43,15 +49,25 @@ describe('LoginComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - RouterTestingModule, - CommonModule + HttpClientModule, + TranslateModule.forRoot(), + RouterTestingModule ], declarations: [ LoginComponent ], providers: [ - Location - ] + { provide: TranslationService, useClass: TranslationMock }, + Location, + CookieService, + LogService, + StorageService, + AlfrescoApiService, + AppConfigService, + AuthenticationService, + UserPreferencesService + ], + schemas: [ NO_ERRORS_SCHEMA ] }); fixture = TestBed.createComponent(LoginComponent); diff --git a/src/app/components/search/search.component.spec.ts b/src/app/components/search/search.component.spec.ts index 7cc3dc903..de37de5b5 100644 --- a/src/app/components/search/search.component.spec.ts +++ b/src/app/components/search/search.component.spec.ts @@ -23,13 +23,12 @@ * along with Alfresco. If not, see . */ +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { TestBed, async } from '@angular/core/testing'; -import { CoreModule } from '@alfresco/adf-core'; import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import { SearchComponent } from './search.component'; -import { CommonModule } from './../../common/common.module'; describe('SearchComponent', () => { let fixture; @@ -39,13 +38,12 @@ describe('SearchComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - CoreModule, - RouterTestingModule, - CommonModule + RouterTestingModule ], declarations: [ SearchComponent - ] + ], + schemas: [ NO_ERRORS_SCHEMA ] }) .compileComponents() .then(() => { diff --git a/src/app/components/sidenav/sidenav.component.spec.ts b/src/app/components/sidenav/sidenav.component.spec.ts index 9d2ed7dcb..db3440f88 100644 --- a/src/app/components/sidenav/sidenav.component.spec.ts +++ b/src/app/components/sidenav/sidenav.component.spec.ts @@ -26,8 +26,14 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { TestBed, async } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; - -import { CoreModule, ContentService, AppConfigService } from '@alfresco/adf-core'; +import { TranslateModule } from '@ngx-translate/core'; +import { MatMenuModule } from '@angular/material'; +import { HttpClientModule } from '@angular/common/http'; +import { + ContentService, AppConfigService, AuthenticationService, + UserPreferencesService, StorageService, AlfrescoApiService, + CookieService, LogService +} from '@alfresco/adf-core'; import { BrowsingFilesService } from '../../common/services/browsing-files.service'; import { SidenavComponent } from './sidenav.component'; @@ -50,13 +56,23 @@ describe('SidenavComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - RouterTestingModule, - CoreModule + HttpClientModule, + MatMenuModule, + TranslateModule.forRoot(), + RouterTestingModule ], declarations: [ SidenavComponent ], providers: [ + LogService, + CookieService, + AlfrescoApiService, + StorageService, + UserPreferencesService, + AuthenticationService, + ContentService, + AppConfigService, BrowsingFilesService ], schemas: [ NO_ERRORS_SCHEMA ] From 8d4e6a660422d7bf8035ab3249494e5fb351a44f Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 26 Feb 2018 16:37:04 +0000 Subject: [PATCH 45/69] upgrade to lastest ADF alpha (#201) --- package-lock.json | 465 +++++++----------- package.json | 6 +- .../components/preview/preview.component.html | 12 +- yarn.lock | 24 +- 4 files changed, 210 insertions(+), 297 deletions(-) diff --git a/package-lock.json b/package-lock.json index 62e723c8f..735f9e522 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,11 +5,11 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66.tgz", - "integrity": "sha512-7tiXcRoQM3q7XAtHFYal8ZR0v/mNQ6yCD/Brw6J21vkSEro4PSIKtpyUPCdh9uqxPOzshkXQ/PsdYJiLh01EdA==", + "version": "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a.tgz", + "integrity": "sha512-OaVop6kosAxDitrdARIxShZ1aZRTPybrM64Oj5IsDJ7Oz+cUF5c+LPubXrl8i4V1JbXJdP4/Ba/hmxoBAe8UPQ==", "requires": { - "@alfresco/adf-core": "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66", + "@alfresco/adf-core": "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a", "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", "@angular/common": "5.1.1", @@ -24,7 +24,7 @@ "@angular/platform-browser-dynamic": "5.1.1", "@angular/router": "5.1.1", "@ngx-translate/core": "9.1.1", - "alfresco-js-api": "2.2.0-c8f6736c571c52038c46b490892f96616b31662c", + "alfresco-js-api": "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652", "chart.js": "2.5.0", "core-js": "2.4.1", "hammerjs": "2.0.8", @@ -61,9 +61,9 @@ } }, "@alfresco/adf-core": { - "version": "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66.tgz", - "integrity": "sha512-/38VJQX1d+C+fWyyVJIQb/M72nnDeVRbTeLfwc71+9ifdYegtYxHb97A5lQW0kVKD5lfbmub/SiUfdA6X4i1Kw==", + "version": "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a.tgz", + "integrity": "sha512-YVBcV1p6D9pxiLkgilSmGCzzF8mVoC7MEMZ48AGJEXtKryjFdZS0Py0h6RIwC44J+RJPHNkdq/NbrS0GfXh8DQ==", "requires": { "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", @@ -79,7 +79,7 @@ "@angular/platform-browser-dynamic": "5.1.1", "@angular/router": "5.1.1", "@ngx-translate/core": "9.1.1", - "alfresco-js-api": "2.2.0-c8f6736c571c52038c46b490892f96616b31662c", + "alfresco-js-api": "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652", "chart.js": "2.5.0", "core-js": "2.4.1", "hammerjs": "2.0.8", @@ -147,6 +147,18 @@ "source-map": "0.5.7" }, "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, "rxjs": { "version": "5.5.6", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.6.tgz", @@ -223,7 +235,7 @@ "chalk": "2.2.2", "circular-dependency-plugin": "4.4.0", "common-tags": "1.7.2", - "copy-webpack-plugin": "4.4.1", + "copy-webpack-plugin": "4.4.2", "core-object": "3.1.5", "css-loader": "0.28.10", "cssnano": "3.10.0", @@ -239,7 +251,7 @@ "karma-source-map-support": "1.2.0", "less": "2.7.3", "less-loader": "4.0.5", - "license-webpack-plugin": "1.1.1", + "license-webpack-plugin": "1.1.2", "loader-utils": "1.1.0", "lodash": "4.17.5", "memory-fs": "0.4.1", @@ -250,8 +262,8 @@ "opn": "5.1.0", "portfinder": "1.0.13", "postcss-import": "11.1.0", - "postcss-loader": "2.1.0", - "postcss-url": "7.3.0", + "postcss-loader": "2.1.1", + "postcss-url": "7.3.1", "raw-loader": "0.5.1", "resolve": "1.5.0", "rxjs": "5.5.6", @@ -262,8 +274,8 @@ "source-map-support": "0.4.18", "style-loader": "0.13.2", "stylus": "0.54.5", - "stylus-loader": "3.0.1", - "uglifyjs-webpack-plugin": "1.2.0", + "stylus-loader": "3.0.2", + "uglifyjs-webpack-plugin": "1.2.2", "url-loader": "0.6.2", "webpack": "3.10.0", "webpack-dev-middleware": "1.12.2", @@ -600,12 +612,11 @@ } }, "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", + "integrity": "sha1-r6wpW7qgFSRJ5SJ0LkVHwa6TKNI=", "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", + "fast-deep-equal": "1.1.0", "fast-json-stable-stringify": "2.0.0", "json-schema-traverse": "0.3.1" } @@ -613,13 +624,12 @@ "ajv-keywords": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz", - "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=", - "dev": true + "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=" }, "alfresco-js-api": { - "version": "2.2.0-c8f6736c571c52038c46b490892f96616b31662c", - "resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-2.2.0-c8f6736c571c52038c46b490892f96616b31662c.tgz", - "integrity": "sha512-zq4e230d6RZyWvOvDJT1+l0uhwC3xj0DEJu+5lCS5UkZkCDktVguRxxhhlwuq/RWXrRprUSVYCtgI2zcSNdWag==", + "version": "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652", + "resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652.tgz", + "integrity": "sha512-jYUUrzmTFgBJLfH2dVz/F386JDdV9L9Vms9n/jAV6s1gbxg6g8eIt3ThAr8P60lVNsW4zKSkPd3bGVyMHojrDQ==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" @@ -919,9 +929,9 @@ "dev": true }, "ast-types": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.1.tgz", - "integrity": "sha512-BAlXqqeEhVEajhgz7rgerupI8sb695KpCaJ/w4Sb9s2LoUci8sSMhXw93Jp8MsOufWGJOY/P2jpUEVw4RlSzNw==", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.2.tgz", + "integrity": "sha512-aL+pcOQ+6dpWd0xrUe+Obo2CgdkFvsntkXEmzZKqEN4cR0PStF+1MBuc4V+YZsv4Q36luvyjG7F4lc+wH2bmag==", "dev": true, "optional": true }, @@ -2129,7 +2139,8 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true }, "coa": { "version": "1.0.4", @@ -6907,9 +6918,9 @@ "dev": true }, "copy-webpack-plugin": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.4.1.tgz", - "integrity": "sha512-ojaz8MpS3zoLJT/JbYMusYM+dCEArhW24hGAUPYPydTCS+87NFh2TWr85sywG3So4Q4E68QoerqQ+Ns1g0fhDg==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.4.2.tgz", + "integrity": "sha512-tf1XKKQ5h+BPvXJ5/zx2xKVdF0/6J8XNvhB6fdmIReMnAfQGMbzph8F7ok2QF9kqWMfIgkCxwzk1zXkYqcLIqg==", "dev": true, "requires": { "cacache": "10.0.4", @@ -7486,7 +7497,7 @@ "dev": true, "optional": true, "requires": { - "ast-types": "0.11.1", + "ast-types": "0.11.2", "escodegen": "1.9.0", "esprima": "3.1.3" }, @@ -8431,6 +8442,29 @@ "loader-utils": "1.1.0", "schema-utils": "0.3.0", "webpack-sources": "1.1.0" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "dev": true, + "requires": { + "ajv": "5.5.2" + } + } } }, "extsprintf": { @@ -8440,9 +8474,9 @@ "dev": true }, "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" }, "fast-json-stable-stringify": { "version": "2.0.0", @@ -8479,29 +8513,6 @@ "requires": { "loader-utils": "1.1.0", "schema-utils": "0.4.5" - }, - "dependencies": { - "ajv": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.1.1.tgz", - "integrity": "sha1-l41Zf7wrfQ5aXD3esUmmgvKr+g4=", - "dev": true, - "requires": { - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", - "dev": true, - "requires": { - "ajv": "6.1.1", - "ajv-keywords": "3.1.0" - } - } } }, "file-uri-to-path": { @@ -11105,6 +11116,29 @@ "istanbul-lib-instrument": "1.9.2", "loader-utils": "1.1.0", "schema-utils": "0.3.0" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "dev": true, + "requires": { + "ajv": "5.5.2" + } + } } }, "istanbul-lib-coverage": { @@ -11647,9 +11681,9 @@ "dev": true }, "license-webpack-plugin": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-1.1.1.tgz", - "integrity": "sha512-TjKOyiC0exqd4Idy/4M8/DETR22dXBZks387DuS5LbslxHiMRXGx/Q2F/j9IUtvEoH5uFvt72vRgk/G6f8j3Dg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-1.1.2.tgz", + "integrity": "sha512-L40JKqFGSJ2z5bKOleYK3IgdOaTCoRx1p+zScf5yMCYQ1HsKrcCGFxVjZYvIWatcqGtdoEC0PZOBFgSaHMmvrw==", "dev": true, "requires": { "ejs": "2.5.7" @@ -11727,24 +11761,6 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, - "lodash.endswith": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.endswith/-/lodash.endswith-4.2.1.tgz", - "integrity": "sha1-/tWawXOO0+I27dcGTsRWRIs3vAk=", - "dev": true - }, - "lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", - "dev": true - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", - "dev": true - }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -11758,12 +11774,6 @@ "dev": true, "optional": true }, - "lodash.startswith": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.startswith/-/lodash.startswith-4.2.1.tgz", - "integrity": "sha1-xZjErc4YiiflMUVzHNxsDnF3YAw=", - "dev": true - }, "lodash.tail": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", @@ -12470,7 +12480,7 @@ "object.pick": "1.3.0", "regex-not": "1.0.2", "snapdragon": "0.8.1", - "to-regex": "3.0.1" + "to-regex": "3.0.2" }, "dependencies": { "arr-diff": { @@ -13515,7 +13525,7 @@ "integrity": "sha1-jABTDyQihmA7/L/dLukXwYK51EE=", "requires": { "node-ensure": "0.0.0", - "worker-loader": "1.1.0" + "worker-loader": "1.1.1" } }, "performance-now": { @@ -14270,38 +14280,15 @@ } }, "postcss-loader": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.0.tgz", - "integrity": "sha512-S/dKzpDwGFmP9g8eyCu9sUIV+/+3UooeTpYlsKf23qKDdrhHuA4pTSfytVu0rEJ0iDqUavXrgtOPq5KhNyNMOw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.1.tgz", + "integrity": "sha512-f0J/DWE/hyO9/LH0WHpXkny/ZZ238sSaG3p1SRBtVZnFWUtD7GXIEgHoBg8cnAeRbmEvUxHQptY46zWfwNYj/w==", "dev": true, "requires": { "loader-utils": "1.1.0", "postcss": "6.0.19", "postcss-load-config": "1.2.0", "schema-utils": "0.4.5" - }, - "dependencies": { - "ajv": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.1.1.tgz", - "integrity": "sha1-l41Zf7wrfQ5aXD3esUmmgvKr+g4=", - "dev": true, - "requires": { - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", - "dev": true, - "requires": { - "ajv": "6.1.1", - "ajv-keywords": "3.1.0" - } - } } }, "postcss-merge-idents": { @@ -15373,9 +15360,9 @@ } }, "postcss-url": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.0.tgz", - "integrity": "sha512-VBP6uf6iL3AZra23nkPkOEkS/5azj1xf/toRrjfkolfFEgg9Gyzg9UhJZeIsz12EGKZTNVeGbPa2XtaZm/iZvg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.1.tgz", + "integrity": "sha512-Ya5KIjGptgz0OtrVYfi2UbLxVAZ6Emc4Of+Grx4Sf1deWlRpFwLr8FrtkUxfqh+XiZIVkXbjQrddE10ESpNmdA==", "dev": true, "requires": { "mime": "1.6.0", @@ -16001,14 +15988,14 @@ "optional": true, "requires": { "double-ended-queue": "2.1.0-0", - "redis-commands": "1.3.1", + "redis-commands": "1.3.3", "redis-parser": "2.6.0" } }, "redis-commands": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz", - "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.3.tgz", + "integrity": "sha512-i41GK1SzbNp5nqmuVAMQw9sgar/cvk4YqD6M2RXp2p94D4itY82OZGVs28Jl8JcslGnOdQvlBrDLPt6jYQzuow==", "dev": true, "optional": true }, @@ -16394,11 +16381,12 @@ "dev": true }, "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", + "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", "requires": { - "ajv": "5.5.2" + "ajv": "6.2.0", + "ajv-keywords": "3.1.0" } }, "scss-tokenizer": { @@ -16912,7 +16900,7 @@ "engine.io": "3.1.5", "socket.io-adapter": "1.1.1", "socket.io-client": "2.0.4", - "socket.io-parser": "3.1.2" + "socket.io-parser": "3.1.3" }, "dependencies": { "debug": { @@ -16949,7 +16937,7 @@ "object-component": "0.0.3", "parseqs": "0.0.5", "parseuri": "0.0.5", - "socket.io-parser": "3.1.2", + "socket.io-parser": "3.1.3", "to-array": "0.1.4" }, "dependencies": { @@ -16965,26 +16953,17 @@ } }, "socket.io-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.2.tgz", - "integrity": "sha1-28IoIVH8T6675Aru3Ady66YZ9/I=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", + "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", "dev": true, "requires": { "component-emitter": "1.2.1", - "debug": "2.6.9", + "debug": "3.1.0", "has-binary2": "1.0.2", "isarray": "2.0.1" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, "isarray": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", @@ -17548,9 +17527,9 @@ } }, "stylus-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.1.tgz", - "integrity": "sha1-d/SzT9Aw0lsmF7z1UT21sHMMQIk=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", + "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -17752,91 +17731,15 @@ } }, "to-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz", - "integrity": "sha1-FTWL7kosg712N3uh3ASdDxiDeq4=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "regex-not": "1.0.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" } }, "to-regex-range": { @@ -18174,9 +18077,9 @@ "optional": true }, "uglifyjs-webpack-plugin": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.0.tgz", - "integrity": "sha512-Bc2NeyTTSJAy2JuKaBpdvWyuySPSPHNcj70KFqu7FhfrfsjPo0Kta9jgAvPrQxnz86mOH1tk4n/I8wvZrXvetA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.2.tgz", + "integrity": "sha512-CG/NvzXfemUAm5Y4Guh5eEaJYHtkG7kKNpXEJHp9QpxsFVB5/qKvYWoMaq4sa99ccZ0hM3MK8vQV9XPZB4357A==", "dev": true, "requires": { "cacache": "10.0.4", @@ -18186,36 +18089,15 @@ "source-map": "0.6.1", "uglify-es": "3.3.9", "webpack-sources": "1.1.0", - "worker-farm": "1.5.2" + "worker-farm": "1.5.4" }, "dependencies": { - "ajv": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.1.1.tgz", - "integrity": "sha1-l41Zf7wrfQ5aXD3esUmmgvKr+g4=", - "dev": true, - "requires": { - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, "commander": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", "dev": true }, - "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", - "dev": true, - "requires": { - "ajv": "6.1.1", - "ajv-keywords": "3.1.0" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -18385,16 +18267,10 @@ } }, "upath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.2.tgz", - "integrity": "sha512-fCmij7T5LnwUme3dbnVSejvOHHlARjB3ikJFwgZfz386pHmf/gueuTLRFU94FZEaeCLlbQrweiUU700gG41tUw==", - "dev": true, - "requires": { - "lodash.endswith": "4.2.1", - "lodash.isfunction": "3.0.9", - "lodash.isstring": "4.0.1", - "lodash.startswith": "4.2.1" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.4.tgz", + "integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==", + "dev": true }, "upper-case": { "version": "1.1.3", @@ -18435,6 +18311,29 @@ "loader-utils": "1.1.0", "mime": "1.6.0", "schema-utils": "0.3.0" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "dev": true, + "requires": { + "ajv": "5.5.2" + } + } } }, "url-parse": { @@ -18801,6 +18700,18 @@ "yargs": "8.0.2" }, "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, "ajv-keywords": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", @@ -19123,7 +19034,7 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "3.1.8", + "micromatch": "3.1.9", "normalize-path": "2.1.1" } }, @@ -19156,7 +19067,7 @@ "snapdragon": "0.8.1", "snapdragon-node": "2.1.1", "split-string": "3.1.0", - "to-regex": "3.0.1" + "to-regex": "3.0.2" }, "dependencies": { "define-property": { @@ -19202,7 +19113,7 @@ "normalize-path": "2.1.1", "path-is-absolute": "1.0.1", "readdirp": "2.1.0", - "upath": "1.0.2" + "upath": "1.0.4" } }, "expand-brackets": { @@ -19217,7 +19128,7 @@ "posix-character-classes": "0.1.1", "regex-not": "1.0.2", "snapdragon": "0.8.1", - "to-regex": "3.0.1" + "to-regex": "3.0.2" }, "dependencies": { "debug": { @@ -19279,7 +19190,7 @@ "fragment-cache": "0.2.1", "regex-not": "1.0.2", "snapdragon": "0.8.1", - "to-regex": "3.0.1" + "to-regex": "3.0.2" }, "dependencies": { "define-property": { @@ -19440,9 +19351,9 @@ "dev": true }, "micromatch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.8.tgz", - "integrity": "sha512-/XeuOQqYg+B5kwjDWekXseSwGS7CzE0w9Gjo4Cjkf/uFitNh47NrZHAY2vp/oS2YQVfebPIdbEIvgdy+kIcAog==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.9.tgz", + "integrity": "sha512-SlIz6sv5UPaAVVFRKodKjCg48EbNoIhgetzfK/Cy0v5U52Z6zB136M8tp0UC9jM53LYbmIRihJszvvqpKkfm9g==", "dev": true, "requires": { "arr-diff": "4.0.0", @@ -19457,7 +19368,7 @@ "object.pick": "1.3.0", "regex-not": "1.0.2", "snapdragon": "0.8.1", - "to-regex": "3.0.1" + "to-regex": "3.0.2" } }, "supports-color": { @@ -19607,9 +19518,9 @@ "dev": true }, "worker-farm": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.5.2.tgz", - "integrity": "sha512-XxiQ9kZN5n6mmnW+mFJ+wXjNNI/Nx4DIdaAKLX1Bn6LYBWlN/zaBhu34DQYPZ1AJobQuu67S2OfDdNSVULvXkQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.5.4.tgz", + "integrity": "sha512-ITyClEvcfv0ozqJl1vmWFWhvI+OIrkbInYqkEPE50wFPXj8J9Gd3FYf8+CkZJXJJsQBYe+2DvmoK9Zhx5w8W+w==", "dev": true, "requires": { "errno": "0.1.7", @@ -19617,12 +19528,12 @@ } }, "worker-loader": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-1.1.0.tgz", - "integrity": "sha512-W91q8Wi1JxbzFQZuLJlFK4x8UuWjKgeOX9IMMyng007K0UkP6I8lOejckoCWY61QmnJq2x9qZ/Viru+uF8g6nA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-1.1.1.tgz", + "integrity": "sha512-qJZLVS/jMCBITDzPo/RuweYSIG8VJP5P67mP/71alGyTZRe1LYJFdwLjLalY3T5ifx0bMDRD3OB6P2p1escvlg==", "requires": { "loader-utils": "1.1.0", - "schema-utils": "0.3.0" + "schema-utils": "0.4.5" } }, "wrap-ansi": { diff --git a/package.json b/package.json index 1f0c480e1..bfd2c6249 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66", - "@alfresco/adf-core": "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66", + "@alfresco/adf-content-services": "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a", + "@alfresco/adf-core": "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a", "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", "@angular/common": "5.1.1", @@ -34,7 +34,7 @@ "@mat-datetimepicker/core": "1.0.1", "@mat-datetimepicker/moment": "1.0.1", "@ngx-translate/core": "9.1.1", - "alfresco-js-api": "2.2.0-c8f6736c571c52038c46b490892f96616b31662c", + "alfresco-js-api": "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652", "core-js": "2.5.3", "hammerjs": "2.0.8", "moment-es6": "1.0.0", diff --git a/src/app/components/preview/preview.component.html b/src/app/components/preview/preview.component.html index 77925f753..c7f0c8de4 100644 --- a/src/app/components/preview/preview.component.html +++ b/src/app/components/preview/preview.component.html @@ -9,13 +9,15 @@ (navigateBefore)="onNavigateBefore()" (navigateNext)="onNavigateNext()"> - - - + + diff --git a/yarn.lock b/yarn.lock index afb2b317a..b062b2f1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,11 @@ # yarn lockfile v1 -"@alfresco/adf-content-services@2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66": - version "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66" - resolved "https://registry.yarnpkg.com/@alfresco/adf-content-services/-/adf-content-services-2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66.tgz#df3f2c96d50993fb1b001e8579ff152949ff248e" +"@alfresco/adf-content-services@2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a": + version "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a" + resolved "https://registry.yarnpkg.com/@alfresco/adf-content-services/-/adf-content-services-2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a.tgz#0bf4dce220ebb3d6f3bb3815f09be0547bc92d4d" dependencies: - "@alfresco/adf-core" "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66" + "@alfresco/adf-core" "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a" "@angular/animations" "5.1.1" "@angular/cdk" "5.0.1" "@angular/common" "5.1.1" @@ -21,7 +21,7 @@ "@angular/platform-browser-dynamic" "5.1.1" "@angular/router" "5.1.1" "@ngx-translate/core" "9.1.1" - alfresco-js-api "2.2.0-c8f6736c571c52038c46b490892f96616b31662c" + alfresco-js-api "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652" chart.js "2.5.0" core-js "2.4.1" hammerjs "2.0.8" @@ -36,9 +36,9 @@ tslib "^1.7.1" zone.js "0.8.14" -"@alfresco/adf-core@2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66": - version "2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66" - resolved "https://registry.yarnpkg.com/@alfresco/adf-core/-/adf-core-2.2.0-ad3dbd4d0b52ff814b90dc5e13136e2ae893fe66.tgz#580f75587cf103c784507ee84e28a17072184f6f" +"@alfresco/adf-core@2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a": + version "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a" + resolved "https://registry.yarnpkg.com/@alfresco/adf-core/-/adf-core-2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a.tgz#56a0a9334057ad7dfb37c494b5c4d23b29267af8" dependencies: "@angular/animations" "5.1.1" "@angular/cdk" "5.0.1" @@ -54,7 +54,7 @@ "@angular/platform-browser-dynamic" "5.1.1" "@angular/router" "5.1.1" "@ngx-translate/core" "9.1.1" - alfresco-js-api "2.2.0-c8f6736c571c52038c46b490892f96616b31662c" + alfresco-js-api "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652" chart.js "2.5.0" core-js "2.4.1" hammerjs "2.0.8" @@ -412,9 +412,9 @@ ajv@^6.1.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" -alfresco-js-api@2.2.0-c8f6736c571c52038c46b490892f96616b31662c: - version "2.2.0-c8f6736c571c52038c46b490892f96616b31662c" - resolved "https://registry.yarnpkg.com/alfresco-js-api/-/alfresco-js-api-2.2.0-c8f6736c571c52038c46b490892f96616b31662c.tgz#0f395db73ff2d2b41e5c24617e9defa8c52760f5" +alfresco-js-api@2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652: + version "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652" + resolved "https://registry.yarnpkg.com/alfresco-js-api/-/alfresco-js-api-2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652.tgz#b6fd32ac4468b183cd053a8c9f2fd3f245e3c440" dependencies: event-emitter "0.3.4" superagent "3.8.2" From 0b5dc47de95944dd8b3953c68f64ade52cedac86 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 27 Feb 2018 11:06:31 +0000 Subject: [PATCH 46/69] move empty folder UI into separate component (#202) * move empty folder UI into separate component * test fixes --- src/app/app.module.ts | 4 ++- .../empty-folder/empty-folder.component.html | 6 ++++ .../empty-folder/empty-folder.component.scss | 29 ++++++++++++++++ .../empty-folder.component.spec.ts | 33 +++++++++++++++++++ .../empty-folder/empty-folder.component.ts | 22 +++++++++++++ .../favorites/favorites.component.html | 10 +++--- .../libraries/libraries.component.html | 10 +++--- .../recent-files/recent-files.component.html | 10 +++--- .../shared-files/shared-files.component.html | 10 +++--- .../trashcan/trashcan.component.html | 12 +++---- .../ui/overrides/_alfresco-document-list.scss | 27 --------------- 11 files changed, 119 insertions(+), 54 deletions(-) create mode 100644 src/app/components/empty-folder/empty-folder.component.html create mode 100644 src/app/components/empty-folder/empty-folder.component.scss create mode 100644 src/app/components/empty-folder/empty-folder.component.spec.ts create mode 100644 src/app/components/empty-folder/empty-folder.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 5548ff91d..ff150bc5e 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -51,6 +51,7 @@ import { SearchComponent } from './components/search/search.component'; import { SidenavComponent } from './components/sidenav/sidenav.component'; import { AboutComponent } from './components/about/about.component'; import { LocationLinkComponent } from './components/location-link/location-link.component'; +import { EmptyFolderComponent } from './components/empty-folder/empty-folder.component'; @NgModule({ imports: [ @@ -80,7 +81,8 @@ import { LocationLinkComponent } from './components/location-link/location-link. TrashcanComponent, PreviewComponent, AboutComponent, - LocationLinkComponent + LocationLinkComponent, + EmptyFolderComponent ], providers: [ { diff --git a/src/app/components/empty-folder/empty-folder.component.html b/src/app/components/empty-folder/empty-folder.component.html new file mode 100644 index 000000000..43ecf6bf8 --- /dev/null +++ b/src/app/components/empty-folder/empty-folder.component.html @@ -0,0 +1,6 @@ +
+ {{ icon }} +

{{ title | translate }}

+

{{ subtitle | translate }}

+ +
diff --git a/src/app/components/empty-folder/empty-folder.component.scss b/src/app/components/empty-folder/empty-folder.component.scss new file mode 100644 index 000000000..2da90ab1c --- /dev/null +++ b/src/app/components/empty-folder/empty-folder.component.scss @@ -0,0 +1,29 @@ +@import 'variables'; + +.app-empty-folder { + color: $alfresco-secondary-text-color; + display: flex; + flex-direction: column; + align-items: center; + + &__icon { + font-size: 52px; + height: 52px; + width: 52px; + } + + p { + line-height: 0; + } + + &__title { + font-size: 18px; + font-weight: 600; + } + + &__subtitle, + &__text { + font-size: 14px; + font-weight: 300; + } +} diff --git a/src/app/components/empty-folder/empty-folder.component.spec.ts b/src/app/components/empty-folder/empty-folder.component.spec.ts new file mode 100644 index 000000000..32e4d5571 --- /dev/null +++ b/src/app/components/empty-folder/empty-folder.component.spec.ts @@ -0,0 +1,33 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { MatIconModule } from '@angular/material'; +import { TranslateModule } from '@ngx-translate/core'; + +import { EmptyFolderComponent } from './empty-folder.component'; + +describe('EmptyFolderComponent', () => { + let component: EmptyFolderComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + TranslateModule.forRoot() + ], + declarations: [ + EmptyFolderComponent + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EmptyFolderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/empty-folder/empty-folder.component.ts b/src/app/components/empty-folder/empty-folder.component.ts new file mode 100644 index 000000000..4e137d1de --- /dev/null +++ b/src/app/components/empty-folder/empty-folder.component.ts @@ -0,0 +1,22 @@ +import { Component, Input, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; + +@Component({ + selector: 'app-empty-folder', + templateUrl: './empty-folder.component.html', + styleUrls: ['./empty-folder.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None, + // tslint:disable-next-line:use-host-property-decorator + host: { class: 'app-empty-folder' } +}) +export class EmptyFolderComponent { + + @Input() + icon = 'cake'; + + @Input() + title = ''; + + @Input() + subtitle = ''; +} diff --git a/src/app/components/favorites/favorites.component.html b/src/app/components/favorites/favorites.component.html index 574d197a3..bd894cfe2 100644 --- a/src/app/components/favorites/favorites.component.html +++ b/src/app/components/favorites/favorites.component.html @@ -88,11 +88,11 @@ -
- star_rate -

{{ 'APP.BROWSE.FAVORITES.EMPTY_STATE.TITLE' | translate }}

-

{{ 'APP.BROWSE.FAVORITES.EMPTY_STATE.TEXT' | translate }}

-
+ +
diff --git a/src/app/components/libraries/libraries.component.html b/src/app/components/libraries/libraries.component.html index 3ad46c62e..170a296c1 100644 --- a/src/app/components/libraries/libraries.component.html +++ b/src/app/components/libraries/libraries.component.html @@ -21,11 +21,11 @@ -
- group_work -

{{ 'APP.BROWSE.LIBRARIES.EMPTY_STATE.TITLE' | translate }}

-

{{ 'APP.BROWSE.LIBRARIES.EMPTY_STATE.TEXT' | translate }}

-
+ +
diff --git a/src/app/components/recent-files/recent-files.component.html b/src/app/components/recent-files/recent-files.component.html index 25d6ec207..98c1bd5ef 100644 --- a/src/app/components/recent-files/recent-files.component.html +++ b/src/app/components/recent-files/recent-files.component.html @@ -84,11 +84,11 @@ -
- access_time -

{{ 'APP.BROWSE.RECENT.EMPTY_STATE.TITLE' | translate }}

-

{{ 'APP.BROWSE.RECENT.EMPTY_STATE.TEXT' | translate }}

-
+ +
diff --git a/src/app/components/shared-files/shared-files.component.html b/src/app/components/shared-files/shared-files.component.html index 649176b2b..a7888c6b1 100644 --- a/src/app/components/shared-files/shared-files.component.html +++ b/src/app/components/shared-files/shared-files.component.html @@ -89,11 +89,11 @@ -
- people -

{{ 'APP.BROWSE.SHARED.EMPTY_STATE.TITLE' | translate }}

-

{{ 'APP.BROWSE.SHARED.EMPTY_STATE.TEXT' | translate }}

-
+ +
diff --git a/src/app/components/trashcan/trashcan.component.html b/src/app/components/trashcan/trashcan.component.html index 91af9997b..e01621e23 100644 --- a/src/app/components/trashcan/trashcan.component.html +++ b/src/app/components/trashcan/trashcan.component.html @@ -38,12 +38,12 @@ -
- delete -

{{ 'APP.BROWSE.TRASHCAN.EMPTY_STATE.TITLE' | translate }}

-

{{ 'APP.BROWSE.TRASHCAN.EMPTY_STATE.FIRST_TEXT' | translate }}

-

{{ 'APP.BROWSE.TRASHCAN.EMPTY_STATE.SECOND_TEXT' | translate }}

-
+ +

{{ 'APP.BROWSE.TRASHCAN.EMPTY_STATE.FIRST_TEXT' | translate }}

+

{{ 'APP.BROWSE.TRASHCAN.EMPTY_STATE.SECOND_TEXT' | translate }}

+
diff --git a/src/app/ui/overrides/_alfresco-document-list.scss b/src/app/ui/overrides/_alfresco-document-list.scss index 7b9042a8c..4cfaf424d 100644 --- a/src/app/ui/overrides/_alfresco-document-list.scss +++ b/src/app/ui/overrides/_alfresco-document-list.scss @@ -98,31 +98,4 @@ adf-document-list { cursor: default; } } - - &__block { - color: $alfresco-secondary-text-color; - display: flex; - flex-direction: column; - align-items: center; - - p { - line-height: 0; - } - } - - &__title { - font-size: 18px; - font-weight: 600; - } - - &__subtitle { - font-size: 14px; - font-weight: 300; - } - - &__block > mat-icon { - font-size: 52px; - height: 52px; - width: 52px; - } } From 3a55411f404499b1d0bcc3d69e50451b10889182 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 27 Feb 2018 15:30:24 +0000 Subject: [PATCH 47/69] [ACA-99] Viewer actions (#203) * "toggle favorite" action * copy and move actions * move actions to the "more" menu --- .../services/content-management.service.ts | 8 ++++ .../components/preview/preview.component.html | 41 +++++++++++++++---- .../preview/preview.component.spec.ts | 5 ++- .../components/preview/preview.component.ts | 18 ++++++-- .../ui/overrides/_alfresco-document-list.scss | 4 -- 5 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/app/common/services/content-management.service.ts b/src/app/common/services/content-management.service.ts index 125876f5c..eebdce4e4 100644 --- a/src/app/common/services/content-management.service.ts +++ b/src/app/common/services/content-management.service.ts @@ -57,6 +57,14 @@ export class ContentManagementService { return this.nodeHasPermission(node, 'delete'); } + canMoveNode(node: Node): boolean { + return this.nodeHasPermission(node, 'delete'); + } + + canCopyNode(node: Node): boolean { + return true; + } + async deleteNode(node: Node) { if (this.canDeleteNode(node)) { try { diff --git a/src/app/components/preview/preview.component.html b/src/app/components/preview/preview.component.html index c7f0c8de4..7b954934c 100644 --- a/src/app/components/preview/preview.component.html +++ b/src/app/components/preview/preview.component.html @@ -9,15 +9,42 @@ (navigateBefore)="onNavigateBefore()" (navigateNext)="onNavigateNext()"> - + - - + + + + + + + diff --git a/src/app/components/preview/preview.component.spec.ts b/src/app/components/preview/preview.component.spec.ts index e653a9194..bc7941c71 100644 --- a/src/app/components/preview/preview.component.spec.ts +++ b/src/app/components/preview/preview.component.spec.ts @@ -29,7 +29,7 @@ import { RouterTestingModule } from '@angular/router/testing'; import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { AlfrescoApiService, UserPreferencesService, TranslationService, TranslationMock, - AppConfigService, StorageService, CookieService, NotificationService + AppConfigService, StorageService, CookieService, NotificationService, NodeFavoriteDirective } from '@alfresco/adf-core'; import { TranslateModule } from '@ngx-translate/core'; import { HttpClientModule } from '@angular/common/http'; @@ -67,7 +67,8 @@ describe('PreviewComponent', () => { ContentManagementService ], declarations: [ - PreviewComponent + PreviewComponent, + NodeFavoriteDirective ], schemas: [ NO_ERRORS_SCHEMA ] }) diff --git a/src/app/components/preview/preview.component.ts b/src/app/components/preview/preview.component.ts index b671b39a3..8ec5d82b6 100644 --- a/src/app/components/preview/preview.component.ts +++ b/src/app/components/preview/preview.component.ts @@ -26,7 +26,7 @@ import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { AlfrescoApiService, UserPreferencesService, ObjectUtils } from '@alfresco/adf-core'; -import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { Node, MinimalNodeEntity } from 'alfresco-js-api'; import { ContentManagementService } from '../../common/services/content-management.service'; @Component({ @@ -39,7 +39,7 @@ import { ContentManagementService } from '../../common/services/content-manageme }) export class PreviewComponent implements OnInit { - node: MinimalNodeEntryEntity; + node: Node; previewLocation: string = null; routesSkipNavigation = [ 'shared', 'recent-files', 'favorites' ]; navigateSource: string = null; @@ -51,6 +51,8 @@ export class PreviewComponent implements OnInit { nextNodeId: string; navigateMultiple = false; + selectedEntities: MinimalNodeEntity[] = []; + constructor(private router: Router, private route: ActivatedRoute, private apiService: AlfrescoApiService, @@ -93,8 +95,10 @@ export class PreviewComponent implements OnInit { if (id) { try { this.node = await this.apiService.nodesApi.getNodeInfo(id, { - include: [ 'allowableOperations'] + include: ['allowableOperations'] }); + this.selectedEntities = [{ entry: this.node }]; + if (this.node && this.node.isFile) { const nearest = await this.getNearestNodes(this.node.id, this.node.parentId); @@ -331,4 +335,12 @@ export class PreviewComponent implements OnInit { } catch { } } + + canMoveFile(): boolean { + return this.content.canMoveNode(this.node); + } + + canCopyFile(): boolean { + return this.content.canCopyNode(this.node); + } } diff --git a/src/app/ui/overrides/_alfresco-document-list.scss b/src/app/ui/overrides/_alfresco-document-list.scss index 4cfaf424d..7598e4485 100644 --- a/src/app/ui/overrides/_alfresco-document-list.scss +++ b/src/app/ui/overrides/_alfresco-document-list.scss @@ -54,10 +54,6 @@ adf-document-list { } } - .adf-no-content-container { - border: none !important; - } - .adf-datatable-header:first-of-type, .adf-datatable-header.adf-data-table-cell--image, .adf-data-table-cell:first-of-type, .adf-data-table-cell.adf-data-table-cell--image { padding-left: 24px; From 77bc9d556d46b7682917f5b1ca40f6957fd957be Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Wed, 28 Feb 2018 10:06:01 +0200 Subject: [PATCH 48/69] last row border-bottom (#204) --- src/app/ui/overrides/_alfresco-document-list.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/ui/overrides/_alfresco-document-list.scss b/src/app/ui/overrides/_alfresco-document-list.scss index 7598e4485..1e03f7719 100644 --- a/src/app/ui/overrides/_alfresco-document-list.scss +++ b/src/app/ui/overrides/_alfresco-document-list.scss @@ -83,6 +83,10 @@ adf-document-list { position: absolute; max-width: calc(100% - 2em); } + + .adf-datatable-row:last-child .adf-datatable-table-cell { + border-bottom: 1px solid rgba(0, 0, 0, 0.07); + } } .empty-list { From bd6e021581504f464104bbe03e9f70cc1d8ea145 Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Wed, 28 Feb 2018 13:21:20 +0200 Subject: [PATCH 49/69] fix title (#205) --- src/app/components/trashcan/trashcan.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/components/trashcan/trashcan.component.html b/src/app/components/trashcan/trashcan.component.html index e01621e23..844c2f346 100644 --- a/src/app/components/trashcan/trashcan.component.html +++ b/src/app/components/trashcan/trashcan.component.html @@ -40,7 +40,7 @@ + title="APP.BROWSE.TRASHCAN.EMPTY_STATE.TITLE">

{{ 'APP.BROWSE.TRASHCAN.EMPTY_STATE.FIRST_TEXT' | translate }}

{{ 'APP.BROWSE.TRASHCAN.EMPTY_STATE.SECOND_TEXT' | translate }}

From 8558d1f3cad60882eb6da04f40732566808585e6 Mon Sep 17 00:00:00 2001 From: suzanadirla Date: Thu, 1 Mar 2018 16:59:54 +0200 Subject: [PATCH 50/69] [ACA-1145] File name incorrectly appears in the breadcrumb when opening the destination picker for a shared node when user does not have permissions on node's parent folder (#206) * [ACA-1145] File name incorrectly appears in the breadcrumb when opening the destination picker for a shared node when user does not have permissions on node's parent folder * [ACA-1145] send the correct argument --- .../common/directives/node-move.directive.ts | 2 +- .../services/node-actions.service.spec.ts | 38 ++----------------- .../common/services/node-actions.service.ts | 18 +-------- 3 files changed, 6 insertions(+), 52 deletions(-) diff --git a/src/app/common/directives/node-move.directive.ts b/src/app/common/directives/node-move.directive.ts index 678792eda..6903072cc 100644 --- a/src/app/common/directives/node-move.directive.ts +++ b/src/app/common/directives/node-move.directive.ts @@ -125,7 +125,7 @@ export class NodeMoveDirective { const beforePartialSuccessMessage = (successMessage && partialSuccessMessage) ? ' ' : ''; const beforeFailedMessage = ((successMessage || partialSuccessMessage) && failedMessage) ? ' ' : ''; - const initialParentId = this.nodeActionsService.getFirstParentId(this.selection); + const initialParentId = this.nodeActionsService.getEntryParentId(this.selection[0].entry); this.translation.get( [successMessage, partialSuccessMessage, failedMessage], diff --git a/src/app/common/services/node-actions.service.spec.ts b/src/app/common/services/node-actions.service.spec.ts index 71749b605..d7c7f8e69 100644 --- a/src/app/common/services/node-actions.service.spec.ts +++ b/src/app/common/services/node-actions.service.spec.ts @@ -223,36 +223,6 @@ describe('NodeActionsService', () => { })); }); - describe('getFirstParentId', () => { - it('should give the parentId, if that exists on the node entry', () => { - const parentID = 'parent-id'; - const contentEntities = [ {entry: {nodeId: '1234', parentId: parentID}} ]; - - expect(service.getFirstParentId(contentEntities)).toBe(parentID); - }); - - it('should give the last element in path property, if parentId is missing and path exists on the node entry', () => { - const firstParentId = 'parent-0-id'; - const contentEntities = [ {entry: {nodeId: '1234', path: {elements: [ {id: 'parent-1-id'}, { id: firstParentId} ]} }} ]; - - expect(service.getFirstParentId(contentEntities)).toBe(firstParentId); - }); - - it('should give the id of the first node entry, if none of nodes has either parentId, or path properties', () => { - const nodeID = '1234'; - const contentEntities = [ {entry: {id: nodeID}}, {entry: {id: `${nodeID}-2`}} ]; - - expect(service.getFirstParentId(contentEntities)).toBe(nodeID); - }); - - it('should give the nodeId of the first node entry, if none of nodes has either parentId, or path properties', () => { - const nodeID = '1234'; - const contentEntities = [ {entry: {nodeId: nodeID}}, {entry: {id: `${nodeID}-2`}} ]; - - expect(service.getFirstParentId(contentEntities)).toBe(nodeID); - }); - }); - describe('getEntryParentId', () => { it('should return the parentId, if that exists on the node entry', () => { const parentID = 'parent-id'; @@ -278,7 +248,7 @@ describe('NodeActionsService', () => { fileToCopy = new TestNode(fileId, isFile, 'file-name'); folderToCopy = new TestNode(); - spyOn(service, 'getFirstParentId').and.returnValue('parent-id'); + spyOn(service, 'getEntryParentId').and.returnValue('parent-id'); const dialog = TestBed.get(MatDialog); spyOn(dialog, 'open').and.callFake((contentNodeSelectorComponent: any, data: any) => { @@ -335,7 +305,7 @@ describe('NodeActionsService', () => { it('should use the custom data object with custom rowFilter & imageResolver & title with destination picker', () => { const spyOnBatchOperation = spyOn(service, 'doBatchOperation').and.callThrough(); const spyOnDestinationPicker = spyOn(service, 'getContentNodeSelection').and.callThrough(); - spyOn(service, 'getFirstParentId').and.returnValue('parent-id'); + spyOn(service, 'getEntryParentId').and.returnValue('parent-id'); let testContentNodeSelectorComponentData; const dialog = TestBed.get(MatDialog); @@ -363,7 +333,7 @@ describe('NodeActionsService', () => { it('should use the ContentNodeSelectorComponentData object with file name in title', () => { const spyOnBatchOperation = spyOn(service, 'doBatchOperation').and.callThrough(); spyOn(service, 'getContentNodeSelection').and.callThrough(); - spyOn(service, 'getFirstParentId').and.returnValue('parent-id'); + spyOn(service, 'getEntryParentId').and.returnValue('parent-id'); let testContentNodeSelectorComponentData; const dialog = TestBed.get(MatDialog); @@ -383,7 +353,7 @@ describe('NodeActionsService', () => { it('should use the ContentNodeSelectorComponentData object without file name in title, if no name exists', () => { const spyOnBatchOperation = spyOn(service, 'doBatchOperation').and.callThrough(); spyOn(service, 'getContentNodeSelection').and.callThrough(); - spyOn(service, 'getFirstParentId').and.returnValue('parent-id'); + spyOn(service, 'getEntryParentId').and.returnValue('parent-id'); let testContentNodeSelectorComponentData; const dialog = TestBed.get(MatDialog); diff --git a/src/app/common/services/node-actions.service.ts b/src/app/common/services/node-actions.service.ts index 318b44da4..63e301af5 100644 --- a/src/app/common/services/node-actions.service.ts +++ b/src/app/common/services/node-actions.service.ts @@ -144,22 +144,6 @@ export class NodeActionsService { return !notAllowedNode; } - getFirstParentId(nodeEntities: any[]): string { - for (let i = 0; i < nodeEntities.length; i++) { - const nodeEntry = nodeEntities[i].entry; - - if (nodeEntry.parentId) { - return nodeEntry.parentId; - - } else if (nodeEntry.path && nodeEntry.path.elements && nodeEntry.path.elements.length) { - return nodeEntry.path.elements[nodeEntry.path.elements.length - 1].id; - } - } - - // if no parent data is found, return the id of first item / the nodeId in case of Shared Files - return nodeEntities[0].entry.nodeId || nodeEntities[0].entry.id; - } - getEntryParentId(nodeEntry: any) { let entryParentId = ''; @@ -174,7 +158,7 @@ export class NodeActionsService { } getContentNodeSelection(action: string, contentEntities: MinimalNodeEntity[]): Subject { - const currentParentFolderId = this.getFirstParentId(contentEntities); + const currentParentFolderId = this.getEntryParentId(contentEntities[0]); const customDropdown: SitePaging = { list: { From 18e657d2ba21b6689d91ea19dca1b97704f7691f Mon Sep 17 00:00:00 2001 From: suzanadirla Date: Thu, 1 Mar 2018 17:57:55 +0200 Subject: [PATCH 51/69] [ACA-1162] Destination picker has incorrect title when opened for multiple selection of items (#207) --- src/app/common/services/node-actions.service.spec.ts | 6 +++--- src/app/common/services/node-actions.service.ts | 4 +++- src/assets/i18n/en.json | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/app/common/services/node-actions.service.spec.ts b/src/app/common/services/node-actions.service.spec.ts index d7c7f8e69..3f01eb5fa 100644 --- a/src/app/common/services/node-actions.service.spec.ts +++ b/src/app/common/services/node-actions.service.spec.ts @@ -324,7 +324,7 @@ describe('NodeActionsService', () => { expect(testContentNodeSelectorComponentData.data.rowFilter({node: destinationFolder})).toBeDefined(); expect(testContentNodeSelectorComponentData.data.imageResolver({node: destinationFolder})).toBeDefined(); expect(testContentNodeSelectorComponentData.data.title).toBe('NODE_SELECTOR.COPY_ITEMS'); - expect(translationService.instant).toHaveBeenCalledWith('NODE_SELECTOR.COPY_ITEMS', {name: ''}); + expect(translationService.instant).toHaveBeenCalledWith('NODE_SELECTOR.COPY_ITEMS', {name: '', number: 2}); destinationFolder.entry['allowableOperations'] = ['update']; expect(testContentNodeSelectorComponentData.data.imageResolver({node: destinationFolder})).toBeDefined(); @@ -347,7 +347,7 @@ describe('NodeActionsService', () => { expect(spyOnBatchOperation).toHaveBeenCalled(); expect(testContentNodeSelectorComponentData).toBeDefined(); expect(testContentNodeSelectorComponentData.data.title).toBe('NODE_SELECTOR.COPY_ITEM'); - expect(translationService.instant).toHaveBeenCalledWith('NODE_SELECTOR.COPY_ITEM', {name: 'entry-name'}); + expect(translationService.instant).toHaveBeenCalledWith('NODE_SELECTOR.COPY_ITEM', {name: 'entry-name', number: 1}); }); it('should use the ContentNodeSelectorComponentData object without file name in title, if no name exists', () => { @@ -367,7 +367,7 @@ describe('NodeActionsService', () => { expect(spyOnBatchOperation).toHaveBeenCalled(); expect(testContentNodeSelectorComponentData).toBeDefined(); expect(testContentNodeSelectorComponentData.data.title).toBe('NODE_SELECTOR.COPY_ITEMS'); - expect(translationService.instant).toHaveBeenCalledWith('NODE_SELECTOR.COPY_ITEMS', {name: ''}); + expect(translationService.instant).toHaveBeenCalledWith('NODE_SELECTOR.COPY_ITEMS', {name: '', number: 1}); }); }); diff --git a/src/app/common/services/node-actions.service.ts b/src/app/common/services/node-actions.service.ts index 63e301af5..fa13a5b56 100644 --- a/src/app/common/services/node-actions.service.ts +++ b/src/app/common/services/node-actions.service.ts @@ -229,7 +229,9 @@ export class NodeActionsService { name = nodes[0].entry.name; keyPrefix = 'ITEM'; } - return this.translation.instant(`NODE_SELECTOR.${action.toUpperCase()}_${keyPrefix}`, {name}); + + const number = nodes.length; + return this.translation.instant(`NODE_SELECTOR.${action.toUpperCase()}_${keyPrefix}`, {name, number}); } private canCopyMoveInsideIt(entry: MinimalNodeEntryEntity): boolean { diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index b3a09d6dd..1eb6a59f8 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -188,9 +188,9 @@ }, "NODE_SELECTOR": { "COPY_ITEM": "Copy '{{ name }}' to ...", - "COPY_ITEMS": "Copy to ...", + "COPY_ITEMS": "Copy {{ number }} items to ...", "MOVE_ITEM": "Move '{{ name }}' to ...", - "MOVE_ITEMS": "Move to ...", + "MOVE_ITEMS": "Move {{ number }} items to ...", "SEARCH": "Search" } } From bd33afb17541882f9432a1a8af1c32ae647e24f4 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 1 Mar 2018 18:15:40 +0000 Subject: [PATCH 52/69] docker setup fixes for public images (#208) * docker setup fixes for public images * update travis config * reverse docs change --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 4ad12144e..a2abdd461 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,7 @@ after_success: - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi) - echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH" - export TAG=`if [ "$BRANCH" == "master" ]; then echo "latest"; else echo $BRANCH ; fi` + - sed -i 's/{:port}/:8080/1' ./dist/app.config.json - docker build -t $DOCKER_REPO:$TAG . # Publish extra image based on Travis build number - docker tag $DOCKER_REPO:$TAG $DOCKER_REPO:travis-$TRAVIS_BUILD_NUMBER From c9ffe0ac244c751a634d57fc58714fd610282a43 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 1 Mar 2018 19:04:22 +0000 Subject: [PATCH 53/69] use alpine image to reduce image size by half (#209) --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1c3cdbc27..0d52ed48c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM nginx +FROM nginx:alpine COPY nginx.conf /etc/nginx/nginx.conf From 14c9995915d8f18542c2798a9c92d4e7d2e668df Mon Sep 17 00:00:00 2001 From: suzanadirla Date: Fri, 2 Mar 2018 11:12:34 +0200 Subject: [PATCH 54/69] [ACA-1146] The main node of the breadcrumb is not displayed in File Libraries (#210) fixes https://issues.alfresco.com/jira/browse/ACA-1146 --- src/app/common/services/node-actions.service.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/app/common/services/node-actions.service.ts b/src/app/common/services/node-actions.service.ts index fa13a5b56..2c8355c7e 100644 --- a/src/app/common/services/node-actions.service.ts +++ b/src/app/common/services/node-actions.service.ts @@ -39,6 +39,7 @@ export class NodeActionsService { contentCopied: Subject = new Subject(); contentMoved: Subject = new Subject(); moveDeletedEntries: any[] = []; + isSitesDestinationAvailable = false; constructor(private contentService: ContentService, private dialog: MatDialog, @@ -181,6 +182,7 @@ export class NodeActionsService { const title = this.getTitleTranslation(action, contentEntities); + this.isSitesDestinationAvailable = false; const data: ContentNodeSelectorComponentData = { title: title, currentFolderId: currentParentFolderId, @@ -278,6 +280,11 @@ export class NodeActionsService { elements.splice(0, 1); } } + } else if (node === null && this.isSitesDestinationAvailable) { + node = { + name: this.translation.instant('APP.BROWSE.LIBRARIES.TITLE'), + path: { elements: [] } + }; } return node; @@ -546,6 +553,8 @@ export class NodeActionsService { // todo: review once 1.10-beta6 is out private rowFilter(row: /*ShareDataRow*/ any): boolean { const node: MinimalNodeEntryEntity = row.node.entry; + + this.isSitesDestinationAvailable = !!node['guid']; return (!node.isFile && (node.nodeType !== 'app:folderlink')); } From 267ba27635e66308a19ec876a5b6b9af65cebad6 Mon Sep 17 00:00:00 2001 From: suzanadirla Date: Fri, 2 Mar 2018 13:14:01 +0200 Subject: [PATCH 55/69] [ACA-1169] Default location of the copy/move file is not displayed (#211) fix for https://issues.alfresco.com/jira/browse/ACA-1169 --- src/app/common/services/node-actions.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/common/services/node-actions.service.ts b/src/app/common/services/node-actions.service.ts index 2c8355c7e..2b1aa82f0 100644 --- a/src/app/common/services/node-actions.service.ts +++ b/src/app/common/services/node-actions.service.ts @@ -145,7 +145,7 @@ export class NodeActionsService { return !notAllowedNode; } - getEntryParentId(nodeEntry: any) { + getEntryParentId(nodeEntry: MinimalNodeEntryEntity) { let entryParentId = ''; if (nodeEntry.parentId) { @@ -159,7 +159,7 @@ export class NodeActionsService { } getContentNodeSelection(action: string, contentEntities: MinimalNodeEntity[]): Subject { - const currentParentFolderId = this.getEntryParentId(contentEntities[0]); + const currentParentFolderId = this.getEntryParentId(contentEntities[0].entry); const customDropdown: SitePaging = { list: { From f0c56442622c26b7104e59b786b2ce0bcf4314a9 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 2 Mar 2018 12:25:49 +0000 Subject: [PATCH 56/69] docs update --- docs/docker.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/docker.md b/docs/docker.md index fcddc4aca..e4961a3f4 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -6,6 +6,28 @@ This article assumes you are familiar with Docker and know how to create images You can create a Docker image to run Alfresco Content App in the container. +## Using public Docker images + +You can find all latest images for ACA in the [alfresco-content-app]( https://hub.docker.com/r/alfresco/alfresco-content-app/) DockerHub repository. + +### Tags + +- `latest`: latest stable release (`master` branch), available with 1.1 release or later +- `development`: most recent code (`development` branch) + +In addition, there are images for feature branches, pull requests and Travis CI builds. + +### Example + +You can run latest `development` build locally with the following command: + +```sh +docker run -p 3000:80 alfresco/alfresco-content-app:development +``` + +The default image expects an ACS 5.2.2 or later running at port `8080`. +You may also need CORS settings to be applied for your ACS installation or image. + ## Building from source code You need to run the following commands to build the project from the source code: From 6688e236d9d73788a0d2374477dc1e08fb02c1d5 Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Fri, 2 Mar 2018 16:11:31 +0200 Subject: [PATCH 57/69] update copyright year on license headers and login page (#212) --- postbuild-dev.js | 2 +- src/app/adf.module.ts | 2 +- src/app/app.component.ts | 2 +- src/app/app.module.ts | 2 +- src/app/app.routes.ts | 2 +- src/app/common/common.module.ts | 2 +- src/app/common/directives/node-copy.directive.spec.ts | 2 +- src/app/common/directives/node-copy.directive.ts | 2 +- src/app/common/directives/node-delete.directive.spec.ts | 2 +- src/app/common/directives/node-delete.directive.ts | 2 +- src/app/common/directives/node-move.directive.spec.ts | 2 +- src/app/common/directives/node-move.directive.ts | 2 +- .../common/directives/node-permanent-delete.directive.spec.ts | 2 +- src/app/common/directives/node-permanent-delete.directive.ts | 2 +- src/app/common/directives/node-restore.directive.spec.ts | 2 +- src/app/common/directives/node-restore.directive.ts | 2 +- src/app/common/directives/node-unshare.directive.ts | 2 +- src/app/common/material.module.ts | 2 +- src/app/common/services/browsing-files.service.spec.ts | 2 +- src/app/common/services/browsing-files.service.ts | 2 +- src/app/common/services/content-management.service.ts | 2 +- src/app/common/services/node-actions.service.spec.ts | 2 +- src/app/common/services/node-actions.service.ts | 2 +- src/app/components/about/about.component.ts | 2 +- src/app/components/current-user/current-user.component.spec.ts | 2 +- src/app/components/current-user/current-user.component.ts | 2 +- src/app/components/favorites/favorites.component.spec.ts | 2 +- src/app/components/favorites/favorites.component.ts | 2 +- src/app/components/files/files.component.spec.ts | 2 +- src/app/components/files/files.component.ts | 2 +- src/app/components/generic-error/generic-error.component.ts | 2 +- src/app/components/header/header.component.spec.ts | 2 +- src/app/components/header/header.component.ts | 2 +- src/app/components/layout/layout.component.spec.ts | 2 +- src/app/components/layout/layout.component.ts | 2 +- src/app/components/libraries/libraries.component.spec.ts | 2 +- src/app/components/libraries/libraries.component.ts | 2 +- src/app/components/location-link/location-link.component.ts | 2 +- src/app/components/login/login.component.html | 2 +- src/app/components/login/login.component.spec.ts | 2 +- src/app/components/login/login.component.ts | 2 +- src/app/components/page.component.spec.ts | 2 +- src/app/components/page.component.ts | 2 +- src/app/components/preview/preview.component.spec.ts | 2 +- src/app/components/preview/preview.component.ts | 2 +- src/app/components/recent-files/recent-files.component.spec.ts | 2 +- src/app/components/recent-files/recent-files.component.ts | 2 +- src/app/components/search/search.component.spec.ts | 2 +- src/app/components/search/search.component.ts | 2 +- src/app/components/shared-files/shared-files.component.spec.ts | 2 +- src/app/components/shared-files/shared-files.component.ts | 2 +- src/app/components/sidenav/sidenav.component.spec.ts | 2 +- src/app/components/sidenav/sidenav.component.ts | 2 +- src/app/components/trashcan/trashcan.component.spec.ts | 2 +- src/app/components/trashcan/trashcan.component.ts | 2 +- src/environments/environment.prod.ts | 2 +- src/environments/environment.ts | 2 +- src/main.ts | 2 +- src/polyfills.ts | 2 +- src/test.ts | 2 +- src/typings.d.ts | 2 +- 61 files changed, 61 insertions(+), 61 deletions(-) diff --git a/postbuild-dev.js b/postbuild-dev.js index abd88c43e..b010b8e91 100644 --- a/postbuild-dev.js +++ b/postbuild-dev.js @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/adf.module.ts b/src/app/adf.module.ts index 15f8206b1..40655f00f 100644 --- a/src/app/adf.module.ts +++ b/src/app/adf.module.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 847d75faa..23990db92 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ff150bc5e..f1f138a22 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 5f466094c..513eeec54 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/common.module.ts b/src/app/common/common.module.ts index 96b3f78c6..f6ea225ba 100644 --- a/src/app/common/common.module.ts +++ b/src/app/common/common.module.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/directives/node-copy.directive.spec.ts b/src/app/common/directives/node-copy.directive.spec.ts index a09b5dc54..e32cd3c9a 100644 --- a/src/app/common/directives/node-copy.directive.spec.ts +++ b/src/app/common/directives/node-copy.directive.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/directives/node-copy.directive.ts b/src/app/common/directives/node-copy.directive.ts index 656865820..91c61268e 100644 --- a/src/app/common/directives/node-copy.directive.ts +++ b/src/app/common/directives/node-copy.directive.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/directives/node-delete.directive.spec.ts b/src/app/common/directives/node-delete.directive.spec.ts index e263a8e94..6bc7d2acf 100644 --- a/src/app/common/directives/node-delete.directive.spec.ts +++ b/src/app/common/directives/node-delete.directive.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/directives/node-delete.directive.ts b/src/app/common/directives/node-delete.directive.ts index 90e3bcd4a..dc76f3ab8 100644 --- a/src/app/common/directives/node-delete.directive.ts +++ b/src/app/common/directives/node-delete.directive.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/directives/node-move.directive.spec.ts b/src/app/common/directives/node-move.directive.spec.ts index 37ad8b9b2..9017c61e5 100644 --- a/src/app/common/directives/node-move.directive.spec.ts +++ b/src/app/common/directives/node-move.directive.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/directives/node-move.directive.ts b/src/app/common/directives/node-move.directive.ts index 6903072cc..812e687ec 100644 --- a/src/app/common/directives/node-move.directive.ts +++ b/src/app/common/directives/node-move.directive.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/directives/node-permanent-delete.directive.spec.ts b/src/app/common/directives/node-permanent-delete.directive.spec.ts index eac0bd309..bf82a5caa 100644 --- a/src/app/common/directives/node-permanent-delete.directive.spec.ts +++ b/src/app/common/directives/node-permanent-delete.directive.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/directives/node-permanent-delete.directive.ts b/src/app/common/directives/node-permanent-delete.directive.ts index 6e9be55a7..c70495ee2 100644 --- a/src/app/common/directives/node-permanent-delete.directive.ts +++ b/src/app/common/directives/node-permanent-delete.directive.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/directives/node-restore.directive.spec.ts b/src/app/common/directives/node-restore.directive.spec.ts index 23fe3319f..2a9c305f3 100644 --- a/src/app/common/directives/node-restore.directive.spec.ts +++ b/src/app/common/directives/node-restore.directive.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/directives/node-restore.directive.ts b/src/app/common/directives/node-restore.directive.ts index c2822e493..8d16d8a67 100644 --- a/src/app/common/directives/node-restore.directive.ts +++ b/src/app/common/directives/node-restore.directive.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/directives/node-unshare.directive.ts b/src/app/common/directives/node-unshare.directive.ts index ca1a454ed..abd6f2b71 100644 --- a/src/app/common/directives/node-unshare.directive.ts +++ b/src/app/common/directives/node-unshare.directive.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/material.module.ts b/src/app/common/material.module.ts index b516f4ec6..3c1cb4fd8 100644 --- a/src/app/common/material.module.ts +++ b/src/app/common/material.module.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/services/browsing-files.service.spec.ts b/src/app/common/services/browsing-files.service.spec.ts index 121bf4914..fea859cf5 100644 --- a/src/app/common/services/browsing-files.service.spec.ts +++ b/src/app/common/services/browsing-files.service.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/services/browsing-files.service.ts b/src/app/common/services/browsing-files.service.ts index c47067f0f..e55f7e723 100644 --- a/src/app/common/services/browsing-files.service.ts +++ b/src/app/common/services/browsing-files.service.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/services/content-management.service.ts b/src/app/common/services/content-management.service.ts index eebdce4e4..48e71eb93 100644 --- a/src/app/common/services/content-management.service.ts +++ b/src/app/common/services/content-management.service.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/services/node-actions.service.spec.ts b/src/app/common/services/node-actions.service.spec.ts index 3f01eb5fa..ffd2e8e11 100644 --- a/src/app/common/services/node-actions.service.spec.ts +++ b/src/app/common/services/node-actions.service.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/common/services/node-actions.service.ts b/src/app/common/services/node-actions.service.ts index 2b1aa82f0..f67f6ed1e 100644 --- a/src/app/common/services/node-actions.service.ts +++ b/src/app/common/services/node-actions.service.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/about/about.component.ts b/src/app/components/about/about.component.ts index d337bbab1..2912748b9 100644 --- a/src/app/components/about/about.component.ts +++ b/src/app/components/about/about.component.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/current-user/current-user.component.spec.ts b/src/app/components/current-user/current-user.component.spec.ts index 5adc0920a..5eef09d37 100644 --- a/src/app/components/current-user/current-user.component.spec.ts +++ b/src/app/components/current-user/current-user.component.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/current-user/current-user.component.ts b/src/app/components/current-user/current-user.component.ts index cc07ceac7..6ef40663a 100644 --- a/src/app/components/current-user/current-user.component.ts +++ b/src/app/components/current-user/current-user.component.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/favorites/favorites.component.spec.ts b/src/app/components/favorites/favorites.component.spec.ts index 9c695851e..d0175dda5 100644 --- a/src/app/components/favorites/favorites.component.spec.ts +++ b/src/app/components/favorites/favorites.component.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts index 1d656df89..65b1b3e3f 100644 --- a/src/app/components/favorites/favorites.component.ts +++ b/src/app/components/favorites/favorites.component.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts index e45aa7d7d..d6f7854ed 100644 --- a/src/app/components/files/files.component.spec.ts +++ b/src/app/components/files/files.component.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index 04e3032d0..d995daab3 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/generic-error/generic-error.component.ts b/src/app/components/generic-error/generic-error.component.ts index b5c6ad3bb..abfbf9a6d 100644 --- a/src/app/components/generic-error/generic-error.component.ts +++ b/src/app/components/generic-error/generic-error.component.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/header/header.component.spec.ts b/src/app/components/header/header.component.spec.ts index 09770857c..c32d91cfc 100644 --- a/src/app/components/header/header.component.spec.ts +++ b/src/app/components/header/header.component.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/header/header.component.ts b/src/app/components/header/header.component.ts index cd9636ea2..421944706 100644 --- a/src/app/components/header/header.component.ts +++ b/src/app/components/header/header.component.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/layout/layout.component.spec.ts b/src/app/components/layout/layout.component.spec.ts index 37b73bc4d..fc926fdef 100644 --- a/src/app/components/layout/layout.component.spec.ts +++ b/src/app/components/layout/layout.component.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/layout/layout.component.ts b/src/app/components/layout/layout.component.ts index a6b17facf..5be6ea1ce 100644 --- a/src/app/components/layout/layout.component.ts +++ b/src/app/components/layout/layout.component.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/libraries/libraries.component.spec.ts b/src/app/components/libraries/libraries.component.spec.ts index c34858680..8355d9b2f 100644 --- a/src/app/components/libraries/libraries.component.spec.ts +++ b/src/app/components/libraries/libraries.component.spec.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/libraries/libraries.component.ts b/src/app/components/libraries/libraries.component.ts index 8f3c503a2..6870d14e1 100644 --- a/src/app/components/libraries/libraries.component.ts +++ b/src/app/components/libraries/libraries.component.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/location-link/location-link.component.ts b/src/app/components/location-link/location-link.component.ts index d360294fe..91c74e3d0 100644 --- a/src/app/components/location-link/location-link.component.ts +++ b/src/app/components/location-link/location-link.component.ts @@ -2,7 +2,7 @@ * @license * Alfresco Example Content Application * - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2018 Alfresco Software Limited * * This file is part of the Alfresco Example Content Application. * If the software was purchased under a paid Alfresco license, the terms of diff --git a/src/app/components/login/login.component.html b/src/app/components/login/login.component.html index 94d00dbc5..b23521bf6 100644 --- a/src/app/components/login/login.component.html +++ b/src/app/components/login/login.component.html @@ -1,5 +1,5 @@ Date: Tue, 6 Mar 2018 10:24:36 +0000 Subject: [PATCH 58/69] upgrade to ADF 2.2.0 RTM (#214) --- package-lock.json | 5425 +++++++-------------------------------------- package.json | 6 +- yarn.lock | 464 ++-- 3 files changed, 1011 insertions(+), 4884 deletions(-) diff --git a/package-lock.json b/package-lock.json index 735f9e522..00f1f7e08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,11 +5,11 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a.tgz", - "integrity": "sha512-OaVop6kosAxDitrdARIxShZ1aZRTPybrM64Oj5IsDJ7Oz+cUF5c+LPubXrl8i4V1JbXJdP4/Ba/hmxoBAe8UPQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-2.2.0.tgz", + "integrity": "sha512-6IrBDtrBo4ekrEBc5850QLshfx4ZnxQtlq5OPTnrno1vNjOJlG30KCvspl+bDPcdc4iVRPRWgC4HpLKN6PArCQ==", "requires": { - "@alfresco/adf-core": "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a", + "@alfresco/adf-core": "2.2.0", "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", "@angular/common": "5.1.1", @@ -24,7 +24,7 @@ "@angular/platform-browser-dynamic": "5.1.1", "@angular/router": "5.1.1", "@ngx-translate/core": "9.1.1", - "alfresco-js-api": "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652", + "alfresco-js-api": "2.2.0", "chart.js": "2.5.0", "core-js": "2.4.1", "hammerjs": "2.0.8", @@ -61,9 +61,9 @@ } }, "@alfresco/adf-core": { - "version": "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a.tgz", - "integrity": "sha512-YVBcV1p6D9pxiLkgilSmGCzzF8mVoC7MEMZ48AGJEXtKryjFdZS0Py0h6RIwC44J+RJPHNkdq/NbrS0GfXh8DQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-2.2.0.tgz", + "integrity": "sha512-TXaVXi9p/S95oKZ8x3fR/NieHN77AWjliwntPI0mR95Syg3U+7aWJCJElU3TkIItceNo23qnoEJCFeQgc86N5w==", "requires": { "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", @@ -79,7 +79,7 @@ "@angular/platform-browser-dynamic": "5.1.1", "@angular/router": "5.1.1", "@ngx-translate/core": "9.1.1", - "alfresco-js-api": "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652", + "alfresco-js-api": "2.2.0", "chart.js": "2.5.0", "core-js": "2.4.1", "hammerjs": "2.0.8", @@ -235,7 +235,7 @@ "chalk": "2.2.2", "circular-dependency-plugin": "4.4.0", "common-tags": "1.7.2", - "copy-webpack-plugin": "4.4.2", + "copy-webpack-plugin": "4.5.0", "core-object": "3.1.5", "css-loader": "0.28.10", "cssnano": "3.10.0", @@ -243,15 +243,15 @@ "ember-cli-string-utils": "1.1.0", "exports-loader": "0.6.4", "extract-text-webpack-plugin": "3.0.2", - "file-loader": "1.1.9", + "file-loader": "1.1.11", "fs-extra": "4.0.3", "glob": "7.1.2", "html-webpack-plugin": "2.30.1", "istanbul-instrumenter-loader": "3.0.0", "karma-source-map-support": "1.2.0", "less": "2.7.3", - "less-loader": "4.0.5", - "license-webpack-plugin": "1.1.2", + "less-loader": "4.0.6", + "license-webpack-plugin": "1.2.3", "loader-utils": "1.1.0", "lodash": "4.17.5", "memory-fs": "0.4.1", @@ -267,7 +267,7 @@ "raw-loader": "0.5.1", "resolve": "1.5.0", "rxjs": "5.5.6", - "sass-loader": "6.0.6", + "sass-loader": "6.0.7", "semver": "5.5.0", "silent-error": "1.1.0", "source-map-loader": "0.2.3", @@ -279,7 +279,7 @@ "url-loader": "0.6.2", "webpack": "3.10.0", "webpack-dev-middleware": "1.12.2", - "webpack-dev-server": "2.11.1", + "webpack-dev-server": "2.11.2", "webpack-merge": "4.1.2", "webpack-sources": "1.1.0", "webpack-subresource-integrity": "1.0.4" @@ -532,9 +532,9 @@ "dev": true }, "accepts": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", - "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "dev": true, "requires": { "mime-types": "2.1.18", @@ -542,9 +542,9 @@ } }, "acorn": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.4.1.tgz", - "integrity": "sha512-XLmq3H/BVvW6/GbxKryGxWORz1ebilSsUDlyC27bXhWGWAZWkGwS6FLHjOlwFXNFoWFQEO/Df4u0YYd0K3BQgQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.0.tgz", + "integrity": "sha512-arn53F07VXmls4o4pUhSzBa4fvaagPRe7AVZ8l7NHxFWUie2DsuFSBMMNAkgzRlOhEhzAnxeKyaWVzOH4xqp/g==", "dev": true }, "acorn-dynamic-import": { @@ -570,7 +570,7 @@ "integrity": "sha512-efP54n3d1aLfjL2UMdaXa6DsswwzJeI5rqhbFvXMrKiJ6eJFpf+7R0zN7t8IC+XKn2YOAFAv6xbBNgHUkoHWLw==", "dev": true, "requires": { - "acorn": "5.4.1", + "acorn": "5.5.0", "xtend": "4.0.1" } }, @@ -612,9 +612,9 @@ } }, "ajv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", - "integrity": "sha1-r6wpW7qgFSRJ5SJ0LkVHwa6TKNI=", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.1.tgz", + "integrity": "sha1-KKarxJOiq+D7TIUHrK7bQ/pVBnE=", "requires": { "fast-deep-equal": "1.1.0", "fast-json-stable-stringify": "2.0.0", @@ -627,9 +627,9 @@ "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=" }, "alfresco-js-api": { - "version": "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652", - "resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652.tgz", - "integrity": "sha512-jYUUrzmTFgBJLfH2dVz/F386JDdV9L9Vms9n/jAV6s1gbxg6g8eIt3ThAr8P60lVNsW4zKSkPd3bGVyMHojrDQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-2.2.0.tgz", + "integrity": "sha512-lskswsRQSulpn8xLC5znj41k0FxJ6KwYh8OuTBytoA47/dT65lmA6CXQAL6et7NKWLcwByfdY+2quDrCt3Dgwg==", "requires": { "event-emitter": "0.3.4", "superagent": "3.8.2" @@ -714,9 +714,9 @@ "dev": true }, "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "1.9.1" @@ -771,7 +771,7 @@ "dev": true, "requires": { "delegates": "1.0.0", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "argparse": { @@ -998,7 +998,7 @@ "dev": true, "requires": { "browserslist": "2.11.3", - "caniuse-lite": "1.0.30000810", + "caniuse-lite": "1.0.30000813", "normalize-range": "0.1.2", "num2fraction": "1.2.2", "postcss": "6.0.19", @@ -1502,7 +1502,7 @@ "htmlescape": "1.1.1", "https-browserify": "1.0.0", "inherits": "2.0.3", - "insert-module-globals": "7.0.1", + "insert-module-globals": "7.0.2", "labeled-stream-splicer": "2.0.0", "module-deps": "4.1.1", "os-browserify": "0.3.0", @@ -1512,7 +1512,7 @@ "punycode": "1.4.1", "querystring-es3": "0.2.1", "read-only-stream": "2.0.0", - "readable-stream": "2.3.4", + "readable-stream": "2.3.5", "resolve": "1.5.0", "shasum": "1.0.2", "shell-quote": "1.6.1", @@ -1672,8 +1672,8 @@ "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", "dev": true, "requires": { - "caniuse-lite": "1.0.30000810", - "electron-to-chromium": "1.3.34" + "caniuse-lite": "1.0.30000813", + "electron-to-chromium": "1.3.36" } }, "buffer": { @@ -1830,7 +1830,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000810", + "caniuse-db": "1.0.30000813", "lodash.memoize": "4.1.2", "lodash.uniq": "4.5.0" }, @@ -1841,22 +1841,22 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000810", - "electron-to-chromium": "1.3.34" + "caniuse-db": "1.0.30000813", + "electron-to-chromium": "1.3.36" } } } }, "caniuse-db": { - "version": "1.0.30000810", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000810.tgz", - "integrity": "sha1-vSWDDEHvq2Qzmi44H0lnc0PIRQk=", + "version": "1.0.30000813", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000813.tgz", + "integrity": "sha1-4KHGA/iICteHsqNWUrJzPzKl4po=", "dev": true }, "caniuse-lite": { - "version": "1.0.30000810", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000810.tgz", - "integrity": "sha512-/0Q00Oie9C72P8zQHtFvzmkrMC3oOFUnMWjCy5F2+BE8lzICm91hQPhh0+XIsAFPKOe2Dh3pKgbRmU3EKxfldA==", + "version": "1.0.30000813", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000813.tgz", + "integrity": "sha512-A8ITSmH5SFdMFdC704ggjg+x2z5PzQmVlG8tavwnfvbC33Q1UYrj0+G+Xm0SNAnd4He36fwUE/KEWytOEchw+A==", "dev": true }, "caseless": { @@ -1873,14 +1873,6 @@ "requires": { "align-text": "0.1.4", "lazy-cache": "1.0.4" - }, - "dependencies": { - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true - } } }, "chalk": { @@ -1889,7 +1881,7 @@ "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", "supports-color": "4.5.0" } @@ -2088,9 +2080,9 @@ } }, "clean-css": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.9.tgz", - "integrity": "sha1-Nc7ornaHpJuYA09w3gDE7dOCYwE=", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.10.tgz", + "integrity": "sha1-PfwsJWnV8DwUtB2HWtm8yuCcuJ4=", "dev": true, "requires": { "source-map": "0.5.7" @@ -2114,15 +2106,15 @@ "dev": true }, "clone-deep": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.3.0.tgz", - "integrity": "sha1-NIxhrpzb4O3+BT2R/0zFIdeQ7eg=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz", + "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==", "dev": true, "requires": { "for-own": "1.0.0", "is-plain-object": "2.0.4", - "kind-of": "3.2.2", - "shallow-clone": "0.1.2" + "kind-of": "6.0.2", + "shallow-clone": "1.0.0" }, "dependencies": { "for-own": { @@ -2133,6 +2125,12 @@ "requires": { "for-in": "1.0.2" } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true } } }, @@ -2152,4442 +2150,162 @@ } }, "codacy-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/codacy-coverage/-/codacy-coverage-2.0.3.tgz", - "integrity": "sha512-E70aH1gN6RPQSn4jj6BJ5lR6wusJW4RgkcKUoXlUuAQcxTmR6WSR7O49Ow6Pd9g7tfB3HyxUnLBZc0ebL0GGkw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/codacy-coverage/-/codacy-coverage-2.1.0.tgz", + "integrity": "sha512-KNQW7z8v1xGpXo0foeef9OTojeotB1ejHXdRLVbb3MHj9g8AmhceyFASJBO66hXtB5OqKGpZqghyy80+7st3Kw==", "dev": true, "requires": { - "bluebird": "2.11.0", - "commander": "2.11.0", - "joi": "6.10.1", - "lcov-parse": "0.0.10", - "lodash": "4.17.4", - "log-driver": "1.2.5", - "request-promise": "0.4.3" + "bluebird": "3.5.1", + "commander": "2.14.1", + "joi": "12.0.0", + "lcov-parse": "1.0.0", + "lodash": "4.17.5", + "log-driver": "1.2.7", + "request": "2.83.0", + "request-promise": "4.2.2" }, "dependencies": { - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=" - }, - "acorn": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", - "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==" - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "requires": { - "acorn": "3.3.0" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" - } - } - }, "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, "requires": { "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=" - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" - }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "requires": { - "sprintf-js": "1.0.3" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "1.0.3" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true - }, "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "assertion-error": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", - "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=" - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" - } - }, - "babylon": { - "version": "6.16.1", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.16.1.tgz", - "integrity": "sha1-MMWiL0gZeKnn+M399JaxHZS0BNM=" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "dev": true, "requires": { - "hoek": "2.16.3" + "hoek": "4.2.1" } }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "requires": { - "callsites": "0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "optional": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "optional": true, - "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" - } - }, - "chai": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-2.3.0.tgz", - "integrity": "sha1-ii9qNHSNqAEJD9cyh7Kqc5pOkJo=", - "requires": { - "assertion-error": "1.0.0", - "deep-eql": "0.1.3" - } - }, - "chai-as-promised": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-5.3.0.tgz", - "integrity": "sha1-CdekApCKpw39vq1T5YU/x50+8hw=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "requires": { - "restore-cursor": "1.0.1" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "optional": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "optional": true - } - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "color-convert": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", - "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", "dev": true, "requires": { - "boom": "2.10.1" - } - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "requires": { - "es5-ext": "0.10.30" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "1.0.0" + "boom": "5.2.0" }, "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "optional": true - }, - "deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", - "requires": { - "type-detect": "0.1.1" - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=" - }, - "dirty-chai": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/dirty-chai/-/dirty-chai-1.2.2.tgz", - "integrity": "sha1-eEleYZY19/5EIZqkyDeEm/GDFC4=" - }, - "doctrine": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "es5-ext": { - "version": "0.10.30", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=", - "requires": { - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" - } - }, - "es6-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-symbol": "3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "requires": { - "esprima": "2.7.3", - "estraverse": "1.9.3", - "esutils": "2.0.2", - "optionator": "0.8.2", - "source-map": "0.2.0" - }, - "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=" - } - } - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.0", - "estraverse": "4.2.0" - } - }, - "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", - "requires": { - "babel-code-frame": "6.26.0", - "chalk": "1.1.3", - "concat-stream": "1.6.0", - "debug": "2.6.8", - "doctrine": "2.0.0", - "escope": "3.6.0", - "espree": "3.5.0", - "esquery": "1.0.0", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.5", - "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.16.1", - "is-resolvable": "1.0.0", - "js-yaml": "3.9.1", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "1.2.1", - "progress": "1.1.8", - "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", - "strip-json-comments": "2.0.1", - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" - } - }, - "espree": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.0.tgz", - "integrity": "sha1-mDWGJb3QVYYeon4oZ+pyn69GPY0=", - "requires": { - "acorn": "5.1.2", - "acorn-jsx": "3.0.1" - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" - }, - "esquery": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", - "requires": { - "estraverse": "4.2.0" - } - }, - "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", - "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30" - } - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=" - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "requires": { - "flat-cache": "1.2.2", - "object-assign": "4.1.1" - } - }, - "filepaths": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/filepaths/-/filepaths-0.3.0.tgz", - "integrity": "sha1-ocmkYBturn+4dvwayYR5zrVXwXc=" - }, - "flat-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", - "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "dev": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=" - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "requires": { - "is-property": "1.0.2" - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - }, - "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=" - }, - "handlebars": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", - "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", - "requires": { - "async": "1.5.2", - "optimist": "0.6.1", - "source-map": "0.4.4", - "uglify-js": "2.8.29" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "dev": true, "requires": { - "amdefine": "1.0.1" + "hoek": "4.2.1" } } } }, "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "dev": true, "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "ajv": "5.5.2", + "har-schema": "2.0.0" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "2.1.1" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" - }, "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", "dev": true, "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.1", + "sntp": "2.1.0" } }, "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", "dev": true }, "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { - "assert-plus": "0.2.0", + "assert-plus": "1.0.0", "jsprim": "1.4.1", "sshpk": "1.13.1" } }, - "ignore": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==" - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "requires": { - "ansi-escapes": "1.4.0", - "ansi-regex": "2.1.1", - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-width": "2.2.0", - "figures": "1.7.0", - "lodash": "4.17.4", - "readline2": "1.0.1", - "run-async": "0.1.0", - "rx-lite": "3.1.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "through": "2.3.8" - } - }, - "interpret": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", - "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=" - }, - "is-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-my-json-valid": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", - "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", - "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" - }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "requires": { - "is-path-inside": "1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", - "requires": { - "path-is-inside": "1.0.2" - } - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" - }, - "is-resolvable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", - "requires": { - "tryit": "1.0.3" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isemail": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz", - "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "istanbul": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", - "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", - "requires": { - "abbrev": "1.0.9", - "async": "1.5.2", - "escodegen": "1.8.1", - "esprima": "2.7.3", - "glob": "5.0.15", - "handlebars": "4.0.10", - "js-yaml": "3.9.1", - "mkdirp": "0.5.1", - "nopt": "3.0.6", - "once": "1.4.0", - "resolve": "1.1.7", - "supports-color": "3.2.3", - "which": "1.3.0", - "wordwrap": "1.0.0" - }, - "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "requires": { - "has-flag": "1.0.0" - } - } - } - }, - "jade": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", - "requires": { - "commander": "0.6.1", - "mkdirp": "0.3.0" - }, - "dependencies": { - "commander": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", - "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=" - }, - "mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=" - } - } - }, - "joi": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz", - "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=", - "dev": true, - "requires": { - "hoek": "2.16.3", - "isemail": "1.2.0", - "moment": "2.18.1", - "topo": "1.1.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" - }, - "js-yaml": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", - "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==", - "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true - }, - "jsinspect": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/jsinspect/-/jsinspect-0.12.7.tgz", - "integrity": "sha512-9pLr5r5moX3XhACEg/nhIlprBuqRDT+loYigZo7hidmfOj0EV2l6ZMk6gmaNMiX6o1YCMod1lWSH3JoX80QHLA==", - "requires": { - "babylon": "6.16.1", - "chalk": "2.1.0", - "commander": "2.11.0", - "filepaths": "0.3.0", - "stable": "0.1.6", - "strip-indent": "1.0.1", - "strip-json-comments": "1.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "requires": { - "color-convert": "1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" - }, - "strip-json-comments": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.2.tgz", - "integrity": "sha1-WkirlgI9usG3uND/q/b2PxZ3vp8=" - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "requires": { - "has-flag": "2.0.0" - } - } - } - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "1.1.5" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "optional": true - }, - "lcov-parse": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", - "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" - } - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - }, - "log-driver": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz", - "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=", - "dev": true - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" - }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" - }, - "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", - "dev": true - }, - "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", - "dev": true, - "requires": { - "mime-db": "1.30.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", - "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", - "requires": { - "commander": "2.3.0", - "debug": "2.2.0", - "diff": "1.4.0", - "escape-string-regexp": "1.0.2", - "glob": "3.2.11", - "growl": "1.9.2", - "jade": "0.26.3", - "mkdirp": "0.5.1", - "supports-color": "1.2.0", - "to-iso-string": "0.0.2" - }, - "dependencies": { - "commander": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=" - }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "requires": { - "ms": "0.7.1" - } - }, - "escape-string-regexp": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", - "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=" - }, - "glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", - "requires": { - "inherits": "2.0.3", - "minimatch": "0.3.0" - } - }, - "minimatch": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" - }, - "supports-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", - "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=" - } - } - }, - "moment": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", - "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "nock": { - "version": "2.18.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-2.18.2.tgz", - "integrity": "sha1-oTiuy/5dKoN75Dl5GKvSOUg85Aw=", - "requires": { - "chai": "2.3.0", - "debug": "1.0.5", - "deep-equal": "1.0.1", - "lodash": "2.4.1", - "mkdirp": "0.5.1", - "propagate": "0.3.1" - }, - "dependencies": { - "debug": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-1.0.5.tgz", - "integrity": "sha1-9yQSF0MPmd7EwrRz6rkiKOh0wqw=", - "requires": { - "ms": "2.0.0" - } - }, - "lodash": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz", - "integrity": "sha1-W3cjA03aTSYuWkb7LFjXzCL3FCA=" - } - } - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "requires": { - "abbrev": "1.0.9" - } - }, - "nsp": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/nsp/-/nsp-2.8.0.tgz", - "integrity": "sha512-Xd2O4BpocQZJJF0DCK5rhOPEPyo9L7A/UlVmT9/Hof14cVgizgDF3y6MSDwJQHD+5eNXN46hdlG528Lrao83Sw==", - "requires": { - "chalk": "1.1.3", - "cli-table": "0.3.1", - "cvss": "1.0.1", - "https-proxy-agent": "1.0.0", - "joi": "6.10.1", - "nodesecurity-npm-utils": "5.0.0", - "path-is-absolute": "1.0.0", - "rc": "1.1.6", - "semver": "5.1.0", - "subcommand": "2.0.3", - "wreck": "6.3.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", - "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=", - "optional": true - }, - "acorn": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz", - "integrity": "sha512-vOk6uEMctu0vQrvuSqFdJyqj1Q0S5VTDL79qtjo+DhRr+1mmaD+tluFSCZqhvi/JUhXSzoZN2BhtstaPEeE8cw==" - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "requires": { - "acorn": "3.3.0" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" - } - } - }, - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=" - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" - }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "requires": { - "sprintf-js": "1.0.3" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "1.0.3" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "assertion-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", - "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=" - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "bossy": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bossy/-/bossy-1.0.3.tgz", - "integrity": "sha1-p9JHiuDC33X0cJi5ute9ZB7tX68=", - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "requires": { - "callsites": "0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "optional": true - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "optional": true, - "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" - } - }, - "chai": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", - "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", - "requires": { - "assertion-error": "1.0.2", - "deep-eql": "0.1.3", - "type-detect": "1.0.0" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", - "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=" - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", - "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=" - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - } - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "requires": { - "restore-cursor": "1.0.1" - } - }, - "cli-table": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", - "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", - "requires": { - "colors": "1.0.3" - }, - "dependencies": { - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" - } - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "optional": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "optional": true - } - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "code": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/code/-/code-1.5.0.tgz", - "integrity": "sha1-1hWfvQ7p+ERRZ4CdQ7XNm8QFEDo=", - "requires": { - "hoek": "2.16.3" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cvss": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cvss/-/cvss-1.0.1.tgz", - "integrity": "sha1-XAffU2FqxW1m6PR0vtJePBRhk9s=" - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "requires": { - "es5-ext": "0.10.30" - } - }, - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "optional": true - }, - "deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", - "requires": { - "type-detect": "0.1.1" - }, - "dependencies": { - "type-detect": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=" - } - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.1" - } - }, - "diff": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz", - "integrity": "sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k=" - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } - }, - "es5-ext": { - "version": "0.10.30", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=", - "requires": { - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" - } - }, - "es6-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-symbol": "3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.0", - "estraverse": "4.2.0" - } - }, - "eslint": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-2.13.1.tgz", - "integrity": "sha1-5MyPoPAJ+4KaquI4VaKTYL4fbBE=", - "requires": { - "chalk": "1.1.3", - "concat-stream": "1.6.0", - "debug": "2.6.8", - "doctrine": "1.5.0", - "es6-map": "0.1.5", - "escope": "3.6.0", - "espree": "3.5.0", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "1.3.1", - "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.5", - "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.16.1", - "is-resolvable": "1.0.0", - "js-yaml": "3.9.1", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "optionator": "0.8.2", - "path-is-absolute": "1.0.0", - "path-is-inside": "1.0.2", - "pluralize": "1.2.1", - "progress": "1.1.8", - "require-uncached": "1.0.3", - "shelljs": "0.6.1", - "strip-json-comments": "1.0.4", - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" - } - }, - "eslint-config-hapi": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eslint-config-hapi/-/eslint-config-hapi-3.0.2.tgz", - "integrity": "sha1-Wk+tJQeELM0phRtjrwWitbFnw2c=" - }, - "eslint-config-nodesecurity": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-config-nodesecurity/-/eslint-config-nodesecurity-1.3.1.tgz", - "integrity": "sha1-8IAQ/DDJZPrdG0Yi5mO8Dx8P7Uk=", - "requires": { - "eslint-plugin-hapi": "4.0.0" - }, - "dependencies": { - "eslint-plugin-hapi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-hapi/-/eslint-plugin-hapi-4.0.0.tgz", - "integrity": "sha1-RKouRfeTmlI5Kc2DK7mqEpqV6CM=", - "requires": { - "hapi-capitalize-modules": "1.1.6", - "hapi-for-you": "1.0.0", - "hapi-scope-start": "2.1.1", - "no-arrowception": "1.0.0" - } - } - } - }, - "eslint-plugin-hapi": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-hapi/-/eslint-plugin-hapi-1.2.2.tgz", - "integrity": "sha1-QcwGNDhxibEcAGdWM6cVZGq4lJA=", - "requires": { - "hapi-capitalize-modules": "1.1.6", - "hapi-scope-start": "1.1.4", - "no-shadow-relaxed": "1.0.1" - }, - "dependencies": { - "hapi-scope-start": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/hapi-scope-start/-/hapi-scope-start-1.1.4.tgz", - "integrity": "sha1-VxC1r7dOdJYdrn6wmdjYvkp1sA4=" - } - } - }, - "espree": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.0.tgz", - "integrity": "sha1-mDWGJb3QVYYeon4oZ+pyn69GPY0=", - "requires": { - "acorn": "5.1.1", - "acorn-jsx": "3.0.1" - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" - }, - "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", - "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" - }, - "estraverse-fb": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/estraverse-fb/-/estraverse-fb-1.3.2.tgz", - "integrity": "sha1-0yOky15awzHOoDNBOpJT4WQ+B8Q=" - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "optional": true - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" - } - }, - "file-entry-cache": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-1.3.1.tgz", - "integrity": "sha1-RMYepgeuS+nBQC9B9EJwy/4zT/g=", - "requires": { - "flat-cache": "1.2.2", - "object-assign": "4.1.1" - } - }, - "flat-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", - "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=" - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "requires": { - "is-property": "1.0.2" - } - }, - "get-stdin": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-3.0.2.tgz", - "integrity": "sha1-wc7SS5A5s43thb3xYeV3E7bdSr4=" - }, - "git-validate": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/git-validate/-/git-validate-2.2.2.tgz", - "integrity": "sha1-nMj/ABF3lXoRcmq1CNQVu4Cxi88=" - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - }, - "handlebars": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", - "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", - "requires": { - "async": "1.5.2", - "optimist": "0.6.1", - "source-map": "0.4.4", - "uglify-js": "2.8.29" - } - }, - "hapi-capitalize-modules": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/hapi-capitalize-modules/-/hapi-capitalize-modules-1.1.6.tgz", - "integrity": "sha1-eZEXFBXhXmqjIx5k3ac8gUZmUxg=" - }, - "hapi-for-you": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hapi-for-you/-/hapi-for-you-1.0.0.tgz", - "integrity": "sha1-02L77o172pwseAHiB+WlzRoLans=" - }, - "hapi-scope-start": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/hapi-scope-start/-/hapi-scope-start-2.1.1.tgz", - "integrity": "sha1-dJWnJv5yt7yo3izcwdh82M5qtPI=" - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" - }, - "https-proxy-agent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", - "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", - "requires": { - "agent-base": "2.0.1", - "debug": "2.2.0", - "extend": "3.0.0" - }, - "dependencies": { - "agent-base": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz", - "integrity": "sha1-vY+ehqjrIh//oHvRS+/VXfFCgV4=", - "requires": { - "extend": "3.0.0", - "semver": "5.0.3" - }, - "dependencies": { - "semver": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", - "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=" - } - } - }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "requires": { - "ms": "0.7.1" - }, - "dependencies": { - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" - } - } - }, - "extend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", - "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=" - } - } - }, - "ignore": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==" - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "requires": { - "ansi-escapes": "1.4.0", - "ansi-regex": "2.1.1", - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-width": "2.2.0", - "figures": "1.7.0", - "lodash": "4.17.4", - "readline2": "1.0.1", - "run-async": "0.1.0", - "rx-lite": "3.1.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "through": "2.3.8" - } - }, - "is-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-my-json-valid": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", - "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", - "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" - }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "requires": { - "is-path-inside": "1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", - "requires": { - "path-is-inside": "1.0.2" - } - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" - }, - "is-resolvable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", - "requires": { - "tryit": "1.0.3" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "items": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/items/-/items-1.1.1.tgz", - "integrity": "sha1-Q1td0hvKKLPP0lu1xrJ4txUBD9k=" - }, - "joi": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz", - "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=", - "requires": { - "hoek": "2.16.3", - "isemail": "1.2.0", - "moment": "2.12.0", - "topo": "1.1.0" - }, - "dependencies": { - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" - }, - "isemail": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz", - "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo=" - }, - "moment": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.12.0.tgz", - "integrity": "sha1-3CVg0Zg41sBzGxpq+gRnUmTTYNY=" - }, - "topo": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz", - "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=", - "requires": { - "hoek": "2.16.3" - } - } - } - }, - "js-yaml": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", - "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==", - "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" - } - }, - "jslint": { - "version": "0.9.8", - "resolved": "https://registry.npmjs.org/jslint/-/jslint-0.9.8.tgz", - "integrity": "sha1-uSyoXKhtaoKXchCO6RnshJ3EsSk=", - "optional": true, - "requires": { - "exit": "0.1.2", - "glob": "4.5.3", - "nopt": "3.0.6", - "readable-stream": "1.0.34" - }, - "dependencies": { - "glob": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", - "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", - "optional": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "2.0.10", - "once": "1.4.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "optional": true - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "optional": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "optional": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "optional": true - } - } - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=" - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "1.1.5" - } - }, - "lab": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/lab/-/lab-6.2.0.tgz", - "integrity": "sha1-RonomYv3V1YH0nNpgmjRXMWe3Qg=", - "requires": { - "bossy": "1.0.3", - "diff": "2.2.3", - "eslint": "1.5.1", - "eslint-config-hapi": "3.0.2", - "eslint-plugin-hapi": "1.2.2", - "espree": "2.2.5", - "handlebars": "4.0.10", - "hoek": "2.16.3", - "items": "1.1.1", - "jslint": "0.9.8", - "json-stringify-safe": "5.0.1", - "mkdirp": "0.5.1", - "source-map-support": "0.3.3" - }, - "dependencies": { - "cli-width": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz", - "integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0=" - }, - "doctrine": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", - "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", - "requires": { - "esutils": "1.1.6", - "isarray": "0.0.1" - } - }, - "eslint": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-1.5.1.tgz", - "integrity": "sha1-u54WHwFh1xuF3EgWO/FKhvICVis=", - "requires": { - "chalk": "1.1.3", - "concat-stream": "1.6.0", - "debug": "2.6.8", - "doctrine": "0.7.2", - "escape-string-regexp": "1.0.5", - "escope": "3.6.0", - "espree": "2.2.5", - "estraverse": "4.2.0", - "estraverse-fb": "1.3.2", - "file-entry-cache": "1.3.1", - "glob": "5.0.15", - "globals": "8.18.0", - "handlebars": "4.0.10", - "inquirer": "0.9.0", - "is-my-json-valid": "2.16.1", - "is-resolvable": "1.0.0", - "js-yaml": "3.9.1", - "lodash.clonedeep": "3.0.2", - "lodash.merge": "3.3.2", - "lodash.omit": "3.1.0", - "minimatch": "2.0.10", - "mkdirp": "0.5.1", - "object-assign": "2.1.1", - "optionator": "0.5.0", - "path-is-absolute": "1.0.0", - "path-is-inside": "1.0.2", - "shelljs": "0.3.0", - "strip-json-comments": "1.0.4", - "text-table": "0.2.0", - "to-double-quotes": "1.0.2", - "to-single-quotes": "1.0.4", - "user-home": "1.1.1", - "xml-escape": "1.0.0" - } - }, - "espree": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/espree/-/espree-2.2.5.tgz", - "integrity": "sha1-32kbkxCIlAKuspzAZnCMVmkLhUs=" - }, - "esutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", - "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=" - }, - "fast-levenshtein": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz", - "integrity": "sha1-AXjc3uAjuSkFGTrwlZ6KdjnP3Lk=" - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "2.0.10", - "once": "1.4.0", - "path-is-absolute": "1.0.0" - } - }, - "globals": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-8.18.0.tgz", - "integrity": "sha1-k9SmK9ysOM+vr8R9awNHaMsP/LQ=" - }, - "inquirer": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.9.0.tgz", - "integrity": "sha1-c2bjijMeYZBJWKzlstpKml9jZ5g=", - "requires": { - "ansi-regex": "2.1.1", - "chalk": "1.1.3", - "cli-width": "1.1.1", - "figures": "1.7.0", - "lodash": "3.10.1", - "readline2": "0.1.1", - "run-async": "0.1.0", - "rx-lite": "2.5.2", - "strip-ansi": "3.0.1", - "through": "2.3.8" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "levn": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.2.5.tgz", - "integrity": "sha1-uo0znQykphDjo/FFucr0iAcVUFQ=", - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "requires": { - "brace-expansion": "1.1.8" - } - }, - "mute-stream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.4.tgz", - "integrity": "sha1-qSGZYKbV1dBGWXruUSUsZlX3F34=" - }, - "object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" - }, - "optionator": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.5.0.tgz", - "integrity": "sha1-t1qJlaLUF98ltuTjhi9QqohlE2g=", - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "1.0.7", - "levn": "0.2.5", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "0.0.3" - } - }, - "readline2": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-0.1.1.tgz", - "integrity": "sha1-mUQ7pug7gw7zBRv9fcJBqCco1Wg=", - "requires": { - "mute-stream": "0.0.4", - "strip-ansi": "2.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-1.1.1.tgz", - "integrity": "sha1-QchHGUZGN15qGl0Qw8oFTvn8mA0=" - }, - "strip-ansi": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-2.0.1.tgz", - "integrity": "sha1-32LBqpTtLxFOHQ8h/R1QSCt5pg4=", - "requires": { - "ansi-regex": "1.1.1" - } - } - } - }, - "rx-lite": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-2.5.2.tgz", - "integrity": "sha1-X+9C1Nbna6tRmdIXEyfbcJ5Y5jQ=" - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=" - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - } - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "optional": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" - } - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - }, - "lodash._arraycopy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", - "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE=" - }, - "lodash._arrayeach": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz", - "integrity": "sha1-urFWsqkNPxu9XGU0AzSeXlkz754=" - }, - "lodash._arraymap": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._arraymap/-/lodash._arraymap-3.0.0.tgz", - "integrity": "sha1-Go/Q9MDfS2HeoHbXF83Jfwo8PmY=" - }, - "lodash._baseassign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "requires": { - "lodash._basecopy": "3.0.1", - "lodash.keys": "3.1.2" - } - }, - "lodash._baseclone": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz", - "integrity": "sha1-MDUZv2OT/n5C802LYw73eU41Qrc=", - "requires": { - "lodash._arraycopy": "3.0.0", - "lodash._arrayeach": "3.0.0", - "lodash._baseassign": "3.2.0", - "lodash._basefor": "3.0.3", - "lodash.isarray": "3.0.4", - "lodash.keys": "3.1.2" - } - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" - }, - "lodash._basedifference": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basedifference/-/lodash._basedifference-3.0.3.tgz", - "integrity": "sha1-8sIEKWwqeOArOJCBtu3KyTPPYpw=", - "requires": { - "lodash._baseindexof": "3.1.0", - "lodash._cacheindexof": "3.0.2", - "lodash._createcache": "3.1.2" - } - }, - "lodash._baseflatten": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/lodash._baseflatten/-/lodash._baseflatten-3.1.4.tgz", - "integrity": "sha1-B3D/gBMa9uNPO1EXlqe6UhTmX/c=", - "requires": { - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, - "lodash._basefor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz", - "integrity": "sha1-dVC06SGO8J+tJDQ7YSAhx5tMIMI=" - }, - "lodash._baseindexof": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz", - "integrity": "sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw=" - }, - "lodash._bindcallback": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", - "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=" - }, - "lodash._cacheindexof": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz", - "integrity": "sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI=" - }, - "lodash._createassigner": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", - "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=", - "requires": { - "lodash._bindcallback": "3.0.1", - "lodash._isiterateecall": "3.0.9", - "lodash.restparam": "3.6.1" - } - }, - "lodash._createcache": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash._createcache/-/lodash._createcache-3.1.2.tgz", - "integrity": "sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=", - "requires": { - "lodash._getnative": "3.9.1" - } - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" - }, - "lodash._pickbyarray": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash._pickbyarray/-/lodash._pickbyarray-3.0.2.tgz", - "integrity": "sha1-H4mNlgfrVgsOFnOEt3x8bRCKpMU=" - }, - "lodash._pickbycallback": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._pickbycallback/-/lodash._pickbycallback-3.0.0.tgz", - "integrity": "sha1-/2G5oBens699MObFPeKK+hm4dQo=", - "requires": { - "lodash._basefor": "3.0.3", - "lodash.keysin": "3.0.8" - } - }, - "lodash.clonedeep": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-3.0.2.tgz", - "integrity": "sha1-oKHkDYKl6on/WxR7hETtY9koJ9s=", - "requires": { - "lodash._baseclone": "3.3.0", - "lodash._bindcallback": "3.0.1" - } - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" - }, - "lodash.isplainobject": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-3.2.0.tgz", - "integrity": "sha1-moI4rhayAEMpYM1zRlEtASP79MU=", - "requires": { - "lodash._basefor": "3.0.3", - "lodash.isarguments": "3.1.0", - "lodash.keysin": "3.0.8" - } - }, - "lodash.istypedarray": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz", - "integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I=" - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, - "lodash.keysin": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/lodash.keysin/-/lodash.keysin-3.0.8.tgz", - "integrity": "sha1-IsRJPrvtsUJ5YqVLRFssinZ/tH8=", - "requires": { - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, - "lodash.merge": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-3.3.2.tgz", - "integrity": "sha1-DZDZPtY3sYeEN7s+IWASYNev6ZQ=", - "requires": { - "lodash._arraycopy": "3.0.0", - "lodash._arrayeach": "3.0.0", - "lodash._createassigner": "3.1.1", - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4", - "lodash.isplainobject": "3.2.0", - "lodash.istypedarray": "3.0.6", - "lodash.keys": "3.1.2", - "lodash.keysin": "3.0.8", - "lodash.toplainobject": "3.0.0" - } - }, - "lodash.omit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-3.1.0.tgz", - "integrity": "sha1-iX/jguZBPZrJfGH3jtHgV6AK+fM=", - "requires": { - "lodash._arraymap": "3.0.0", - "lodash._basedifference": "3.0.3", - "lodash._baseflatten": "3.1.4", - "lodash._bindcallback": "3.0.1", - "lodash._pickbyarray": "3.0.2", - "lodash._pickbycallback": "3.0.0", - "lodash.keysin": "3.0.8", - "lodash.restparam": "3.6.1" - } - }, - "lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" - }, - "lodash.toplainobject": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash.toplainobject/-/lodash.toplainobject-3.0.0.tgz", - "integrity": "sha1-KHkK2ULSk9eKpmOgfs9/UsoEGY0=", - "requires": { - "lodash._basecopy": "3.0.1", - "lodash.keysin": "3.0.8" - } - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=" - }, - "no-arrowception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/no-arrowception/-/no-arrowception-1.0.0.tgz", - "integrity": "sha1-W/PpXrnEG1c4SoBTM9qjtzTuMno=" - }, - "no-shadow-relaxed": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/no-shadow-relaxed/-/no-shadow-relaxed-1.0.1.tgz", - "integrity": "sha1-z2zAFAL0IwuE/TvYoVZG3d8i7fI=", - "requires": { - "eslint": "0.24.1" - }, - "dependencies": { - "ansi-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-1.1.1.tgz", - "integrity": "sha1-QchHGUZGN15qGl0Qw8oFTvn8mA0=" - }, - "cli-width": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz", - "integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0=" - }, - "doctrine": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.6.4.tgz", - "integrity": "sha1-gUKEkalC7xiwSSBW7aOADu5X1h0=", - "requires": { - "esutils": "1.1.6", - "isarray": "0.0.1" - } - }, - "eslint": { - "version": "0.24.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-0.24.1.tgz", - "integrity": "sha1-VKUICYVbllVyHG8u5Xs1HtzigQE=", - "requires": { - "chalk": "1.1.3", - "concat-stream": "1.6.0", - "debug": "2.6.8", - "doctrine": "0.6.4", - "escape-string-regexp": "1.0.5", - "escope": "3.6.0", - "espree": "2.2.5", - "estraverse": "4.2.0", - "estraverse-fb": "1.3.2", - "globals": "8.18.0", - "inquirer": "0.8.5", - "is-my-json-valid": "2.16.1", - "js-yaml": "3.9.1", - "minimatch": "2.0.10", - "mkdirp": "0.5.1", - "object-assign": "2.1.1", - "optionator": "0.5.0", - "path-is-absolute": "1.0.0", - "strip-json-comments": "1.0.4", - "text-table": "0.2.0", - "user-home": "1.1.1", - "xml-escape": "1.0.0" - } - }, - "espree": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/espree/-/espree-2.2.5.tgz", - "integrity": "sha1-32kbkxCIlAKuspzAZnCMVmkLhUs=" - }, - "esutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", - "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=" - }, - "fast-levenshtein": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz", - "integrity": "sha1-AXjc3uAjuSkFGTrwlZ6KdjnP3Lk=" - }, - "globals": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-8.18.0.tgz", - "integrity": "sha1-k9SmK9ysOM+vr8R9awNHaMsP/LQ=" - }, - "inquirer": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.8.5.tgz", - "integrity": "sha1-29dAz2yjtzEpamPOb22WGFHzNt8=", - "requires": { - "ansi-regex": "1.1.1", - "chalk": "1.1.3", - "cli-width": "1.1.1", - "figures": "1.7.0", - "lodash": "3.10.1", - "readline2": "0.1.1", - "rx": "2.5.3", - "through": "2.3.8" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "levn": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.2.5.tgz", - "integrity": "sha1-uo0znQykphDjo/FFucr0iAcVUFQ=", - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "requires": { - "brace-expansion": "1.1.8" - } - }, - "mute-stream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.4.tgz", - "integrity": "sha1-qSGZYKbV1dBGWXruUSUsZlX3F34=" - }, - "object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" - }, - "optionator": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.5.0.tgz", - "integrity": "sha1-t1qJlaLUF98ltuTjhi9QqohlE2g=", - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "1.0.7", - "levn": "0.2.5", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "0.0.3" - } - }, - "readline2": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-0.1.1.tgz", - "integrity": "sha1-mUQ7pug7gw7zBRv9fcJBqCco1Wg=", - "requires": { - "mute-stream": "0.0.4", - "strip-ansi": "2.0.1" - } - }, - "strip-ansi": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-2.0.1.tgz", - "integrity": "sha1-32LBqpTtLxFOHQ8h/R1QSCt5pg4=", - "requires": { - "ansi-regex": "1.1.1" - } - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=" - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - } - } - }, - "nock": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/nock/-/nock-7.7.3.tgz", - "integrity": "sha1-0GAJgKREPt9uULXtMxRgLLfMxIk=", - "requires": { - "chai": "3.5.0", - "debug": "2.6.8", - "deep-equal": "1.0.1", - "json-stringify-safe": "5.0.1", - "lodash": "3.10.1", - "mkdirp": "0.5.1", - "propagate": "0.3.1", - "qs": "6.5.0" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - } - } - }, - "nodesecurity-npm-utils": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nodesecurity-npm-utils/-/nodesecurity-npm-utils-5.0.0.tgz", - "integrity": "sha1-Baow3jDKjIRcQEjpT9eOXgi1Xtk=" - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "optional": true, - "requires": { - "abbrev": "1.1.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1.0.2" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - } - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "path-is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", - "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "2.0.4" - } - }, - "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=" - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" - }, - "propagate": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-0.3.1.tgz", - "integrity": "sha1-46hEBKfs6CDda76p9tkk4xNa4Jw=" - }, - "qs": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz", - "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg==" - }, - "rc": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.1.6.tgz", - "integrity": "sha1-Q2UbdrauU7XIAvEVH6P8OwWZack=", - "requires": { - "deep-extend": "0.4.1", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "1.0.4" - }, - "dependencies": { - "deep-extend": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.1.tgz", - "integrity": "sha1-7+QRPQgIX05vlod1mBD4B0aeIlM=" - }, - "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=" - } - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "mute-stream": "0.0.5" - } - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" - } - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "optional": true, - "requires": { - "align-text": "0.1.4" - } - }, - "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "requires": { - "glob": "7.1.2" - } - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "requires": { - "once": "1.4.0" - } - }, - "rx": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/rx/-/rx-2.5.3.tgz", - "integrity": "sha1-Ia3H2A8CACr1Da6X/Z2/JIdV9WY=" - }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=" - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - }, - "semver": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.0.tgz", - "integrity": "sha1-hfLPhVBGXE3wAM99hvawVBBqueU=" - }, - "shelljs": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.6.1.tgz", - "integrity": "sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg=" - }, - "shrinkydink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/shrinkydink/-/shrinkydink-1.0.1.tgz", - "integrity": "sha1-3IbklqHndptP4GIYm89s18TxhIY=", - "requires": { - "minimist": "1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=" - }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "requires": { - "amdefine": "1.0.1" - } - }, - "source-map-support": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.3.3.tgz", - "integrity": "sha1-NJAJd9W6PwfHdX7nLnO7GptTdU8=", - "requires": { - "source-map": "0.1.32" - }, - "dependencies": { - "source-map": { - "version": "0.1.32", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz", - "integrity": "sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY=", - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=" - }, - "subcommand": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/subcommand/-/subcommand-2.0.3.tgz", - "integrity": "sha1-mz/Rp1PjxEHwBBDLRBMdhlX1LDI=", - "requires": { - "cliclopts": "1.1.1", - "debug": "2.2.0", - "minimist": "1.2.0", - "xtend": "4.0.1" - }, - "dependencies": { - "cliclopts": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cliclopts/-/cliclopts-1.1.1.tgz", - "integrity": "sha1-aUMcfLWvcjd0sNORG0w3USQxkQ8=" - }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "requires": { - "ms": "0.7.1" - }, - "dependencies": { - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" - } - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - } - } - }, - "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", - "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.17.4", - "slice-ansi": "0.0.4", - "string-width": "2.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "3.0.0" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "to-double-quotes": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/to-double-quotes/-/to-double-quotes-1.0.2.tgz", - "integrity": "sha1-u27TbHhjTD1k/YelGtWGDcWU7f0=", - "requires": { - "get-stdin": "3.0.2" - } - }, - "to-single-quotes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/to-single-quotes/-/to-single-quotes-1.0.4.tgz", - "integrity": "sha1-LuqBma8myhFx9TV8WeGS1WXuUxM=", - "requires": { - "get-stdin": "3.0.2" - } - }, - "tryit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", - "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "requires": { - "prelude-ls": "1.1.2" - } - }, - "type-detect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", - "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=" - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "optional": true, - "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "optional": true - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "optional": true - }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "requires": { - "os-homedir": "1.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "optional": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "wreck": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/wreck/-/wreck-6.3.0.tgz", - "integrity": "sha1-oTaXafB7u2LWo3gzanhx/Hc8dAs=", - "requires": { - "boom": "2.10.1", - "hoek": "2.16.3" - }, - "dependencies": { - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "requires": { - "hoek": "2.16.3" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" - } - } - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "requires": { - "mkdirp": "0.5.1" - } - }, - "xml-escape": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/xml-escape/-/xml-escape-1.0.0.tgz", - "integrity": "sha1-AJY9aXsq3wwYXE4E5zF0upsojrI=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "optional": true, - "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", - "window-size": "0.1.0" - } - } - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1.0.2" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - } - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" - }, "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "2.0.4" - } - }, - "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=" - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" - }, - "propagate": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-0.3.1.tgz", - "integrity": "sha1-46hEBKfs6CDda76p9tkk4xNa4Jw=" - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "mute-stream": "0.0.5" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "requires": { - "resolve": "1.4.0" - } - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", "dev": true, "requires": { - "aws-sign2": "0.6.0", + "aws-sign2": "0.7.0", "aws4": "1.6.0", "caseless": "0.12.0", - "combined-stream": "1.0.5", + "combined-stream": "1.0.6", "extend": "3.0.1", "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", + "form-data": "2.3.2", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", + "mime-types": "2.1.18", "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", + "performance-now": "2.1.0", + "qs": "6.5.1", "safe-buffer": "5.1.1", "stringstream": "0.0.5", - "tough-cookie": "2.3.2", + "tough-cookie": "2.3.4", "tunnel-agent": "0.6.0", - "uuid": "3.1.0" + "uuid": "3.2.1" } }, - "request-promise": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-0.4.3.tgz", - "integrity": "sha1-PI3cgvBviQjXIK7eHWeUJY4iEhw=", - "dev": true, - "requires": { - "bluebird": "2.11.0", - "chalk": "1.1.3", - "lodash": "3.10.1", - "request": "2.81.0" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" - } - }, - "resolve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", - "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", - "requires": { - "path-parse": "1.0.5" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" - } - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "optional": true, - "requires": { - "align-text": "0.1.4" - } - }, - "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "requires": { - "glob": "7.1.2" - } - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "requires": { - "once": "1.4.0" - } - }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=" - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", - "requires": { - "glob": "7.1.2", - "interpret": "1.0.3", - "rechoir": "0.6.2" - } - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=" - }, "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "dev": true, "requires": { - "hoek": "2.16.3" - } - }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "optional": true, - "requires": { - "amdefine": "1.0.1" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", - "dev": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "stable": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.6.tgz", - "integrity": "sha1-kQ9dKu17Ugxud3SZwfMuE5/eyxA=" - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" - } - }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "requires": { - "get-stdin": "4.0.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", - "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.17.4", - "slice-ansi": "0.0.4", - "string-width": "2.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "3.0.0" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "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=" - }, - "topo": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz", - "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "tough-cookie": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", - "dev": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tryit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", - "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "requires": { - "prelude-ls": "1.1.2" - } - }, - "type-detect": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=" - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "optional": true, - "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "optional": true - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "optional": true - }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "requires": { - "os-homedir": "1.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "1.3.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "requires": { - "isexe": "2.0.0" - } - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "optional": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "requires": { - "mkdirp": "0.5.1" - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "optional": true, - "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", - "window-size": "0.1.0" + "hoek": "4.2.1" } } } @@ -6599,9 +2317,9 @@ "dev": true }, "codelyzer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-4.1.0.tgz", - "integrity": "sha512-a3FCIAS3FNQIACvj7KA4iKvH3c6r7X6t6zXsrtV797QGYPQyCwD1fIEd9yV+ZDamijF3YaZ5fbB7QbUMOJGC/g==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-4.2.1.tgz", + "integrity": "sha512-CKwfgpfkqi9dyzy4s6ELaxJ54QgJ6A8iTSsM4bzHbLuTpbKncvNc3DUlCvpnkHBhK47gEf4qFsWoYqLrJPhy6g==", "dev": true, "requires": { "app-root-path": "2.0.1", @@ -6776,7 +2494,7 @@ "integrity": "sha1-qv+81qr4VLROuygDU9WtFlH1mmk=", "dev": true, "requires": { - "accepts": "1.3.4", + "accepts": "1.3.5", "bytes": "3.0.0", "compressible": "2.0.13", "debug": "2.6.9", @@ -6802,13 +2520,13 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-gslSSJx03QKa59cIKqeJO9HQ/WZMotvYJCuaUULrLpjj8oG40kV2Z+gz82pVxlTkOADi4PJxQPPfhl1ELYrrXw==", "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.4", + "readable-stream": "2.3.5", "typedarray": "0.0.6" } }, @@ -6918,16 +2636,16 @@ "dev": true }, "copy-webpack-plugin": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.4.2.tgz", - "integrity": "sha512-tf1XKKQ5h+BPvXJ5/zx2xKVdF0/6J8XNvhB6fdmIReMnAfQGMbzph8F7ok2QF9kqWMfIgkCxwzk1zXkYqcLIqg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.5.0.tgz", + "integrity": "sha512-ROQ85fWKuhJfUkBTdHvfV+Zv6Ltm3G/vPVFdLPFwzWzd9RUY1yLw3rt6FmKK2PaeNQCNvmwgFhuarkjuV4PVDQ==", "dev": true, "requires": { "cacache": "10.0.4", "find-cache-dir": "1.0.0", "globby": "7.1.1", "is-glob": "4.0.0", - "loader-utils": "0.2.17", + "loader-utils": "1.1.0", "minimatch": "3.0.4", "p-limit": "1.2.0", "serialize-javascript": "1.4.0" @@ -6947,18 +2665,6 @@ "requires": { "is-extglob": "2.1.1" } - }, - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" - } } } }, @@ -7266,7 +2972,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000810", + "caniuse-db": "1.0.30000813", "normalize-range": "0.1.2", "num2fraction": "1.2.2", "postcss": "5.2.18", @@ -7279,8 +2985,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000810", - "electron-to-chromium": "1.3.34" + "caniuse-db": "1.0.30000813", + "electron-to-chromium": "1.3.36" } }, "chalk": { @@ -7498,7 +3204,7 @@ "optional": true, "requires": { "ast-types": "0.11.2", - "escodegen": "1.9.0", + "escodegen": "1.9.1", "esprima": "3.1.3" }, "dependencies": { @@ -7620,7 +3326,7 @@ "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", "dev": true, "requires": { - "acorn": "5.4.1", + "acorn": "5.5.0", "defined": "1.0.0" } }, @@ -7631,9 +3337,9 @@ "dev": true }, "diff": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", - "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "diffie-hellman": { @@ -7773,18 +3479,18 @@ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "duplexify": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.3.tgz", - "integrity": "sha512-g8ID9OroF9hKt2POf8YLayy+9594PzmM3scI00/uBXocX3TWNgoB67hjzkFe9ITAbQOne/lLdBxHXvYUM4ZgGA==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz", + "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==", "dev": true, "requires": { "end-of-stream": "1.4.1", "inherits": "2.0.3", - "readable-stream": "2.3.4", + "readable-stream": "2.3.5", "stream-shift": "1.0.0" } }, @@ -7811,9 +3517,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.34", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz", - "integrity": "sha1-2TSY9AORuwwWpgPYJBuZUUBBV+0=", + "version": "1.3.36", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.36.tgz", + "integrity": "sha1-Dqv3Gp6+qQE/scw1o5DgaGJPJ+g=", "dev": true }, "elliptic": { @@ -7863,7 +3569,7 @@ "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", "dev": true, "requires": { - "accepts": "1.3.4", + "accepts": "1.3.5", "base64id": "1.0.0", "cookie": "0.3.1", "debug": "3.1.0", @@ -8123,9 +3829,9 @@ "dev": true }, "escodegen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", - "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", "dev": true, "optional": true, "requires": { @@ -8133,7 +3839,7 @@ "estraverse": "4.2.0", "esutils": "2.0.2", "optionator": "0.8.2", - "source-map": "0.5.7" + "source-map": "0.6.1" }, "dependencies": { "esprima": { @@ -8142,6 +3848,13 @@ "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "dev": true, "optional": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true } } }, @@ -8153,7 +3866,7 @@ "requires": { "es6-map": "0.1.5", "es6-weak-map": "2.0.2", - "esrecurse": "4.2.0", + "esrecurse": "4.2.1", "estraverse": "4.2.0" } }, @@ -8164,13 +3877,12 @@ "dev": true }, "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" + "estraverse": "4.2.0" } }, "estraverse": { @@ -8348,7 +4060,7 @@ "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", "dev": true, "requires": { - "accepts": "1.3.4", + "accepts": "1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.2", "content-disposition": "0.5.2", @@ -8506,9 +4218,9 @@ } }, "file-loader": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.9.tgz", - "integrity": "sha512-6ql03hOSoJHBkTB+3De/f7NJse+JXkUwvAf3y4Q5rIcTD0kqJiE3btvLnDcZT+P4t1QYLb9dJ9EI4auzfo3wFA==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", + "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -8610,7 +4322,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "follow-redirects": { @@ -8705,7 +4417,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "fs-access": { @@ -8737,7 +4449,7 @@ "graceful-fs": "4.1.11", "iferr": "0.1.5", "imurmurhash": "0.1.4", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "fs.realpath": { @@ -9781,7 +5493,7 @@ "extend": "3.0.1", "file-uri-to-path": "1.0.0", "ftp": "0.3.10", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" }, "dependencies": { "debug": { @@ -10212,7 +5924,7 @@ "requires": { "inherits": "2.0.3", "obuf": "1.1.1", - "readable-stream": "2.3.4", + "readable-stream": "2.3.5", "wbuf": "1.7.2" } }, @@ -10229,19 +5941,19 @@ "dev": true }, "html-minifier": { - "version": "3.5.9", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.9.tgz", - "integrity": "sha512-EZqO91XJwkj8BeLx9C12sKB/AHoTANaZax39vEOP9f/X/9jgJ3r1O2+neabuHqpz5kJO71TapP9JrtCY39su1A==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.10.tgz", + "integrity": "sha512-5c8iAyeIGAiuFhVjJ0qy1lgvyQxxuZgjeOuMnoK/wjEyy8DF3xKUnE9pO+6H7VMir976K6SGlZV8ZEmIOea/Zg==", "dev": true, "requires": { "camel-case": "3.0.0", - "clean-css": "4.1.9", + "clean-css": "4.1.10", "commander": "2.14.1", "he": "1.1.1", "ncname": "1.0.0", "param-case": "2.1.1", "relateurl": "0.2.7", - "uglify-js": "3.3.12" + "uglify-js": "3.3.13" } }, "html-webpack-plugin": { @@ -10251,7 +5963,7 @@ "dev": true, "requires": { "bluebird": "3.5.1", - "html-minifier": "3.5.9", + "html-minifier": "3.5.10", "loader-utils": "0.2.17", "lodash": "4.17.5", "pretty-error": "2.1.1", @@ -10607,9 +6319,9 @@ } }, "insert-module-globals": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz", - "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.2.tgz", + "integrity": "sha512-p3s7g96Nm62MbHRuj9ZXab0DuJNWD7qcmdUXCOQ/ZZn42DtDXfsLill7bq19lDCx3K3StypqUnuE3H2VmIJFUw==", "dev": true, "requires": { "JSONStream": "1.3.2", @@ -11066,6 +6778,23 @@ "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=", "dev": true }, + "isemail": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.1.1.tgz", + "integrity": "sha512-mVjAjvdPkpwXW61agT2E9AkGoegZO7SdJGCezWwxnETL58f5KwJ4vSVAMBUL5idL6rTlYAIGkX3n4suiviMLNw==", + "dev": true, + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "dev": true + } + } + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -11307,6 +7036,25 @@ "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=", "dev": true }, + "joi": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-12.0.0.tgz", + "integrity": "sha512-z0FNlV4NGgjQN1fdtHYXf5kmgludM65fG/JlXzU6+rwkt9U5UWuXVYnXa2FpK0u6+qBuCmrm5byPNuiiddAHvQ==", + "dev": true, + "requires": { + "hoek": "4.2.1", + "isemail": "3.1.1", + "topo": "2.0.2" + }, + "dependencies": { + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true + } + } + }, "js-base64": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz", @@ -11574,9 +7322,9 @@ } }, "lazy-cache": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz", - "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", "dev": true }, "lcid": { @@ -11588,6 +7336,12 @@ "invert-kv": "1.0.0" } }, + "lcov-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", + "dev": true + }, "less": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz", @@ -11605,14 +7359,14 @@ } }, "less-loader": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.0.5.tgz", - "integrity": "sha1-rhVadAbKxqzSk9eFWH/P8PR4xN0=", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.0.6.tgz", + "integrity": "sha512-WPFY3NMJGJna8kIxtgSu6AVG7K6uRPdfE2J7vpQqFWMN/RkOosV09rOVUt3wghNClWH2Pg7YumD1dHiv1Thfug==", "dev": true, "requires": { "clone": "2.1.1", "loader-utils": "1.1.0", - "pify": "2.3.0" + "pify": "3.0.0" }, "dependencies": { "clone": { @@ -11620,12 +7374,6 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true } } }, @@ -11681,9 +7429,9 @@ "dev": true }, "license-webpack-plugin": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-1.1.2.tgz", - "integrity": "sha512-L40JKqFGSJ2z5bKOleYK3IgdOaTCoRx1p+zScf5yMCYQ1HsKrcCGFxVjZYvIWatcqGtdoEC0PZOBFgSaHMmvrw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-1.2.3.tgz", + "integrity": "sha512-+sie46vNe5L48N94LEzEvreJqAdi+N3x3mXUx+iujuAmftWdJUh68RSDPgWK3DRJuu50dwiyH7MdVAx95zfKQA==", "dev": true, "requires": { "ejs": "2.5.7" @@ -11786,6 +7534,12 @@ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", "dev": true }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true + }, "log4js": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.5.3.tgz", @@ -11912,7 +7666,7 @@ "oauth-sign": "0.8.2", "qs": "6.2.3", "stringstream": "0.0.5", - "tough-cookie": "2.3.3", + "tough-cookie": "2.3.4", "tunnel-agent": "0.4.3" } }, @@ -12157,7 +7911,7 @@ "dev": true, "requires": { "errno": "0.1.7", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "meow": { @@ -12284,8 +8038,8 @@ "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", "dev": true, "requires": { - "concat-stream": "1.6.0", - "duplexify": "3.5.3", + "concat-stream": "1.6.1", + "duplexify": "3.5.4", "end-of-stream": "1.4.1", "flush-write-stream": "1.0.2", "from2": "2.3.0", @@ -12359,7 +8113,7 @@ "duplexer2": "0.1.4", "inherits": "2.0.3", "parents": "1.0.1", - "readable-stream": "2.3.4", + "readable-stream": "2.3.5", "resolve": "1.5.0", "stream-combiner2": "1.1.1", "subarg": "1.0.0", @@ -12518,6 +8272,12 @@ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", "dev": true }, + "neo-async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.0.tgz", + "integrity": "sha512-nJmSswG4As/MkRq7QZFuH/sf/yuv8ODdMZrY4Bedjp77a5MK4A6s7YbBB64c9u79EBUOfXUXBvArmvzTD0X+6g==", + "dev": true + }, "netmask": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", @@ -12530,22 +8290,17 @@ "resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-1.6.0.tgz", "integrity": "sha512-9w0WH69x5/nuqC1og2WaY39NbaBqTGIP1+5gZaH7/KPN6UEPonNg/pYnsIVklLj1DWPWXKa8+XXIJZ1jy5nLxg==", "requires": { - "chart.js": "2.7.1" + "chart.js": "2.7.2" }, "dependencies": { "chart.js": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.7.1.tgz", - "integrity": "sha512-pX1oQAY86MiuyZ2hY593Acbl4MLHKrBBhhmZ1YqSadzQbbsBE2rnd6WISoHjIsdf0WDeC0hbePYCz2ZxkV8L+g==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.7.2.tgz", + "integrity": "sha512-90wl3V9xRZ8tnMvMlpcW+0Yg13BelsGS9P9t0ClaDxv/hdypHDr/YAGf+728m11P5ljwyB0ZHfPKCapZFqSqYA==", "requires": { "chartjs-color": "2.2.0", - "moment": "2.18.1" + "moment": "2.20.1" } - }, - "moment": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", - "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=" } } }, @@ -12630,7 +8385,7 @@ "process": "0.11.10", "punycode": "1.4.1", "querystring-es3": "0.2.1", - "readable-stream": "2.3.4", + "readable-stream": "2.3.5", "stream-browserify": "2.0.1", "stream-http": "2.8.0", "string_decoder": "1.0.3", @@ -12757,7 +8512,7 @@ "oauth-sign": "0.8.2", "qs": "6.3.2", "stringstream": "0.0.5", - "tough-cookie": "2.3.3", + "tough-cookie": "2.3.4", "tunnel-agent": "0.4.3", "uuid": "3.2.1" } @@ -12881,7 +8636,7 @@ "hosted-git-info": "2.5.0", "is-builtin-module": "1.0.0", "semver": "5.5.0", - "validate-npm-package-license": "3.0.1" + "validate-npm-package-license": "3.0.3" } }, "normalize-path": { @@ -13333,7 +9088,7 @@ "requires": { "cyclist": "0.2.2", "inherits": "2.0.3", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "param-case": { @@ -13604,20 +9359,20 @@ "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", "dev": true, "requires": { - "chalk": "2.3.1", + "chalk": "2.3.2", "source-map": "0.6.1", - "supports-color": "5.2.0" + "supports-color": "5.3.0" }, "dependencies": { "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.3.0" } }, "has-flag": { @@ -13633,9 +9388,9 @@ "dev": true }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -14448,8 +10203,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000810", - "electron-to-chromium": "1.3.34" + "caniuse-db": "1.0.30000813", + "electron-to-chromium": "1.3.36" } }, "chalk": { @@ -15709,7 +11464,7 @@ "integrity": "sha512-2kmNR9ry+Pf45opRVirpNuIFotsxUGLaYqxIwuR77AYrYRMuFCz9eryHBS52L360O+NcR383CL4QYlMKPq4zYA==", "dev": true, "requires": { - "duplexify": "3.5.3", + "duplexify": "3.5.4", "inherits": "2.0.3", "pump": "2.0.1" } @@ -15880,7 +11635,7 @@ "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", "dev": true, "requires": { - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "read-pkg": { @@ -15945,9 +11700,9 @@ } }, "readable-stream": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz", - "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", + "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", @@ -15966,7 +11721,7 @@ "requires": { "graceful-fs": "4.1.11", "minimatch": "3.0.4", - "readable-stream": "2.3.4", + "readable-stream": "2.3.5", "set-immediate-shim": "1.0.1" } }, @@ -15988,14 +11743,14 @@ "optional": true, "requires": { "double-ended-queue": "2.1.0-0", - "redis-commands": "1.3.3", + "redis-commands": "1.3.5", "redis-parser": "2.6.0" } }, "redis-commands": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.3.tgz", - "integrity": "sha512-i41GK1SzbNp5nqmuVAMQw9sgar/cvk4YqD6M2RXp2p94D4itY82OZGVs28Jl8JcslGnOdQvlBrDLPt6jYQzuow==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", + "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==", "dev": true, "optional": true }, @@ -16183,7 +11938,7 @@ "qs": "6.4.0", "safe-buffer": "5.1.1", "stringstream": "0.0.5", - "tough-cookie": "2.3.3", + "tough-cookie": "2.3.4", "tunnel-agent": "0.6.0", "uuid": "3.2.1" }, @@ -16207,6 +11962,27 @@ } } }, + "request-promise": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz", + "integrity": "sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ=", + "dev": true, + "requires": { + "bluebird": "3.5.1", + "request-promise-core": "1.1.1", + "stealthy-require": "1.1.1", + "tough-cookie": "2.3.4" + } + }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "dev": true, + "requires": { + "lodash": "4.17.5" + } + }, "requestretry": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", @@ -16353,15 +12129,15 @@ } }, "sass-loader": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.6.tgz", - "integrity": "sha512-c3/Zc+iW+qqDip6kXPYLEgsAu2lf4xz0EZDplB7EmSUMda12U1sGJPetH55B/j9eu0bTtKzKlNPWWyYC7wFNyQ==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.7.tgz", + "integrity": "sha512-JoiyD00Yo1o61OJsoP2s2kb19L1/Y2p3QFcCdWdF6oomBGKVYuZyqHWemRBfQ2uGYsk+CH3eCguXNfpjzlcpaA==", "dev": true, "requires": { - "async": "2.6.0", - "clone-deep": "0.3.0", + "clone-deep": "2.0.2", "loader-utils": "1.1.0", "lodash.tail": "4.1.1", + "neo-async": "2.5.0", "pify": "3.0.0" } }, @@ -16385,7 +12161,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", "requires": { - "ajv": "6.2.0", + "ajv": "6.2.1", "ajv-keywords": "3.1.0" } }, @@ -16515,7 +12291,7 @@ "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", "dev": true, "requires": { - "accepts": "1.3.4", + "accepts": "1.3.5", "batch": "0.6.1", "debug": "2.6.9", "escape-html": "1.0.3", @@ -16614,25 +12390,21 @@ } }, "shallow-clone": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz", - "integrity": "sha1-WQnodLp3EG1zrEFM/sH/yofZcGA=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", + "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", "dev": true, "requires": { "is-extendable": "0.1.1", - "kind-of": "2.0.1", - "lazy-cache": "0.2.7", + "kind-of": "5.1.0", "mixin-object": "2.0.1" }, "dependencies": { "kind-of": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz", - "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -17118,24 +12890,35 @@ "dev": true }, "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { - "spdx-license-ids": "1.2.2" + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" } }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", "dev": true }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" + } + }, "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, "spdy": { @@ -17173,7 +12956,7 @@ "detect-node": "2.0.3", "hpack.js": "2.1.6", "obuf": "1.1.1", - "readable-stream": "2.3.4", + "readable-stream": "2.3.5", "safe-buffer": "5.1.1", "wbuf": "1.7.2" }, @@ -17328,9 +13111,15 @@ "dev": true, "optional": true, "requires": { - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, "stream-browserify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", @@ -17338,7 +13127,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "stream-combiner2": { @@ -17348,7 +13137,7 @@ "dev": true, "requires": { "duplexer2": "0.1.4", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "stream-each": { @@ -17369,7 +13158,7 @@ "requires": { "builtin-status-codes": "3.0.0", "inherits": "2.0.3", - "readable-stream": "2.3.4", + "readable-stream": "2.3.5", "to-arraybuffer": "1.0.1", "xtend": "4.0.1" } @@ -17387,7 +13176,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "streamroller": { @@ -17399,7 +13188,7 @@ "date-format": "1.2.0", "debug": "3.1.0", "mkdirp": "0.5.1", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "strict-uri-encode": { @@ -17576,7 +13365,7 @@ "methods": "1.1.2", "mime": "1.6.0", "qs": "6.5.1", - "readable-stream": "2.3.4" + "readable-stream": "2.3.5" } }, "supports-color": { @@ -17655,7 +13444,7 @@ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "readable-stream": "2.3.4", + "readable-stream": "2.3.5", "xtend": "4.0.1" } }, @@ -17763,6 +13552,23 @@ } } }, + "topo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz", + "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=", + "dev": true, + "requires": { + "hoek": "4.2.1" + }, + "dependencies": { + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true + } + } + }, "toposort": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.6.tgz", @@ -17770,9 +13576,9 @@ "dev": true }, "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "dev": true, "requires": { "punycode": "1.4.1" @@ -17829,26 +13635,26 @@ "dev": true, "requires": { "arrify": "1.0.1", - "chalk": "2.3.1", - "diff": "3.4.0", + "chalk": "2.3.2", + "diff": "3.5.0", "make-error": "1.3.4", "minimist": "1.2.0", "mkdirp": "0.5.1", "source-map-support": "0.5.3", "tsconfig": "7.0.0", - "v8flags": "3.0.1", + "v8flags": "3.0.2", "yn": "2.0.0" }, "dependencies": { "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.3.0" } }, "has-flag": { @@ -17879,9 +13685,9 @@ } }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -17942,27 +13748,27 @@ "requires": { "babel-code-frame": "6.26.0", "builtin-modules": "1.1.1", - "chalk": "2.3.1", + "chalk": "2.3.2", "commander": "2.14.1", - "diff": "3.4.0", + "diff": "3.5.0", "glob": "7.1.2", "js-yaml": "3.7.0", "minimatch": "3.0.4", "resolve": "1.5.0", "semver": "5.5.0", "tslib": "1.9.0", - "tsutils": "2.21.2" + "tsutils": "2.22.2" }, "dependencies": { "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.3.0" } }, "has-flag": { @@ -17972,9 +13778,9 @@ "dev": true }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -17990,9 +13796,9 @@ "optional": true }, "tsutils": { - "version": "2.21.2", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.21.2.tgz", - "integrity": "sha512-iaIuyjIUeFLdD39MYdzqBuY7Zv6+uGxSwRH4mf+HuzsnznjFz0R2tGrAe0/JvtNh91WrN8UN/DZRFTZNDuVekA==", + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.22.2.tgz", + "integrity": "sha512-u06FUSulCJ+Y8a2ftuqZN6kIGqdP2yJjUPEngXqmdPND4UQfb04igcotH+dw+IFr417yP6muCLE8/5/Qlfnx0w==", "dev": true, "requires": { "tslib": "1.9.0" @@ -18052,9 +13858,9 @@ "dev": true }, "uglify-js": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.12.tgz", - "integrity": "sha512-4jxrTXlV0HaXTsNILfXW0eey7Qo8qHYM6ih5ZNh45erDWU2GHmKDmekwBTskDb12h+kdd2DBvdzqVb47YzNmTA==", + "version": "3.3.13", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.13.tgz", + "integrity": "sha512-7rdn/bDOG1ElSTPdh7AI5TCjLv63ZD4k8BBadN3ssIkhlaQL2c0yRxmXCyOYhZK0wZTgGgUSnYQ4CGu+Jos5cA==", "dev": true, "requires": { "commander": "2.14.1", @@ -18506,22 +14312,22 @@ "optional": true }, "v8flags": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.1.tgz", - "integrity": "sha1-3Oj8N5wX2fLJ6e142JzgAFKxt2s=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.2.tgz", + "integrity": "sha512-6sgSKoFw1UpUPd3cFdF7QGnrH6tDeBgW1F3v9gy8gLY0mlbiBXq8soy8aQpY6xeeCjH5K+JvC62Acp7gtl7wWA==", "dev": true, "requires": { "homedir-polyfill": "1.0.1" } }, "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "dev": true, "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" } }, "vary": { @@ -18577,14 +14383,347 @@ "dev": true }, "watchpack": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", - "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.5.0.tgz", + "integrity": "sha512-RSlipNQB1u48cq0wH/BNfCu1tD/cJ8ydFIkNYhp9o+3d+8unClkIovpW5qpFPgmL9OE48wfAnlZydXByWP82AA==", "dev": true, "requires": { - "async": "2.6.0", - "chokidar": "1.7.0", - "graceful-fs": "4.1.11" + "chokidar": "2.0.2", + "graceful-fs": "4.1.11", + "neo-async": "2.5.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "3.1.9", + "normalize-path": "2.1.1" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz", + "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==", + "dev": true, + "requires": { + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "define-property": "1.0.0", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "kind-of": "6.0.2", + "repeat-element": "1.1.2", + "snapdragon": "0.8.1", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "chokidar": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.2.tgz", + "integrity": "sha512-l32Hw3wqB0L2kGVmSbK/a+xXLDrUEsc84pSgMkmwygHvD7ubRsP/vxxHa5BtB6oix1XLLVCHyYMsckRXxThmZw==", + "dev": true, + "requires": { + "anymatch": "2.0.0", + "async-each": "1.0.1", + "braces": "2.3.1", + "fsevents": "1.1.3", + "glob-parent": "3.1.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "4.0.0", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.0.4" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.1", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.1", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + } + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "micromatch": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.9.tgz", + "integrity": "sha512-SlIz6sv5UPaAVVFRKodKjCg48EbNoIhgetzfK/Cy0v5U52Z6zB136M8tp0UC9jM53LYbmIRihJszvvqpKkfm9g==", + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.1", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.9", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.1", + "to-regex": "3.0.2" + } + } } }, "wbuf": { @@ -18676,7 +14815,7 @@ "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==", "dev": true, "requires": { - "acorn": "5.4.1", + "acorn": "5.5.0", "acorn-dynamic-import": "2.0.2", "ajv": "5.5.2", "ajv-keywords": "2.1.1", @@ -18695,7 +14834,7 @@ "supports-color": "4.5.0", "tapable": "0.2.8", "uglifyjs-webpack-plugin": "0.4.6", - "watchpack": "1.4.0", + "watchpack": "1.5.0", "webpack-sources": "1.1.0", "yargs": "8.0.2" }, @@ -18994,9 +15133,9 @@ } }, "webpack-dev-server": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.11.1.tgz", - "integrity": "sha512-ombhu5KsO/85sVshIDTyQ5HF3xjZR3N0sf5Ao6h3vFwpNyzInEzA1GV3QPVjTMLTNckp8PjfG1PFGznzBwS5lg==", + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.11.2.tgz", + "integrity": "sha512-zrPoX97bx47vZiAXfDrkw8pe9QjJ+lunQl3dypojyWwWr1M5I2h0VSrMPfTjopHQPRNn+NqfjcMmhoLcUJe2gA==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -19023,7 +15162,7 @@ "sockjs-client": "1.1.4", "spdy": "3.4.7", "strip-ansi": "3.0.1", - "supports-color": "5.2.0", + "supports-color": "5.3.0", "webpack-dev-middleware": "1.12.2", "yargs": "6.6.0" }, @@ -19372,9 +15511,9 @@ } }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { "has-flag": "3.0.0" diff --git a/package.json b/package.json index bfd2c6249..3ccef3cd5 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a", - "@alfresco/adf-core": "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a", + "@alfresco/adf-content-services": "2.2.0", + "@alfresco/adf-core": "2.2.0", "@angular/animations": "5.1.1", "@angular/cdk": "5.0.1", "@angular/common": "5.1.1", @@ -34,7 +34,7 @@ "@mat-datetimepicker/core": "1.0.1", "@mat-datetimepicker/moment": "1.0.1", "@ngx-translate/core": "9.1.1", - "alfresco-js-api": "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652", + "alfresco-js-api": "2.2.0", "core-js": "2.5.3", "hammerjs": "2.0.8", "moment-es6": "1.0.0", diff --git a/yarn.lock b/yarn.lock index b062b2f1e..d6ecf4438 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,11 @@ # yarn lockfile v1 -"@alfresco/adf-content-services@2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a": - version "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a" - resolved "https://registry.yarnpkg.com/@alfresco/adf-content-services/-/adf-content-services-2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a.tgz#0bf4dce220ebb3d6f3bb3815f09be0547bc92d4d" +"@alfresco/adf-content-services@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@alfresco/adf-content-services/-/adf-content-services-2.2.0.tgz#1724604e2eb6c6396963f7b079deba622ee32171" dependencies: - "@alfresco/adf-core" "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a" + "@alfresco/adf-core" "2.2.0" "@angular/animations" "5.1.1" "@angular/cdk" "5.0.1" "@angular/common" "5.1.1" @@ -21,7 +21,7 @@ "@angular/platform-browser-dynamic" "5.1.1" "@angular/router" "5.1.1" "@ngx-translate/core" "9.1.1" - alfresco-js-api "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652" + alfresco-js-api "2.2.0" chart.js "2.5.0" core-js "2.4.1" hammerjs "2.0.8" @@ -36,9 +36,9 @@ tslib "^1.7.1" zone.js "0.8.14" -"@alfresco/adf-core@2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a": - version "2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a" - resolved "https://registry.yarnpkg.com/@alfresco/adf-core/-/adf-core-2.2.0-273e0a3900fa5862de2cfb4ed5f9422c047f878a.tgz#56a0a9334057ad7dfb37c494b5c4d23b29267af8" +"@alfresco/adf-core@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@alfresco/adf-core/-/adf-core-2.2.0.tgz#88dcfea55b221160c682699e302ca3a0cf21277c" dependencies: "@angular/animations" "5.1.1" "@angular/cdk" "5.0.1" @@ -54,7 +54,7 @@ "@angular/platform-browser-dynamic" "5.1.1" "@angular/router" "5.1.1" "@ngx-translate/core" "9.1.1" - alfresco-js-api "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652" + alfresco-js-api "2.2.0" chart.js "2.5.0" core-js "2.4.1" hammerjs "2.0.8" @@ -330,10 +330,10 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" accepts@~1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" dependencies: - mime-types "~2.1.16" + mime-types "~2.1.18" negotiator "0.6.1" acorn-dynamic-import@^2.0.0: @@ -354,8 +354,8 @@ acorn@^4.0.3: resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" acorn@^5.0.0, acorn@^5.2.1, acorn@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.4.1.tgz#fdc58d9d17f4a4e98d102ded826a9b9759125102" + version "5.5.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.0.tgz#1abb587fbf051f94e3de20e6b26ef910b1828298" addressparser@1.0.1: version "1.0.1" @@ -405,16 +405,16 @@ ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5, ajv@~5.5.1: json-schema-traverse "^0.3.0" ajv@^6.1.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.1.1.tgz#978d597fbc2b7d0e5a5c3ddeb149a682f2abfa0e" + version "6.2.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.2.1.tgz#28a6abc493a2abe0fb4c8507acaedb43fa550671" dependencies: fast-deep-equal "^1.0.0" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" -alfresco-js-api@2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652: - version "2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652" - resolved "https://registry.yarnpkg.com/alfresco-js-api/-/alfresco-js-api-2.2.0-8a2c1fb6ee2bda69d7fba46f9498586e81a3f652.tgz#b6fd32ac4468b183cd053a8c9f2fd3f245e3c440" +alfresco-js-api@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/alfresco-js-api/-/alfresco-js-api-2.2.0.tgz#9a5bbe290e793c0074e2b369010f23509ecac904" dependencies: event-emitter "0.3.4" superagent "3.8.2" @@ -461,9 +461,9 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@^3.1.0, ansi-styles@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" +ansi-styles@^3.1.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" dependencies: color-convert "^1.9.0" @@ -622,8 +622,8 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" ast-types@0.x.x: - version "0.11.1" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.1.tgz#5bb3a8d5ba292c3f4ae94d46df37afc30300b990" + version "0.11.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.2.tgz#cc4e1d15a36b39979a1986fe1e91321cbfae7783" astw@^2.0.0: version "2.2.0" @@ -647,7 +647,7 @@ async@^1.4.0, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" -async@^2.1.2, async@^2.1.4, async@^2.1.5, async@^2.4.1, async@^2.5.0: +async@^2.1.2, async@^2.1.4, async@^2.4.1, async@^2.5.0: version "2.6.0" resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" dependencies: @@ -866,11 +866,7 @@ blocking-proxy@0.0.5: dependencies: minimist "^1.2.0" -bluebird@^2.3, bluebird@^2.9.x: - version "2.11.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" - -bluebird@^3.3.0, bluebird@^3.4.6, bluebird@^3.4.7, bluebird@^3.5.1: +bluebird@^3.3.0, bluebird@^3.4.6, bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.x: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -1234,12 +1230,12 @@ caniuse-api@^1.5.2: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000810" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000810.tgz#bd25830c41efab64339a2e381f49677343c84509" + version "1.0.30000813" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000813.tgz#e0a1c603f8880ad787b2a35652b2733f32a5e29a" caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805: - version "1.0.30000810" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000810.tgz#47585fffce0e9f3593a6feea4673b945424351d9" + version "1.0.30000813" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000813.tgz#7b25e27fdfb8d133f3c932b01f77452140fcc6c9" caseless@~0.11.0: version "0.11.0" @@ -1256,7 +1252,7 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" -chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -1267,12 +1263,12 @@ chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: supports-color "^2.0.0" chalk@^2.0.0, chalk@^2.3.0, chalk@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796" + version "2.3.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" dependencies: - ansi-styles "^3.2.0" + ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" - supports-color "^5.2.0" + supports-color "^5.3.0" chalk@~2.2.0: version "2.2.2" @@ -1290,11 +1286,11 @@ chart.js@2.5.0: moment "^2.10.6" chart.js@^2.6.0: - version "2.7.1" - resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.7.1.tgz#ae90b4aa4ff1f02decd6b1a2a8dabfd73c9f9886" + version "2.7.2" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.7.2.tgz#3c9fde4dc5b95608211bdefeda7e5d33dffa5714" dependencies: - chartjs-color "~2.2.0" - moment "~2.18.0" + chartjs-color "^2.1.0" + moment "^2.10.2" chartjs-color-string@^0.5.0: version "0.5.0" @@ -1302,7 +1298,7 @@ chartjs-color-string@^0.5.0: dependencies: color-name "^1.0.0" -chartjs-color@^2.0.0, chartjs-color@~2.2.0: +chartjs-color@^2.0.0, chartjs-color@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.2.0.tgz#84a2fb755787ed85c39dd6dd8c7b1d88429baeae" dependencies: @@ -1324,7 +1320,7 @@ chokidar@^1.4.1, chokidar@^1.4.2, chokidar@^1.7.0: optionalDependencies: fsevents "^1.0.0" -chokidar@^2.0.0: +chokidar@^2.0.0, chokidar@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.2.tgz#4dc65139eeb2714977735b6a35d06e97b494dfd7" dependencies: @@ -1377,8 +1373,8 @@ class-utils@^0.3.5: static-extend "^0.1.1" clean-css@4.1.x: - version "4.1.9" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.1.9.tgz#35cee8ae7687a49b98034f70de00c4edd3826301" + version "4.1.10" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.1.10.tgz#3dfc2c2569d5f03c14b41d875ad9bccae09cb89e" dependencies: source-map "0.5.x" @@ -1398,14 +1394,14 @@ cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" -clone-deep@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.3.0.tgz#348c61ae9cdbe0edfe053d91ff4cc521d790ede8" +clone-deep@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-2.0.2.tgz#00db3a1e173656730d1188c3d6aced6d7ea97713" dependencies: for-own "^1.0.0" - is-plain-object "^2.0.1" - kind-of "^3.2.2" - shallow-clone "^0.1.2" + is-plain-object "^2.0.4" + kind-of "^6.0.0" + shallow-clone "^1.0.0" clone@^1.0.2: version "1.0.3" @@ -1430,24 +1426,25 @@ coa@~1.0.1: q "^1.1.2" codacy-coverage@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/codacy-coverage/-/codacy-coverage-2.0.3.tgz#5635af71391d2f55c3fc284f72a13c2250c47c76" + version "2.1.0" + resolved "https://registry.yarnpkg.com/codacy-coverage/-/codacy-coverage-2.1.0.tgz#5022f23a4ea00d6f2569775c630897f86b8ee8fc" dependencies: - bluebird "^2.9.x" + bluebird "^3.5.x" commander "^2.x" - joi "^6.4.x" - lcov-parse "0.x" + joi "^12.x" + lcov-parse "^1.x" lodash "^4.17.4" log-driver "^1.x" - request-promise "^0.x" + request "^2.83.0" + request-promise "^4.x" code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" codelyzer@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-4.1.0.tgz#3117754538d8f5ffa36dff91d340573a836cf373" + version "4.2.1" + resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-4.2.1.tgz#d56eaacefca7e8138aac0a630e484bdb09988544" dependencies: app-root-path "^2.0.1" css-selector-tokenizer "^0.7.0" @@ -1586,8 +1583,8 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" concat-stream@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + version "1.6.1" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.1.tgz#261b8f518301f1d834e36342b9fea095d2620a26" dependencies: inherits "^2.0.3" readable-stream "^2.2.2" @@ -1672,14 +1669,14 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" copy-webpack-plugin@^4.1.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.4.1.tgz#1e8c366211db6dc2ddee40e5a3e4fc661dd149e8" + version "4.5.0" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.5.0.tgz#9cb012163317666ea47479d2a8c57daca3557da5" dependencies: cacache "^10.0.1" find-cache-dir "^1.0.0" globby "^7.1.1" is-glob "^4.0.0" - loader-utils "^0.2.15" + loader-utils "^1.1.0" minimatch "^3.0.4" p-limit "^1.0.0" serialize-javascript "^1.4.0" @@ -2105,8 +2102,8 @@ di@^0.0.1: resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" diff@^3.1.0, diff@^3.2.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" diffie-hellman@^5.0.0: version "5.0.2" @@ -2208,8 +2205,8 @@ duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: readable-stream "^2.0.2" duplexify@^3.4.2, duplexify@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e" + version "3.5.4" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.4.tgz#4bb46c1796eabebeec4ca9a2e66b808cb7a3d8b4" dependencies: end-of-stream "^1.0.0" inherits "^2.0.1" @@ -2231,8 +2228,8 @@ ejs@^2.5.7: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30: - version "1.3.34" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz#d93498f40391bb0c16a603d8241b9951404157ed" + version "1.3.36" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.36.tgz#0eabf71a9ebea9013fb1cc35a390e068624f27e8" elliptic@^6.0.0: version "6.4.0" @@ -2320,7 +2317,7 @@ entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" -errno@^0.1.1, errno@^0.1.3, errno@^0.1.4: +errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" dependencies: @@ -2411,15 +2408,15 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" escodegen@1.x.x: - version "1.9.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.0.tgz#9811a2f265dc1cd3894420ee3717064b632b8852" + version "1.9.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2" dependencies: esprima "^3.1.3" estraverse "^4.2.0" esutils "^2.0.2" optionator "^0.8.1" optionalDependencies: - source-map "~0.5.6" + source-map "~0.6.1" escope@^3.6.0: version "3.6.0" @@ -2443,11 +2440,10 @@ esprima@^4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" esrecurse@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" dependencies: estraverse "^4.1.0" - object-assign "^4.0.1" estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" @@ -2651,8 +2647,8 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" fast-json-stable-stringify@^2.0.0: version "2.0.0" @@ -2679,8 +2675,8 @@ faye-websocket@~0.11.0: websocket-driver ">=0.5.1" file-loader@^1.1.5: - version "1.1.9" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.9.tgz#cf152aedbcfb3d67038d0845efb7cf11a96e53de" + version "1.1.11" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.11.tgz#6fe886449b0f2a936e43cabaac0cdbfb369506f8" dependencies: loader-utils "^1.0.2" schema-utils "^0.4.5" @@ -3287,8 +3283,8 @@ html-entities@^1.2.0: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" html-minifier@^3.2.3: - version "3.5.9" - resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.9.tgz#74424014b872598d4bb0e20ac420926ec61024b6" + version "3.5.10" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.10.tgz#8522c772c388db81aa5c26f62033302d906ea1c7" dependencies: camel-case "3.0.x" clean-css "4.1.x" @@ -3500,8 +3496,8 @@ inline-source-map@~0.6.0: source-map "~0.5.3" insert-module-globals@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.0.1.tgz#c03bf4e01cb086d5b5e5ace8ad0afe7889d638c3" + version "7.0.2" + resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.0.2.tgz#012c56baa7d3307a8b417d4ec5270cf9741c18f4" dependencies: JSONStream "^1.0.3" combine-source-map "~0.7.1" @@ -3570,7 +3566,7 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" -is-buffer@^1.0.2, is-buffer@^1.1.0, is-buffer@^1.1.5: +is-buffer@^1.1.0, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -3812,9 +3808,11 @@ isbinaryfile@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621" -isemail@1.x.x: - version "1.2.0" - resolved "https://registry.yarnpkg.com/isemail/-/isemail-1.2.0.tgz#be03df8cc3e29de4d2c5df6501263f1fa4595e9a" +isemail@3.x.x: + version "3.1.1" + resolved "https://registry.yarnpkg.com/isemail/-/isemail-3.1.1.tgz#e8450fe78ff1b48347db599122adcd0668bd92b5" + dependencies: + punycode "2.x.x" isexe@^2.0.0: version "2.0.0" @@ -3947,14 +3945,13 @@ jasminewd2@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/jasminewd2/-/jasminewd2-2.2.0.tgz#e37cf0b17f199cce23bea71b2039395246b4ec4e" -joi@^6.4.x: - version "6.10.1" - resolved "https://registry.yarnpkg.com/joi/-/joi-6.10.1.tgz#4d50c318079122000fe5f16af1ff8e1917b77e06" +joi@^12.x: + version "12.0.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-12.0.0.tgz#46f55e68f4d9628f01bbb695902c8b307ad8d33a" dependencies: - hoek "2.x.x" - isemail "1.x.x" - moment "2.x.x" - topo "1.x.x" + hoek "4.x.x" + isemail "3.x.x" + topo "2.x.x" js-base64@^2.1.8, js-base64@^2.1.9: version "2.4.3" @@ -3965,8 +3962,8 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" js-yaml@^3.4.3, js-yaml@^3.7.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + version "3.11.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -4132,13 +4129,7 @@ killable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b" -kind-of@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" - dependencies: - is-buffer "^1.0.2" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0, kind-of@^3.2.2: +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" dependencies: @@ -4172,10 +4163,6 @@ labeled-stream-splicer@^2.0.0: isarray "~0.0.1" stream-splicer "^2.0.0" -lazy-cache@^0.2.3: - version "0.2.7" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" - lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" @@ -4192,17 +4179,17 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" -lcov-parse@0.x: - version "0.0.10" - resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" +lcov-parse@^1.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0" less-loader@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.0.5.tgz#ae155a7406cac6acd293d785587fcff0f478c4dd" + version "4.0.6" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.0.6.tgz#7bcfbb9053181c18d57e213e87346958e02b2769" dependencies: clone "^2.1.1" loader-utils "^1.1.0" - pify "^2.3.0" + pify "^3.0.0" less@^2.7.2: version "2.7.3" @@ -4247,8 +4234,8 @@ libqp@1.1.0: resolved "https://registry.yarnpkg.com/libqp/-/libqp-1.1.0.tgz#f5e6e06ad74b794fb5b5b66988bf728ef1dedbe8" license-webpack-plugin@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/license-webpack-plugin/-/license-webpack-plugin-1.1.1.tgz#76b2cedccc78f139fd7877e576f756cfc141b8c2" + version "1.2.3" + resolved "https://registry.yarnpkg.com/license-webpack-plugin/-/license-webpack-plugin-1.2.3.tgz#170272565db467d692ca782e4a6ad90cf81553ec" dependencies: ejs "^2.5.7" @@ -4283,7 +4270,7 @@ loader-utils@1.1.0, loader-utils@^1.0.0, loader-utils@^1.0.1, loader-utils@^1.0. emojis-list "^2.0.0" json5 "^0.5.0" -loader-utils@^0.2.15, loader-utils@^0.2.16, loader-utils@~0.2.2: +loader-utils@^0.2.16, loader-utils@~0.2.2: version "0.2.17" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" dependencies: @@ -4311,18 +4298,6 @@ lodash.clonedeep@^4.3.2, lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" -lodash.endswith@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09" - -lodash.isfunction@^3.0.8: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" - -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -4335,10 +4310,6 @@ lodash.mergewith@^4.6.0: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" -lodash.startswith@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.startswith/-/lodash.startswith-4.2.1.tgz#c598c4adce188a27e53145731cdc6c0e7177600c" - lodash.tail@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664" @@ -4347,11 +4318,7 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^3.10.0: - version "3.10.1" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" - -lodash@^4.0.0, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.5.0, lodash@~4.17.4: +lodash@^4.0.0, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.5.0, lodash@~4.17.4: version "4.17.5" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" @@ -4547,8 +4514,8 @@ micromatch@^2.1.5, micromatch@^2.3.11: regex-cache "^0.4.2" micromatch@^3.1.4: - version "3.1.8" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.8.tgz#5c8caa008de588eebb395e8c0ad12c128f25fff1" + version "3.1.9" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.9.tgz#15dc93175ae39e52e93087847096effc73efcf89" dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -4575,7 +4542,7 @@ miller-rabin@^4.0.0: version "1.33.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" -mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.7: +mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.7: version "2.1.18" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" dependencies: @@ -4680,14 +4647,14 @@ moment-es6@1.0.0: dependencies: moment "*" -moment@*, moment@2.20.1, moment@2.x.x, moment@^2.10.6: +moment@*, moment@^2.10.2, moment@^2.10.6: + version "2.21.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.21.0.tgz#2a114b51d2a6ec9e6d83cf803f838a878d8a023a" + +moment@2.20.1: version "2.20.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" -moment@~2.18.0: - version "2.18.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" - move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -4749,6 +4716,10 @@ negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" +neo-async@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.0.tgz#76b1c823130cca26acfbaccc8fbaf0a2fa33b18f" + netmask@~1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" @@ -5476,8 +5447,8 @@ postcss-load-plugins@^2.3.0: object-assign "^4.1.0" postcss-loader@^2.0.10: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-2.1.0.tgz#038c2d6d59753fef4667827fd3ae03f5dc5e6a7a" + version "2.1.1" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-2.1.1.tgz#208935af3b1d65e1abb1a870a912dd12e7b36895" dependencies: loader-utils "^1.1.0" postcss "^6.0.0" @@ -5641,8 +5612,8 @@ postcss-unique-selectors@^2.0.2: uniqs "^2.0.0" postcss-url@^7.1.2: - version "7.3.0" - resolved "https://registry.yarnpkg.com/postcss-url/-/postcss-url-7.3.0.tgz#cf2f45e06743cf43cfea25309f81cbc003dc783f" + version "7.3.1" + resolved "https://registry.yarnpkg.com/postcss-url/-/postcss-url-7.3.1.tgz#b43ae0f0dae4cd06c831fa3aeac2d7a5b73754ed" dependencies: mime "^1.4.1" minimatch "^3.0.4" @@ -5801,6 +5772,10 @@ punycode@1.4.1, punycode@^1.2.4, punycode@^1.3.2, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" +punycode@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + q@1.4.1, q@~1.4.0: version "1.4.1" resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" @@ -5947,8 +5922,8 @@ read-pkg@^2.0.0: path-type "^2.0.0" "readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.4.tgz#c946c3f47fa7d8eabc0b6150f4a12f69a4574071" + version "2.3.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.5.tgz#b4f85003a938cbb6ecbce2a124fb1012bd1a838d" dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -6004,8 +5979,8 @@ redent@^1.0.0: strip-indent "^1.0.1" redis-commands@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.3.1.tgz#81d826f45fa9c8b2011f4cd7a0fe597d241d442b" + version "1.3.5" + resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.3.5.tgz#4495889414f1e886261180b1442e7295602d83a2" redis-parser@^2.6.0: version "2.6.0" @@ -6055,7 +6030,7 @@ regex-cache@^0.4.2: dependencies: is-equal-shallow "^0.1.3" -regex-not@^1.0.0: +regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" dependencies: @@ -6116,16 +6091,22 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request-promise@^0.x: - version "0.4.3" - resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-0.4.3.tgz#3c8ddc82f06f8908d720aede1d6794258e22121c" +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" dependencies: - bluebird "^2.3" - chalk "^1.1.0" - lodash "^3.10.0" - request "^2.34" + lodash "^4.13.1" -request@2, request@^2.0.0, request@^2.34, request@^2.74.0, request@^2.78.0: +request-promise@^4.x: + version "4.2.2" + resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.2.tgz#d1ea46d654a6ee4f8ee6a4fea1018c22911904b4" + dependencies: + bluebird "^3.5.0" + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request@2, request@^2.0.0, request@^2.74.0, request@^2.78.0, request@^2.83.0: version "2.83.0" resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" dependencies: @@ -6340,13 +6321,13 @@ sass-graph@^2.2.4: yargs "^7.0.0" sass-loader@^6.0.6: - version "6.0.6" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-6.0.6.tgz#e9d5e6c1f155faa32a4b26d7a9b7107c225e40f9" + version "6.0.7" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-6.0.7.tgz#dd2fdb3e7eeff4a53f35ba6ac408715488353d00" dependencies: - async "^2.1.5" - clone-deep "^0.3.0" + clone-deep "^2.0.1" loader-utils "^1.0.1" lodash.tail "^4.1.1" + neo-async "^2.5.0" pify "^3.0.0" saucelabs@~1.3.0: @@ -6528,13 +6509,12 @@ sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4: inherits "^2.0.1" safe-buffer "^5.0.1" -shallow-clone@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060" +shallow-clone@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-1.0.0.tgz#4480cd06e882ef68b2ad88a3ea54832e2c48b571" dependencies: is-extendable "^0.1.1" - kind-of "^2.0.1" - lazy-cache "^0.2.3" + kind-of "^5.0.0" mixin-object "^2.0.1" shasum@^1.0.0: @@ -6656,11 +6636,11 @@ socket.io-client@2.0.4: to-array "0.1.4" socket.io-parser@~3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.1.2.tgz#dbc2282151fc4faebbe40aeedc0772eba619f7f2" + version "3.1.3" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.1.3.tgz#ed2da5ee79f10955036e3da413bfd7f1e4d86c8e" dependencies: component-emitter "1.2.1" - debug "~2.6.4" + debug "~3.1.0" has-binary2 "~1.0.2" isarray "2.0.1" @@ -6768,7 +6748,7 @@ source-map@0.1.x: dependencies: amdefine ">=0.0.4" -source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, source-map@~0.5.3, source-map@~0.5.6: +source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, source-map@~0.5.3: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -6782,19 +6762,27 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" -spdx-correct@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" +spdx-correct@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" dependencies: - spdx-license-ids "^1.0.2" + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" -spdx-expression-parse@~1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" +spdx-exceptions@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" -spdx-license-ids@^1.0.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" spdy-transport@^2.0.18: version "2.0.20" @@ -6874,6 +6862,10 @@ stdout-stream@^1.4.0: dependencies: readable-stream "^2.0.1" +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + stream-browserify@^2.0.0, stream-browserify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" @@ -7001,8 +6993,8 @@ style-loader@^0.13.1: loader-utils "^1.0.2" stylus-loader@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-3.0.1.tgz#77f4b34fd030d25b2617bcf5513db5b0730c4089" + version "3.0.2" + resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-3.0.2.tgz#27a706420b05a38e038e7cacb153578d450513c6" dependencies: loader-utils "^1.0.2" lodash.clonedeep "^4.5.0" @@ -7056,9 +7048,9 @@ supports-color@^4.0.0, supports-color@^4.2.1: dependencies: has-flag "^2.0.0" -supports-color@^5.1.0, supports-color@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a" +supports-color@^5.1.0, supports-color@^5.2.0, supports-color@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" dependencies: has-flag "^3.0.0" @@ -7200,26 +7192,27 @@ to-regex-range@^2.1.0: repeat-string "^1.6.1" to-regex@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.1.tgz#15358bee4a2c83bd76377ba1dc049d0f18837aae" + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" dependencies: - define-property "^0.2.5" - extend-shallow "^2.0.1" - regex-not "^1.0.0" + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" -topo@1.x.x: - version "1.1.0" - resolved "https://registry.yarnpkg.com/topo/-/topo-1.1.0.tgz#e9d751615d1bb87dc865db182fa1ca0a5ef536d5" +topo@2.x.x: + version "2.0.2" + resolved "https://registry.yarnpkg.com/topo/-/topo-2.0.2.tgz#cd5615752539057c0dc0491a621c3bc6fbe1d182" dependencies: - hoek "2.x.x" + hoek "4.x.x" toposort@^1.0.0: version "1.0.6" resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec" -tough-cookie@~2.3.0, tough-cookie@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" +tough-cookie@>=2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" dependencies: punycode "^1.4.1" @@ -7300,8 +7293,8 @@ tsscmp@~1.0.0: resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.5.tgz#7dc4a33af71581ab4337da91d85ca5427ebd9a97" tsutils@^2.12.1: - version "2.21.2" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.21.2.tgz#902aa5987e1440c47673543d96752df8d44ab9c7" + version "2.22.2" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.22.2.tgz#0b9f3d87aa3eb95bd32d26ce2b88aa329a657951" dependencies: tslib "^1.8.1" @@ -7360,8 +7353,8 @@ uglify-es@^3.3.4: source-map "~0.6.1" uglify-js@3.3.x: - version "3.3.12" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.12.tgz#efd87c16a1f4c674a8a5ede571001ef634dcc883" + version "3.3.13" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.13.tgz#8a1a89eeb16e2d6a66b0db2b04cb871af3c669cf" dependencies: commander "~2.14.1" source-map "~0.6.1" @@ -7388,8 +7381,8 @@ uglifyjs-webpack-plugin@^0.4.6: webpack-sources "^1.0.1" uglifyjs-webpack-plugin@^1.1.5: - version "1.2.0" - resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.0.tgz#f706fa4c655000a086b4a97c7d835ed0f6e9b0ef" + version "1.2.2" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.2.tgz#e7516d4367afdb715c3847841eb46f94c45ca2b9" dependencies: cacache "^10.0.1" find-cache-dir "^1.0.0" @@ -7471,13 +7464,8 @@ unset-value@^1.0.0: isobject "^3.0.0" upath@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.2.tgz#80aaae5395abc5fd402933ae2f58694f0860204c" - dependencies: - lodash.endswith "^4.2.1" - lodash.isfunction "^3.0.8" - lodash.isstring "^4.0.1" - lodash.startswith "^4.2.1" + version "1.0.4" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.4.tgz#ee2321ba0a786c50973db043a50b7bcba822361d" upper-case@^1.1.1: version "1.1.3" @@ -7562,17 +7550,17 @@ uws@~9.14.0: resolved "https://registry.yarnpkg.com/uws/-/uws-9.14.0.tgz#fac8386befc33a7a3705cbd58dc47b430ca4dd95" v8flags@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.0.1.tgz#dce8fc379c17d9f2c9e9ed78d89ce00052b1b76b" + version "3.0.2" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.0.2.tgz#ad6a78a20a6b23d03a8debc11211e3cc23149477" dependencies: homedir-polyfill "^1.0.1" validate-npm-package-license@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + version "3.0.3" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338" dependencies: - spdx-correct "~1.0.0" - spdx-expression-parse "~1.0.0" + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" vary@~1.1.2: version "1.1.2" @@ -7605,12 +7593,12 @@ void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" watchpack@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac" + version "1.5.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.5.0.tgz#231e783af830a22f8966f65c4c4bacc814072eed" dependencies: - async "^2.1.2" - chokidar "^1.7.0" + chokidar "^2.0.2" graceful-fs "^4.1.2" + neo-async "^2.5.0" wbuf@^1.1.0, wbuf@^1.7.2: version "1.7.2" @@ -7663,8 +7651,8 @@ webpack-dev-middleware@1.12.2, webpack-dev-middleware@~1.12.0: time-stamp "^2.0.0" webpack-dev-server@~2.11.0: - version "2.11.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.11.1.tgz#6f9358a002db8403f016e336816f4485384e5ec0" + version "2.11.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.11.2.tgz#1f4f4c78bf1895378f376815910812daf79a216f" dependencies: ansi-html "0.0.7" array-includes "^3.0.3" @@ -7800,18 +7788,18 @@ wordwrap@~1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" worker-farm@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.2.tgz#32b312e5dc3d5d45d79ef44acc2587491cd729ae" + version "1.5.4" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.4.tgz#4debbe46b40edefcc717ebde74a90b1ae1e909a1" dependencies: - errno "^0.1.4" - xtend "^4.0.1" + errno "~0.1.7" + xtend "~4.0.1" worker-loader@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-1.1.0.tgz#8cf21869a07add84d66f821d948d23c1eb98e809" + version "1.1.1" + resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-1.1.1.tgz#920d74ddac6816fc635392653ed8b4af1929fd92" dependencies: loader-utils "^1.0.0" - schema-utils "^0.3.0" + schema-utils "^0.4.0" wrap-ansi@^2.0.0: version "2.1.0" From bc07fd1c5864993599bbb95409bef0b5308a3b0c Mon Sep 17 00:00:00 2001 From: john-knowles <18680913+john-knowles@users.noreply.github.com> Date: Tue, 6 Mar 2018 12:13:51 +0000 Subject: [PATCH 59/69] Update README.md (#215) --- docs/README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/docs/README.md b/docs/README.md index dd04a4138..64933fe90 100644 --- a/docs/README.md +++ b/docs/README.md @@ -32,15 +32,6 @@ due to the application using the latest [REST APIs](https://docs.alfresco.com/5. There are several ways to get help with building applications using the Alfresco Application Development Framework: -### Alfresco DevCon 2018 - -DevCon 2018 is an international developer conference entirely dedicated to Alfresco technology. -With the support of our community, customers, and partners, DevCon will increase your technical know-how, -connect you with other Alfresco developers, and let you collaborate with our team and each other. - -Register now to avoid disappointment, places are limited: -http://devcon.alfresco.com/ - ### Alfresco Community Visit the Alfresco Community space where you can find many resources to help you get started building your application, From 74eb2e3ad0e55b40f845692dfe31caf7cace098d Mon Sep 17 00:00:00 2001 From: john-knowles <18680913+john-knowles@users.noreply.github.com> Date: Tue, 6 Mar 2018 13:27:49 +0000 Subject: [PATCH 60/69] Add files via upload --- docs/images/File-Viewer.png | Bin 0 -> 1276787 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/File-Viewer.png diff --git a/docs/images/File-Viewer.png b/docs/images/File-Viewer.png new file mode 100644 index 0000000000000000000000000000000000000000..9fea38b1ca84292f4cf15758a1bdf1ef651bee40 GIT binary patch literal 1276787 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%0Aqs;f~JpbsEpn(S&A{R4t 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
CEU-69YDNx{BP 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

9CbbcFPdQ(}b9|AtsY`n~5FC6=@w6^SJ5y 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 miTRVJ3hVr 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

-You also need [node.js](https://nodejs.org/en/) (8.9.1 or later) installed to build it locally from source code. +You also need node.js (8.9.1 or later) installed to build it locally from source code.