diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..1a158fb --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Jest Tests", + "type": "node", + "request": "launch", + "runtimeArgs": [ + "--inspect-brk", + "${workspaceRoot}/node_modules/.bin/jest", + "--runInBand" + ], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "port": 9229 + } + ] +} diff --git a/test/transforms/components/index.test.js b/test/transforms/components/index.test.js index 633a960..d2bb6e4 100644 --- a/test/transforms/components/index.test.js +++ b/test/transforms/components/index.test.js @@ -909,4 +909,30 @@ describe('parseComponents method', () => { const result = parseComponents({}, parsedJSDocs); expect(result).toEqual(expected); }); + + it('Should parse jsdoc component spec record type', () => { + const jsodInput = [` + /** + * Records dict + * @typedef {Dictionary} Records map + */ + `]; + const expected = { + components: { + schemas: { + Records: { + type: 'object', + description: 'Records dict', + properties: {}, + additionalProperties: { + type: 'string', + }, + }, + }, + }, + }; + const parsedJSDocs = jsdocInfo()(jsodInput); + const result = parseComponents({}, parsedJSDocs); + expect(result).toEqual(expected); + }); }); diff --git a/transforms/components/index.js b/transforms/components/index.js index ecbe66f..174b342 100644 --- a/transforms/components/index.js +++ b/transforms/components/index.js @@ -4,6 +4,7 @@ const { refSchema, formatRefSchema } = require('../utils/refSchema'); const addEnumValues = require('../utils/enumValues'); const formatDescription = require('../utils/formatDescription'); const combineSchema = require('../utils/combineSchema'); +const validateTypes = require('../utils/validateTypes'); const REQUIRED = 'required'; @@ -65,15 +66,21 @@ const getRequiredProperties = properties => ( const formatRequiredProperties = requiredProperties => requiredProperties.map(getPropertyName); const addDictionaryAdditionalProperties = typedef => { - if (!typedef.type.expression || typedef.type.expression.name !== 'Dictionary') { - return {}; + if ( + typedef.type.expression + && typedef.type.expression.name === 'Dictionary' + ) { + const typeName = typedef.type.applications[0].name; + const isPrimitive = validateTypes(typeName); + + return { + additionalProperties: { + ...(isPrimitive ? { type: typeName } : { $ref: `#/components/schemas/${typeName}` }), + }, + }; } - return { - additionalProperties: { - $ref: `#/components/schemas/${typedef.type.applications[0].name}`, - }, - }; + return {}; }; const parseSchema = (schema, options = {}) => {