apigen-ts 1.1.0 → 1.2.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/dist/cli.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var main$1 = require('./main-B2qgp9dv.cjs');
3
+ var main$1 = require('./main-BLaUzCCM.cjs');
4
4
  require('fs/promises');
5
5
  require('path');
6
6
  require('url');
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as apigen, g as getCliConfig } from './main-BvB08bJo.js';
2
+ import { a as apigen, g as getCliConfig } from './main-BZrWxHPM.js';
3
3
  import 'fs/promises';
4
4
  import 'path';
5
5
  import 'url';
package/dist/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as apigen, g as getCliConfig } from './main-BvB08bJo.mjs';
1
+ import { a as apigen, g as getCliConfig } from './main-BZrWxHPM.mjs';
2
2
  import 'fs/promises';
3
3
  import 'path';
4
4
  import 'url';
@@ -13,7 +13,7 @@ var path = require('node:path');
13
13
 
14
14
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
15
15
  var name = "apigen-ts";
16
- var version = "1.1.0";
16
+ var version = "1.2.1";
17
17
 
18
18
  const initCtx = (config) => {
19
19
  return {
@@ -23,11 +23,20 @@ const initCtx = (config) => {
23
23
  doc: { openapi: "3.1.0" },
24
24
  parseDates: false,
25
25
  inlineEnums: false,
26
+ headers: {},
26
27
  ...config,
27
28
  logTag: "",
28
29
  usedNames: /* @__PURE__ */ new Set()
29
30
  };
30
31
  };
32
+ const parseHeaders = (items) => {
33
+ const headers = {};
34
+ for (const item of items) {
35
+ const [key, val] = item.split(":");
36
+ if (key && val) headers[key.trim()] = val.trim();
37
+ }
38
+ return headers;
39
+ };
31
40
  const getCliConfig = () => {
32
41
  const argv = cleye.cli({
33
42
  name,
@@ -36,18 +45,24 @@ const getCliConfig = () => {
36
45
  flags: {
37
46
  name: {
38
47
  type: String,
39
- description: "api class name to export",
48
+ description: "API class name to export",
40
49
  default: "ApiClient"
41
50
  },
42
51
  parseDates: {
43
52
  type: Boolean,
44
- description: "parse dates as Date objects",
53
+ description: "Parse dates as Date objects",
45
54
  default: false
46
55
  },
47
56
  inlineEnums: {
48
57
  type: Boolean,
49
- description: "use inline enums instead of enum types",
58
+ description: "Use inline enums instead of enum types",
50
59
  default: false
60
+ },
61
+ header: {
62
+ type: [String],
63
+ alias: "H",
64
+ description: 'HTTP header as key=value (e.g., -H "x-api-key: your-key"). Used only when generating code.',
65
+ default: []
51
66
  }
52
67
  }
53
68
  });
@@ -56,13 +71,14 @@ const getCliConfig = () => {
56
71
  output: argv._.output ?? null,
57
72
  name: argv.flags.name,
58
73
  parseDates: argv.flags.parseDates,
59
- inlineEnums: argv.flags.inlineEnums
74
+ inlineEnums: argv.flags.inlineEnums,
75
+ headers: parseHeaders(argv.flags.header)
60
76
  };
61
77
  return config;
62
78
  };
63
79
 
64
80
  const unref = (ctx, s) => {
65
- if (!s) return undefined;
81
+ if (!s) return void 0;
66
82
  if ("$ref" in s && s.$ref) {
67
83
  const parts = s.$ref.replace("#/", "").split("/");
68
84
  const obj = parts.reduce(
@@ -72,15 +88,15 @@ const unref = (ctx, s) => {
72
88
  );
73
89
  if (obj) return obj;
74
90
  console.warn(`${ctx.logTag} ref ${s.$ref} not found`);
75
- return undefined;
91
+ return void 0;
76
92
  }
77
93
  return s;
78
94
  };
79
95
  const getReqSchema = (ctx, config) => {
80
96
  const req = unref(ctx, config.requestBody);
81
- if (!req) return undefined;
97
+ if (!req) return void 0;
82
98
  const cts = Object.entries(req.content ?? {}).map((x) => [x[0].split(";")[0], x[1].schema]).filter((x) => x[1]);
83
- if (cts.length === 0) return undefined;
99
+ if (cts.length === 0) return void 0;
84
100
  const pretenders = [
85
101
  "application/json",
86
102
  "text/",
@@ -92,18 +108,18 @@ const getReqSchema = (ctx, config) => {
92
108
  if (ct) return ct;
93
109
  }
94
110
  cts.map((x) => x[0]);
95
- return undefined;
111
+ return void 0;
96
112
  };
97
113
  const getRepSchema = (ctx, config) => {
98
114
  const successCodes = Object.keys(config.responses ?? {}).filter((x) => x.startsWith("2")).filter((x) => lodashEs.get(config, ["responses", x, "content"]));
99
115
  const cts = Object.entries(lodashEs.get(config, ["responses", successCodes[0], "content"], {})).filter((x) => x[1].schema);
100
- if (cts.length === 0) return undefined;
116
+ if (cts.length === 0) return void 0;
101
117
  const ctJson = cts.find((x) => x[0].startsWith("application/json"));
102
118
  if (ctJson) return ctJson[1].schema;
103
119
  const ctText = cts.find((x) => x[0].startsWith("text/"));
104
120
  if (ctText) return { type: "string" };
105
121
  cts.map((x) => x[0]).join(", ");
106
- return undefined;
122
+ return void 0;
107
123
  };
108
124
 
109
125
  const f$2 = ts.factory;
@@ -179,9 +195,9 @@ const normalizeIdentifier = (val, asVar = false) => {
179
195
  return name;
180
196
  };
181
197
  const makeInlineEnum = (s) => {
182
- if (!s.enum) return undefined;
198
+ if (!s.enum) return void 0;
183
199
  const values = arrayUtilsTs.filterEmpty(s.enum);
184
- if (!values.length) return undefined;
200
+ if (!values.length) return void 0;
185
201
  if (!s.type) {
186
202
  if (values.every((x) => typeof x === "string")) s.type = "string";
187
203
  if (values.every((x) => typeof x === "number")) s.type = "number";
@@ -202,7 +218,7 @@ const makeInlineEnum = (s) => {
202
218
  return f$2.createUnionTypeNode(tokens.map((x) => f$2.createLiteralTypeNode(x)));
203
219
  }
204
220
  console.warn(`enum with unknown type "${s.type}" in`, s);
205
- return undefined;
221
+ return void 0;
206
222
  };
207
223
  const makeObject = (ctx, s) => {
208
224
  if (s.type !== "object") throw new Error(`makeObject: not an object ${JSON.stringify(s)}`);
@@ -214,9 +230,15 @@ const makeObject = (ctx, s) => {
214
230
  }
215
231
  return f$2.createKeywordTypeNode(ts.SyntaxKind.ObjectKeyword);
216
232
  };
233
+ const makeLiteralUnion = (ctx, types) => {
234
+ const tokens = types.map((x) => makeType(ctx, { type: x }));
235
+ const hasUnknown = tokens.some((x) => x.kind === ts.SyntaxKind.UnknownKeyword);
236
+ if (hasUnknown) return f$2.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
237
+ return f$2.createUnionTypeNode(tokens);
238
+ };
217
239
  const makeType = (ctx, s) => {
218
240
  const mk = makeType.bind(null, ctx);
219
- if (s === undefined) return f$2.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
241
+ if (s === void 0) return f$2.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
220
242
  if (s === null) return f$2.createLiteralTypeNode(f$2.createNull());
221
243
  if ("$ref" in s && s.$ref) {
222
244
  const parts = s.$ref.replace("#/", "").split("/");
@@ -240,28 +262,22 @@ const makeType = (ctx, s) => {
240
262
  return f$2.createTypeLiteralNode(
241
263
  Object.entries(s.properties).map(([k, v]) => {
242
264
  const r = s.required ?? [];
243
- const q = r.includes(k) ? undefined : f$2.createToken(ts.SyntaxKind.QuestionToken);
244
- return f$2.createPropertySignature(undefined, f$2.createStringLiteral(k), q, mk(v));
265
+ const q = r.includes(k) ? void 0 : f$2.createToken(ts.SyntaxKind.QuestionToken);
266
+ return f$2.createPropertySignature(void 0, f$2.createStringLiteral(k), q, mk(v));
245
267
  })
246
268
  );
247
269
  }
248
270
  if ("type" in s) {
249
- if (Array.isArray(s.type)) {
250
- const types = [];
251
- for (const type of s.type) {
252
- if (type === "null") types.push({ type: "null" });
253
- else types.push({ ...s, type });
254
- }
255
- return mk({ oneOf: types });
256
- }
257
271
  let t;
258
272
  if (s.type === "object") t = makeObject(ctx, s);
259
273
  else if (s.type === "boolean") t = f$2.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
260
274
  else if (s.type === "number") t = f$2.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
261
275
  else if (s.type === "string") t = f$2.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
262
- else if (s.type === "array") t = f$2.createArrayTypeNode(mk(s.items));
263
276
  else if (s.type === "null") t = f$2.createLiteralTypeNode(f$2.createNull());
264
- else if (lodashEs.isArray(s.type)) t = f$2.createUnionTypeNode(s.type.map((x) => mk({ type: x })));
277
+ else if (lodashEs.isArray(s.type)) t = makeLiteralUnion(ctx, s.type);
278
+ else if (s.type === "array" && isPrefixItems(s) && s.prefixItems && !s.items)
279
+ t = f$2.createTupleTypeNode(s.prefixItems.map(mk));
280
+ else if (s.type === "array" && !lodashEs.isBoolean(s.items)) t = f$2.createArrayTypeNode(mk(s.items));
265
281
  else {
266
282
  console.warn(`makeType: unknown type "${s.type}"`);
267
283
  return f$2.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
@@ -270,7 +286,10 @@ const makeType = (ctx, s) => {
270
286
  if (s.format === "binary") t = f$2.createTypeReferenceNode("File");
271
287
  if (s.format === "date-time" && ctx.parseDates) t = f$2.createTypeReferenceNode("Date");
272
288
  }
273
- return s.nullable ? f$2.createUnionTypeNode([t, f$2.createLiteralTypeNode(f$2.createNull())]) : t;
289
+ if ("nullable" in s && s.nullable) {
290
+ return f$2.createUnionTypeNode([t, f$2.createLiteralTypeNode(f$2.createNull())]);
291
+ }
292
+ return t;
274
293
  }
275
294
  return f$2.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
276
295
  };
@@ -280,6 +299,9 @@ const isStringEnum = (s) => {
280
299
  }
281
300
  return false;
282
301
  };
302
+ const isPrefixItems = (s) => {
303
+ return s.prefixItems !== void 0;
304
+ };
283
305
  const makeTypeAlias = (ctx, name, s) => {
284
306
  if (isStringEnum(s) && !ctx.inlineEnums) {
285
307
  const tokens1 = lodashEs.uniq(s.enum);
@@ -298,7 +320,7 @@ const makeTypeAlias = (ctx, name, s) => {
298
320
  return f$2.createTypeAliasDeclaration(
299
321
  [f$2.createToken(ts.SyntaxKind.ExportKeyword)],
300
322
  f$2.createIdentifier(normalizeIdentifier(name, true)),
301
- undefined,
323
+ void 0,
302
324
  makeType(ctx, s)
303
325
  );
304
326
  };
@@ -327,7 +349,7 @@ const getOpName = (ctx, op) => {
327
349
  if (ctx.resolveName) {
328
350
  const res = ctx.resolveName(ctx, op, proposal);
329
351
  if (Array.isArray(res) && res.length === 2) return res;
330
- if (res !== undefined) {
352
+ if (res !== void 0) {
331
353
  console.warn(`${ctx.logTag} resolveName should return [ns, fn] or undefined (skipping)`);
332
354
  }
333
355
  }
@@ -369,10 +391,10 @@ const prepareOp = (ctx, cfg, opName) => {
369
391
  const name = normalizeIdentifier(x.name, true);
370
392
  const type = makeType(ctx, x.schema);
371
393
  urlReplacements[x.name] = name;
372
- return f$1.createParameterDeclaration(undefined, undefined, name, undefined, type);
394
+ return f$1.createParameterDeclaration(void 0, void 0, name, void 0, type);
373
395
  });
374
396
  const cbArgs = arrayUtilsTs.filterNullable([
375
- search.length ? f$1.createShorthandPropertyAssignment("search") : undefined,
397
+ search.length ? f$1.createShorthandPropertyAssignment("search") : void 0,
376
398
  reqSchema && f$1.createShorthandPropertyAssignment("body"),
377
399
  reqSchema && reqSchema[0] !== "application/json" ? f$1.createPropertyAssignment(
378
400
  "headers",
@@ -382,16 +404,16 @@ const prepareOp = (ctx, cfg, opName) => {
382
404
  f$1.createStringLiteral(reqSchema[0])
383
405
  )
384
406
  ])
385
- ) : undefined
407
+ ) : void 0
386
408
  ]);
387
409
  return f$1.createPropertyAssignment(
388
410
  f$1.createIdentifier(normalizeIdentifier(opName)),
389
411
  f$1.createArrowFunction(
390
- undefined,
391
- undefined,
412
+ void 0,
413
+ void 0,
392
414
  fnArgs,
393
- undefined,
394
- undefined,
415
+ void 0,
416
+ void 0,
395
417
  f$1.createBlock([
396
418
  f$1.createReturnStatement(
397
419
  f$1.createCallExpression(
@@ -413,10 +435,10 @@ const prepareOp = (ctx, cfg, opName) => {
413
435
  };
414
436
  const prepareNs = (ctx, name, handlers) => {
415
437
  return f$1.createPropertyDeclaration(
416
- undefined,
438
+ void 0,
417
439
  normalizeIdentifier(name),
418
- undefined,
419
- undefined,
440
+ void 0,
441
+ void 0,
420
442
  f$1.createObjectLiteralExpression(handlers)
421
443
  );
422
444
  };
@@ -476,12 +498,23 @@ const generateAst = async (ctx) => {
476
498
  }
477
499
  return { modules, types };
478
500
  };
479
- const loadSchema = async (url, upgrade = true) => {
501
+ const loadSchema = async ({
502
+ url,
503
+ upgrade = true,
504
+ headers = {}
505
+ }) => {
480
506
  if (url.startsWith("file://")) url = url.substring(7);
481
507
  const { bundle } = await redocly.bundle({
482
508
  ref: url,
483
509
  config: await redocly.createConfig({}),
484
- removeUnusedComponents: false
510
+ removeUnusedComponents: false,
511
+ externalRefResolver: new redocly.BaseResolver({
512
+ http: {
513
+ headers: Object.entries(headers).map(([name, value]) => {
514
+ return { name, value, matches: "**" };
515
+ })
516
+ }
517
+ })
485
518
  });
486
519
  if (bundle.parsed.swagger && upgrade) {
487
520
  const { openapi } = await swagger2openapi.convertObj(bundle.parsed, { patch: true });
@@ -519,10 +552,10 @@ const formatCode = async (code) => {
519
552
  };
520
553
 
521
554
  const apigen = async (config) => {
522
- const doc = await loadSchema(config.source);
555
+ const doc = await loadSchema({ url: config.source, headers: config.headers });
523
556
  const ctx = initCtx({ ...config, doc });
524
557
  const { modules, types } = await generateAst(ctx);
525
- const filepath = path$1.join(path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('main-B2qgp9dv.cjs', document.baseURI).href)))), "_template.ts");
558
+ const filepath = path$1.join(path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('main-BLaUzCCM.cjs', document.baseURI).href)))), "_template.ts");
526
559
  const file = await fs.readFile(filepath, "utf-8");
527
560
  let code = [
528
561
  `// Auto-generated by https://github.com/vladkens/apigen-ts`,
@@ -2,15 +2,15 @@ import fs from 'fs/promises';
2
2
  import { join, dirname } from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import { cli } from 'cleye';
5
- import redocly from '@redocly/openapi-core';
5
+ import redocly, { BaseResolver } from '@redocly/openapi-core';
6
6
  import { filterEmpty, filterNullable } from 'array-utils-ts';
7
- import { get, uniq, upperFirst, isArray, isBoolean, isObject, sortBy, lowerFirst, uniqBy } from 'lodash-es';
7
+ import { get, uniq, upperFirst, isArray, isBoolean, sortBy, isObject, lowerFirst, uniqBy } from 'lodash-es';
8
8
  import { convertObj } from 'swagger2openapi';
9
9
  import ts from 'typescript';
10
10
  import path from 'node:path';
11
11
 
12
12
  var name = "apigen-ts";
13
- var version = "1.1.0";
13
+ var version = "1.2.1";
14
14
 
15
15
  const initCtx = (config) => {
16
16
  return {
@@ -20,11 +20,20 @@ const initCtx = (config) => {
20
20
  doc: { openapi: "3.1.0" },
21
21
  parseDates: false,
22
22
  inlineEnums: false,
23
+ headers: {},
23
24
  ...config,
24
25
  logTag: "",
25
26
  usedNames: /* @__PURE__ */ new Set()
26
27
  };
27
28
  };
29
+ const parseHeaders = (items) => {
30
+ const headers = {};
31
+ for (const item of items) {
32
+ const [key, val] = item.split(":");
33
+ if (key && val) headers[key.trim()] = val.trim();
34
+ }
35
+ return headers;
36
+ };
28
37
  const getCliConfig = () => {
29
38
  const argv = cli({
30
39
  name,
@@ -33,18 +42,24 @@ const getCliConfig = () => {
33
42
  flags: {
34
43
  name: {
35
44
  type: String,
36
- description: "api class name to export",
45
+ description: "API class name to export",
37
46
  default: "ApiClient"
38
47
  },
39
48
  parseDates: {
40
49
  type: Boolean,
41
- description: "parse dates as Date objects",
50
+ description: "Parse dates as Date objects",
42
51
  default: false
43
52
  },
44
53
  inlineEnums: {
45
54
  type: Boolean,
46
- description: "use inline enums instead of enum types",
55
+ description: "Use inline enums instead of enum types",
47
56
  default: false
57
+ },
58
+ header: {
59
+ type: [String],
60
+ alias: "H",
61
+ description: 'HTTP header as key=value (e.g., -H "x-api-key: your-key"). Used only when generating code.',
62
+ default: []
48
63
  }
49
64
  }
50
65
  });
@@ -53,13 +68,14 @@ const getCliConfig = () => {
53
68
  output: argv._.output ?? null,
54
69
  name: argv.flags.name,
55
70
  parseDates: argv.flags.parseDates,
56
- inlineEnums: argv.flags.inlineEnums
71
+ inlineEnums: argv.flags.inlineEnums,
72
+ headers: parseHeaders(argv.flags.header)
57
73
  };
58
74
  return config;
59
75
  };
60
76
 
61
77
  const unref = (ctx, s) => {
62
- if (!s) return undefined;
78
+ if (!s) return void 0;
63
79
  if ("$ref" in s && s.$ref) {
64
80
  const parts = s.$ref.replace("#/", "").split("/");
65
81
  const obj = parts.reduce(
@@ -69,15 +85,15 @@ const unref = (ctx, s) => {
69
85
  );
70
86
  if (obj) return obj;
71
87
  console.warn(`${ctx.logTag} ref ${s.$ref} not found`);
72
- return undefined;
88
+ return void 0;
73
89
  }
74
90
  return s;
75
91
  };
76
92
  const getReqSchema = (ctx, config) => {
77
93
  const req = unref(ctx, config.requestBody);
78
- if (!req) return undefined;
94
+ if (!req) return void 0;
79
95
  const cts = Object.entries(req.content ?? {}).map((x) => [x[0].split(";")[0], x[1].schema]).filter((x) => x[1]);
80
- if (cts.length === 0) return undefined;
96
+ if (cts.length === 0) return void 0;
81
97
  const pretenders = [
82
98
  "application/json",
83
99
  "text/",
@@ -89,18 +105,18 @@ const getReqSchema = (ctx, config) => {
89
105
  if (ct) return ct;
90
106
  }
91
107
  cts.map((x) => x[0]);
92
- return undefined;
108
+ return void 0;
93
109
  };
94
110
  const getRepSchema = (ctx, config) => {
95
111
  const successCodes = Object.keys(config.responses ?? {}).filter((x) => x.startsWith("2")).filter((x) => get(config, ["responses", x, "content"]));
96
112
  const cts = Object.entries(get(config, ["responses", successCodes[0], "content"], {})).filter((x) => x[1].schema);
97
- if (cts.length === 0) return undefined;
113
+ if (cts.length === 0) return void 0;
98
114
  const ctJson = cts.find((x) => x[0].startsWith("application/json"));
99
115
  if (ctJson) return ctJson[1].schema;
100
116
  const ctText = cts.find((x) => x[0].startsWith("text/"));
101
117
  if (ctText) return { type: "string" };
102
118
  cts.map((x) => x[0]).join(", ");
103
- return undefined;
119
+ return void 0;
104
120
  };
105
121
 
106
122
  const f$2 = ts.factory;
@@ -176,9 +192,9 @@ const normalizeIdentifier = (val, asVar = false) => {
176
192
  return name;
177
193
  };
178
194
  const makeInlineEnum = (s) => {
179
- if (!s.enum) return undefined;
195
+ if (!s.enum) return void 0;
180
196
  const values = filterEmpty(s.enum);
181
- if (!values.length) return undefined;
197
+ if (!values.length) return void 0;
182
198
  if (!s.type) {
183
199
  if (values.every((x) => typeof x === "string")) s.type = "string";
184
200
  if (values.every((x) => typeof x === "number")) s.type = "number";
@@ -199,7 +215,7 @@ const makeInlineEnum = (s) => {
199
215
  return f$2.createUnionTypeNode(tokens.map((x) => f$2.createLiteralTypeNode(x)));
200
216
  }
201
217
  console.warn(`enum with unknown type "${s.type}" in`, s);
202
- return undefined;
218
+ return void 0;
203
219
  };
204
220
  const makeObject = (ctx, s) => {
205
221
  if (s.type !== "object") throw new Error(`makeObject: not an object ${JSON.stringify(s)}`);
@@ -211,9 +227,15 @@ const makeObject = (ctx, s) => {
211
227
  }
212
228
  return f$2.createKeywordTypeNode(ts.SyntaxKind.ObjectKeyword);
213
229
  };
230
+ const makeLiteralUnion = (ctx, types) => {
231
+ const tokens = types.map((x) => makeType(ctx, { type: x }));
232
+ const hasUnknown = tokens.some((x) => x.kind === ts.SyntaxKind.UnknownKeyword);
233
+ if (hasUnknown) return f$2.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
234
+ return f$2.createUnionTypeNode(tokens);
235
+ };
214
236
  const makeType = (ctx, s) => {
215
237
  const mk = makeType.bind(null, ctx);
216
- if (s === undefined) return f$2.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
238
+ if (s === void 0) return f$2.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
217
239
  if (s === null) return f$2.createLiteralTypeNode(f$2.createNull());
218
240
  if ("$ref" in s && s.$ref) {
219
241
  const parts = s.$ref.replace("#/", "").split("/");
@@ -237,28 +259,22 @@ const makeType = (ctx, s) => {
237
259
  return f$2.createTypeLiteralNode(
238
260
  Object.entries(s.properties).map(([k, v]) => {
239
261
  const r = s.required ?? [];
240
- const q = r.includes(k) ? undefined : f$2.createToken(ts.SyntaxKind.QuestionToken);
241
- return f$2.createPropertySignature(undefined, f$2.createStringLiteral(k), q, mk(v));
262
+ const q = r.includes(k) ? void 0 : f$2.createToken(ts.SyntaxKind.QuestionToken);
263
+ return f$2.createPropertySignature(void 0, f$2.createStringLiteral(k), q, mk(v));
242
264
  })
243
265
  );
244
266
  }
245
267
  if ("type" in s) {
246
- if (Array.isArray(s.type)) {
247
- const types = [];
248
- for (const type of s.type) {
249
- if (type === "null") types.push({ type: "null" });
250
- else types.push({ ...s, type });
251
- }
252
- return mk({ oneOf: types });
253
- }
254
268
  let t;
255
269
  if (s.type === "object") t = makeObject(ctx, s);
256
270
  else if (s.type === "boolean") t = f$2.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
257
271
  else if (s.type === "number") t = f$2.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
258
272
  else if (s.type === "string") t = f$2.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
259
- else if (s.type === "array") t = f$2.createArrayTypeNode(mk(s.items));
260
273
  else if (s.type === "null") t = f$2.createLiteralTypeNode(f$2.createNull());
261
- else if (isArray(s.type)) t = f$2.createUnionTypeNode(s.type.map((x) => mk({ type: x })));
274
+ else if (isArray(s.type)) t = makeLiteralUnion(ctx, s.type);
275
+ else if (s.type === "array" && isPrefixItems(s) && s.prefixItems && !s.items)
276
+ t = f$2.createTupleTypeNode(s.prefixItems.map(mk));
277
+ else if (s.type === "array" && !isBoolean(s.items)) t = f$2.createArrayTypeNode(mk(s.items));
262
278
  else {
263
279
  console.warn(`makeType: unknown type "${s.type}"`);
264
280
  return f$2.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
@@ -267,7 +283,10 @@ const makeType = (ctx, s) => {
267
283
  if (s.format === "binary") t = f$2.createTypeReferenceNode("File");
268
284
  if (s.format === "date-time" && ctx.parseDates) t = f$2.createTypeReferenceNode("Date");
269
285
  }
270
- return s.nullable ? f$2.createUnionTypeNode([t, f$2.createLiteralTypeNode(f$2.createNull())]) : t;
286
+ if ("nullable" in s && s.nullable) {
287
+ return f$2.createUnionTypeNode([t, f$2.createLiteralTypeNode(f$2.createNull())]);
288
+ }
289
+ return t;
271
290
  }
272
291
  return f$2.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
273
292
  };
@@ -277,6 +296,9 @@ const isStringEnum = (s) => {
277
296
  }
278
297
  return false;
279
298
  };
299
+ const isPrefixItems = (s) => {
300
+ return s.prefixItems !== void 0;
301
+ };
280
302
  const makeTypeAlias = (ctx, name, s) => {
281
303
  if (isStringEnum(s) && !ctx.inlineEnums) {
282
304
  const tokens1 = uniq(s.enum);
@@ -295,7 +317,7 @@ const makeTypeAlias = (ctx, name, s) => {
295
317
  return f$2.createTypeAliasDeclaration(
296
318
  [f$2.createToken(ts.SyntaxKind.ExportKeyword)],
297
319
  f$2.createIdentifier(normalizeIdentifier(name, true)),
298
- undefined,
320
+ void 0,
299
321
  makeType(ctx, s)
300
322
  );
301
323
  };
@@ -324,7 +346,7 @@ const getOpName = (ctx, op) => {
324
346
  if (ctx.resolveName) {
325
347
  const res = ctx.resolveName(ctx, op, proposal);
326
348
  if (Array.isArray(res) && res.length === 2) return res;
327
- if (res !== undefined) {
349
+ if (res !== void 0) {
328
350
  console.warn(`${ctx.logTag} resolveName should return [ns, fn] or undefined (skipping)`);
329
351
  }
330
352
  }
@@ -366,10 +388,10 @@ const prepareOp = (ctx, cfg, opName) => {
366
388
  const name = normalizeIdentifier(x.name, true);
367
389
  const type = makeType(ctx, x.schema);
368
390
  urlReplacements[x.name] = name;
369
- return f$1.createParameterDeclaration(undefined, undefined, name, undefined, type);
391
+ return f$1.createParameterDeclaration(void 0, void 0, name, void 0, type);
370
392
  });
371
393
  const cbArgs = filterNullable([
372
- search.length ? f$1.createShorthandPropertyAssignment("search") : undefined,
394
+ search.length ? f$1.createShorthandPropertyAssignment("search") : void 0,
373
395
  reqSchema && f$1.createShorthandPropertyAssignment("body"),
374
396
  reqSchema && reqSchema[0] !== "application/json" ? f$1.createPropertyAssignment(
375
397
  "headers",
@@ -379,16 +401,16 @@ const prepareOp = (ctx, cfg, opName) => {
379
401
  f$1.createStringLiteral(reqSchema[0])
380
402
  )
381
403
  ])
382
- ) : undefined
404
+ ) : void 0
383
405
  ]);
384
406
  return f$1.createPropertyAssignment(
385
407
  f$1.createIdentifier(normalizeIdentifier(opName)),
386
408
  f$1.createArrowFunction(
387
- undefined,
388
- undefined,
409
+ void 0,
410
+ void 0,
389
411
  fnArgs,
390
- undefined,
391
- undefined,
412
+ void 0,
413
+ void 0,
392
414
  f$1.createBlock([
393
415
  f$1.createReturnStatement(
394
416
  f$1.createCallExpression(
@@ -410,10 +432,10 @@ const prepareOp = (ctx, cfg, opName) => {
410
432
  };
411
433
  const prepareNs = (ctx, name, handlers) => {
412
434
  return f$1.createPropertyDeclaration(
413
- undefined,
435
+ void 0,
414
436
  normalizeIdentifier(name),
415
- undefined,
416
- undefined,
437
+ void 0,
438
+ void 0,
417
439
  f$1.createObjectLiteralExpression(handlers)
418
440
  );
419
441
  };
@@ -473,12 +495,23 @@ const generateAst = async (ctx) => {
473
495
  }
474
496
  return { modules, types };
475
497
  };
476
- const loadSchema = async (url, upgrade = true) => {
498
+ const loadSchema = async ({
499
+ url,
500
+ upgrade = true,
501
+ headers = {}
502
+ }) => {
477
503
  if (url.startsWith("file://")) url = url.substring(7);
478
504
  const { bundle } = await redocly.bundle({
479
505
  ref: url,
480
506
  config: await redocly.createConfig({}),
481
- removeUnusedComponents: false
507
+ removeUnusedComponents: false,
508
+ externalRefResolver: new BaseResolver({
509
+ http: {
510
+ headers: Object.entries(headers).map(([name, value]) => {
511
+ return { name, value, matches: "**" };
512
+ })
513
+ }
514
+ })
482
515
  });
483
516
  if (bundle.parsed.swagger && upgrade) {
484
517
  const { openapi } = await convertObj(bundle.parsed, { patch: true });
@@ -516,7 +549,7 @@ const formatCode = async (code) => {
516
549
  };
517
550
 
518
551
  const apigen = async (config) => {
519
- const doc = await loadSchema(config.source);
552
+ const doc = await loadSchema({ url: config.source, headers: config.headers });
520
553
  const ctx = initCtx({ ...config, doc });
521
554
  const { modules, types } = await generateAst(ctx);
522
555
  const filepath = join(dirname(fileURLToPath(import.meta.url)), "_template.ts");
@@ -2,15 +2,15 @@ import fs from 'fs/promises';
2
2
  import { join, dirname } from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import { cli } from 'cleye';
5
- import redocly from '@redocly/openapi-core';
5
+ import redocly, { BaseResolver } from '@redocly/openapi-core';
6
6
  import { filterEmpty, filterNullable } from 'array-utils-ts';
7
- import { get, uniq, upperFirst, isArray, isBoolean, isObject, sortBy, lowerFirst, uniqBy } from 'lodash-es';
7
+ import { get, uniq, upperFirst, isArray, isBoolean, sortBy, isObject, lowerFirst, uniqBy } from 'lodash-es';
8
8
  import { convertObj } from 'swagger2openapi';
9
9
  import ts from 'typescript';
10
10
  import path from 'node:path';
11
11
 
12
12
  var name = "apigen-ts";
13
- var version = "1.1.0";
13
+ var version = "1.2.1";
14
14
 
15
15
  const initCtx = (config) => {
16
16
  return {
@@ -20,11 +20,20 @@ const initCtx = (config) => {
20
20
  doc: { openapi: "3.1.0" },
21
21
  parseDates: false,
22
22
  inlineEnums: false,
23
+ headers: {},
23
24
  ...config,
24
25
  logTag: "",
25
26
  usedNames: /* @__PURE__ */ new Set()
26
27
  };
27
28
  };
29
+ const parseHeaders = (items) => {
30
+ const headers = {};
31
+ for (const item of items) {
32
+ const [key, val] = item.split(":");
33
+ if (key && val) headers[key.trim()] = val.trim();
34
+ }
35
+ return headers;
36
+ };
28
37
  const getCliConfig = () => {
29
38
  const argv = cli({
30
39
  name,
@@ -33,18 +42,24 @@ const getCliConfig = () => {
33
42
  flags: {
34
43
  name: {
35
44
  type: String,
36
- description: "api class name to export",
45
+ description: "API class name to export",
37
46
  default: "ApiClient"
38
47
  },
39
48
  parseDates: {
40
49
  type: Boolean,
41
- description: "parse dates as Date objects",
50
+ description: "Parse dates as Date objects",
42
51
  default: false
43
52
  },
44
53
  inlineEnums: {
45
54
  type: Boolean,
46
- description: "use inline enums instead of enum types",
55
+ description: "Use inline enums instead of enum types",
47
56
  default: false
57
+ },
58
+ header: {
59
+ type: [String],
60
+ alias: "H",
61
+ description: 'HTTP header as key=value (e.g., -H "x-api-key: your-key"). Used only when generating code.',
62
+ default: []
48
63
  }
49
64
  }
50
65
  });
@@ -53,13 +68,14 @@ const getCliConfig = () => {
53
68
  output: argv._.output ?? null,
54
69
  name: argv.flags.name,
55
70
  parseDates: argv.flags.parseDates,
56
- inlineEnums: argv.flags.inlineEnums
71
+ inlineEnums: argv.flags.inlineEnums,
72
+ headers: parseHeaders(argv.flags.header)
57
73
  };
58
74
  return config;
59
75
  };
60
76
 
61
77
  const unref = (ctx, s) => {
62
- if (!s) return undefined;
78
+ if (!s) return void 0;
63
79
  if ("$ref" in s && s.$ref) {
64
80
  const parts = s.$ref.replace("#/", "").split("/");
65
81
  const obj = parts.reduce(
@@ -69,15 +85,15 @@ const unref = (ctx, s) => {
69
85
  );
70
86
  if (obj) return obj;
71
87
  console.warn(`${ctx.logTag} ref ${s.$ref} not found`);
72
- return undefined;
88
+ return void 0;
73
89
  }
74
90
  return s;
75
91
  };
76
92
  const getReqSchema = (ctx, config) => {
77
93
  const req = unref(ctx, config.requestBody);
78
- if (!req) return undefined;
94
+ if (!req) return void 0;
79
95
  const cts = Object.entries(req.content ?? {}).map((x) => [x[0].split(";")[0], x[1].schema]).filter((x) => x[1]);
80
- if (cts.length === 0) return undefined;
96
+ if (cts.length === 0) return void 0;
81
97
  const pretenders = [
82
98
  "application/json",
83
99
  "text/",
@@ -89,18 +105,18 @@ const getReqSchema = (ctx, config) => {
89
105
  if (ct) return ct;
90
106
  }
91
107
  cts.map((x) => x[0]);
92
- return undefined;
108
+ return void 0;
93
109
  };
94
110
  const getRepSchema = (ctx, config) => {
95
111
  const successCodes = Object.keys(config.responses ?? {}).filter((x) => x.startsWith("2")).filter((x) => get(config, ["responses", x, "content"]));
96
112
  const cts = Object.entries(get(config, ["responses", successCodes[0], "content"], {})).filter((x) => x[1].schema);
97
- if (cts.length === 0) return undefined;
113
+ if (cts.length === 0) return void 0;
98
114
  const ctJson = cts.find((x) => x[0].startsWith("application/json"));
99
115
  if (ctJson) return ctJson[1].schema;
100
116
  const ctText = cts.find((x) => x[0].startsWith("text/"));
101
117
  if (ctText) return { type: "string" };
102
118
  cts.map((x) => x[0]).join(", ");
103
- return undefined;
119
+ return void 0;
104
120
  };
105
121
 
106
122
  const f$2 = ts.factory;
@@ -176,9 +192,9 @@ const normalizeIdentifier = (val, asVar = false) => {
176
192
  return name;
177
193
  };
178
194
  const makeInlineEnum = (s) => {
179
- if (!s.enum) return undefined;
195
+ if (!s.enum) return void 0;
180
196
  const values = filterEmpty(s.enum);
181
- if (!values.length) return undefined;
197
+ if (!values.length) return void 0;
182
198
  if (!s.type) {
183
199
  if (values.every((x) => typeof x === "string")) s.type = "string";
184
200
  if (values.every((x) => typeof x === "number")) s.type = "number";
@@ -199,7 +215,7 @@ const makeInlineEnum = (s) => {
199
215
  return f$2.createUnionTypeNode(tokens.map((x) => f$2.createLiteralTypeNode(x)));
200
216
  }
201
217
  console.warn(`enum with unknown type "${s.type}" in`, s);
202
- return undefined;
218
+ return void 0;
203
219
  };
204
220
  const makeObject = (ctx, s) => {
205
221
  if (s.type !== "object") throw new Error(`makeObject: not an object ${JSON.stringify(s)}`);
@@ -211,9 +227,15 @@ const makeObject = (ctx, s) => {
211
227
  }
212
228
  return f$2.createKeywordTypeNode(ts.SyntaxKind.ObjectKeyword);
213
229
  };
230
+ const makeLiteralUnion = (ctx, types) => {
231
+ const tokens = types.map((x) => makeType(ctx, { type: x }));
232
+ const hasUnknown = tokens.some((x) => x.kind === ts.SyntaxKind.UnknownKeyword);
233
+ if (hasUnknown) return f$2.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
234
+ return f$2.createUnionTypeNode(tokens);
235
+ };
214
236
  const makeType = (ctx, s) => {
215
237
  const mk = makeType.bind(null, ctx);
216
- if (s === undefined) return f$2.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
238
+ if (s === void 0) return f$2.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
217
239
  if (s === null) return f$2.createLiteralTypeNode(f$2.createNull());
218
240
  if ("$ref" in s && s.$ref) {
219
241
  const parts = s.$ref.replace("#/", "").split("/");
@@ -237,28 +259,22 @@ const makeType = (ctx, s) => {
237
259
  return f$2.createTypeLiteralNode(
238
260
  Object.entries(s.properties).map(([k, v]) => {
239
261
  const r = s.required ?? [];
240
- const q = r.includes(k) ? undefined : f$2.createToken(ts.SyntaxKind.QuestionToken);
241
- return f$2.createPropertySignature(undefined, f$2.createStringLiteral(k), q, mk(v));
262
+ const q = r.includes(k) ? void 0 : f$2.createToken(ts.SyntaxKind.QuestionToken);
263
+ return f$2.createPropertySignature(void 0, f$2.createStringLiteral(k), q, mk(v));
242
264
  })
243
265
  );
244
266
  }
245
267
  if ("type" in s) {
246
- if (Array.isArray(s.type)) {
247
- const types = [];
248
- for (const type of s.type) {
249
- if (type === "null") types.push({ type: "null" });
250
- else types.push({ ...s, type });
251
- }
252
- return mk({ oneOf: types });
253
- }
254
268
  let t;
255
269
  if (s.type === "object") t = makeObject(ctx, s);
256
270
  else if (s.type === "boolean") t = f$2.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
257
271
  else if (s.type === "number") t = f$2.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
258
272
  else if (s.type === "string") t = f$2.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
259
- else if (s.type === "array") t = f$2.createArrayTypeNode(mk(s.items));
260
273
  else if (s.type === "null") t = f$2.createLiteralTypeNode(f$2.createNull());
261
- else if (isArray(s.type)) t = f$2.createUnionTypeNode(s.type.map((x) => mk({ type: x })));
274
+ else if (isArray(s.type)) t = makeLiteralUnion(ctx, s.type);
275
+ else if (s.type === "array" && isPrefixItems(s) && s.prefixItems && !s.items)
276
+ t = f$2.createTupleTypeNode(s.prefixItems.map(mk));
277
+ else if (s.type === "array" && !isBoolean(s.items)) t = f$2.createArrayTypeNode(mk(s.items));
262
278
  else {
263
279
  console.warn(`makeType: unknown type "${s.type}"`);
264
280
  return f$2.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
@@ -267,7 +283,10 @@ const makeType = (ctx, s) => {
267
283
  if (s.format === "binary") t = f$2.createTypeReferenceNode("File");
268
284
  if (s.format === "date-time" && ctx.parseDates) t = f$2.createTypeReferenceNode("Date");
269
285
  }
270
- return s.nullable ? f$2.createUnionTypeNode([t, f$2.createLiteralTypeNode(f$2.createNull())]) : t;
286
+ if ("nullable" in s && s.nullable) {
287
+ return f$2.createUnionTypeNode([t, f$2.createLiteralTypeNode(f$2.createNull())]);
288
+ }
289
+ return t;
271
290
  }
272
291
  return f$2.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
273
292
  };
@@ -277,6 +296,9 @@ const isStringEnum = (s) => {
277
296
  }
278
297
  return false;
279
298
  };
299
+ const isPrefixItems = (s) => {
300
+ return s.prefixItems !== void 0;
301
+ };
280
302
  const makeTypeAlias = (ctx, name, s) => {
281
303
  if (isStringEnum(s) && !ctx.inlineEnums) {
282
304
  const tokens1 = uniq(s.enum);
@@ -295,7 +317,7 @@ const makeTypeAlias = (ctx, name, s) => {
295
317
  return f$2.createTypeAliasDeclaration(
296
318
  [f$2.createToken(ts.SyntaxKind.ExportKeyword)],
297
319
  f$2.createIdentifier(normalizeIdentifier(name, true)),
298
- undefined,
320
+ void 0,
299
321
  makeType(ctx, s)
300
322
  );
301
323
  };
@@ -324,7 +346,7 @@ const getOpName = (ctx, op) => {
324
346
  if (ctx.resolveName) {
325
347
  const res = ctx.resolveName(ctx, op, proposal);
326
348
  if (Array.isArray(res) && res.length === 2) return res;
327
- if (res !== undefined) {
349
+ if (res !== void 0) {
328
350
  console.warn(`${ctx.logTag} resolveName should return [ns, fn] or undefined (skipping)`);
329
351
  }
330
352
  }
@@ -366,10 +388,10 @@ const prepareOp = (ctx, cfg, opName) => {
366
388
  const name = normalizeIdentifier(x.name, true);
367
389
  const type = makeType(ctx, x.schema);
368
390
  urlReplacements[x.name] = name;
369
- return f$1.createParameterDeclaration(undefined, undefined, name, undefined, type);
391
+ return f$1.createParameterDeclaration(void 0, void 0, name, void 0, type);
370
392
  });
371
393
  const cbArgs = filterNullable([
372
- search.length ? f$1.createShorthandPropertyAssignment("search") : undefined,
394
+ search.length ? f$1.createShorthandPropertyAssignment("search") : void 0,
373
395
  reqSchema && f$1.createShorthandPropertyAssignment("body"),
374
396
  reqSchema && reqSchema[0] !== "application/json" ? f$1.createPropertyAssignment(
375
397
  "headers",
@@ -379,16 +401,16 @@ const prepareOp = (ctx, cfg, opName) => {
379
401
  f$1.createStringLiteral(reqSchema[0])
380
402
  )
381
403
  ])
382
- ) : undefined
404
+ ) : void 0
383
405
  ]);
384
406
  return f$1.createPropertyAssignment(
385
407
  f$1.createIdentifier(normalizeIdentifier(opName)),
386
408
  f$1.createArrowFunction(
387
- undefined,
388
- undefined,
409
+ void 0,
410
+ void 0,
389
411
  fnArgs,
390
- undefined,
391
- undefined,
412
+ void 0,
413
+ void 0,
392
414
  f$1.createBlock([
393
415
  f$1.createReturnStatement(
394
416
  f$1.createCallExpression(
@@ -410,10 +432,10 @@ const prepareOp = (ctx, cfg, opName) => {
410
432
  };
411
433
  const prepareNs = (ctx, name, handlers) => {
412
434
  return f$1.createPropertyDeclaration(
413
- undefined,
435
+ void 0,
414
436
  normalizeIdentifier(name),
415
- undefined,
416
- undefined,
437
+ void 0,
438
+ void 0,
417
439
  f$1.createObjectLiteralExpression(handlers)
418
440
  );
419
441
  };
@@ -473,12 +495,23 @@ const generateAst = async (ctx) => {
473
495
  }
474
496
  return { modules, types };
475
497
  };
476
- const loadSchema = async (url, upgrade = true) => {
498
+ const loadSchema = async ({
499
+ url,
500
+ upgrade = true,
501
+ headers = {}
502
+ }) => {
477
503
  if (url.startsWith("file://")) url = url.substring(7);
478
504
  const { bundle } = await redocly.bundle({
479
505
  ref: url,
480
506
  config: await redocly.createConfig({}),
481
- removeUnusedComponents: false
507
+ removeUnusedComponents: false,
508
+ externalRefResolver: new BaseResolver({
509
+ http: {
510
+ headers: Object.entries(headers).map(([name, value]) => {
511
+ return { name, value, matches: "**" };
512
+ })
513
+ }
514
+ })
482
515
  });
483
516
  if (bundle.parsed.swagger && upgrade) {
484
517
  const { openapi } = await convertObj(bundle.parsed, { patch: true });
@@ -516,7 +549,7 @@ const formatCode = async (code) => {
516
549
  };
517
550
 
518
551
  const apigen = async (config) => {
519
- const doc = await loadSchema(config.source);
552
+ const doc = await loadSchema({ url: config.source, headers: config.headers });
520
553
  const ctx = initCtx({ ...config, doc });
521
554
  const { modules, types } = await generateAst(ctx);
522
555
  const filepath = join(dirname(fileURLToPath(import.meta.url)), "_template.ts");
package/dist/main.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
  require('fs/promises');
4
4
  require('path');
5
5
  require('url');
6
- var main = require('./main-B2qgp9dv.cjs');
6
+ var main = require('./main-BLaUzCCM.cjs');
7
7
  require('cleye');
8
8
  require('@redocly/openapi-core');
9
9
  require('array-utils-ts');
package/dist/main.d.cts CHANGED
@@ -13,6 +13,7 @@ type Config = {
13
13
  parseDates: boolean;
14
14
  inlineEnums: boolean;
15
15
  resolveName?: (ctx: Context, op: OpConfig, proposal: OpName) => OpName | undefined;
16
+ headers: Record<string, string>;
16
17
  };
17
18
  type Context = Config & {
18
19
  doc: Oas3Definition;
package/dist/main.d.mts CHANGED
@@ -13,6 +13,7 @@ type Config = {
13
13
  parseDates: boolean;
14
14
  inlineEnums: boolean;
15
15
  resolveName?: (ctx: Context, op: OpConfig, proposal: OpName) => OpName | undefined;
16
+ headers: Record<string, string>;
16
17
  };
17
18
  type Context = Config & {
18
19
  doc: Oas3Definition;
package/dist/main.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import 'fs/promises';
2
2
  import 'path';
3
3
  import 'url';
4
- export { a as apigen } from './main-BvB08bJo.js';
4
+ export { a as apigen } from './main-BZrWxHPM.js';
5
5
  import 'cleye';
6
6
  import '@redocly/openapi-core';
7
7
  import 'array-utils-ts';
package/dist/main.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import 'fs/promises';
2
2
  import 'path';
3
3
  import 'url';
4
- export { a as apigen } from './main-BvB08bJo.mjs';
4
+ export { a as apigen } from './main-BZrWxHPM.mjs';
5
5
  import 'cleye';
6
6
  import '@redocly/openapi-core';
7
7
  import 'array-utils-ts';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "apigen-ts",
4
- "version": "1.1.0",
4
+ "version": "1.2.1",
5
5
  "license": "MIT",
6
6
  "author": "vladkens <v.pronsky@gmail.com>",
7
7
  "repository": "vladkens/apigen-ts",
@@ -22,23 +22,23 @@
22
22
  "ci": "tsc --noEmit && yarn test-cov && yarn build"
23
23
  },
24
24
  "dependencies": {
25
- "@redocly/openapi-core": "1.27.2",
25
+ "@redocly/openapi-core": "1.34.3",
26
26
  "@types/lodash-es": "4.17.12",
27
27
  "@types/swagger2openapi": "7.0.4",
28
28
  "array-utils-ts": "1.0.2",
29
- "cleye": "1.3.2",
29
+ "cleye": "1.3.4",
30
30
  "lodash-es": "4.17.21",
31
31
  "swagger2openapi": "7.0.8"
32
32
  },
33
33
  "devDependencies": {
34
- "@types/node": "22.10.7",
34
+ "@types/node": "22.15.18",
35
35
  "c8": "10.1.3",
36
- "fetch-mock": "12.2.0",
37
- "pkgroll": "2.6.1",
38
- "prettier": "3.4.2",
36
+ "fetch-mock": "12.5.2",
37
+ "pkgroll": "2.12.2",
38
+ "prettier": "3.5.3",
39
39
  "prettier-plugin-organize-imports": "4.1.0",
40
40
  "tsm": "2.3.0",
41
- "typescript": "5.7.3",
41
+ "typescript": "5.8.3",
42
42
  "uvu": "0.5.6"
43
43
  },
44
44
  "peerDependencies": {
package/readme.md CHANGED
@@ -2,17 +2,16 @@
2
2
 
3
3
  <div align="center">
4
4
 
5
- [<img src="https://badgen.net/npm/v/apigen-ts" alt="version" />](https://npmjs.org/package/apigen-ts)
6
- [<img src="https://badgen.net/packagephobia/publish/apigen-ts" alt="size" />](https://packagephobia.now.sh/result?p=apigen-ts)
7
- [<img src="https://badgen.net/npm/dm/apigen-ts" alt="downloads" />](https://npmjs.org/package/apigen-ts)
8
- [<img src="https://badgen.net/github/license/vladkens/apigen-ts" alt="license" />](https://github.com/vladkens/apigen-ts/blob/main/LICENSE)
9
- [<img src="https://badgen.net/static/-/buy%20me%20a%20coffee/ff813f?icon=buymeacoffee&label" alt="donate" />](https://buymeacoffee.com/vladkens)
5
+ [<img src="https://badges.ws/npm/v/apigen-ts" alt="version" />](https://npmjs.org/package/apigen-ts)
6
+ [<img src="https://badges.ws/packagephobia/publish/apigen-ts" alt="size" />](https://packagephobia.now.sh/result?p=apigen-ts)
7
+ [<img src="https://badges.ws/npm/dm/apigen-ts" alt="downloads" />](https://npmjs.org/package/apigen-ts)
8
+ [<img src="https://badges.ws/github/license/vladkens/apigen-ts" alt="license" />](https://github.com/vladkens/apigen-ts/blob/main/LICENSE)
9
+ [<img src="https://badges.ws/badge/-/buy%20me%20a%20coffee/ff813f?icon=buymeacoffee&label" alt="donate" />](https://buymeacoffee.com/vladkens)
10
10
 
11
11
  </div>
12
12
 
13
13
  <div align="center">
14
14
  <img src="./logo.svg" alt="apigen-ts logo" height="80" />
15
- <div>Simple typed OpenAPI client generator</div>
16
15
  </div>
17
16
 
18
17
  ## Features
@@ -29,7 +28,11 @@
29
28
  ## Install
30
29
 
31
30
  ```sh
32
- yarn install -D apigen-ts
31
+ npm install apigen-ts --save-dev
32
+ ```
33
+
34
+ ```sh
35
+ yarn add -D apigen-ts
33
36
  ```
34
37
 
35
38
  ## Usage
@@ -37,14 +40,17 @@ yarn install -D apigen-ts
37
40
  ### 1. Generate
38
41
 
39
42
  ```sh
43
+ # From file
44
+ npx apigen-ts ./openapi.json ./api-client.ts
45
+
40
46
  # From url
41
- yarn apigen-ts https://petstore3.swagger.io/api/v3/openapi.json ./api-client.ts
47
+ npx apigen-ts https://petstore3.swagger.io/api/v3/openapi.json ./api-client.ts
42
48
 
43
- # From file
44
- yarn apigen-ts ./openapi.json ./api-client.ts
49
+ # From protected url
50
+ npx apigen-ts https://secret-api.example.com ./api-client.ts -H "x-api-key: secret-key"
45
51
  ```
46
52
 
47
- Run `yarn apigen-ts --help` for more options. Examples of generated clients [here](./examples/).
53
+ Run `npx apigen-ts --help` for more options. Examples of generated clients [here](./examples/).
48
54
 
49
55
  ### 2. Import
50
56
 
@@ -84,7 +90,7 @@ await api.protectedRoute.get() // here authenticated
84
90
  ### Automatic date parsing
85
91
 
86
92
  ```sh
87
- yarn apigen-ts ./openapi.json ./api-client.ts --parse-dates
93
+ npx apigen-ts ./openapi.json ./api-client.ts --parse-dates
88
94
  ```
89
95
 
90
96
  ```ts
@@ -97,7 +103,7 @@ const createdAt: Date = pet.createdAt // date parsed from string with format=dat
97
103
  You can generate string literal union instead of native enums in case you want to run in Node.js environment with [type-stripping](https://nodejs.org/api/typescript.html#type-stripping). To achive this pass `--inline-enums` command line argument or use `inlineEnums: true` in Node.js API.
98
104
 
99
105
  ```sh
100
- yarn apigen-ts ./openapi.json ./api-client.ts --inline-enums
106
+ npx apigen-ts ./openapi.json ./api-client.ts --inline-enums
101
107
  ```
102
108
 
103
109
  This will generate:
@@ -177,6 +183,7 @@ await apigen({
177
183
  name: "MyApiClient", // default "ApiClient"
178
184
  parseDates: true, // default false
179
185
  inlineEnums: false, // default false, use string literal union instead of enum
186
+ headers: { "x-api-key": "secret-key" }, // Custom HTTP headers to use when fetching schema
180
187
  resolveName(ctx, op, proposal) {
181
188
  // proposal is [string, string] which represents module.funcName
182
189
  if (proposal[0] === "users") return // will use default proposal