document list extensions (demo shell) (#4511)

* doclist extensibility test page

* desktopOnly support

* extensions category, custom column

* update code

* Fix styling for column templates

* update package lock
This commit is contained in:
Denys Vuika 2019-03-29 09:14:36 +00:00 committed by Eugenio Romano
parent 49847bf809
commit b51fc8a7d2
14 changed files with 414 additions and 50 deletions

View File

@ -223,6 +223,11 @@ export const appRoutes: Routes = [
component: FilesComponent,
canActivate: [AuthGuardEcm]
},
{
path: 'extensions/document-list/presets',
canActivate: [AuthGuardEcm],
loadChildren: './components/document-list/extension-presets/extension-presets.module#ExtensionPresetsModule'
},
{
path: 'files/:id',
component: FilesComponent,

View File

@ -32,6 +32,11 @@ export class AppLayoutComponent implements OnInit {
links: Array<any> = [
{ href: '/home', icon: 'home', title: 'APP_LAYOUT.HOME' },
{
href: '/extensions', icon: 'extension', title: 'Extensions', children: [
{ href: '/extensions/document-list/presets', icon: 'extension', title: 'Document List' }
]
},
{ href: '/files', icon: 'folder_open', title: 'APP_LAYOUT.CONTENT_SERVICES' },
{ href: '/breadcrumb', icon: 'label', title: 'APP_LAYOUT.BREADCRUMB' },
{ href: '/notifications', icon: 'alarm', title: 'APP_LAYOUT.NOTIFICATIONS' },

View File

@ -0,0 +1,46 @@
<adf-document-list
currentFolderId="-my-"
[navigate]="false">
<data-columns>
<ng-container *ngFor="let column of columns; trackBy: trackById">
<ng-container
*ngIf="
column.template && !(column.desktopOnly && isSmallScreen)
"
>
<data-column
[key]="column.key"
[title]="column.title"
[type]="column.type"
[format]="column.format"
[class]="column.class"
[sortable]="column.sortable"
>
<ng-template let-context>
<adf-dynamic-column
[id]="column.template"
[context]="context"
>
</adf-dynamic-column>
</ng-template>
</data-column>
</ng-container>
<ng-container
*ngIf="
!column.template && !(column.desktopOnly && isSmallScreen)
"
>
<data-column
[key]="column.key"
[title]="column.title"
[type]="column.type"
[format]="column.format"
[class]="column.class"
[sortable]="column.sortable"
>
</data-column>
</ng-container>
</ng-container>
</data-columns>
</adf-document-list>

View File

@ -0,0 +1,61 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component, OnInit, OnDestroy } from '@angular/core';
import { AppExtensionService } from '@alfresco/adf-extensions';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-extension-presets',
templateUrl: './extension-presets.component.html'
})
export class ExtensionPresetsComponent implements OnInit, OnDestroy {
onDestroy$ = new Subject<boolean>();
columns: any[] = [];
isSmallScreen = false;
constructor(
private extensions: AppExtensionService,
private breakpointObserver: BreakpointObserver
) {}
ngOnInit() {
this.columns = this.extensions.getDocumentListPreset('files');
this.breakpointObserver
.observe([
Breakpoints.HandsetPortrait,
Breakpoints.HandsetLandscape
])
.pipe(takeUntil(this.onDestroy$))
.subscribe((result) => {
this.isSmallScreen = result.matches;
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
trackById(index: number, obj: { id: string }) {
return obj.id;
}
}

View File

@ -0,0 +1,56 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { CoreModule } from '@alfresco/adf-core';
import { ContentModule } from '@alfresco/adf-content-services';
import { ExtensionPresetsComponent } from './extension-presets.component';
import { ExtensionsModule, ExtensionService } from '@alfresco/adf-extensions';
import { NameColumnComponent } from './name-column/name-column.component';
const routes: Routes = [
{
path: '',
component: ExtensionPresetsComponent
}
];
@NgModule({
imports: [
CommonModule,
CoreModule.forChild(),
RouterModule.forChild(routes),
ContentModule.forChild(),
ExtensionsModule.forChild()
],
declarations: [
ExtensionPresetsComponent,
NameColumnComponent
],
entryComponents: [
NameColumnComponent
]
})
export class ExtensionPresetsModule {
constructor(extensionService: ExtensionService) {
extensionService.setComponents({
'app.columns.name': NameColumnComponent
});
}
}

View File

@ -0,0 +1,95 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
Component,
Input,
OnInit,
ChangeDetectionStrategy,
ViewEncapsulation,
ElementRef,
OnDestroy
} from '@angular/core';
import { NodeEntry } from '@alfresco/js-api';
import { BehaviorSubject, Subscription } from 'rxjs';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { Node } from '@alfresco/js-api';
@Component({
selector: 'app-name-column',
template: `
<span class="adf-datatable-cell-value" title="{{ node | adfNodeNameTooltip }}" (click)="onClick()">
{{ displayText$ | async }}
</span>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: { class: 'adf-datatable-cell adf-datatable-link adf-name-column' }
})
export class NameColumnComponent implements OnInit, OnDestroy {
@Input()
context: any;
displayText$ = new BehaviorSubject<string>('');
node: NodeEntry;
private sub: Subscription;
constructor(private element: ElementRef, private alfrescoApiService: AlfrescoApiService) {}
ngOnInit() {
this.updateValue();
this.sub = this.alfrescoApiService.nodeUpdated.subscribe((node: Node) => {
const row = this.context.row;
if (row) {
const { entry } = row.node;
if (entry === node) {
row.node = { entry };
this.updateValue();
}
}
});
}
protected updateValue() {
this.node = this.context.row.node;
if (this.node && this.node.entry) {
this.displayText$.next(this.node.entry.name || this.node.entry.id);
}
}
onClick() {
this.element.nativeElement.dispatchEvent(
new CustomEvent('name-click', {
bubbles: true,
detail: {
node: this.node
}
})
);
}
ngOnDestroy() {
if (this.sub) {
this.sub.unsubscribe();
this.sub = null;
}
}
}

View File

@ -10,6 +10,54 @@
"features": {
"viewer": {
"content": []
},
"documentList": {
"files": [
{
"id": "app.files.thumbnail",
"key": "$thumbnail",
"type": "image",
"sortable": false,
"desktopOnly": false
},
{
"id": "app.files.name",
"key": "name",
"title": "Name",
"type": "text",
"class": "adf-ellipsis-cell adf-expand-cell-5",
"sortable": true,
"template": "app.columns.name",
"desktopOnly": false
},
{
"id": "app.files.size",
"key": "content.sizeInBytes",
"title": "Size",
"type": "fileSize",
"sortable": true,
"desktopOnly": true
},
{
"id": "app.files.modifiedOn",
"key": "modifiedAt",
"title": "Modified on",
"type": "date",
"format": "timeAgo",
"sortable": true,
"desktopOnly": true
},
{
"id": "app.files.modifiedBy",
"key": "modifiedByUser.displayName",
"title": "Modified by",
"type": "text",
"class": "adf-ellipsis-cell",
"sortable": true,
"desktopOnly": true
}
]
}
}
}

View File

@ -32,7 +32,7 @@ import { BehaviorSubject, Subscription } from 'rxjs';
@Component({
selector: 'adf-library-name-column',
template: `
<span title="{{ displayTooltip$ | async }}" (click)="onClick()">
<span class="adf-datatable-cell-value" title="{{ displayTooltip$ | async }}" (click)="onClick()">
{{ displayText$ | async }}
</span>
`,

View File

@ -31,7 +31,7 @@ import { ShareDataRow } from '../../data/share-data-row.model';
@Component({
selector: 'adf-library-role-column',
template: `
<span title="{{ (displayText$ | async) | translate }}">
<span class="adf-datatable-cell-value" title="{{ (displayText$ | async) | translate }}">
{{ (displayText$ | async) | translate }}
</span>
`,

View File

@ -24,7 +24,7 @@ import { ShareDataRow } from '../../data/share-data-row.model';
@Component({
selector: 'adf-library-status-column',
template: `
<span title="{{ (displayText$ | async) | translate }}">
<span class="adf-datatable-cell-value" title="{{ (displayText$ | async) | translate }}">
{{ (displayText$ | async) | translate }}
</span>
`,

View File

@ -33,7 +33,7 @@ import { ShareDataRow } from '../../data/share-data-row.model';
@Component({
selector: 'adf-name-column',
template: `
<span title="{{ node | adfNodeNameTooltip }}" (click)="onClick()">
<span class="adf-datatable-cell-value" title="{{ node | adfNodeNameTooltip }}" (click)="onClick()">
{{ displayText$ | async }}
</span>
`,

View File

@ -29,10 +29,10 @@ import { ShareDataRow } from '../../data/share-data-row.model';
selector: 'adf-trashcan-name-column',
template: `
<ng-container *ngIf="!isLibrary">
<span title="{{ node | adfNodeNameTooltip }}">{{ displayText }}</span>
<span class="adf-datatable-cell-value" title="{{ node | adfNodeNameTooltip }}">{{ displayText }}</span>
</ng-container>
<ng-container *ngIf="isLibrary">
<span title="{{ displayTooltip }}">{{ displayText }}</span>
<span class="adf-datatable-cell-value" title="{{ displayTooltip }}">{{ displayText }}</span>
</ng-container>
`,
changeDetection: ChangeDetectionStrategy.OnPush,

View File

@ -20,6 +20,7 @@ import { ExtensionConfig, ExtensionRef } from '../config/extension.config';
import { ExtensionService } from '../services/extension.service';
import { Observable, BehaviorSubject } from 'rxjs';
import { ViewerExtensionRef } from '../config/viewer.extensions';
import { DocumentListPresetRef } from '../config/document-list.extensions';
@Injectable({
providedIn: 'root'
@ -49,9 +50,22 @@ export class AppExtensionService {
this._references.next(references);
}
/**
* Provides a collection of document list columns for the particular preset.
* The result is filtered by the **disabled** state.
* @param key Preset key.
*/
getDocumentListPreset(key: string) {
return this.extensionService
.getElements<DocumentListPresetRef>(
`features.documentList.${key}`
)
.filter((entry) => !entry.disabled);
}
/**
* Provides a list of the Viewer content extensions,
* filtered by disabled state and rules.
* filtered by **disabled** state and **rules**.
*/
getViewerExtensions(): ViewerExtensionRef[] {
return this.extensionService

120
package-lock.json generated
View File

@ -1,61 +1,61 @@
{
"name": "alfresco-components",
"version": "3.2.0-beta1",
"version": "3.2.0-beta2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@alfresco/adf-content-services": {
"version": "3.2.0-beta1",
"resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-beta1.tgz",
"integrity": "sha512-IDMvGc9gFMkBuIuvP9pM7WhpWGXTbKGl/Wy/v8ZQUQJKqI+/frDBJLCer1oct22Mw2H+pq9NzAAmHqGOiqh3cw==",
"version": "3.2.0-beta2",
"resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.2.0-beta2.tgz",
"integrity": "sha512-1VKsXquJjtWXFcuMmhAbhM2eqcDXWpI28ZFEnE6zOLrRF4qqUyDCEpPTAjfnGcd503rAzT0IKiNftfRzcgphnA==",
"requires": {
"tslib": "^1.9.0"
}
},
"@alfresco/adf-core": {
"version": "3.2.0-beta1",
"resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-beta1.tgz",
"integrity": "sha512-tWdC2ht65MTcPBn2ILqRTy9T8MbXv5hzJIxzEOqoOSLf1pbuyGBN2dI6vWPzmtbZeLTMJg6B5DMeyHykxJHYkQ==",
"version": "3.2.0-beta2",
"resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.2.0-beta2.tgz",
"integrity": "sha512-swIk99PpbTWObq63Dct1kQz+YHLuJ6J+RZu/bkwJkxodATkcpLQcPPO0l7bdMN2/uYduI5vD9zy8Pm6Ssg9izQ==",
"requires": {
"tslib": "^1.9.0"
}
},
"@alfresco/adf-extensions": {
"version": "3.2.0-beta1",
"resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-beta1.tgz",
"integrity": "sha512-hkgQ97t/jZYTv1COhjt3RVONF8HmXM9Uo7/fvDDbGoac+hc2nJbQCWKdIwysZwkglHHbBRZSj/DVwppbKuNroQ==",
"version": "3.2.0-beta2",
"resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.2.0-beta2.tgz",
"integrity": "sha512-vvT5lO8Jk9hQF9Ky2S6sZKu9w8KDeTHPJhJ/w12z7xN5FybWLuDP8kXVN0UDKplJe6mSPBsMJ0uU0OwLTK/qvA==",
"requires": {
"tslib": "^1.9.0"
}
},
"@alfresco/adf-insights": {
"version": "3.2.0-beta1",
"resolved": "https://registry.npmjs.org/@alfresco/adf-insights/-/adf-insights-3.2.0-beta1.tgz",
"integrity": "sha512-9bXFrCCzYbD1/mB7KIwrFKqLBx5UCEZ0+V3+MIpbJRprOU5iTlvzim1uNFbvJX8TNoHi2trEADo+0uSo7F+Zog==",
"version": "3.2.0-beta2",
"resolved": "https://registry.npmjs.org/@alfresco/adf-insights/-/adf-insights-3.2.0-beta2.tgz",
"integrity": "sha512-Jgq76LO3/4+6xkfha0tHWAZKv/EYe0DhdmdNMCzRtJXZlWi63mADA4hcWpwGApw7Gnn80o28TojJ8LGWfYD3Cw==",
"requires": {
"tslib": "^1.9.0"
}
},
"@alfresco/adf-process-services": {
"version": "3.2.0-beta1",
"resolved": "https://registry.npmjs.org/@alfresco/adf-process-services/-/adf-process-services-3.2.0-beta1.tgz",
"integrity": "sha512-ljFWeaUn12x5MYBIBk1fEMqtFZJWZk32ivpuxpVMjiKrL55ryxrzSnc6SNddJMpcm1l6wXdO+ljygSUr3yhcDA==",
"version": "3.2.0-beta2",
"resolved": "https://registry.npmjs.org/@alfresco/adf-process-services/-/adf-process-services-3.2.0-beta2.tgz",
"integrity": "sha512-CiCMctQPbRKDYq2UzobSZ/vu0eKLxAvcIxzi8q0up1qOwhEjK/EJ5vpjzsuJ2pJpvjInIWd5iMFLQD02O84Dnw==",
"requires": {
"tslib": "^1.9.0"
}
},
"@alfresco/adf-process-services-cloud": {
"version": "3.2.0-beta1",
"resolved": "https://registry.npmjs.org/@alfresco/adf-process-services-cloud/-/adf-process-services-cloud-3.2.0-beta1.tgz",
"integrity": "sha512-yV1V4UzEgaqvbiqFo/m8/bMeiTzWHV9PodaqV9T7j1tDkrf+QFpvWIf/eXpXRtTOqdFZbt2ojcZLEd7drOgM4g==",
"version": "3.2.0-beta2",
"resolved": "https://registry.npmjs.org/@alfresco/adf-process-services-cloud/-/adf-process-services-cloud-3.2.0-beta2.tgz",
"integrity": "sha512-EJVNgbtTHeSTMpg4YdZvVthSmNkG+wA2K5JYfxCayj6jJfFCe0ykyr1g6Z+DmbkfhxOQpgsaR651uya2XdvIbQ==",
"requires": {
"tslib": "^1.9.0"
}
},
"@alfresco/adf-testing": {
"version": "3.2.0-beta1",
"resolved": "https://registry.npmjs.org/@alfresco/adf-testing/-/adf-testing-3.2.0-beta1.tgz",
"integrity": "sha512-EL9hmTsCqSNXe4EK0lIw1XUy1utL0ooNltsafr4nsAUI5sFNUbWC/UZynmBv9fLvTGIe4Fd3ubDZgnBNBUNtSw==",
"version": "3.2.0-beta2",
"resolved": "https://registry.npmjs.org/@alfresco/adf-testing/-/adf-testing-3.2.0-beta2.tgz",
"integrity": "sha512-OdQ9QXrwWF0ZE1z6QBJV912pgL0quEph/BMUeMBExMDZjRMW0FF53Rucbul5C6yDu5OpRaHVwYCmJDaAC1D+KQ==",
"requires": {
"tslib": "^1.9.0"
}
@ -2880,6 +2880,7 @@
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
"dev": true,
"optional": true,
"requires": {
"hoek": "2.x.x"
}
@ -3543,7 +3544,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz",
"integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==",
"dev": true
"dev": true,
"optional": true
},
"buffer-xor": {
"version": "1.0.3",
@ -6790,7 +6792,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -6811,12 +6814,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -6831,17 +6836,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -6958,7 +6966,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -6970,6 +6979,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -6984,6 +6994,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -6991,12 +7002,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -7015,6 +7028,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -7095,7 +7109,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -7107,6 +7122,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -7192,7 +7208,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -7228,6 +7245,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -7247,6 +7265,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -7290,12 +7309,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},
@ -8062,7 +8083,8 @@
"version": "2.16.3",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
"dev": true
"dev": true,
"optional": true
},
"homedir-polyfill": {
"version": "1.0.3",
@ -8225,6 +8247,7 @@
"resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz",
"integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=",
"dev": true,
"optional": true,
"requires": {
"httpreq": ">=0.4.22",
"underscore": "~1.7.0"
@ -8234,7 +8257,8 @@
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz",
"integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=",
"dev": true
"dev": true,
"optional": true
},
"https-browserify": {
"version": "1.0.0",
@ -9135,7 +9159,8 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
"dev": true
"dev": true,
"optional": true
},
"is-redirect": {
"version": "1.0.0",
@ -10068,13 +10093,15 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz",
"integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=",
"dev": true
"dev": true,
"optional": true
},
"libmime": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz",
"integrity": "sha1-UaGp50SOy9Ms2lRCFnW7IbwJPaY=",
"dev": true,
"optional": true,
"requires": {
"iconv-lite": "0.4.15",
"libbase64": "0.1.0",
@ -10085,7 +10112,8 @@
"version": "0.4.15",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
"integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=",
"dev": true
"dev": true,
"optional": true
}
}
},
@ -10093,7 +10121,8 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz",
"integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=",
"dev": true
"dev": true,
"optional": true
},
"license-checker": {
"version": "25.0.1",
@ -12158,13 +12187,15 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz",
"integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=",
"dev": true
"dev": true,
"optional": true
},
"nodemailer-shared": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz",
"integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=",
"dev": true,
"optional": true,
"requires": {
"nodemailer-fetch": "1.6.0"
}
@ -12197,7 +12228,8 @@
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz",
"integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=",
"dev": true
"dev": true,
"optional": true
},
"nopt": {
"version": "3.0.6",
@ -15788,6 +15820,7 @@
"resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz",
"integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=",
"dev": true,
"optional": true,
"requires": {
"httpntlm": "1.6.1",
"nodemailer-shared": "1.1.0"
@ -17867,7 +17900,8 @@
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
"integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=",
"dev": true
"dev": true,
"optional": true
},
"unherit": {
"version": "1.1.1",