mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-02 17:53:30 +00:00
Migrate to Angular 20, TypeScript 5.9, and Angular Material 20 (#11657)
* chore: migrate to Angular 20, TypeScript 5.9, and supporting packages chore: migrate to Angular 20, TypeScript 5.9, and supporting packages This commit migrates the Nx monorepo from Angular 19 to Angular 20 and updates all related dependencies to their compatible versions. - @angular/core: 19.2.18 → 20.3.9 - @angular/material: 19.2.19 → 20.2.14 - @angular/cdk: 19.2.19 → 20.2.14 - @angular/material-date-fns-adapter: 19.2.19 → 20.2.14 - typescript: 5.8.3 → 5.9.3 - ng-packagr: 19.2.2 → 20.3.2 - @angular-devkit/build-angular: 19.2.19 → 20.3.16 - @angular-devkit/architect: 0.1902.19 → 0.2003.16 - @angular-devkit/core: 19.2.19 → 20.3.16 - @angular-devkit/schematics: 19.2.19 → 20.3.16 - @schematics/angular: 19.2.7 → 20.3.16 - @angular-eslint/eslint-plugin: 19.3.0 → 20.7.0 - @angular-eslint/eslint-plugin-template: 19.3.0 → 20.7.0 - @angular-eslint/template-parser: 19.3.0 → 20.7.0 - @typescript-eslint/eslint-plugin: 6.21.0 → 8.55.0 - @typescript-eslint/parser: 6.21.0 → 8.55.0 - @typescript-eslint/typescript-estree: 8.41.0 → 8.55.0 - @typescript-eslint/utils: ^8.51.0 → 8.55.0 - nx: 22.4.1 → 22.5.1 - @nx/angular: 22.1.3 → 22.5.1 - @nx/eslint-plugin: 22.3.3 → 22.5.1 - @nx/js: 22.1.3 → 22.5.1 - @nx/node: 22.1.3 → 22.5.1 - @nx/storybook: ^20.8.4 → 22.5.1 - @nx/workspace: 22.4.5 → 22.5.1 - @nx/webpack: 22.3.3 → 22.5.1 - storybook: ^10.2.0 → 10.2.8 - @storybook/angular: ^10.2.0 → 10.2.8 - @storybook/addon-themes: ^10.2.0 → 10.2.8 1. **PortalInjector Removal (Angular CDK 20)** - Replaced PortalInjector usage with Injector.create() - Updated context-menu-overlay.service.ts to use new API 2. **ESLint Configuration** - Removed deprecated @typescript-eslint/brace-style rule - This rule was removed in @typescript-eslint v8 All libraries build successfully: - ✅ js-api - ✅ extensions - ✅ core - ✅ content-services - ✅ process-services - ✅ process-services-cloud - ✅ insights Dependencies were installed using npm install --legacy-peer-deps due to peer dependency conflicts with @mat-datetimepicker/core which requires Angular CDK ^19.0.0 but we are using 20.2.14. - ESLint warnings about @angular-eslint/prefer-inject are expected - this is a new recommendation in Angular 20 to use inject() function instead of constructor injection. These can be addressed in a follow-up PR. chore: migrate to Angular 20, TypeScript 5.9, and supporting packages This commit migrates the Nx monorepo from Angular 19 to Angular 20 and updates all related dependencies to their compatible versions. - @angular/core: 19.2.18 → 20.3.9 - @angular/material: 19.2.19 → 20.2.14 - @angular/cdk: 19.2.19 → 20.2.14 - @angular/material-date-fns-adapter: 19.2.19 → 20.2.14 - typescript: 5.8.3 → 5.9.3 - ng-packagr: 19.2.2 → 20.3.2 - @angular-devkit/build-angular: 19.2.19 → 20.3.16 - @angular-devkit/architect: 0.1902.19 → 0.2003.16 - @angular-devkit/core: 19.2.19 → 20.3.16 - @angular-devkit/schematics: 19.2.19 → 20.3.16 - @schematics/angular: 19.2.7 → 20.3.16 - @angular-eslint/eslint-plugin: 19.3.0 → 20.7.0 - @angular-eslint/eslint-plugin-template: 19.3.0 → 20.7.0 - @angular-eslint/template-parser: 19.3.0 → 20.7.0 - @typescript-eslint/eslint-plugin: 6.21.0 → 8.55.0 - @typescript-eslint/parser: 6.21.0 → 8.55.0 - @typescript-eslint/typescript-estree: 8.41.0 → 8.55.0 - @typescript-eslint/utils: ^8.51.0 → 8.55.0 - nx: 22.4.1 → 22.5.1 - @nx/angular: 22.1.3 → 22.5.1 - @nx/eslint-plugin: 22.3.3 → 22.5.1 - @nx/js: 22.1.3 → 22.5.1 - @nx/node: 22.1.3 → 22.5.1 - @nx/storybook: ^20.8.4 → 22.5.1 - @nx/workspace: 22.4.5 → 22.5.1 - @nx/webpack: 22.3.3 → 22.5.1 - storybook: ^10.2.0 → 10.2.8 - @storybook/angular: ^10.2.0 → 10.2.8 - @storybook/addon-themes: ^10.2.0 → 10.2.8 1. **PortalInjector Removal (Angular CDK 20)** - Replaced PortalInjector usage with Injector.create() - Updated context-menu-overlay.service.ts to use new API 2. **ESLint Configuration** - Removed deprecated @typescript-eslint/brace-style rule - This rule was removed in @typescript-eslint v8 All libraries build successfully: - ✅ js-api - ✅ extensions - ✅ core - ✅ content-services - ✅ process-services - ✅ process-services-cloud - ✅ insights Dependencies were installed using npm install --legacy-peer-deps due to peer dependency conflicts with @mat-datetimepicker/core which requires Angular CDK ^19.0.0 but we are using 20.2.14. - ESLint warnings about @angular-eslint/prefer-inject are expected - this is a new recommendation in Angular 20 to use inject() function instead of constructor injection. These can be addressed in a follow-up PR. To fix these automatically, run: ng generate @angular/core:inject --path=lib fix: resolve peer dependency conflicts for CI/CD - Update @mat-datetimepicker/core from 15.0.2 to 16.0.1 (supports Angular 20) - Update webpack override to 5.104.1 for consistency - Add .npmrc with legacy-peer-deps=true for npm ci compatibility - Fixes npm ci failures in CI/CD pipeline fix: update webpack to 5.105.0 for Storybook compatibility - Align webpack version with @angular-devkit/build-angular bundled version - Fixes Storybook compilation error with webpack instance mismatch - Removes unnecessary webpack overrides chore: finalize Angular 20 migration and improve migration prompt - Marked all migration tasks as completed in the migration plan. - Added a comprehensive summary of the migration process, including phases, completed tasks, and known issues. - Introduced an improved migration prompt that addresses critical considerations and provides a detailed migration strategy for Angular 20 and related packages. fix: update migration prompt and tests for Angular 20 breaking changes - Enhanced migration prompt with specific instructions for handling Angular CDK Directionality API changes and removal of ng-reflect-* attributes. - Updated unit tests to replace deprecated ng-reflect-* attribute checks with appropriate Angular testing patterns. - Adjusted user preferences service to utilize the new directionality API method for setting text direction. fix: enhance ImgViewerComponent to handle cleanup and prevent errors after destruction - Added a `destroyed` flag to manage component lifecycle and prevent operations on a destroyed instance. - Implemented `afterEach` hooks in tests to ensure proper fixture cleanup. - Updated key event handlers and methods to check for the `destroyed` state before executing actions, improving stability and preventing errors. feat: update ESLint configuration to include @angular-eslint/prefer-inject rule - Added the @angular-eslint/prefer-inject rule to .eslintrc.json files in content-services, process-services, and process-services-cloud, promoting the use of the inject() function for dependency injection. - Made minor adjustments to comments in search-logical-filter.component.ts for clarity. chore: update ESLint configuration to include @angular-eslint/prefer-inject rule - Added the @angular-eslint/prefer-inject rule to .eslintrc.json files in extensions, insights, and js-api, promoting the use of the inject() function for dependency injection. - Removed unnecessary eslint-disable comments in process-list-cloud.component.ts and base-task-list-cloud.component.ts for cleaner code. remove unnecessary changes remove useless changes cleanup useless changes remove useless changes Update package.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> chore: update version of @ngx-translate/core to 17.0.0 in package.json and package-lock.json Update package.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Update package.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Update .npmrc Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> chore: upgrade apollo-angular and jest packages to support Angular 20 - Upgrade apollo-angular from 10.0.3 to 13.0.0 - Upgrade @apollo/client from 3.13.1 to ^4.0.1 - Upgrade jest packages to v30 (jest, jest-environment-jsdom) - Upgrade jest-preset-angular from 14.4.2 to 16.1.1 - Add overrides for Angular 20 peer dependency compatibility chore: downgrade @apollo/client and apollo-angular to compatible versions chore: downgrade @apollo/client and apollo-angular to compatible versions chore: remove unused configuration options from jest and tsconfig chore: refactor window.location mock in oauth2 tests for improved clarity and functionality chore: enhance oauth2Auth tests and improve hash handling logic chore: remove @typescript-eslint/brace-style rule from ESLint configuration chore: add prefer-optional-chain rule to ESLint configuration chore: update ESLint rules for optional chaining and refactor type definitions chore: refactor tests to use TestBed for dependency injection in FileViewer and ProcessFormRendering services chore: update AttachFileWidgetComponent to ensure early return after download chore: update AttachFileWidgetComponent to ensure early return after download chore: update unselectFacetBucket method to use optional chaining for safer property access * chore: clean up package-lock.json and update webpack version in package.json * [ACS-11306] Corrected main for eslint-angular * [ACS-11306] Reverted unwanted change * [ACS-11306] Fixed importing issue on ACA * [ACS-11306] Updated node-fetch * [ACS-11306] Reverted last commit * [ACS-11306] Fixed rendering issue with pdf viewer * [ACS-11306] Corrected storybook related versions * Updating dependencies and fixing conflict * [ACS-11306] Fixed cannot find name Buffer occurred in ACA * chore: Updating pnpm lock file * chore: Fixing ESLint issue * chore: Upgrading to version 20.3.24 to avoid security issue * chore: Fixing unit test * chore: Fixing type and exporting missing model * chore: Fixing type * Chore: Migrating to Angular 20.3.25 to mitigate security issues * Fix after rebase * Removing unused deps * Aligning deps * fix create dialog name field hint (#12007) --------- Co-authored-by: Aleksander Sklorz <Aleksander.Sklorz@hyland.com> Co-authored-by: Ehsan Rezaei <ehsan.rezaei@hyland.com> Co-authored-by: Grzegorz Jaśkowski <138671284+g-jaskowski@users.noreply.github.com>
This commit is contained in:
co-authored by
Aleksander Sklorz
Ehsan Rezaei
Grzegorz Jaśkowski
parent
7546aa91a3
commit
d2d6696c05
@@ -14,16 +14,22 @@
|
|||||||
[formControlName]="'name'"
|
[formControlName]="'name'"
|
||||||
adf-auto-focus
|
adf-auto-focus
|
||||||
/>
|
/>
|
||||||
|
@if (form.controls['name'].dirty && form.controls['name'].invalid) {
|
||||||
|
<mat-error>
|
||||||
|
@if (form.controls['name'].hasError('required')) {
|
||||||
|
<span>
|
||||||
|
{{ 'CORE.FOLDER_DIALOG.FOLDER_NAME.ERRORS.REQUIRED' | translate }}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
|
||||||
<mat-hint *ngIf="form.controls['name'].dirty">
|
@else if (form.controls['name'].hasError('message')) {
|
||||||
<span *ngIf="form.controls['name'].errors?.required">
|
<span>
|
||||||
{{ 'CORE.FOLDER_DIALOG.FOLDER_NAME.ERRORS.REQUIRED' | translate }}
|
{{ form.controls['name'].errors?.message | translate }}
|
||||||
</span>
|
</span>
|
||||||
|
}
|
||||||
|
</mat-error>
|
||||||
|
}
|
||||||
|
|
||||||
<span *ngIf="!form.controls['name'].errors?.required && form.controls['name'].errors?.message">
|
|
||||||
{{ form.controls['name'].errors?.message | translate }}
|
|
||||||
</span>
|
|
||||||
</mat-hint>
|
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field class="adf-full-width adf-folder-dialog-form-field">
|
<mat-form-field class="adf-full-width adf-folder-dialog-form-field">
|
||||||
|
|||||||
+1
-1
@@ -100,7 +100,7 @@ describe('SearchChipListComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should remove the entry upon remove button click', async () => {
|
it('should remove the entry upon remove button click', async () => {
|
||||||
spyOn(searchFacetFiltersService, 'unselectFacetBucket').and.callThrough();
|
spyOn(searchFacetFiltersService, 'unselectFacetBucket').and.stub();
|
||||||
|
|
||||||
searchFacetFiltersService.selectedBuckets = [
|
searchFacetFiltersService.selectedBuckets = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ export class SearchFacetFiltersService {
|
|||||||
unselectFacetBucket(facetField: FacetField, bucket: FacetFieldBucket) {
|
unselectFacetBucket(facetField: FacetField, bucket: FacetFieldBucket) {
|
||||||
if (bucket) {
|
if (bucket) {
|
||||||
bucket.checked = false;
|
bucket.checked = false;
|
||||||
this.queryBuilder.removeUserFacetBucket(facetField.field, bucket);
|
this.queryBuilder.removeUserFacetBucket(facetField?.field, bucket);
|
||||||
this.updateSelectedBuckets();
|
this.updateSelectedBuckets();
|
||||||
this.queryBuilder.update();
|
this.queryBuilder.update();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,3 +16,4 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './services/security-controls-groups-marks-security.service';
|
export * from './services/security-controls-groups-marks-security.service';
|
||||||
|
export * from './services/models/security-controls-mark-response.interface';
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
[mimeType]="mimeType"
|
[mimeType]="mimeType"
|
||||||
[nodeMimeType]="nodeMimeType"
|
[nodeMimeType]="nodeMimeType"
|
||||||
[urlFile]="urlFileContent"
|
[urlFile]="urlFileContent"
|
||||||
|
[blobFile]="blobFileContent"
|
||||||
[tracks]="tracks"
|
[tracks]="tracks"
|
||||||
[readOnly]="readOnly || !canEditNode"
|
[readOnly]="readOnly || !canEditNode"
|
||||||
[showToolbarDividers]="showToolbarDividers"
|
[showToolbarDividers]="showToolbarDividers"
|
||||||
|
|||||||
@@ -374,13 +374,20 @@ describe('AlfrescoViewerComponent', () => {
|
|||||||
expect(component.nodesApi.getNode).toHaveBeenCalledTimes(2);
|
expect(component.nodesApi.getNode).toHaveBeenCalledTimes(2);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should append version of the file to the file content URL', fakeAsync(() => {
|
it('should append version of the file to the file content URL', async () => {
|
||||||
|
const mockBlob = new Blob(['fake pdf content'], { type: 'application/pdf' });
|
||||||
|
const mockResponse = {
|
||||||
|
ok: true,
|
||||||
|
blob: () => Promise.resolve(mockBlob)
|
||||||
|
} as Response;
|
||||||
|
spyOn(window, 'fetch').and.returnValue(Promise.resolve(mockResponse));
|
||||||
|
|
||||||
spyOn(component.nodesApi, 'getNode').and.returnValue(
|
spyOn(component.nodesApi, 'getNode').and.returnValue(
|
||||||
Promise.resolve(
|
Promise.resolve(
|
||||||
new NodeEntry({
|
new NodeEntry({
|
||||||
entry: new Node({
|
entry: new Node({
|
||||||
name: 'file1.pdf',
|
name: 'file1.pdf',
|
||||||
content: new ContentInfo(),
|
content: new ContentInfo({ mimeType: 'application/pdf' }),
|
||||||
properties: { 'cm:versionLabel': '10' }
|
properties: { 'cm:versionLabel': '10' }
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -392,11 +399,12 @@ describe('AlfrescoViewerComponent', () => {
|
|||||||
component.showViewer = true;
|
component.showViewer = true;
|
||||||
component.versionId = null;
|
component.versionId = null;
|
||||||
component.ngOnChanges(getSimpleChanges('id1'));
|
component.ngOnChanges(getSimpleChanges('id1'));
|
||||||
tick();
|
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
expect(component.fileName).toBe('file1.pdf');
|
expect(component.fileName).toBe('file1.pdf');
|
||||||
expect(component.urlFileContent).toContain('/public/alfresco/versions/1/nodes/id1/content?attachment=false&10');
|
expect(component.blobFileContent).toBe(mockBlob);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should change display name every time node`s version changes', fakeAsync(() => {
|
it('should change display name every time node`s version changes', fakeAsync(() => {
|
||||||
spyOn(component.nodesApi, 'getNode').and.returnValue(
|
spyOn(component.nodesApi, 'getNode').and.returnValue(
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ export class AlfrescoViewerComponent implements OnChanges, OnInit {
|
|||||||
|
|
||||||
versionEntry: VersionEntry;
|
versionEntry: VersionEntry;
|
||||||
urlFileContent: string;
|
urlFileContent: string;
|
||||||
|
blobFileContent: Blob;
|
||||||
fileName: string;
|
fileName: string;
|
||||||
mimeType: string;
|
mimeType: string;
|
||||||
nodeMimeType: string;
|
nodeMimeType: string;
|
||||||
@@ -274,6 +275,7 @@ export class AlfrescoViewerComponent implements OnChanges, OnInit {
|
|||||||
private async onNodeUpdated(node: Node) {
|
private async onNodeUpdated(node: Node) {
|
||||||
if (node && node.id === this.nodeId) {
|
if (node && node.id === this.nodeId) {
|
||||||
this.generateCacheBusterNumber();
|
this.generateCacheBusterNumber();
|
||||||
|
this.blobFileContent = null;
|
||||||
|
|
||||||
await this.setUpNodeFile(node);
|
await this.setUpNodeFile(node);
|
||||||
}
|
}
|
||||||
@@ -298,6 +300,7 @@ export class AlfrescoViewerComponent implements OnChanges, OnInit {
|
|||||||
|
|
||||||
private async setupNode() {
|
private async setupNode() {
|
||||||
try {
|
try {
|
||||||
|
this.blobFileContent = null;
|
||||||
this.nodeEntry = await this.nodesApi.getNode(this.nodeId, { include: ['allowableOperations'] });
|
this.nodeEntry = await this.nodesApi.getNode(this.nodeId, { include: ['allowableOperations'] });
|
||||||
if (this.versionId) {
|
if (this.versionId) {
|
||||||
this.versionEntry = await this.versionsApi.getVersion(this.nodeId, this.versionId);
|
this.versionEntry = await this.versionsApi.getVersion(this.nodeId, this.versionId);
|
||||||
@@ -348,12 +351,34 @@ export class AlfrescoViewerComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
} else if (viewerType === 'media') {
|
} else if (viewerType === 'media') {
|
||||||
this.tracks = await this.renditionService.generateMediaTracksRendition(this.nodeId);
|
this.tracks = await this.renditionService.generateMediaTracksRendition(this.nodeId);
|
||||||
|
} else if (viewerType === 'pdf') {
|
||||||
|
try {
|
||||||
|
const contentUrl = versionData
|
||||||
|
? this.contentApi.getVersionContentUrl(this.nodeId, versionData.id)
|
||||||
|
: this.contentApi.getContentUrl(this.nodeId);
|
||||||
|
|
||||||
|
// Fetch the content as Blob using fetch API with credentials
|
||||||
|
const response = await fetch(contentUrl, {
|
||||||
|
credentials: 'include',
|
||||||
|
headers: {
|
||||||
|
'Cache-Control': 'no-cache'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.blobFileContent = await response.blob();
|
||||||
|
urlFileContent = null;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[ADF DEBUG] Failed to fetch PDF as blob, falling back to URL', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mimeType = mimeType;
|
this.mimeType = mimeType;
|
||||||
this.nodeMimeType = nodeMimeType;
|
this.nodeMimeType = nodeMimeType;
|
||||||
this.fileName = versionData ? versionData.name : nodeData.name;
|
this.fileName = versionData ? versionData.name : nodeData.name;
|
||||||
this.urlFileContent = urlFileContent + (this.cacheBusterNumber ? '&' + this.cacheBusterNumber : '');
|
this.urlFileContent = urlFileContent ? urlFileContent + (this.cacheBusterNumber ? '&' + this.cacheBusterNumber : '') : null;
|
||||||
this.sidebarRightTemplateContext.node = nodeData;
|
this.sidebarRightTemplateContext.node = nodeData;
|
||||||
this.sidebarLeftTemplateContext.node = nodeData;
|
this.sidebarLeftTemplateContext.node = nodeData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/// <reference types="node" />
|
||||||
|
|
||||||
import { Injectable, inject } from '@angular/core';
|
import { Injectable, inject } from '@angular/core';
|
||||||
import { AdfHttpClient } from '@alfresco/adf-core/api';
|
import { AdfHttpClient } from '@alfresco/adf-core/api';
|
||||||
import { Authentication } from '../interfaces/authentication.interface';
|
import { Authentication } from '../interfaces/authentication.interface';
|
||||||
|
|||||||
+1
-1
@@ -751,7 +751,7 @@ describe('CardViewDateItemComponent', () => {
|
|||||||
label: 'Date label',
|
label: 'Date label',
|
||||||
value: new Date('07/10/2017'),
|
value: new Date('07/10/2017'),
|
||||||
key: 'dateKey',
|
key: 'dateKey',
|
||||||
format: 'YYYY-MM-dd',
|
format: 'yyyy-MM-dd',
|
||||||
editable: true,
|
editable: true,
|
||||||
allowManualInput: false
|
allowManualInput: false
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -135,7 +135,8 @@ export class UserPreferencesService {
|
|||||||
|
|
||||||
this.select('textOrientation').subscribe((direction: Direction) => {
|
this.select('textOrientation').subscribe((direction: Direction) => {
|
||||||
renderer.setAttribute(this.document.body, 'dir', direction);
|
renderer.setAttribute(this.document.body, 'dir', direction);
|
||||||
(this.directionality as any).value = direction;
|
this.directionality.valueSignal.set(direction);
|
||||||
|
this.directionality.change.emit(direction);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -92,7 +92,7 @@ export default createESLintRule<unknown[], MessageIds>({
|
|||||||
(() => {
|
(() => {
|
||||||
const propValue = (node as TSESTree.Property).value;
|
const propValue = (node as TSESTree.Property).value;
|
||||||
return ASTUtils.isMemberExpression(propValue)
|
return ASTUtils.isMemberExpression(propValue)
|
||||||
? fixer.replaceText(propValue.property, 'None')
|
? fixer.replaceText((propValue as TSESTree.MemberExpression).property, 'None')
|
||||||
: fixer.replaceText(propValue, viewEncapsulationNone);
|
: fixer.replaceText(propValue, viewEncapsulationNone);
|
||||||
})()
|
})()
|
||||||
].filter(isNotNullOrUndefined);
|
].filter(isNotNullOrUndefined);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { EnvironmentProviders, inject, provideAppInitializer, Provider, Type } f
|
|||||||
import { AppExtensionService } from './services/app-extension.service';
|
import { AppExtensionService } from './services/app-extension.service';
|
||||||
import { ExtensionService } from './services/extension.service';
|
import { ExtensionService } from './services/extension.service';
|
||||||
import { RuleEvaluator } from './config/rule.extensions';
|
import { RuleEvaluator } from './config/rule.extensions';
|
||||||
|
import { CanActivateFn } from '@angular/router';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides all necessary entries for the app extensibility
|
* Provides all necessary entries for the app extensibility
|
||||||
@@ -61,7 +62,7 @@ export function provideAppExtensions(): (Provider | EnvironmentProviders)[] {
|
|||||||
* @returns list of Angular providers
|
* @returns list of Angular providers
|
||||||
*/
|
*/
|
||||||
export function provideExtensions(params: {
|
export function provideExtensions(params: {
|
||||||
authGuards?: Record<string, unknown>;
|
authGuards?: Record<string, CanActivateFn>;
|
||||||
evaluators?: Record<string, RuleEvaluator>;
|
evaluators?: Record<string, RuleEvaluator>;
|
||||||
components?: Record<string, Type<any>>;
|
components?: Record<string, Type<any>>;
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import { ComponentRegisterService } from './component-register.service';
|
|||||||
import { RuleService } from './rule.service';
|
import { RuleService } from './rule.service';
|
||||||
import { ExtensionElement } from '../config/extension-element';
|
import { ExtensionElement } from '../config/extension-element';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
|
import { CanActivateFn } from '@angular/router';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default extensions factory
|
* The default extensions factory
|
||||||
@@ -87,7 +88,7 @@ export class ExtensionService {
|
|||||||
routes: Array<RouteRef> = [];
|
routes: Array<RouteRef> = [];
|
||||||
actions: Array<ActionRef> = [];
|
actions: Array<ActionRef> = [];
|
||||||
features: Array<any> = [];
|
features: Array<any> = [];
|
||||||
authGuards: Record<string, unknown> = {};
|
authGuards: Record<string, CanActivateFn> = {};
|
||||||
|
|
||||||
setup$: Observable<ExtensionConfig>;
|
setup$: Observable<ExtensionConfig>;
|
||||||
|
|
||||||
@@ -162,7 +163,7 @@ export class ExtensionService {
|
|||||||
* Adds one or more new auth guards to the existing set.
|
* Adds one or more new auth guards to the existing set.
|
||||||
* @param values The new auth guards to add
|
* @param values The new auth guards to add
|
||||||
*/
|
*/
|
||||||
setAuthGuards(values: Record<string, unknown>) {
|
setAuthGuards(values: Record<string, CanActivateFn>) {
|
||||||
if (values) {
|
if (values) {
|
||||||
this.authGuards = Object.assign({}, this.authGuards, values);
|
this.authGuards = Object.assign({}, this.authGuards, values);
|
||||||
}
|
}
|
||||||
@@ -190,7 +191,7 @@ export class ExtensionService {
|
|||||||
* @param ids Array of ID value to look for
|
* @param ids Array of ID value to look for
|
||||||
* @returns Array of auth guards or empty array if none were found
|
* @returns Array of auth guards or empty array if none were found
|
||||||
*/
|
*/
|
||||||
getAuthGuards(ids: string[]): Array<unknown> {
|
getAuthGuards(ids: string[]): Array<CanActivateFn> {
|
||||||
return (ids || []).map((id) => this.authGuards[id]).filter((guard) => guard);
|
return (ids || []).map((id) => this.authGuards[id]).filter((guard) => guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ export default {
|
|||||||
testEnvironment: '<rootDir>/test/jest-jsdom-fetch-environment.ts',
|
testEnvironment: '<rootDir>/test/jest-jsdom-fetch-environment.ts',
|
||||||
setupFiles: ['<rootDir>/src/test-fetch-setup.ts'],
|
setupFiles: ['<rootDir>/src/test-fetch-setup.ts'],
|
||||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||||
collectCoverage: true,
|
|
||||||
coverageReporters: ['html', ['text-summary', { file: 'summary.txt' }], 'text-summary'],
|
coverageReporters: ['html', ['text-summary', { file: 'summary.txt' }], 'text-summary'],
|
||||||
coverageDirectory: '../../coverage/js-api',
|
coverageDirectory: '../../coverage/js-api',
|
||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
|
|||||||
@@ -438,7 +438,7 @@ export class Oauth2Auth extends AlfrescoApiClient {
|
|||||||
|
|
||||||
if (!externalHash) {
|
if (!externalHash) {
|
||||||
hash = decodeURIComponent(window.location.hash);
|
hash = decodeURIComponent(window.location.hash);
|
||||||
if (!this.startWithHashRoute(hash)) {
|
if (hash && !this.startWithHashRoute(hash)) {
|
||||||
window.location.hash = '';
|
window.location.hash = '';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -15,5 +15,4 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
|
|
||||||
export const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
export const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
||||||
|
|||||||
@@ -42,26 +42,24 @@ describe('Oauth2 test', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
alfrescoJsApi.storage.setStorage(mockStorage);
|
alfrescoJsApi.storage.setStorage(mockStorage);
|
||||||
Object.defineProperty(window, 'location', {
|
delete (window as any).location;
|
||||||
writable: true,
|
(window as any).location = {
|
||||||
value: {
|
ancestorOrigins: null,
|
||||||
ancestorOrigins: null,
|
hash: null,
|
||||||
hash: null,
|
host: 'dummy.com',
|
||||||
host: 'dummy.com',
|
port: '80',
|
||||||
port: '80',
|
protocol: 'http:',
|
||||||
protocol: 'http:',
|
hostname: 'dummy.com',
|
||||||
hostname: 'dummy.com',
|
href: 'http://localhost/',
|
||||||
href: 'http://localhost/',
|
origin: 'dummy.com',
|
||||||
origin: 'dummy.com',
|
pathname: null,
|
||||||
pathname: null,
|
search: null,
|
||||||
search: null,
|
assign: jest.fn((url: string) => {
|
||||||
assign: (url: string) => {
|
window.location.href = url;
|
||||||
window.location.href = url;
|
}),
|
||||||
},
|
reload: jest.fn(),
|
||||||
reload: null,
|
replace: jest.fn()
|
||||||
replace: null
|
};
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -209,6 +207,10 @@ describe('Oauth2 test', () => {
|
|||||||
alfrescoJsApi
|
alfrescoJsApi
|
||||||
);
|
);
|
||||||
|
|
||||||
|
jest.spyOn(oauth2Auth as any, 'silentRefresh').mockImplementation(function (this: any) {
|
||||||
|
this.pollingRefreshToken();
|
||||||
|
});
|
||||||
|
|
||||||
let calls = 0;
|
let calls = 0;
|
||||||
oauth2Auth.refreshToken = () => {
|
oauth2Auth.refreshToken = () => {
|
||||||
calls++;
|
calls++;
|
||||||
@@ -245,6 +247,10 @@ describe('Oauth2 test', () => {
|
|||||||
alfrescoJsApi
|
alfrescoJsApi
|
||||||
);
|
);
|
||||||
|
|
||||||
|
jest.spyOn(oauth2Auth as any, 'silentRefresh').mockImplementation(function (this: any) {
|
||||||
|
this.pollingRefreshToken();
|
||||||
|
});
|
||||||
|
|
||||||
let calls = 0;
|
let calls = 0;
|
||||||
oauth2Auth.refreshToken = () => {
|
oauth2Auth.refreshToken = () => {
|
||||||
calls++;
|
calls++;
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ describe('Oauth2 Implicit flow test', () => {
|
|||||||
alfrescoJsApi
|
alfrescoJsApi
|
||||||
);
|
);
|
||||||
|
|
||||||
oauth2Auth.on('implicit_redirect', () => {
|
oauth2Auth.on('implicit_redirect', (href: string) => {
|
||||||
assert.equal(window.location.href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
|
assert.equal(href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -116,8 +116,8 @@ describe('Oauth2 Implicit flow test', () => {
|
|||||||
let setItemCalled = false;
|
let setItemCalled = false;
|
||||||
alfrescoJsApi.storage.setItem = () => (setItemCalled = true);
|
alfrescoJsApi.storage.setItem = () => (setItemCalled = true);
|
||||||
|
|
||||||
oauth2Auth.on('implicit_redirect', () => {
|
oauth2Auth.on('implicit_redirect', (href: string) => {
|
||||||
assert.equal(window.location.href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
|
assert.equal(href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
|
||||||
assert.equal(setItemCalled, true);
|
assert.equal(setItemCalled, true);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -174,8 +174,8 @@ describe('Oauth2 Implicit flow test', () => {
|
|||||||
let lastValues: [string, any];
|
let lastValues: [string, any];
|
||||||
alfrescoJsApi.storage.setItem = (key, value) => (lastValues = [key, value]);
|
alfrescoJsApi.storage.setItem = (key, value) => (lastValues = [key, value]);
|
||||||
|
|
||||||
oauth2Auth.on('implicit_redirect', () => {
|
oauth2Auth.on('implicit_redirect', (href: string) => {
|
||||||
assert.equal(window.location.href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
|
assert.equal(href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
|
||||||
assert.deepEqual(lastValues, ['loginFragment', '/redirect-path&session_state=eqfqwfqwf']);
|
assert.deepEqual(lastValues, ['loginFragment', '/redirect-path&session_state=eqfqwfqwf']);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './components/screen-cloud/user-task-screen/screen-cloud.model';
|
export * from './components/screen-cloud/user-task-screen/screen-cloud.model';
|
||||||
|
export * from './components/screen-cloud/start-process-event-screen/start-process-screen.model';
|
||||||
export * from './components/screen-cloud/start-process-event-screen/start-process-screen-cloud.component';
|
export * from './components/screen-cloud/start-process-event-screen/start-process-screen-cloud.component';
|
||||||
export * from './services/screen-rendering.service';
|
export * from './services/screen-rendering.service';
|
||||||
export * from './services/provide-screen';
|
export * from './services/provide-screen';
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { ProcessFormRenderingService } from './process-form-rendering.service';
|
import { ProcessFormRenderingService } from './process-form-rendering.service';
|
||||||
import { FormFieldModel, FormFieldTypes } from '@alfresco/adf-core';
|
import { FormFieldModel, FormFieldTypes, FormService } from '@alfresco/adf-core';
|
||||||
import { AttachFolderWidgetComponent } from './widgets/content-widget/attach-folder-widget.component';
|
import { AttachFolderWidgetComponent } from './widgets/content-widget/attach-folder-widget.component';
|
||||||
import { DropdownWidgetComponent } from './widgets/dropdown/dropdown.widget';
|
import { DropdownWidgetComponent } from './widgets/dropdown/dropdown.widget';
|
||||||
import { DynamicTableWidgetComponent } from './widgets/dynamic-table/dynamic-table.widget';
|
import { DynamicTableWidgetComponent } from './widgets/dynamic-table/dynamic-table.widget';
|
||||||
@@ -27,13 +27,16 @@ import { TypeaheadWidgetComponent } from './widgets/typeahead/typeahead.widget';
|
|||||||
import { DocumentWidgetComponent } from './widgets/document/document.widget';
|
import { DocumentWidgetComponent } from './widgets/document/document.widget';
|
||||||
import { AttachFileWidgetComponent } from './widgets/content-widget/attach-file-widget.component';
|
import { AttachFileWidgetComponent } from './widgets/content-widget/attach-file-widget.component';
|
||||||
import { FileViewerWidgetComponent } from './widgets/file-viewer/file-viewer.widget';
|
import { FileViewerWidgetComponent } from './widgets/file-viewer/file-viewer.widget';
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
describe('ProcessFormRenderingService', () => {
|
describe('ProcessFormRenderingService', () => {
|
||||||
|
|
||||||
let service: ProcessFormRenderingService;
|
let service: ProcessFormRenderingService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service = new ProcessFormRenderingService();
|
TestBed.configureTestingModule({
|
||||||
|
providers: [ProcessFormRenderingService, FormService]
|
||||||
|
});
|
||||||
|
service = TestBed.inject(ProcessFormRenderingService);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should resolve Upload field as Upload widget', () => {
|
it('should resolve Upload field as Upload widget', () => {
|
||||||
@@ -106,5 +109,4 @@ describe('ProcessFormRenderingService', () => {
|
|||||||
const type = resolver(null);
|
const type = resolver(null);
|
||||||
expect(type).toBe(FileViewerWidgetComponent);
|
expect(type).toBe(FileViewerWidgetComponent);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
+1
@@ -166,6 +166,7 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
|
|||||||
const nodeUrl = this.contentService.getContentUrl(nodeUploaded.id);
|
const nodeUrl = this.contentService.getContentUrl(nodeUploaded.id);
|
||||||
this.downloadService.downloadUrl(nodeUrl, file.name);
|
this.downloadService.downloadUrl(nodeUrl, file.name);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (file.sourceId) {
|
if (file.sourceId) {
|
||||||
const sourceHost = this.findSource(file.source);
|
const sourceHost = this.findSource(file.source);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
import { FileViewerWidgetComponent } from './file-viewer.widget';
|
import { FileViewerWidgetComponent } from './file-viewer.widget';
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { FormModel, FormService, FormFieldModel, RedirectAuthService } from '@alfresco/adf-core';
|
import { FormModel, FormService, FormFieldModel, RedirectAuthService } from '@alfresco/adf-core';
|
||||||
import { EMPTY, of } from 'rxjs';
|
import { EMPTY, of, Subject } from 'rxjs';
|
||||||
|
|
||||||
describe('FileViewerWidgetComponent', () => {
|
describe('FileViewerWidgetComponent', () => {
|
||||||
const fakeForm = new FormModel();
|
const fakeForm = new FormModel();
|
||||||
@@ -42,6 +42,11 @@ describe('FileViewerWidgetComponent', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
formServiceStub = {
|
||||||
|
formEvents: new Subject(),
|
||||||
|
formRulesEvent: new Subject()
|
||||||
|
};
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [FileViewerWidgetComponent],
|
imports: [FileViewerWidgetComponent],
|
||||||
providers: [
|
providers: [
|
||||||
@@ -49,8 +54,6 @@ describe('FileViewerWidgetComponent', () => {
|
|||||||
{ provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } }
|
{ provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
formServiceStub = TestBed.inject(FormService);
|
|
||||||
fixture = TestBed.createComponent(FileViewerWidgetComponent);
|
fixture = TestBed.createComponent(FileViewerWidgetComponent);
|
||||||
widget = fixture.componentInstance;
|
widget = fixture.componentInstance;
|
||||||
});
|
});
|
||||||
|
|||||||
+32
-32
@@ -39,24 +39,25 @@
|
|||||||
"process services-cloud"
|
"process services-cloud"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "19.2.20",
|
"@angular-eslint/utils": "20.7.0",
|
||||||
"@angular/cdk": "19.2.19",
|
"@angular/animations": "20.3.25",
|
||||||
"@angular/common": "19.2.20",
|
"@angular/cdk": "20.2.14",
|
||||||
"@angular/compiler": "19.2.20",
|
"@angular/common": "20.3.25",
|
||||||
"@angular/core": "19.2.20",
|
"@angular/compiler": "20.3.25",
|
||||||
"@angular/forms": "19.2.20",
|
"@angular/core": "20.3.25",
|
||||||
"@angular/material": "19.2.19",
|
"@angular/forms": "20.3.25",
|
||||||
"@angular/material-date-fns-adapter": "19.2.19",
|
"@angular/material": "20.2.14",
|
||||||
"@angular/platform-browser": "19.2.20",
|
"@angular/material-date-fns-adapter": "20.2.14",
|
||||||
"@angular/platform-browser-dynamic": "19.2.20",
|
"@angular/platform-browser": "20.3.25",
|
||||||
"@angular/router": "19.2.20",
|
"@angular/platform-browser-dynamic": "20.3.25",
|
||||||
|
"@angular/router": "20.3.25",
|
||||||
"@apollo/client": "3.13.1",
|
"@apollo/client": "3.13.1",
|
||||||
"@babel/runtime": "7.26.10",
|
"@babel/runtime": "7.26.10",
|
||||||
"@cspell/eslint-plugin": "10.0.0",
|
"@cspell/eslint-plugin": "10.0.0",
|
||||||
"@mat-datetimepicker/core": "15.0.2",
|
"@mat-datetimepicker/core": "16.0.1",
|
||||||
"@ngx-translate/core": "17.0.0",
|
"@ngx-translate/core": "17.0.0",
|
||||||
"angular-oauth2-oidc": "19.0.0",
|
"angular-oauth2-oidc": "19.0.0",
|
||||||
"apollo-angular": "10.0.3",
|
"apollo-angular": "11.0.0",
|
||||||
"chart.js": "4.4.4",
|
"chart.js": "4.4.4",
|
||||||
"cropperjs": "1.6.2",
|
"cropperjs": "1.6.2",
|
||||||
"date-fns": "2.30.0",
|
"date-fns": "2.30.0",
|
||||||
@@ -78,15 +79,14 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@alfresco/eslint-plugin-eslint-angular": "workspace:*",
|
"@alfresco/eslint-plugin-eslint-angular": "workspace:*",
|
||||||
"@angular-devkit/architect": "0.1902.22",
|
"@angular-devkit/architect": "0.2003.16",
|
||||||
"@angular-devkit/build-angular": "19.2.24",
|
"@angular-devkit/build-angular": "20.3.16",
|
||||||
"@angular-devkit/core": "19.2.22",
|
"@angular-devkit/core": "20.3.16",
|
||||||
"@angular-devkit/schematics": "19.2.22",
|
"@angular-devkit/schematics": "20.3.16",
|
||||||
"@angular-eslint/eslint-plugin": "19.8.1",
|
"@angular-eslint/eslint-plugin": "20.7.0",
|
||||||
"@angular-eslint/eslint-plugin-template": "19.8.1",
|
"@angular-eslint/eslint-plugin-template": "20.7.0",
|
||||||
"@angular-eslint/template-parser": "19.8.1",
|
"@angular-eslint/template-parser": "20.7.0",
|
||||||
"@angular-eslint/utils": "19.8.1",
|
"@angular/compiler-cli": "20.3.25",
|
||||||
"@angular/compiler-cli": "19.2.20",
|
|
||||||
"@chromatic-com/storybook": "4.1.3",
|
"@chromatic-com/storybook": "4.1.3",
|
||||||
"@nx/angular": "22.7.4",
|
"@nx/angular": "22.7.4",
|
||||||
"@nx/eslint-plugin": "22.7.4",
|
"@nx/eslint-plugin": "22.7.4",
|
||||||
@@ -94,9 +94,9 @@
|
|||||||
"@nx/js": "22.7.4",
|
"@nx/js": "22.7.4",
|
||||||
"@nx/storybook": "22.7.4",
|
"@nx/storybook": "22.7.4",
|
||||||
"@nx/workspace": "22.7.4",
|
"@nx/workspace": "22.7.4",
|
||||||
"@schematics/angular": "19.2.22",
|
"@schematics/angular": "20.3.16",
|
||||||
"@storybook/addon-themes": "10.2.0",
|
"@storybook/addon-themes": "10.4.0",
|
||||||
"@storybook/angular": "10.2.0",
|
"@storybook/angular": "10.4.0",
|
||||||
"@types/ejs": "3.1.5",
|
"@types/ejs": "3.1.5",
|
||||||
"@types/jasmine": "4.0.3",
|
"@types/jasmine": "4.0.3",
|
||||||
"@types/jasminewd2": "2.0.13",
|
"@types/jasminewd2": "2.0.13",
|
||||||
@@ -119,15 +119,15 @@
|
|||||||
"eslint-plugin-license-header": "0.8.0",
|
"eslint-plugin-license-header": "0.8.0",
|
||||||
"eslint-plugin-prettier": "5.5.6",
|
"eslint-plugin-prettier": "5.5.6",
|
||||||
"eslint-plugin-rxjs": "5.0.3",
|
"eslint-plugin-rxjs": "5.0.3",
|
||||||
"eslint-plugin-storybook": "10.2.0",
|
"eslint-plugin-storybook": "10.4.0",
|
||||||
"eslint-plugin-unicorn": "49.0.0",
|
"eslint-plugin-unicorn": "49.0.0",
|
||||||
"graphql": "16.14.0",
|
"graphql": "16.14.0",
|
||||||
"husky": "9.1.7",
|
"husky": "9.1.7",
|
||||||
"jasmine-core": "5.13.0",
|
"jasmine-core": "5.13.0",
|
||||||
"jasmine-reporters": "2.5.2",
|
"jasmine-reporters": "2.5.2",
|
||||||
"jest": "29.7.0",
|
"jest": "30.0.0",
|
||||||
"jest-environment-jsdom": "29.7.0",
|
"jest-environment-jsdom": "30.0.0",
|
||||||
"jest-preset-angular": "14.4.2",
|
"jest-preset-angular": "16.1.5",
|
||||||
"jsdom": "27.4.0",
|
"jsdom": "27.4.0",
|
||||||
"karma": "6.4.4",
|
"karma": "6.4.4",
|
||||||
"karma-chrome-launcher": "3.2.0",
|
"karma-chrome-launcher": "3.2.0",
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
"karma-jasmine": "5.1.0",
|
"karma-jasmine": "5.1.0",
|
||||||
"karma-jasmine-html-reporter": "2.2.0",
|
"karma-jasmine-html-reporter": "2.2.0",
|
||||||
"lint-staged": "17.0.5",
|
"lint-staged": "17.0.5",
|
||||||
"ng-packagr": "19.2.2",
|
"ng-packagr": "20.3.2",
|
||||||
"nx": "22.7.4",
|
"nx": "22.7.4",
|
||||||
"prettier": "3.8.3",
|
"prettier": "3.8.3",
|
||||||
"react": "19.2.6",
|
"react": "19.2.6",
|
||||||
@@ -144,11 +144,11 @@
|
|||||||
"sass-loader": "16.0.8",
|
"sass-loader": "16.0.8",
|
||||||
"semver": "7.6.3",
|
"semver": "7.6.3",
|
||||||
"spdx-license-list": "6.11.0",
|
"spdx-license-list": "6.11.0",
|
||||||
"storybook": "10.2.13",
|
"storybook": "10.4.0",
|
||||||
"stylelint": "16.20.0",
|
"stylelint": "16.20.0",
|
||||||
"stylelint-config-standard-scss": "13.1.0",
|
"stylelint-config-standard-scss": "13.1.0",
|
||||||
"ts-node": "10.9.2",
|
"ts-node": "10.9.2",
|
||||||
"typescript": "5.8.3",
|
"typescript": "5.9.3",
|
||||||
"undici": "8.5.0",
|
"undici": "8.5.0",
|
||||||
"webpack": "5.107.2"
|
"webpack": "5.107.2"
|
||||||
},
|
},
|
||||||
|
|||||||
Generated
+3511
-2883
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,6 @@
|
|||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"declaration": false,
|
"declaration": false,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"emitDecoratorMetadata": true,
|
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user