Skip to content

Commit

Permalink
Release 1.6.3 (#40)
Browse files Browse the repository at this point in the history
* chore(ci/cd): slack notifications only when happens failure

* fix: 'nullable' property shouldn't be used as required property

* fix: problems of usage 'nullable' and 'required' properties; feat: parse type: 'null' schema components

Co-authored-by: svolkov <svolkov@everpoint.ru>
  • Loading branch information
js2me and js2me authored Mar 26, 2020
1 parent 2fdcf73 commit 6695576
Show file tree
Hide file tree
Showing 10 changed files with 253 additions and 72 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

language: node_js
node_js:
- "node"
Expand Down Expand Up @@ -26,5 +25,7 @@ jobs:

notifications:
slack:
on_success: never
on_failure: always
rooms:
secure: vOYvagXgEbjgwSJaK70QU574OcUq1MyqJYJp08wqcLA2AUfxrN3HJj24s2qd3NAMIU2Zw6jfEwQBbH3vV10cwf2u5Yp9pAgbrLOJCV+1wixMJL6GxWLesbtUuizoOCEL+f5qogFPNpy4W2FDcG0DEYwuhLSdf5qToGXP5BSn3VPuvZYRhKRq9wJpeXNTLbu+XW8hEkuUpjbr2zzm+k8pCggONGVQ5SCSCI5DVHsCnsxzumwNcKbNitLiRMQKRJiFCOQ4YQwpZ7SCEu75YxMjb+UDIEYi5CtxgxCRaoBZfYj/uI4exxavmb0/vp5CJ1dTUNmI2R3pTQUIERoFXajl479FMnxhGsKycVG7O2hKqxNCDT8tPAzxdMaF31u7AtWajdZpmOLyAIc/RjUAJfuSlzT3hcSfZUQ23VOcf8Q/yJXVT6XqYPuEO8xhVXdCJN4PtDowjzeoMqZCTSmknrPcKGfvuY86rw5aIFngYy1TysR8fhDgpxqTmsrG2HOrVzmq4oLsEsm6jGqghvLM3x03HOxX6pdo/lDoaTl1lR0ZraC1tGvGQpb1M38GxNpWFmmqb0A7Q9aHK4OBddvEMEU1nivb2t41DQou3ga+czm8vo1o0cEXOczDQmCQhOrPn0/m5ud49rzMLfxhXQbT4fphuNAAbumn2dc2eKc3ZB3w4ng=
secure: vOYvagXgEbjgwSJaK70QU574OcUq1MyqJYJp08wqcLA2AUfxrN3HJj24s2qd3NAMIU2Zw6jfEwQBbH3vV10cwf2u5Yp9pAgbrLOJCV+1wixMJL6GxWLesbtUuizoOCEL+f5qogFPNpy4W2FDcG0DEYwuhLSdf5qToGXP5BSn3VPuvZYRhKRq9wJpeXNTLbu+XW8hEkuUpjbr2zzm+k8pCggONGVQ5SCSCI5DVHsCnsxzumwNcKbNitLiRMQKRJiFCOQ4YQwpZ7SCEu75YxMjb+UDIEYi5CtxgxCRaoBZfYj/uI4exxavmb0/vp5CJ1dTUNmI2R3pTQUIERoFXajl479FMnxhGsKycVG7O2hKqxNCDT8tPAzxdMaF31u7AtWajdZpmOLyAIc/RjUAJfuSlzT3hcSfZUQ23VOcf8Q/yJXVT6XqYPuEO8xhVXdCJN4PtDowjzeoMqZCTSmknrPcKGfvuY86rw5aIFngYy1TysR8fhDgpxqTmsrG2HOrVzmq4oLsEsm6jGqghvLM3x03HOxX6pdo/lDoaTl1lR0ZraC1tGvGQpb1M38GxNpWFmmqb0A7Q9aHK4OBddvEMEU1nivb2t41DQou3ga+czm8vo1o0cEXOczDQmCQhOrPn0/m5ud49rzMLfxhXQbT4fphuNAAbumn2dc2eKc3ZB3w4ng=
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# next release

# 1.6.3

Fixes:

- Handling of nullable for $ref in OpenAPI 3.0 ([issue](https://github.com/acacode/swagger-typescript-api/issues/39))
Plus based on this issue was fixed most other problems with using `required` and `nullable` properties


# 1.6.2

Fixes:
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "swagger-typescript-api",
"version": "1.6.2",
"version": "1.6.3",
"description": "Create typescript api module from swagger schema",
"scripts": {
"cli": "node index.js -d -p ./swagger-test-cli.json -n swagger-test-cli.ts",
Expand Down
12 changes: 7 additions & 5 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

const config = {
/** CLI flag */
generateResponses: false,
Expand All @@ -8,14 +7,17 @@ const config = {
generateRouteTypes: false,
/** CLI flag */
generateClient: true,
/** parsed swagger schema from getSwaggerObject() */
/** parsed swagger schema from getSwaggerObject() */

swaggerSchema: null,
/** { "#/components/schemas/Foo": @TypeInfo, ... } */
componentsMap: {},
}
/** flag for catching convertion from swagger 2.0 */
convertedFromSwagger2: false,
};

/** needs to use data everywhere in project */
module.exports = {
addToConfig: configParts => Object.assign(config, configParts),
addToConfig: (configParts) => Object.assign(config, configParts),
config,
}
};
20 changes: 10 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ const { getModelType } = require("./modelTypes");
const { getSwaggerObject } = require("./swagger");
const { createComponentsMap, filterComponentsMap } = require("./components");
const { getTemplate, createFile, pathIsExist } = require("./files");
const { addToConfig, config: defaults } = require("./config");
const { addToConfig, config } = require("./config");

mustache.escape = value => value;
mustache.escape = (value) => value;

const prettierConfig = {
printWidth: 120,
Expand All @@ -33,10 +33,10 @@ module.exports = {
output,
url,
name,
generateResponses = defaults.generateResponses,
defaultResponseAsSuccess = defaults.defaultResponseAsSuccess,
generateRouteTypes = defaults.generateRouteTypes,
generateClient = defaults.generateClient,
generateResponses = config.generateResponses,
defaultResponseAsSuccess = config.defaultResponseAsSuccess,
generateRouteTypes = config.generateRouteTypes,
generateClient = config.generateClient,
}) =>
new Promise((resolve, reject) => {
addToConfig({
Expand All @@ -46,7 +46,7 @@ module.exports = {
generateResponses,
});
getSwaggerObject(input, url)
.then(swaggerSchema => {
.then((swaggerSchema) => {
console.log("☄️ start generating your typescript api");

addToConfig({ swaggerSchema });
Expand All @@ -62,8 +62,8 @@ module.exports = {

const parsedSchemas = parseSchemas(components);
const routes = parseRoutes(swaggerSchema, parsedSchemas, componentsMap, components);
const hasSecurityRoutes = routes.some(route => route.security);
const hasQueryRoutes = routes.some(route => route.hasQuery);
const hasSecurityRoutes = routes.some((route) => route.security);
const hasQueryRoutes = routes.some((route) => route.hasQuery);
const apiConfig = createApiConfig({ info, servers }, hasSecurityRoutes);

const configuration = {
Expand Down Expand Up @@ -91,7 +91,7 @@ module.exports = {

resolve(sourceFile);
})
.catch(e => {
.catch((e) => {
reject(e);
throw new Error("Swagger schema parse error!\r\n " + e);
});
Expand Down
42 changes: 26 additions & 16 deletions src/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,21 @@ const findSchemaType = (schema) => {
return "primitive";
};

const nullableExtras = (schema, value) => {
const { nullable, type } = schema || {};
return nullable || type === "null" ? `${value} | null` : value;
};

const getPrimitiveType = (property) => {
const { type, nullable } = property || {};
const { type } = property || {};
const primitiveType = typeAliases[type] || type;
return primitiveType
? (nullable && `${primitiveType} | null`) || primitiveType
: DEFAULT_PRIMITIVE_TYPE;
return primitiveType ? nullableExtras(property, primitiveType) : DEFAULT_PRIMITIVE_TYPE;
};

const specificObjectTypes = {
array: ({ items }) => {
array: ({ items, ...schemaPart }) => {
const { content, type } = parseSchema(items, null, inlineExtraFormatters);
return type === "primitive" ? `${content}[]` : `Array<${content}>`;
return nullableExtras(schemaPart, type === "primitive" ? `${content}[]` : `Array<${content}>`);
},
};

Expand All @@ -48,14 +51,17 @@ const getType = (property) => {
if (!property) return DEFAULT_PRIMITIVE_TYPE;

const anotherTypeGetter = specificObjectTypes[property.type] || getPrimitiveType;
return getRefTypeName(property) || anotherTypeGetter(property);
const refType = getRefTypeName(property);
return refType ? nullableExtras(property, refType) : anotherTypeGetter(property);
};

const getObjectTypeContent = (properties) => {
return _.map(properties, (property, name) => {
// TODO: probably nullable should'n be use as required/no-required conditions
const isRequired =
typeof property.nullable === "undefined" ? property.required : !property.nullable;
const isRequired = config.convertedFromSwagger2
? typeof property.nullable === "undefined"
? property.required
: !property.nullable
: !!property.required;
return {
description: property.description,
isRequired,
Expand All @@ -72,16 +78,21 @@ const complexSchemaParsers = {
oneOf: (schema) => {
// T1 | T2
const combined = _.map(schema.oneOf, complexTypeGetter);
return combined.join(" | ");
return nullableExtras(schema, combined.join(" | "));
},
allOf: (schema) => {
// T1 & T2
return _.map(schema.allOf, complexTypeGetter).join(" & ");
return nullableExtras(schema, _.map(schema.allOf, complexTypeGetter).join(" & "));
},
anyOf: (schema) => {
// T1 | T2 | (T1 & T2)
const combined = _.map(schema.anyOf, complexTypeGetter);
return `${combined.join(" | ")}` + (combined.length > 1 ? ` | (${combined.join(" & ")})` : "");
const nonEmptyTypesCombined = combined.filter((type) => !jsEmptyTypes.includes(type));
return nullableExtras(
schema,
`${combined.join(" | ")}` +
(nonEmptyTypesCombined.length > 1 ? ` | (${nonEmptyTypesCombined.join(" & ")})` : ""),
);
},
// TODO
not: (schema) => {
Expand Down Expand Up @@ -170,7 +181,8 @@ const schemaParsers = {
typeIdentifier: "type",
name: typeName,
description: formatDescription(description),
content: contentType || getType(schema),
// TODO: probably it should be refactored. `type === 'null'` is not flexible
content: type === "null" ? type : contentType || getType(schema),
};
},
};
Expand All @@ -191,12 +203,10 @@ const parseSchema = (rawSchema, typeName, formattersMap) => {
let parsedSchema = null;

if (typeof rawSchema === "string") {
console.log("WOW THERE IS STRING", rawSchema);
return rawSchema;
}

if (rawSchema.$parsedSchema) {
console.log("IT IS ALREADY PARSED SCHEMA", rawSchema);
schemaType = rawSchema.schemaType;
parsedSchema = rawSchema;
} else {
Expand Down
85 changes: 48 additions & 37 deletions src/swagger.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const _ = require('lodash');
const yaml = require('js-yaml');
const _ = require("lodash");
const yaml = require("js-yaml");
const axios = require("axios");
const converter = require('swagger2openapi');
const converter = require("swagger2openapi");
const { addToConfig } = require("./config");
const { pathIsExist, getFileContent } = require("./files");

const parseSwaggerFile = (file) => {
Expand All @@ -10,44 +11,54 @@ const parseSwaggerFile = (file) => {
try {
return JSON.parse(file);
} catch (e) {
return yaml.safeLoad(file)
return yaml.safeLoad(file);
}
}
};

const getSwaggerFile = (pathToSwagger, urlToSwagger) => new Promise((resolve) => {
if (pathIsExist(pathToSwagger)){
console.log(`✨ try to get swagger by path "${pathToSwagger}"`)
resolve(getFileContent(pathToSwagger))
} else {
console.log(`✨ try to get swagger by url "${urlToSwagger}"`)
axios.get(urlToSwagger).then(res => resolve(res.data))
}
})
const getSwaggerFile = (pathToSwagger, urlToSwagger) =>
new Promise((resolve) => {
if (pathIsExist(pathToSwagger)) {
console.log(`✨ try to get swagger by path "${pathToSwagger}"`);
resolve(getFileContent(pathToSwagger));
} else {
console.log(`✨ try to get swagger by url "${urlToSwagger}"`);
axios.get(urlToSwagger).then((res) => resolve(res.data));
}
});

const getSwaggerObject = (pathToSwagger, urlToSwagger) =>
new Promise(resolve =>
getSwaggerFile(pathToSwagger, urlToSwagger).then(file => {
const swaggerSchema = parseSwaggerFile(file);
if (!(swaggerSchema.openapi)) {
converter.convertObj(swaggerSchema, {
warnOnly: true,
refSiblings: 'preserve',
rbname: "requestBodyName",
}, function(err, options){
const swaggerSchema = _.get(err, 'options.openapi', _.get(options, 'openapi'))
if (!swaggerSchema && err) {
throw new Error(err)
}
resolve(swaggerSchema)
});
} else {
resolve(swaggerSchema)
}
}).catch(e => {
throw new Error(e)
})
)
new Promise((resolve) =>
getSwaggerFile(pathToSwagger, urlToSwagger)
.then((file) => {
const swaggerSchema = parseSwaggerFile(file);
if (!swaggerSchema.openapi) {
converter.convertObj(
swaggerSchema,
{
warnOnly: true,
refSiblings: "preserve",
rbname: "requestBodyName",
},
function (err, options) {
const swaggerSchema = _.get(err, "options.openapi", _.get(options, "openapi"));
if (!swaggerSchema && err) {
throw new Error(err);
}
addToConfig({
convertedFromSwagger2: true,
});
resolve(swaggerSchema);
},
);
} else {
resolve(swaggerSchema);
}
})
.catch((e) => {
throw new Error(e);
}),
);

module.exports = {
getSwaggerObject,
}
};
Loading

0 comments on commit 6695576

Please sign in to comment.