@automatons/typescript-client-axios 2.0.1 → 2.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 (40) hide show
  1. package/index.js +405 -70
  2. package/index.js.map +1 -1
  3. package/package.json +5 -8
  4. package/templates/apis/abstractApi.hbs +0 -63
  5. package/templates/apis/api.hbs +0 -17
  6. package/templates/apis/index.hbs +0 -3
  7. package/templates/apis/partials/arguments/server.hbs +0 -3
  8. package/templates/apis/partials/arguments/server_interface.hbs +0 -3
  9. package/templates/apis/partials/class/arguments.hbs +0 -21
  10. package/templates/apis/partials/class/arguments_interface.hbs +0 -21
  11. package/templates/apis/partials/class/path.hbs +0 -4
  12. package/templates/apis/partials/class/request.hbs +0 -14
  13. package/templates/apis/partials/class/variables.hbs +0 -4
  14. package/templates/apis/partials/class.hbs +0 -17
  15. package/templates/apis/partials/config/arguments.hbs +0 -19
  16. package/templates/apis/partials/config/request/baseURL.hbs +0 -1
  17. package/templates/apis/partials/config/request/cookies.hbs +0 -13
  18. package/templates/apis/partials/config/request/headers.hbs +0 -14
  19. package/templates/apis/partials/config/request/queries.hbs +0 -11
  20. package/templates/apis/partials/config/request.hbs +0 -19
  21. package/templates/apis/partials/config/server.hbs +0 -11
  22. package/templates/apis/partials/config.hbs +0 -14
  23. package/templates/config.hbs +0 -19
  24. package/templates/index.hbs +0 -3
  25. package/templates/models/index.hbs +0 -3
  26. package/templates/models/model.hbs +0 -6
  27. package/templates/models/partials/allOf.hbs +0 -7
  28. package/templates/models/partials/array.hbs +0 -6
  29. package/templates/models/partials/boolean.hbs +0 -1
  30. package/templates/models/partials/nullable.hbs +0 -1
  31. package/templates/models/partials/number.hbs +0 -6
  32. package/templates/models/partials/object.hbs +0 -13
  33. package/templates/models/partials/oneOf.hbs +0 -7
  34. package/templates/models/partials/string.hbs +0 -10
  35. package/templates/models/partials/type.hbs +0 -19
  36. package/templates/partials/comment.hbs +0 -24
  37. /package/{templates/utils/formData.hbs → static/utils/formData.ts} +0 -0
  38. /package/{templates/utils/index.hbs → static/utils/index.ts} +0 -0
  39. /package/{templates/utils/query.hbs → static/utils/query.ts} +0 -0
  40. /package/{templates/utils/template.hbs → static/utils/template.ts} +0 -0
package/index.js CHANGED
@@ -1,102 +1,437 @@
1
1
  // src/generator/generate.ts
2
2
  import { parser } from "@automatons/parser";
3
3
 
4
- // src/generator/writer.ts
5
- import path2 from "path";
6
- import { mkdir, readFile, writeFile } from "fs/promises";
7
- import { format } from "prettier";
8
- import Handlebars from "handlebars";
9
-
10
- // src/paths.ts
4
+ // src/generator/render.ts
11
5
  import path from "path";
12
- var paths = {
13
- src: path.resolve(import.meta.dirname),
14
- templates: path.resolve(import.meta.dirname, "templates"),
15
- tmp: path.resolve(import.meta.dirname, "../tmp")
6
+ import { mkdir, writeFile } from "fs/promises";
7
+ import { IndentationText, Project, QuoteKind } from "ts-morph";
8
+ import { format } from "prettier";
9
+ var project = new Project({
10
+ useInMemoryFileSystem: true,
11
+ manipulationSettings: {
12
+ quoteKind: QuoteKind.Double,
13
+ indentationText: IndentationText.TwoSpaces,
14
+ useTrailingCommas: true
15
+ }
16
+ });
17
+ var counter = 0;
18
+ var render = (build) => {
19
+ const sf = project.createSourceFile(`__gen_${counter++}.ts`, "", { overwrite: true });
20
+ build(sf);
21
+ const text = sf.getFullText();
22
+ project.removeSourceFile(sf);
23
+ return text;
24
+ };
25
+ var write = async (outDir, relPath, text) => {
26
+ const outputPath = path.resolve(outDir, relPath);
27
+ await mkdir(path.dirname(outputPath), { recursive: true });
28
+ const formatted = await format(text, { parser: "typescript" });
29
+ await writeFile(outputPath, formatted, { encoding: "utf-8" });
16
30
  };
17
- var paths_default = paths;
18
31
 
19
- // src/generator/writer.ts
20
- var write = async (template, outDir, context) => {
21
- const outputPath = Array.isArray(outDir) ? path2.resolve(...outDir) : outDir;
22
- await mkdir(path2.dirname(outputPath), { recursive: true });
23
- const data = await readFile(path2.resolve(paths_default.templates, template), { encoding: "utf-8" });
24
- const formatted = await format(Handlebars.compile(data)(context), { parser: "typescript" });
25
- return writeFile(outputPath, formatted);
32
+ // src/generator/schema.ts
33
+ var quoteKey = (name) => name.includes("-") ? `"${name}"` : name;
34
+ var nullable = (schema) => schema.nullable ? " | null" : "";
35
+ var schemaToType = (schema) => {
36
+ switch (schema.type) {
37
+ case "model":
38
+ return schema.name;
39
+ case "object": {
40
+ if (schema.properties && schema.properties.length) {
41
+ const props = schema.properties.map(
42
+ (property) => `/**
43
+ * ${property.name}
44
+ */
45
+ ${quoteKey(property.name)}${property.required ? "" : "?"}: ${schemaToType(property.schema)};`
46
+ ).join("\n");
47
+ return `{
48
+ ${props}
49
+ }${nullable(schema)}`;
50
+ }
51
+ return `object${nullable(schema)}`;
52
+ }
53
+ case "allOf":
54
+ return `(${schema.schemas.map(schemaToType).join(" & ")})`;
55
+ case "oneOf":
56
+ return `(${schema.schemas.map(schemaToType).join(" | ")})`;
57
+ case "array":
58
+ return `${schema.items ? `Array<${schemaToType(schema.items)}>` : "any[]"}${nullable(schema)}`;
59
+ case "boolean":
60
+ return `boolean${nullable(schema)}`;
61
+ case "string": {
62
+ const base = schema.enum && schema.enum.length ? schema.enum.map((value) => `"${value}"`).join(" | ") : schema.format === "date" || schema.format === "date-time" ? "Date" : schema.format === "url" ? "URL" : "string";
63
+ return `${base}${nullable(schema)}`;
64
+ }
65
+ case "integer":
66
+ case "number": {
67
+ const base = schema.enum && schema.enum.length ? schema.enum.join(" | ") : "number";
68
+ return `${base}${nullable(schema)}`;
69
+ }
70
+ default:
71
+ throw new Error(`Unsupported schema type: ${schema.type}`);
72
+ }
26
73
  };
27
74
 
28
- // src/generator/setup.ts
29
- import helpers from "handlebars-helpers";
30
- import HB from "handlebars";
75
+ // src/generator/comment.ts
76
+ var docs = (options) => {
77
+ const tags = [];
78
+ if (options.async) tags.push({ tagName: "async" });
79
+ if (options.description) tags.push({ tagName: "description", text: options.description });
80
+ if (options.deprecated) tags.push({ tagName: "deprecated" });
81
+ if (options.readOnly) tags.push({ tagName: "readonly" });
82
+ return [{ description: options.title, tags }];
83
+ };
31
84
 
32
- // src/generator/register.ts
33
- import { readFile as readFile2 } from "fs/promises";
34
- import { glob } from "glob";
35
- import Handlebars2 from "handlebars";
36
- var partial = Handlebars2.registerPartial.bind(Handlebars2);
37
- var convertName = (match) => match.replace(`${paths_default.templates}/`, "").replace("partials/", "").replace(".hbs", "");
38
- var register = () => glob("**/partials/**/*.hbs", { cwd: paths_default.templates, absolute: true }).then((matches) => matches.map((match) => ({ name: convertName(match), path: match }))).then(
39
- (files) => Promise.all(
40
- files.map(({ name, path: path3 }) => readFile2(path3, { encoding: "utf-8" }).then((data) => partial(name, data)))
41
- )
85
+ // src/generator/model.ts
86
+ var emitModel = (model) => render((sf) => {
87
+ model.imports.forEach(
88
+ (imported) => sf.addImportDeclaration({
89
+ namedImports: [imported.title],
90
+ moduleSpecifier: `./${imported.filename}`
91
+ })
92
+ );
93
+ sf.addTypeAlias({
94
+ isExported: true,
95
+ name: model.title,
96
+ type: schemaToType(model.schema),
97
+ docs: docs({ title: model.title })
98
+ });
99
+ });
100
+ var emitModelsIndex = (models) => render(
101
+ (sf) => models.forEach((model) => sf.addExportDeclaration({ moduleSpecifier: `./${model.filename}` }))
42
102
  );
43
103
 
44
- // src/generator/setup.ts
45
- HB.registerHelper("every", function(value, key, text) {
46
- if (text === void 0) {
47
- return value.every((item) => item[key] == void 0 ? false : item[key]);
104
+ // src/generator/config.ts
105
+ var callable = (returns, arg = "") => `${returns} | Promise<${returns}> | ((${arg}) => ${returns} | Promise<${returns}>)`;
106
+ var securityType = (security) => {
107
+ if (security.type === "http" && security.scheme === "basic") {
108
+ const basic = "{username: string; password: string;}";
109
+ return `${security.name}?: ${callable(basic)};`;
110
+ }
111
+ if (security.type === "oauth2" || security.type === "openIdConnect") {
112
+ return `${security.name}?: ${callable("string", "scopes?: string[]")};`;
48
113
  }
49
- return value.every((item) => (item[key] == void 0 ? false : item[key]) === text);
114
+ return `${security.name}?: ${callable("string")};`;
115
+ };
116
+ var emitConfig = (securities) => render((sf) => {
117
+ sf.addImportDeclaration({ namedImports: ["AxiosInstance"], moduleSpecifier: "axios" });
118
+ sf.addTypeAlias({
119
+ isExported: true,
120
+ name: "Security",
121
+ type: `{
122
+ ${securities.map(securityType).join("\n")}
123
+ }`
124
+ });
125
+ sf.addTypeAlias({
126
+ isExported: true,
127
+ name: "Config",
128
+ type: `{
129
+ axios?: AxiosInstance;
130
+ token?: string | Promise<string> | (() => string | Promise<string>);
131
+ security?: Security;
132
+ }`
133
+ });
134
+ });
135
+ var emitIndex = (hasModels, hasApis) => render((sf) => {
136
+ if (hasModels) sf.addExportDeclaration({ moduleSpecifier: "./models" });
137
+ if (hasApis) sf.addExportDeclaration({ moduleSpecifier: "./apis" });
138
+ sf.addExportDeclaration({ moduleSpecifier: "./config" });
50
139
  });
51
- HB.registerHelper("any", function(value, key, text) {
52
- if (text === void 0) {
53
- return value.some((item) => item[key] == void 0 ? false : item[key]);
140
+
141
+ // src/generator/abstractApi.ts
142
+ import { Scope } from "ts-morph";
143
+ var BASE_STATEMENTS = [
144
+ "const DateFormat = /^\\d{4}-\\d{2}-\\d{2}([tT]\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2})|Z)?$/;",
145
+ "const reviver = (_key: string, value: any) => typeof value === 'string' && DateFormat.test(value) ? new Date(value) : value;",
146
+ "const BASE_AXIOS = Axios.create({ transformResponse: (data) => JSON.parse(data, reviver) });"
147
+ ];
148
+ var overload = (security) => {
149
+ const base = { scope: Scope.Protected, isAsync: true };
150
+ if (security.type === "http" && security.scheme === "basic") {
151
+ return {
152
+ ...base,
153
+ parameters: [{ name: "key", type: `"${security.name}"` }],
154
+ returnType: "Promise<{username: string; password: string;}>"
155
+ };
54
156
  }
55
- return value.some((item) => (item[key] == void 0 ? false : item[key]) === text);
157
+ if (security.type === "oauth2" || security.type === "openIdConnect") {
158
+ return {
159
+ ...base,
160
+ parameters: [{ name: "key", type: `"${security.name}"` }, { name: "scopes", type: "string[]" }],
161
+ returnType: "Promise<string>"
162
+ };
163
+ }
164
+ return { ...base, parameters: [{ name: "key", type: `"${security.name}"` }], returnType: "Promise<string>" };
165
+ };
166
+ var emitAbstractApi = (securities) => render((sf) => {
167
+ sf.addImportDeclaration({ defaultImport: "Axios", namedImports: ["AxiosInstance"], moduleSpecifier: "axios" });
168
+ sf.addImportDeclaration({
169
+ isTypeOnly: true,
170
+ namedImports: securities.length ? ["Config", "Security"] : ["Config"],
171
+ moduleSpecifier: "../config"
172
+ });
173
+ sf.addStatements(BASE_STATEMENTS);
174
+ const abstractConfig = sf.addClass({ isExported: true, name: "AbstractConfig", docs: docs({ title: "AbstractConfig" }) });
175
+ if (securities.length) {
176
+ abstractConfig.addProperty({ name: "#security", isReadonly: true, type: "Security" });
177
+ abstractConfig.addConstructor({
178
+ docs: docs({ title: "constructor" }),
179
+ parameters: [{ name: "security", type: "Security", initializer: "{}" }],
180
+ statements: ["this.#security = security;"]
181
+ });
182
+ const scoped = securities.some((s) => s.type === "oauth2" || s.type === "openIdConnect");
183
+ abstractConfig.addMethod({
184
+ scope: Scope.Protected,
185
+ isAsync: true,
186
+ name: "security",
187
+ overloads: securities.map(overload),
188
+ parameters: [
189
+ { name: "key", type: "keyof Security" },
190
+ ...scoped ? [{ name: "scopes", type: "string[]", hasQuestionToken: true }] : []
191
+ ],
192
+ returnType: "Promise<string | {username: string; password: string;}>",
193
+ statements: [
194
+ "const security = this.#security[key];",
195
+ 'if (!security) { throw new Error("Unauthorized user request."); }',
196
+ `else if (security instanceof Function) { ${scoped ? "return scopes ? security(scopes) : security();" : "return security();"} }`,
197
+ "return security;"
198
+ ]
199
+ });
200
+ }
201
+ const abstractApi = sf.addClass({ isExported: true, name: "AbstractApi", docs: docs({ title: "AbstractApi" }) });
202
+ abstractApi.addProperty({ scope: Scope.Protected, name: "axios", type: "AxiosInstance", initializer: "BASE_AXIOS" });
203
+ abstractApi.addConstructor({
204
+ docs: docs({ title: "constructor" }),
205
+ parameters: [{ name: "{axios}", type: "Config" }],
206
+ statements: ["if (axios) this.axios = axios;"]
207
+ });
56
208
  });
57
- helpers({ handlebars: HB });
58
- var setup = () => register();
209
+
210
+ // src/generator/api.ts
211
+ import { Scope as Scope2 } from "ts-morph";
59
212
 
60
213
  // src/extractors/api.ts
61
- var isAffectPath = (path3) => ["post", "patch", "put"].includes(path3.method);
214
+ var isAffectPath = (path4) => ["post", "patch", "put"].includes(path4.method);
62
215
  var extractApiMeta = (api) => {
63
- const hasTemplate = api.servers.some((server) => server.values?.length) || api.paths.some((path3) => path3.parameters?.length) || api.paths.some((path3) => path3.headers?.length);
64
- const hasQuery = api.paths.some((path3) => path3.queries?.length) || api.paths.some((path3) => path3.cookies?.length);
65
- const hasFormData = api.paths.some((path3) => isAffectPath(path3) ? path3.forms?.length : false);
216
+ const hasTemplate = api.servers.some((server) => server.values?.length) || api.paths.some((path4) => path4.parameters?.length) || api.paths.some((path4) => path4.headers?.length);
217
+ const hasQuery = api.paths.some((path4) => path4.queries?.length) || api.paths.some((path4) => path4.cookies?.length);
218
+ const hasFormData = api.paths.some((path4) => isAffectPath(path4) ? path4.forms?.length : false);
66
219
  return { hasQuery, hasTemplate, hasFormData };
67
220
  };
68
221
 
222
+ // src/generator/api.ts
223
+ var isAffect = (path4) => ["post", "put", "patch"].includes(path4.method);
224
+ var formsOf = (path4) => isAffect(path4) && path4.forms ? path4.forms : [];
225
+ var objectType = (entries) => `{ ${entries.map((e) => `${e.name}${e.required ? "" : "?"}: ${schemaToType(e.schema)}, `).join("")}}`;
226
+ var allOptional = (entries = []) => entries.every((e) => !e.required);
227
+ var contentType = (path4) => {
228
+ const forms = formsOf(path4);
229
+ return forms.length ? forms.map((form) => form.types.map((type) => `'${type}'`).join(" | ")).join(" | ") : "'application/json'";
230
+ };
231
+ var headersType = (path4) => `{ 'Content-Type': ${contentType(path4)}, ${(path4.headers ?? []).map((h) => `${h.name}${h.required ? "" : "?"}: ${schemaToType(h.schema)}, `).join("")}}`;
232
+ var serverUnion = (servers) => servers.map((server) => `${server.name}Server`).join(" | ");
233
+ var serverDefault = (servers) => {
234
+ const [first] = servers;
235
+ return servers.length === 1 && first && !(first.values && first.values.length) ? `{ name: '${first.name}' }` : void 0;
236
+ };
237
+ var withInit = (init) => init ? { initializer: init } : {};
238
+ var queriesParam = (path4) => path4.queries?.length ? { name: "queries", type: objectType(path4.queries), ...withInit(allOptional(path4.queries) ? "{}" : void 0) } : void 0;
239
+ var cookiesParam = (path4) => path4.cookies?.length ? { name: "cookies", type: objectType(path4.cookies), ...withInit(allOptional(path4.cookies) ? "{}" : void 0) } : void 0;
240
+ var headersParam = (path4) => ({
241
+ name: "headers",
242
+ type: headersType(path4),
243
+ ...withInit(allOptional(path4.headers) ? "{ 'Content-Type': 'application/json' }" : void 0)
244
+ });
245
+ var serverParam = (path4) => path4.servers?.length ? { name: "server", type: serverUnion(path4.servers), ...withInit(serverDefault(path4.servers)) } : void 0;
246
+ var configParam = () => ({
247
+ name: "config",
248
+ type: "AxiosRequestConfig",
249
+ hasQuestionToken: true
250
+ });
251
+ var compact = (items) => items.filter((item) => item !== void 0);
252
+ var requestParams = (path4) => {
253
+ const forms = formsOf(path4);
254
+ return compact([
255
+ ...(path4.parameters ?? []).map((p) => ({ name: p.name, type: schemaToType(p.schema) })),
256
+ forms.length ? { name: "form", type: forms.map((form) => schemaToType(form.schema)).join(" | ") } : void 0,
257
+ queriesParam(path4),
258
+ cookiesParam(path4),
259
+ headersParam(path4),
260
+ serverParam(path4),
261
+ configParam()
262
+ ]);
263
+ };
264
+ var configParams = (path4) => compact([queriesParam(path4), cookiesParam(path4), headersParam(path4), serverParam(path4), configParam()]);
265
+ var requestVariables = (path4) => compact([
266
+ path4.queries?.length ? "queries" : void 0,
267
+ path4.cookies?.length ? "cookies" : void 0,
268
+ "headers",
269
+ path4.servers?.length ? "server" : void 0,
270
+ "config"
271
+ ]).join(", ");
272
+ var requestBody = (api, path4) => {
273
+ const forms = formsOf(path4);
274
+ const replaces = (path4.parameters ?? []).map((p) => `.replace("{${p.name}}", template('${p.name}', ${p.name}, '${p.style ?? "simple"}', ${p.explode ?? false}))`).join("");
275
+ void api;
276
+ return compact([
277
+ `const path = "${path4.path}"${replaces};`,
278
+ `const requestConfig = await this.#config.${path4.name}(${requestVariables(path4)});`,
279
+ forms.length ? "const _form = formData(headers['Content-Type'], form);" : void 0,
280
+ `return this.axios.${path4.method}(path, ${forms.length ? "_form, " : ""}requestConfig);`
281
+ ]);
282
+ };
283
+ var configBody = (api, path4) => {
284
+ const securities = path4.securities ?? [];
285
+ const params = compact([
286
+ "...config?.params,",
287
+ ...(path4.queries ?? []).map((q) => `...query("${q.name}", queries.${q.name}, '${q.style ?? "form"}', ${q.explode ?? false}),`),
288
+ ...securities.map((s) => s.type === "apiKey" && s.in === "query" ? `${s.key}: await this.security("${s.name}"),` : void 0)
289
+ ]);
290
+ const cookieStatements = compact([
291
+ ...(path4.cookies ?? []).map(
292
+ (c) => `if (cookies.${c.name}) { _cookies += Object.entries(query('${c.name}', cookies.${c.name}, 'form', ${c.explode ?? false})).reduce((pre, [key, value]) => \`\${pre}\${key}=\${value};\`, ''); }`
293
+ ),
294
+ ...securities.flatMap(
295
+ (s) => s.type === "apiKey" && s.in === "cookie" ? [
296
+ `const _cookie${s.name} = await this.security("${s.name}");`,
297
+ `if (_cookie${s.name}) { _cookies += \`${s.key}=\${_cookie${s.name}};\`; }`
298
+ ] : []
299
+ )
300
+ ]);
301
+ const headerStatements = compact([
302
+ ...(path4.headers ?? []).map(
303
+ (h) => `if (headers.${h.name}) { _headers['${h.name}'] = template('${h.name}', headers.${h.name}, 'simple', ${h.explode ?? false}); }`
304
+ ),
305
+ ...securities.map((s) => {
306
+ if (s.type === "apiKey" && s.in === "header") return `_headers['${s.key}'] = await this.security("${s.name}");`;
307
+ if (s.type === "http" && s.scheme === "bearer") return `_headers['Authorization'] = \`Bearer \${await this.security("${s.name}")}\`;`;
308
+ if (s.type === "oauth2" || s.type === "openIdConnect")
309
+ return `_headers['Authorization'] = \`Bearer \${await this.security("${s.name}", [${s.scopes.map((x) => `"${x}"`).join(", ")}])}\`;`;
310
+ return void 0;
311
+ })
312
+ ]);
313
+ const basic = securities.find((s) => s.type === "http" && s.scheme === "basic");
314
+ return [
315
+ `const params = { ${params.join(" ")} };`,
316
+ "let _cookies = config?.headers?.Cookie ?? '';",
317
+ ...cookieStatements,
318
+ "const _headers = Object.assign({ ...config?.headers, 'Content-Type': headers['Content-Type'] }, _cookies ? { Cookie: _cookies } : undefined);",
319
+ ...headerStatements,
320
+ `return { ...config, ${basic ? `auth: await this.security("${basic.name}"), ` : ""}baseURL: config?.baseURL ? config.baseURL : ${api.title}Config.server(server), params, headers: _headers };`
321
+ ];
322
+ };
323
+ var serverTypeAlias = (server) => {
324
+ const values = server.values?.length ? `; values: { ${server.values.map((v) => `${v.name}: ${v.enums?.length ? v.enums.map((e) => `'${e}'`).join(" | ") : "string"} `).join("")}}` : "";
325
+ return `{ name: "${server.name}"${values} }`;
326
+ };
327
+ var serverMethodStatements = (servers) => [
328
+ ...servers.map((server) => {
329
+ const replaces = (server.values ?? []).map((v) => `.replace('{${v.name}}', template('${v.name}', server.values.${v.name}, 'simple', false))`).join("");
330
+ return `if ('${server.name}' === server.name) { return '${server.url}'${replaces}; }`;
331
+ }),
332
+ "throw new Error('Undefined server. please define server.');"
333
+ ];
334
+ var utilImports = (api) => {
335
+ const meta = extractApiMeta(api);
336
+ return compact([meta.hasTemplate ? "template" : void 0, meta.hasQuery ? "query" : void 0, meta.hasFormData ? "formData" : void 0]);
337
+ };
338
+ var emitApi = (api, securities) => render((sf) => {
339
+ sf.addImportDeclaration({ namedImports: ["AxiosResponse", "AxiosRequestConfig"], moduleSpecifier: "axios" });
340
+ sf.addImportDeclaration({ namedImports: ["AbstractApi", "AbstractConfig"], moduleSpecifier: "./abstractApi" });
341
+ sf.addImportDeclaration({
342
+ namedImports: securities.length ? ["Config", "Security"] : ["Config"],
343
+ moduleSpecifier: "../config"
344
+ });
345
+ const utils = utilImports(api);
346
+ if (utils.length) sf.addImportDeclaration({ namedImports: utils, moduleSpecifier: "../utils" });
347
+ if (api.imports.length) sf.addImportDeclaration({ namedImports: api.imports.map((m) => m.title), moduleSpecifier: "../models" });
348
+ api.servers.forEach((server) => sf.addTypeAlias({ name: `${server.name}Server`, type: serverTypeAlias(server) }));
349
+ const apiClass = sf.addClass({ isExported: true, name: api.title, extends: "AbstractApi", docs: docs({ title: api.title }) });
350
+ apiClass.addProperty({ name: "#config", isReadonly: true, type: `${api.title}Config` });
351
+ apiClass.addConstructor({
352
+ docs: docs({ title: "constructor" }),
353
+ parameters: [{ name: "config", type: "Config", initializer: "{}" }],
354
+ statements: ["super(config);", `this.#config = new ${api.title}Config(${securities.length ? "config.security" : ""});`]
355
+ });
356
+ api.paths.forEach(
357
+ (path4) => apiClass.addMethod({
358
+ scope: Scope2.Public,
359
+ isAsync: true,
360
+ name: path4.name,
361
+ docs: docs({ title: path4.name, async: true }),
362
+ parameters: requestParams(path4),
363
+ returnType: `Promise<AxiosResponse${path4.schema ? `<${schemaToType(path4.schema)}>` : ""}>`,
364
+ statements: requestBody(api, path4)
365
+ })
366
+ );
367
+ const configClass = sf.addClass({ name: `${api.title}Config`, extends: "AbstractConfig" });
368
+ if (securities.length)
369
+ configClass.addConstructor({
370
+ parameters: [{ name: "security", type: "Security", initializer: "{}" }],
371
+ statements: ["super(security);"]
372
+ });
373
+ configClass.addMethod({
374
+ isStatic: true,
375
+ scope: Scope2.Private,
376
+ name: "server",
377
+ parameters: [{ name: "server", type: serverUnion(api.servers.length ? api.servers : api.paths[0]?.servers ?? []) }],
378
+ statements: serverMethodStatements(api.servers.length ? api.servers : api.paths[0]?.servers ?? [])
379
+ });
380
+ api.paths.forEach(
381
+ (path4) => configClass.addMethod({
382
+ scope: Scope2.Public,
383
+ isAsync: true,
384
+ name: path4.name,
385
+ parameters: configParams(path4),
386
+ returnType: "Promise<AxiosRequestConfig>",
387
+ statements: configBody(api, path4)
388
+ })
389
+ );
390
+ });
391
+ var emitApisIndex = (apis) => render((sf) => apis.forEach((api) => sf.addExportDeclaration({ moduleSpecifier: `./${api.filename}` })));
392
+
393
+ // src/generator/statics.ts
394
+ import path3 from "path";
395
+ import { readdir, readFile } from "fs/promises";
396
+
397
+ // src/paths.ts
398
+ import path2 from "path";
399
+ var paths = {
400
+ static: path2.resolve(import.meta.dirname, "static"),
401
+ tmp: path2.resolve(import.meta.dirname, "../tmp")
402
+ };
403
+ var paths_default = paths;
404
+
405
+ // src/generator/statics.ts
406
+ var emitStatics = async (outDir) => {
407
+ const dir = path3.join(paths_default.static, "utils");
408
+ const files = await readdir(dir);
409
+ await Promise.all(
410
+ files.map(async (file) => {
411
+ const text = await readFile(path3.join(dir, file), { encoding: "utf-8" });
412
+ await write(outDir, path3.join("utils", file), text);
413
+ })
414
+ );
415
+ };
416
+
69
417
  // src/generator/generate.ts
70
418
  var generate = async (openapi, settings) => {
71
419
  const { outDir } = settings;
72
- const promises = [];
73
- await setup();
74
420
  const { models, apis, securities } = await parser(openapi, settings);
421
+ const tasks = [];
75
422
  if (models.length) {
76
- promises.push(write("models/index.hbs", [outDir, "models", "index.ts"], models));
77
- const modelPromises = models.map((model) => write("models/model.hbs", [outDir, "models", `${model.filename}.ts`], model));
78
- promises.push(...modelPromises);
423
+ tasks.push(write(outDir, "models/index.ts", emitModelsIndex(models)));
424
+ models.forEach((model) => tasks.push(write(outDir, `models/${model.filename}.ts`, emitModel(model))));
79
425
  }
80
426
  if (apis.length) {
81
- promises.push(
82
- write("apis/index.hbs", [outDir, "apis", "index.ts"], apis),
83
- write("apis/abstractApi.hbs", [outDir, "apis", "abstractApi.ts"], { securities })
84
- );
85
- promises.push(...apis.map((api) => write("apis/api.hbs", [outDir, "apis", `${api.filename}.ts`], {
86
- api,
87
- meta: extractApiMeta(api),
88
- securities
89
- })));
427
+ tasks.push(write(outDir, "apis/index.ts", emitApisIndex(apis)));
428
+ tasks.push(write(outDir, "apis/abstractApi.ts", emitAbstractApi(securities)));
429
+ apis.forEach((api) => tasks.push(write(outDir, `apis/${api.filename}.ts`, emitApi(api, securities))));
90
430
  }
91
- promises.push(
92
- write("index.hbs", [outDir, "index.ts"], { api: apis.length, model: models.length }),
93
- write("config.hbs", [outDir, "config.ts"], { securities }),
94
- write("utils/index.hbs", [outDir, "utils", "index.ts"]),
95
- write("utils/template.hbs", [outDir, "utils", "template.ts"]),
96
- write("utils/query.hbs", [outDir, "utils", "query.ts"]),
97
- write("utils/formData.hbs", [outDir, "utils", "formData.ts"])
98
- );
99
- return Promise.all(promises);
431
+ tasks.push(write(outDir, "index.ts", emitIndex(models.length > 0, apis.length > 0)));
432
+ tasks.push(write(outDir, "config.ts", emitConfig(securities)));
433
+ tasks.push(emitStatics(outDir));
434
+ return Promise.all(tasks);
100
435
  };
101
436
 
102
437
  // src/index.ts
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/generator/generate.ts","../src/generator/writer.ts","../src/paths.ts","../src/generator/setup.ts","../src/generator/register.ts","../src/extractors/api.ts","../src/index.ts"],"sourcesContent":["import {AutomatonSettings, Openapi} from \"@automatons/tools\";\nimport {parser} from \"@automatons/parser\";\nimport {write} from \"./writer\";\nimport {setup} from \"./setup\";\nimport {extractApiMeta} from \"../extractors/api\";\n\n\nexport const generate = async (openapi: Openapi, settings: AutomatonSettings) => {\n const {outDir} = settings;\n const promises: Promise<void>[] = [];\n await setup();\n\n const {models, apis, securities} = await parser(openapi, settings);\n if (models.length) {\n promises.push(write('models/index.hbs', [outDir, 'models', 'index.ts'], models))\n const modelPromises = models\n .map(model => write('models/model.hbs', [outDir, 'models', `${model.filename}.ts`], model));\n promises.push(...modelPromises)\n }\n\n if (apis.length) {\n promises.push(\n write('apis/index.hbs', [outDir, 'apis', 'index.ts'], apis),\n write('apis/abstractApi.hbs', [outDir, 'apis', 'abstractApi.ts'], {securities}),\n );\n promises.push(...apis.map(api => write('apis/api.hbs', [outDir, 'apis', `${api.filename}.ts`], {\n api,\n meta: extractApiMeta(api),\n securities\n })));\n }\n\n promises.push(\n write('index.hbs', [outDir, 'index.ts'], {api: apis.length, model: models.length}),\n write('config.hbs', [outDir, 'config.ts'], {securities}),\n write('utils/index.hbs', [outDir, 'utils', 'index.ts']),\n write('utils/template.hbs', [outDir, 'utils', 'template.ts']),\n write('utils/query.hbs', [outDir, 'utils', 'query.ts']),\n write('utils/formData.hbs', [outDir, 'utils', 'formData.ts'])\n );\n return Promise.all(promises)\n};\n","import path from \"node:path\";\nimport {mkdir, readFile, writeFile} from \"node:fs/promises\";\nimport {format} from \"prettier\";\nimport Handlebars from \"handlebars\";\nimport paths from \"../paths\";\n\nexport const write = async (template: string, outDir: string | string[], context?: any) => {\n const outputPath = Array.isArray(outDir) ? path.resolve(...outDir) : outDir;\n await mkdir(path.dirname(outputPath), {recursive: true});\n const data = await readFile(path.resolve(paths.templates, template), {encoding: 'utf-8'});\n const formatted = await format(Handlebars.compile(data)(context), {parser: 'typescript'});\n return writeFile(outputPath, formatted);\n};\n","import path from 'node:path';\n\nconst paths = {\n src: path.resolve(import.meta.dirname),\n templates: path.resolve(import.meta.dirname, 'templates'),\n tmp: path.resolve(import.meta.dirname, '../tmp')\n};\nexport default paths;\n","import helpers from \"handlebars-helpers\";\nimport HB from \"handlebars\";\nimport {register} from \"./register\";\n\nHB.registerHelper('every', function (value: Record<string, unknown>[], key: string, text?: unknown) {\n if (text === undefined) {\n return value.every(item => (item[key] == undefined ? false : item[key]))\n }\n return value.every(item => (item[key] == undefined ? false : item[key]) === text)\n});\n\nHB.registerHelper('any', function (value: Record<string, unknown>[], key: string, text?: unknown) {\n if (text === undefined) {\n return value.some(item => (item[key] == undefined ? false : item[key]))\n }\n return value.some(item => (item[key] == undefined ? false : item[key]) === text)\n});\n\nhelpers({handlebars: HB});\nexport const setup = () => register();\n","import {readFile} from \"node:fs/promises\";\nimport {glob} from 'glob';\nimport Handlebars from \"handlebars\";\nimport paths from \"../paths\";\n\nconst partial = Handlebars.registerPartial.bind(Handlebars);\n\nconst convertName = (match: string) =>\n match.replace(`${paths.templates}/`, '')\n .replace('partials/', '')\n .replace('.hbs', '');\n\nexport const register = () =>\n glob('**/partials/**/*.hbs', {cwd: paths.templates, absolute: true})\n .then(matches => matches.map<{ name: string, path: string }>(match =>\n ({name: convertName(match), path: match})))\n .then(files => Promise.all(\n files.map(({name, path}) => readFile(path, {encoding: 'utf-8'})\n .then(data => partial(name, data))))\n );\n","import {AffectPath, Api, Path} from \"@automatons/parser\";\n\nconst isAffectPath = (path: Path): path is AffectPath => ['post', 'patch', 'put'].includes(path.method);\n\nexport const extractApiMeta = (api: Api) => {\n const hasTemplate = api.servers.some(server => server.values?.length)\n || api.paths.some(path => path.parameters?.length)\n || api.paths.some(path => path.headers?.length);\n const hasQuery = api.paths.some(path => path.queries?.length)\n || api.paths.some(path => path.cookies?.length);\n const hasFormData = api.paths.some(path => isAffectPath(path) ? path.forms?.length : false);\n return {hasQuery, hasTemplate, hasFormData};\n};\n","import {Automaton} from \"@automatons/tools\";\nimport {generate} from \"./generator\";\n\nconst generatorTypescriptAxiosClient: Automaton = (openapi, settings) =>\n generate(openapi, settings);\n\nexport default generatorTypescriptAxiosClient;\n"],"mappings":"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","names":["path","path","readFile","Handlebars","Handlebars","path","readFile","path"]}
1
+ {"version":3,"sources":["../src/generator/generate.ts","../src/generator/render.ts","../src/generator/schema.ts","../src/generator/comment.ts","../src/generator/model.ts","../src/generator/config.ts","../src/generator/abstractApi.ts","../src/generator/api.ts","../src/extractors/api.ts","../src/generator/statics.ts","../src/paths.ts","../src/index.ts"],"sourcesContent":["import {AutomatonSettings, Openapi} from \"@automatons/tools\";\nimport {parser} from \"@automatons/parser\";\nimport {write} from \"./render\";\nimport {emitModel, emitModelsIndex} from \"./model\";\nimport {emitConfig, emitIndex} from \"./config\";\nimport {emitAbstractApi} from \"./abstractApi\";\nimport {emitApi, emitApisIndex} from \"./api\";\nimport {emitStatics} from \"./statics\";\n\nexport const generate = async (openapi: Openapi, settings: AutomatonSettings): Promise<void[]> => {\n const {outDir} = settings;\n const {models, apis, securities} = await parser(openapi, settings);\n const tasks: Promise<void>[] = [];\n\n if (models.length) {\n tasks.push(write(outDir, \"models/index.ts\", emitModelsIndex(models)));\n models.forEach((model) => tasks.push(write(outDir, `models/${model.filename}.ts`, emitModel(model))));\n }\n\n if (apis.length) {\n tasks.push(write(outDir, \"apis/index.ts\", emitApisIndex(apis)));\n tasks.push(write(outDir, \"apis/abstractApi.ts\", emitAbstractApi(securities)));\n apis.forEach((api) => tasks.push(write(outDir, `apis/${api.filename}.ts`, emitApi(api, securities))));\n }\n\n tasks.push(write(outDir, \"index.ts\", emitIndex(models.length > 0, apis.length > 0)));\n tasks.push(write(outDir, \"config.ts\", emitConfig(securities)));\n tasks.push(emitStatics(outDir));\n\n return Promise.all(tasks);\n};\n","import path from \"node:path\";\nimport {mkdir, writeFile} from \"node:fs/promises\";\nimport {IndentationText, Project, QuoteKind, SourceFile} from \"ts-morph\";\nimport {format} from \"prettier\";\n\nconst project = new Project({\n useInMemoryFileSystem: true,\n manipulationSettings: {\n quoteKind: QuoteKind.Double,\n indentationText: IndentationText.TwoSpaces,\n useTrailingCommas: true,\n },\n});\n\nlet counter = 0;\n\n/**\n * Build a TypeScript source string by manipulating a throwaway ts-morph SourceFile.\n */\nexport const render = (build: (sf: SourceFile) => void): string => {\n const sf = project.createSourceFile(`__gen_${counter++}.ts`, \"\", {overwrite: true});\n build(sf);\n const text = sf.getFullText();\n project.removeSourceFile(sf);\n return text;\n};\n\n/**\n * Format with prettier and write the file under outDir.\n */\nexport const write = async (outDir: string, relPath: string, text: string): Promise<void> => {\n const outputPath = path.resolve(outDir, relPath);\n await mkdir(path.dirname(outputPath), {recursive: true});\n const formatted = await format(text, {parser: \"typescript\"});\n await writeFile(outputPath, formatted, {encoding: \"utf-8\"});\n};\n","import {Schema} from \"@automatons/parser\";\n\nconst quoteKey = (name: string): string => (name.includes(\"-\") ? `\"${name}\"` : name);\n\nconst nullable = (schema: {nullable?: boolean}): string => (schema.nullable ? \" | null\" : \"\");\n\n/**\n * Render a parser Schema (a discriminated union) as a TypeScript type string.\n * Mirrors the previous models/* handlebars partials.\n */\nexport const schemaToType = (schema: Schema): string => {\n switch (schema.type) {\n case \"model\":\n return schema.name;\n case \"object\": {\n if (schema.properties && schema.properties.length) {\n const props = schema.properties\n .map(\n (property) =>\n `/**\\n * ${property.name}\\n */\\n${quoteKey(property.name)}${\n property.required ? \"\" : \"?\"\n }: ${schemaToType(property.schema)};`,\n )\n .join(\"\\n\");\n return `{\\n${props}\\n}${nullable(schema)}`;\n }\n return `object${nullable(schema)}`;\n }\n case \"allOf\":\n return `(${schema.schemas.map(schemaToType).join(\" & \")})`;\n case \"oneOf\":\n return `(${schema.schemas.map(schemaToType).join(\" | \")})`;\n case \"array\":\n return `${schema.items ? `Array<${schemaToType(schema.items)}>` : \"any[]\"}${nullable(schema)}`;\n case \"boolean\":\n return `boolean${nullable(schema)}`;\n case \"string\": {\n const base =\n schema.enum && schema.enum.length\n ? schema.enum.map((value) => `\"${value}\"`).join(\" | \")\n : schema.format === \"date\" || schema.format === \"date-time\"\n ? \"Date\"\n : schema.format === \"url\"\n ? \"URL\"\n : \"string\";\n return `${base}${nullable(schema)}`;\n }\n case \"integer\":\n case \"number\": {\n const base = schema.enum && schema.enum.length ? schema.enum.join(\" | \") : \"number\";\n return `${base}${nullable(schema)}`;\n }\n default:\n throw new Error(`Unsupported schema type: ${(schema as {type: string}).type}`);\n }\n};\n","import {OptionalKind, JSDocStructure, JSDocTagStructure} from \"ts-morph\";\n\nexport type CommentOptions = {\n title: string;\n async?: boolean;\n description?: string;\n deprecated?: boolean;\n readOnly?: boolean;\n};\n\n/**\n * Build a ts-morph JSDoc structure mirroring the previous comment partial.\n */\nexport const docs = (options: CommentOptions): OptionalKind<JSDocStructure>[] => {\n const tags: OptionalKind<JSDocTagStructure>[] = [];\n if (options.async) tags.push({tagName: \"async\"});\n if (options.description) tags.push({tagName: \"description\", text: options.description});\n if (options.deprecated) tags.push({tagName: \"deprecated\"});\n if (options.readOnly) tags.push({tagName: \"readonly\"});\n return [{description: options.title, tags}];\n};\n","import {Model} from \"@automatons/parser\";\nimport {render} from \"./render\";\nimport {schemaToType} from \"./schema\";\nimport {docs} from \"./comment\";\n\n/**\n * Emit a single model file: imports for referenced models + an exported type alias.\n */\nexport const emitModel = (model: Model): string =>\n render((sf) => {\n model.imports.forEach((imported) =>\n sf.addImportDeclaration({\n namedImports: [imported.title],\n moduleSpecifier: `./${imported.filename}`,\n }),\n );\n sf.addTypeAlias({\n isExported: true,\n name: model.title,\n type: schemaToType(model.schema),\n docs: docs({title: model.title}),\n });\n });\n\n/**\n * Emit models/index.ts re-exporting every model.\n */\nexport const emitModelsIndex = (models: Model[]): string =>\n render((sf) =>\n models.forEach((model) => sf.addExportDeclaration({moduleSpecifier: `./${model.filename}`})),\n );\n","import {Security} from \"@automatons/parser\";\nimport {render} from \"./render\";\n\nconst callable = (returns: string, arg = \"\"): string =>\n `${returns} | Promise<${returns}> | ((${arg}) => ${returns} | Promise<${returns}>)`;\n\nconst securityType = (security: Security): string => {\n if (security.type === \"http\" && security.scheme === \"basic\") {\n const basic = \"{username: string; password: string;}\";\n return `${security.name}?: ${callable(basic)};`;\n }\n if (security.type === \"oauth2\" || security.type === \"openIdConnect\") {\n return `${security.name}?: ${callable(\"string\", \"scopes?: string[]\")};`;\n }\n return `${security.name}?: ${callable(\"string\")};`;\n};\n\n/**\n * Emit config.ts: the Security map type and the Config type.\n */\nexport const emitConfig = (securities: Security[]): string =>\n render((sf) => {\n sf.addImportDeclaration({namedImports: [\"AxiosInstance\"], moduleSpecifier: \"axios\"});\n sf.addTypeAlias({\n isExported: true,\n name: \"Security\",\n type: `{\\n${securities.map(securityType).join(\"\\n\")}\\n}`,\n });\n sf.addTypeAlias({\n isExported: true,\n name: \"Config\",\n type: `{\n axios?: AxiosInstance;\n token?: string | Promise<string> | (() => string | Promise<string>);\n security?: Security;\n}`,\n });\n });\n\n/**\n * Emit the top-level index.ts.\n */\nexport const emitIndex = (hasModels: boolean, hasApis: boolean): string =>\n render((sf) => {\n if (hasModels) sf.addExportDeclaration({moduleSpecifier: \"./models\"});\n if (hasApis) sf.addExportDeclaration({moduleSpecifier: \"./apis\"});\n sf.addExportDeclaration({moduleSpecifier: \"./config\"});\n });\n","import {Security} from \"@automatons/parser\";\nimport {OptionalKind, MethodDeclarationOverloadStructure, Scope} from \"ts-morph\";\nimport {render} from \"./render\";\nimport {docs} from \"./comment\";\n\nconst BASE_STATEMENTS = [\n \"const DateFormat = /^\\\\d{4}-\\\\d{2}-\\\\d{2}([tT]\\\\d{2}:\\\\d{2}:\\\\d{2}(Z|[+-]\\\\d{2}:\\\\d{2})|Z)?$/;\",\n \"const reviver = (_key: string, value: any) => typeof value === 'string' && DateFormat.test(value) ? new Date(value) : value;\",\n \"const BASE_AXIOS = Axios.create({ transformResponse: (data) => JSON.parse(data, reviver) });\",\n];\n\nconst overload = (security: Security): OptionalKind<MethodDeclarationOverloadStructure> => {\n const base = {scope: Scope.Protected, isAsync: true};\n if (security.type === \"http\" && security.scheme === \"basic\") {\n return {\n ...base,\n parameters: [{name: \"key\", type: `\"${security.name}\"`}],\n returnType: \"Promise<{username: string; password: string;}>\",\n };\n }\n if (security.type === \"oauth2\" || security.type === \"openIdConnect\") {\n return {\n ...base,\n parameters: [{name: \"key\", type: `\"${security.name}\"`}, {name: \"scopes\", type: \"string[]\"}],\n returnType: \"Promise<string>\",\n };\n }\n return {...base, parameters: [{name: \"key\", type: `\"${security.name}\"`}], returnType: \"Promise<string>\"};\n};\n\n/**\n * Emit apis/abstractApi.ts: the shared axios setup plus the AbstractConfig / AbstractApi base classes.\n */\nexport const emitAbstractApi = (securities: Security[]): string =>\n render((sf) => {\n sf.addImportDeclaration({defaultImport: \"Axios\", namedImports: [\"AxiosInstance\"], moduleSpecifier: \"axios\"});\n sf.addImportDeclaration({\n isTypeOnly: true,\n namedImports: securities.length ? [\"Config\", \"Security\"] : [\"Config\"],\n moduleSpecifier: \"../config\",\n });\n sf.addStatements(BASE_STATEMENTS);\n\n const abstractConfig = sf.addClass({isExported: true, name: \"AbstractConfig\", docs: docs({title: \"AbstractConfig\"})});\n if (securities.length) {\n abstractConfig.addProperty({name: \"#security\", isReadonly: true, type: \"Security\"});\n abstractConfig.addConstructor({\n docs: docs({title: \"constructor\"}),\n parameters: [{name: \"security\", type: \"Security\", initializer: \"{}\"}],\n statements: [\"this.#security = security;\"],\n });\n const scoped = securities.some((s) => s.type === \"oauth2\" || s.type === \"openIdConnect\");\n abstractConfig.addMethod({\n scope: Scope.Protected,\n isAsync: true,\n name: \"security\",\n overloads: securities.map(overload),\n parameters: [\n {name: \"key\", type: \"keyof Security\"},\n ...(scoped ? [{name: \"scopes\", type: \"string[]\", hasQuestionToken: true}] : []),\n ],\n returnType: \"Promise<string | {username: string; password: string;}>\",\n statements: [\n \"const security = this.#security[key];\",\n 'if (!security) { throw new Error(\"Unauthorized user request.\"); }',\n `else if (security instanceof Function) { ${scoped ? \"return scopes ? security(scopes) : security();\" : \"return security();\"} }`,\n \"return security;\",\n ],\n });\n }\n\n const abstractApi = sf.addClass({isExported: true, name: \"AbstractApi\", docs: docs({title: \"AbstractApi\"})});\n abstractApi.addProperty({scope: Scope.Protected, name: \"axios\", type: \"AxiosInstance\", initializer: \"BASE_AXIOS\"});\n abstractApi.addConstructor({\n docs: docs({title: \"constructor\"}),\n parameters: [{name: \"{axios}\", type: \"Config\"}],\n statements: [\"if (axios) this.axios = axios;\"],\n });\n });\n","import {AffectPath, Api, Path, Schema, Security, Server} from \"@automatons/parser\";\nimport {OptionalKind, ParameterDeclarationStructure, Scope} from \"ts-morph\";\nimport {render} from \"./render\";\nimport {schemaToType} from \"./schema\";\nimport {docs} from \"./comment\";\nimport {extractApiMeta} from \"../extractors/api\";\n\nconst isAffect = (path: Path): path is AffectPath => [\"post\", \"put\", \"patch\"].includes(path.method);\nconst formsOf = (path: Path): NonNullable<AffectPath[\"forms\"]> => (isAffect(path) && path.forms ? path.forms : []);\n\ntype Entry = {name: string; required?: boolean; schema: Schema};\nconst objectType = (entries: ReadonlyArray<Entry>): string =>\n `{ ${entries.map((e) => `${e.name}${e.required ? \"\" : \"?\"}: ${schemaToType(e.schema)}, `).join(\"\")}}`;\nconst allOptional = (entries: ReadonlyArray<{required?: boolean}> = []): boolean => entries.every((e) => !e.required);\n\nconst contentType = (path: Path): string => {\n const forms = formsOf(path);\n return forms.length\n ? forms.map((form) => form.types.map((type) => `'${type}'`).join(\" | \")).join(\" | \")\n : \"'application/json'\";\n};\nconst headersType = (path: Path): string =>\n `{ 'Content-Type': ${contentType(path)}, ${(path.headers ?? [])\n .map((h) => `${h.name}${h.required ? \"\" : \"?\"}: ${schemaToType(h.schema)}, `)\n .join(\"\")}}`;\n\nconst serverUnion = (servers: Server[]): string => servers.map((server) => `${server.name}Server`).join(\" | \");\nconst serverDefault = (servers: Server[]): string | undefined => {\n const [first] = servers;\n return servers.length === 1 && first && !(first.values && first.values.length)\n ? `{ name: '${first.name}' }`\n : undefined;\n};\n\nconst withInit = (init?: string): {initializer: string} | object => (init ? {initializer: init} : {});\n\nconst queriesParam = (path: Path): OptionalKind<ParameterDeclarationStructure> | undefined =>\n path.queries?.length\n ? {name: \"queries\", type: objectType(path.queries), ...withInit(allOptional(path.queries) ? \"{}\" : undefined)}\n : undefined;\nconst cookiesParam = (path: Path): OptionalKind<ParameterDeclarationStructure> | undefined =>\n path.cookies?.length\n ? {name: \"cookies\", type: objectType(path.cookies), ...withInit(allOptional(path.cookies) ? \"{}\" : undefined)}\n : undefined;\nconst headersParam = (path: Path): OptionalKind<ParameterDeclarationStructure> => ({\n name: \"headers\",\n type: headersType(path),\n ...withInit(allOptional(path.headers) ? \"{ 'Content-Type': 'application/json' }\" : undefined),\n});\nconst serverParam = (path: Path): OptionalKind<ParameterDeclarationStructure> | undefined =>\n path.servers?.length\n ? {name: \"server\", type: serverUnion(path.servers), ...withInit(serverDefault(path.servers))}\n : undefined;\nconst configParam = (): OptionalKind<ParameterDeclarationStructure> => ({\n name: \"config\",\n type: \"AxiosRequestConfig\",\n hasQuestionToken: true,\n});\nconst compact = <T>(items: (T | undefined)[]): T[] => items.filter((item): item is T => item !== undefined);\n\nconst requestParams = (path: Path): OptionalKind<ParameterDeclarationStructure>[] => {\n const forms = formsOf(path);\n return compact([\n ...(path.parameters ?? []).map((p) => ({name: p.name, type: schemaToType(p.schema)})),\n forms.length ? {name: \"form\", type: forms.map((form) => schemaToType(form.schema)).join(\" | \")} : undefined,\n queriesParam(path),\n cookiesParam(path),\n headersParam(path),\n serverParam(path),\n configParam(),\n ]);\n};\nconst configParams = (path: Path): OptionalKind<ParameterDeclarationStructure>[] =>\n compact([queriesParam(path), cookiesParam(path), headersParam(path), serverParam(path), configParam()]);\n\nconst requestVariables = (path: Path): string =>\n compact([\n path.queries?.length ? \"queries\" : undefined,\n path.cookies?.length ? \"cookies\" : undefined,\n \"headers\",\n path.servers?.length ? \"server\" : undefined,\n \"config\",\n ]).join(\", \");\n\nconst requestBody = (api: Api, path: Path): string[] => {\n const forms = formsOf(path);\n const replaces = (path.parameters ?? [])\n .map((p) => `.replace(\"{${p.name}}\", template('${p.name}', ${p.name}, '${p.style ?? \"simple\"}', ${p.explode ?? false}))`)\n .join(\"\");\n void api;\n return compact([\n `const path = \"${path.path}\"${replaces};`,\n `const requestConfig = await this.#config.${path.name}(${requestVariables(path)});`,\n forms.length ? \"const _form = formData(headers['Content-Type'], form);\" : undefined,\n `return this.axios.${path.method}(path, ${forms.length ? \"_form, \" : \"\"}requestConfig);`,\n ]);\n};\n\nconst configBody = (api: Api, path: Path): string[] => {\n const securities = path.securities ?? [];\n const params = compact([\n \"...config?.params,\",\n ...(path.queries ?? []).map((q) => `...query(\"${q.name}\", queries.${q.name}, '${q.style ?? \"form\"}', ${q.explode ?? false}),`),\n ...securities.map((s) => (s.type === \"apiKey\" && s.in === \"query\" ? `${s.key}: await this.security(\"${s.name}\"),` : undefined)),\n ]);\n const cookieStatements = compact<string>([\n ...(path.cookies ?? []).map(\n (c) =>\n `if (cookies.${c.name}) { _cookies += Object.entries(query('${c.name}', cookies.${c.name}, 'form', ${c.explode ?? false})).reduce((pre, [key, value]) => \\`\\${pre}\\${key}=\\${value};\\`, ''); }`,\n ),\n ...securities.flatMap((s) =>\n s.type === \"apiKey\" && s.in === \"cookie\"\n ? [\n `const _cookie${s.name} = await this.security(\"${s.name}\");`,\n `if (_cookie${s.name}) { _cookies += \\`${s.key}=\\${_cookie${s.name}};\\`; }`,\n ]\n : [],\n ),\n ]);\n const headerStatements = compact<string>([\n ...(path.headers ?? []).map(\n (h) => `if (headers.${h.name}) { _headers['${h.name}'] = template('${h.name}', headers.${h.name}, 'simple', ${h.explode ?? false}); }`,\n ),\n ...securities.map((s) => {\n if (s.type === \"apiKey\" && s.in === \"header\") return `_headers['${s.key}'] = await this.security(\"${s.name}\");`;\n if (s.type === \"http\" && s.scheme === \"bearer\") return `_headers['Authorization'] = \\`Bearer \\${await this.security(\"${s.name}\")}\\`;`;\n if (s.type === \"oauth2\" || s.type === \"openIdConnect\")\n return `_headers['Authorization'] = \\`Bearer \\${await this.security(\"${s.name}\", [${s.scopes.map((x) => `\"${x}\"`).join(\", \")}])}\\`;`;\n return undefined;\n }),\n ]);\n const basic = securities.find((s): s is Extract<Security, {type: \"http\"}> => s.type === \"http\" && s.scheme === \"basic\");\n return [\n `const params = { ${params.join(\" \")} };`,\n \"let _cookies = config?.headers?.Cookie ?? '';\",\n ...cookieStatements,\n \"const _headers = Object.assign({ ...config?.headers, 'Content-Type': headers['Content-Type'] }, _cookies ? { Cookie: _cookies } : undefined);\",\n ...headerStatements,\n `return { ...config, ${basic ? `auth: await this.security(\"${basic.name}\"), ` : \"\"}baseURL: config?.baseURL ? config.baseURL : ${api.title}Config.server(server), params, headers: _headers };`,\n ];\n};\n\nconst serverTypeAlias = (server: Server): string => {\n const values = server.values?.length\n ? `; values: { ${server.values\n .map((v) => `${v.name}: ${v.enums?.length ? v.enums.map((e) => `'${e}'`).join(\" | \") : \"string\"} `)\n .join(\"\")}}`\n : \"\";\n return `{ name: \"${server.name}\"${values} }`;\n};\n\nconst serverMethodStatements = (servers: Server[]): string[] => [\n ...servers.map((server) => {\n const replaces = (server.values ?? [])\n .map((v) => `.replace('{${v.name}}', template('${v.name}', server.values.${v.name}, 'simple', false))`)\n .join(\"\");\n return `if ('${server.name}' === server.name) { return '${server.url}'${replaces}; }`;\n }),\n \"throw new Error('Undefined server. please define server.');\",\n];\n\nconst utilImports = (api: Api): string[] => {\n const meta = extractApiMeta(api);\n return compact([meta.hasTemplate ? \"template\" : undefined, meta.hasQuery ? \"query\" : undefined, meta.hasFormData ? \"formData\" : undefined]);\n};\n\n/**\n * Emit a single api file: the typed axios client class and its request-config class.\n */\nexport const emitApi = (api: Api, securities: Security[]): string =>\n render((sf) => {\n sf.addImportDeclaration({namedImports: [\"AxiosResponse\", \"AxiosRequestConfig\"], moduleSpecifier: \"axios\"});\n sf.addImportDeclaration({namedImports: [\"AbstractApi\", \"AbstractConfig\"], moduleSpecifier: \"./abstractApi\"});\n sf.addImportDeclaration({\n namedImports: securities.length ? [\"Config\", \"Security\"] : [\"Config\"],\n moduleSpecifier: \"../config\",\n });\n const utils = utilImports(api);\n if (utils.length) sf.addImportDeclaration({namedImports: utils, moduleSpecifier: \"../utils\"});\n if (api.imports.length) sf.addImportDeclaration({namedImports: api.imports.map((m) => m.title), moduleSpecifier: \"../models\"});\n\n api.servers.forEach((server) => sf.addTypeAlias({name: `${server.name}Server`, type: serverTypeAlias(server)}));\n\n const apiClass = sf.addClass({isExported: true, name: api.title, extends: \"AbstractApi\", docs: docs({title: api.title})});\n apiClass.addProperty({name: \"#config\", isReadonly: true, type: `${api.title}Config`});\n apiClass.addConstructor({\n docs: docs({title: \"constructor\"}),\n parameters: [{name: \"config\", type: \"Config\", initializer: \"{}\"}],\n statements: [\"super(config);\", `this.#config = new ${api.title}Config(${securities.length ? \"config.security\" : \"\"});`],\n });\n api.paths.forEach((path) =>\n apiClass.addMethod({\n scope: Scope.Public,\n isAsync: true,\n name: path.name,\n docs: docs({title: path.name, async: true}),\n parameters: requestParams(path),\n returnType: `Promise<AxiosResponse${path.schema ? `<${schemaToType(path.schema)}>` : \"\"}>`,\n statements: requestBody(api, path),\n }),\n );\n\n const configClass = sf.addClass({name: `${api.title}Config`, extends: \"AbstractConfig\"});\n if (securities.length)\n configClass.addConstructor({\n parameters: [{name: \"security\", type: \"Security\", initializer: \"{}\"}],\n statements: [\"super(security);\"],\n });\n configClass.addMethod({\n isStatic: true,\n scope: Scope.Private,\n name: \"server\",\n parameters: [{name: \"server\", type: serverUnion(api.servers.length ? api.servers : api.paths[0]?.servers ?? [])}],\n statements: serverMethodStatements(api.servers.length ? api.servers : api.paths[0]?.servers ?? []),\n });\n api.paths.forEach((path) =>\n configClass.addMethod({\n scope: Scope.Public,\n isAsync: true,\n name: path.name,\n parameters: configParams(path),\n returnType: \"Promise<AxiosRequestConfig>\",\n statements: configBody(api, path),\n }),\n );\n });\n\n/**\n * Emit apis/index.ts re-exporting every api.\n */\nexport const emitApisIndex = (apis: Api[]): string =>\n render((sf) => apis.forEach((api) => sf.addExportDeclaration({moduleSpecifier: `./${api.filename}`})));\n","import {AffectPath, Api, Path} from \"@automatons/parser\";\n\nconst isAffectPath = (path: Path): path is AffectPath => ['post', 'patch', 'put'].includes(path.method);\n\nexport const extractApiMeta = (api: Api) => {\n const hasTemplate = api.servers.some(server => server.values?.length)\n || api.paths.some(path => path.parameters?.length)\n || api.paths.some(path => path.headers?.length);\n const hasQuery = api.paths.some(path => path.queries?.length)\n || api.paths.some(path => path.cookies?.length);\n const hasFormData = api.paths.some(path => isAffectPath(path) ? path.forms?.length : false);\n return {hasQuery, hasTemplate, hasFormData};\n};\n","import path from \"node:path\";\nimport {readdir, readFile} from \"node:fs/promises\";\nimport paths from \"../paths\";\nimport {write} from \"./render\";\n\n/**\n * Copy the static utility files (template/query/formData/index) into the output.\n */\nexport const emitStatics = async (outDir: string): Promise<void> => {\n const dir = path.join(paths.static, \"utils\");\n const files = await readdir(dir);\n await Promise.all(\n files.map(async (file) => {\n const text = await readFile(path.join(dir, file), {encoding: \"utf-8\"});\n await write(outDir, path.join(\"utils\", file), text);\n }),\n );\n};\n","import path from \"node:path\";\n\nconst paths = {\n static: path.resolve(import.meta.dirname, \"static\"),\n tmp: path.resolve(import.meta.dirname, \"../tmp\"),\n};\nexport default paths;\n","import {Automaton} from \"@automatons/tools\";\nimport {generate} from \"./generator\";\n\nconst generatorTypescriptAxiosClient: Automaton = (openapi, settings) =>\n generate(openapi, settings);\n\nexport default generatorTypescriptAxiosClient;\n"],"mappings":"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","names":["Scope","path","path","Scope","path","path","path"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automatons/typescript-client-axios",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "repository": "https://github.com/openapi-automatons/typescript-client-axios.git",
5
5
  "author": "tanmen <yt.prog@gmail.com>",
6
6
  "license": "MIT",
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "scripts": {
28
28
  "prebuild": "depcheck",
29
- "build": "tsup && cp -R src/templates dist/ && cp package.json README.md LICENSE dist",
29
+ "build": "tsup && cp -R src/static dist/ && cp package.json README.md LICENSE dist",
30
30
  "lint": "eslint src",
31
31
  "test": "vitest run",
32
32
  "test:watch": "vitest",
@@ -37,10 +37,8 @@
37
37
  "dependencies": {
38
38
  "@automatons/parser": "^1.0.0",
39
39
  "@automatons/tools": "^2.0.0",
40
- "glob": "^13.0.6",
41
- "handlebars": "^4.7.9",
42
- "handlebars-helpers": "^0.10.0",
43
- "prettier": "^3.8.3"
40
+ "prettier": "^3.8.3",
41
+ "ts-morph": "^28.0.0"
44
42
  },
45
43
  "peerDependencies": {
46
44
  "axios": "^0 || ^1",
@@ -50,10 +48,9 @@
50
48
  "devDependencies": {
51
49
  "@commitlint/cli": "^21.0.2",
52
50
  "@commitlint/config-conventional": "^21.0.2",
53
- "@eslint/js": "^9.39.0",
51
+ "@eslint/js": "^10.0.1",
54
52
  "@semantic-release/changelog": "^6.0.3",
55
53
  "@semantic-release/git": "^10.0.1",
56
- "@types/handlebars-helpers": "^0.5.6",
57
54
  "@types/node": "^24.0.0",
58
55
  "@vitest/coverage-v8": "^3.2.0",
59
56
  "axios": "^1",
@@ -1,63 +0,0 @@
1
- import Axios, { AxiosInstance } from "axios";
2
- import type { Config{{#if securities}}, Security{{/if}} } from "../config";
3
-
4
- const DateFormat = /^\d{4}-\d{2}-\d{2}([tT]\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})|Z)?$/;
5
- const reviver = (_key: string, value: any) =>
6
- typeof value === 'string' && DateFormat.test(value) ? new Date(value) : value;
7
-
8
- const BASE_AXIOS = Axios.create({
9
- transformResponse: (data) => JSON.parse(data, reviver)
10
- });
11
-
12
- /**
13
- * AbstractConfig
14
- */
15
- export class AbstractConfig {
16
- {{#if securities}}
17
- readonly #security: Security;
18
-
19
- /**
20
- * constructor
21
- */
22
- constructor(security: Security = {}) {
23
- this.#security = security;
24
- }
25
-
26
- {{#each securities}}
27
- {{#and (eq type 'http') (eq scheme 'basic')}}
28
- protected async security(key: "{{name}}"): Promise<{username: string; password: string;}>;
29
- {{else or (eq type 'oauth2') (eq type 'openIdConnect')}}
30
- protected async security(key: "{{name}}", scopes: string[]): Promise<string>;
31
- {{else}}
32
- protected async security(key: "{{name}}"): Promise<string>;
33
- {{/and}}
34
- {{/each}}
35
- protected async security(key: keyof Security{{#or (any securities 'type' 'oauth2') (any securities 'type' 'openIdConnect')}}, scopes?: string[]{{/or}}): Promise<string | {username: string; password: string;}> {
36
- const security = this.#security[key];
37
- if (!security) {
38
- throw new Error("Unauthorized user request.");
39
- } else if (security instanceof Function) {
40
- {{#or (any securities 'type' 'oauth2') (any securities 'type' 'openIdConnect')}}
41
- return scopes ? security(scopes) : security();
42
- {{else}}
43
- return security();
44
- {{/or}}
45
- }
46
- return security;
47
- }
48
- {{/if}}
49
- }
50
-
51
- /**
52
- * AbstractApi
53
- */
54
- export class AbstractApi {
55
- protected axios: AxiosInstance = BASE_AXIOS;
56
-
57
- /**
58
- * constructor
59
- */
60
- constructor({axios}: Config) {
61
- if (axios) this.axios = axios;
62
- }
63
- }
@@ -1,17 +0,0 @@
1
- import { AxiosResponse, AxiosRequestConfig } from "axios";
2
- import { AbstractApi, AbstractConfig } from "./abstractApi";
3
- import { Config{{#if securities}}, Security{{/if}} } from "../config";
4
- {{#with meta}}
5
- {{#or hasTemplate hasQuery hasFormData ~}}
6
- import { {{#if hasTemplate}}template{{#or hasQuery hasFormData}},{{/or}}{{/if}} {{#if hasQuery}}query{{#if hasFormData}},{{/if}}{{/if}} {{#if hasFormData}}formData{{/if}} } from "../utils";
7
- {{/or}}
8
- {{/with}}
9
- import { {{#each api/imports~}} {{title}}{{#unless @last}}, {{/unless}}{{/each}} } from "../models";
10
-
11
- {{#each api/servers}}
12
- type {{name}}Server = { name: "{{name}}"{{#if values}}; values: { {{#each values}}{{name}}: {{#if enums}}{{#each enums}}'{{this}}'{{#unless @last}} | {{/unless}}{{/each}}{{else}}string{{/if}} {{/each}} }; {{/if}} }
13
- {{/each}}
14
-
15
- {{> apis/class api=api securities=securities }}
16
-
17
- {{> apis/config api=api securities=securities }}
@@ -1,3 +0,0 @@
1
- {{#each this ~}}
2
- export * from "./{{filename}}";
3
- {{/each}}
@@ -1,3 +0,0 @@
1
- {{#if this~}}
2
- server: {{#each this}}{{name}}Server{{#unless @last}} | {{/unless}}{{/each}}{{#and (lengthEqual this 1) (isEmpty this/0/values)}} = { name: '{{this/0/name}}'{{#if this/0/values}}, values: { {{#each this/0/values}}{{name}}: '{{defaultValue}}',{{/each}} } {{/if}} }{{/and}},
3
- {{~/if}}
@@ -1,3 +0,0 @@
1
- {{#if this~}}
2
- server?: {{#each this}}{{name}}Server{{#unless @last}} | {{/unless}}{{/each}},
3
- {{~/if}}
@@ -1,21 +0,0 @@
1
- {{~#each parameters}}{{name}}: {{> models/type schema}},{{/each}}
2
- {{~#if forms}}form: {{#each forms}}{{#unless @first}} | {{/unless}}{{> models/type schema}}{{/each}},{{/if}}
3
- {{~#if queries}}queries: {
4
- {{~#each queries}}
5
- {{name}}{{#unless required}}?{{/unless}}: {{> models/type schema}},
6
- {{/each}}
7
- }{{#if (every queries 'required' false)}} = {}{{/if}},
8
- {{/if}}
9
- {{~#if cookies}}cookies: {
10
- {{~#each cookies}}
11
- {{name}}{{#unless required}}?{{/unless}}: {{> models/type schema}},
12
- {{/each}}
13
- }{{#if (every cookies 'required' false)}} = {}{{/if}},
14
- {{/if}}
15
- headers: {
16
- 'Content-Type': {{#if forms}}{{#each forms}}{{#unless @first}} | {{/unless}}{{#each types}}{{#unless @first}} | {{/unless}}'{{this}}'{{/each}}{{/each}}{{else}}'application/json'{{/if}},
17
- {{#each headers}}
18
- {{name}}{{#unless required}}?{{/unless}}: {{> models/type schema}},
19
- {{/each}}
20
- }{{#if (every headers 'required' false)}} = { 'Content-Type': 'application/json' }{{/if}},
21
- {{~> apis/arguments/server servers}} config?: AxiosRequestConfig
@@ -1,21 +0,0 @@
1
- {{~#each parameters}}{{name}}: {{> models/type schema}},{{/each}}
2
- form: {{> models/type form/schema}},
3
- {{~#if queries}}queries: {
4
- {{~#each queries}}
5
- {{name}}{{#unless required}}?{{/unless}}: {{> models/type schema}},
6
- {{/each}}
7
- },
8
- {{/if}}
9
- headers{{#filter form/types 'application/json'}}?{{/filter}}: {
10
- 'Content-Type': {{#each form/types}}{{#unless @first}} | {{/unless}}'{{this}}'{{/each}},
11
- {{#each headers}}
12
- {{name}}{{#unless required}}?{{/unless}}: {{> models/type schema}},
13
- {{/each}}
14
- },
15
- {{~#if cookies}}cookies: {
16
- {{~#each cookies}}
17
- {{name}}{{#unless required}}?{{/unless}}: {{> models/type schema}},
18
- {{/each}}
19
- },
20
- {{/if}}
21
- {{~> apis/arguments/server_interface servers}} config?: AxiosRequestConfig
@@ -1,4 +0,0 @@
1
- "{{path}}"
2
- {{#each parameters}}
3
- .replace("{ {{~name~}} }", template('{{name}}', {{name}}, '{{#unless style}}simple{{else}}{{style}}{{/unless}}', {{#unless explode}}false{{else}}{{explode}}{{/unless}}))
4
- {{~/each}}
@@ -1,14 +0,0 @@
1
- {{> comment title=name async=true}}
2
- {{#gt (length forms) 1 }}
3
- {{#each forms}}
4
- public async {{../name}}({{> apis/class/arguments_interface .. form=this}}): Promise<AxiosResponse{{#if ../schema}}<{{> models/type ../schema}}>{{/if}}>;
5
- {{/each}}
6
- {{/gt}}
7
- public async {{name}}({{> apis/class/arguments}}): Promise<AxiosResponse{{#if schema}}<{{> models/type schema}}>{{/if}}> {
8
- const path = {{> apis/class/path}};
9
- const requestConfig = await this.#config.{{name}}({{> apis/class/variables }});
10
- {{#if forms}}
11
- const _form = formData(headers['Content-Type'], form);
12
- {{/if}}
13
- return this.axios.{{method}}(path, {{#if forms}}_form, {{/if}}requestConfig)
14
- }
@@ -1,4 +0,0 @@
1
- {{~#if queries}}queries,{{/if}}
2
- {{~#if cookies}}cookies,{{/if}}
3
- headers,
4
- {{~#if servers}}server,{{/if}} config
@@ -1,17 +0,0 @@
1
- {{> comment api}}
2
- export class {{api.title}} extends AbstractApi {
3
- readonly #config: {{api.title}}Config;
4
-
5
- /**
6
- * constructor
7
- * @param {Config} config
8
- */
9
- constructor(config: Config = {}) {
10
- super(config);
11
- this.#config = new {{api.title}}Config({{#if securities}}config.security{{/if}});
12
- }
13
- {{#each api.paths}}
14
-
15
- {{> apis/class/request }}
16
- {{/each}}
17
- }
@@ -1,19 +0,0 @@
1
- {{~#if queries}}queries: {
2
- {{~#each queries}}
3
- {{name}}{{#unless required}}?{{/unless}}: {{> models/type schema}},
4
- {{/each}}
5
- }{{#if (every queries 'required' false)}} = {}{{/if}},
6
- {{/if}}
7
- {{~#if cookies}}cookies: {
8
- {{~#each cookies}}
9
- {{name}}{{#unless required}}?{{/unless}}: {{> models/type schema}},
10
- {{/each}}
11
- }{{#if (every cookies 'required' false)}} = {}{{/if}},
12
- {{/if}}
13
- headers: {
14
- 'Content-Type': {{#if forms}}{{#each forms}}{{#unless @first}} | {{/unless}}{{#each types}}{{#unless @first}} | {{/unless}}'{{this}}'{{/each}}{{/each}}{{else}}'application/json'{{/if}},
15
- {{#each headers}}
16
- {{name}}{{#unless required}}?{{/unless}}: {{> models/type schema}},
17
- {{/each}}
18
- }{{#if (every headers 'required' false)}} = { 'Content-Type': 'application/json' }{{/if}},
19
- {{~> apis/arguments/server servers}} config?: AxiosRequestConfig
@@ -1 +0,0 @@
1
- config?.baseURL ? config.baseURL : {{title}}Config.server(server)
@@ -1,13 +0,0 @@
1
- {{~#each cookies}}
2
- if (cookies.{{name}}) {
3
- _cookies += Object.entries(query('{{name}}', cookies.{{name}}, 'form', {{#if explode}}true{{else}}false{{/if}})).reduce((pre, [key, value]) => `${pre}${key}=${value};`, '');
4
- }
5
- {{/each}}
6
- {{~#each securities}}
7
- {{#and (eq type 'apiKey') (eq in 'cookie')~}}
8
- const _cookie{{name}} = await this.security("{{name}}");
9
- if (_cookie{{name}}) {
10
- _cookies += `{{key}}=${_cookie{{name~}} };`;
11
- }
12
- {{/and}}
13
- {{/each}}
@@ -1,14 +0,0 @@
1
- {{~#each headers}}
2
- if (headers.{{name}}) {
3
- _headers['{{name}}'] = template('{{name}}', headers.{{name}}, 'simple', {{#if explode}}true{{else}}false{{/if}});
4
- }
5
- {{/each}}
6
- {{~#each securities}}
7
- {{#and (eq type 'apiKey') (eq in 'header')~}}
8
- _headers['{{key}}'] = await this.security("{{name}}");
9
- {{else and (eq type 'http') (eq schema 'bearer')}}
10
- _headers['Authorization'] = `Bearer ${await this.security("{{name}}")}`;
11
- {{else or (eq type 'oauth2') (eq type 'openIdConnect')}}
12
- _headers['Authorization'] = `Bearer ${await this.security("{{name}}", [{{#each scopes}}"{{this}}"{{#unless @last}}, {{/unless}}{{/each}}])}`;
13
- {{/and}}
14
- {{/each}}
@@ -1,11 +0,0 @@
1
- {
2
- ...config?.params,
3
- {{#each queries}}
4
- ...query("{{name}}", queries.{{name}}, '{{#unless style}}form{{else}}{{style}}{{/unless}}', {{#unless explode}}false{{else}}{{explode}}{{/unless}}),
5
- {{/each}}
6
- {{#each securities}}
7
- {{#and (eq type 'apiKey') (eq in 'query')}}
8
- {{key}}: await this.security("{{name}}"),
9
- {{/and}}
10
- {{/each}}
11
- }
@@ -1,19 +0,0 @@
1
- public async {{name}}({{> apis/config/arguments}}): Promise<AxiosRequestConfig> {
2
- const params = {{> apis/config/request/queries }};
3
-
4
- let _cookies = config?.headers?.Cookie ?? '';
5
- {{> apis/config/request/cookies }}
6
-
7
- const _headers = Object.assign({ ...config?.headers, 'Content-Type': headers['Content-Type']}, _cookies ? {Cookie: _cookies} : undefined);
8
- {{> apis/config/request/headers }}
9
-
10
- return {
11
- ...config,
12
- {{#each securities}}
13
- {{#and (eq type 'http') (eq scheme 'basic') }}auth: await this.security("{{name}}"),{{/and}}
14
- {{~/each}}
15
- baseURL: {{> apis/config/request/baseURL title=title }},
16
- params,
17
- headers: _headers
18
- };
19
- }
@@ -1,11 +0,0 @@
1
- private static server(server: {{#each servers}}{{name}}Server{{#unless @last}} | {{/unless}}{{/each}}) {
2
- {{#each servers}}
3
- if ('{{name}}' === server.name) {
4
- return '{{url}}'
5
- {{#each values}}
6
- .replace('{ {{~name~}} }', template('{{name}}', server.values.{{name}}, 'simple', false))
7
- {{~/each}};
8
- }
9
- {{/each}}
10
- throw new Error('Undefined server. please define server.');
11
- }
@@ -1,14 +0,0 @@
1
- class {{api.title}}Config extends AbstractConfig {
2
- {{#if securities}}
3
- constructor(security: Security = {}) {
4
- super(security);
5
- }
6
- {{/if}}
7
-
8
- {{> apis/config/server api }}
9
-
10
- {{#each api.paths}}
11
-
12
- {{> apis/config/request title=../api.title }}
13
- {{/each}}
14
- }
@@ -1,19 +0,0 @@
1
- import { AxiosInstance } from "axios";
2
-
3
- export type Security = {
4
- {{#each securities}}
5
- {{#and (eq type 'http') (eq scheme 'basic')}}
6
- {{name}}?: {username: string; password: string;} | Promise<{username: string; password: string;}> | (() => {username: string; password: string;} | Promise<{username: string; password: string;}>);
7
- {{else or (eq type 'oauth2') (eq type 'openIdConnect')}}
8
- {{name}}?: string | Promise<string> | ((scopes?: string[]) => string | Promise<string>);
9
- {{else}}
10
- {{name}}?: string | Promise<string> | (() => string | Promise<string>);
11
- {{/and}}
12
- {{/each}}
13
- };
14
-
15
- export type Config = {
16
- axios?: AxiosInstance;
17
- token?: string | Promise<string> | (() => string | Promise<string>);
18
- security?: Security;
19
- }
@@ -1,3 +0,0 @@
1
- {{#if model}}export * from './models';{{/if}}
2
- {{#if api}}export * from './apis';{{/if}}
3
- export * from './config';
@@ -1,3 +0,0 @@
1
- {{#each this ~}}
2
- export * from "./{{filename}}";
3
- {{/each}}
@@ -1,6 +0,0 @@
1
- {{#each imports~}}
2
- import { {{title}} } from "./{{filename}}";
3
- {{/each}}
4
-
5
- {{> comment}}
6
- export type {{title}} = {{> models/type schema}};
@@ -1,7 +0,0 @@
1
- {{#noop~}}
2
- (
3
- {{~#each schemas}}
4
- {{~#if @first}}{{> models/type}}{{else}} & {{> models/type}}{{/if~}}
5
- {{/each~}}
6
- )
7
- {{~/noop}}
@@ -1,6 +0,0 @@
1
- {{#if items ~}}
2
- Array<{{#with items}}{{> models/type}}{{/with}}>
3
- {{~ else ~}}
4
- any[]
5
- {{~/if}}
6
- {{~> models/nullable}}
@@ -1 +0,0 @@
1
- boolean{{> models/nullable}}
@@ -1 +0,0 @@
1
- {{#if nullable}} | null{{/if}}
@@ -1,6 +0,0 @@
1
- {{#if enum}}
2
- {{~#each enum}}{{#if @first}}{{this}}{{else}} | {{this}}{{/if}}{{/each ~}}
3
- {{~ else ~}}
4
- number
5
- {{~/if}}
6
- {{> models/nullable}}
@@ -1,13 +0,0 @@
1
- {{#noop}}
2
- {{#if properties ~}}
3
- {
4
- {{#each properties}}
5
- {{> comment title=name}}
6
- {{#inArray name "-"}}"{{name}}"{{else}}{{name}}{{/inArray}}{{#unless required}}?{{/unless}}: {{> models/type schema}};
7
- {{/each}}
8
- }
9
- {{~ else ~}}
10
- object
11
- {{~/if}}
12
- {{> models/nullable}}
13
- {{~/noop}}
@@ -1,7 +0,0 @@
1
- {{#noop~}}
2
- (
3
- {{~#each schemas}}
4
- {{~#if @first}}{{> models/type}}{{else}} | {{> models/type}}{{/if~}}
5
- {{/each~}}
6
- )
7
- {{~/noop}}
@@ -1,10 +0,0 @@
1
- {{~#if enum}}
2
- {{~#each enum}}{{~#if @first}}"{{this}}"{{~else}} | "{{this}}"{{~/if}}{{~/each}}
3
- {{~else or (eq format 'date') (eq format 'date-time')~}}
4
- Date
5
- {{~else eq format 'url'~}}
6
- URL
7
- {{~else~}}
8
- string
9
- {{~/if}}
10
- {{> models/nullable}}
@@ -1,19 +0,0 @@
1
- {{#eq type 'model'}}
2
- {{~ name ~}}
3
- {{else eq type 'object'}}
4
- {{~> models/object}}
5
- {{else eq type 'allOf'}}
6
- {{~> models/allOf}}
7
- {{else eq type 'oneOf'}}
8
- {{~> models/oneOf}}
9
- {{else eq type 'array'}}
10
- {{~> models/array}}
11
- {{else eq type 'boolean'}}
12
- {{~> models/boolean}}
13
- {{else eq type 'string'}}
14
- {{~> models/string}}
15
- {{else eq type 'number'}}
16
- {{~> models/number}}
17
- {{else}}
18
- {{~ type}}
19
- {{/eq}}
@@ -1,24 +0,0 @@
1
- /**
2
- * {{title}}
3
- {{#if async}}
4
- * @async
5
- {{/if}}
6
- {{#if description}}
7
- * @description {{description}}
8
- {{/if}}
9
- {{#if deprecated}}
10
- * @deprecated
11
- {{/if}}
12
- {{#if readOnly}}
13
- * @readonly
14
- {{/if}}
15
- {{#if defaultValue}}
16
- * @default {{defaultValue}}
17
- {{/if}}
18
- {{#each params}}
19
- * @params { {{type}} } {{name}}
20
- {{/each}}
21
- {{#if example}}
22
- * @example
23
- {{/if}}
24
- */