Skip to content

Commit 64081bc

Browse files
committed
Merge branch 'main' into develop
2 parents 153b308 + c5a9506 commit 64081bc

File tree

12 files changed

+316
-69
lines changed

12 files changed

+316
-69
lines changed

package-lock.json

Lines changed: 30 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@netcracker/qubership-apihub-api-processor",
3-
"version": "4.2.5",
3+
"version": "5.0.0",
44
"description": "",
55
"license": "Apache-2.0",
66
"module": "dist/esm/src/index.js",
@@ -31,10 +31,10 @@
3131
"update-lock-file": "update-lock-file @netcracker"
3232
},
3333
"dependencies": {
34-
"@netcracker/qubership-apihub-api-diff": "dev",
35-
"@netcracker/qubership-apihub-api-unifier": "dev",
36-
"@netcracker/qubership-apihub-graphapi": "dev",
37-
"@netcracker/qubership-apihub-json-crawl": "dev",
34+
"@netcracker/qubership-apihub-api-diff": "3.0.0",
35+
"@netcracker/qubership-apihub-api-unifier": "2.5.0",
36+
"@netcracker/qubership-apihub-graphapi": "1.0.9",
37+
"@netcracker/qubership-apihub-json-crawl": "1.2.0",
3838
"adm-zip": "0.5.10",
3939
"ajv": "^8.12.0",
4040
"ajv-formats": "^2.1.1",

src/apitypes/graphql/graphql.changes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export const compareDocuments: DocumentsCompare = async (
5858
ctx: CompareOperationsPairContext,
5959
): Promise<DocumentsCompareData> => {
6060
const { apiType, rawDocumentResolver, previousVersion, currentVersion, previousPackageId, currentPackageId } = ctx
61-
const comparisonInternalDocumentId = createComparisonInternalDocumentId(prevDoc, currDoc, previousVersion, currentVersion)
61+
const comparisonInternalDocumentId = createComparisonInternalDocumentId(previousVersion, previousPackageId, prevDoc?.slug, currentVersion, currentPackageId, currDoc?.slug)
6262
const prevFile = prevDoc && await rawDocumentResolver(previousVersion, previousPackageId, prevDoc.slug)
6363
const currFile = currDoc && await rawDocumentResolver(currentVersion, currentPackageId, currDoc.slug)
6464
const prevDocSchema = prevFile && buildSchema(await prevFile.text(), { noLocation: true })

src/apitypes/rest/rest.changes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export const compareDocuments: DocumentsCompare = async (
103103
previousVersionLabels,
104104
currentVersionLabels,
105105
} = ctx
106-
const comparisonInternalDocumentId = createComparisonInternalDocumentId(prevDoc, currDoc, previousVersion, currentVersion)
106+
const comparisonInternalDocumentId = createComparisonInternalDocumentId(previousVersion, previousPackageId, prevDoc?.slug, currentVersion, currentPackageId, currDoc?.slug)
107107
const prevFile = prevDoc && await rawDocumentResolver(previousVersion, previousPackageId, prevDoc.slug)
108108
const currFile = currDoc && await rawDocumentResolver(currentVersion, currentPackageId, currDoc.slug)
109109
let prevDocData = prevFile && JSON.parse(await prevFile.text())

src/apitypes/rest/rest.operation.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ import {
3232
import {
3333
_calculateRestOperationIdV1,
3434
buildSearchScope,
35-
calculateRestOperationId,
36-
capitalize,
35+
calculateRestOperationId, calculateRestOperationTitle,
3736
extractSymbolProperty,
3837
getKeyValue,
3938
getSplittedVersionKey,
@@ -174,7 +173,7 @@ export const buildRestOperation = (
174173
apiType: REST_API_TYPE,
175174
apiKind: operationApiKind,
176175
deprecated: !!effectiveOperationObject.deprecated,
177-
title: effectiveOperationObject.summary || operationId.split('-').map(str => capitalize(str)).join(' '),
176+
title: effectiveOperationObject.summary || calculateRestOperationTitle(basePath, method, path),
178177
metadata: {
179178
customTags: customTags,
180179
path: normalizePath(basePath + path),

src/apitypes/rest/rest.utils.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import YAML from 'js-yaml'
3535
import { Diff, DIFF_META_KEY, DIFFS_AGGREGATED_META_KEY } from '@netcracker/qubership-apihub-api-diff'
3636
import { isPathParamRenameDiff } from '../../utils'
3737

38-
3938
export function getCustomTags(data: object): CustomTags {
4039
const initialValue: CustomTags = {}
4140
if (!data || typeof data !== 'object') {

src/components/compare/compare.utils.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import {
1919
ApiDocument,
2020
ChangeSummary,
2121
CompareOperationsPairContext,
22-
ComparisonDocument, ComparisonInternalDocument,
22+
ComparisonDocument,
23+
ComparisonInternalDocument,
2324
DIFF_TYPES,
2425
ImpactedOperationSummary,
2526
NormalizedOperationId,
@@ -39,9 +40,9 @@ import {
3940
difference,
4041
intersection,
4142
removeFirstSlash,
43+
serializeDocument,
4244
SLUG_OPTIONS_OPERATION_ID,
4345
slugify,
44-
serializeDocument,
4546
takeIfDefined,
4647
} from '../../utils'
4748
import { Diff } from '@netcracker/qubership-apihub-api-diff'
@@ -296,7 +297,6 @@ export function createOperationChange(
296297
}
297298
}
298299

299-
300300
export function createComparisonDocument(comparisonDocumentId: string, apiDocument: ApiDocument): ComparisonDocument {
301301
return {
302302
comparisonDocumentId,
@@ -305,19 +305,21 @@ export function createComparisonDocument(comparisonDocumentId: string, apiDocume
305305
}
306306

307307
type FileParam = string | undefined
308-
type FileParams = [FileParam, FileParam] | null
308+
type FileParams = FileParam[] | null
309309

310310
export const createComparisonFileId = (prev: FileParams | null, curr: FileParams): string => {
311-
return [...prev || [], ...curr || []].filter(Boolean).join('_')
311+
return [...prev || [], ...curr || []].filter(Boolean).join('_').replace(/\//g, '_')
312312
}
313313

314314
export const createComparisonInternalDocumentId = (
315-
prevDoc: ResolvedVersionDocument | undefined,
316-
currDoc: ResolvedVersionDocument | undefined,
317-
previousVersion: FileParam,
318-
currentVersion: FileParam,
315+
previousVersion: string,
316+
previousPackageId: string,
317+
prevSlug: string | undefined,
318+
currentVersion: string,
319+
currentPackageId: string,
320+
currSlug: string | undefined,
319321
): string => {
320-
return createComparisonFileId([prevDoc?.slug, previousVersion], [currDoc?.slug, currentVersion])
322+
return createComparisonFileId([prevSlug, previousVersion, previousPackageId || currentPackageId], [currSlug, currentVersion, currentPackageId])
321323
}
322324

323325
export const removeGroupPrefixFromOperationId = (operationId: string, groupPrefix: string): string => {

src/utils/operations.utils.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,14 @@ import { ApiDocument, ApiOperation, BuildResult, OperationIdNormalizer, VersionD
1818
import { GraphApiComponents, GraphApiDirectiveDefinition } from '@netcracker/qubership-apihub-graphapi'
1919
import { OpenAPIV3 } from 'openapi-types'
2020
import { isObject } from './objects'
21-
import { serializeDocument } from './document'
22-
import { SLUG_OPTIONS_DOCUMENT_ID, SLUG_OPTIONS_NORMALIZED_OPERATION_ID, SLUG_OPTIONS_OPERATION_ID, slugify } from './slugify'
21+
import { capitalize, serializeDocument } from './document'
22+
import {
23+
SLUG_OPTIONS_DOCUMENT_ID,
24+
SLUG_OPTIONS_NORMALIZED_OPERATION_ID,
25+
SLUG_OPTIONS_OPERATION_ID,
26+
SLUG_OPTIONS_TITLE,
27+
slugify,
28+
} from './slugify'
2329
import { normalizePath, removeFirstSlash } from './builder'
2430
import { Diff, DiffAction } from '@netcracker/qubership-apihub-api-diff'
2531
import {
@@ -146,6 +152,27 @@ export const calculateRestOperationId = (
146152
return _calculateRestOperationIdV2(basePath, path, method)
147153
}
148154

155+
/**
156+
* Calculates a human-readable REST operation title.
157+
*
158+
* @param basePath - The base path from servers configuration
159+
* @param key - Operation key (usually HTTP method)
160+
* @param path - The operation path
161+
* @returns The formatted operation title (space-separated, title-cased)
162+
*/
163+
export const calculateRestOperationTitle = (
164+
basePath: string,
165+
key: string,
166+
path: string,
167+
): string => {
168+
const operationPath = `${basePath}${path}`
169+
return slugify(`${removeFirstSlash(operationPath)}-${key}`, SLUG_OPTIONS_TITLE)
170+
.split(' ')
171+
.filter(Boolean)
172+
.map(capitalize)
173+
.join(' ')
174+
}
175+
149176
export const calculateGraphqlOperationId = (
150177
operationType: string,
151178
operationName: string,

src/utils/slugify.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@ export const SLUG_OPTIONS_DOCUMENT_ID: Options = {
1313
},
1414
}
1515

16+
// Intended for human-readable titles (keeps original casing, uses spaces as separators)
17+
export const SLUG_OPTIONS_TITLE: Options = {
18+
replacement: ' ',
19+
lower: false,
20+
trim: true,
21+
charmap: {
22+
...createSlug.charmap,
23+
...{
24+
'/': ' ',
25+
'_': ' ',
26+
'.': ' ',
27+
'(': ' ',
28+
')': ' ',
29+
'-': ' ',
30+
},
31+
},
32+
}
33+
1634
// additional characters are added for more selectivity
1735
export const SLUG_OPTIONS_OPERATION_ID: Options = {
1836
charmap: {

test/bugs.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { API_AUDIENCE_INTERNAL, APIHUB_API_COMPATIBILITY_KIND_BWC, APIHUB_API_CO
1818
import { Editor, LocalRegistry } from './helpers'
1919

2020
import { describe, expect, test } from '@jest/globals'
21+
import { calculateRestOperationTitle } from '../src/utils'
2122

2223
const bugsPackage = LocalRegistry.openPackage('bugs')
2324
const swaggerPackage = LocalRegistry.openPackage('basic_swagger')
@@ -367,4 +368,26 @@ describe('Operation Bugs', () => {
367368
expect(data).toHaveProperty(['paths', '/test', 'post', 'responses', '200', 'content', 'application/json', 'schema', 'properties', 'testConnectionDate', 'example'], '2022-03-10T16:15:50Z')
368369
})
369370

371+
test('should format rest operationId title without extra characters', async () => {
372+
type TestCase = [string, string, string, string]
373+
374+
const testData: TestCase[] = [
375+
['', 'get', '/path1', 'Path1 Get'],
376+
['', 'get', '/items/{itemId}', 'Items ItemId Get'],
377+
['api/v1', 'get', '/path1', 'Api V1 Path1 Get'],
378+
['api/v1', 'get', '/items/{itemId}', 'Api V1 Items ItemId Get'],
379+
['api/v1/rest', 'get', '/items/{itemId}', 'Api V1 Rest Items ItemId Get'],
380+
]
381+
testData.forEach(([basePath, key, path, expectedTitle]) =>{
382+
const title = calculateRestOperationTitle(basePath, key, path)
383+
expect(title).toEqual(expectedTitle)
384+
})
385+
386+
const editor = await Editor.openProject('bugs', bugsPackage)
387+
const result = await editor.run({
388+
files: [{ fileId: 'title-rest-operation-id-format.yaml', publish: true }],
389+
})
390+
const restOperationTitle = result.operations.get('api-v1-items-_item_-get')?.title
391+
expect(restOperationTitle).toEqual('Api V1 Items Item Get')
392+
})
370393
})

0 commit comments

Comments
 (0)