apigen-ts 0.2.0 → 1.0.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.
- package/dist/_template.ts +10 -2
- package/dist/cli.cjs +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/{main-byN_-fkF.js → main-BTcttgNf.js} +13 -3
- package/dist/{main-byN_-fkF.mjs → main-BTcttgNf.mjs} +13 -3
- package/dist/{main-Dkcn3PTN.cjs → main-oWgfChRG.cjs} +13 -3
- package/dist/main.cjs +1 -1
- package/dist/main.js +1 -1
- package/dist/main.mjs +1 -1
- package/package.json +18 -18
- package/readme.md +28 -1
package/dist/_template.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
// Note: Use uppercase for names in ApiClient to avoid conflict with the generated code
|
|
2
2
|
|
|
3
|
+
type Headers = Record<string, string>
|
|
4
|
+
export type ApigenHeaders = Headers | ((method: string, path: string) => Headers | Promise<Headers>)
|
|
5
|
+
|
|
3
6
|
export interface ApigenConfig {
|
|
4
7
|
baseUrl: string
|
|
5
|
-
headers:
|
|
8
|
+
headers: ApigenHeaders
|
|
6
9
|
}
|
|
7
10
|
|
|
8
11
|
export interface ApigenRequest extends Omit<RequestInit, "body"> {
|
|
@@ -58,7 +61,12 @@ export class ApiClient {
|
|
|
58
61
|
url.searchParams.append(k, Array.isArray(v) ? v.join(",") : (v as string))
|
|
59
62
|
}
|
|
60
63
|
|
|
61
|
-
const
|
|
64
|
+
const configHeaders =
|
|
65
|
+
typeof this.Config.headers === "function"
|
|
66
|
+
? await this.Config.headers(method, path)
|
|
67
|
+
: this.Config.headers
|
|
68
|
+
|
|
69
|
+
const headers = new Headers({ ...configHeaders, ...opts.headers })
|
|
62
70
|
const ct = headers.get("content-type") ?? "application/json"
|
|
63
71
|
|
|
64
72
|
let body: FormData | URLSearchParams | string | undefined = undefined
|
package/dist/cli.cjs
CHANGED
package/dist/cli.js
CHANGED
package/dist/cli.mjs
CHANGED
|
@@ -4,13 +4,13 @@ import { fileURLToPath } from 'url';
|
|
|
4
4
|
import { cli } from 'cleye';
|
|
5
5
|
import redocly from '@redocly/openapi-core';
|
|
6
6
|
import { filterEmpty, filterNullable } from 'array-utils-ts';
|
|
7
|
-
import { get, uniq, upperFirst, isArray, isObject, sortBy, lowerFirst, uniqBy } from 'lodash-es';
|
|
7
|
+
import { get, uniq, upperFirst, isArray, isBoolean, isObject, sortBy, 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 = "0.
|
|
13
|
+
var version = "1.0.0";
|
|
14
14
|
|
|
15
15
|
const initCtx = (config) => {
|
|
16
16
|
return {
|
|
@@ -194,6 +194,16 @@ const makeInlineEnum = (s) => {
|
|
|
194
194
|
console.warn(`enum with unknown type "${s.type}" in`, s);
|
|
195
195
|
return void 0;
|
|
196
196
|
};
|
|
197
|
+
const makeObject = (ctx, s) => {
|
|
198
|
+
if (s.type !== "object") throw new Error(`makeObject: not an object ${JSON.stringify(s)}`);
|
|
199
|
+
if (s.additionalProperties && !isBoolean(s.additionalProperties)) {
|
|
200
|
+
return f$2.createTypeReferenceNode("Record", [
|
|
201
|
+
f$2.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
202
|
+
makeType(ctx, s.additionalProperties)
|
|
203
|
+
]);
|
|
204
|
+
}
|
|
205
|
+
return f$2.createKeywordTypeNode(ts.SyntaxKind.ObjectKeyword);
|
|
206
|
+
};
|
|
197
207
|
const makeType = (ctx, s) => {
|
|
198
208
|
const mk = makeType.bind(null, ctx);
|
|
199
209
|
if (s === void 0) return f$2.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
|
|
@@ -235,7 +245,7 @@ const makeType = (ctx, s) => {
|
|
|
235
245
|
return mk({ oneOf: types });
|
|
236
246
|
}
|
|
237
247
|
let t;
|
|
238
|
-
if (s.type === "object") t =
|
|
248
|
+
if (s.type === "object") t = makeObject(ctx, s);
|
|
239
249
|
else if (s.type === "boolean") t = f$2.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
|
|
240
250
|
else if (s.type === "number") t = f$2.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
|
|
241
251
|
else if (s.type === "string") t = f$2.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
|
|
@@ -4,13 +4,13 @@ import { fileURLToPath } from 'url';
|
|
|
4
4
|
import { cli } from 'cleye';
|
|
5
5
|
import redocly from '@redocly/openapi-core';
|
|
6
6
|
import { filterEmpty, filterNullable } from 'array-utils-ts';
|
|
7
|
-
import { get, uniq, upperFirst, isArray, isObject, sortBy, lowerFirst, uniqBy } from 'lodash-es';
|
|
7
|
+
import { get, uniq, upperFirst, isArray, isBoolean, isObject, sortBy, 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 = "0.
|
|
13
|
+
var version = "1.0.0";
|
|
14
14
|
|
|
15
15
|
const initCtx = (config) => {
|
|
16
16
|
return {
|
|
@@ -194,6 +194,16 @@ const makeInlineEnum = (s) => {
|
|
|
194
194
|
console.warn(`enum with unknown type "${s.type}" in`, s);
|
|
195
195
|
return void 0;
|
|
196
196
|
};
|
|
197
|
+
const makeObject = (ctx, s) => {
|
|
198
|
+
if (s.type !== "object") throw new Error(`makeObject: not an object ${JSON.stringify(s)}`);
|
|
199
|
+
if (s.additionalProperties && !isBoolean(s.additionalProperties)) {
|
|
200
|
+
return f$2.createTypeReferenceNode("Record", [
|
|
201
|
+
f$2.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
202
|
+
makeType(ctx, s.additionalProperties)
|
|
203
|
+
]);
|
|
204
|
+
}
|
|
205
|
+
return f$2.createKeywordTypeNode(ts.SyntaxKind.ObjectKeyword);
|
|
206
|
+
};
|
|
197
207
|
const makeType = (ctx, s) => {
|
|
198
208
|
const mk = makeType.bind(null, ctx);
|
|
199
209
|
if (s === void 0) return f$2.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
|
|
@@ -235,7 +245,7 @@ const makeType = (ctx, s) => {
|
|
|
235
245
|
return mk({ oneOf: types });
|
|
236
246
|
}
|
|
237
247
|
let t;
|
|
238
|
-
if (s.type === "object") t =
|
|
248
|
+
if (s.type === "object") t = makeObject(ctx, s);
|
|
239
249
|
else if (s.type === "boolean") t = f$2.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
|
|
240
250
|
else if (s.type === "number") t = f$2.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
|
|
241
251
|
else if (s.type === "string") t = f$2.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
|
|
@@ -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 = "0.
|
|
16
|
+
var version = "1.0.0";
|
|
17
17
|
|
|
18
18
|
const initCtx = (config) => {
|
|
19
19
|
return {
|
|
@@ -197,6 +197,16 @@ const makeInlineEnum = (s) => {
|
|
|
197
197
|
console.warn(`enum with unknown type "${s.type}" in`, s);
|
|
198
198
|
return void 0;
|
|
199
199
|
};
|
|
200
|
+
const makeObject = (ctx, s) => {
|
|
201
|
+
if (s.type !== "object") throw new Error(`makeObject: not an object ${JSON.stringify(s)}`);
|
|
202
|
+
if (s.additionalProperties && !lodashEs.isBoolean(s.additionalProperties)) {
|
|
203
|
+
return f$2.createTypeReferenceNode("Record", [
|
|
204
|
+
f$2.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
205
|
+
makeType(ctx, s.additionalProperties)
|
|
206
|
+
]);
|
|
207
|
+
}
|
|
208
|
+
return f$2.createKeywordTypeNode(ts.SyntaxKind.ObjectKeyword);
|
|
209
|
+
};
|
|
200
210
|
const makeType = (ctx, s) => {
|
|
201
211
|
const mk = makeType.bind(null, ctx);
|
|
202
212
|
if (s === void 0) return f$2.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
|
|
@@ -238,7 +248,7 @@ const makeType = (ctx, s) => {
|
|
|
238
248
|
return mk({ oneOf: types });
|
|
239
249
|
}
|
|
240
250
|
let t;
|
|
241
|
-
if (s.type === "object") t =
|
|
251
|
+
if (s.type === "object") t = makeObject(ctx, s);
|
|
242
252
|
else if (s.type === "boolean") t = f$2.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
|
|
243
253
|
else if (s.type === "number") t = f$2.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
|
|
244
254
|
else if (s.type === "string") t = f$2.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
|
|
@@ -505,7 +515,7 @@ const apigen = async (config) => {
|
|
|
505
515
|
const doc = await loadSchema(config.source);
|
|
506
516
|
const ctx = initCtx({ ...config, doc });
|
|
507
517
|
const { modules, types } = await generateAst(ctx);
|
|
508
|
-
const filepath = path$1.join(path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('main-
|
|
518
|
+
const filepath = path$1.join(path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('main-oWgfChRG.cjs', document.baseURI).href)))), "_template.ts");
|
|
509
519
|
const file = await fs.readFile(filepath, "utf-8");
|
|
510
520
|
let code = [
|
|
511
521
|
`// Auto-generated by https://github.com/vladkens/apigen-ts`,
|
package/dist/main.cjs
CHANGED
package/dist/main.js
CHANGED
package/dist/main.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "apigen-ts",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "vladkens <v.pronsky@gmail.com>",
|
|
7
7
|
"repository": "vladkens/apigen-ts",
|
|
8
|
-
"description": "OpenAPI
|
|
8
|
+
"description": "Simple typed OpenAPI client generator",
|
|
9
9
|
"keywords": [
|
|
10
10
|
"openapi",
|
|
11
11
|
"swagger",
|
|
@@ -22,24 +22,24 @@
|
|
|
22
22
|
"ci": "tsc --noEmit && yarn test-cov && yarn build"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@redocly/openapi-core": "
|
|
26
|
-
"@types/lodash-es": "
|
|
27
|
-
"@types/swagger2openapi": "
|
|
28
|
-
"array-utils-ts": "
|
|
29
|
-
"cleye": "
|
|
30
|
-
"lodash-es": "
|
|
31
|
-
"swagger2openapi": "
|
|
25
|
+
"@redocly/openapi-core": "1.25.5",
|
|
26
|
+
"@types/lodash-es": "4.17.12",
|
|
27
|
+
"@types/swagger2openapi": "7.0.4",
|
|
28
|
+
"array-utils-ts": "0.1.2",
|
|
29
|
+
"cleye": "1.3.2",
|
|
30
|
+
"lodash-es": "4.17.21",
|
|
31
|
+
"swagger2openapi": "7.0.8"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@types/node": "
|
|
35
|
-
"c8": "
|
|
36
|
-
"fetch-mock": "
|
|
37
|
-
"pkgroll": "
|
|
38
|
-
"prettier": "
|
|
39
|
-
"prettier-plugin-organize-imports": "
|
|
40
|
-
"tsm": "
|
|
41
|
-
"typescript": "
|
|
42
|
-
"uvu": "
|
|
34
|
+
"@types/node": "22.7.5",
|
|
35
|
+
"c8": "10.1.2",
|
|
36
|
+
"fetch-mock": "11.1.5",
|
|
37
|
+
"pkgroll": "2.5.0",
|
|
38
|
+
"prettier": "3.3.3",
|
|
39
|
+
"prettier-plugin-organize-imports": "4.1.0",
|
|
40
|
+
"tsm": "2.3.0",
|
|
41
|
+
"typescript": "5.6.3",
|
|
42
|
+
"uvu": "0.5.6"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"prettier": "^3.0.0",
|
package/readme.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
<div align="center">
|
|
14
14
|
<img src="./logo.svg" alt="apigen-ts logo" height="80" />
|
|
15
|
-
<div>
|
|
15
|
+
<div>Simple typed OpenAPI client generator</div>
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
## Features
|
|
@@ -168,6 +168,33 @@ await apigen({
|
|
|
168
168
|
|
|
169
169
|
Then run with: `node apigen.mjs`
|
|
170
170
|
|
|
171
|
+
## Usage with different backend frameworks
|
|
172
|
+
|
|
173
|
+
### FastAPI
|
|
174
|
+
|
|
175
|
+
By default `apigen-ts` generates noisy method names when used with FastAPI. This can be fixed by [custom resolving](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#using-the-path-operation-function-name-as-the-operationid) for operations ids.
|
|
176
|
+
|
|
177
|
+
```py
|
|
178
|
+
from fastapi import FastAPI
|
|
179
|
+
from fastapi.routing import APIRoute
|
|
180
|
+
|
|
181
|
+
app = FastAPI()
|
|
182
|
+
|
|
183
|
+
# add your routes here
|
|
184
|
+
|
|
185
|
+
def update_operation_ids(app: FastAPI) -> None:
|
|
186
|
+
for route in app.routes:
|
|
187
|
+
if isinstance(route, APIRoute):
|
|
188
|
+
ns = route.tags[0] if route.tags else "general"
|
|
189
|
+
route.operation_id = f"{ns}_{route.name}".lower()
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
# this function should be after all routes added
|
|
193
|
+
update_operation_ids(app)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
_Note: If you want FastAPI to be added as preset, open PR please._
|
|
197
|
+
|
|
171
198
|
## Compare
|
|
172
199
|
|
|
173
200
|
- [openapi-typescript-codegen](https://github.com/ferdikoomen/openapi-typescript-codegen) ([npm](https://www.npmjs.com/package/openapi-typescript-codegen)): no single file mode [#1263](https://github.com/ferdikoomen/openapi-typescript-codegen/issues/1263#issuecomment-1502890838)
|