@kevinoid/openapi-transformers 0.1.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.
Files changed (50) hide show
  1. package/LICENSE.txt +19 -0
  2. package/README.md +134 -0
  3. package/add-tag-to-operation-ids.js +60 -0
  4. package/add-x-ms-enum-name.js +96 -0
  5. package/add-x-ms-enum-value-names.js +142 -0
  6. package/additional-properties-to-object.js +35 -0
  7. package/additional-properties-to-unconstrained.js +115 -0
  8. package/any-of-null-to-nullable.js +50 -0
  9. package/assert-properties.js +56 -0
  10. package/binary-string-to-file.js +54 -0
  11. package/bool-enum-to-bool.js +100 -0
  12. package/clear-html-response-schema.js +77 -0
  13. package/client-params-to-global.js +97 -0
  14. package/const-to-enum.js +49 -0
  15. package/escape-enum-values.js +211 -0
  16. package/exclusive-min-max-to-bool.js +61 -0
  17. package/format-to-type.js +54 -0
  18. package/index.js +94 -0
  19. package/inline-non-object-schemas.js +120 -0
  20. package/lib/component-manager.js +60 -0
  21. package/lib/matching-component-manager.js +74 -0
  22. package/lib/matching-parameter-manager.js +36 -0
  23. package/merge-all-of.js +60 -0
  24. package/merge-any-of.js +48 -0
  25. package/merge-one-of.js +48 -0
  26. package/nullable-not-required.js +240 -0
  27. package/nullable-to-type-null.js +46 -0
  28. package/openapi31to30.js +54 -0
  29. package/package.json +131 -0
  30. package/path-parameters-to-operations.js +63 -0
  31. package/pattern-properties-to-additional-properties.js +62 -0
  32. package/queries-to-x-ms-paths.js +63 -0
  33. package/read-only-not-required.js +111 -0
  34. package/ref-path-parameters.js +73 -0
  35. package/remove-default-only-response-produces.js +58 -0
  36. package/remove-paths-with-servers.js +34 -0
  37. package/remove-query-from-paths.js +526 -0
  38. package/remove-ref-siblings.js +78 -0
  39. package/remove-request-body.js +102 -0
  40. package/remove-response-headers.js +42 -0
  41. package/remove-security-scheme-if.js +166 -0
  42. package/remove-type-if.js +65 -0
  43. package/rename-components.js +285 -0
  44. package/replaced-by-to-description.js +50 -0
  45. package/server-vars-to-path-params.js +224 -0
  46. package/server-vars-to-x-ms-parameterized-host.js +247 -0
  47. package/type-null-to-enum.js +47 -0
  48. package/type-null-to-nullable.js +57 -0
  49. package/urlencoded-to-string.js +160 -0
  50. package/x-enum-to-ms.js +92 -0
@@ -0,0 +1,111 @@
1
+ /**
2
+ * @copyright Copyright 2019 Kevin Locke <kevin@kevinlocke.name>
3
+ * @license MIT
4
+ * @module "openapi-transformers/read-only-not-required.js"
5
+ */
6
+
7
+ import OpenApiTransformerBase from 'openapi-transformer-base';
8
+
9
+ /**
10
+ * Transformer to ensure readOnly schema properties are not required, to work
11
+ * around lack of support in generators.
12
+ *
13
+ * The behavior of required readOnly/writeOnly properties is defined in OAS3
14
+ * (the requirement only applies on response/request), but not in OAS2 (where
15
+ * writeOnly is not defined and "Properties marked as readOnly being true
16
+ * SHOULD NOT be in the required list").
17
+ *
18
+ * AutoRest Behavior:
19
+ * - required properties must be specified in the constructor.
20
+ * - required properties are non-nullable (unless x-nullable: true).
21
+ * - non-required properties are nullable (unless x-nullable: false).
22
+ * - validation is applied to non-null values in requests, not responses.
23
+ */
24
+ export default class ReadOnlyNotRequiredTransformer
25
+ extends OpenApiTransformerBase {
26
+ constructor({ removeValidation, setNonNullable } = {}) {
27
+ super();
28
+
29
+ if (removeValidation !== undefined
30
+ && typeof removeValidation !== 'boolean') {
31
+ throw new TypeError('options.removeValidation must be boolean');
32
+ }
33
+
34
+ if (setNonNullable !== undefined
35
+ && typeof setNonNullable !== 'boolean') {
36
+ throw new TypeError('options.setNonNullable must be boolean');
37
+ }
38
+
39
+ this.options = {
40
+ removeValidation,
41
+ setNonNullable,
42
+ };
43
+ }
44
+
45
+ transformSchema(schema) {
46
+ const newSchema = super.transformSchema(schema);
47
+ const { properties, required } = newSchema;
48
+ if (!properties || !Array.isArray(required) || required.length === 0) {
49
+ // No properties are defined or none are required
50
+ return newSchema;
51
+ }
52
+
53
+ const readOnlyNames = Object.keys(properties)
54
+ .filter((propName) => properties[propName].readOnly);
55
+ if (readOnlyNames.length === 0) {
56
+ // No readOnly properties
57
+ return newSchema;
58
+ }
59
+
60
+ const newRequired = required
61
+ .filter((propName) => !readOnlyNames.includes(propName));
62
+ if (newRequired.length === required.length) {
63
+ // No readOnly properties are required
64
+ return newSchema;
65
+ }
66
+
67
+ let newProperties = properties;
68
+ if (this.options.removeValidation || this.options.setNonNullable) {
69
+ newProperties = { ...properties };
70
+ const readOnlyRequired = required
71
+ .filter((propName) => readOnlyNames.includes(propName));
72
+ for (const readOnlyName of readOnlyRequired) {
73
+ const newProperty = { ...properties[readOnlyName] };
74
+
75
+ if (this.options.removeValidation) {
76
+ // FIXME: Should handle $ref, which is complicated
77
+ delete newProperty.exclusiveMaximum;
78
+ delete newProperty.exclusiveMinimum;
79
+ delete newProperty.maxItems;
80
+ delete newProperty.maxLength;
81
+ delete newProperty.maximum;
82
+ delete newProperty.minItems;
83
+ delete newProperty.minLength;
84
+ delete newProperty.minimum;
85
+ delete newProperty.multipleOf;
86
+ delete newProperty.pattern;
87
+ }
88
+
89
+ if (this.options.setNonNullable
90
+ && !Object.hasOwn(newProperty, 'x-nullable')) {
91
+ // Note: x-nullable: false is ignored for enum and class types
92
+ // FIXME: Adding x-nullable to $ref works in AutoRest (if $ref is to
93
+ // non-nullable type other than enum) but violates spec.
94
+ newProperty['x-nullable'] = false;
95
+ }
96
+
97
+ newProperties[readOnlyName] = newProperty;
98
+ }
99
+ }
100
+
101
+ const updatedSchema = {
102
+ ...newSchema,
103
+ properties: newProperties,
104
+ required: newRequired,
105
+ };
106
+ if (newRequired.length === 0) {
107
+ delete updatedSchema.required;
108
+ }
109
+ return updatedSchema;
110
+ }
111
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @copyright Copyright 2019 Kevin Locke <kevin@kevinlocke.name>
3
+ * @license MIT
4
+ * @module "openapi-transformers/ref-path-parameters.js"
5
+ */
6
+
7
+ // Note: Undocumented function which is part of the public API:
8
+ // https://github.com/flitbit/json-ptr/issues/29
9
+ import { encodeUriFragmentIdentifier } from 'json-ptr';
10
+ import OpenApiTransformerBase from 'openapi-transformer-base';
11
+
12
+ import MatchingParameterManager from './lib/matching-parameter-manager.js';
13
+
14
+ const parameterManagerSymbol = Symbol('parameterManager');
15
+ const parametersPathSymbol = Symbol('parametersPath');
16
+
17
+ /**
18
+ * Transformer to move Parameters defined on Path Item Objects to global
19
+ * parameters which are referenced in the Path Item so that Autorest will
20
+ * treat them as properties of the generated client, rather than method.
21
+ * https://github.com/Azure/autorest/tree/master/docs/extensions#x-ms-parameter-location
22
+ */
23
+ export default class RefPathParametersTransformer
24
+ extends OpenApiTransformerBase {
25
+ transformParameter(param) {
26
+ if (!param || param.$ref) {
27
+ return param;
28
+ }
29
+
30
+ const defName =
31
+ this[parameterManagerSymbol].add(param, param.name);
32
+ return {
33
+ $ref: encodeUriFragmentIdentifier([
34
+ ...this[parametersPathSymbol],
35
+ defName,
36
+ ]),
37
+ };
38
+ }
39
+
40
+ transformPathItem(pathItem) {
41
+ if (!pathItem
42
+ || !Array.isArray(pathItem.parameters)
43
+ || pathItem.parameters.length === 0) {
44
+ return pathItem;
45
+ }
46
+
47
+ return {
48
+ ...pathItem,
49
+ parameters: pathItem.parameters.map(this.transformParameter.bind(this)),
50
+ };
51
+ }
52
+
53
+ transformOpenApi(spec) {
54
+ const newSpec = { ...spec };
55
+
56
+ if (spec.swagger) {
57
+ newSpec.parameters = { ...newSpec.parameters };
58
+ this[parameterManagerSymbol] =
59
+ new MatchingParameterManager(newSpec.parameters);
60
+ this[parametersPathSymbol] = ['parameters'];
61
+ } else {
62
+ newSpec.components = { ...newSpec.components };
63
+ newSpec.components.parameters = { ...newSpec.components.parameters };
64
+ this[parameterManagerSymbol] =
65
+ new MatchingParameterManager(newSpec.components.parameters);
66
+ this[parametersPathSymbol] = ['components', 'parameters'];
67
+ }
68
+
69
+ newSpec.paths = this.transformPaths(spec.paths);
70
+
71
+ return newSpec;
72
+ }
73
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @copyright Copyright 2020 Kevin Locke <kevin@kevinlocke.name>
3
+ * @license MIT
4
+ * @module "openapi-transformers/remove-default-only-response-produces.js"
5
+ */
6
+
7
+ import OpenApiTransformerBase from 'openapi-transformer-base';
8
+
9
+ /**
10
+ * Transformer to remove produces from operations with only a default response.
11
+ *
12
+ * If an operation only produces non-JSON types and only has a default response
13
+ * code, Autorest (core 2.0.4413 and 3.0.6246) will generate methods which do
14
+ * not return a value. If the operation does not produce any types, Autorest
15
+ * will generate a method which returns the response value (e.g. Stream for
16
+ * type: file).
17
+ */
18
+ export default class RemoveDefaultOnlyResponseProducesTransformer
19
+ extends OpenApiTransformerBase {
20
+ // eslint-disable-next-line class-methods-use-this
21
+ transformOperation(operation) {
22
+ if (!operation || !operation.responses) {
23
+ return operation;
24
+ }
25
+
26
+ const codes = Object.keys(operation.responses);
27
+ if (codes.length !== 1 || codes[0] !== 'default') {
28
+ return operation;
29
+ }
30
+
31
+ return {
32
+ ...operation,
33
+ // Note: empty produces is required to override global produces (if any)
34
+ produces: [],
35
+ };
36
+ }
37
+
38
+ transformOpenApi(openApi) {
39
+ // There is no way to remove response media types in OpenAPI 3 without
40
+ // removing the schema type (which is what we are trying to return).
41
+ if (!openApi || openApi.swagger !== '2.0') {
42
+ throw new Error(
43
+ `${this.constructor.name} can only be applied to OpenAPI 2.0 documents`,
44
+ );
45
+ }
46
+
47
+ // Optimization: not calling super.transformOpenApi since only .paths
48
+ // needs to be transformed.
49
+ if (openApi.paths === undefined) {
50
+ return openApi;
51
+ }
52
+
53
+ return {
54
+ ...openApi,
55
+ paths: this.transformPaths(openApi.paths),
56
+ };
57
+ }
58
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @copyright Copyright 2019 Kevin Locke <kevin@kevinlocke.name>
3
+ * @license MIT
4
+ * @module "openapi-transformers/remove-paths-with-servers.js"
5
+ */
6
+
7
+ import OpenApiTransformerBase from 'openapi-transformer-base';
8
+
9
+ /**
10
+ * Transformer to remove Path Item Objects which have servers (and therefore
11
+ * can't be represented in OpenAPI 2).
12
+ */
13
+ export default class RemovePathsWithServersTransformer
14
+ extends OpenApiTransformerBase {
15
+ // eslint-disable-next-line class-methods-use-this
16
+ transformPaths(paths) {
17
+ return Object.keys(paths)
18
+ .reduce((newPaths, path) => {
19
+ const pathItem = paths[path];
20
+ if (!pathItem.servers) {
21
+ newPaths[path] = pathItem;
22
+ }
23
+ return newPaths;
24
+ }, Object.create(Object.getPrototypeOf(paths)));
25
+ }
26
+
27
+ // Optimization: Only transform paths
28
+ transformOpenApi(spec) {
29
+ return {
30
+ ...spec,
31
+ paths: this.transformPaths(spec.paths),
32
+ };
33
+ }
34
+ }