Browse Source

feat: create 3 separate commands for proxy generation

pull/5222/head
Arman Ozak 6 years ago
parent
commit
7dd5aa74ef
  1. 18
      npm/ng-packs/packages/schematics/src/collection.json
  2. 9
      npm/ng-packs/packages/schematics/src/commands/api/index.ts
  3. 16
      npm/ng-packs/packages/schematics/src/commands/api/schema.ts
  4. 48
      npm/ng-packs/packages/schematics/src/commands/proxy-add/index.ts
  5. 12
      npm/ng-packs/packages/schematics/src/commands/proxy-add/schema.json
  6. 37
      npm/ng-packs/packages/schematics/src/commands/proxy-refresh/index.ts
  7. 39
      npm/ng-packs/packages/schematics/src/commands/proxy-refresh/schema.json
  8. 43
      npm/ng-packs/packages/schematics/src/commands/proxy-remove/index.ts
  9. 39
      npm/ng-packs/packages/schematics/src/commands/proxy-remove/schema.json
  10. 39
      npm/ng-packs/packages/schematics/src/commands/proxy/index.ts
  11. 16
      npm/ng-packs/packages/schematics/src/commands/proxy/schema.ts
  12. 51
      npm/ng-packs/packages/schematics/src/utils/source.ts

18
npm/ng-packs/packages/schematics/src/collection.json

@ -1,9 +1,19 @@
{
"schematics": {
"proxy": {
"description": "ABP Proxy Generator Schematics",
"factory": "./commands/proxy",
"schema": "./commands/proxy/schema.json"
"proxy-add": {
"description": "ABP Proxy Generator Add Schematics",
"factory": "./commands/proxy-add",
"schema": "./commands/proxy-add/schema.json"
},
"proxy-refresh": {
"description": "ABP Proxy Generator Refresh Schematics",
"factory": "./commands/proxy-refresh",
"schema": "./commands/proxy-refresh/schema.json"
},
"proxy-remove": {
"description": "ABP Proxy Generator Remove Schematics",
"factory": "./commands/proxy-remove",
"schema": "./commands/proxy-remove/schema.json"
},
"api": {
"description": "ABP API Generator Schematics",

9
npm/ng-packs/packages/schematics/src/commands/api/index.ts

@ -9,9 +9,8 @@ import {
Tree,
url,
} from '@angular-devkit/schematics';
import { PROXY_CONFIG_PATH } from '../../constants';
import { Exception } from '../../enums';
import { ServiceGeneratorParams } from '../../models';
import { GenerateProxySchema, ServiceGeneratorParams } from '../../models';
import {
applyWithOverwrite,
buildDefaultPath,
@ -31,7 +30,6 @@ import {
serializeParameters,
} from '../../utils';
import * as cases from '../../utils/text';
import { Schema as GenerateProxySchema } from './schema';
export default function(schema: GenerateProxySchema) {
const params = removeDefaultPlaceholders(schema);
@ -43,9 +41,8 @@ export default function(schema: GenerateProxySchema) {
const target = await resolveProject(tree, params.target!);
const solution = getRootNamespace(tree, source, moduleName);
const targetPath = buildDefaultPath(target.definition);
const definitionPath = targetPath + PROXY_CONFIG_PATH;
const readProxyConfig = createProxyConfigReader(definitionPath);
const createProxyConfigWriter = createProxyConfigWriterCreator(definitionPath);
const readProxyConfig = createProxyConfigReader(targetPath);
const createProxyConfigWriter = createProxyConfigWriterCreator(targetPath);
const data = readProxyConfig(tree);
const types = data.types;
const modules = data.modules;

16
npm/ng-packs/packages/schematics/src/commands/api/schema.ts

@ -1,16 +0,0 @@
export interface Schema {
/**
* Backend module to generate code for
*/
module?: string;
/**
* Angular project to resolve root namespace & API definition URL from
*/
source?: string;
/**
* Angular project to generate code in
*/
target?: string;
}

48
npm/ng-packs/packages/schematics/src/commands/proxy-add/index.ts

@ -0,0 +1,48 @@
import { strings } from '@angular-devkit/core';
import { chain, SchematicContext, Tree } from '@angular-devkit/schematics';
import { GenerateProxySchema } from '../../models';
import {
buildDefaultPath,
chainAndMerge,
createApiDefinitionGetter,
createApisGenerator,
createProxyClearer,
createProxyConfigReader,
createProxyConfigSaver,
removeDefaultPlaceholders,
resolveProject,
} from '../../utils';
export default function(schema: GenerateProxySchema) {
const params = removeDefaultPlaceholders(schema);
const moduleName = strings.camelize(params.module || 'app');
return chain([
async (host: Tree, _context: SchematicContext) => {
const target = await resolveProject(host, params.target!);
const targetPath = buildDefaultPath(target.definition);
const readProxyConfig = createProxyConfigReader(targetPath);
let generated: string[] = [];
try {
generated = readProxyConfig(host).generated;
const index = generated.findIndex(m => m === moduleName);
if (index < 0) generated.push(moduleName);
} catch (_) {
generated.push(moduleName);
}
const getApiDefinition = createApiDefinitionGetter(params);
const data = { generated, ...(await getApiDefinition(host)) };
data.generated = [];
const clearProxy = createProxyClearer(targetPath);
const saveProxyConfig = createProxyConfigSaver(data, targetPath);
const generateApis = createApisGenerator(schema, generated);
return chainAndMerge([clearProxy, saveProxyConfig, generateApis])(host);
},
]);
}

12
npm/ng-packs/packages/schematics/src/commands/proxy/schema.json → npm/ng-packs/packages/schematics/src/commands/proxy-add/schema.json

@ -6,33 +6,33 @@
"properties": {
"module": {
"alias": "m",
"description": "Backend module to generate code for",
"description": "Backend module name",
"type": "string",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "Please enter name of the backend module you wish to generate proxies for. (default: \"app\")"
"x-prompt": "Please enter backend module name. (default: \"app\")"
},
"source": {
"alias": "s",
"description": "Angular project to resolve root namespace & API definition URL from",
"description": "Source Angular project for API definition URL & root namespace resolution",
"type": "string",
"$default": {
"$source": "argv",
"index": 1
},
"x-prompt": "Plese enter Angular project name to resolve root namespace & API definition URL from. (default: workspace \"defaultProject\")"
"x-prompt": "Plese enter source Angular project for API definition URL & root namespace resolution. (default: workspace \"defaultProject\")"
},
"target": {
"alias": "t",
"description": "Angular project to generate code in",
"description": "Target Angular project to place the generated code",
"type": "string",
"$default": {
"$source": "argv",
"index": 2
},
"x-prompt": "Plese enter Angular project name to place generated code in. (default: workspace \"defaultProject\")"
"x-prompt": "Plese enter target Angular project to place the generated code. (default: workspace \"defaultProject\")"
}
},
"required": []

37
npm/ng-packs/packages/schematics/src/commands/proxy-refresh/index.ts

@ -0,0 +1,37 @@
import { SchematicContext, Tree } from '@angular-devkit/schematics';
import { GenerateProxySchema } from '../../models';
import {
buildDefaultPath,
chainAndMerge,
createApiDefinitionGetter,
createApisGenerator,
createProxyClearer,
createProxyConfigReader,
createProxyConfigSaver,
removeDefaultPlaceholders,
resolveProject,
} from '../../utils';
export default function(schema: GenerateProxySchema) {
const params = removeDefaultPlaceholders(schema);
return async (host: Tree, _context: SchematicContext) => {
const target = await resolveProject(host, params.target!);
const targetPath = buildDefaultPath(target.definition);
const readProxyConfig = createProxyConfigReader(targetPath);
const { generated } = readProxyConfig(host);
const getApiDefinition = createApiDefinitionGetter(params);
const data = { generated, ...(await getApiDefinition(host)) };
data.generated = [];
const clearProxy = createProxyClearer(targetPath);
const saveProxyConfig = createProxyConfigSaver(data, targetPath);
const generateApis = createApisGenerator(schema, generated);
return chainAndMerge([clearProxy, saveProxyConfig, generateApis])(host);
};
}

39
npm/ng-packs/packages/schematics/src/commands/proxy-refresh/schema.json

@ -0,0 +1,39 @@
{
"$schema": "http://json-schema.org/schema",
"id": "SchematicsAbpGenerateProxy",
"title": "ABP Generate Proxy Schema",
"type": "object",
"properties": {
"module": {
"alias": "m",
"description": "Backend module name",
"type": "string",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "Please enter backend module name. (default: \"app\")"
},
"source": {
"alias": "s",
"description": "Source Angular project for API definition URL & root namespace resolution",
"type": "string",
"$default": {
"$source": "argv",
"index": 1
},
"x-prompt": "Plese enter source Angular project for API definition URL & root namespace resolution. (default: workspace \"defaultProject\")"
},
"target": {
"alias": "t",
"description": "Target Angular project to place the generated code",
"type": "string",
"$default": {
"$source": "argv",
"index": 2
},
"x-prompt": "Plese enter target Angular project to place the generated code. (default: workspace \"defaultProject\")"
}
},
"required": []
}

43
npm/ng-packs/packages/schematics/src/commands/proxy-remove/index.ts

@ -0,0 +1,43 @@
import { strings } from '@angular-devkit/core';
import { SchematicContext, Tree } from '@angular-devkit/schematics';
import { GenerateProxySchema } from '../../models';
import {
buildDefaultPath,
chainAndMerge,
createApiDefinitionGetter,
createApisGenerator,
createProxyClearer,
createProxyConfigReader,
createProxyConfigSaver,
removeDefaultPlaceholders,
resolveProject,
} from '../../utils';
export default function(schema: GenerateProxySchema) {
const params = removeDefaultPlaceholders(schema);
const moduleName = strings.camelize(params.module || 'app');
return async (host: Tree, _context: SchematicContext) => {
const target = await resolveProject(host, params.target!);
const targetPath = buildDefaultPath(target.definition);
const readProxyConfig = createProxyConfigReader(targetPath);
const { generated } = readProxyConfig(host);
const index = generated.findIndex(m => m === moduleName);
if (index < 0) return host;
generated.splice(index, 1);
const getApiDefinition = createApiDefinitionGetter(params);
const data = { generated, ...(await getApiDefinition(host)) };
data.generated = [];
const clearProxy = createProxyClearer(targetPath);
const saveProxyConfig = createProxyConfigSaver(data, targetPath);
const generateApis = createApisGenerator(schema, generated);
return chainAndMerge([clearProxy, saveProxyConfig, generateApis])(host);
};
}

39
npm/ng-packs/packages/schematics/src/commands/proxy-remove/schema.json

@ -0,0 +1,39 @@
{
"$schema": "http://json-schema.org/schema",
"id": "SchematicsAbpGenerateProxy",
"title": "ABP Generate Proxy Schema",
"type": "object",
"properties": {
"module": {
"alias": "m",
"description": "Backend module name",
"type": "string",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "Please enter backend module name. (default: \"app\")"
},
"source": {
"alias": "s",
"description": "Source Angular project for API definition URL & root namespace resolution",
"type": "string",
"$default": {
"$source": "argv",
"index": 1
},
"x-prompt": "Plese enter source Angular project for API definition URL & root namespace resolution. (default: workspace \"defaultProject\")"
},
"target": {
"alias": "t",
"description": "Target Angular project to place the generated code",
"type": "string",
"$default": {
"$source": "argv",
"index": 2
},
"x-prompt": "Plese enter target Angular project to place the generated code. (default: workspace \"defaultProject\")"
}
},
"required": []
}

39
npm/ng-packs/packages/schematics/src/commands/proxy/index.ts

@ -1,39 +0,0 @@
import { strings } from '@angular-devkit/core';
import {
branchAndMerge,
chain,
schematic,
SchematicContext,
Tree,
} from '@angular-devkit/schematics';
import { API_DEFINITION_ENDPOINT, PROXY_CONFIG_PATH } from '../../constants';
import { ApiDefinition } from '../../models';
import {
buildDefaultPath,
createProxyConfigSaver,
getApiDefinition,
getSourceUrl,
removeDefaultPlaceholders,
resolveProject,
} from '../../utils';
import { Schema as GenerateProxySchema } from './schema';
export default function(schema: GenerateProxySchema) {
const params = removeDefaultPlaceholders(schema);
const moduleName = strings.camelize(params.module || 'app');
return chain([
async (tree: Tree, _context: SchematicContext) => {
const source = await resolveProject(tree, params.source!);
const target = await resolveProject(tree, params.target!);
const sourceUrl = getSourceUrl(tree, source, moduleName);
const targetPath = buildDefaultPath(target.definition);
const data: ApiDefinition = await getApiDefinition(sourceUrl + API_DEFINITION_ENDPOINT);
const saveProxyConfig = createProxyConfigSaver(data, targetPath + PROXY_CONFIG_PATH);
const createApi = schematic('api', schema);
return branchAndMerge(chain([saveProxyConfig, createApi]));
},
]);
}

16
npm/ng-packs/packages/schematics/src/commands/proxy/schema.ts

@ -1,16 +0,0 @@
export interface Schema {
/**
* Backend module to generate code for
*/
module?: string;
/**
* Angular project to resolve root namespace & API definition URL from
*/
source?: string;
/**
* Angular project to generate code in
*/
target?: string;
}

51
npm/ng-packs/packages/schematics/src/utils/source.ts

@ -1,13 +1,26 @@
import { strings } from '@angular-devkit/core';
import { SchematicsException, Tree } from '@angular-devkit/schematics';
import got from 'got';
import { API_DEFINITION_ENDPOINT, PROXY_CONFIG_PATH, PROXY_PATH } from '../constants';
import { Exception } from '../enums';
import { ApiDefinition, Project, ProxyConfig, WriteOp } from '../models';
import { ApiDefinition, GenerateProxySchema, Project, ProxyConfig, WriteOp } from '../models';
import { getAssignedPropertyFromObjectliteral } from './ast';
import { interpolate } from './common';
import { readEnvironment } from './workspace';
import { readEnvironment, resolveProject } from './workspace';
export async function getApiDefinition(url: string) {
let body: any;
export function createApiDefinitionGetter(params: GenerateProxySchema) {
const moduleName = strings.camelize(params.module || 'app');
return async (host: Tree) => {
const source = await resolveProject(host, params.source!);
const sourceUrl = getSourceUrl(host, source, moduleName);
return await getApiDefinition(sourceUrl);
};
}
async function getApiDefinition(sourceUrl: string) {
const url = sourceUrl + API_DEFINITION_ENDPOINT;
let body: ApiDefinition;
try {
({ body } = await got(url, {
@ -17,9 +30,10 @@ export async function getApiDefinition(url: string) {
}));
} catch ({ response }) {
// handle redirects
if (response?.body && response.statusCode < 400) return response.body;
if (response.statusCode >= 400 || !response?.body)
throw new SchematicsException(Exception.NoApi);
throw new SchematicsException(Exception.NoApi);
body = response.body;
}
return body;
@ -72,13 +86,33 @@ export function getSourceUrl(tree: Tree, project: Project, moduleName: string) {
}
export function createProxyConfigReader(targetPath: string) {
targetPath += PROXY_CONFIG_PATH;
return (tree: Tree) => {
try {
const buffer = tree.read(targetPath);
return JSON.parse(buffer!.toString()) as ProxyConfig;
} catch (_) {}
throw new SchematicsException(interpolate(Exception.NoApiDefinition, targetPath));
throw new SchematicsException(interpolate(Exception.NoProxyConfig, targetPath));
};
}
export function createProxyClearer(targetPath: string) {
targetPath += PROXY_PATH;
return (tree: Tree) => {
try {
tree.getDir(targetPath).subdirs.forEach(dirName => {
if (!['enums', 'models', 'services'].includes(dirName)) return;
tree.delete(`${targetPath}/${dirName}`);
});
return tree;
} catch (_) {
throw new SchematicsException(interpolate(Exception.DirRemoveFailed, targetPath));
}
};
}
@ -86,6 +120,7 @@ export function createProxyConfigSaver(apiDefinition: ApiDefinition, targetPath:
const createProxyConfigJson = createProxyConfigJsonCreator(apiDefinition);
const readPreviousConfig = createProxyConfigReader(targetPath);
const createProxyConfigWriter = createProxyConfigWriterCreator(targetPath);
targetPath += PROXY_CONFIG_PATH;
return (tree: Tree) => {
const generated: string[] = [];
@ -108,6 +143,8 @@ export function createProxyConfigSaver(apiDefinition: ApiDefinition, targetPath:
}
export function createProxyConfigWriterCreator(targetPath: string) {
targetPath += PROXY_CONFIG_PATH;
return (op: WriteOp, data: string) => (tree: Tree) => {
try {
tree[op](targetPath, data);

Loading…
Cancel
Save