Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: remove dependency to sway #1700

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/@ama-sdk/schematics/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
"minimatch": "~9.0.3",
"rxjs": "^7.8.1",
"semver": "^7.5.2",
"sway": "^2.0.6",
"tslib": "^2.5.3"
},
"devDependencies": {
Expand Down Expand Up @@ -106,6 +105,7 @@
"npm-run-all2": "^6.0.0",
"nx": "~18.0.2",
"onchange": "^7.0.2",
"openapi-types": "^12.0.0",
"pid-from-port": "^1.1.3",
"semver": "^7.5.2",
"ts-jest": "~29.1.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/* eslint-disable @typescript-eslint/naming-convention */
import type { OpenAPIV3 } from 'openapi-types';
import { generateOperationFinderFromSingleFile } from './path-extractor';

describe('generateOperationFinderFromSingleFile', () => {

it('should parse a full path object', () => {
const spec: OpenAPIV3.Document = {
openapi: '3.0.0',
info: {
title: 'test',
version: '0.0.0'
},
paths: {
'/pet': {
post: {
description: 'Add a new pet to the store',
operationId: 'addPet',
responses: {
200: {
$ref: ''
},
405: {
$ref: ''
}
}
},
put: {
description: 'Update an existing pet by Id',
operationId: 'updatePet',
responses: {
200: {
$ref: ''
},
405: {
$ref: ''
}
}
}
},
// eslint-disable-next-line @typescript-eslint/naming-convention
'/pet/{petId}': {
get: {
description: 'Returns a single pet',
operationId: 'getPetById',
responses: {
200: {
$ref: ''
},
405: {
$ref: ''
}
}
}
}
}
};

const result = generateOperationFinderFromSingleFile(spec);
expect(result).toEqual([
{
path: '/pet', regexp: new RegExp('^/pet(?:/(?=$))?$'), operations: [{ 'method': 'post', 'operationId': 'addPet' }, { 'method': 'put', 'operationId': 'updatePet' }]
},
{
path: '/pet/{petId}', regexp: new RegExp('^/pet/((?:[^/]+?))(?:/(?=$))?$'), operations: [{ 'method': 'get', 'operationId': 'getPetById' }]
}
]);
});

it('should parse a path object with reference', () => {
const spec: OpenAPIV3.Document = {
openapi: '3.0.0',
info: {
title: 'test',
version: '0.0.0'
},
paths: {
'/pet': {
$ref: '#/components/schemas'
}
},
components: {
schemas: {
post: {
description: 'Add a new pet to the store',
operationId: 'addPet',
responses: {
200: {
$ref: ''
},
405: {
$ref: ''
}
}
} as any
}
}
};

const result = generateOperationFinderFromSingleFile(spec);
expect(result).toEqual([
{
path: '/pet', regexp: new RegExp('^/pet(?:/(?=$))?$'), operations: [{ 'method': 'post', 'operationId': 'addPet' }]
}
]);
});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { PathObject } from '@ama-sdk/core';
// eslint-disable-next-line camelcase
import type { OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';

/**
* Parse a single specification to retrieve the Operation Finder information
* This function is properly working to a specification that does not include external references in the Paths object
* @param specification Specification single object to parse
*/
// eslint-disable-next-line camelcase
export const generateOperationFinderFromSingleFile = (specification: OpenAPIV2.Document | OpenAPIV3.Document | OpenAPIV3_1.Document): PathObject[] => {
if (!specification.paths) {
return [];
}

return Object.entries(specification.paths)
.filter(([, pathObject]) => !!pathObject)
.map(([path, pathObjectOrRef]) => {
// eslint-disable-next-line camelcase
const pathObject: Record<OpenAPIV2.HttpMethods, OpenAPIV2.OperationObject | OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject> = pathObjectOrRef.$ref
? (pathObjectOrRef.$ref as string).replace(/^#\/?/, '').split('/').reduce((acc: any, ref) => acc[ref], specification)
: pathObjectOrRef;
return {
path,
regexp: new RegExp(`^${path.replace(/\{[^}]+}/g, '((?:[^/]+?))')}(?:/(?=$))?$`),
operations: Object.entries(pathObject)
.map(([method, reqObject]) => ({
method,
operationId: reqObject.operationId
}))
};
});
};
26 changes: 14 additions & 12 deletions packages/@ama-sdk/schematics/schematics/typescript/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@
Tree,
url
} from '@angular-devkit/schematics';
import type { Operation, PathObject } from '@ama-sdk/core';
import { createSchematicWithMetricsIfInstalled } from '@o3r/schematics';
import { readFileSync } from 'node:fs';
import type { PathObject } from '@ama-sdk/core';
import * as path from 'node:path';
import * as semver from 'semver';
import * as sway from 'sway';

import { OpenApiCliOptions } from '../../code-generator/open-api-cli-generator/open-api-cli.options';
import { treeGlob } from '../../helpers/tree-glob';
import { NgGenerateTypescriptSDKCoreSchematicsSchema } from './schema';
import { OpenApiCliGenerator } from '../../code-generator/open-api-cli-generator/open-api-cli.generator';
import { generateOperationFinderFromSingleFile } from './helpers/path-extractor';

const JAVA_OPTIONS = ['specPath', 'specConfigPath', 'globalProperty', 'outputPath'];
const OPEN_API_TOOLS_OPTIONS = ['generatorName', 'output', 'inputSpec', 'config', 'globalProperty'];
Expand Down Expand Up @@ -128,7 +128,7 @@
let globalPropertyMap: Map<string, any> = new Map();
if (openApiToolsJsonGenerator?.globalProperty) {
if (typeof openApiToolsJsonGenerator.globalProperty === 'object') {
Object.entries(openApiToolsJsonGenerator.globalProperty).forEach(([key, value]) => globalPropertyMap.set(key, value));

Check failure on line 131 in packages/@ama-sdk/schematics/schematics/typescript/core/index.ts

View workflow job for this annotation

GitHub Actions / checks / test (ubuntu-latest)

Typescript Core Generator › should update readme

Path "/home/runner/work/otter/otter/packages/@ama-sdk/schematics/testing/MOCK_swagger.yaml" does not exist. at HostTree.readText (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/tree/host-tree.js:222:19) at UnitTestTree.readText (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/tree/delegate.js:31:28) at generateOperationFinder (schematics/typescript/core/index.ts:131:176) at async generateSource (schematics/typescript/core/index.ts:139:33) at async callRuleAsync (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/rules/call.js:77:18)

Check failure on line 131 in packages/@ama-sdk/schematics/schematics/typescript/core/index.ts

View workflow job for this annotation

GitHub Actions / checks / test (ubuntu-latest)

Typescript Core Generator › should clean previous install

Path "/home/runner/work/otter/otter/packages/@ama-sdk/schematics/testing/MOCK_swagger.yaml" does not exist. at HostTree.readText (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/tree/host-tree.js:222:19) at UnitTestTree.readText (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/tree/delegate.js:31:28) at generateOperationFinder (schematics/typescript/core/index.ts:131:176) at async generateSource (schematics/typescript/core/index.ts:139:33) at async callRuleAsync (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/rules/call.js:77:18)

Check failure on line 131 in packages/@ama-sdk/schematics/schematics/typescript/core/index.ts

View workflow job for this annotation

GitHub Actions / checks / test (windows-latest)

Typescript Core Generator › should update readme

Path "D:\a\otter\otter\packages\@ama-sdk\schematics\testing\MOCK_swagger.yaml" does not exist. at HostTree.readText (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/tree/host-tree.js:222:19) at UnitTestTree.readText (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/tree/delegate.js:31:28) at generateOperationFinder (schematics/typescript/core/index.ts:131:176) at async generateSource (schematics/typescript/core/index.ts:139:33) at async callRuleAsync (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/rules/call.js:77:18)

Check failure on line 131 in packages/@ama-sdk/schematics/schematics/typescript/core/index.ts

View workflow job for this annotation

GitHub Actions / checks / test (windows-latest)

Typescript Core Generator › should clean previous install

Path "D:\a\otter\otter\packages\@ama-sdk\schematics\testing\MOCK_swagger.yaml" does not exist. at HostTree.readText (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/tree/host-tree.js:222:19) at UnitTestTree.readText (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/tree/delegate.js:31:28) at generateOperationFinder (schematics/typescript/core/index.ts:131:176) at async generateSource (schematics/typescript/core/index.ts:139:33) at async callRuleAsync (../../../.yarn/cache/@angular-devkit-schematics-npm-17.2.2-c347678006-c1924b45c3.zip/node_modules/@angular-devkit/schematics/src/rules/call.js:77:18)
} else {
globalPropertyMap = getGlobalProperties(globalPropertyMap, openApiToolsJsonGenerator.globalProperty);
}
Expand Down Expand Up @@ -162,6 +162,15 @@
return (tree, context) => {
const targetPath = options.directory || '';
const generatorOptions = getGeneratorOptions(tree, context, options);
const specContent = readFileSync(generatorOptions.specPath!).toString();

let isJson = false;
try {
JSON.parse(specContent);
isJson = true;
} catch (e) {
isJson = false;
}

/**
* rule to clear previous SDK generation
Expand All @@ -174,15 +183,9 @@
};

const generateOperationFinder = async (): Promise<PathObject[]> => {
const swayOptions = {
definition: path.resolve(generatorOptions.specPath!)
};
const swayApi = await sway.create(swayOptions);
const extraction = swayApi.getPaths().map((obj) => ({
path: obj.path,
regexp: obj.regexp as RegExp,
operations: obj.getOperations().map((op: any) => ({method: op.method, operationId: op.operationId} as Operation))
}));

const specification: any = isJson ? tree.readJson(generatorOptions.specPath!) : (await import('js-yaml')).load(tree.readText(generatorOptions.specPath!));
const extraction = generateOperationFinderFromSingleFile(specification);
return extraction || [];
};

Expand All @@ -209,7 +212,6 @@
*/
const updateSpec = () => {
const readmeFile = path.posix.join(targetPath, 'readme.md');
const specContent = readFileSync(generatorOptions.specPath!).toString();
if (tree.exists(readmeFile)) {
const specVersion = /version: *([0-9]+\.[0-9]+\.[0-9]+(?:-[^ ]+)?)/.exec(specContent);

Expand Down
Loading
Loading