Skip to content

Commit fdceb74

Browse files
committed
feat: fail build if ref can't be resolved
1 parent d091bfe commit fdceb74

File tree

11 files changed

+131
-3
lines changed

11 files changed

+131
-3
lines changed

src/apitypes/rest/rest.operations.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { OpenAPIV3 } from 'openapi-types'
1818

1919
import { buildRestOperation } from './rest.operation'
2020
import type { OperationsBuilder } from '../../types'
21-
import { removeComponents, removeFirstSlash, slugify } from '../../utils'
21+
import { removeComponents, removeFirstSlash, slugify, takeIf } from '../../utils'
2222
import { getOperationBasePath } from './rest.utils'
2323
import type * as TYPE from './rest.types'
2424
import { HASH_FLAG, INLINE_REFS_FLAG, MESSAGE_SEVERITY, NORMALIZE_OPTIONS, ORIGINS_SYMBOL } from '../../consts'
@@ -37,6 +37,18 @@ export const buildRestOperations: OperationsBuilder<OpenAPIV3.Document> = async
3737
originsFlag: ORIGINS_SYMBOL,
3838
hashFlag: HASH_FLAG,
3939
source: document.data,
40+
...takeIf({
41+
onRefResolveError: (message: string, path: PropertyKey[], ref: string) => {
42+
// console.debug([
43+
// '[Ref Resolve Error]',
44+
// `Message: ${message}`,
45+
// `JSON path: ${path}`,
46+
// `Ref: ${ref}`,
47+
// ].join('\n'))
48+
// todo is this message enough? (ErrorMessage.refNotFound)
49+
throw new Error(message)
50+
},
51+
}, !!ctx.config.strictValidation),
4052
},
4153
) as OpenAPIV3.Document
4254
const refsOnlyDocument = normalize(

src/builder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export class PackageVersionBuilder implements IPackageVersionBuilder {
9090

9191
constructor(config: BuildConfig, public params: BuilderParams, fileSources?: FileSourceMap) {
9292
this.apiBuilders.push(restApiBuilder, graphqlApiBuilder, textApiBuilder, unknownApiBuilder)
93-
this.config = { previousVersion: '', previousVersionPackageId: '', ...config }
93+
this.config = { previousVersion: '', previousVersionPackageId: '', strictValidation: true, ...config }
9494

9595
this.params.configuration = {
9696
batchSize: DEFAULT_BATCH_SIZE,

src/types/external/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ export interface BuildConfig {
4848

4949
metadata?: Record<string, unknown>
5050
format?: OperationsGroupExportFormat
51+
52+
strictValidation?: boolean
5153
}
5254

5355
export interface BuildConfigFile {

test/bundle-dependencies.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { LocalRegistry } from './helpers'
2+
3+
describe('Bundle dependencies test', () => {
4+
test('components external dependencies should be bundled', async () => {
5+
const pkg = LocalRegistry.openPackage('bundle-dependencies/case1')
6+
const result = await pkg.publish(pkg.packageId, { packageId: pkg.packageId })
7+
8+
expect(result.documents.get('main.yaml')?.dependencies).toEqual(['dependency.yaml'])
9+
})
10+
11+
// todo test transitive deps bundling (unknown document)
12+
13+
test('should throw on invalid ref', async () => {
14+
const pkg = LocalRegistry.openPackage('bundle-dependencies/case2')
15+
16+
await expect(pkg.publish(pkg.packageId)).rejects.toThrowError(/\$ref can't be resolved/)
17+
})
18+
19+
test('should not throw on invalid ref', async () => {
20+
const pkg = LocalRegistry.openPackage('bundle-dependencies/case2')
21+
const result = await pkg.publish(pkg.packageId, {
22+
packageId: pkg.packageId,
23+
strictValidation: false,
24+
})
25+
26+
expect(result.documents.get('main.yaml')?.dependencies.length).toBe(0)
27+
})
28+
})

test/helpers/registry/local.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ export class LocalRegistry implements IRegistry {
319319
return null
320320
}
321321

322-
async publish(projectId: string, publishParams?: Partial<BuildConfig>): Promise<void> {
322+
async publish(projectId: string, publishParams?: Partial<BuildConfig>): Promise<BuildResult> {
323323
const loadedConfig = await loadConfig(this.projectsDir, projectId) as BuildConfig
324324
const versionConfig = {
325325
...loadedConfig,
@@ -336,6 +336,8 @@ export class LocalRegistry implements IRegistry {
336336
const buildResult = await builder.run()
337337

338338
await this.publishPackage(buildResult, builder.builderContext(versionConfig), versionConfig)
339+
340+
return buildResult
339341
}
340342

341343
async publishPackage(
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"packageId": "bundle-dependencies",
3+
"apiType": "rest",
4+
"version": "v1",
5+
"files": [
6+
{
7+
"fileId": "dependency.yaml",
8+
"publish": true,
9+
"labels": [],
10+
"commitId": "6c778b1f44200bd19944a6a8eac10a4e5a21a1cd"
11+
},
12+
{
13+
"fileId": "main.yaml",
14+
"publish": true,
15+
"labels": [],
16+
"commitId": "6c778b1f44200bd19944a6a8eac10a4e5a21a1xd"
17+
}
18+
]
19+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
User:
2+
type: object
3+
properties:
4+
id:
5+
type: integer
6+
name:
7+
type: string
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
openapi: 3.0.1
2+
info:
3+
title: API
4+
version: 1.0.0
5+
paths:
6+
/users:
7+
get:
8+
responses:
9+
'200':
10+
description: description
11+
content:
12+
application/json:
13+
schema:
14+
type: array
15+
items:
16+
$ref: './dependency.yaml#/User'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"packageId": "bundle-dependencies",
3+
"apiType": "rest",
4+
"version": "v1",
5+
"files": [
6+
{
7+
"fileId": "dependency.yaml",
8+
"publish": true,
9+
"labels": [],
10+
"commitId": "6c778b1f44200bd19944a6a8eac10a4e5a21a1cd"
11+
},
12+
{
13+
"fileId": "main.yaml",
14+
"publish": true,
15+
"labels": [],
16+
"commitId": "6c778b1f44200bd19944a6a8eac10a4e5a21a1xd"
17+
}
18+
]
19+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
User:
2+
type: object
3+
properties:
4+
id:
5+
type: integer
6+
name:
7+
type: string

0 commit comments

Comments
 (0)