[AAE-20109] Move alfresco js-API and alfrescoapi service out from the core (#9317)

* AAE-20109 Remove alfrescoapiservice from core

* fix after rebase

* [AAe-12502] Post-rebase fix

* [AAE-12502] Add unit test fix

---------

Co-authored-by: Bartosz Sekula <Bartosz.Sekula@hyland.com>
Co-authored-by: MichalKinas <michal.kinas@hyland.com>
This commit is contained in:
Eugenio Romano
2024-09-06 18:43:33 +02:00
committed by GitHub
parent b60797e3b1
commit e617333f00
167 changed files with 1430 additions and 589 deletions

View File

@@ -16,3 +16,4 @@
*/
export * from './src/public-api';
export * from './api/src/index';

View File

@@ -37,7 +37,8 @@
"@alfresco/adf-extensions": ">=7.0.0-alpha.2-0",
"@ngx-translate/core": ">=14.0.0",
"minimatch-browser": ">=1.0.0",
"pdfjs-dist": ">=3.3.122"
"pdfjs-dist": ">=3.3.122",
"ts-morph": "^20.0.0"
},
"keywords": [
"core",
@@ -45,5 +46,11 @@
"angular",
"components"
],
"license": "Apache-2.0"
"license": "Apache-2.0",
"ng-update": {
"migrations": "./schematics/migrations/collection.json"
},
"nx-migrations": {
"migrations": "./schematics/migrations/collection.json"
}
}

View File

@@ -23,6 +23,16 @@
},
"defaultConfiguration": "production"
},
"build-schematics": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "npx tsc -p lib/core/tsconfig.schematics.json && cp lib/core/schematics/migrations/collection.json dist/libs/core/schematics/migrations/collection.json"
}
]
}
},
"test": {
"executor": "@angular-devkit/build-angular:karma",
"options": {
@@ -133,7 +143,7 @@
},
"npm-publish": {
"executor": "nx:run-commands",
"dependsOn": ["build", "pretheme"],
"dependsOn": ["build", "pretheme", "build-schematics"],
"options": {
"cwd": "dist/libs/core",
"commands": [

View File

@@ -0,0 +1,189 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Rule, SchematicContext, SchematicsException, Tree } from '@angular-devkit/schematics';
import { Project, NamedImports, SourceFile, ImportSpecifier, ImportDeclaration } from 'ts-morph';
interface MigrationData {
change: {
importedValue: string;
importSource: string;
};
to: {
importedValue: string;
importSource: string;
};
}
const alfrescoApiServiceMigration: MigrationData = {
change: {
importedValue: 'AlfrescoApiService',
importSource: '@alfresco/adf-core'
},
to: {
importedValue: 'AlfrescoApiService',
importSource: '@alfresco/adf-content-services'
}
};
const alfrescoApiMockMigration: MigrationData = {
change: {
importedValue: 'AlfrescoApiServiceMock',
importSource: '@alfresco/adf-core'
},
to: {
importedValue: 'AlfrescoApiServiceMock',
importSource: '@alfresco/adf-content-services'
}
};
const alfrescoApiFactoryMigration: MigrationData = {
change: {
importedValue: 'AlfrescoApiFactory',
importSource: '@alfresco/adf-core'
},
to: {
importedValue: 'AlfrescoApiFactory',
importSource: '@alfresco/adf-content-services'
}
};
const migrations: MigrationData[] = [alfrescoApiServiceMigration, alfrescoApiMockMigration, alfrescoApiFactoryMigration];
/**
* @returns Schematic rule for updating imports
*/
export function updateAlfrescoApiImports(): Rule {
const project = new Project();
// eslint-disable-next-line @typescript-eslint/no-unused-vars
return (tree: Tree, _context: SchematicContext) => {
tree.visit((filePath: string) => visitor(filePath, tree, project));
return tree;
};
}
export const visitor = (filePath: string, tree: Pick<Tree, 'read' | 'overwrite'>, project: Project) => {
if (
!filePath.includes('/.git/') &&
!filePath.includes('/node_modules/') &&
!filePath.includes('/.angular/') &&
!filePath.includes('/.nxcache/') &&
/\.ts$/.test(filePath)
) {
const bufferFileContent = tree.read(filePath);
if (!bufferFileContent) {
throw new SchematicsException(`Could not read file: ${filePath}`);
}
migrations.forEach((migrationData) => {
const fileWithUpdatedImport = moveImport(filePath, bufferFileContent, project, migrationData);
if (fileWithUpdatedImport) {
tree.overwrite(filePath, fileWithUpdatedImport);
}
});
}
};
const moveImport = (filePath: string, bufferFileContent: Buffer, project: Project, migrationData: MigrationData): string | undefined => {
const fileContent = bufferFileContent.toString();
const predictImport = fileContent.includes(migrationData.change.importedValue);
if (predictImport) {
const sourceFile = project.getSourceFile(`migration-${filePath}`) ?? project.createSourceFile(`migration-${filePath}`, fileContent);
const alfrescoApiImportResult = getImportedValueFromSource(sourceFile, {
importedIdentifier: migrationData.change.importedValue,
from: migrationData.change.importSource
});
if (alfrescoApiImportResult?.importedValue) {
if (alfrescoApiImportResult.allImportedValuesCount === 1) {
// There is only one import e.g. import { A } from 'A';
// Therefore, we need to remove whole import statement
alfrescoApiImportResult.importSource?.remove();
} else {
alfrescoApiImportResult.importedValue?.remove();
}
const alfrescoContentServiceImport = getSourceImport(sourceFile, migrationData.to.importSource);
if (alfrescoContentServiceImport) {
alfrescoContentServiceImport.addNamedImport(migrationData.to.importedValue);
} else {
sourceFile.insertStatements(
sourceFile.getImportDeclarations().length + 1,
`import { ${migrationData.to.importedValue} } from '${migrationData.to.importSource}';`
);
}
return sourceFile.getFullText();
}
}
return undefined;
};
const getSourceImport = (sourceFile: SourceFile, from: string): ImportDeclaration | undefined => {
const moduleImports = sourceFile.getImportDeclarations();
const importDeclaration = moduleImports.find((moduleImport) => {
const currentImportSource = moduleImport.getModuleSpecifierValue();
return currentImportSource === from;
});
return importDeclaration;
};
const getImportedValueFromSource = (
sourceFile: SourceFile,
searchedImport: {
importedIdentifier: string;
from: string;
}
): {
importedValue: ImportSpecifier | undefined;
importSource: ImportDeclaration | undefined;
allImportedValuesCount: number | undefined;
} => {
const importSource = getSourceImport(sourceFile, searchedImport.from);
if (!importSource) {
return {
importedValue: undefined,
importSource: undefined,
allImportedValuesCount: undefined
};
}
const importedValues = importSource?.getImportClause();
const namedImports = importedValues?.getNamedBindings() as NamedImports;
const namedImportsElements = namedImports?.getElements() ?? [];
const importedValue = namedImportsElements.find((binding) => binding.getName() === searchedImport.importedIdentifier);
return {
importedValue,
importSource,
allImportedValuesCount: namedImportsElements.length
};
};
export default updateAlfrescoApiImports;

View File

@@ -0,0 +1,46 @@
{
"$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"move-out-alfresco-api": {
"description": "Update alfresco-api imports",
"version": "7.0.0",
"factory": "./7_0_0/index#updateAlfrescoApiImports"
}
},
"packageJsonUpdates": {
"move-out-alfresco-api": {
"version": "7.0.0",
"packages": {
"ts-morph": {
"version": "^20.0.0",
"alwaysAddToPackageJson": true,
"addToPackageJson": "devDependencies"
},
"@alfresco/adf-content-services": {
"version": "7.0.0",
"alwaysAddToPackageJson": false
},
"@alfresco/adf-extensions": {
"version": "7.0.0",
"alwaysAddToPackageJson": false
},
"@alfresco/adf-process-services-cloud": {
"version": "7.0.0",
"alwaysAddToPackageJson": false
},
"@alfresco/adf-process-services": {
"version": "7.0.0",
"alwaysAddToPackageJson": false
},
"@alfresco/eslint-plugin-eslint-angular": {
"version": "7.0.0",
"alwaysAddToPackageJson": false
},
"@alfresco/js-api": {
"version": "8.0.0",
"alwaysAddToPackageJson": false
}
}
}
}
}

View File

@@ -1,41 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AdfHttpClient } from '@alfresco/adf-core/api';
import { StorageService } from '../common/services/storage.service';
import { AlfrescoApi, AlfrescoApiConfig } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { AppConfigService } from '../app-config';
import { AlfrescoApiService } from '../services/alfresco-api.service';
@Injectable()
export class AlfrescoApiNoAuthService extends AlfrescoApiService {
constructor(
storage: StorageService,
appConfig: AppConfigService,
private readonly adfHttpClient: AdfHttpClient
) {
super(appConfig, storage);
}
override createInstance(config: AlfrescoApiConfig) {
return new AlfrescoApi({
...config,
oauthInit: false
}, this.adfHttpClient);
}
}

View File

@@ -1,73 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AlfrescoApiConfig } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { AppConfigService, AppConfigValues } from '../app-config/app-config.service';
import { AlfrescoApiService } from '../services/alfresco-api.service';
import { StorageService } from '../common/services/storage.service';
/**
* Create a factory to resolve an api service instance
*
* @param angularAlfrescoApiService loader service
* @returns factory function
*/
export function createAlfrescoApiInstance(angularAlfrescoApiService: AlfrescoApiLoaderService) {
return () => angularAlfrescoApiService.init();
}
@Injectable({
providedIn: 'root'
})
export class AlfrescoApiLoaderService {
constructor(private readonly appConfig: AppConfigService,
private readonly apiService: AlfrescoApiService,
private storageService: StorageService) {
}
async init(): Promise<any> {
await this.appConfig.load();
return this.initAngularAlfrescoApi();
}
private async initAngularAlfrescoApi() {
const oauth = this.appConfig.oauth2;
if (oauth) {
oauth.redirectUri = window.location.origin + window.location.pathname;
oauth.redirectUriLogout = window.location.origin + window.location.pathname;
}
const config = new AlfrescoApiConfig({
provider: this.appConfig.get<string>(AppConfigValues.PROVIDERS),
hostEcm: this.appConfig.get<string>(AppConfigValues.ECMHOST),
hostBpm: this.appConfig.get<string>(AppConfigValues.BPMHOST),
authType: this.appConfig.get<string>(AppConfigValues.AUTHTYPE, 'BASIC'),
contextRootBpm: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTBPM),
contextRoot: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTECM),
disableCsrf: this.appConfig.get<boolean>(AppConfigValues.DISABLECSRF),
withCredentials: this.appConfig.get<boolean>(AppConfigValues.AUTH_WITH_CREDENTIALS, false),
domainPrefix: this.appConfig.get<string>(AppConfigValues.STORAGE_PREFIX),
ticketEcm: this.storageService.getItem(AppConfigValues.CONTENT_TICKET_STORAGE_LABEL),
ticketBpm: this.storageService.getItem(AppConfigValues.PROCESS_TICKET_STORAGE_LABEL),
oauth2: oauth
});
await this.apiService.load(config);
}
}

View File

@@ -63,7 +63,6 @@ export enum Status {
providedIn: 'root'
})
export class AppConfigService {
config: any = {
application: {
name: 'Alfresco ADF Application'
@@ -97,11 +96,10 @@ export class AppConfigService {
* @returns Property value, when loaded
*/
select(property: string): Observable<any> {
return this.onLoadSubject
.pipe(
map((config) => ObjectUtils.getValue(config, property)),
distinctUntilChanged()
);
return this.onLoadSubject.pipe(
map((config) => ObjectUtils.getValue(config, property)),
distinctUntilChanged()
);
}
/**
@@ -170,9 +168,7 @@ export class AppConfigService {
protected onDataLoaded() {
this.onLoadSubject.next(this.config);
this.extensionService.setup$
.pipe(take(1))
.subscribe((config) => this.onExtensionsLoaded(config));
this.extensionService.setup$.pipe(take(1)).subscribe((config) => this.onExtensionsLoaded(config));
}
protected onExtensionsLoaded(config: ExtensionConfig) {
@@ -227,20 +223,18 @@ export class AppConfigService {
* @param hostIdp host address
* @returns Discovery configuration
*/
loadWellKnown(hostIdp: string): Promise<OpenidConfiguration> {
loadWellKnown(hostIdp: string): Promise<OpenidConfiguration> {
return new Promise((resolve, reject) => {
this.http
.get<OpenidConfiguration>(`${hostIdp}/.well-known/openid-configuration`)
.subscribe({
next: (res: OpenidConfiguration) => {
resolve(res);
},
error: (err: any) => {
// eslint-disable-next-line no-console
console.error('hostIdp not correctly configured or unreachable');
reject(err);
}
});
this.http.get<OpenidConfiguration>(`${hostIdp}/.well-known/openid-configuration`).subscribe({
next: (res: OpenidConfiguration) => {
resolve(res);
},
error: (err: any) => {
// eslint-disable-next-line no-console
console.error('hostIdp not correctly configured or unreachable');
reject(err);
}
});
});
}
@@ -273,5 +267,4 @@ export class AppConfigService {
return result;
}
}

View File

@@ -17,8 +17,6 @@
import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core';
import { AUTH_CONFIG, OAuthModule, OAuthStorage } from 'angular-oauth2-oidc';
import { AlfrescoApiNoAuthService } from '../../api-factories/alfresco-api-no-auth.service';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { AuthenticationService } from '../services/authentication.service';
import { StorageService } from '../../common/services/storage.service';
import { AuthModuleConfig, AUTH_MODULE_CONFIG } from './auth-config';
@@ -44,7 +42,6 @@ export function loginFactory(redirectService: RedirectAuthService): () => Promis
providers: [
{ provide: OAuthStorage, useExisting: StorageService },
{ provide: AuthenticationService},
{ provide: AlfrescoApiService, useClass: AlfrescoApiNoAuthService },
{
provide: AUTH_CONFIG,
useFactory: authConfigFactory,

View File

@@ -21,8 +21,6 @@ import { AppConfigService } from '../../app-config/app-config.service';
import { StorageService } from '../../common/services/storage.service';
import { UserPreferencesService, UserPreferenceValues } from '../../common/services/user-preferences.service';
import { AppConfigServiceMock } from '../mock/app-config.service.mock';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { AlfrescoApiServiceMock } from '../../mock';
import { NoopTranslateModule } from '@alfresco/adf-core';
describe('UserPreferencesService', () => {
@@ -30,14 +28,12 @@ describe('UserPreferencesService', () => {
let preferences: UserPreferencesService;
let storage: StorageService;
let appConfig: AppConfigServiceMock;
let alfrescoApiService: AlfrescoApiServiceMock;
let translate: TranslateService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [NoopTranslateModule],
providers: [
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock },
{ provide: AppConfigService, useClass: AppConfigServiceMock }
]
});
@@ -53,7 +49,6 @@ describe('UserPreferencesService', () => {
storage = TestBed.inject(StorageService);
storage.clear();
translate = TestBed.inject(TranslateService);
alfrescoApiService = TestBed.inject(AlfrescoApiService) as AlfrescoApiServiceMock;
});
afterEach(() => {
@@ -103,7 +98,7 @@ describe('UserPreferencesService', () => {
});
it('should null value return default prefix', () => {
storage.setItem('paginationSize', null);
storage.setItem('paginationSize', '');
const paginationSize = preferences.getPropertyKey('paginationSize');
expect(preferences.get(paginationSize, 'default')).toBe('default');
});
@@ -172,7 +167,7 @@ describe('UserPreferencesService', () => {
}
];
appConfig.config.locale = 'fake-locale-config';
alfrescoApiService.initialize();
appConfig.load();
const textOrientation = preferences.getPropertyKey('textOrientation');
expect(storage.getItem(textOrientation)).toBe('ltr');
});
@@ -185,7 +180,7 @@ describe('UserPreferencesService', () => {
}
];
appConfig.config.locale = 'fake-locale-config';
alfrescoApiService.initialize();
appConfig.load();
const textOrientation = preferences.getPropertyKey('textOrientation');
expect(storage.getItem(textOrientation)).toBe('rtl');
});
@@ -196,7 +191,6 @@ describe('UserPreferencesService', () => {
key: 'fake-locale-browser'
}
];
alfrescoApiService.initialize();
const textOrientation = preferences.getPropertyKey('textOrientation');
expect(storage.getItem(textOrientation)).toBe(null);
@@ -210,7 +204,7 @@ describe('UserPreferencesService', () => {
}
];
spyOn(translate, 'getBrowserCultureLang').and.returnValue('fake-locale-browser');
alfrescoApiService.initialize();
appConfig.load();
let lastValue;

View File

@@ -20,8 +20,7 @@ import { TranslateService } from '@ngx-translate/core';
import { Observable, BehaviorSubject } from 'rxjs';
import { AppConfigService, AppConfigValues } from '../../app-config/app-config.service';
import { StorageService } from './storage.service';
import { distinctUntilChanged, map, filter } from 'rxjs/operators';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { LanguageItem } from './language-item.interface';
// eslint-disable-next-line no-shadow
@@ -48,13 +47,17 @@ export class UserPreferencesService {
private onChangeSubject: BehaviorSubject<any>;
onChange: Observable<any>;
constructor(public translate: TranslateService,
constructor(
public translate: TranslateService,
private appConfig: AppConfigService,
private storage: StorageService,
private alfrescoApiService: AlfrescoApiService) {
this.alfrescoApiService.alfrescoApiInitialized.pipe(filter(status => status)).subscribe(this.initUserPreferenceStatus.bind(this));
private storage: StorageService
) {
this.onChangeSubject = new BehaviorSubject(this.userPreferenceStatus);
this.onChange = this.onChangeSubject.asObservable();
this.appConfig.onLoad.subscribe(() => {
this.initUserPreferenceStatus();
});
}
private initUserPreferenceStatus() {
@@ -168,7 +171,7 @@ export class UserPreferencesService {
*
* @param value Name of the prefix
*/
setStoragePrefix(value: string) {
setStoragePrefix(value: string | null) {
this.storage.setItem('USER_PROFILE', value || 'GUEST');
this.initUserPreferenceStatus();
}

View File

@@ -50,7 +50,6 @@ import { MAT_SNACK_BAR_DEFAULT_OPTIONS } from '@angular/material/snack-bar';
import { loadAppConfig } from './app-config/app-config.loader';
import { AppConfigService } from './app-config/app-config.service';
import { StorageService } from './common/services/storage.service';
import { AlfrescoApiLoaderService, createAlfrescoApiInstance } from './api-factories/alfresco-api-v2-loader.service';
import { MomentDateAdapter } from './common/utils/moment-date-adapter';
import { AppConfigPipe, StoragePrefixFactory } from './app-config';
import { IconComponent } from './icon';
@@ -159,12 +158,6 @@ export class CoreModule {
useValue: {
duration: 10000
}
},
{
provide: APP_INITIALIZER,
useFactory: createAlfrescoApiInstance,
deps: [AlfrescoApiLoaderService],
multi: true
}
]
};

View File

@@ -19,7 +19,7 @@ import { ChangeDetectionStrategy, Component, Input, OnInit, ViewEncapsulation }
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
import { AsyncPipe } from '@angular/common';
import { RouterModule } from '@angular/router';
import { PathInfo } from '@alfresco/js-api';
import { PathInfo } from '../../../models/path.model';
@Component({
standalone: true,

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { PathInfo } from '@alfresco/js-api';
import { PathInfo } from '../../../models/path.model';
import { DataColumn } from '../../data/data-column.model';
export const mockCarsData: any = [

View File

@@ -1,40 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { AppConfigService } from '../app-config/app-config.service';
import { AlfrescoApiService } from '../services/alfresco-api.service';
import { StorageService } from '../common/services/storage.service';
@Injectable()
export class AlfrescoApiServiceMock extends AlfrescoApiService {
constructor(protected appConfig: AppConfigService,
protected storageService: StorageService) {
super(appConfig, storageService);
if (!this.alfrescoApi) {
this.initAlfrescoApi();
}
}
initialize(): Promise<any> {
return new Promise((resolve) => {
this.alfrescoApiInitialized.next(true);
resolve({});
});
}
}

View File

@@ -18,7 +18,6 @@
export * from './cookie.service.mock';
export * from './event.mock';
export * from './translation.service.mock';
export * from './alfresco-api.service.mock';
export * from './form/form.component.mock';
export * from './form/form-definition.mock';

View File

@@ -15,5 +15,8 @@
* limitations under the License.
*/
export * from './alfresco-api.service';
export { AlfrescoApiFactory } from './alfresco-api.interface';
export interface BasicAuth {
username?: string;
password?: string;
ticket?: string;
}

View File

@@ -15,4 +15,7 @@
* limitations under the License.
*/
export * from './public-api';
export interface Oauth2 {
refreshToken?: string;
accessToken?: string;
}

View File

@@ -15,12 +15,21 @@
* limitations under the License.
*/
import { AlfrescoApiConfig, AlfrescoApi } from '@alfresco/js-api';
export class PathInfo {
elements?: PathElement[];
name?: string;
isComplete?: boolean;
export interface AlfrescoApiInterface {
load(): Promise<void> ;
constructor(input?: Partial<PathInfo>) {
if (input) {
Object.assign(this, input);
}
}
}
export interface AlfrescoApiFactory {
createAlfrescoApi(config: AlfrescoApiConfig): AlfrescoApi;
export interface PathElement {
id?: string;
name?: string;
nodeType?: string;
aspectNames?: string[];
}

View File

@@ -21,3 +21,4 @@ export * from './pagination.model';
export * from './request-pagination.model';
export * from './decimal-number.model';
export * from './general-user.model';
export * from './path.model';

View File

@@ -1,139 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Inject, Injectable, InjectionToken, Optional } from '@angular/core';
import { AlfrescoApi, AlfrescoApiConfig } from '@alfresco/js-api';
import { AppConfigService, AppConfigValues } from '../app-config/app-config.service';
import { ReplaySubject } from 'rxjs';
import { OauthConfigModel } from '../auth/models/oauth-config.model';
import { StorageService } from '../common/services/storage.service';
import { OpenidConfiguration } from '../auth/interfaces/openid-configuration.interface';
import { AlfrescoApiFactory } from './alfresco-api.interface';
export const ALFRESCO_API_FACTORY = new InjectionToken('ALFRESCO_API_FACTORY');
@Injectable({
providedIn: 'root'
})
export class AlfrescoApiService {
alfrescoApiInitialized: ReplaySubject<boolean> = new ReplaySubject(1);
protected alfrescoApi: AlfrescoApi;
lastConfig: AlfrescoApiConfig;
currentAppConfig: AlfrescoApiConfig;
idpConfig: OpenidConfiguration;
private excludedErrorUrl: string[] = ['api/enterprise/system/properties'];
getInstance(): AlfrescoApi {
return this.alfrescoApi;
}
constructor(
protected appConfig: AppConfigService,
protected storageService: StorageService,
@Optional()
@Inject(ALFRESCO_API_FACTORY) private alfrescoApiFactory?: AlfrescoApiFactory
) {}
async load(config: AlfrescoApiConfig): Promise<void> {
this.currentAppConfig = config;
if (config.authType === 'OAUTH') {
await this.mapAlfrescoApiOpenIdConfig();
}
this.initAlfrescoApiWithConfig();
this.alfrescoApiInitialized.next(true);
}
async reset() {
this.getCurrentAppConfig();
if (this.currentAppConfig.authType === 'OAUTH') {
await this.mapAlfrescoApiOpenIdConfig();
}
this.initAlfrescoApiWithConfig();
}
private getAuthWithFixedOriginLocation(): OauthConfigModel {
const oauth = this.appConfig.oauth2;
if (oauth) {
oauth.redirectUri = window.location.origin + window.location.pathname;
oauth.redirectUriLogout = window.location.origin + window.location.pathname;
}
return oauth;
}
private async mapAlfrescoApiOpenIdConfig() {
this.idpConfig = await this.appConfig.loadWellKnown(this.currentAppConfig.oauth2.host);
this.currentAppConfig.oauth2.tokenUrl = this.idpConfig.token_endpoint;
this.currentAppConfig.oauth2.authorizationUrl = this.idpConfig.authorization_endpoint;
this.currentAppConfig.oauth2.logoutUrl = this.idpConfig.end_session_endpoint;
this.currentAppConfig.oauth2.userinfoEndpoint = this.idpConfig.userinfo_endpoint;
}
private getCurrentAppConfig() {
const oauth = this.getAuthWithFixedOriginLocation();
this.currentAppConfig = new AlfrescoApiConfig({
provider: this.appConfig.get<string>(AppConfigValues.PROVIDERS),
hostEcm: this.appConfig.get<string>(AppConfigValues.ECMHOST),
hostBpm: this.appConfig.get<string>(AppConfigValues.BPMHOST),
authType: this.appConfig.get<string>(AppConfigValues.AUTHTYPE, 'BASIC'),
contextRootBpm: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTBPM),
contextRoot: this.appConfig.get<string>(AppConfigValues.CONTEXTROOTECM),
disableCsrf: this.appConfig.get<boolean>(AppConfigValues.DISABLECSRF),
withCredentials: this.appConfig.get<boolean>(AppConfigValues.AUTH_WITH_CREDENTIALS, false),
domainPrefix: this.appConfig.get<string>(AppConfigValues.STORAGE_PREFIX),
oauth2: oauth
});
}
protected initAlfrescoApi() {
this.getCurrentAppConfig();
this.initAlfrescoApiWithConfig();
}
private initAlfrescoApiWithConfig() {
if (this.alfrescoApi && this.isDifferentConfig(this.lastConfig, this.currentAppConfig)) {
this.alfrescoApi.setConfig(this.currentAppConfig);
} else {
this.alfrescoApi = this.createInstance(this.currentAppConfig);
}
this.lastConfig = this.currentAppConfig;
}
createInstance(config: AlfrescoApiConfig): AlfrescoApi {
if (this.alfrescoApiFactory) {
return this.alfrescoApiFactory.createAlfrescoApi(config);
}
return new AlfrescoApi(config);
}
isDifferentConfig(lastConfig: AlfrescoApiConfig, newConfig: AlfrescoApiConfig) {
return JSON.stringify(lastConfig) !== JSON.stringify(newConfig);
}
isExcludedErrorListener(currentFullPath: string): boolean {
const formattedPath = currentFullPath.replace(this.lastConfig.hostBpm + '/' + this.lastConfig.contextRootBpm, '');
return this.excludedErrorUrl.includes(formattedPath);
}
}

View File

@@ -19,8 +19,6 @@ import { NgModule, APP_INITIALIZER } from '@angular/core';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
import { CoreModule } from '../core.module';
import { AlfrescoApiService } from '../services/alfresco-api.service';
import { AlfrescoApiServiceMock } from '../mock/alfresco-api.service.mock';
import { AppConfigService } from '../app-config/app-config.service';
import { AppConfigServiceMock } from '../common/mock/app-config.service.mock';
import { DatePipe } from '@angular/common';
@@ -32,6 +30,7 @@ import { DirectionalityConfigService } from '../common/services/directionality-c
import { AuthModule, RedirectAuthService } from '../auth';
import { EMPTY, of } from 'rxjs';
import { NoopTranslateModule } from './noop-translate.module';
import { UserPreferencesService } from '../common/services/user-preferences.service';
@NgModule({
imports: [
@@ -44,7 +43,7 @@ import { NoopTranslateModule } from './noop-translate.module';
],
providers: [
DatePipe,
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock },
UserPreferencesService,
{ provide: AppConfigService, useClass: AppConfigServiceMock },
{ provide: CookieService, useClass: CookieServiceMock },
{

View File

@@ -24,8 +24,6 @@ import { TranslateLoaderService } from './translate-loader.service';
import { provideTranslations, TranslationService } from './translation.service';
import { AppConfigService } from '../app-config/app-config.service';
import { AppConfigServiceMock } from '../common/mock/app-config.service.mock';
import { AlfrescoApiService } from '../services/alfresco-api.service';
import { AlfrescoApiServiceMock } from '../mock/alfresco-api.service.mock';
declare let jasmine: any;
@@ -45,7 +43,6 @@ describe('TranslationService', () => {
})
],
providers: [
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock },
{ provide: AppConfigService, useClass: AppConfigServiceMock },
provideTranslations('@alfresco/adf-core', 'assets/ng2-alfresco-core')
]

View File

@@ -38,7 +38,6 @@ export * from './lib/comments/index';
export * from './lib/sorting-picker/index';
export * from './lib/templates/index';
export * from './lib/pipes/index';
export * from './lib/services/index';
export * from './lib/directives/index';
export * from './lib/dynamic-chip-list/index';
export * from './lib/clipboard/index';
@@ -49,7 +48,6 @@ export * from './lib/blank-page/index';
export * from './lib/search-text/index';
export * from './lib/snackbar-content/index';
export * from './lib/translation/index';
export * from './lib/common/utils/index';
export * from './lib/interface/index';
export * from './lib/models/index';

View File

@@ -0,0 +1,31 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": [
"es2018",
"dom"
],
"declaration": true,
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitThis": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"rootDir": "./migrations",
"outDir": "../../dist/libs/core/migrations",
"skipDefaultLibCheck": true,
"skipLibCheck": true,
"sourceMap": true,
"strictNullChecks": true,
"target": "es2015",
"types": []
},
"include": [
"migrations/**/*"
],
"files": ["schematics/migrations/7_0_0/index.ts"]
}

View File

@@ -0,0 +1,29 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": [
"es2018",
"dom"
],
"declaration": true,
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noFallthroughCasesInSwitch": true,
"noImplicitThis": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"rootDir": "./schematics",
"outDir": "../../dist/libs/core/schematics",
"skipDefaultLibCheck": true,
"skipLibCheck": true,
"sourceMap": true,
"strictNullChecks": true,
"target": "es2015",
"types": []
},
"include": [
"schematics/**/*"
]
}