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 f7e1032cacb..e675a863f8c 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 6d5aa89db72..25547554b03 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 1b1c7a4b00d..55cb7977501 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 9542bfdbe18..edfa13ae848 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 9a59df4b95a..4906ebd0d44 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 6236c7a5dc0..51e8d926eb8 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 b79e83a3f3c..a621895633b 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 2d5acb2cb3d..16dc14dac49 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 b84bb40373a..53817625709 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 3fbeb205d2f..87a90b53a31 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 d45010980e9..037cea8cc58 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 a0cbb06b66d..e2af88fa65f 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 8ed2f9a12ed..c06bcad7f2b 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 d7fcc0cb76a..fcb5c706ac7 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 f1ebecb84fa..440ccd135fc 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 5030ef3bb3d..3c1bad5114e 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 9c0942d4ff4..1dc1db26cc3 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 44ec406e80f..474e6fb0254 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 8999a643e8a..bf6f949575d 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 17a6b034ee0..94dfa007917 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 5d0ff20e2f6..9afeafd4790 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 c15badb976a..2979c3dc090 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 9db9caf3641..37dfda693aa 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 c6819012d96..3b3229f5559 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 5f7ccb2438c..802a7c37c15 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 58960af19e0..06636f4256e 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 bebef5860e1..d44d24f8b8f 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 cd10b9a4a3b..fe495419f0c 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 ef5e84e5015..4978af970ba 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 a281942bc76..b3a78d4669d 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 ca4a47c089d..2aa40f97ae4 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 bd6820d4b39..86a7d99e411 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 764f52ffdf0..2818e37b25f 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 7c16be7542d..086b5e1fd8c 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 22094b2e5d2..c1e9b12efa8 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 c4d6003abd9..2dbf78f5658 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 1d3faabdaa6..08b9585a8c7 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 f153d1009e8..97ae09c1a67 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 b8347971159..fde92e8891b 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 98272d4f433..d37d6a349b6 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 1602fb9839a..4f8954259ef 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 91d9200c2da..cec67e721c5 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 b120c3e016a..b8591848455 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 1852277673e..0e1b4f221b3 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 2abd5290cb6..c094e37ef23 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 a0dd0e5bba1..3cbf033b178 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 e675a863f8c..e494a826138 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 ad2525bb7fd..f04cd1bc28f 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 76eadb2d31a..b573daf4768 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 4a7907cab16..98646009d5b 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 564e5a701b4..a05bf05f52c 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 7c6c242d428..778063dd316 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 6299b0ccdc9..326d277ffb0 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 d82cff82d68..de6d43e1eb1 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 56b2356ed70..cc2802dba7d 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 4eb577de0f7..7d2e9a69afb 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 6e3ebf5d37c..6baf339003e 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 fa529c4ad97..17e394ede80 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 217f301bd57..a6188c9f15c 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 4ba6ccd5e93..bc34c1199da 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 2c33d91afd2..5a3b4910ae7 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 9228d411413..05db3b7abff 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',