@penkov/swagger-code-gen 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,6 +13,9 @@ generate-client --url <URI> output_filename.ts
13
13
  ```
14
14
 
15
15
  Cli parameters:
16
- * `--url` - the swagger url
16
+ * `--url <URI>` - the swagger url
17
+ * `--referencedObjectsNullableByDefault` - then specified, the generated code will assume that
18
+ any object's field, that references another object, can be null, unless it is explicitly specified to be not nullable
19
+ (which is default in .net world: asp generates wrong spec)
17
20
  * `--enableScats` - generate additional wrappers in [scats](https://www.npmjs.com/package/scats)
18
21
  style for all objects and create a service with methods for each endpoint.
package/dist/cli.mjs CHANGED
@@ -7,11 +7,15 @@ program
7
7
  .description('CLI to generate client based on swagger definitions')
8
8
  .version('1.0.0')
9
9
  .option('--url <URI>', 'The url with swagger definitions')
10
+ .option('--referencedObjectsNullableByDefault', 'Assume that referenced objects can be null (say hello to .net assholes)', false)
10
11
  .option('--enableScats', 'Generate scats', false)
11
12
  .argument('outputFile', 'File with generated code')
12
13
  .parse();
13
14
  const url = program.opts().url;
15
+ const referencedObjectsNullableByDefault = program.opts().referencedObjectsNullableByDefault;
14
16
  const enableScats = program.opts().enableScats;
15
17
  const outputFile = program.args[0];
16
- main(url, enableScats, outputFile).then(() => {
18
+ main(url, enableScats, outputFile, {
19
+ referencedObjectsNullableByDefault: referencedObjectsNullableByDefault
20
+ }).then(() => {
17
21
  });
@@ -6,16 +6,16 @@ export function resolveSchemasTypes(json) {
6
6
  const schemasNames = Collection.from(Object.keys(jsonSchemas));
7
7
  return schemasNames.toMap(name => [name, SchemaFactory.resolveSchemaType(jsonSchemas[name])]);
8
8
  }
9
- export function resolveSchemas(json, schemasTypes) {
9
+ export function resolveSchemas(json, schemasTypes, options) {
10
10
  const jsonSchemas = json.components.schemas;
11
11
  const schemasNames = Collection.from(Object.keys(jsonSchemas));
12
12
  return schemasNames
13
- .toMap(name => [name, SchemaFactory.build(name, jsonSchemas[name], schemasTypes)]);
13
+ .toMap(name => [name, SchemaFactory.build(name, jsonSchemas[name], schemasTypes, options)]);
14
14
  }
15
- export function resolvePaths(json, schemasTypes) {
15
+ export function resolvePaths(json, schemasTypes, options) {
16
16
  const jsonSchemas = json.paths;
17
17
  return Collection.from(Object.keys(jsonSchemas)).flatMap(path => {
18
18
  const methods = jsonSchemas[path];
19
- return Collection.from(Object.keys(methods)).map(methodName => new Method(path, methodName, methods[methodName], schemasTypes));
19
+ return Collection.from(Object.keys(methods)).map(methodName => new Method(path, methodName, methods[methodName], schemasTypes, options));
20
20
  });
21
21
  }
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'url';
6
6
  import { dirname } from 'path';
7
7
  const __filename = fileURLToPath(import.meta.url);
8
8
  const __dirname = dirname(__filename);
9
- export async function main(url, enableScats, outputFile) {
9
+ export async function main(url, enableScats, outputFile, options) {
10
10
  const { configure, getLogger } = log4js;
11
11
  configure(`${__dirname}/../config/log4js.json`);
12
12
  const logger = getLogger('Generator');
@@ -16,8 +16,8 @@ export async function main(url, enableScats, outputFile) {
16
16
  .then(res => res.json())
17
17
  .then(async (json) => {
18
18
  const schemasTypes = resolveSchemasTypes(json);
19
- const schemas = resolveSchemas(json, schemasTypes);
20
- const paths = resolvePaths(json, schemasTypes);
19
+ const schemas = resolveSchemas(json, schemasTypes, options);
20
+ const paths = resolvePaths(json, schemasTypes, options);
21
21
  logger.debug(`Downloaded swagger: ${schemas.size} schemas, ${paths.size} paths`);
22
22
  await renderer.renderToFile(schemas.values, paths, enableScats, outputFile);
23
23
  logger.debug(`Wrote client to ${outputFile}`);
package/dist/method.js CHANGED
@@ -4,13 +4,13 @@ import { Parameter } from './parameter.js';
4
4
  import { SchemaFactory } from './schemas.js';
5
5
  const sortByIn = HashMap.of(['path', 0], ['query', 1], ['header', 2], ['body', 3]);
6
6
  export class Method {
7
- constructor(path, method, def, schemasTypes) {
7
+ constructor(path, method, def, schemasTypes, options) {
8
8
  this.path = path;
9
9
  this.method = method;
10
10
  this.tags = option(def.tags).getOrElseValue([]);
11
11
  this.summary = def.summary;
12
12
  const parameters = Collection.from(def.parameters)
13
- .map(p => Parameter.fromDefinition(p, schemasTypes))
13
+ .map(p => Parameter.fromDefinition(p, schemasTypes, options))
14
14
  .sort((a, b) => {
15
15
  const r1 = a.required ? 1 : 0;
16
16
  const r2 = b.required ? 1 : 0;
@@ -39,7 +39,7 @@ export class Method {
39
39
  return mimeTypes
40
40
  .find(_ => _ === 'application/json')
41
41
  .orElseValue(mimeTypes.headOption)
42
- .map(mt => SchemaFactory.build('body', body[mt].schema, schemasTypes));
42
+ .map(mt => SchemaFactory.build('body', body[mt].schema, schemasTypes, options));
43
43
  });
44
44
  const statusCodes = Collection.from(Object.keys(def.responses))
45
45
  .map(x => parseInt(x));
@@ -51,14 +51,16 @@ export class Method {
51
51
  .map(content => Collection.from(Object.keys(content)).toMap(mimeType => [mimeType, content[mimeType]])).getOrElseValue(HashMap.empty);
52
52
  this.response = mimeTypes.get('application/json')
53
53
  .orElseValue(mimeTypes.values.headOption)
54
- .map(p => Property.fromDefinition('', p.schema, schemasTypes))
54
+ .map(p => Property.fromDefinition('', p.schema, schemasTypes, options).copy({
55
+ nullable: false
56
+ }))
55
57
  .map(r => ({
56
58
  asProperty: r,
57
59
  responseType: r.jsType,
58
60
  description: respDef.description
59
61
  }))
60
62
  .getOrElseValue(({
61
- asProperty: Property.fromDefinition('UNKNOWN', { type: 'any' }, schemasTypes),
63
+ asProperty: Property.fromDefinition('UNKNOWN', { type: 'any' }, schemasTypes, options),
62
64
  responseType: 'any'
63
65
  }));
64
66
  }
package/dist/parameter.js CHANGED
@@ -11,12 +11,12 @@ export class Parameter {
11
11
  this.description = description;
12
12
  this.in = inValue;
13
13
  }
14
- static fromDefinition(def, schemas) {
14
+ static fromDefinition(def, schemas, options) {
15
15
  const name = Parameter.toJSName(def.name);
16
16
  const inValue = def.in;
17
17
  const desc = option(def.description);
18
18
  const required = option(def.required).exists(identity);
19
- const schema = SchemaFactory.build(def.name, def.schema, schemas);
19
+ const schema = SchemaFactory.build(def.name, def.schema, schemas, options);
20
20
  let jsType;
21
21
  if (schema instanceof SchemaObject) {
22
22
  jsType = schema.type;
package/dist/property.js CHANGED
@@ -13,7 +13,10 @@ export class Property {
13
13
  this.itemReferencesObject = itemReferencesObject;
14
14
  this.schemaType = 'property';
15
15
  }
16
- static fromDefinition(name, definition, schemas) {
16
+ copy(p) {
17
+ return new Property(option(p.name).getOrElseValue(this.name), option(p.type).getOrElseValue(this.type), option(p.description).getOrElseValue(this.description), option(p.defaultValue).getOrElseValue(this.defaultValue), option(p.nullable).getOrElseValue(this.nullable), option(p.required).getOrElseValue(this.required), option(p.items).getOrElseValue(this.items), option(p.referencesObject).getOrElseValue(this.referencesObject), option(p.itemReferencesObject).getOrElseValue(this.itemReferencesObject));
18
+ }
19
+ static fromDefinition(name, definition, schemas, options) {
17
20
  const referencesObject = option(definition.$ref)
18
21
  .exists(ref => schemas.get(ref.substring(SCHEMA_PREFIX.length)).contains('object'));
19
22
  const itemReferencesObject = option(definition.items)
@@ -22,7 +25,8 @@ export class Property {
22
25
  const type = option(definition.$ref)
23
26
  .map(ref => ref.substring(SCHEMA_PREFIX.length))
24
27
  .getOrElseValue(definition.type);
25
- const nullable = option(definition.nullable).contains(true);
28
+ const nullable = option(definition.nullable).contains(true) ||
29
+ (referencesObject && options.referencedObjectsNullableByDefault && !option(definition.nullable).contains(false));
26
30
  const description = option(definition.description);
27
31
  const required = option(definition.required).contains(true);
28
32
  const items = option(definition.items?.$ref)
package/dist/schemas.js CHANGED
@@ -12,27 +12,27 @@ export class SchemaFactory {
12
12
  return 'property';
13
13
  }
14
14
  }
15
- static build(name, def, schemasTypes) {
15
+ static build(name, def, schemasTypes, options) {
16
16
  if (def.type === 'object') {
17
- return SchemaObject.fromDefinition(name, def, schemasTypes);
17
+ return SchemaObject.fromDefinition(name, def, schemasTypes, options);
18
18
  }
19
19
  else if (def.enum) {
20
20
  return SchemaEnum.fromDefinition(name, def);
21
21
  }
22
22
  else if (def.type === 'string') {
23
- return Property.fromDefinition(name, def, schemasTypes);
23
+ return Property.fromDefinition(name, def, schemasTypes, options);
24
24
  }
25
25
  else if (def.type === 'boolean') {
26
- return Property.fromDefinition(name, def, schemasTypes);
26
+ return Property.fromDefinition(name, def, schemasTypes, options);
27
27
  }
28
28
  else if (def.type === 'integer') {
29
- return Property.fromDefinition(name, def, schemasTypes);
29
+ return Property.fromDefinition(name, def, schemasTypes, options);
30
30
  }
31
31
  else if (def.type === 'array') {
32
- return Property.fromDefinition(name, def, schemasTypes);
32
+ return Property.fromDefinition(name, def, schemasTypes, options);
33
33
  }
34
34
  else {
35
- return Property.fromDefinition(name, def, schemasTypes);
35
+ return Property.fromDefinition(name, def, schemasTypes, options);
36
36
  }
37
37
  }
38
38
  }
@@ -56,8 +56,8 @@ export class SchemaObject {
56
56
  this.properties = properties;
57
57
  this.schemaType = 'object';
58
58
  }
59
- static fromDefinition(name, def, schemasTypes) {
60
- const properties = Collection.from(Object.keys(def.properties)).map(p => Property.fromDefinition(p, def.properties[p], schemasTypes));
59
+ static fromDefinition(name, def, schemasTypes, options) {
60
+ const properties = Collection.from(Object.keys(def.properties)).map(p => Property.fromDefinition(p, def.properties[p], schemasTypes, options));
61
61
  return new SchemaObject(name, def.title, def.type, properties);
62
62
  }
63
63
  }
@@ -15,7 +15,7 @@ export class <%= schema.name %>Dto {
15
15
  <%_ if (p.required || !p.nullable) { _%>
16
16
  <%- p.scatsWrapperType %>.fromJson(json.<%= p.name %>),
17
17
  <%_ } else { _%>
18
- option(json.<%= p.name %>).map(_ => <%- p.scatsWrapperType %>.fromJson(_)),
18
+ option(json.<%= p.name %>).map(_ => <%- p.type %>Dto.fromJson(_)),
19
19
  <%_ } _%>
20
20
  <%_ } else if (p.isArray) { _%>
21
21
  Collection.from(option(json.<%= p.name %>).getOrElseValue([]))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@penkov/swagger-code-gen",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "generate-client": "./dist/cli.mjs"