diff --git a/common.props b/common.props index 4855f1cd9c..890cdff1e6 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.1.0 + 3.2.0 $(NoWarn);CS1591 https://abp.io/assets/abp_nupkg.png https://abp.io/ diff --git a/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts b/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts index 19fa4f509c..eb8dd5b3a2 100644 --- a/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts +++ b/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts @@ -25,7 +25,7 @@ export abstract class AuthFlowStrategy { constructor(protected injector: Injector) { this.store = injector.get(Store); this.oAuthService = injector.get(OAuthService); - this.oAuthConfig = injector.get(Store).selectSnapshot(ConfigState.getDeep('environment.oAuthConfig')); + this.oAuthConfig = this.store.selectSnapshot(ConfigState.getDeep('environment.oAuthConfig')); } async init(): Promise { @@ -41,7 +41,14 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { return super .init() .then(() => this.oAuthService.tryLogin()) - .then(() => this.oAuthService.setupAutomaticSilentRefresh()); + .then(() => { + if (this.oAuthService.hasValidAccessToken() || !this.oAuthService.getRefreshToken()) { + return Promise.resolve(); + } + + return this.oAuthService.refreshToken() as Promise; + }) + .then(() => this.oAuthService.setupAutomaticSilentRefresh({}, 'access_token')); } login() { @@ -88,7 +95,7 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { ) .pipe( tap(() => this.oAuthService.logOut()), - switchMap(() => this.store.dispatch(new GetAppConfiguration())), + switchMap(() => this.store.dispatch(new GetAppConfiguration())), ); } diff --git a/npm/ng-packs/packages/schematics/src/commands/api/files-enum/proxy/enums/__namespace@dir__/__name@kebab__.ts.template b/npm/ng-packs/packages/schematics/src/commands/api/files-enum/proxy/__namespace@dir__/__name@kebab__.enum.ts.template similarity index 100% rename from npm/ng-packs/packages/schematics/src/commands/api/files-enum/proxy/enums/__namespace@dir__/__name@kebab__.ts.template rename to npm/ng-packs/packages/schematics/src/commands/api/files-enum/proxy/__namespace@dir__/__name@kebab__.enum.ts.template diff --git a/npm/ng-packs/packages/schematics/src/commands/api/files-model/proxy/models/__namespace@dir__/index.ts.template b/npm/ng-packs/packages/schematics/src/commands/api/files-model/proxy/__namespace@dir__/models.ts.template similarity index 100% rename from npm/ng-packs/packages/schematics/src/commands/api/files-model/proxy/models/__namespace@dir__/index.ts.template rename to npm/ng-packs/packages/schematics/src/commands/api/files-model/proxy/__namespace@dir__/models.ts.template diff --git a/npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/services/__namespace@dir__/__name@kebab__.service.ts.template b/npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/__namespace@dir__/__name@kebab__.service.ts.template similarity index 100% rename from npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/services/__namespace@dir__/__name@kebab__.service.ts.template rename to npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/__namespace@dir__/__name@kebab__.service.ts.template diff --git a/npm/ng-packs/packages/schematics/src/commands/proxy-add/index.ts b/npm/ng-packs/packages/schematics/src/commands/proxy-add/index.ts index 1400cfca1c..3177bedeaa 100644 --- a/npm/ng-packs/packages/schematics/src/commands/proxy-add/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/proxy-add/index.ts @@ -3,13 +3,14 @@ import { chain, SchematicContext, Tree } from '@angular-devkit/schematics'; import { GenerateProxySchema } from '../../models'; import { buildDefaultPath, - chainAndMerge, createApiDefinitionGetter, createApisGenerator, createProxyClearer, createProxyConfigReader, createProxyConfigSaver, + createProxyIndexGenerator, createProxyWarningSaver, + mergeAndAllowDelete, removeDefaultPlaceholders, resolveProject, } from '../../utils'; @@ -45,7 +46,15 @@ export default function(schema: GenerateProxySchema) { const generateApis = createApisGenerator(schema, generated); - return chainAndMerge([clearProxy, saveProxyConfig, saveProxyWarning, generateApis])(host); + const generateIndex = createProxyIndexGenerator(targetPath); + + return chain([ + mergeAndAllowDelete(host, clearProxy), + saveProxyConfig, + saveProxyWarning, + generateApis, + generateIndex, + ]); }, ]); } diff --git a/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/index.ts b/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/index.ts index 2c4e20d7d2..1a0a5ea3be 100644 --- a/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/index.ts @@ -1,13 +1,14 @@ -import { SchematicContext, Tree } from '@angular-devkit/schematics'; +import { chain, SchematicContext, Tree } from '@angular-devkit/schematics'; import { GenerateProxySchema } from '../../models'; import { buildDefaultPath, - chainAndMerge, createApiDefinitionGetter, createApisGenerator, createProxyClearer, createProxyConfigReader, createProxyConfigSaver, + createProxyIndexGenerator, + mergeAndAllowDelete, removeDefaultPlaceholders, resolveProject, } from '../../utils'; @@ -32,6 +33,13 @@ export default function(schema: GenerateProxySchema) { const generateApis = createApisGenerator(schema, generated); - return chainAndMerge([clearProxy, saveProxyConfig, generateApis])(host); + const generateIndex = createProxyIndexGenerator(targetPath); + + return chain([ + mergeAndAllowDelete(host, clearProxy), + saveProxyConfig, + generateApis, + generateIndex, + ]); }; } diff --git a/npm/ng-packs/packages/schematics/src/commands/proxy-remove/index.ts b/npm/ng-packs/packages/schematics/src/commands/proxy-remove/index.ts index 83cc43c0b8..59004bff11 100644 --- a/npm/ng-packs/packages/schematics/src/commands/proxy-remove/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/proxy-remove/index.ts @@ -1,14 +1,15 @@ import { strings } from '@angular-devkit/core'; -import { SchematicContext, Tree } from '@angular-devkit/schematics'; +import { chain, SchematicContext, Tree } from '@angular-devkit/schematics'; import { GenerateProxySchema } from '../../models'; import { buildDefaultPath, - chainAndMerge, createApiDefinitionGetter, createApisGenerator, createProxyClearer, createProxyConfigReader, createProxyConfigSaver, + createProxyIndexGenerator, + mergeAndAllowDelete, removeDefaultPlaceholders, resolveProject, } from '../../utils'; @@ -38,6 +39,13 @@ export default function(schema: GenerateProxySchema) { const generateApis = createApisGenerator(schema, generated); - return chainAndMerge([clearProxy, saveProxyConfig, generateApis])(host); + const generateIndex = createProxyIndexGenerator(targetPath); + + return chain([ + mergeAndAllowDelete(host, clearProxy), + saveProxyConfig, + generateApis, + generateIndex, + ]); }; } diff --git a/npm/ng-packs/packages/schematics/src/constants/proxy.ts b/npm/ng-packs/packages/schematics/src/constants/proxy.ts index fbf7f127bd..847b373f75 100644 --- a/npm/ng-packs/packages/schematics/src/constants/proxy.ts +++ b/npm/ng-packs/packages/schematics/src/constants/proxy.ts @@ -5,14 +5,14 @@ export const PROXY_WARNING_PATH = `${PROXY_PATH}/README.md`; export const PROXY_WARNING = `# Proxy Generation Output This directory includes the output of the latest proxy generation. -The \`services\`, \`models\`, and \`enums\` folders will be overwritten when proxy generation is run again. -Therefore, please do not place your own content in those folders. +The files and folders in it will be overwritten when proxy generation is run again. +Therefore, please do not place your own content in this folder. In addition, \`generate-proxy.json\` works like a lock file. It includes information used by the proxy generator, so please do not delete or modify it. -Finally, the name of this folder should not be changed for two reasons: -- Proxy generator will keep creating this folder and you will have multiple copies of the same content. -- ABP Suite generates imports from this folder and uses the path \`/proxy\` when doing so. +Finally, the name of the files and folders should not be changed for two reasons: +- Proxy generator will keep creating them at those paths and you will have multiple copies of the same content. +- ABP Suite generates files which include imports from this folder. `; diff --git a/npm/ng-packs/packages/schematics/src/utils/barrel.ts b/npm/ng-packs/packages/schematics/src/utils/barrel.ts new file mode 100644 index 0000000000..b21acc77fa --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/utils/barrel.ts @@ -0,0 +1,48 @@ +import { strings } from '@angular-devkit/core'; +import { Tree } from '@angular-devkit/schematics'; +import { PROXY_PATH } from '../constants'; +import { createFileSaver } from './file'; + +export function createProxyIndexGenerator(targetPath: string) { + return createBarrelsGenerator(targetPath + PROXY_PATH); +} + +export function createBarrelsGenerator(rootPath: string) { + return (tree: Tree) => { + generateBarrelFromPath(tree, rootPath); + return tree; + }; +} + +export function generateBarrelFromPath(tree: Tree, indexPath: string) { + const saveFile = createFileSaver(tree); + const dir = tree.getDir(indexPath); + + const _exports: string[] = []; + + dir.subfiles.forEach(fragment => { + if (!fragment.endsWith('.ts')) return; + + _exports.push(`export * from './${fragment.replace(/\.ts$/, '')}';`); + }); + + dir.subdirs.forEach(fragment => { + const subDirPath = indexPath + '/' + fragment; + const subDir = tree.getDir(subDirPath); + let hasFiles = false; + subDir.visit(() => (hasFiles = true)); + if (!hasFiles) return; + + _exports.push(`export * as ${strings.classify(fragment)} from './${fragment}';`); + generateBarrelFromPath(tree, subDirPath); + }); + + _exports.sort(); + + if (_exports.length) + saveFile( + indexPath + '/index.ts', + _exports.join(` +`), + ); +} diff --git a/npm/ng-packs/packages/schematics/src/utils/enum.ts b/npm/ng-packs/packages/schematics/src/utils/enum.ts index 818a1a089b..c01b086ec5 100644 --- a/npm/ng-packs/packages/schematics/src/utils/enum.ts +++ b/npm/ng-packs/packages/schematics/src/utils/enum.ts @@ -13,7 +13,7 @@ export interface EnumGeneratorParams { } export function isEnumImport(path: string) { - return path.includes('/enums/'); + return path.endsWith('.enum'); } export function getEnumNamesFromImports(serviceImports: Record) { diff --git a/npm/ng-packs/packages/schematics/src/utils/file.ts b/npm/ng-packs/packages/schematics/src/utils/file.ts new file mode 100644 index 0000000000..cbfa9afcd2 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/utils/file.ts @@ -0,0 +1,8 @@ +import { Tree } from '@angular-devkit/schematics'; + +export function createFileSaver(tree: Tree) { + return (filePath: string, fileContent: string) => + tree.exists(filePath) + ? tree.overwrite(filePath, fileContent) + : tree.create(filePath, fileContent); +} diff --git a/npm/ng-packs/packages/schematics/src/utils/index.ts b/npm/ng-packs/packages/schematics/src/utils/index.ts index 304c2294b0..178920dccc 100644 --- a/npm/ng-packs/packages/schematics/src/utils/index.ts +++ b/npm/ng-packs/packages/schematics/src/utils/index.ts @@ -1,8 +1,10 @@ export * from './angular'; export * from './api'; export * from './ast'; +export * from './barrel'; export * from './common'; export * from './enum'; +export * from './file'; export * from './import'; export * from './model'; export * from './namespace'; diff --git a/npm/ng-packs/packages/schematics/src/utils/path.ts b/npm/ng-packs/packages/schematics/src/utils/path.ts index cb1d499755..c28951c8db 100644 --- a/npm/ng-packs/packages/schematics/src/utils/path.ts +++ b/npm/ng-packs/packages/schematics/src/utils/path.ts @@ -1,15 +1,33 @@ -import { dir, kebab } from './text'; +import { strings } from '@angular-devkit/core'; +import { kebab } from './text'; export function relativePathToEnum(namespace: string, enumNamespace: string, enumName: string) { - const repeats = namespace ? namespace.split('.').length : 0; - const path = '..' + '/..'.repeat(repeats) + '/enums/' + dir(enumNamespace); - return removeDoubleSlash(path + '/' + kebab(enumName)); + const path = calculateRelativePath(namespace, enumNamespace); + return path + `/${kebab(enumName)}.enum`; } export function relativePathToModel(namespace: string, modelNamespace: string) { - const repeats = namespace ? namespace.split('.').length : 0; - const path = '..' + '/..'.repeat(repeats) + '/models/' + dir(modelNamespace); - return removeTrailingSlash(path); + const path = calculateRelativePath(namespace, modelNamespace); + return path + '/models'; +} + +function calculateRelativePath(ns1: string, ns2: string) { + if (ns1 === ns2) return '.'; + + const parts1 = ns1 ? ns1.split('.') : []; + const parts2 = ns2 ? ns2.split('.') : []; + + while (parts1.length && parts2.length) { + if (parts1[0] !== parts2[0]) break; + + parts1.shift(); + parts2.shift(); + } + + const up = '../'.repeat(parts1.length) || '.'; + const down = parts2.reduce((acc, p) => acc + '/' + strings.dasherize(p), ''); + + return removeTrailingSlash(removeDoubleSlash(up + down)); } function removeDoubleSlash(path: string) { diff --git a/npm/ng-packs/packages/schematics/src/utils/rule.ts b/npm/ng-packs/packages/schematics/src/utils/rule.ts index 39b14cec78..bd6acdd646 100644 --- a/npm/ng-packs/packages/schematics/src/utils/rule.ts +++ b/npm/ng-packs/packages/schematics/src/utils/rule.ts @@ -1,6 +1,6 @@ import { apply, - chain, + callRule, forEach, MergeStrategy, mergeWith, @@ -18,12 +18,11 @@ export function applyWithOverwrite(source: Source, rules: Rule[]): Rule { }; } -export function chainAndMerge(rules: Rule[]) { - return (host: Tree) => async (tree: Tree, context: SchematicContext) => - host.merge( - (await (chain(rules)(tree, context) as any).toPromise()) as Tree, - MergeStrategy.AllowDeleteConflict, - ); +export function mergeAndAllowDelete(host: Tree, rule: Rule) { + return async (tree: Tree, context: SchematicContext) => { + const nextTree = await callRule(rule, tree, context).toPromise(); + host.merge(nextTree, MergeStrategy.AllowDeleteConflict); + }; } export function overwriteFileIfExists(tree: Tree): Rule { diff --git a/npm/ng-packs/packages/schematics/src/utils/source.ts b/npm/ng-packs/packages/schematics/src/utils/source.ts index b495e75c20..d555e2ec1f 100644 --- a/npm/ng-packs/packages/schematics/src/utils/source.ts +++ b/npm/ng-packs/packages/schematics/src/utils/source.ts @@ -106,15 +106,18 @@ export function createProxyConfigReader(targetPath: string) { export function createProxyClearer(targetPath: string) { targetPath += PROXY_PATH; + const proxyIndexPath = `${targetPath}/index.ts`; return (tree: Tree) => { try { tree.getDir(targetPath).subdirs.forEach(dirName => { - if (!['enums', 'models', 'services'].includes(dirName)) return; - - tree.delete(`${targetPath}/${dirName}`); + const dirPath = `${targetPath}/${dirName}`; + tree.getDir(dirPath).visit(filePath => tree.delete(filePath)); + tree.delete(dirPath); }); + if (tree.exists(proxyIndexPath)) tree.delete(proxyIndexPath); + return tree; } catch (_) { throw new SchematicsException(interpolate(Exception.DirRemoveFailed, targetPath)); diff --git a/npm/ng-packs/tsconfig.base.json b/npm/ng-packs/tsconfig.base.json index d73d137f99..87b45cb3a9 100644 --- a/npm/ng-packs/tsconfig.base.json +++ b/npm/ng-packs/tsconfig.base.json @@ -29,7 +29,9 @@ "@abp/ng.setting-management": ["packages/setting-management/src/public-api.ts"], "@abp/ng.setting-management/config": ["packages/setting-management/config/src/public-api.ts"], "@abp/ng.permission-management": ["packages/permission-management/src/public-api.ts"], - "@abp/ng.feature-management": ["packages/feature-management/src/public-api.ts"] + "@abp/ng.feature-management": ["packages/feature-management/src/public-api.ts"], + "@proxy": ["apps/dev-app/src/app/proxy/index.ts"], + "@proxy/*": ["apps/dev-app/src/app/proxy/*"] } }, "angularCompilerOptions": { diff --git a/templates/app/angular/tsconfig.base.json b/templates/app/angular/tsconfig.base.json index 2f67131c75..7a5bf82308 100644 --- a/templates/app/angular/tsconfig.base.json +++ b/templates/app/angular/tsconfig.base.json @@ -12,7 +12,11 @@ "importHelpers": true, "target": "es2015", "typeRoots": ["node_modules/@types"], - "lib": ["es2018", "dom"] + "lib": ["es2018", "dom"], + "paths": { + "@proxy": ["src/app/proxy/index.ts"], + "@proxy/*": ["src/app/proxy/*"] + } }, "angularCompilerOptions": { "fullTemplateTypeCheck": true, diff --git a/templates/module/angular/tsconfig.base.json b/templates/module/angular/tsconfig.base.json index e8a830851f..5879bfbc59 100644 --- a/templates/module/angular/tsconfig.base.json +++ b/templates/module/angular/tsconfig.base.json @@ -7,7 +7,9 @@ ], "@my-company-name/my-project-name/config": [ "projects/my-project-name/config/src/public-api.ts" - ] + ], + "@proxy": ["projects/my-project-name/src/lib/proxy/index.ts"], + "@proxy/*": ["projects/my-project-name/src/lib/proxy/*"] } } }