Skip to content

Commit 499e9f5

Browse files
authored
fix: add suffix to esm import (#35)
* fix(esm): add suffix to import * fix(modules): Change module resolution to node16 to prevent esm import errors, change types library * fix(nested-definitions): add definitions availability for nested definitions
1 parent eaab2be commit 499e9f5

File tree

5 files changed

+124
-15
lines changed

5 files changed

+124
-15
lines changed

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"dependencies": {
3737
"@apidevtools/json-schema-ref-parser": "^9.0.9",
3838
"json-schema-walker": "^0.0.4",
39+
"openapi-types": "^12.0.0",
3940
"yargs": "^17.5.1"
4041
},
4142
"devDependencies": {
@@ -48,10 +49,9 @@
4849
"eslint-plugin-prettier": "^4.2.1",
4950
"eslint-plugin-unused-imports": "^2.0.0",
5051
"nock": "^13.2.9",
51-
"openapi-typescript": "^5.4.1",
5252
"prettier": "^2.7.1",
5353
"typescript": "^4.7.4",
54-
"vitest": "^0.20.3"
54+
"vitest": "^0.21.0"
5555
},
5656
"prettier": {
5757
"singleQuote": true,

src/index.ts

+22-12
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import type {
66
} from 'json-schema';
77
import type { Options, SchemaType, SchemaTypeKeys } from './types';
88
import { Walker } from 'json-schema-walker';
9-
import { allowedKeywords } from './const';
10-
import type { OpenAPI3 } from 'openapi-typescript';
9+
import { allowedKeywords } from './const.js';
10+
import type { OpenAPIV3 } from 'openapi-types';
1111

1212
class InvalidTypeError extends Error {
1313
constructor(message: string) {
@@ -31,16 +31,26 @@ const handleDefinition = async <T>(
3131
if (type) {
3232
// Walk just the definitions types
3333
const walker = new Walker<T>();
34-
await walker.loadSchema({ ...def, $schema: schema['$schema'] } as any, {
35-
dereference: true,
36-
cloneSchema: true,
37-
dereferenceOptions: {
38-
dereference: {
39-
circular: 'ignore',
34+
await walker.loadSchema(
35+
{
36+
definitions: schema['definitions'] || [],
37+
...def,
38+
$schema: schema['$schema'],
39+
} as any,
40+
{
41+
dereference: true,
42+
cloneSchema: true,
43+
dereferenceOptions: {
44+
dereference: {
45+
circular: 'ignore',
46+
},
4047
},
41-
},
42-
});
48+
}
49+
);
4350
await walker.walk(convertSchema, walker.vocabularies.DRAFT_07);
51+
if ('definitions' in walker.rootSchema) {
52+
delete (<any>walker.rootSchema).definitions;
53+
}
4454
return walker.rootSchema;
4555
} else if (Array.isArray(def)) {
4656
// if it's an array, we might want to reconstruct the type;
@@ -62,7 +72,7 @@ const handleDefinition = async <T>(
6272
const convert = async <T = JSONSchema>(
6373
schema: T,
6474
options?: Options
65-
): Promise<OpenAPI3> => {
75+
): Promise<OpenAPIV3.Document> => {
6676
const walker = new Walker<T>();
6777
const convertDefs = options?.convertUnreferencedDefinitions ?? true;
6878
await walker.loadSchema(schema, options);
@@ -75,7 +85,7 @@ const convert = async <T = JSONSchema>(
7585
rootSchema.definitions[defName] = await handleDefinition(def, schema);
7686
}
7787
}
78-
return rootSchema as OpenAPI3;
88+
return rootSchema as OpenAPIV3.Document;
7989
};
8090

8191
function stripIllegalKeywords(schema: SchemaType) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Vitest Snapshot v1
2+
3+
exports[`throws an error when dereferecing fails 1`] = `
4+
{
5+
"additionalProperties": false,
6+
"definitions": {
7+
"configvariable": {
8+
"additionalProperties": false,
9+
"properties": {
10+
"default": {
11+
"type": "string",
12+
},
13+
"name": {
14+
"pattern": "^[A-Z_]+[A-Z0-9_]*$",
15+
"type": "string",
16+
},
17+
"required": {
18+
"default": true,
19+
"type": "boolean",
20+
},
21+
},
22+
"required": [
23+
"name",
24+
],
25+
"type": "object",
26+
},
27+
"envVarName": {
28+
"pattern": "^[A-Z_]+[A-Z0-9_]*$",
29+
"type": "string",
30+
},
31+
},
32+
"properties": {
33+
"componentId": {
34+
"pattern": "^(.*)$",
35+
"title": "The component id Schema",
36+
"type": "string",
37+
},
38+
"configurationTemplate": {
39+
"items": {
40+
"$ref": "#/definitions/configvariable",
41+
},
42+
"title": "The Configurationtemplate Schema",
43+
"type": "array",
44+
},
45+
},
46+
"required": [
47+
"componentId",
48+
],
49+
"title": "Component Manifest Schema",
50+
"type": "object",
51+
}
52+
`;

test/dereference_schema.test.ts

+47
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,50 @@ it('throws an error when dereferecing fails', async ({ expect }) => {
264264

265265
expect(error).have.property('ioErrorCode', 'ENOENT');
266266
});
267+
268+
it('throws an error when dereferecing fails', async ({ expect }) => {
269+
const schema = {
270+
definitions: {
271+
envVarName: {
272+
type: 'string',
273+
pattern: '^[A-Z_]+[A-Z0-9_]*$',
274+
},
275+
configvariable: {
276+
type: 'object',
277+
properties: {
278+
name: { $ref: '#/definitions/envVarName' },
279+
default: { type: 'string' },
280+
required: { type: 'boolean', default: true },
281+
},
282+
required: ['name'],
283+
additionalProperties: false,
284+
},
285+
},
286+
$schema: 'http://json-schema.org/draft-07/schema#',
287+
$id: 'http://example.com/root.json',
288+
type: 'object',
289+
title: 'Component Manifest Schema',
290+
required: ['componentId'],
291+
additionalProperties: false,
292+
properties: {
293+
componentId: {
294+
$id: '#/properties/componentId',
295+
type: 'string',
296+
title: 'The component id Schema',
297+
pattern: '^(.*)$',
298+
},
299+
configurationTemplate: {
300+
$id: '#/properties/configurationTemplate',
301+
type: 'array',
302+
title: 'The Configurationtemplate Schema',
303+
items: {
304+
$ref: '#/definitions/configvariable',
305+
},
306+
},
307+
},
308+
};
309+
310+
const result = await convert(schema);
311+
312+
expect(result).toMatchSnapshot();
313+
});

tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"lib": ["esnext"],
1313
"listEmittedFiles": false,
1414
"listFiles": false,
15-
"moduleResolution": "node",
15+
"moduleResolution": "node16",
1616
"noFallthroughCasesInSwitch": true,
1717
"pretty": true,
1818
"resolveJsonModule": true,

0 commit comments

Comments
 (0)