mirror of https://github.com/abpframework/abp
				
				
				
			
							parent
							
								
									70308947b6
								
							
						
					
					
						commit
						57cd025ba5
					
				| @ -0,0 +1,16 @@ | ||||
| 
 | ||||
| export class FindTenantResultDto  { | ||||
|   success: boolean; | ||||
|   tenantId?: string; | ||||
|   name: string; | ||||
| 
 | ||||
|   constructor(initialValues: Partial<FindTenantResultDto> = {}) { | ||||
|     if (initialValues) { | ||||
|       for (const key in initialValues) { | ||||
|         if (initialValues.hasOwnProperty(key)) { | ||||
|           this[key] = initialValues[key]; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,156 @@ | ||||
| class ExtractionResult { | ||||
|   public isMatch: boolean; | ||||
|   public matches: any[]; | ||||
| 
 | ||||
|   constructor(isMatch: boolean) { | ||||
|     this.isMatch = isMatch; | ||||
|     this.matches = []; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| enum FormatStringTokenType { | ||||
|   ConstantText, | ||||
|   DynamicValue, | ||||
| } | ||||
| 
 | ||||
| class FormatStringToken { | ||||
|   public text: string; | ||||
|   public type: FormatStringTokenType; | ||||
| 
 | ||||
|   constructor(text: string, type: FormatStringTokenType) { | ||||
|     this.text = text; | ||||
|     this.type = type; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class FormatStringTokenizer { | ||||
|   tokenize(format: string, includeBracketsForDynamicValues: boolean = false): FormatStringToken[] { | ||||
|     const tokens: FormatStringToken[] = []; | ||||
| 
 | ||||
|     let currentText = ''; | ||||
|     let inDynamicValue = false; | ||||
| 
 | ||||
|     for (let i = 0; i < format.length; i++) { | ||||
|       const c = format[i]; | ||||
|       switch (c) { | ||||
|         case '{': | ||||
|           if (inDynamicValue) { | ||||
|             throw new Error( | ||||
|               'Incorrect syntax at char ' + | ||||
|                 i + | ||||
|                 '! format string can not contain nested dynamic value expression!', | ||||
|             ); | ||||
|           } | ||||
| 
 | ||||
|           inDynamicValue = true; | ||||
| 
 | ||||
|           if (currentText.length > 0) { | ||||
|             tokens.push(new FormatStringToken(currentText, FormatStringTokenType.ConstantText)); | ||||
|             currentText = ''; | ||||
|           } | ||||
| 
 | ||||
|           break; | ||||
|         case '}': | ||||
|           if (!inDynamicValue) { | ||||
|             throw new Error( | ||||
|               'Incorrect syntax at char ' + | ||||
|                 i + | ||||
|                 '! These is no opening brackets for the closing bracket }.', | ||||
|             ); | ||||
|           } | ||||
| 
 | ||||
|           inDynamicValue = false; | ||||
| 
 | ||||
|           if (currentText.length <= 0) { | ||||
|             throw new Error( | ||||
|               'Incorrect syntax at char ' + i + '! Brackets does not containt any chars.', | ||||
|             ); | ||||
|           } | ||||
| 
 | ||||
|           let dynamicValue = currentText; | ||||
|           if (includeBracketsForDynamicValues) { | ||||
|             dynamicValue = '{' + dynamicValue + '}'; | ||||
|           } | ||||
| 
 | ||||
|           tokens.push(new FormatStringToken(dynamicValue, FormatStringTokenType.DynamicValue)); | ||||
|           currentText = ''; | ||||
| 
 | ||||
|           break; | ||||
|         default: | ||||
|           currentText += c; | ||||
|           break; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     if (inDynamicValue) { | ||||
|       throw new Error('There is no closing } char for an opened { char.'); | ||||
|     } | ||||
| 
 | ||||
|     if (currentText.length > 0) { | ||||
|       tokens.push(new FormatStringToken(currentText, FormatStringTokenType.ConstantText)); | ||||
|     } | ||||
| 
 | ||||
|     return tokens; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class FormattedStringValueExtractor { | ||||
|   extract(str: string, format: string): ExtractionResult { | ||||
|     if (str === format) { | ||||
|       return new ExtractionResult(true); | ||||
|     } | ||||
| 
 | ||||
|     const formatTokens = new FormatStringTokenizer().tokenize(format); | ||||
|     if (!formatTokens) { | ||||
|       return new ExtractionResult(str === ''); | ||||
|     } | ||||
| 
 | ||||
|     const result = new ExtractionResult(true); | ||||
| 
 | ||||
|     for (let i = 0; i < formatTokens.length; i++) { | ||||
|       const currentToken = formatTokens[i]; | ||||
|       const previousToken = i > 0 ? formatTokens[i - 1] : null; | ||||
| 
 | ||||
|       if (currentToken.type === FormatStringTokenType.ConstantText) { | ||||
|         if (i === 0) { | ||||
|           if (str.indexOf(currentToken.text) !== 0) { | ||||
|             result.isMatch = false; | ||||
|             return result; | ||||
|           } | ||||
| 
 | ||||
|           str = str.substr(currentToken.text.length, str.length - currentToken.text.length); | ||||
|         } else { | ||||
|           const matchIndex = str.indexOf(currentToken.text); | ||||
|           if (matchIndex < 0) { | ||||
|             result.isMatch = false; | ||||
|             return result; | ||||
|           } | ||||
| 
 | ||||
|           result.matches.push({ name: previousToken.text, value: str.substr(0, matchIndex) }); | ||||
|           str = str.substring(0, matchIndex + currentToken.text.length); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     const lastToken = formatTokens[formatTokens.length - 1]; | ||||
|     if (lastToken.type === FormatStringTokenType.DynamicValue) { | ||||
|       result.matches.push({ name: lastToken.text, value: str }); | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   isMatch(str: string, format: string): string[] { | ||||
|     const result = new FormattedStringValueExtractor().extract(str, format); | ||||
|     if (!result.isMatch) { | ||||
|       return []; | ||||
|     } | ||||
| 
 | ||||
|     const values = []; | ||||
|     for (let i = 0; i < result.matches.length; i++) { | ||||
|       values.push(result.matches[i].value); | ||||
|     } | ||||
| 
 | ||||
|     return values; | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,73 @@ | ||||
| import { Injector } from '@angular/core'; | ||||
| import { Store } from '@ngxs/store'; | ||||
| import { ConfigState } from '../states/config.state'; | ||||
| import { Config } from '../models/config'; | ||||
| import { FormattedStringValueExtractor } from './formatted-string-value-extractor'; | ||||
| import { MultiTenancyService } from '../services/multi-tenancy.service'; | ||||
| import { tap, switchMap } from 'rxjs/operators'; | ||||
| import { SetTenant, SetEnvironment } from '../actions'; | ||||
| import { of } from 'rxjs'; | ||||
| 
 | ||||
| const tenancyPlaceholder = '{TENANCY_NAME}'; | ||||
| 
 | ||||
| export function getCurrentTenancyNameOrNull(appBaseUrl: string): string { | ||||
|   if (appBaseUrl.indexOf(tenancyPlaceholder) < 0) return null; | ||||
| 
 | ||||
|   const currentRootAddress = document.location.href; | ||||
| 
 | ||||
|   const formattedStringValueExtracter = new FormattedStringValueExtractor(); | ||||
|   const values: any[] = formattedStringValueExtracter.isMatch(currentRootAddress, appBaseUrl); | ||||
|   if (!values.length) { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   return values[0]; | ||||
| } | ||||
| 
 | ||||
| export async function parseTenantFromUrl(injector: Injector) { | ||||
|   const store: Store = injector.get(Store); | ||||
|   const multiTenancyService = injector.get(MultiTenancyService); | ||||
|   const environment = store.selectSnapshot(ConfigState.getOne('environment')) as Config.Environment; | ||||
| 
 | ||||
|   const { baseUrl = '' } = environment.application; | ||||
|   const tenancyName = getCurrentTenancyNameOrNull(baseUrl); | ||||
| 
 | ||||
|   if (tenancyName) { | ||||
|     multiTenancyService.isTenantBoxVisible = false; | ||||
| 
 | ||||
|     return setEnvironment(store, tenancyName) | ||||
|       .pipe( | ||||
|         switchMap(() => multiTenancyService.findTenantByName(tenancyName, { __tenant: '' })), | ||||
|         tap(res => { | ||||
|           if (!res.success) return; | ||||
|           const tenant = { id: res.tenantId, name: res.name }; | ||||
|           multiTenancyService.domainTenant = tenant; | ||||
|         }), | ||||
|       ) | ||||
|       .toPromise(); | ||||
|   } | ||||
| 
 | ||||
|   return Promise.resolve(); | ||||
| } | ||||
| 
 | ||||
| export function setEnvironment(store: Store, tenancyName: string) { | ||||
|   const environment = store.selectSnapshot(ConfigState.getOne('environment')) as Config.Environment; | ||||
| 
 | ||||
|   if (environment.application.baseUrl) { | ||||
|     environment.application.baseUrl = environment.application.baseUrl.replace( | ||||
|       tenancyPlaceholder, | ||||
|       tenancyName, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   Object.keys(environment.apis).forEach(api => { | ||||
|     Object.keys(environment.apis[api]).forEach(key => { | ||||
|       environment.apis[api][key] = environment.apis[api][key].replace( | ||||
|         tenancyPlaceholder, | ||||
|         tenancyName, | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   return store.dispatch(new SetEnvironment(environment)); | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue
	
	 mehmet-erim
						mehmet-erim