Skip to content

Commit 2d34cfb

Browse files
authored
Merge branch 'develop' into feature/ignore-param-name-while-matching
2 parents 930eb67 + 217c4b7 commit 2d34cfb

File tree

7 files changed

+115
-49
lines changed

7 files changed

+115
-49
lines changed

package-lock.json

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

package.json

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,11 @@
2929
"operation:test": "node ./test/operation.js",
3030
"profile": "node --inspect-brk ./test/profile.js",
3131
"test:coverage": "jest --verbose --coverage",
32-
"feature-start": "feature-start --featureName",
33-
"feature-finish": "feature-finish",
34-
"release-start": "release-start",
35-
"release-finish": "release-finish"
32+
"update-lock-file": "update-lock-file @netcracker"
3633
},
3734
"dependencies": {
3835
"@netcracker/qubership-apihub-api-diff": "dev",
39-
"@netcracker/qubership-apihub-api-unifier": "1.0.4",
36+
"@netcracker/qubership-apihub-api-unifier": "dev",
4037
"@netcracker/qubership-apihub-json-crawl": "1.0.4",
4138
"@netcracker/qubership-apihub-graphapi": "1.0.8",
4239
"adm-zip": "0.5.10",
@@ -53,7 +50,7 @@
5350
"swagger2openapi": "^7.0.8"
5451
},
5552
"devDependencies": {
56-
"@netcracker/qubership-apihub-npm-gitflow": "2.2.2",
53+
"@netcracker/qubership-apihub-npm-gitflow": "3.0.1",
5754
"@types/adm-zip": "0.5.7",
5855
"@types/jest": "^29.5.12",
5956
"@types/js-yaml": "^4.0.5",
@@ -84,4 +81,4 @@
8481
"engines": {
8582
"node": ">=18.0.0"
8683
}
87-
}
84+
}

src/apitypes/rest/rest.operations.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import type * as TYPE from './rest.types'
3030
import { HASH_FLAG, INLINE_REFS_FLAG, MESSAGE_SEVERITY, NORMALIZE_OPTIONS, ORIGINS_SYMBOL } from '../../consts'
3131
import { asyncFunction } from '../../utils/async'
3232
import { logLongBuild, syncDebugPerformance } from '../../utils/logs'
33-
import { normalize } from '@netcracker/qubership-apihub-api-unifier'
33+
import { normalize, RefErrorType } from '@netcracker/qubership-apihub-api-unifier'
3434

3535
export const buildRestOperations: OperationsBuilder<OpenAPIV3.Document> = async (document, ctx, debugCtx) => {
3636
const documentWithoutComponents = removeComponents(document.data)
@@ -44,8 +44,8 @@ export const buildRestOperations: OperationsBuilder<OpenAPIV3.Document> = async
4444
originsFlag: ORIGINS_SYMBOL,
4545
hashFlag: HASH_FLAG,
4646
source: document.data,
47-
onRefResolveError: (_: string, __: PropertyKey[], ref: string) =>
48-
bundlingErrorHandler([`The $ref "${ref}" references an invalid location in the document.`]),
47+
onRefResolveError: (message: string, _path: PropertyKey[], _ref: string, errorType: RefErrorType) =>
48+
bundlingErrorHandler([{ message, errorType }]),
4949
},
5050
) as OpenAPIV3.Document
5151
const refsOnlyDocument = normalize(

src/utils/document.ts

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ import {
2929
PackageDocument,
3030
ResolvedDocument,
3131
VALIDATION_RULES_SEVERITY_LEVEL_ERROR,
32-
VALIDATION_RULES_SEVERITY_LEVEL_WARNING,
3332
VersionDocument,
3433
YAML_EXPORT_GROUP_FORMAT,
3534
} from '../types'
3635
import { bundle, Resolver } from 'api-ref-bundler'
3736
import { FILE_FORMAT_JSON, FILE_FORMAT_YAML, MESSAGE_SEVERITY } from '../consts'
3837
import { isNotEmpty } from './arrays'
3938
import { PATH_PARAM_UNIFIED_PLACEHOLDER } from './builder'
39+
import { RefErrorType, RefErrorTypes } from '@netcracker/qubership-apihub-api-unifier'
4040

4141
export const EXPORT_FORMAT_TO_FILE_FORMAT = new Map<OperationsGroupExportFormat, FileFormat>([
4242
[YAML_EXPORT_GROUP_FORMAT, FILE_FORMAT_YAML],
@@ -124,42 +124,60 @@ export const getDocumentTitle = (fileId: string): string => {
124124
return fileId.substring(cutDot).split('/').pop()!.replace(/\.[^/.]+$/, '')
125125
}
126126

127-
export const createBundlingErrorHandler = (ctx: BuilderContext, fileId: FileId) => (messages: string[]): void => {
128-
switch (ctx.config.validationRulesSeverity?.brokenRefs) {
129-
case VALIDATION_RULES_SEVERITY_LEVEL_ERROR:
130-
throw new Error(messages[0])
131-
case VALIDATION_RULES_SEVERITY_LEVEL_WARNING:
132-
default:
133-
for (const message of messages) {
134-
ctx.notifications.push({
135-
severity: MESSAGE_SEVERITY.Error,
136-
message: message,
137-
fileId: fileId,
138-
})
139-
}
127+
export interface BundlingError {
128+
message: string
129+
errorType: RefErrorType
130+
}
131+
132+
export const createBundlingErrorHandler = (ctx: BuilderContext, fileId: FileId) => (errors: BundlingError[]): void => {
133+
// Only throw if severity is ERROR and there's at least one critical error
134+
if (ctx.config.validationRulesSeverity?.brokenRefs === VALIDATION_RULES_SEVERITY_LEVEL_ERROR) {
135+
const criticalError = errors.find(error =>
136+
error.errorType === RefErrorTypes.REF_NOT_FOUND ||
137+
error.errorType === RefErrorTypes.REF_NOT_VALID_FORMAT,
138+
)
139+
140+
if (criticalError) {
141+
throw new Error(criticalError.message)
142+
}
143+
}
144+
145+
// In other cases push all errors to notifications
146+
for (const error of errors) {
147+
ctx.notifications.push({
148+
severity: MESSAGE_SEVERITY.Error,
149+
message: error.message,
150+
fileId: fileId,
151+
})
140152
}
141153
}
142154

143155
export const getBundledFileDataWithDependencies = async (
144156
fileId: FileId,
145157
parsedFileResolver: _ParsedFileResolver,
146-
onError: (messages: string[]) => void,
158+
onError: (errors: BundlingError[]) => void,
147159
): Promise<{ data: any; dependencies: string[] }> => {
148160
const dependencies: string[] = []
149-
const errorMessages: string[] = []
161+
const errors: BundlingError[] = []
150162

151163
const resolver: Resolver = async (filepath: string) => {
152164
const data = await parsedFileResolver(filepath)
153165

154166
if (data === null) {
155167
// can't throw the error here because it will be suppressed: https://github.com/udamir/api-ref-bundler/blob/0.4.0/src/resolver.ts#L33
156-
errorMessages.push(`Unable to resolve the file "${filepath}" because it does not exist.`)
168+
errors.push({
169+
message: `Unable to resolve the file "${filepath}" because it does not exist.`,
170+
errorType: RefErrorTypes.REF_NOT_FOUND,
171+
})
157172
return {}
158173
}
159174

160175
if (data.kind !== FILE_KIND.TEXT) {
161176
// can't throw the error here because it will be suppressed: https://github.com/udamir/api-ref-bundler/blob/0.4.0/src/resolver.ts#L33
162-
errorMessages.push(`Unable to resolve the file "${filepath}" because it is not a valid text file.`)
177+
errors.push({
178+
message: `Unable to resolve the file "${filepath}" because it is not a valid text file.`,
179+
errorType: RefErrorTypes.REF_NOT_VALID_FORMAT,
180+
})
163181
return {}
164182
}
165183

@@ -172,8 +190,8 @@ export const getBundledFileDataWithDependencies = async (
172190

173191
const bundledFileData = await bundle(fileId, resolver)
174192

175-
if (isNotEmpty(errorMessages)) {
176-
onError(errorMessages)
193+
if (isNotEmpty(errors)) {
194+
onError(errors)
177195
}
178196

179197
return { data: bundledFileData, dependencies: dependencies }
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"packageId": "reference-bundling/description-override",
3+
"apiType": "rest",
4+
"version": "v1",
5+
"files": [
6+
{
7+
"fileId": "openapi.yaml",
8+
"publish": true,
9+
"labels": [],
10+
"commitId": "6c778b1f44200bd19944a6a8eac10a4e5a21a1xd"
11+
}
12+
]
13+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
openapi: 3.0.3
2+
info:
3+
title: test
4+
version: 0.1.0
5+
paths:
6+
/path1:
7+
get:
8+
responses:
9+
'200':
10+
description: OK
11+
content:
12+
application/json:
13+
schema:
14+
$ref: '#/components/schemas/Test'
15+
description: Description override
16+
components:
17+
schemas:
18+
Test:
19+
type: object

test/reference-bundling.test.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ describe('Reference bundling test', () => {
2222
const result = await pkg.publish(pkg.packageId)
2323

2424
expect(result).toEqual(notificationsMatcher([
25-
errorNotificationMatcher('references an invalid location'),
25+
errorNotificationMatcher('can\'t be resolved'),
2626
errorNotificationMatcher('does not exist'),
2727
]))
2828
expect(result.operations.size).toBe(1)
@@ -52,7 +52,7 @@ describe('Reference bundling test', () => {
5252
const result = await pkg.publish(pkg.packageId)
5353

5454
expect(result).toEqual(notificationsMatcher([
55-
errorNotificationMatcher('references an invalid location'),
55+
errorNotificationMatcher('can\'t be resolved'),
5656
errorNotificationMatcher('does not exist'),
5757
]))
5858
expect(result.operations.size).toBe(1)
@@ -64,14 +64,14 @@ describe('Reference bundling test', () => {
6464

6565
await expect(
6666
pkg.publish(pkg.packageId, { validationRulesSeverity: { brokenRefs: VALIDATION_RULES_SEVERITY_LEVEL_ERROR } }),
67-
).rejects.toThrow(/references an invalid location/)
67+
).rejects.toThrow(/can't be resolved/)
6868
})
6969

7070
test('should collect missing internal reference notification if severity level is not configured', async () => {
7171
const pkg = LocalRegistry.openPackage('reference-bundling/case5')
7272
const result = await pkg.publish(pkg.packageId)
7373

74-
expect(result).toEqual(notificationsMatcher([errorNotificationMatcher('references an invalid location')]))
74+
expect(result).toEqual(notificationsMatcher([errorNotificationMatcher('can\'t be resolved')]))
7575
expect(result.operations.size).toBe(1)
7676
})
7777

@@ -81,4 +81,18 @@ describe('Reference bundling test', () => {
8181
pkg.publish(pkg.packageId, { validationRulesSeverity: { brokenRefs: VALIDATION_RULES_SEVERITY_LEVEL_ERROR } }),
8282
).rejects.toThrow(/not a valid text file/)
8383
})
84+
85+
test('should collect notifications on publishing specification with incorrect description override', async () => {
86+
const pkg = LocalRegistry.openPackage('reference-bundling/description-override')
87+
const result = await pkg.publish(pkg.packageId, {
88+
validationRulesSeverity: {
89+
brokenRefs: VALIDATION_RULES_SEVERITY_LEVEL_ERROR,
90+
},
91+
})
92+
93+
expect(result).toEqual(notificationsMatcher([
94+
errorNotificationMatcher('can\'t have siblings in this specification version'),
95+
]))
96+
expect(result.operations.size).toBe(1)
97+
})
8498
})

0 commit comments

Comments
 (0)