Skip to content

Commit 097c189

Browse files
committed
fix: add a separate mapper for method
1 parent 757c289 commit 097c189

File tree

4 files changed

+40
-24
lines changed

4 files changed

+40
-24
lines changed

src/openapi/openapi3.classify.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { getKeyValue, isExist, isNotEmptyArray } from '../utils'
1414
import { emptySecurity, includeSecurity } from './openapi3.utils'
1515
import type { ClassifyRule, CompareContext } from '../types'
1616
import { DiffType } from '../types'
17-
import { unifyPath } from './openapi3.mapping'
17+
import { createPathUnifier } from './openapi3.mapping'
1818

1919
export const paramClassifyRule: ClassifyRule = [
2020
({ after }) => {
@@ -143,8 +143,8 @@ export const pathChangeClassifyRule: ClassifyRule = [
143143
({ before, after }) => {
144144
const beforePath = before.key as string
145145
const afterPath = after.key as string
146-
const unifiedBeforePath = unifyPath(before)(beforePath)
147-
const unifiedAfterPath = unifyPath(after)(afterPath)
146+
const unifiedBeforePath = createPathUnifier(before)(beforePath)
147+
const unifiedAfterPath = createPathUnifier(after)(afterPath)
148148

149149
// If unified paths are the same, it means only parameter names changed
150150
return unifiedBeforePath === unifiedAfterPath ? annotation : breaking

src/openapi/openapi3.mapping.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { MapKeysResult, MappingResolver, NodeContext } from '../types'
2-
import { getStringValue, objectKeys, onlyExistedArrayIndexes } from '../utils'
2+
import { difference, getStringValue, intersection, objectKeys, onlyExistedArrayIndexes } from '../utils'
33
import { mapPathParams } from './openapi3.utils'
44
import { OpenAPIV3 } from 'openapi-types'
55

@@ -28,28 +28,33 @@ export const pathMappingResolver: MappingResolver<string> = (before, after, ctx)
2828

2929
const result: MapKeysResult<string> = { added: [], removed: [], mapped: {} }
3030

31-
const originalBeforeKeys = objectKeys(before)
32-
const originalAfterKeys = objectKeys(after)
33-
const unifiedAfterKeys = originalAfterKeys.map(unifyPath(ctx.after))
31+
const unifiedBeforeKeyToKey = Object.fromEntries(objectKeys(before).map(key => [createPathUnifier(ctx.before)(key), key]))
32+
const unifiedAfterKeyToKey = Object.fromEntries(objectKeys(after).map(key => [createPathUnifier(ctx.after)(key), key]))
3433

35-
const notMappedAfterIndices = new Set(originalAfterKeys.keys())
34+
const unifiedBeforeKeys = Object.keys(unifiedBeforeKeyToKey)
35+
const unifiedAfterKeys = Object.keys(unifiedAfterKeyToKey)
3636

37-
originalBeforeKeys.forEach(beforeKey => {
38-
const unifiedBeforePath = unifyPath(ctx.before)(beforeKey)
39-
const index = unifiedAfterKeys.indexOf(unifiedBeforePath)
37+
result.added = difference(unifiedAfterKeys, unifiedBeforeKeys).map(key => unifiedAfterKeyToKey[key])
38+
result.removed = difference(unifiedBeforeKeys, unifiedAfterKeys).map(key => unifiedBeforeKeyToKey[key])
39+
result.mapped = Object.fromEntries(
40+
intersection(unifiedBeforeKeys, unifiedAfterKeys).map(key => [unifiedBeforeKeyToKey[key], unifiedAfterKeyToKey[key]]),
41+
)
4042

41-
if (index < 0) {
42-
// removed item
43-
result.removed.push(beforeKey)
44-
} else {
45-
// mapped items
46-
result.mapped[beforeKey] = originalAfterKeys[index]
47-
notMappedAfterIndices.delete(index)
48-
}
49-
})
43+
return result
44+
}
45+
46+
export const methodMappingResolver: MappingResolver<string> = (before, after) => {
47+
48+
const result: MapKeysResult<string> = { added: [], removed: [], mapped: {} }
49+
50+
const beforeKeys = objectKeys(before)
51+
const afterKeys = objectKeys(after)
52+
53+
result.added = difference(afterKeys, beforeKeys)
54+
result.removed = difference(beforeKeys, afterKeys)
5055

51-
// added items
52-
notMappedAfterIndices.forEach((notMappedIndex) => result.added.push(originalAfterKeys[notMappedIndex]))
56+
const mapped = intersection(beforeKeys, afterKeys)
57+
mapped.forEach(key => result.mapped[key] = key)
5358

5459
return result
5560
}
@@ -196,7 +201,7 @@ export const extractOperationBasePath = (servers?: OpenAPIV3.ServerObject[]): st
196201
}
197202
}
198203

199-
export function unifyPath(nodeContext: NodeContext): (path: string) => string {
204+
export function createPathUnifier(nodeContext: NodeContext): (path: string) => string {
200205
const serverPrefix = extractOperationBasePath((nodeContext.root as OpenAPIV3.Document).servers) // /api/v2
201206
return (path) => (
202207
serverPrefix

src/openapi/openapi3.rules.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import {
5555
} from './openapi3.classify'
5656
import {
5757
contentMediaTypeMappingResolver,
58+
methodMappingResolver,
5859
paramMappingResolver,
5960
pathMappingResolver,
6061
singleOperationPathMappingResolver,
@@ -392,7 +393,7 @@ export const openApi3Rules = (options: OpenApi3RulesOptions): CompareRules => {
392393

393394
const pathItemObjectRules = (options: OpenApi3RulesOptions): CompareRules => ({
394395
$: pathChangeClassifyRule,
395-
mapping: options.mode === COMPARE_MODE_OPERATION ? singleOperationPathMappingResolver : pathMappingResolver,
396+
mapping: options.mode === COMPARE_MODE_OPERATION ? singleOperationPathMappingResolver : methodMappingResolver,
396397
'/description': { $: allAnnotation },
397398
'/parameters': {
398399
$: [nonBreaking, breaking, breaking],

src/utils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,13 @@ export const checkPrimitiveType = (value: unknown): PrimitiveType | undefined =>
221221
}
222222
return undefined
223223
}
224+
225+
export function intersection(array1: string[], array2: string[]): string[] {
226+
const set2 = new Set(array2)
227+
return [...new Set(array1.filter(x => set2.has(x)))]
228+
}
229+
230+
export function difference(array1: string[], array2: string[]): string[] {
231+
const set2 = new Set(array2)
232+
return [...new Set(array1.filter(x => !set2.has(x)))]
233+
}

0 commit comments

Comments
 (0)