api-farmer 0.0.28 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -84,6 +84,7 @@ export default defineConfig({
84
84
  url() {},
85
85
  entity() {},
86
86
  fn() {},
87
+ comment() {},
87
88
  type() {},
88
89
  typeValue() {},
89
90
  typeQuery() {},
@@ -152,6 +153,11 @@ export interface Config {
152
153
  * Certain uncountable nouns that do not change from singular to plural
153
154
  */
154
155
  uncountableNouns?: string[]
156
+ /**
157
+ * The options for the openapiTS library.
158
+ * @see https://openapi-ts.dev/node
159
+ */
160
+ openapiTsOptions?: OpenAPITSOptions
155
161
  }
156
162
  ```
157
163
 
@@ -189,6 +195,10 @@ export interface ApiModule {
189
195
  }
190
196
 
191
197
  export interface ApiModulePayload {
198
+ /**
199
+ * The comment of the API endpoint, including summary, description, URL, and method.
200
+ */
201
+ comment: string
192
202
  /**
193
203
  * The name of the API function/dispatcher,
194
204
  * such as apiGetUsers, apiCreatePost, apiUpdateComment, etc.
@@ -105,7 +105,7 @@ function getResponseMetadataItems(operation, validateStatus) {
105
105
  const validStatusResults = Object.keys(responses).sort((a, b) => Number(a) - Number(b)).filter((key) => validateStatus(Number(key))).map(Number);
106
106
  const metadataItems = validStatusResults.map((status) => {
107
107
  const content = operation.responses?.[status]?.content ?? {};
108
- const responseContentType = findObjectKey(content, ["application/json", "*/*"]);
108
+ const responseContentType = findObjectKey(content, ["application/json", "application/octet-stream", "*/*"]);
109
109
  return {
110
110
  status,
111
111
  responseContentType
@@ -6,7 +6,7 @@ import {
6
6
  isRequiredRequestBody,
7
7
  readSchema,
8
8
  readTemplateFile
9
- } from "./chunk-56NOW5DM.js";
9
+ } from "./chunk-2227C45C.js";
10
10
 
11
11
  // src/generate.ts
12
12
  import { resolve } from "path";
@@ -16,6 +16,7 @@ import openapiTS, { astToString } from "openapi-typescript";
16
16
  import prettier from "prettier";
17
17
  import { groupBy, isArray, merge } from "rattail";
18
18
  import { logger } from "rslog";
19
+ import ts from "typescript";
19
20
 
20
21
  // src/config.ts
21
22
  import { loadConfig } from "unconfig";
@@ -42,6 +43,22 @@ function transformModuleName({ name }) {
42
43
  function transformUrl({ path }) {
43
44
  return path.replace(/{/g, ":").replace(/}/g, "");
44
45
  }
46
+ function transformComment({
47
+ summary,
48
+ description,
49
+ path,
50
+ method
51
+ }) {
52
+ return `
53
+ /**${summary ? `
54
+ * ${summary}` : ""}${description && summary !== description ? `
55
+ * @description ${description}
56
+ *` : ""}
57
+ * @url ${path}
58
+ * @method ${method.toLocaleUpperCase()}
59
+ */
60
+ `.trim();
61
+ }
45
62
  function transformVerb({ method }) {
46
63
  switch (method) {
47
64
  case "post":
@@ -113,6 +130,7 @@ function createTransformer() {
113
130
  moduleName: transformModuleName,
114
131
  verb: transformVerb,
115
132
  url: transformUrl,
133
+ comment: transformComment,
116
134
  entity: transformEntity,
117
135
  fn: transformFn,
118
136
  type: transformType,
@@ -134,6 +152,7 @@ function transformPayloads(pathItems, options) {
134
152
  const args = { path, base, fullPath, url, method, uncountableNouns, operation };
135
153
  const entity = transformer.entity(args);
136
154
  const verb = transformer.verb(args);
155
+ const comment = transformer.comment({ ...args, ...operation });
137
156
  const requestContentType = operation.requestBody ? getRequestBodyContentType(operation.requestBody) : void 0;
138
157
  const responseMetadataItems = getResponseMetadataItems(operation, validateStatus);
139
158
  const fn = transformer.fn({ ...args, verb, entity });
@@ -153,6 +172,7 @@ function transformPayloads(pathItems, options) {
153
172
  const typeResponseBody = transformer.typeResponseBody({ ...args, type, verb, entity });
154
173
  const typeResponseBodyValue = responseMetadataItems.length > 0 ? transformer.typeResponseBodyValue({ ...args, type, verb, entity, responseMetadataItems }) : "undefined";
155
174
  payloads.push({
175
+ comment,
156
176
  fn,
157
177
  url,
158
178
  method,
@@ -198,7 +218,7 @@ function partitionApiModules(schema, options) {
198
218
  return apiModules;
199
219
  }
200
220
  function renderApiModules(apiModules, options) {
201
- const { output, ts, typesOnly, overrides, preset } = options;
221
+ const { output, ts: ts2, typesOnly, overrides, preset } = options;
202
222
  const templateFile = readTemplateFile(preset);
203
223
  const typesFilename = options.typesFilename.replace(".ts", "");
204
224
  return Promise.all(
@@ -207,7 +227,7 @@ function renderApiModules(apiModules, options) {
207
227
  const data = {
208
228
  apiModule,
209
229
  typesFilename,
210
- ts,
230
+ ts: ts2,
211
231
  typesOnly
212
232
  };
213
233
  prettier.format(ejs.render(templateFile, data), {
@@ -216,7 +236,7 @@ function renderApiModules(apiModules, options) {
216
236
  singleQuote: true,
217
237
  printWidth: 120
218
238
  }).then((content) => {
219
- const path = resolve(output, `${apiModule.name}.${ts ? "ts" : "js"}`);
239
+ const path = resolve(output, `${apiModule.name}.${ts2 ? "ts" : "js"}`);
220
240
  const shouldSkip = (!overrides || isArray(overrides) && !overrides.includes(apiModule.name)) && fse.existsSync(path);
221
241
  if (shouldSkip) {
222
242
  logger.warn(`File already exists, skip: ${path}`);
@@ -231,9 +251,17 @@ function renderApiModules(apiModules, options) {
231
251
  )
232
252
  );
233
253
  }
234
- async function generateTypes(schema, output, typesFilename) {
254
+ async function generateTypes(schema, output, typesFilename, openapiTsOptions) {
255
+ const BLOB = ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Blob"));
256
+ const NULL = ts.factory.createLiteralTypeNode(ts.factory.createNull());
235
257
  const ast = await openapiTS(schema, {
236
- defaultNonNullable: false
258
+ defaultNonNullable: false,
259
+ transform(schemaObject) {
260
+ if (schemaObject.format === "binary") {
261
+ return schemaObject.nullable ? ts.factory.createUnionTypeNode([BLOB, NULL]) : BLOB;
262
+ }
263
+ },
264
+ ...openapiTsOptions
237
265
  });
238
266
  const contents = astToString(ast);
239
267
  const typesFilepath = resolve(CWD, output, typesFilename);
@@ -245,7 +273,7 @@ async function generate(userOptions = {}) {
245
273
  const options = merge(config, userOptions);
246
274
  const {
247
275
  base,
248
- ts = true,
276
+ ts: ts2 = true,
249
277
  typesOnly = false,
250
278
  overrides = true,
251
279
  preset = "axle",
@@ -254,13 +282,14 @@ async function generate(userOptions = {}) {
254
282
  typesFilename = "_types.ts",
255
283
  validateStatus = (status) => status >= 200 && status < 300,
256
284
  transformer = {},
257
- uncountableNouns = []
285
+ uncountableNouns = [],
286
+ openapiTsOptions = {}
258
287
  } = options;
259
288
  const mergedTransformer = { ...createTransformer(), ...transformer };
260
289
  const schema = await readSchema(input);
261
290
  logger.info("Generating API modules...");
262
- if (ts) {
263
- await generateTypes(schema, output, typesFilename);
291
+ if (ts2) {
292
+ await generateTypes(schema, output, typesFilename, openapiTsOptions);
264
293
  }
265
294
  const apiModules = partitionApiModules(schema, {
266
295
  base,
@@ -268,7 +297,7 @@ async function generate(userOptions = {}) {
268
297
  transformer: mergedTransformer,
269
298
  validateStatus
270
299
  });
271
- await renderApiModules(apiModules, { output, typesFilename, ts, typesOnly, overrides, preset });
300
+ await renderApiModules(apiModules, { output, typesFilename, ts: ts2, typesOnly, overrides, preset });
272
301
  logger.success("Done");
273
302
  }
274
303
 
@@ -277,6 +306,7 @@ export {
277
306
  getConfig,
278
307
  transformModuleName,
279
308
  transformUrl,
309
+ transformComment,
280
310
  transformVerb,
281
311
  transformEntity,
282
312
  transformFn,
package/dist/cli.cjs CHANGED
@@ -102,7 +102,7 @@ function getResponseMetadataItems(operation, validateStatus) {
102
102
  const validStatusResults = Object.keys(responses).sort((a, b) => Number(a) - Number(b)).filter((key) => validateStatus(Number(key))).map(Number);
103
103
  const metadataItems = validStatusResults.map((status) => {
104
104
  const content = operation.responses?.[status]?.content ?? {};
105
- const responseContentType = findObjectKey(content, ["application/json", "*/*"]);
105
+ const responseContentType = findObjectKey(content, ["application/json", "application/octet-stream", "*/*"]);
106
106
  return {
107
107
  status,
108
108
  responseContentType
@@ -153,6 +153,22 @@ function transformModuleName({ name }) {
153
153
  function transformUrl({ path }) {
154
154
  return path.replace(/{/g, ":").replace(/}/g, "");
155
155
  }
156
+ function transformComment({
157
+ summary,
158
+ description,
159
+ path,
160
+ method
161
+ }) {
162
+ return `
163
+ /**${summary ? `
164
+ * ${summary}` : ""}${description && summary !== description ? `
165
+ * @description ${description}
166
+ *` : ""}
167
+ * @url ${path}
168
+ * @method ${method.toLocaleUpperCase()}
169
+ */
170
+ `.trim();
171
+ }
156
172
  function transformVerb({ method }) {
157
173
  switch (method) {
158
174
  case "post":
@@ -224,6 +240,7 @@ function createTransformer() {
224
240
  moduleName: transformModuleName,
225
241
  verb: transformVerb,
226
242
  url: transformUrl,
243
+ comment: transformComment,
227
244
  entity: transformEntity,
228
245
  fn: transformFn,
229
246
  type: transformType,
@@ -262,6 +279,7 @@ function transformPayloads(pathItems, options) {
262
279
  const args = { path, base, fullPath, url, method, uncountableNouns, operation };
263
280
  const entity = transformer.entity(args);
264
281
  const verb = transformer.verb(args);
282
+ const comment = transformer.comment({ ...args, ...operation });
265
283
  const requestContentType = operation.requestBody ? getRequestBodyContentType(operation.requestBody) : void 0;
266
284
  const responseMetadataItems = getResponseMetadataItems(operation, validateStatus);
267
285
  const fn = transformer.fn({ ...args, verb, entity });
@@ -281,6 +299,7 @@ function transformPayloads(pathItems, options) {
281
299
  const typeResponseBody = transformer.typeResponseBody({ ...args, type, verb, entity });
282
300
  const typeResponseBodyValue = responseMetadataItems.length > 0 ? transformer.typeResponseBodyValue({ ...args, type, verb, entity, responseMetadataItems }) : "undefined";
283
301
  payloads.push({
302
+ comment,
284
303
  fn,
285
304
  url,
286
305
  method,
@@ -326,7 +345,7 @@ function partitionApiModules(schema, options) {
326
345
  return apiModules;
327
346
  }
328
347
  function renderApiModules(apiModules, options) {
329
- const { output, ts, typesOnly, overrides, preset } = options;
348
+ const { output, ts: ts2, typesOnly, overrides, preset } = options;
330
349
  const templateFile = readTemplateFile(preset);
331
350
  const typesFilename = options.typesFilename.replace(".ts", "");
332
351
  return Promise.all(
@@ -335,7 +354,7 @@ function renderApiModules(apiModules, options) {
335
354
  const data = {
336
355
  apiModule,
337
356
  typesFilename,
338
- ts,
357
+ ts: ts2,
339
358
  typesOnly
340
359
  };
341
360
  import_prettier.default.format(import_ejs.default.render(templateFile, data), {
@@ -344,7 +363,7 @@ function renderApiModules(apiModules, options) {
344
363
  singleQuote: true,
345
364
  printWidth: 120
346
365
  }).then((content) => {
347
- const path = (0, import_path3.resolve)(output, `${apiModule.name}.${ts ? "ts" : "js"}`);
366
+ const path = (0, import_path3.resolve)(output, `${apiModule.name}.${ts2 ? "ts" : "js"}`);
348
367
  const shouldSkip = (!overrides || (0, import_rattail3.isArray)(overrides) && !overrides.includes(apiModule.name)) && import_fs_extra2.default.existsSync(path);
349
368
  if (shouldSkip) {
350
369
  import_rslog2.logger.warn(`File already exists, skip: ${path}`);
@@ -359,9 +378,17 @@ function renderApiModules(apiModules, options) {
359
378
  )
360
379
  );
361
380
  }
362
- async function generateTypes(schema, output, typesFilename) {
381
+ async function generateTypes(schema, output, typesFilename, openapiTsOptions) {
382
+ const BLOB = import_typescript.default.factory.createTypeReferenceNode(import_typescript.default.factory.createIdentifier("Blob"));
383
+ const NULL = import_typescript.default.factory.createLiteralTypeNode(import_typescript.default.factory.createNull());
363
384
  const ast = await (0, import_openapi_typescript.default)(schema, {
364
- defaultNonNullable: false
385
+ defaultNonNullable: false,
386
+ transform(schemaObject) {
387
+ if (schemaObject.format === "binary") {
388
+ return schemaObject.nullable ? import_typescript.default.factory.createUnionTypeNode([BLOB, NULL]) : BLOB;
389
+ }
390
+ },
391
+ ...openapiTsOptions
365
392
  });
366
393
  const contents = (0, import_openapi_typescript.astToString)(ast);
367
394
  const typesFilepath = (0, import_path3.resolve)(CWD, output, typesFilename);
@@ -373,7 +400,7 @@ async function generate(userOptions = {}) {
373
400
  const options = (0, import_rattail3.merge)(config, userOptions);
374
401
  const {
375
402
  base,
376
- ts = true,
403
+ ts: ts2 = true,
377
404
  typesOnly = false,
378
405
  overrides = true,
379
406
  preset = "axle",
@@ -382,13 +409,14 @@ async function generate(userOptions = {}) {
382
409
  typesFilename = "_types.ts",
383
410
  validateStatus = (status) => status >= 200 && status < 300,
384
411
  transformer = {},
385
- uncountableNouns = []
412
+ uncountableNouns = [],
413
+ openapiTsOptions = {}
386
414
  } = options;
387
415
  const mergedTransformer = { ...createTransformer(), ...transformer };
388
416
  const schema = await readSchema(input);
389
417
  import_rslog2.logger.info("Generating API modules...");
390
- if (ts) {
391
- await generateTypes(schema, output, typesFilename);
418
+ if (ts2) {
419
+ await generateTypes(schema, output, typesFilename, openapiTsOptions);
392
420
  }
393
421
  const apiModules = partitionApiModules(schema, {
394
422
  base,
@@ -396,10 +424,10 @@ async function generate(userOptions = {}) {
396
424
  transformer: mergedTransformer,
397
425
  validateStatus
398
426
  });
399
- await renderApiModules(apiModules, { output, typesFilename, ts, typesOnly, overrides, preset });
427
+ await renderApiModules(apiModules, { output, typesFilename, ts: ts2, typesOnly, overrides, preset });
400
428
  import_rslog2.logger.success("Done");
401
429
  }
402
- var import_path3, import_ejs, import_fs_extra2, import_openapi_typescript, import_prettier, import_rattail3, import_rslog2;
430
+ var import_path3, import_ejs, import_fs_extra2, import_openapi_typescript, import_prettier, import_rattail3, import_rslog2, import_typescript;
403
431
  var init_generate = __esm({
404
432
  "src/generate.ts"() {
405
433
  "use strict";
@@ -411,6 +439,7 @@ var init_generate = __esm({
411
439
  import_prettier = __toESM(require("prettier"), 1);
412
440
  import_rattail3 = require("rattail");
413
441
  import_rslog2 = require("rslog");
442
+ import_typescript = __toESM(require("typescript"), 1);
414
443
  init_config();
415
444
  init_constants();
416
445
  init_transformer();
package/dist/cli.js CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getCliVersion
4
- } from "./chunk-56NOW5DM.js";
4
+ } from "./chunk-2227C45C.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { Command } from "commander";
8
8
  var program = new Command();
9
9
  program.version(getCliVersion());
10
10
  program.action(async () => {
11
- const { generate } = await import("./generate-NRJ4NQ4O.js");
11
+ const { generate } = await import("./generate-WIU5E7EL.js");
12
12
  return generate();
13
13
  });
14
14
  program.parse();
@@ -4,8 +4,8 @@ import {
4
4
  partitionApiModules,
5
5
  renderApiModules,
6
6
  transformPayloads
7
- } from "./chunk-XM2F7GOE.js";
8
- import "./chunk-56NOW5DM.js";
7
+ } from "./chunk-P3SVS555.js";
8
+ import "./chunk-2227C45C.js";
9
9
  export {
10
10
  generate,
11
11
  generateTypes,
package/dist/index.cjs CHANGED
@@ -49,6 +49,7 @@ __export(index_exports, {
49
49
  readSchemaContent: () => readSchemaContent,
50
50
  readTemplateFile: () => readTemplateFile,
51
51
  renderApiModules: () => renderApiModules,
52
+ transformComment: () => transformComment,
52
53
  transformEntity: () => transformEntity,
53
54
  transformFn: () => transformFn,
54
55
  transformModuleName: () => transformModuleName,
@@ -75,6 +76,22 @@ function transformModuleName({ name }) {
75
76
  function transformUrl({ path }) {
76
77
  return path.replace(/{/g, ":").replace(/}/g, "");
77
78
  }
79
+ function transformComment({
80
+ summary,
81
+ description,
82
+ path,
83
+ method
84
+ }) {
85
+ return `
86
+ /**${summary ? `
87
+ * ${summary}` : ""}${description && summary !== description ? `
88
+ * @description ${description}
89
+ *` : ""}
90
+ * @url ${path}
91
+ * @method ${method.toLocaleUpperCase()}
92
+ */
93
+ `.trim();
94
+ }
78
95
  function transformVerb({ method }) {
79
96
  switch (method) {
80
97
  case "post":
@@ -146,6 +163,7 @@ function createTransformer() {
146
163
  moduleName: transformModuleName,
147
164
  verb: transformVerb,
148
165
  url: transformUrl,
166
+ comment: transformComment,
149
167
  entity: transformEntity,
150
168
  fn: transformFn,
151
169
  type: transformType,
@@ -167,6 +185,7 @@ var import_openapi_typescript = __toESM(require("openapi-typescript"), 1);
167
185
  var import_prettier = __toESM(require("prettier"), 1);
168
186
  var import_rattail3 = require("rattail");
169
187
  var import_rslog2 = require("rslog");
188
+ var import_typescript = __toESM(require("typescript"), 1);
170
189
 
171
190
  // src/config.ts
172
191
  var import_unconfig = require("unconfig");
@@ -284,7 +303,7 @@ function getResponseMetadataItems(operation, validateStatus) {
284
303
  const validStatusResults = Object.keys(responses).sort((a, b) => Number(a) - Number(b)).filter((key) => validateStatus(Number(key))).map(Number);
285
304
  const metadataItems = validStatusResults.map((status) => {
286
305
  const content = operation.responses?.[status]?.content ?? {};
287
- const responseContentType = findObjectKey(content, ["application/json", "*/*"]);
306
+ const responseContentType = findObjectKey(content, ["application/json", "application/octet-stream", "*/*"]);
288
307
  return {
289
308
  status,
290
309
  responseContentType
@@ -301,6 +320,7 @@ function transformPayloads(pathItems, options) {
301
320
  const args = { path, base, fullPath, url, method, uncountableNouns, operation };
302
321
  const entity = transformer.entity(args);
303
322
  const verb = transformer.verb(args);
323
+ const comment = transformer.comment({ ...args, ...operation });
304
324
  const requestContentType = operation.requestBody ? getRequestBodyContentType(operation.requestBody) : void 0;
305
325
  const responseMetadataItems = getResponseMetadataItems(operation, validateStatus);
306
326
  const fn = transformer.fn({ ...args, verb, entity });
@@ -320,6 +340,7 @@ function transformPayloads(pathItems, options) {
320
340
  const typeResponseBody = transformer.typeResponseBody({ ...args, type, verb, entity });
321
341
  const typeResponseBodyValue = responseMetadataItems.length > 0 ? transformer.typeResponseBodyValue({ ...args, type, verb, entity, responseMetadataItems }) : "undefined";
322
342
  payloads.push({
343
+ comment,
323
344
  fn,
324
345
  url,
325
346
  method,
@@ -365,7 +386,7 @@ function partitionApiModules(schema, options) {
365
386
  return apiModules;
366
387
  }
367
388
  function renderApiModules(apiModules, options) {
368
- const { output, ts, typesOnly, overrides, preset } = options;
389
+ const { output, ts: ts2, typesOnly, overrides, preset } = options;
369
390
  const templateFile = readTemplateFile(preset);
370
391
  const typesFilename = options.typesFilename.replace(".ts", "");
371
392
  return Promise.all(
@@ -374,7 +395,7 @@ function renderApiModules(apiModules, options) {
374
395
  const data = {
375
396
  apiModule,
376
397
  typesFilename,
377
- ts,
398
+ ts: ts2,
378
399
  typesOnly
379
400
  };
380
401
  import_prettier.default.format(import_ejs.default.render(templateFile, data), {
@@ -383,7 +404,7 @@ function renderApiModules(apiModules, options) {
383
404
  singleQuote: true,
384
405
  printWidth: 120
385
406
  }).then((content) => {
386
- const path = (0, import_path3.resolve)(output, `${apiModule.name}.${ts ? "ts" : "js"}`);
407
+ const path = (0, import_path3.resolve)(output, `${apiModule.name}.${ts2 ? "ts" : "js"}`);
387
408
  const shouldSkip = (!overrides || (0, import_rattail3.isArray)(overrides) && !overrides.includes(apiModule.name)) && import_fs_extra2.default.existsSync(path);
388
409
  if (shouldSkip) {
389
410
  import_rslog2.logger.warn(`File already exists, skip: ${path}`);
@@ -398,9 +419,17 @@ function renderApiModules(apiModules, options) {
398
419
  )
399
420
  );
400
421
  }
401
- async function generateTypes(schema, output, typesFilename) {
422
+ async function generateTypes(schema, output, typesFilename, openapiTsOptions) {
423
+ const BLOB = import_typescript.default.factory.createTypeReferenceNode(import_typescript.default.factory.createIdentifier("Blob"));
424
+ const NULL = import_typescript.default.factory.createLiteralTypeNode(import_typescript.default.factory.createNull());
402
425
  const ast = await (0, import_openapi_typescript.default)(schema, {
403
- defaultNonNullable: false
426
+ defaultNonNullable: false,
427
+ transform(schemaObject) {
428
+ if (schemaObject.format === "binary") {
429
+ return schemaObject.nullable ? import_typescript.default.factory.createUnionTypeNode([BLOB, NULL]) : BLOB;
430
+ }
431
+ },
432
+ ...openapiTsOptions
404
433
  });
405
434
  const contents = (0, import_openapi_typescript.astToString)(ast);
406
435
  const typesFilepath = (0, import_path3.resolve)(CWD, output, typesFilename);
@@ -412,7 +441,7 @@ async function generate(userOptions = {}) {
412
441
  const options = (0, import_rattail3.merge)(config, userOptions);
413
442
  const {
414
443
  base,
415
- ts = true,
444
+ ts: ts2 = true,
416
445
  typesOnly = false,
417
446
  overrides = true,
418
447
  preset = "axle",
@@ -421,13 +450,14 @@ async function generate(userOptions = {}) {
421
450
  typesFilename = "_types.ts",
422
451
  validateStatus = (status) => status >= 200 && status < 300,
423
452
  transformer = {},
424
- uncountableNouns = []
453
+ uncountableNouns = [],
454
+ openapiTsOptions = {}
425
455
  } = options;
426
456
  const mergedTransformer = { ...createTransformer(), ...transformer };
427
457
  const schema = await readSchema(input);
428
458
  import_rslog2.logger.info("Generating API modules...");
429
- if (ts) {
430
- await generateTypes(schema, output, typesFilename);
459
+ if (ts2) {
460
+ await generateTypes(schema, output, typesFilename, openapiTsOptions);
431
461
  }
432
462
  const apiModules = partitionApiModules(schema, {
433
463
  base,
@@ -435,7 +465,7 @@ async function generate(userOptions = {}) {
435
465
  transformer: mergedTransformer,
436
466
  validateStatus
437
467
  });
438
- await renderApiModules(apiModules, { output, typesFilename, ts, typesOnly, overrides, preset });
468
+ await renderApiModules(apiModules, { output, typesFilename, ts: ts2, typesOnly, overrides, preset });
439
469
  import_rslog2.logger.success("Done");
440
470
  }
441
471
 
@@ -462,6 +492,7 @@ var import_pluralize2 = __toESM(require("pluralize"), 1);
462
492
  readSchemaContent,
463
493
  readTemplateFile,
464
494
  renderApiModules,
495
+ transformComment,
465
496
  transformEntity,
466
497
  transformFn,
467
498
  transformModuleName,
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { OpenAPI3, RequestBodyObject, ReferenceObject, OperationObject } from 'openapi-typescript';
1
+ import { OpenAPI3, RequestBodyObject, ReferenceObject, OperationObject, OpenAPITSOptions } from 'openapi-typescript';
2
2
  export { default as pluralize } from 'pluralize';
3
3
 
4
4
  type Preset = 'axle' | 'axios';
@@ -69,6 +69,12 @@ declare function transformUrl({ path }: {
69
69
  fullPath: string;
70
70
  base: string | undefined;
71
71
  }): string;
72
+ declare function transformComment({ summary, description, path, method, }: {
73
+ summary?: string;
74
+ description?: string;
75
+ path: string;
76
+ method: string;
77
+ } & TransformerBaseArgs): string;
72
78
  declare function transformVerb({ method }: {
73
79
  method: string;
74
80
  }): string;
@@ -122,6 +128,7 @@ interface Transformer {
122
128
  moduleName: typeof transformModuleName;
123
129
  verb: typeof transformVerb;
124
130
  url: typeof transformUrl;
131
+ comment: typeof transformComment;
125
132
  entity: typeof transformEntity;
126
133
  fn: typeof transformFn;
127
134
  type: typeof transformType;
@@ -164,6 +171,10 @@ interface ApiModule {
164
171
  payloads: ApiModulePayload[];
165
172
  }
166
173
  interface ApiModulePayload {
174
+ /**
175
+ * The comment of the API endpoint, including summary, description, URL, and method.
176
+ */
177
+ comment: string;
167
178
  /**
168
179
  * The name of the API function/dispatcher, such as apiGetUsers, apiCreatePost, apiUpdateComment, etc.
169
180
  */
@@ -274,6 +285,10 @@ interface GenerateOptions {
274
285
  * Certain uncountable nouns that do not change from singular to plural
275
286
  */
276
287
  uncountableNouns?: string[];
288
+ /**
289
+ * A function to transform the generated types AST before printing to string.
290
+ */
291
+ openapiTsOptions?: OpenAPITSOptions;
277
292
  }
278
293
  declare function transformPayloads(pathItems: Record<string, OperationObject>, options: {
279
294
  path: string;
@@ -297,11 +312,11 @@ declare function renderApiModules(apiModules: ApiModule[], options: {
297
312
  overrides: boolean | string[];
298
313
  preset: Preset;
299
314
  }): Promise<unknown[]>;
300
- declare function generateTypes(schema: OpenAPI3, output: string, typesFilename: string): Promise<void>;
315
+ declare function generateTypes(schema: OpenAPI3, output: string, typesFilename: string, openapiTsOptions: OpenAPITSOptions): Promise<void>;
301
316
  declare function generate(userOptions?: GenerateOptions): Promise<void>;
302
317
 
303
318
  type Config = GenerateOptions;
304
319
  declare function defineConfig(config: Config): GenerateOptions;
305
320
  declare function getConfig(): Promise<Config>;
306
321
 
307
- export { type ApiModule, type ApiModulePayload, type ApiModuleTemplateData, type Config, type GenerateOptions, type Preset, type ResponseMetadataItem, type StatusCodeStrategy, type StatusCodes, type Transformer, type TransformerBaseArgs, createStatusCodesByStrategy, createTransformer, defineConfig, findObjectKey, generate, generateTypes, getCliVersion, getConfig, getRequestBodyContentType, getResponseMetadataItems, getSchemaNode, isRemoteSchema, isRequiredRequestBody, partitionApiModules, readSchema, readSchemaContent, readTemplateFile, renderApiModules, transformEntity, transformFn, transformModuleName, transformPayloads, transformType, transformTypeQuery, transformTypeQueryValue, transformTypeRequestBody, transformTypeRequestBodyValue, transformTypeResponseBody, transformTypeResponseBodyValue, transformTypeValue, transformUrl, transformVerb };
322
+ export { type ApiModule, type ApiModulePayload, type ApiModuleTemplateData, type Config, type GenerateOptions, type Preset, type ResponseMetadataItem, type StatusCodeStrategy, type StatusCodes, type Transformer, type TransformerBaseArgs, createStatusCodesByStrategy, createTransformer, defineConfig, findObjectKey, generate, generateTypes, getCliVersion, getConfig, getRequestBodyContentType, getResponseMetadataItems, getSchemaNode, isRemoteSchema, isRequiredRequestBody, partitionApiModules, readSchema, readSchemaContent, readTemplateFile, renderApiModules, transformComment, transformEntity, transformFn, transformModuleName, transformPayloads, transformType, transformTypeQuery, transformTypeQueryValue, transformTypeRequestBody, transformTypeRequestBodyValue, transformTypeResponseBody, transformTypeResponseBodyValue, transformTypeValue, transformUrl, transformVerb };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { OpenAPI3, RequestBodyObject, ReferenceObject, OperationObject } from 'openapi-typescript';
1
+ import { OpenAPI3, RequestBodyObject, ReferenceObject, OperationObject, OpenAPITSOptions } from 'openapi-typescript';
2
2
  export { default as pluralize } from 'pluralize';
3
3
 
4
4
  type Preset = 'axle' | 'axios';
@@ -69,6 +69,12 @@ declare function transformUrl({ path }: {
69
69
  fullPath: string;
70
70
  base: string | undefined;
71
71
  }): string;
72
+ declare function transformComment({ summary, description, path, method, }: {
73
+ summary?: string;
74
+ description?: string;
75
+ path: string;
76
+ method: string;
77
+ } & TransformerBaseArgs): string;
72
78
  declare function transformVerb({ method }: {
73
79
  method: string;
74
80
  }): string;
@@ -122,6 +128,7 @@ interface Transformer {
122
128
  moduleName: typeof transformModuleName;
123
129
  verb: typeof transformVerb;
124
130
  url: typeof transformUrl;
131
+ comment: typeof transformComment;
125
132
  entity: typeof transformEntity;
126
133
  fn: typeof transformFn;
127
134
  type: typeof transformType;
@@ -164,6 +171,10 @@ interface ApiModule {
164
171
  payloads: ApiModulePayload[];
165
172
  }
166
173
  interface ApiModulePayload {
174
+ /**
175
+ * The comment of the API endpoint, including summary, description, URL, and method.
176
+ */
177
+ comment: string;
167
178
  /**
168
179
  * The name of the API function/dispatcher, such as apiGetUsers, apiCreatePost, apiUpdateComment, etc.
169
180
  */
@@ -274,6 +285,10 @@ interface GenerateOptions {
274
285
  * Certain uncountable nouns that do not change from singular to plural
275
286
  */
276
287
  uncountableNouns?: string[];
288
+ /**
289
+ * A function to transform the generated types AST before printing to string.
290
+ */
291
+ openapiTsOptions?: OpenAPITSOptions;
277
292
  }
278
293
  declare function transformPayloads(pathItems: Record<string, OperationObject>, options: {
279
294
  path: string;
@@ -297,11 +312,11 @@ declare function renderApiModules(apiModules: ApiModule[], options: {
297
312
  overrides: boolean | string[];
298
313
  preset: Preset;
299
314
  }): Promise<unknown[]>;
300
- declare function generateTypes(schema: OpenAPI3, output: string, typesFilename: string): Promise<void>;
315
+ declare function generateTypes(schema: OpenAPI3, output: string, typesFilename: string, openapiTsOptions: OpenAPITSOptions): Promise<void>;
301
316
  declare function generate(userOptions?: GenerateOptions): Promise<void>;
302
317
 
303
318
  type Config = GenerateOptions;
304
319
  declare function defineConfig(config: Config): GenerateOptions;
305
320
  declare function getConfig(): Promise<Config>;
306
321
 
307
- export { type ApiModule, type ApiModulePayload, type ApiModuleTemplateData, type Config, type GenerateOptions, type Preset, type ResponseMetadataItem, type StatusCodeStrategy, type StatusCodes, type Transformer, type TransformerBaseArgs, createStatusCodesByStrategy, createTransformer, defineConfig, findObjectKey, generate, generateTypes, getCliVersion, getConfig, getRequestBodyContentType, getResponseMetadataItems, getSchemaNode, isRemoteSchema, isRequiredRequestBody, partitionApiModules, readSchema, readSchemaContent, readTemplateFile, renderApiModules, transformEntity, transformFn, transformModuleName, transformPayloads, transformType, transformTypeQuery, transformTypeQueryValue, transformTypeRequestBody, transformTypeRequestBodyValue, transformTypeResponseBody, transformTypeResponseBodyValue, transformTypeValue, transformUrl, transformVerb };
322
+ export { type ApiModule, type ApiModulePayload, type ApiModuleTemplateData, type Config, type GenerateOptions, type Preset, type ResponseMetadataItem, type StatusCodeStrategy, type StatusCodes, type Transformer, type TransformerBaseArgs, createStatusCodesByStrategy, createTransformer, defineConfig, findObjectKey, generate, generateTypes, getCliVersion, getConfig, getRequestBodyContentType, getResponseMetadataItems, getSchemaNode, isRemoteSchema, isRequiredRequestBody, partitionApiModules, readSchema, readSchemaContent, readTemplateFile, renderApiModules, transformComment, transformEntity, transformFn, transformModuleName, transformPayloads, transformType, transformTypeQuery, transformTypeQueryValue, transformTypeRequestBody, transformTypeRequestBodyValue, transformTypeResponseBody, transformTypeResponseBodyValue, transformTypeValue, transformUrl, transformVerb };
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  getConfig,
7
7
  partitionApiModules,
8
8
  renderApiModules,
9
+ transformComment,
9
10
  transformEntity,
10
11
  transformFn,
11
12
  transformModuleName,
@@ -20,7 +21,7 @@ import {
20
21
  transformTypeValue,
21
22
  transformUrl,
22
23
  transformVerb
23
- } from "./chunk-XM2F7GOE.js";
24
+ } from "./chunk-P3SVS555.js";
24
25
  import {
25
26
  createStatusCodesByStrategy,
26
27
  findObjectKey,
@@ -33,7 +34,7 @@ import {
33
34
  readSchema,
34
35
  readSchemaContent,
35
36
  readTemplateFile
36
- } from "./chunk-56NOW5DM.js";
37
+ } from "./chunk-2227C45C.js";
37
38
 
38
39
  // src/index.ts
39
40
  import { default as default2 } from "pluralize";
@@ -57,6 +58,7 @@ export {
57
58
  readSchemaContent,
58
59
  readTemplateFile,
59
60
  renderApiModules,
61
+ transformComment,
60
62
  transformEntity,
61
63
  transformFn,
62
64
  transformModuleName,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "api-farmer",
3
- "version": "0.0.28",
3
+ "version": "0.1.1",
4
4
  "description": "API module generation tool based on Openapi3/Swagger2.",
5
5
  "keywords": [
6
6
  "cli",
@@ -55,21 +55,21 @@
55
55
  "fs-extra": "^11.2.0",
56
56
  "openapi-typescript": "^7.5.2",
57
57
  "pluralize": "^8.0.0",
58
+ "prettier": "^3.4.2",
58
59
  "rattail": "^1.0.19",
59
60
  "rslog": "^1.2.3",
60
61
  "swagger2openapi": "^7.0.8",
61
62
  "unconfig": "^0.6.0",
62
- "yaml": "^2.7.0",
63
- "prettier": "^3.4.2"
63
+ "yaml": "^2.7.0"
64
64
  },
65
65
  "devDependencies": {
66
- "@configurajs/eslint": "^0.1.0",
67
- "@configurajs/prettier": "^0.1.1",
66
+ "@configurajs/eslint": "^0.1.2",
67
+ "@configurajs/prettier": "^0.1.4",
68
68
  "@types/ejs": "^3.1.5",
69
69
  "@types/fs-extra": "^11.0.4",
70
70
  "@types/node": "^22.8.1",
71
71
  "@types/swagger2openapi": "^7.0.4",
72
- "@varlet/release": "^0.3.1",
72
+ "@varlet/release": "^0.4.1",
73
73
  "eslint": "^9.17.0",
74
74
  "nano-staged": "0.8.0",
75
75
  "rimraf": "^6.0.1",
@@ -78,7 +78,7 @@
78
78
  "typescript": "5.3.3"
79
79
  },
80
80
  "peerDependencies": {
81
- "eslint": "^9.17.0"
81
+ "typescript": "^5.3.3"
82
82
  },
83
83
  "engines": {
84
84
  "pnpm": ">=9.0"
@@ -88,8 +88,8 @@
88
88
  "clean": "rimraf node_modules dist",
89
89
  "dev": "tsup src/index.ts src/cli.ts --format esm,cjs --watch --dts --shims",
90
90
  "format": "prettier --write .",
91
+ "gen": "rimraf ./fixtures/axios/src/apis/generated ./fixtures/axle/src/apis/generated && pnpm --dir ./fixtures/axios gen & pnpm --dir ./fixtures/axle gen",
91
92
  "lint": "eslint . --fix",
92
- "release": "pnpm build && vr release",
93
- "gen": "rimraf ./fixtures/axios/src/apis/generated ./fixtures/axle/src/apis/generated && pnpm --dir ./fixtures/axios gen & pnpm --dir ./fixtures/axle gen"
93
+ "release": "pnpm build && vr release"
94
94
  }
95
95
  }
@@ -4,6 +4,7 @@
4
4
 
5
5
  <%_ if (!typesOnly) { _%>
6
6
  <% apiModule.payloads.forEach(payload => { %> %>
7
+ <%- payload.comment %>
7
8
  export const <%- payload.fn %> =
8
9
  (config<% if (ts) { %>: RequestConfig<<%- payload.typeQuery %>, <%- payload.typeRequestBody %>> <% } %> = {}) => request
9
10
  <% if (ts) { %><<%- payload.typeResponseBody %>><% } %>({
@@ -3,6 +3,7 @@
3
3
 
4
4
  <% if (!typesOnly) { %>
5
5
  <% apiModule.payloads.forEach(payload => { %> %>
6
+ <%- payload.comment %>
6
7
  export const <%- payload.fn %> = api
7
8
 
8
9
  <% if (ts) { %>