From 674a4829ce5b72d06ee9941c08aa1840e77cbec9 Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Sat, 22 Oct 2022 00:24:48 +0200 Subject: [PATCH 1/4] 96252: Even more lazy dsMarkdown --- src/app/shared/utils/markdown.pipe.ts | 36 +++++++++++++++++++++------ 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/app/shared/utils/markdown.pipe.ts b/src/app/shared/utils/markdown.pipe.ts index f7e1032cac..e675a863f8 100644 --- a/src/app/shared/utils/markdown.pipe.ts +++ b/src/app/shared/utils/markdown.pipe.ts @@ -1,9 +1,14 @@ -import { Inject, InjectionToken, Pipe, PipeTransform } from '@angular/core'; -import MarkdownIt from 'markdown-it'; -import * as sanitizeHtml from 'sanitize-html'; +import { Inject, InjectionToken, Pipe, PipeTransform, SecurityContext } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { environment } from '../../../environments/environment'; +const markdownItLoader = async () => (await import('markdown-it')).default; +type LazyMarkdownIt = ReturnType; +const MARKDOWN_IT = new InjectionToken( + 'Lazily loaded MarkdownIt', + { providedIn: 'root', factory: markdownItLoader } +); + const mathjaxLoader = async () => (await import('markdown-it-mathjax3')).default; type Mathjax = ReturnType; const MATHJAX = new InjectionToken( @@ -11,6 +16,13 @@ const MATHJAX = new InjectionToken( { providedIn: 'root', factory: mathjaxLoader } ); +const sanitizeHtmlLoader = async () => (await import('sanitize-html') as any).default; +type SanitizeHtml = ReturnType; +const SANITIZE_HTML = new InjectionToken( + 'Lazily loaded sanitize-html', + { providedIn: 'root', factory: sanitizeHtmlLoader } +); + /** * Pipe for rendering markdown and mathjax. * - markdown will only be rendered if {@link MarkdownConfig#enabled} is true @@ -31,7 +43,9 @@ export class MarkdownPipe implements PipeTransform { constructor( protected sanitizer: DomSanitizer, + @Inject(MARKDOWN_IT) private markdownIt: LazyMarkdownIt, @Inject(MATHJAX) private mathjax: Mathjax, + @Inject(SANITIZE_HTML) private sanitizeHtml: SanitizeHtml, ) { } @@ -39,15 +53,17 @@ export class MarkdownPipe implements PipeTransform { if (!environment.markdown.enabled) { return value; } + const MarkdownIt = await this.markdownIt; const md = new MarkdownIt({ html: true, linkify: true, }); + + let html: string; if (environment.markdown.mathjax) { md.use(await this.mathjax); - } - return this.sanitizer.bypassSecurityTrustHtml( - sanitizeHtml(md.render(value), { + const sanitizeHtml = await this.sanitizeHtml + html = sanitizeHtml(md.render(value), { // sanitize-html doesn't let through SVG by default, so we extend its allowlists to cover MathJax SVG allowedTags: [ ...sanitizeHtml.defaults.allowedTags, @@ -77,7 +93,11 @@ export class MarkdownPipe implements PipeTransform { parser: { lowerCaseAttributeNames: false, }, - }) - ); + }); + } else { + html = this.sanitizer.sanitize(SecurityContext.HTML, md.render(value)); + } + + return this.sanitizer.bypassSecurityTrustHtml(html) } } From be43fcb47fc7604990f23f061823c34ffb740d96 Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Mon, 24 Oct 2022 12:07:18 +0200 Subject: [PATCH 2/4] 96252: Enforce tree-shakeable lodash imports in ESLint --- .eslintrc.json | 10 ++++++++-- package.json | 1 + yarn.lock | 7 +++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 6d5aa89db7..25547554b0 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -6,7 +6,8 @@ "eslint-plugin-import", "eslint-plugin-jsdoc", "eslint-plugin-deprecation", - "eslint-plugin-unused-imports" + "eslint-plugin-unused-imports", + "eslint-plugin-lodash" ], "overrides": [ { @@ -202,7 +203,12 @@ "deprecation/deprecation": "warn", "import/order": "off", - "import/no-deprecated": "warn" + "import/no-deprecated": "warn", + + "lodash/import-scope": [ + "error", + "method" + ] } }, { diff --git a/package.json b/package.json index 1b1c7a4b00..55cb797750 100644 --- a/package.json +++ b/package.json @@ -178,6 +178,7 @@ "eslint-plugin-deprecation": "^1.3.2", "eslint-plugin-import": "^2.25.4", "eslint-plugin-jsdoc": "^38.0.6", + "eslint-plugin-lodash": "^7.4.0", "eslint-plugin-unused-imports": "^2.0.0", "express-static-gzip": "^2.1.5", "fork-ts-checker-webpack-plugin": "^6.0.3", diff --git a/yarn.lock b/yarn.lock index 9542bfdbe1..edfa13ae84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5704,6 +5704,13 @@ eslint-plugin-jsdoc@^38.0.6: semver "^7.3.5" spdx-expression-parse "^3.0.1" +eslint-plugin-lodash@^7.4.0: + version "7.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-lodash/-/eslint-plugin-lodash-7.4.0.tgz#14a761547f126c92ff56789662a20a44f8bb6290" + integrity sha512-Tl83UwVXqe1OVeBRKUeWcfg6/pCW1GTRObbdnbEJgYwjxp5Q92MEWQaH9+dmzbRt6kvYU1Mp893E79nJiCSM8A== + dependencies: + lodash "^4.17.21" + eslint-plugin-unused-imports@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-2.0.0.tgz#d8db8c4d0cfa0637a8b51ce3fd7d1b6bc3f08520" From 47ae04986dde3cdc157e50205ac0d74bb09a2f77 Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Mon, 24 Oct 2022 12:39:27 +0200 Subject: [PATCH 3/4] 96252: Make existing lodash imports tree-shakeable --- .../edit-bitstream-page/edit-bitstream-page.component.ts | 2 +- .../collection-source/collection-source.component.ts | 2 +- src/app/core/data/dso-change-analyzer.service.ts | 2 +- src/app/core/data/request.service.ts | 2 +- src/app/core/services/route.service.ts | 2 +- src/app/core/shared/metadata.utils.ts | 3 ++- src/app/core/utilities/equatable.spec.ts | 2 +- src/app/init.service.ts | 2 +- .../item-authorizations/item-authorizations.component.ts | 2 +- .../item-edit-bitstream/item-edit-bitstream.component.ts | 2 +- .../edit-in-place-field/edit-in-place-field.component.ts | 2 +- .../edit-item-page/item-metadata/item-metadata.component.ts | 2 +- .../profile-page-metadata-form.component.spec.ts | 2 +- .../profile-page-metadata-form.component.ts | 2 +- .../authority-confidence-state.directive.ts | 2 +- src/app/shared/chips/chips.component.ts | 2 +- src/app/shared/chips/models/chips-item.model.ts | 3 ++- src/app/shared/chips/models/chips.model.ts | 4 +++- src/app/shared/cookies/browser-klaro.service.spec.ts | 3 ++- src/app/shared/cookies/browser-klaro.service.ts | 3 ++- src/app/shared/date.util.ts | 2 +- .../file-dropzone-no-uploader.component.ts | 2 +- .../ds-dynamic-form-ui/models/list/dynamic-list.component.ts | 2 +- .../relation-group/dynamic-relation-group.components.ts | 3 ++- .../ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts | 2 +- src/app/shared/form/builder/form-builder.service.ts | 4 +++- .../form/builder/models/form-field-previous-value-object.ts | 2 +- src/app/shared/form/builder/parsers/field-parser.ts | 2 +- src/app/shared/form/builder/parsers/row-parser.ts | 2 +- src/app/shared/form/form.component.ts | 2 +- src/app/shared/form/form.reducer.ts | 3 ++- src/app/shared/form/form.service.ts | 2 +- .../notifications-board.component.spec.ts | 2 +- .../notifications-board/notifications-board.component.ts | 2 +- src/app/shared/notifications/notifications.reducers.spec.ts | 2 +- src/app/shared/notifications/notifications.service.ts | 2 +- src/app/shared/object.util.ts | 4 +++- .../eperson-group-list/eperson-group-list.component.spec.ts | 4 +--- .../form/eperson-group-list/eperson-group-list.component.ts | 2 +- .../search-switch-configuration.component.ts | 2 +- src/app/shared/search/search.component.ts | 2 +- src/app/shared/uploader/uploader.component.ts | 2 +- src/app/shared/utils/markdown.pipe.ts | 4 ++-- .../vocabulary-treeview/vocabulary-treeview.service.ts | 2 +- src/app/statistics/statistics.service.spec.ts | 2 +- src/app/submission/objects/submission-objects.effects.ts | 4 +++- src/app/submission/objects/submission-objects.reducer.ts | 5 ++++- .../sections/form/section-form-operations.service.ts | 3 ++- src/app/submission/sections/form/section-form.component.ts | 3 ++- src/app/submission/sections/sections.directive.ts | 2 +- src/app/submission/sections/sections.service.ts | 4 +++- tsconfig.json | 1 + 52 files changed, 74 insertions(+), 54 deletions(-) diff --git a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts index 9a59df4b95..4906ebd0d4 100644 --- a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts +++ b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts @@ -26,7 +26,7 @@ import { import { FormGroup } from '@angular/forms'; import { TranslateService } from '@ngx-translate/core'; import { DynamicCustomSwitchModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/custom-switch/custom-switch.model'; -import { cloneDeep } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; import { BitstreamDataService } from '../../core/data/bitstream-data.service'; import { getAllSucceededRemoteDataPayload, diff --git a/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.ts b/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.ts index 6236c7a5dc..51e8d926eb 100644 --- a/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.ts +++ b/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.ts @@ -23,7 +23,7 @@ import { RemoteData } from '../../../core/data/remote-data'; import { Collection } from '../../../core/shared/collection.model'; import { first, map, switchMap, take } from 'rxjs/operators'; import { ActivatedRoute, Router } from '@angular/router'; -import { cloneDeep } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; import { CollectionDataService } from '../../../core/data/collection-data.service'; import { getFirstSucceededRemoteData, getFirstCompletedRemoteData } from '../../../core/shared/operators'; import { MetadataConfig } from '../../../core/shared/metadata-config.model'; diff --git a/src/app/core/data/dso-change-analyzer.service.ts b/src/app/core/data/dso-change-analyzer.service.ts index b79e83a3f3..a621895633 100644 --- a/src/app/core/data/dso-change-analyzer.service.ts +++ b/src/app/core/data/dso-change-analyzer.service.ts @@ -3,7 +3,7 @@ import { ChangeAnalyzer } from './change-analyzer'; import { Injectable } from '@angular/core'; import { DSpaceObject } from '../shared/dspace-object.model'; import { MetadataMap } from '../shared/metadata.models'; -import { cloneDeep } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; /** * A class to determine what differs between two diff --git a/src/app/core/data/request.service.ts b/src/app/core/data/request.service.ts index 2d5acb2cb3..16dc14dac4 100644 --- a/src/app/core/data/request.service.ts +++ b/src/app/core/data/request.service.ts @@ -4,7 +4,7 @@ import { HttpHeaders } from '@angular/common/http'; import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { filter, map, take, tap } from 'rxjs/operators'; -import { cloneDeep } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; import { hasValue, isEmpty, isNotEmpty, hasNoValue } from '../../shared/empty.util'; import { ObjectCacheEntry } from '../cache/object-cache.reducer'; import { ObjectCacheService } from '../cache/object-cache.service'; diff --git a/src/app/core/services/route.service.ts b/src/app/core/services/route.service.ts index b84bb40373..5381762570 100644 --- a/src/app/core/services/route.service.ts +++ b/src/app/core/services/route.service.ts @@ -4,7 +4,7 @@ import { ActivatedRoute, NavigationEnd, Params, Router, RouterStateSnapshot, } f import { combineLatest, Observable } from 'rxjs'; import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; -import { isEqual } from 'lodash'; +import isEqual from 'lodash/isEqual'; import { AddParameterAction, SetParameterAction, SetParametersAction, SetQueryParameterAction, SetQueryParametersAction } from './route.actions'; import { coreSelector } from '../core.selectors'; diff --git a/src/app/core/shared/metadata.utils.ts b/src/app/core/shared/metadata.utils.ts index 3fbeb205d2..87a90b53a3 100644 --- a/src/app/core/shared/metadata.utils.ts +++ b/src/app/core/shared/metadata.utils.ts @@ -5,7 +5,8 @@ import { MetadataValueFilter, MetadatumViewModel } from './metadata.models'; -import { groupBy, sortBy } from 'lodash'; +import groupBy from 'lodash/groupBy'; +import sortBy from 'lodash/sortBy'; /** * Utility class for working with DSpace object metadata. diff --git a/src/app/core/utilities/equatable.spec.ts b/src/app/core/utilities/equatable.spec.ts index d45010980e..037cea8cc5 100644 --- a/src/app/core/utilities/equatable.spec.ts +++ b/src/app/core/utilities/equatable.spec.ts @@ -1,6 +1,6 @@ /* eslint-disable max-classes-per-file */ import { EquatableObject, excludeFromEquals, fieldsForEquals } from './equals.decorators'; -import { cloneDeep } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; class Dog extends EquatableObject { public name: string; diff --git a/src/app/init.service.ts b/src/app/init.service.ts index a0cbb06b66..e2af88fa65 100644 --- a/src/app/init.service.ts +++ b/src/app/init.service.ts @@ -13,7 +13,7 @@ import { makeStateKey, TransferState } from '@angular/platform-browser'; import { APP_CONFIG, AppConfig } from '../config/app-config.interface'; import { environment } from '../environments/environment'; import { AppState } from './app.reducer'; -import { isEqual } from 'lodash'; +import isEqual from 'lodash/isEqual'; import { TranslateService } from '@ngx-translate/core'; import { LocaleService } from './core/locale/locale.service'; import { Angulartics2DSpace } from './statistics/angulartics/dspace-provider'; diff --git a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts index 8ed2f9a12e..c06bcad7f2 100644 --- a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts +++ b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts @@ -1,4 +1,4 @@ -import { isEqual } from 'lodash'; +import isEqual from 'lodash/isEqual'; import { DSONameService } from '../../../core/breadcrumbs/dso-name.service'; import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts index d7fcc0cb76..fcb5c706ac 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts @@ -1,6 +1,6 @@ import { Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild, ViewContainerRef } from '@angular/core'; import { Bitstream } from '../../../../core/shared/bitstream.model'; -import { cloneDeep } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { Observable } from 'rxjs'; import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model'; diff --git a/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts b/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts index f1ebecb84f..440ccd135f 100644 --- a/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts +++ b/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts @@ -5,7 +5,7 @@ import { } from '../../../../core/shared/operators'; import { hasValue, isNotEmpty } from '../../../../shared/empty.util'; import { RegistryService } from '../../../../core/registry/registry.service'; -import { cloneDeep } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { map } from 'rxjs/operators'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; diff --git a/src/app/item-page/edit-item-page/item-metadata/item-metadata.component.ts b/src/app/item-page/edit-item-page/item-metadata/item-metadata.component.ts index 5030ef3bb3..3c1bad5114 100644 --- a/src/app/item-page/edit-item-page/item-metadata/item-metadata.component.ts +++ b/src/app/item-page/edit-item-page/item-metadata/item-metadata.component.ts @@ -3,7 +3,7 @@ import { Item } from '../../../core/shared/item.model'; import { ItemDataService } from '../../../core/data/item-data.service'; import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service'; import { ActivatedRoute, Router } from '@angular/router'; -import { cloneDeep } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; import { first, switchMap } from 'rxjs/operators'; import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; import { RemoteData } from '../../../core/data/remote-data'; diff --git a/src/app/profile-page/profile-page-metadata-form/profile-page-metadata-form.component.spec.ts b/src/app/profile-page/profile-page-metadata-form/profile-page-metadata-form.component.spec.ts index 9c0942d4ff..1dc1db26cc 100644 --- a/src/app/profile-page/profile-page-metadata-form/profile-page-metadata-form.component.spec.ts +++ b/src/app/profile-page/profile-page-metadata-form/profile-page-metadata-form.component.spec.ts @@ -8,7 +8,7 @@ import { EPerson } from '../../core/eperson/models/eperson.model'; import { FormBuilderService } from '../../shared/form/builder/form-builder.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { EPersonDataService } from '../../core/eperson/eperson-data.service'; -import { cloneDeep } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; describe('ProfilePageMetadataFormComponent', () => { diff --git a/src/app/profile-page/profile-page-metadata-form/profile-page-metadata-form.component.ts b/src/app/profile-page/profile-page-metadata-form/profile-page-metadata-form.component.ts index 44ec406e80..474e6fb025 100644 --- a/src/app/profile-page/profile-page-metadata-form/profile-page-metadata-form.component.ts +++ b/src/app/profile-page/profile-page-metadata-form/profile-page-metadata-form.component.ts @@ -11,7 +11,7 @@ import { TranslateService } from '@ngx-translate/core'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { LangConfig } from '../../../config/lang-config.interface'; import { EPersonDataService } from '../../core/eperson/eperson-data.service'; -import { cloneDeep } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../../core/shared/operators'; import { FormBuilderService } from '../../shared/form/builder/form-builder.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; diff --git a/src/app/shared/authority-confidence/authority-confidence-state.directive.ts b/src/app/shared/authority-confidence/authority-confidence-state.directive.ts index 8999a643e8..bf6f949575 100644 --- a/src/app/shared/authority-confidence/authority-confidence-state.directive.ts +++ b/src/app/shared/authority-confidence/authority-confidence-state.directive.ts @@ -11,7 +11,7 @@ import { SimpleChanges } from '@angular/core'; -import { findIndex } from 'lodash'; +import findIndex from 'lodash/findIndex'; import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model'; import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model'; diff --git a/src/app/shared/chips/chips.component.ts b/src/app/shared/chips/chips.component.ts index 17a6b034ee..94dfa00791 100644 --- a/src/app/shared/chips/chips.component.ts +++ b/src/app/shared/chips/chips.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, } from '@angular/core'; import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'; -import { isObject } from 'lodash'; +import isObject from 'lodash/isObject'; import { Chips } from './models/chips.model'; import { ChipsItem } from './models/chips-item.model'; diff --git a/src/app/shared/chips/models/chips-item.model.ts b/src/app/shared/chips/models/chips-item.model.ts index 5d0ff20e2f..9afeafd479 100644 --- a/src/app/shared/chips/models/chips-item.model.ts +++ b/src/app/shared/chips/models/chips-item.model.ts @@ -1,4 +1,5 @@ -import { isObject, uniqueId } from 'lodash'; +import isObject from 'lodash/isObject'; +import uniqueId from 'lodash/uniqueId'; import { hasValue, isNotEmpty } from '../../empty.util'; import { FormFieldMetadataValueObject } from '../../form/builder/models/form-field-metadata-value.model'; import { ConfidenceType } from '../../../core/shared/confidence-type'; diff --git a/src/app/shared/chips/models/chips.model.ts b/src/app/shared/chips/models/chips.model.ts index c15badb976..2979c3dc09 100644 --- a/src/app/shared/chips/models/chips.model.ts +++ b/src/app/shared/chips/models/chips.model.ts @@ -1,4 +1,6 @@ -import { findIndex, isEqual, isObject } from 'lodash'; +import findIndex from 'lodash/findIndex'; +import isEqual from 'lodash/isEqual'; +import isObject from 'lodash/isObject'; import { BehaviorSubject } from 'rxjs'; import { ChipsItem, ChipsItemIcon } from './chips-item.model'; import { hasValue, isNotEmpty } from '../../empty.util'; diff --git a/src/app/shared/cookies/browser-klaro.service.spec.ts b/src/app/shared/cookies/browser-klaro.service.spec.ts index 9db9caf364..37dfda693a 100644 --- a/src/app/shared/cookies/browser-klaro.service.spec.ts +++ b/src/app/shared/cookies/browser-klaro.service.spec.ts @@ -10,7 +10,8 @@ import { AuthService } from '../../core/auth/auth.service'; import { CookieService } from '../../core/services/cookie.service'; import { getTestScheduler } from 'jasmine-marbles'; import { MetadataValue } from '../../core/shared/metadata.models'; -import { clone, cloneDeep } from 'lodash'; +import clone from 'lodash/clone'; +import cloneDeep from 'lodash/cloneDeep'; import { ConfigurationDataService } from '../../core/data/configuration-data.service'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; diff --git a/src/app/shared/cookies/browser-klaro.service.ts b/src/app/shared/cookies/browser-klaro.service.ts index c6819012d9..3b3229f555 100644 --- a/src/app/shared/cookies/browser-klaro.service.ts +++ b/src/app/shared/cookies/browser-klaro.service.ts @@ -10,7 +10,8 @@ import { KlaroService } from './klaro.service'; import { hasValue, isEmpty, isNotEmpty } from '../empty.util'; import { CookieService } from '../../core/services/cookie.service'; import { EPersonDataService } from '../../core/eperson/eperson-data.service'; -import { cloneDeep, debounce } from 'lodash'; +import cloneDeep from 'lodash/cloneDeep'; +import debounce from 'lodash/debounce'; import { ANONYMOUS_STORAGE_NAME_KLARO, klaroConfiguration } from './klaro-configuration'; import { Operation } from 'fast-json-patch'; import { getFirstCompletedRemoteData } from '../../core/shared/operators'; diff --git a/src/app/shared/date.util.ts b/src/app/shared/date.util.ts index 5f7ccb2438..802a7c37c1 100644 --- a/src/app/shared/date.util.ts +++ b/src/app/shared/date.util.ts @@ -1,6 +1,6 @@ import { NgbDateStruct } from '@ng-bootstrap/ng-bootstrap'; -import { isObject } from 'lodash'; +import isObject from 'lodash/isObject'; import * as moment from 'moment'; import { isNull, isUndefined } from './empty.util'; diff --git a/src/app/shared/file-dropzone-no-uploader/file-dropzone-no-uploader.component.ts b/src/app/shared/file-dropzone-no-uploader/file-dropzone-no-uploader.component.ts index 58960af19e..06636f4256 100644 --- a/src/app/shared/file-dropzone-no-uploader/file-dropzone-no-uploader.component.ts +++ b/src/app/shared/file-dropzone-no-uploader/file-dropzone-no-uploader.component.ts @@ -1,5 +1,5 @@ import { Component, EventEmitter, HostListener, Input, OnInit, Output } from '@angular/core'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import { FileUploader } from 'ng2-file-upload'; import { Observable, of as observableOf } from 'rxjs'; import { UploaderOptions } from '../uploader/uploader-options.model'; diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts index bebef5860e..d44d24f8b8 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts @@ -7,7 +7,7 @@ import { DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; -import { findKey } from 'lodash'; +import findKey from 'lodash/findKey'; import { hasValue, isNotEmpty } from '../../../../../empty.util'; import { DynamicListCheckboxGroupModel } from './dynamic-list-checkbox-group.model'; diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts index cd10b9a4a3..fe495419f0 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts @@ -11,7 +11,8 @@ import { DynamicFormValidationService, DynamicInputModel } from '@ng-dynamic-forms/core'; -import { isEqual, isObject } from 'lodash'; +import isEqual from 'lodash/isEqual'; +import isObject from 'lodash/isObject'; import { DynamicRelationGroupModel } from './dynamic-relation-group.model'; import { FormBuilderService } from '../../../form-builder.service'; diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts index ef5e84e501..4978af970b 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts @@ -5,7 +5,7 @@ import { DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dyna import { Observable, of as observableOf } from 'rxjs'; import { catchError, debounceTime, distinctUntilChanged, map, merge, switchMap, tap } from 'rxjs/operators'; import { NgbTypeahead, NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap'; -import { isEqual } from 'lodash'; +import isEqual from 'lodash/isEqual'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service'; import { DynamicTagModel } from './dynamic-tag.model'; diff --git a/src/app/shared/form/builder/form-builder.service.ts b/src/app/shared/form/builder/form-builder.service.ts index a281942bc7..b3a78d4669 100644 --- a/src/app/shared/form/builder/form-builder.service.ts +++ b/src/app/shared/form/builder/form-builder.service.ts @@ -18,7 +18,9 @@ import { DynamicPathable, parseReviver, } from '@ng-dynamic-forms/core'; -import { isObject, isString, mergeWith } from 'lodash'; +import isObject from 'lodash/isObject'; +import isString from 'lodash/isString'; +import mergeWith from 'lodash/mergeWith'; import { hasNoValue, diff --git a/src/app/shared/form/builder/models/form-field-previous-value-object.ts b/src/app/shared/form/builder/models/form-field-previous-value-object.ts index ca4a47c089..2aa40f97ae 100644 --- a/src/app/shared/form/builder/models/form-field-previous-value-object.ts +++ b/src/app/shared/form/builder/models/form-field-previous-value-object.ts @@ -1,4 +1,4 @@ -import { isEqual } from 'lodash'; +import isEqual from 'lodash/isEqual'; export class FormFieldPreviousValueObject { diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts index bd6820d4b3..86a7d99e41 100644 --- a/src/app/shared/form/builder/parsers/field-parser.ts +++ b/src/app/shared/form/builder/parsers/field-parser.ts @@ -1,6 +1,6 @@ import {Inject, InjectionToken} from '@angular/core'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import {DynamicFormControlLayout, DynamicFormControlRelation, MATCH_VISIBLE, OR_OPERATOR} from '@ng-dynamic-forms/core'; import { hasValue, isNotEmpty, isNotNull, isNotUndefined } from '../../../empty.util'; diff --git a/src/app/shared/form/builder/parsers/row-parser.ts b/src/app/shared/form/builder/parsers/row-parser.ts index 764f52ffdf..2818e37b25 100644 --- a/src/app/shared/form/builder/parsers/row-parser.ts +++ b/src/app/shared/form/builder/parsers/row-parser.ts @@ -1,7 +1,7 @@ import { Injectable, Injector } from '@angular/core'; import { DYNAMIC_FORM_CONTROL_TYPE_ARRAY, DynamicFormGroupModelConfig } from '@ng-dynamic-forms/core'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import { isEmpty } from '../../../empty.util'; import { DynamicRowGroupModel } from '../ds-dynamic-form-ui/models/ds-dynamic-row-group-model'; diff --git a/src/app/shared/form/form.component.ts b/src/app/shared/form/form.component.ts index 7c16be7542..086b5e1fd8 100644 --- a/src/app/shared/form/form.component.ts +++ b/src/app/shared/form/form.component.ts @@ -11,7 +11,7 @@ import { DynamicFormLayout, } from '@ng-dynamic-forms/core'; import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; -import { findIndex } from 'lodash'; +import findIndex from 'lodash/findIndex'; import { FormBuilderService } from './builder/form-builder.service'; import { hasValue, isNotEmpty, isNotNull, isNull } from '../empty.util'; diff --git a/src/app/shared/form/form.reducer.ts b/src/app/shared/form/form.reducer.ts index 22094b2e5d..c1e9b12efa 100644 --- a/src/app/shared/form/form.reducer.ts +++ b/src/app/shared/form/form.reducer.ts @@ -11,7 +11,8 @@ import { FormStatusChangeAction } from './form.actions'; import { hasValue } from '../empty.util'; -import { isEqual, uniqWith } from 'lodash'; +import isEqual from 'lodash/isEqual'; +import uniqWith from 'lodash/uniqWith'; export interface FormError { message: string; diff --git a/src/app/shared/form/form.service.ts b/src/app/shared/form/form.service.ts index c4d6003abd..2dbf78f565 100644 --- a/src/app/shared/form/form.service.ts +++ b/src/app/shared/form/form.service.ts @@ -9,7 +9,7 @@ import { formObjectFromIdSelector } from './selectors'; import { FormBuilderService } from './builder/form-builder.service'; import { DynamicFormControlEvent, DynamicFormControlModel, DynamicFormGroupModel } from '@ng-dynamic-forms/core'; import { isEmpty, isNotUndefined } from '../empty.util'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import { FormAddError, FormAddTouchedAction, diff --git a/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts b/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts index 1d3faabdaa..08b9585a8c 100644 --- a/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts +++ b/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts @@ -11,7 +11,7 @@ import { AppState } from '../../../app.reducer'; import { NotificationComponent } from '../notification/notification.component'; import { Notification } from '../models/notification.model'; import { NotificationType } from '../models/notification-type'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import { INotificationBoardOptions } from '../../../../config/notifications-config.interfaces'; import { NotificationsServiceStub } from '../../testing/notifications-service.stub'; import { cold } from 'jasmine-marbles'; diff --git a/src/app/shared/notifications/notifications-board/notifications-board.component.ts b/src/app/shared/notifications/notifications-board/notifications-board.component.ts index f153d1009e..97ae09c1a6 100644 --- a/src/app/shared/notifications/notifications-board/notifications-board.component.ts +++ b/src/app/shared/notifications/notifications-board/notifications-board.component.ts @@ -10,7 +10,7 @@ import { import { select, Store } from '@ngrx/store'; import { BehaviorSubject, Subscription } from 'rxjs'; -import { difference } from 'lodash'; +import difference from 'lodash/difference'; import { NotificationsService } from '../notifications.service'; import { AppState } from '../../../app.reducer'; diff --git a/src/app/shared/notifications/notifications.reducers.spec.ts b/src/app/shared/notifications/notifications.reducers.spec.ts index b834797115..fde92e8891 100644 --- a/src/app/shared/notifications/notifications.reducers.spec.ts +++ b/src/app/shared/notifications/notifications.reducers.spec.ts @@ -9,7 +9,7 @@ import { NotificationOptions } from './models/notification-options.model'; import { NotificationAnimationsType } from './models/notification-animations-type'; import { NotificationType } from './models/notification-type'; import { Notification } from './models/notification.model'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import { ChangeDetectorRef } from '@angular/core'; import { storeModuleConfig } from '../../app.reducer'; diff --git a/src/app/shared/notifications/notifications.service.ts b/src/app/shared/notifications/notifications.service.ts index 98272d4f43..d37d6a349b 100644 --- a/src/app/shared/notifications/notifications.service.ts +++ b/src/app/shared/notifications/notifications.service.ts @@ -4,7 +4,7 @@ import { of as observableOf } from 'rxjs'; import { first } from 'rxjs/operators'; import { Store } from '@ngrx/store'; import { TranslateService } from '@ngx-translate/core'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import { INotification, Notification } from './models/notification.model'; import { NotificationType } from './models/notification-type'; diff --git a/src/app/shared/object.util.ts b/src/app/shared/object.util.ts index 1602fb9839..4f8954259e 100644 --- a/src/app/shared/object.util.ts +++ b/src/app/shared/object.util.ts @@ -1,5 +1,7 @@ import { isNotEmpty } from './empty.util'; -import { isEqual, isObject, transform } from 'lodash'; +import isEqual from 'lodash/isEqual'; +import isObject from 'lodash/isObject'; +import transform from 'lodash/transform'; /** * Returns passed object without specified property diff --git a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts index 91d9200c2d..cec67e721c 100644 --- a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts +++ b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts @@ -4,7 +4,7 @@ import { ChangeDetectorRef, Component, Injector, NO_ERRORS_SCHEMA } from '@angul import { of as observableOf } from 'rxjs'; import { TranslateModule } from '@ngx-translate/core'; import { cold } from 'jasmine-marbles'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import { createSuccessfulRemoteDataObject } from '../../../remote-data.utils'; import { createTestComponent } from '../../../testing/utils.test'; @@ -19,10 +19,8 @@ import { PaginationComponentOptions } from '../../../pagination/pagination-compo import { buildPaginatedList } from '../../../../core/data/paginated-list.model'; import { PageInfo } from '../../../../core/shared/page-info.model'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; import { PaginationService } from '../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../testing/pagination-service.stub'; -import { FindListOptions } from '../../../../core/data/find-list-options.model'; describe('EpersonGroupListComponent test suite', () => { let comp: EpersonGroupListComponent; diff --git a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts index b120c3e016..b859184845 100644 --- a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts +++ b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts @@ -2,7 +2,7 @@ import { Component, EventEmitter, Injector, Input, OnDestroy, OnInit, Output } f import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { map } from 'rxjs/operators'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import { RemoteData } from '../../../../core/data/remote-data'; import { PaginatedList } from '../../../../core/data/paginated-list.model'; diff --git a/src/app/shared/search/search-switch-configuration/search-switch-configuration.component.ts b/src/app/shared/search/search-switch-configuration/search-switch-configuration.component.ts index 1852277673..0e1b4f221b 100644 --- a/src/app/shared/search/search-switch-configuration/search-switch-configuration.component.ts +++ b/src/app/shared/search/search-switch-configuration/search-switch-configuration.component.ts @@ -10,7 +10,7 @@ import { MyDSpaceConfigurationValueType } from '../../../my-dspace-page/my-dspac import { SearchConfigurationOption } from './search-configuration-option.model'; import { SearchService } from '../../../core/shared/search/search.service'; import { currentPath } from '../../utils/route.utils'; -import { findIndex } from 'lodash'; +import findIndex from 'lodash/findIndex'; @Component({ selector: 'ds-search-switch-configuration', diff --git a/src/app/shared/search/search.component.ts b/src/app/shared/search/search.component.ts index 2abd5290cb..c094e37ef2 100644 --- a/src/app/shared/search/search.component.ts +++ b/src/app/shared/search/search.component.ts @@ -3,7 +3,7 @@ import { Router } from '@angular/router'; import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs'; import { debounceTime, distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { RemoteData } from '../../core/data/remote-data'; diff --git a/src/app/shared/uploader/uploader.component.ts b/src/app/shared/uploader/uploader.component.ts index a0dd0e5bba..3cbf033b17 100644 --- a/src/app/shared/uploader/uploader.component.ts +++ b/src/app/shared/uploader/uploader.component.ts @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Ho import { of as observableOf } from 'rxjs'; import { FileUploader } from 'ng2-file-upload'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import { ScrollToService } from '@nicky-lenaers/ngx-scroll-to'; import { UploaderOptions } from './uploader-options.model'; diff --git a/src/app/shared/utils/markdown.pipe.ts b/src/app/shared/utils/markdown.pipe.ts index e675a863f8..e494a82613 100644 --- a/src/app/shared/utils/markdown.pipe.ts +++ b/src/app/shared/utils/markdown.pipe.ts @@ -62,7 +62,7 @@ export class MarkdownPipe implements PipeTransform { let html: string; if (environment.markdown.mathjax) { md.use(await this.mathjax); - const sanitizeHtml = await this.sanitizeHtml + const sanitizeHtml = await this.sanitizeHtml; html = sanitizeHtml(md.render(value), { // sanitize-html doesn't let through SVG by default, so we extend its allowlists to cover MathJax SVG allowedTags: [ @@ -98,6 +98,6 @@ export class MarkdownPipe implements PipeTransform { html = this.sanitizer.sanitize(SecurityContext.HTML, md.render(value)); } - return this.sanitizer.bypassSecurityTrustHtml(html) + return this.sanitizer.bypassSecurityTrustHtml(html); } } diff --git a/src/app/shared/vocabulary-treeview/vocabulary-treeview.service.ts b/src/app/shared/vocabulary-treeview/vocabulary-treeview.service.ts index ad2525bb7f..f04cd1bc28 100644 --- a/src/app/shared/vocabulary-treeview/vocabulary-treeview.service.ts +++ b/src/app/shared/vocabulary-treeview/vocabulary-treeview.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { map, merge, mergeMap, scan } from 'rxjs/operators'; -import { findIndex } from 'lodash'; +import findIndex from 'lodash/findIndex'; import { LOAD_MORE_NODE, diff --git a/src/app/statistics/statistics.service.spec.ts b/src/app/statistics/statistics.service.spec.ts index 76eadb2d31..b573daf476 100644 --- a/src/app/statistics/statistics.service.spec.ts +++ b/src/app/statistics/statistics.service.spec.ts @@ -2,7 +2,7 @@ import { StatisticsService } from './statistics.service'; import { RequestService } from '../core/data/request.service'; import { HALEndpointServiceStub } from '../shared/testing/hal-endpoint-service.stub'; import { getMockRequestService } from '../shared/mocks/request.service.mock'; -import { isEqual } from 'lodash'; +import isEqual from 'lodash/isEqual'; import { DSpaceObjectType } from '../core/shared/dspace-object-type.model'; import { SearchOptions } from '../shared/search/models/search-options.model'; import { RestRequest } from '../core/data/rest-request.model'; diff --git a/src/app/submission/objects/submission-objects.effects.ts b/src/app/submission/objects/submission-objects.effects.ts index 4a7907cab1..98646009d5 100644 --- a/src/app/submission/objects/submission-objects.effects.ts +++ b/src/app/submission/objects/submission-objects.effects.ts @@ -2,7 +2,9 @@ import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { TranslateService } from '@ngx-translate/core'; -import { findKey, isEqual, union } from 'lodash'; +import findKey from 'lodash/findKey'; +import isEqual from 'lodash/isEqual'; +import union from 'lodash/union'; import { from as observableFrom, Observable, of as observableOf } from 'rxjs'; import { catchError, filter, map, mergeMap, switchMap, take, tap, withLatestFrom } from 'rxjs/operators'; diff --git a/src/app/submission/objects/submission-objects.reducer.ts b/src/app/submission/objects/submission-objects.reducer.ts index 564e5a701b..a05bf05f52 100644 --- a/src/app/submission/objects/submission-objects.reducer.ts +++ b/src/app/submission/objects/submission-objects.reducer.ts @@ -1,5 +1,8 @@ import { hasValue, isEmpty, isNotEmpty, isNotNull, isUndefined } from '../../shared/empty.util'; -import { differenceWith, findKey, isEqual, uniqWith } from 'lodash'; +import differenceWith from 'lodash/differenceWith'; +import findKey from 'lodash/findKey'; +import isEqual from 'lodash/isEqual'; +import uniqWith from 'lodash/uniqWith'; import { ChangeSubmissionCollectionAction, diff --git a/src/app/submission/sections/form/section-form-operations.service.ts b/src/app/submission/sections/form/section-form-operations.service.ts index 7c6c242d42..778063dd31 100644 --- a/src/app/submission/sections/form/section-form-operations.service.ts +++ b/src/app/submission/sections/form/section-form-operations.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; -import { isEqual, isObject } from 'lodash'; +import isEqual from 'lodash/isEqual'; +import isObject from 'lodash/isObject'; import { DYNAMIC_FORM_CONTROL_TYPE_ARRAY, DYNAMIC_FORM_CONTROL_TYPE_GROUP, diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts index 6299b0ccdc..326d277ffb 100644 --- a/src/app/submission/sections/form/section-form.component.ts +++ b/src/app/submission/sections/form/section-form.component.ts @@ -4,7 +4,8 @@ import { DynamicFormControlEvent, DynamicFormControlModel } from '@ng-dynamic-fo import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs'; import { distinctUntilChanged, filter, find, map, mergeMap, take, tap } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; -import { findIndex, isEqual } from 'lodash'; +import findIndex from 'lodash/findIndex'; +import isEqual from 'lodash/isEqual'; import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; import { FormComponent } from '../../../shared/form/form.component'; diff --git a/src/app/submission/sections/sections.directive.ts b/src/app/submission/sections/sections.directive.ts index d82cff82d6..de6d43e1eb 100644 --- a/src/app/submission/sections/sections.directive.ts +++ b/src/app/submission/sections/sections.directive.ts @@ -2,7 +2,7 @@ import { ChangeDetectorRef, Directive, Input, OnDestroy, OnInit } from '@angular import { Observable, Subscription } from 'rxjs'; import { map } from 'rxjs/operators'; -import { uniq } from 'lodash'; +import uniq from 'lodash/uniq'; import { SectionsService } from './sections.service'; import { hasValue, isNotEmpty, isNotNull } from '../../shared/empty.util'; diff --git a/src/app/submission/sections/sections.service.ts b/src/app/submission/sections/sections.service.ts index 56b2356ed7..cc2802dba7 100644 --- a/src/app/submission/sections/sections.service.ts +++ b/src/app/submission/sections/sections.service.ts @@ -5,7 +5,9 @@ import { distinctUntilChanged, filter, map, mergeMap, take } from 'rxjs/operator import { Store } from '@ngrx/store'; import { TranslateService } from '@ngx-translate/core'; import { ScrollToConfigOptions, ScrollToService } from '@nicky-lenaers/ngx-scroll-to'; -import { findIndex, findKey, isEqual } from 'lodash'; +import findIndex from 'lodash/findIndex'; +import findKey from 'lodash/findKey'; +import isEqual from 'lodash/isEqual'; import { SubmissionState } from '../submission.reducers'; import { hasValue, isEmpty, isNotEmpty, isNotUndefined } from '../../shared/empty.util'; diff --git a/tsconfig.json b/tsconfig.json index 4eb577de0f..7d2e9a69af 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,6 +20,7 @@ "strictNullChecks": false, "skipDefaultLibCheck": true, "pretty": true, + "allowSyntheticDefaultImports": true, "target": "es2015", "typeRoots": [ "node_modules/@types", From bde841918c3a22b6a0bdacbcba6981cebd3fde83 Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Mon, 24 Oct 2022 18:54:42 +0200 Subject: [PATCH 4/4] 96252: Transform .json5 to .json in Webpack This allows us to get rid of the json5 dependency in the main bundle and reduces the size of the i18n files we serve a bit --- src/modules/app/browser-app.module.ts | 2 +- src/modules/app/server-app.module.ts | 2 +- .../translate-browser.loader.ts | 3 +-- .../translate-server.loader.ts | 4 +--- webpack/webpack.browser.ts | 4 ++-- webpack/webpack.common.ts | 15 +++++++++++++++ 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/modules/app/browser-app.module.ts b/src/modules/app/browser-app.module.ts index 6e3ebf5d37..6baf339003 100644 --- a/src/modules/app/browser-app.module.ts +++ b/src/modules/app/browser-app.module.ts @@ -35,7 +35,7 @@ import { BrowserInitService } from './browser-init.service'; export const REQ_KEY = makeStateKey('req'); export function createTranslateLoader(transferState: TransferState, http: HttpClient) { - return new TranslateBrowserLoader(transferState, http, 'assets/i18n/', '.json5'); + return new TranslateBrowserLoader(transferState, http, 'assets/i18n/', '.json'); } export function getRequest(transferState: TransferState): any { diff --git a/src/modules/app/server-app.module.ts b/src/modules/app/server-app.module.ts index fa529c4ad9..17e394ede8 100644 --- a/src/modules/app/server-app.module.ts +++ b/src/modules/app/server-app.module.ts @@ -31,7 +31,7 @@ import { ServerAuthRequestService } from '../../app/core/auth/server-auth-reques import { ServerInitService } from './server-init.service'; export function createTranslateLoader(transferState: TransferState) { - return new TranslateServerLoader(transferState, 'dist/server/assets/i18n/', '.json5'); + return new TranslateServerLoader(transferState, 'dist/server/assets/i18n/', '.json'); } @NgModule({ diff --git a/src/ngx-translate-loaders/translate-browser.loader.ts b/src/ngx-translate-loaders/translate-browser.loader.ts index 217f301bd5..a6188c9f15 100644 --- a/src/ngx-translate-loaders/translate-browser.loader.ts +++ b/src/ngx-translate-loaders/translate-browser.loader.ts @@ -5,7 +5,6 @@ import { NGX_TRANSLATE_STATE, NgxTranslateState } from './ngx-translate-state'; import { hasValue } from '../app/shared/empty.util'; import { map } from 'rxjs/operators'; import { of as observableOf, Observable } from 'rxjs'; -import * as JSON5 from 'json5'; /** * A TranslateLoader for ngx-translate to retrieve i18n messages from the TransferState, or download @@ -37,7 +36,7 @@ export class TranslateBrowserLoader implements TranslateLoader { // If they're not available on the transfer state (e.g. when running in dev mode), retrieve // them using HttpClient return this.http.get('' + this.prefix + lang + this.suffix, { responseType: 'text' }).pipe( - map((json: any) => JSON5.parse(json)) + map((json: any) => JSON.parse(json)) ); } } diff --git a/src/ngx-translate-loaders/translate-server.loader.ts b/src/ngx-translate-loaders/translate-server.loader.ts index 4ba6ccd5e9..bc34c1199d 100644 --- a/src/ngx-translate-loaders/translate-server.loader.ts +++ b/src/ngx-translate-loaders/translate-server.loader.ts @@ -4,8 +4,6 @@ import * as fs from 'fs'; import { TransferState } from '@angular/platform-browser'; import { NGX_TRANSLATE_STATE, NgxTranslateState } from './ngx-translate-state'; -const JSON5 = require('json5').default; - /** * A TranslateLoader for ngx-translate to parse json5 files server-side, and store them in the * TransferState @@ -26,7 +24,7 @@ export class TranslateServerLoader implements TranslateLoader { */ public getTranslation(lang: string): Observable { // Retrieve the file for the given language, and parse it - const messages = JSON5.parse(fs.readFileSync(`${this.prefix}${lang}${this.suffix}`, 'utf8')); + const messages = JSON.parse(fs.readFileSync(`${this.prefix}${lang}${this.suffix}`, 'utf8')); // Store the parsed messages in the transfer state so they'll be available immediately when the // app loads on the client this.storeInTransferState(lang, messages); diff --git a/webpack/webpack.browser.ts b/webpack/webpack.browser.ts index 2c33d91afd..5a3b4910ae 100644 --- a/webpack/webpack.browser.ts +++ b/webpack/webpack.browser.ts @@ -13,14 +13,14 @@ module.exports = Object.assign({}, commonExports, { new CompressionPlugin({ filename: '[path][base].gz', algorithm: 'gzip', - test: /\.(js|css|html|svg|json5)$/, + test: /\.(js|css|html|svg|json)$/, threshold: 10240, minRatio: 0.8, }), new CompressionPlugin({ filename: '[path][base].br', algorithm: 'brotliCompress', - test: /\.(js|css|html|svg|json5)$/, + test: /\.(js|css|html|svg|json)$/, compressionOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 11, diff --git a/webpack/webpack.common.ts b/webpack/webpack.common.ts index 9228d41141..05db3b7abf 100644 --- a/webpack/webpack.common.ts +++ b/webpack/webpack.common.ts @@ -3,6 +3,7 @@ import { globalCSSImports, projectRoot } from './helpers'; const CopyWebpackPlugin = require('copy-webpack-plugin'); const path = require('path'); const sass = require('sass'); +const JSON5 = require('json5'); export const copyWebpackOptions = { patterns: [ @@ -11,6 +12,20 @@ export const copyWebpackOptions = { to: path.join('assets', 'fonts'), force: undefined }, + { + from: path.join(__dirname, '..', 'src', 'assets', '**', '*.json5').replace(/\\/g, '/'), + to({ absoluteFilename }) { + // use [\/|\\] to match both POSIX and Windows separators + const matches = absoluteFilename.match(/.*[\/|\\]assets[\/|\\](.+)\.json5$/); + if (matches) { + // matches[1] is the relative path from src/assets to the JSON5 file, without the extension + return path.join('assets', matches[1] + '.json'); + } + }, + transform(content) { + return JSON.stringify(JSON5.parse(content.toString())) + } + }, { from: path.join(__dirname, '..', 'src', 'assets'), to: 'assets',