oazapfts 5.1.6 → 5.1.7

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.
@@ -1,32 +1,41 @@
1
1
  import ts from "typescript";
2
- import { OpenAPIV3 } from "openapi-types";
2
+ import { OpenAPIV3, OpenAPIV3_1 } from "openapi-types";
3
3
  import { Opts } from ".";
4
4
  export declare const verbs: string[];
5
5
  type ContentType = "json" | "form" | "multipart";
6
6
  type OnlyMode = "readOnly" | "writeOnly";
7
7
  type OnlyModes = Record<OnlyMode, boolean>;
8
+ type OpenAPISchemaObject = OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject;
9
+ type OpenAPIReferenceObject = OpenAPIV3.ReferenceObject | OpenAPIV3_1.ReferenceObject;
10
+ type OpenAPIParameterObject = OpenAPIV3.ParameterObject | OpenAPIV3_1.ParameterObject;
11
+ type OpenAPIDocument = OpenAPIV3.Document | OpenAPIV3_1.Document;
12
+ type OpenAPIDiscriminatorObject = OpenAPIV3.DiscriminatorObject | OpenAPIV3_1.DiscriminatorObject;
13
+ type OpenAPIResponseObject = OpenAPIV3.ResponseObject | OpenAPIV3_1.ResponseObject;
14
+ type OpenAPIResponsesObject = OpenAPIV3.ResponsesObject | OpenAPIV3_1.ResponsesObject;
15
+ type OpenAPIRequestBodyObject = OpenAPIV3.RequestBodyObject | OpenAPIV3_1.RequestBodyObject;
16
+ type OpenAPIMediaTypeObject = OpenAPIV3.MediaTypeObject | OpenAPIV3_1.MediaTypeObject;
8
17
  export declare function isMimeType(s: unknown): boolean;
9
18
  export declare function isJsonMimeType(mime: string): boolean;
10
- export declare function getBodyFormatter(body?: OpenAPIV3.RequestBodyObject): ContentType | undefined;
11
- type SchemaObject = OpenAPIV3.SchemaObject & {
19
+ export declare function getBodyFormatter(body?: OpenAPIRequestBodyObject): ContentType | undefined;
20
+ type SchemaObject = OpenAPISchemaObject & {
12
21
  const?: unknown;
13
22
  "x-enumNames"?: string[];
14
23
  "x-enum-varnames"?: string[];
15
24
  "x-component-ref-path"?: string;
16
- prefixItems?: (OpenAPIV3.ReferenceObject | SchemaObject)[];
25
+ prefixItems?: (OpenAPIReferenceObject | SchemaObject)[];
17
26
  };
18
27
  /**
19
28
  * Get the name of a formatter function for a given parameter.
20
29
  */
21
- export declare function getFormatter({ style, explode, content, }: OpenAPIV3.ParameterObject): "json" | "form" | "deep" | "explode" | "space" | "pipe";
30
+ export declare function getFormatter({ style, explode, content, }: OpenAPIParameterObject): "json" | "form" | "deep" | "explode" | "space" | "pipe";
22
31
  export declare function getOperationIdentifier(id?: string): string | undefined;
23
32
  /**
24
33
  * Create a method name for a given operation, either from its operationId or
25
34
  * the HTTP verb and path.
26
35
  */
27
36
  export declare function getOperationName(verb: string, path: string, operationId?: string): string;
28
- export declare function isNullable(schema?: SchemaObject | OpenAPIV3.ReferenceObject): boolean | undefined;
29
- export declare function isReference(obj: unknown): obj is OpenAPIV3.ReferenceObject;
37
+ export declare function isNullable(schema?: SchemaObject | OpenAPIReferenceObject): boolean | undefined;
38
+ export declare function isReference(obj: unknown): obj is OpenAPIReferenceObject;
30
39
  /**
31
40
  * Converts a local reference path into an array of property names.
32
41
  */
@@ -55,16 +64,16 @@ export declare function callOazapftsFunction(name: string, args: ts.Expression[]
55
64
  * deeply nested objects. As a workaround we detect parameters that contain
56
65
  * square brackets and merge them into a single object.
57
66
  */
58
- export declare function supportDeepObjects(params: OpenAPIV3.ParameterObject[]): OpenAPIV3.ParameterObject[];
67
+ export declare function supportDeepObjects(params: OpenAPIParameterObject[]): OpenAPIV3.ParameterObject[];
59
68
  /**
60
69
  * Main entry point that generates TypeScript code from a given API spec.
61
70
  */
62
71
  export default class ApiGenerator {
63
- readonly spec: OpenAPIV3.Document;
72
+ readonly spec: OpenAPIDocument;
64
73
  readonly opts: Opts;
65
74
  /** Indicates if the document was converted from an older version of the OpenAPI specification. */
66
75
  readonly isConverted: boolean;
67
- constructor(spec: OpenAPIV3.Document, opts?: Opts,
76
+ constructor(spec: OpenAPIDocument, opts?: Opts,
68
77
  /** Indicates if the document was converted from an older version of the OpenAPI specification. */
69
78
  isConverted?: boolean);
70
79
  discriminatingSchemas: Set<string>;
@@ -82,8 +91,8 @@ export default class ApiGenerator {
82
91
  refsOnlyMode: Map<string, OnlyModes>;
83
92
  typeAliases: Record<string, number>;
84
93
  reset(): void;
85
- resolve<T>(obj: T | OpenAPIV3.ReferenceObject): T;
86
- resolveArray<T>(array?: Array<T | OpenAPIV3.ReferenceObject>): T[];
94
+ resolve<T>(obj: T | OpenAPIReferenceObject): T;
95
+ resolveArray<T>(array?: Array<T | OpenAPIReferenceObject>): T[];
87
96
  skip(tags?: string[]): boolean;
88
97
  findAvailableRef(ref: string): string;
89
98
  getUniqueAlias(name: string): string;
@@ -91,19 +100,19 @@ export default class ApiGenerator {
91
100
  /**
92
101
  * Create a type alias for the schema referenced by the given ReferenceObject
93
102
  */
94
- getRefAlias(obj: OpenAPIV3.ReferenceObject, onlyMode?: OnlyMode, ignoreDiscriminator?: boolean): ts.TypeNode;
95
- getUnionType(variants: (OpenAPIV3.ReferenceObject | SchemaObject)[], discriminator?: OpenAPIV3.DiscriminatorObject, onlyMode?: OnlyMode): ts.UnionTypeNode;
103
+ getRefAlias(obj: OpenAPIReferenceObject, onlyMode?: OnlyMode, ignoreDiscriminator?: boolean): ts.TypeNode;
104
+ getUnionType(variants: (OpenAPIReferenceObject | SchemaObject)[], discriminator?: OpenAPIDiscriminatorObject, onlyMode?: OnlyMode): ts.UnionTypeNode;
96
105
  /**
97
106
  * Creates a type node from a given schema.
98
107
  * Delegates to getBaseTypeFromSchema internally and
99
108
  * optionally adds a union with null.
100
109
  */
101
- getTypeFromSchema(schema?: SchemaObject | OpenAPIV3.ReferenceObject, name?: string, onlyMode?: OnlyMode): ts.TypeNode;
110
+ getTypeFromSchema(schema?: SchemaObject | OpenAPIReferenceObject, name?: string, onlyMode?: OnlyMode): ts.TypeNode;
102
111
  /**
103
112
  * This is the very core of the OpenAPI to TS conversion - it takes a
104
113
  * schema and returns the appropriate type.
105
114
  */
106
- getBaseTypeFromSchema(schema?: SchemaObject | OpenAPIV3.ReferenceObject, name?: string, onlyMode?: OnlyMode): ts.TypeNode;
115
+ getBaseTypeFromSchema(schema?: SchemaObject | OpenAPIReferenceObject, name?: string, onlyMode?: OnlyMode): ts.TypeNode;
107
116
  isTrueEnum(schema: SchemaObject, name?: string): name is string;
108
117
  /**
109
118
  * Creates literal type (or union) from an array of values
@@ -116,18 +125,18 @@ export default class ApiGenerator {
116
125
  * Returns a tuple of booleans; the first one is about readOnly, the second
117
126
  * one is about writeOnly.
118
127
  */
119
- checkSchemaOnlyMode(schema: SchemaObject | OpenAPIV3.ReferenceObject, resolveRefs?: boolean): OnlyModes;
128
+ checkSchemaOnlyMode(schema: SchemaObject | OpenAPIReferenceObject, resolveRefs?: boolean): OnlyModes;
120
129
  /**
121
130
  * Recursively creates a type literal with the given props.
122
131
  */
123
132
  getTypeFromProperties(props: {
124
- [prop: string]: SchemaObject | OpenAPIV3.ReferenceObject;
125
- }, required?: string[], additionalProperties?: boolean | OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject, onlyMode?: OnlyMode): ts.TypeLiteralNode;
126
- getTypeFromResponses(responses: OpenAPIV3.ResponsesObject, onlyMode?: OnlyMode): ts.UnionTypeNode;
127
- getTypeFromResponse(resOrRef: OpenAPIV3.ResponseObject | OpenAPIV3.ReferenceObject, onlyMode?: OnlyMode): ts.TypeNode;
128
- getResponseType(responses?: OpenAPIV3.ResponsesObject): "json" | "text" | "blob";
129
- getSchemaFromContent(content: Record<string, OpenAPIV3.MediaTypeObject>): OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject;
130
- getTypeFromParameter(p: OpenAPIV3.ParameterObject): ts.TypeNode;
133
+ [prop: string]: SchemaObject | OpenAPIReferenceObject;
134
+ }, required?: string[], additionalProperties?: boolean | OpenAPISchemaObject | OpenAPIReferenceObject, onlyMode?: OnlyMode): ts.TypeLiteralNode;
135
+ getTypeFromResponses(responses: OpenAPIResponsesObject, onlyMode?: OnlyMode): ts.UnionTypeNode;
136
+ getTypeFromResponse(resOrRef: OpenAPIResponseObject | OpenAPIReferenceObject, onlyMode?: OnlyMode): ts.TypeNode;
137
+ getResponseType(responses?: OpenAPIResponsesObject): "json" | "text" | "blob";
138
+ getSchemaFromContent(content: Record<string, OpenAPIMediaTypeObject>): OpenAPISchemaObject | OpenAPIReferenceObject;
139
+ getTypeFromParameter(p: OpenAPIParameterObject): ts.TypeNode;
131
140
  wrapResult(ex: ts.Expression): ts.Expression;
132
141
  /**
133
142
  * Does three things:
@@ -138,7 +147,7 @@ export default class ApiGenerator {
138
147
  * 3. Make all mappings of discriminating schemas explicit to generate types immediately.
139
148
  */
140
149
  preprocessComponents(schemas: {
141
- [key: string]: OpenAPIV3.ReferenceObject | SchemaObject;
150
+ [key: string]: OpenAPIReferenceObject | SchemaObject;
142
151
  }): void;
143
152
  generateApi(): ts.SourceFile;
144
153
  }
@@ -116,7 +116,9 @@ function getOperationName(verb, path, operationId) {
116
116
  }
117
117
  exports.getOperationName = getOperationName;
118
118
  function isNullable(schema) {
119
- return schema && !isReference(schema) && schema.nullable;
119
+ if (schema && "nullable" in schema)
120
+ return !isReference(schema) && schema.nullable;
121
+ return false;
120
122
  }
121
123
  exports.isNullable = isNullable;
122
124
  function isReference(obj) {
@@ -252,6 +254,9 @@ function supportDeepObjects(params) {
252
254
  return res;
253
255
  }
254
256
  exports.supportDeepObjects = supportDeepObjects;
257
+ function isKeyOfKeywordType(key) {
258
+ return key in cg.keywordType;
259
+ }
255
260
  /**
256
261
  * Main entry point that generates TypeScript code from a given API spec.
257
262
  */
@@ -556,11 +561,23 @@ class ApiGenerator {
556
561
  return this.getTypeFromEnum([schema.const]);
557
562
  }
558
563
  if (schema.type) {
559
- // string, boolean, null, number
564
+ // string, boolean, null, number, array
565
+ if (Array.isArray(schema.type)) {
566
+ return typescript_1.factory.createUnionTypeNode(schema.type.map((type) => {
567
+ if (type === "null")
568
+ return cg.keywordType.null;
569
+ if (type === "integer")
570
+ return cg.keywordType.number;
571
+ if (isKeyOfKeywordType(type))
572
+ return cg.keywordType[type];
573
+ return cg.keywordType.any;
574
+ }));
575
+ }
560
576
  if (schema.type === "integer")
561
577
  return cg.keywordType.number;
562
- if (schema.type in cg.keywordType)
578
+ if (isKeyOfKeywordType(schema.type))
563
579
  return cg.keywordType[schema.type];
580
+ return cg.keywordType.any;
564
581
  }
565
582
  return cg.keywordType.any;
566
583
  }
@@ -663,7 +680,7 @@ class ApiGenerator {
663
680
  let readOnly = (_a = schema.readOnly) !== null && _a !== void 0 ? _a : false;
664
681
  let writeOnly = (_b = schema.writeOnly) !== null && _b !== void 0 ? _b : false;
665
682
  const subSchemas = [];
666
- if ("items" in schema) {
683
+ if ("items" in schema && schema.items) {
667
684
  subSchemas.push(schema.items);
668
685
  }
669
686
  else {
@@ -877,185 +894,188 @@ class ApiGenerator {
877
894
  const functions = [];
878
895
  // Keep track of names to detect duplicates
879
896
  const names = {};
880
- Object.keys(this.spec.paths).forEach((path) => {
881
- const item = this.spec.paths[path];
882
- if (!item) {
883
- return;
884
- }
885
- Object.keys(this.resolve(item)).forEach((verb) => {
886
- var _a;
887
- const method = verb.toUpperCase();
888
- // skip summary/description/parameters etc...
889
- if (!exports.verbs.includes(method))
897
+ if (this.spec.paths) {
898
+ Object.keys(this.spec.paths).forEach((path) => {
899
+ if (!this.spec.paths)
890
900
  return;
891
- const op = item[verb];
892
- const { operationId, requestBody, responses, summary, description, tags, } = op;
893
- if (this.skip(tags)) {
901
+ const item = this.spec.paths[path];
902
+ if (!item) {
894
903
  return;
895
904
  }
896
- let name = getOperationName(verb, path, operationId);
897
- const count = (names[name] = (names[name] || 0) + 1);
898
- if (count > 1) {
899
- // The name is already taken, which means that the spec is probably
900
- // invalid as operationIds must be unique. Since this is quite common
901
- // nevertheless we append a counter:
902
- name += count;
903
- }
904
- // merge item and op parameters
905
- const resolvedParameters = this.resolveArray(item.parameters);
906
- for (const p of this.resolveArray(op.parameters)) {
907
- const existing = resolvedParameters.find((r) => r.name === p.name && r.in === p.in);
908
- if (!existing) {
909
- resolvedParameters.push(p);
905
+ Object.keys(this.resolve(item)).forEach((verb) => {
906
+ var _a;
907
+ const method = verb.toUpperCase();
908
+ // skip summary/description/parameters etc...
909
+ if (!exports.verbs.includes(method))
910
+ return;
911
+ const op = item[verb];
912
+ const { operationId, requestBody, responses, summary, description, tags, } = op;
913
+ if (this.skip(tags)) {
914
+ return;
910
915
  }
911
- }
912
- // expand older OpenAPI parameters into deepObject style where needed
913
- const parameters = this.isConverted
914
- ? supportDeepObjects(resolvedParameters)
915
- : resolvedParameters;
916
- // convert parameter names to argument names ...
917
- const argNames = new Map();
918
- lodash_1.default.sortBy(parameters, "name.length").forEach((p) => {
919
- const identifier = toIdentifier(p.name);
920
- const existing = [...argNames.values()];
921
- const suffix = existing.includes(identifier)
922
- ? lodash_1.default.upperFirst(p.in)
923
- : "";
924
- argNames.set(p, identifier + suffix);
925
- });
926
- const getArgName = (param) => {
927
- const name = argNames.get(param);
928
- if (!name)
929
- throw new Error(`Can't find parameter: ${param.name}`);
930
- return name;
931
- };
932
- const methodParams = [];
933
- let body = undefined;
934
- let bodyVar = undefined;
935
- switch ((_a = this.opts.argumentStyle) !== null && _a !== void 0 ? _a : "positional") {
936
- case "positional":
937
- // split into required/optional
938
- const [required, optional] = lodash_1.default.partition(parameters, "required");
939
- // build the method signature - first all the required parameters
940
- const requiredParams = required.map((p) => cg.createParameter(getArgName(this.resolve(p)), {
941
- type: this.getTypeFromParameter(p),
942
- }));
943
- methodParams.push(...requiredParams);
944
- // add body if present
945
- if (requestBody) {
946
- body = this.resolve(requestBody);
947
- const schema = this.getSchemaFromContent(body.content);
948
- const type = this.getTypeFromSchema(schema, undefined, "writeOnly");
949
- bodyVar = toIdentifier(type.name || getReferenceName(schema) || "body");
950
- methodParams.push(cg.createParameter(bodyVar, {
951
- type,
952
- questionToken: !body.required,
953
- }));
916
+ let name = getOperationName(verb, path, operationId);
917
+ const count = (names[name] = (names[name] || 0) + 1);
918
+ if (count > 1) {
919
+ // The name is already taken, which means that the spec is probably
920
+ // invalid as operationIds must be unique. Since this is quite common
921
+ // nevertheless we append a counter:
922
+ name += count;
923
+ }
924
+ // merge item and op parameters
925
+ const resolvedParameters = this.resolveArray(item.parameters);
926
+ for (const p of this.resolveArray(op.parameters)) {
927
+ const existing = resolvedParameters.find((r) => r.name === p.name && r.in === p.in);
928
+ if (!existing) {
929
+ resolvedParameters.push(p);
954
930
  }
955
- // add an object with all optional parameters
956
- if (optional.length) {
957
- methodParams.push(cg.createParameter(cg.createObjectBinding(optional
958
- .map((param) => this.resolve(param))
959
- .map((param) => ({ name: getArgName(param) }))), {
960
- initializer: typescript_1.factory.createObjectLiteralExpression(),
961
- type: typescript_1.factory.createTypeLiteralNode(optional.map((p) => cg.createPropertySignature({
962
- name: getArgName(this.resolve(p)),
963
- questionToken: true,
964
- type: this.getTypeFromParameter(p),
965
- }))),
931
+ }
932
+ // expand older OpenAPI parameters into deepObject style where needed
933
+ const parameters = this.isConverted
934
+ ? supportDeepObjects(resolvedParameters)
935
+ : resolvedParameters;
936
+ // convert parameter names to argument names ...
937
+ const argNames = new Map();
938
+ lodash_1.default.sortBy(parameters, "name.length").forEach((p) => {
939
+ const identifier = toIdentifier(p.name);
940
+ const existing = [...argNames.values()];
941
+ const suffix = existing.includes(identifier)
942
+ ? lodash_1.default.upperFirst(p.in)
943
+ : "";
944
+ argNames.set(p, identifier + suffix);
945
+ });
946
+ const getArgName = (param) => {
947
+ const name = argNames.get(param);
948
+ if (!name)
949
+ throw new Error(`Can't find parameter: ${param.name}`);
950
+ return name;
951
+ };
952
+ const methodParams = [];
953
+ let body = undefined;
954
+ let bodyVar = undefined;
955
+ switch ((_a = this.opts.argumentStyle) !== null && _a !== void 0 ? _a : "positional") {
956
+ case "positional":
957
+ // split into required/optional
958
+ const [required, optional] = lodash_1.default.partition(parameters, "required");
959
+ // build the method signature - first all the required parameters
960
+ const requiredParams = required.map((p) => cg.createParameter(getArgName(this.resolve(p)), {
961
+ type: this.getTypeFromParameter(p),
966
962
  }));
967
- }
968
- break;
969
- case "object":
970
- // build the method signature - first all the required/optional parameters
971
- const paramMembers = parameters.map((p) => cg.createPropertySignature({
972
- name: getArgName(this.resolve(p)),
973
- questionToken: !p.required,
974
- type: this.getTypeFromParameter(p),
975
- }));
976
- // add body if present
977
- if (requestBody) {
978
- body = this.resolve(requestBody);
979
- const schema = this.getSchemaFromContent(body.content);
980
- const type = this.getTypeFromSchema(schema, undefined, "writeOnly");
981
- bodyVar = toIdentifier(type.name || getReferenceName(schema) || "body");
982
- paramMembers.push(cg.createPropertySignature({
983
- name: bodyVar,
984
- questionToken: !body.required,
985
- type,
963
+ methodParams.push(...requiredParams);
964
+ // add body if present
965
+ if (requestBody) {
966
+ body = this.resolve(requestBody);
967
+ const schema = this.getSchemaFromContent(body.content);
968
+ const type = this.getTypeFromSchema(schema, undefined, "writeOnly");
969
+ bodyVar = toIdentifier(type.name || getReferenceName(schema) || "body");
970
+ methodParams.push(cg.createParameter(bodyVar, {
971
+ type,
972
+ questionToken: !body.required,
973
+ }));
974
+ }
975
+ // add an object with all optional parameters
976
+ if (optional.length) {
977
+ methodParams.push(cg.createParameter(cg.createObjectBinding(optional
978
+ .map((param) => this.resolve(param))
979
+ .map((param) => ({ name: getArgName(param) }))), {
980
+ initializer: typescript_1.factory.createObjectLiteralExpression(),
981
+ type: typescript_1.factory.createTypeLiteralNode(optional.map((p) => cg.createPropertySignature({
982
+ name: getArgName(this.resolve(p)),
983
+ questionToken: true,
984
+ type: this.getTypeFromParameter(p),
985
+ }))),
986
+ }));
987
+ }
988
+ break;
989
+ case "object":
990
+ // build the method signature - first all the required/optional parameters
991
+ const paramMembers = parameters.map((p) => cg.createPropertySignature({
992
+ name: getArgName(this.resolve(p)),
993
+ questionToken: !p.required,
994
+ type: this.getTypeFromParameter(p),
995
+ }));
996
+ // add body if present
997
+ if (requestBody) {
998
+ body = this.resolve(requestBody);
999
+ const schema = this.getSchemaFromContent(body.content);
1000
+ const type = this.getTypeFromSchema(schema, undefined, "writeOnly");
1001
+ bodyVar = toIdentifier(type.name || getReferenceName(schema) || "body");
1002
+ paramMembers.push(cg.createPropertySignature({
1003
+ name: bodyVar,
1004
+ questionToken: !body.required,
1005
+ type,
1006
+ }));
1007
+ }
1008
+ // if there's no params, leave methodParams as is and prevent empty object argument generation
1009
+ if (paramMembers.length === 0) {
1010
+ break;
1011
+ }
1012
+ methodParams.push(cg.createParameter(cg.createObjectBinding([
1013
+ ...parameters
1014
+ .map((param) => this.resolve(param))
1015
+ .map((param) => ({ name: getArgName(param) })),
1016
+ ...(bodyVar ? [{ name: bodyVar }] : []),
1017
+ ]), {
1018
+ type: typescript_1.factory.createTypeLiteralNode(paramMembers),
986
1019
  }));
987
- }
988
- // if there's no params, leave methodParams as is and prevent empty object argument generation
989
- if (paramMembers.length === 0) {
990
1020
  break;
991
- }
992
- methodParams.push(cg.createParameter(cg.createObjectBinding([
993
- ...parameters
994
- .map((param) => this.resolve(param))
995
- .map((param) => ({ name: getArgName(param) })),
996
- ...(bodyVar ? [{ name: bodyVar }] : []),
997
- ]), {
998
- type: typescript_1.factory.createTypeLiteralNode(paramMembers),
999
- }));
1000
- break;
1001
- }
1002
- // add oazapfts options
1003
- methodParams.push(cg.createParameter("opts", {
1004
- type: typescript_1.factory.createTypeReferenceNode("Oazapfts.RequestOpts", undefined),
1005
- questionToken: true,
1006
- }));
1007
- // Next, build the method body...
1008
- const returnType = this.getResponseType(responses);
1009
- const query = parameters.filter((p) => p.in === "query");
1010
- const header = parameters.filter((p) => p.in === "header");
1011
- let qs;
1012
- if (query.length) {
1013
- const paramsByFormatter = lodash_1.default.groupBy(query, getFormatter);
1014
- qs = callQsFunction("query", Object.entries(paramsByFormatter).map(([format, params]) => {
1015
- //const [allowReserved, encodeReserved] = _.partition(params, "allowReserved");
1016
- return callQsFunction(format, [
1017
- cg.createObjectLiteral(params.map((p) => [p.name, getArgName(p)])),
1018
- ]);
1021
+ }
1022
+ // add oazapfts options
1023
+ methodParams.push(cg.createParameter("opts", {
1024
+ type: typescript_1.factory.createTypeReferenceNode("Oazapfts.RequestOpts", undefined),
1025
+ questionToken: true,
1019
1026
  }));
1020
- }
1021
- const url = createUrlExpression(path, qs);
1022
- const init = [
1023
- typescript_1.factory.createSpreadAssignment(typescript_1.factory.createIdentifier("opts")),
1024
- ];
1025
- if (method !== "GET") {
1026
- init.push(typescript_1.factory.createPropertyAssignment("method", typescript_1.factory.createStringLiteral(method)));
1027
- }
1028
- if (bodyVar) {
1029
- init.push(cg.createPropertyAssignment("body", typescript_1.factory.createIdentifier(bodyVar)));
1030
- }
1031
- if (header.length) {
1032
- init.push(typescript_1.factory.createPropertyAssignment("headers", callOazapftsFunction("mergeHeaders", [
1033
- typescript_1.factory.createPropertyAccessChain(typescript_1.factory.createIdentifier("opts"), typescript_1.factory.createToken(typescript_1.default.SyntaxKind.QuestionDotToken), "headers"),
1034
- typescript_1.factory.createObjectLiteralExpression([
1035
- ...header.map((param) => cg.createPropertyAssignment(param.name, typescript_1.factory.createIdentifier(getArgName(param)))),
1036
- ], true),
1037
- ])));
1038
- }
1039
- const args = [url];
1040
- if (init.length) {
1041
- const formatter = getBodyFormatter(body); // json, form, multipart
1042
- const initObj = typescript_1.factory.createObjectLiteralExpression(init, true);
1043
- args.push(formatter ? callOazapftsFunction(formatter, [initObj]) : initObj);
1044
- }
1045
- functions.push(cg.addComment(cg.createFunctionDeclaration(name, {
1046
- modifiers: [cg.modifier.export],
1047
- }, methodParams, cg.block(typescript_1.factory.createReturnStatement(this.wrapResult(callOazapftsFunction({
1048
- json: "fetchJson",
1049
- text: "fetchText",
1050
- blob: "fetchBlob",
1051
- }[returnType], args, returnType === "json" || returnType === "blob"
1052
- ? [
1053
- this.getTypeFromResponses(responses, "readOnly") ||
1054
- typescript_1.default.SyntaxKind.AnyKeyword,
1055
- ]
1056
- : undefined))))), summary || description));
1027
+ // Next, build the method body...
1028
+ const returnType = this.getResponseType(responses);
1029
+ const query = parameters.filter((p) => p.in === "query");
1030
+ const header = parameters.filter((p) => p.in === "header");
1031
+ let qs;
1032
+ if (query.length) {
1033
+ const paramsByFormatter = lodash_1.default.groupBy(query, getFormatter);
1034
+ qs = callQsFunction("query", Object.entries(paramsByFormatter).map(([format, params]) => {
1035
+ //const [allowReserved, encodeReserved] = _.partition(params, "allowReserved");
1036
+ return callQsFunction(format, [
1037
+ cg.createObjectLiteral(params.map((p) => [p.name, getArgName(p)])),
1038
+ ]);
1039
+ }));
1040
+ }
1041
+ const url = createUrlExpression(path, qs);
1042
+ const init = [
1043
+ typescript_1.factory.createSpreadAssignment(typescript_1.factory.createIdentifier("opts")),
1044
+ ];
1045
+ if (method !== "GET") {
1046
+ init.push(typescript_1.factory.createPropertyAssignment("method", typescript_1.factory.createStringLiteral(method)));
1047
+ }
1048
+ if (bodyVar) {
1049
+ init.push(cg.createPropertyAssignment("body", typescript_1.factory.createIdentifier(bodyVar)));
1050
+ }
1051
+ if (header.length) {
1052
+ init.push(typescript_1.factory.createPropertyAssignment("headers", callOazapftsFunction("mergeHeaders", [
1053
+ typescript_1.factory.createPropertyAccessChain(typescript_1.factory.createIdentifier("opts"), typescript_1.factory.createToken(typescript_1.default.SyntaxKind.QuestionDotToken), "headers"),
1054
+ typescript_1.factory.createObjectLiteralExpression([
1055
+ ...header.map((param) => cg.createPropertyAssignment(param.name, typescript_1.factory.createIdentifier(getArgName(param)))),
1056
+ ], true),
1057
+ ])));
1058
+ }
1059
+ const args = [url];
1060
+ if (init.length) {
1061
+ const formatter = getBodyFormatter(body); // json, form, multipart
1062
+ const initObj = typescript_1.factory.createObjectLiteralExpression(init, true);
1063
+ args.push(formatter ? callOazapftsFunction(formatter, [initObj]) : initObj);
1064
+ }
1065
+ functions.push(cg.addComment(cg.createFunctionDeclaration(name, {
1066
+ modifiers: [cg.modifier.export],
1067
+ }, methodParams, cg.block(typescript_1.factory.createReturnStatement(this.wrapResult(callOazapftsFunction({
1068
+ json: "fetchJson",
1069
+ text: "fetchText",
1070
+ blob: "fetchBlob",
1071
+ }[returnType], args, returnType === "json" || returnType === "blob"
1072
+ ? [
1073
+ this.getTypeFromResponses(responses, "readOnly") || typescript_1.default.SyntaxKind.AnyKeyword,
1074
+ ]
1075
+ : undefined))))), summary || description));
1076
+ });
1057
1077
  });
1058
- });
1078
+ }
1059
1079
  Object.assign(stub, {
1060
1080
  statements: cg.appendNodes(stub.statements, ...[...this.aliases, ...functions], ...this.enumAliases),
1061
1081
  });