Skip to content

Commit 865fcf6

Browse files
authored
fix: getReferenceSchema for names with '.' chars (#141)
* fix: getReferenceSchema fo names with '.' chars * add getReferenceSchema tests * cleanup unused import in test
1 parent 6e34b24 commit 865fcf6

File tree

4 files changed

+126
-15
lines changed

4 files changed

+126
-15
lines changed

.all-contributorsrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@
9191
"contributions": [
9292
"code"
9393
]
94+
},
95+
{
96+
"login": "ci-vamp",
97+
"name": "ci-vamp",
98+
"avatar_url": "https://avatars.githubusercontent.com/u/116516277?v=4",
99+
"profile": "https://github.com/ci-vamp",
100+
"contributions": [
101+
"bug",
102+
"code"
103+
]
94104
}
95105
],
96106
"contributorsPerLine": 7

README.md

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -216,20 +216,19 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
216216
<!-- prettier-ignore-start -->
217217
<!-- markdownlint-disable -->
218218
<table>
219-
<tbody>
220-
<tr>
221-
<td align="center"><a href="https://fabien0102.com/"><img src="https://avatars.githubusercontent.com/u/1761469?v=4?s=100" width="100px;" alt="Fabien BERNARD"/><br /><sub><b>Fabien BERNARD</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=fabien0102" title="Code">💻</a> <a href="#design-fabien0102" title="Design">🎨</a> <a href="https://github.com/fabien0102/openapi-codegen/commits?author=fabien0102" title="Documentation">📖</a> <a href="#ideas-fabien0102" title="Ideas, Planning, & Feedback">🤔</a> <a href="#projectManagement-fabien0102" title="Project Management">📆</a> <a href="https://github.com/fabien0102/openapi-codegen/pulls?q=is%3Apr+reviewed-by%3Afabien0102" title="Reviewed Pull Requests">👀</a></td>
222-
<td align="center"><a href="https://github.com/mpotomin"><img src="https://avatars.githubusercontent.com/u/639406?v=4?s=100" width="100px;" alt="mpotomin"/><br /><sub><b>mpotomin</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=mpotomin" title="Code">💻</a> <a href="#ideas-mpotomin" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/fabien0102/openapi-codegen/pulls?q=is%3Apr+reviewed-by%3Ampotomin" title="Reviewed Pull Requests">👀</a></td>
223-
<td align="center"><a href="https://github.com/micha-f"><img src="https://avatars.githubusercontent.com/u/200647?v=4?s=100" width="100px;" alt="Michael Franzkowiak"/><br /><sub><b>Michael Franzkowiak</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=micha-f" title="Documentation">📖</a></td>
224-
<td align="center"><a href="https://github.com/SferaDev"><img src="https://avatars.githubusercontent.com/u/2181866?v=4?s=100" width="100px;" alt="Alexis Rico"/><br /><sub><b>Alexis Rico</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=SferaDev" title="Code">💻</a> <a href="#ideas-SferaDev" title="Ideas, Planning, & Feedback">🤔</a></td>
225-
<td align="center"><a href="https://ned.im/"><img src="https://avatars.githubusercontent.com/u/271912?v=4?s=100" width="100px;" alt="Nedim Arabacı"/><br /><sub><b>Nedim Arabacı</b></sub></a><br /><a href="#question-needim" title="Answering Questions">💬</a> <a href="https://github.com/fabien0102/openapi-codegen/commits?author=needim" title="Code">💻</a> <a href="#ideas-needim" title="Ideas, Planning, & Feedback">🤔</a></td>
226-
<td align="center"><a href="https://github.com/antoniel"><img src="https://avatars.githubusercontent.com/u/17225358?v=4?s=100" width="100px;" alt="Antoniel Magalhães"/><br /><sub><b>Antoniel Magalhães</b></sub></a><br /><a href="#example-antoniel" title="Examples">💡</a></td>
227-
<td align="center"><a href="https://github.com/DreierF"><img src="https://avatars.githubusercontent.com/u/5631865?v=4?s=100" width="100px;" alt="Florian Dreier"/><br /><sub><b>Florian Dreier</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=DreierF" title="Code">💻</a></td>
228-
</tr>
229-
<tr>
230-
<td align="center"><a href="https://fabianalthaus.de"><img src="https://avatars.githubusercontent.com/u/2795534?v=4?s=100" width="100px;" alt="Fabian Althaus [el-j]"/><br /><sub><b>Fabian Althaus [el-j]</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=el-j" title="Code">💻</a></td>
231-
</tr>
232-
</tbody>
219+
<tr>
220+
<td align="center"><a href="https://fabien0102.com/"><img src="https://avatars.githubusercontent.com/u/1761469?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fabien BERNARD</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=fabien0102" title="Code">💻</a> <a href="#design-fabien0102" title="Design">🎨</a> <a href="https://github.com/fabien0102/openapi-codegen/commits?author=fabien0102" title="Documentation">📖</a> <a href="#ideas-fabien0102" title="Ideas, Planning, & Feedback">🤔</a> <a href="#projectManagement-fabien0102" title="Project Management">📆</a> <a href="https://github.com/fabien0102/openapi-codegen/pulls?q=is%3Apr+reviewed-by%3Afabien0102" title="Reviewed Pull Requests">👀</a></td>
221+
<td align="center"><a href="https://github.com/mpotomin"><img src="https://avatars.githubusercontent.com/u/639406?v=4?s=100" width="100px;" alt=""/><br /><sub><b>mpotomin</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=mpotomin" title="Code">💻</a> <a href="#ideas-mpotomin" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/fabien0102/openapi-codegen/pulls?q=is%3Apr+reviewed-by%3Ampotomin" title="Reviewed Pull Requests">👀</a></td>
222+
<td align="center"><a href="https://github.com/micha-f"><img src="https://avatars.githubusercontent.com/u/200647?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Franzkowiak</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=micha-f" title="Documentation">📖</a></td>
223+
<td align="center"><a href="https://github.com/SferaDev"><img src="https://avatars.githubusercontent.com/u/2181866?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alexis Rico</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=SferaDev" title="Code">💻</a> <a href="#ideas-SferaDev" title="Ideas, Planning, & Feedback">🤔</a></td>
224+
<td align="center"><a href="https://ned.im/"><img src="https://avatars.githubusercontent.com/u/271912?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nedim Arabacı</b></sub></a><br /><a href="#question-needim" title="Answering Questions">💬</a> <a href="https://github.com/fabien0102/openapi-codegen/commits?author=needim" title="Code">💻</a> <a href="#ideas-needim" title="Ideas, Planning, & Feedback">🤔</a></td>
225+
<td align="center"><a href="https://github.com/antoniel"><img src="https://avatars.githubusercontent.com/u/17225358?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Antoniel Magalhães</b></sub></a><br /><a href="#example-antoniel" title="Examples">💡</a></td>
226+
<td align="center"><a href="https://github.com/DreierF"><img src="https://avatars.githubusercontent.com/u/5631865?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Florian Dreier</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=DreierF" title="Code">💻</a></td>
227+
</tr>
228+
<tr>
229+
<td align="center"><a href="http://fabianalthaus.de"><img src="https://avatars.githubusercontent.com/u/2795534?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fabian Althaus</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/commits?author=el-j" title="Code">💻</a></td>
230+
<td align="center"><a href="https://github.com/ci-vamp"><img src="https://avatars.githubusercontent.com/u/116516277?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ci-vamp</b></sub></a><br /><a href="https://github.com/fabien0102/openapi-codegen/issues?q=author%3Aci-vamp" title="Bug reports">🐛</a> <a href="https://github.com/fabien0102/openapi-codegen/commits?author=ci-vamp" title="Code">💻</a></td>
231+
</tr>
233232
</table>
234233

235234
<!-- markdownlint-restore -->
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { getReferenceSchema } from "./getReferenceSchema";
2+
3+
import type { OpenAPIObject, SchemasObject } from "openapi3-ts";
4+
5+
type OpenAPIDocWithComponents = Pick<OpenAPIObject, "components">;
6+
7+
const schemas: SchemasObject = {
8+
"Pet": {
9+
"type": "object",
10+
"description": "Pet",
11+
"required": [
12+
"id",
13+
"name"
14+
],
15+
"properties": {
16+
"id": {
17+
"type": "integer",
18+
"format": "int64"
19+
},
20+
"name": {
21+
"type": "string"
22+
},
23+
"tag": {
24+
"type": "string"
25+
}
26+
}
27+
},
28+
"Pet.With.Dot": {
29+
"type": "object",
30+
"description": "Pet.With.Dot",
31+
"required": [
32+
"id",
33+
"name"
34+
],
35+
"properties": {
36+
"id": {
37+
"type": "integer",
38+
"format": "int64"
39+
},
40+
"name": {
41+
"type": "string"
42+
},
43+
"tag": {
44+
"type": "string"
45+
}
46+
}
47+
},
48+
"PetRef": {
49+
$ref: "#/components/schemas/Pet"
50+
},
51+
};
52+
53+
const document: OpenAPIDocWithComponents = {
54+
components: {
55+
schemas
56+
}
57+
};
58+
59+
const base$Ref = "#/components/schemas";
60+
61+
describe('getReferenceSchema', () => {
62+
it('should return the SchemaObject from $ref with a nested leaf path', () => {
63+
const $ref = `${base$Ref}/Pet`;
64+
const schema = getReferenceSchema($ref, document);
65+
expect(schema).toBeDefined();
66+
expect(schema.description).toBe(schemas.Pet.description);
67+
});
68+
69+
it('should return the SchemaObject from $ref with a dot-separated leaf path', () => {
70+
const $ref = `${base$Ref}/Pet.With.Dot`;
71+
const schema = getReferenceSchema($ref, document);
72+
expect(schema).toBeDefined();
73+
expect(schema.description).toBe(schemas['Pet.With.Dot'].description);
74+
});
75+
76+
it('should throw an Error if the $ref cannot be found', () => {
77+
const $ref = `${base$Ref}/does/not/exist`;
78+
expect(() => getReferenceSchema($ref, document)).toThrowError(new RegExp($ref, 'g'));
79+
});
80+
81+
it("should resolve the schema if the $ref has a nested $ref", () => {
82+
const $ref = `${base$Ref}/PetRef`;
83+
const schema = getReferenceSchema($ref, document);
84+
expect(schema).toBeDefined();
85+
expect(schema.description).toBe(schemas.Pet.description);
86+
});
87+
88+
it("should throw an error if he resulting schema is not a valid SchemaObject", () => {
89+
// TODO: not sure how to produce this scenario
90+
});
91+
});

plugins/typescript/src/core/getReferenceSchema.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,19 @@ export const getReferenceSchema = (
2121
if (hash !== "#") {
2222
throw new Error("This library only resolve local $ref");
2323
}
24-
const referenceSchema = get(openAPIDocument, refPath.join("."));
2524

25+
// NOTE: this is a fix for schema names that have '.' characters in them
26+
// if passed directly to lodash.get they are treated as path traversals instead of a literal schema name
27+
28+
// get the last element of the refPath, [0] = 'components', [1] = 'schemas'
29+
const directSchemaName = refPath.at(-1);
30+
// try a direct access of the name from the schemas object
31+
const defaultDirectSearch = openAPIDocument.components?.schemas && openAPIDocument.components.schemas[directSchemaName!];
32+
33+
// try to perform the typical ref path search but use the direct search as a fallback
34+
const referenceSchema = get(openAPIDocument, refPath.join("."), defaultDirectSearch);
35+
36+
// if neither ref path nor direct search find the schema then throw that the ref cant be found
2637
if (!referenceSchema) {
2738
throw new Error(`${$ref} not found!`);
2839
}

0 commit comments

Comments
 (0)