@devbie/apits 1.0.2 → 1.0.4
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/cjs/core/generator.js +3 -3
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/types.d.ts +330 -0
- package/dist/cjs/utils/console.d.ts +16 -0
- package/dist/cjs/utils/getOutputPath.d.ts +5 -0
- package/dist/cjs/utils/helpers.d.ts +65 -0
- package/dist/cjs/utils/helpers.js +1 -1
- package/dist/cjs/utils/openApiToInterfaces.d.ts +14 -0
- package/dist/cjs/utils/spinner.d.ts +15 -0
- package/dist/cjs/utils/vtilsLite.d.ts +55 -0
- package/dist/esm/core/cli.mjs +1 -0
- package/dist/esm/core/generator.mjs +1 -2
- package/dist/esm/core/writeRequestClient.mjs +0 -1
- package/dist/esm/index.d.mts +2 -0
- package/dist/esm/types.d.mts +330 -0
- package/dist/esm/utils/console.d.mts +16 -0
- package/dist/esm/utils/getOutputPath.d.mts +5 -0
- package/dist/esm/utils/getOutputPath.mjs +0 -1
- package/dist/esm/utils/helpers.d.mts +65 -0
- package/dist/esm/utils/helpers.mjs +1 -1
- package/dist/esm/utils/openApiToInterfaces.d.mts +14 -0
- package/dist/esm/utils/spinner.d.mts +15 -0
- package/dist/esm/utils/utils.mjs +1 -0
- package/dist/esm/utils/vtilsLite.d.mts +55 -0
- package/package.json +15 -18
|
@@ -45,7 +45,7 @@ var import_types = require("../types.js");
|
|
|
45
45
|
var import_utils = require("../utils/utils.js");
|
|
46
46
|
var import_getOutputPath = require("../utils/getOutputPath.js");
|
|
47
47
|
var import_writeRequestClient = __toESM(require("./writeRequestClient.js"));
|
|
48
|
-
function defaultClientImportTemplate(
|
|
48
|
+
function defaultClientImportTemplate(_config) {
|
|
49
49
|
return `import request from './request'`;
|
|
50
50
|
}
|
|
51
51
|
var getDataKeySetStr = (method) => {
|
|
@@ -174,9 +174,9 @@ var Generator = class {
|
|
|
174
174
|
})
|
|
175
175
|
);
|
|
176
176
|
const allApi = await (0, import_openApiToInterfaces.openApiToInterfaces)(openApiV3Json);
|
|
177
|
-
|
|
177
|
+
const interfaceList = allApi.interfaces;
|
|
178
178
|
const categoryCode = [...componentsCode];
|
|
179
|
-
for (
|
|
179
|
+
for (const interfaceInfo of interfaceList) {
|
|
180
180
|
const code = await this.generateInterfaceCode(
|
|
181
181
|
{
|
|
182
182
|
...this.config,
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
export * from "json-schema";
|
|
3
|
+
import { JSONSchema4 } from "json-schema";
|
|
4
|
+
import { OpenAPIV3 } from "openapi-types";
|
|
5
|
+
import { ParsedPath } from "path";
|
|
6
|
+
/** Returns the client import snippet placed at the top of each generated file. */
|
|
7
|
+
export type ClientImportTemplate = () => string;
|
|
8
|
+
/** Interface definition */
|
|
9
|
+
export interface Interface {
|
|
10
|
+
/** Interface name */
|
|
11
|
+
title: string;
|
|
12
|
+
/** Request path */
|
|
13
|
+
path: string;
|
|
14
|
+
/** Request method, HEAD and OPTIONS are handled like GET, others like POST */
|
|
15
|
+
method: Method;
|
|
16
|
+
/** Path parameters */
|
|
17
|
+
req_params: Array<{
|
|
18
|
+
/** Name */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Description */
|
|
21
|
+
desc: string;
|
|
22
|
+
/** Example */
|
|
23
|
+
example: string;
|
|
24
|
+
/** Type (YApi-X) */
|
|
25
|
+
type?: RequestParamType;
|
|
26
|
+
}>;
|
|
27
|
+
/** GET only: query string */
|
|
28
|
+
req_query: Array<{
|
|
29
|
+
/** Name */
|
|
30
|
+
name: string;
|
|
31
|
+
/** Description */
|
|
32
|
+
desc: string;
|
|
33
|
+
/** Example */
|
|
34
|
+
example: string;
|
|
35
|
+
/** Required */
|
|
36
|
+
required: Required;
|
|
37
|
+
/** Type (YApi-X) */
|
|
38
|
+
type?: RequestQueryType;
|
|
39
|
+
}>;
|
|
40
|
+
/** POST only: request content type. No special handling needed for text, file, raw. */
|
|
41
|
+
req_body_type: RequestBodyType;
|
|
42
|
+
/** Whether it is json schema when `req_body_type = json` */
|
|
43
|
+
req_body_is_json_schema: boolean;
|
|
44
|
+
/** Request content when `req_body_type = form` */
|
|
45
|
+
req_body_form: Array<{
|
|
46
|
+
/** Name */
|
|
47
|
+
name: string;
|
|
48
|
+
/** Type */
|
|
49
|
+
type: RequestFormItemType;
|
|
50
|
+
/** Description */
|
|
51
|
+
desc: string;
|
|
52
|
+
/** Example */
|
|
53
|
+
example: string;
|
|
54
|
+
/** Required */
|
|
55
|
+
required: Required;
|
|
56
|
+
/**
|
|
57
|
+
* Whether the field accepts multiple files (a binary array in the
|
|
58
|
+
* OpenAPI schema, e.g. `files: {type: 'array', items: {format: 'binary'}}`).
|
|
59
|
+
* Only meaningful when `type` is `file`.
|
|
60
|
+
*/
|
|
61
|
+
isArray?: boolean;
|
|
62
|
+
/** Allowed literal values when the form field is an enum */
|
|
63
|
+
enum?: Array<string | number>;
|
|
64
|
+
}>;
|
|
65
|
+
/**
|
|
66
|
+
* Whether the form body is `multipart/form-data` (true) or
|
|
67
|
+
* `application/x-www-form-urlencoded` (false). Only set when
|
|
68
|
+
* `req_body_type = form`.
|
|
69
|
+
*/
|
|
70
|
+
req_body_multipart?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* JSON Schema fragment describing dynamic form fields (the
|
|
73
|
+
* `additionalProperties` of a multipart request schema). Used for
|
|
74
|
+
* runtime-named upload fields such as `evidence_0`, `evidence_1`, ...
|
|
75
|
+
*/
|
|
76
|
+
req_body_additional?: Record<string, any>;
|
|
77
|
+
/** Request content when `req_body_type = json` */
|
|
78
|
+
req_body_other: string;
|
|
79
|
+
/** Response data type */
|
|
80
|
+
res_body_type: ResponseBodyType;
|
|
81
|
+
/** Whether it is json schema when `res_body_type = json` */
|
|
82
|
+
res_body_is_json_schema: boolean;
|
|
83
|
+
/** Response data */
|
|
84
|
+
res_body: string;
|
|
85
|
+
[key: string]: any;
|
|
86
|
+
}
|
|
87
|
+
/** Category information */
|
|
88
|
+
export interface Category {
|
|
89
|
+
/** Category name */
|
|
90
|
+
name: string;
|
|
91
|
+
/** Category description */
|
|
92
|
+
desc: string;
|
|
93
|
+
}
|
|
94
|
+
/** Request method */
|
|
95
|
+
export declare enum Method {
|
|
96
|
+
GET = "GET",
|
|
97
|
+
POST = "POST",
|
|
98
|
+
PUT = "PUT",
|
|
99
|
+
DELETE = "DELETE",
|
|
100
|
+
HEAD = "HEAD",
|
|
101
|
+
OPTIONS = "OPTIONS",
|
|
102
|
+
PATCH = "PATCH"
|
|
103
|
+
}
|
|
104
|
+
/** Required */
|
|
105
|
+
export declare enum Required {
|
|
106
|
+
/** Not required */
|
|
107
|
+
false = "0",
|
|
108
|
+
/** Required */
|
|
109
|
+
true = "1"
|
|
110
|
+
}
|
|
111
|
+
/** Request body type */
|
|
112
|
+
export declare enum RequestBodyType {
|
|
113
|
+
/** Query string */
|
|
114
|
+
query = "query",
|
|
115
|
+
/** Form */
|
|
116
|
+
form = "form",
|
|
117
|
+
/** JSON */
|
|
118
|
+
json = "json",
|
|
119
|
+
/** Plain text */
|
|
120
|
+
text = "text",
|
|
121
|
+
/** File */
|
|
122
|
+
file = "file",
|
|
123
|
+
/** Raw data */
|
|
124
|
+
raw = "raw",
|
|
125
|
+
/** No request data */
|
|
126
|
+
none = "none"
|
|
127
|
+
}
|
|
128
|
+
/** Request path parameter type */
|
|
129
|
+
export declare enum RequestParamType {
|
|
130
|
+
/** String */
|
|
131
|
+
string = "string",
|
|
132
|
+
/** Number */
|
|
133
|
+
number = "number"
|
|
134
|
+
}
|
|
135
|
+
/** Request query parameter type */
|
|
136
|
+
export declare enum RequestQueryType {
|
|
137
|
+
/** String */
|
|
138
|
+
string = "string",
|
|
139
|
+
/** Number */
|
|
140
|
+
number = "number"
|
|
141
|
+
}
|
|
142
|
+
/** Request form item type */
|
|
143
|
+
export declare enum RequestFormItemType {
|
|
144
|
+
/** Plain text */
|
|
145
|
+
text = "text",
|
|
146
|
+
/** File */
|
|
147
|
+
file = "file"
|
|
148
|
+
}
|
|
149
|
+
/** Response body type */
|
|
150
|
+
export declare enum ResponseBodyType {
|
|
151
|
+
/** JSON */
|
|
152
|
+
json = "json",
|
|
153
|
+
/** Plain text */
|
|
154
|
+
text = "text",
|
|
155
|
+
/** XML */
|
|
156
|
+
xml = "xml",
|
|
157
|
+
/** Raw data */
|
|
158
|
+
raw = "raw"
|
|
159
|
+
}
|
|
160
|
+
/** Extended interface definition */
|
|
161
|
+
export interface ExtendedInterface extends Interface {
|
|
162
|
+
parsedPath: ParsedPath;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Generator configuration for one OpenAPI source.
|
|
166
|
+
*/
|
|
167
|
+
export interface ApiConfig {
|
|
168
|
+
/**
|
|
169
|
+
* The OpenAPI document to generate code from. Required.
|
|
170
|
+
*
|
|
171
|
+
* Accepts an http(s) URL or a local file path. Local files may be
|
|
172
|
+
* JSON (.json / .json5) or YAML (.yaml / .yml).
|
|
173
|
+
*
|
|
174
|
+
* @example 'http://localhost:3041/api-json'
|
|
175
|
+
* @example './openapi.json'
|
|
176
|
+
* @example './docs/openapi.yaml'
|
|
177
|
+
*/
|
|
178
|
+
input: string;
|
|
179
|
+
/**
|
|
180
|
+
* Output directory for generated files (relative or absolute path).
|
|
181
|
+
*
|
|
182
|
+
* Two files are written into it: `<name>.ts` (type declarations and
|
|
183
|
+
* request functions) and `request.ts` (the axios client, unless
|
|
184
|
+
* `client` is false or the file already exists).
|
|
185
|
+
*
|
|
186
|
+
* @default 'src/api'
|
|
187
|
+
*/
|
|
188
|
+
output?: string;
|
|
189
|
+
/**
|
|
190
|
+
* Base name of the generated types file: code is written to
|
|
191
|
+
* `<output>/<name>.ts`. Also serves as the source identifier for
|
|
192
|
+
* `apits gen -n <name>` filtering.
|
|
193
|
+
*
|
|
194
|
+
* Defaults to a name derived from `input`: the URL hostname
|
|
195
|
+
* (`http://localhost:3041/api-json` -> `localhost`) or the local file
|
|
196
|
+
* name without extension (`./user.openapi.yaml` -> `userOpenapi`).
|
|
197
|
+
* Duplicated derived names get an index suffix.
|
|
198
|
+
*/
|
|
199
|
+
name?: string;
|
|
200
|
+
/**
|
|
201
|
+
* Runtime `baseURL` baked into every generated request function.
|
|
202
|
+
*
|
|
203
|
+
* Prefix with `[code]:` to emit the value as code instead of a string
|
|
204
|
+
* literal, e.g. to read from an env var at runtime:
|
|
205
|
+
*
|
|
206
|
+
* - `baseURL: '[code]:process.env.BASE_URL'` -> `baseURL: process.env.BASE_URL`
|
|
207
|
+
* - `baseURL: 'http://localhost:3000'` -> `baseURL: "http://localhost:3000"`
|
|
208
|
+
*
|
|
209
|
+
* May also be a function receiving each API path and returning the
|
|
210
|
+
* baseURL to use for that path (or undefined to omit).
|
|
211
|
+
*/
|
|
212
|
+
baseURL?: ((path: string) => string | undefined) | string;
|
|
213
|
+
/**
|
|
214
|
+
* Returns the import snippet placed at the top of every generated file —
|
|
215
|
+
* use it to point at a custom request client instead of the scaffolded
|
|
216
|
+
* `request.ts`.
|
|
217
|
+
*
|
|
218
|
+
* Providing this option also flips the default of `client` to `false`,
|
|
219
|
+
* so no unused `request.ts` is scaffolded; set `client: true` explicitly
|
|
220
|
+
* to keep both.
|
|
221
|
+
*
|
|
222
|
+
* @default () => "import request from './request'"
|
|
223
|
+
*/
|
|
224
|
+
clientImportTemplate?: ClientImportTemplate;
|
|
225
|
+
/**
|
|
226
|
+
* Type used for the `extra` argument of every generated request
|
|
227
|
+
* function — the object spread into the underlying client call as
|
|
228
|
+
* per-request overrides (headers, signal, `responseType`, ...).
|
|
229
|
+
*
|
|
230
|
+
* Defaults to `AxiosRequestConfig`, in which case each generated file
|
|
231
|
+
* also imports that type from `axios`. When using a custom client via
|
|
232
|
+
* `clientImportTemplate`, set this to that client's config type and
|
|
233
|
+
* make sure `clientImportTemplate` imports it, e.g.:
|
|
234
|
+
*
|
|
235
|
+
* ```ts
|
|
236
|
+
* clientImportTemplate: () => "import {request, type RequestConfig} from '../fetch'",
|
|
237
|
+
* clientConfigType: 'RequestConfig',
|
|
238
|
+
* ```
|
|
239
|
+
*
|
|
240
|
+
* @default 'AxiosRequestConfig'
|
|
241
|
+
*/
|
|
242
|
+
clientConfigType?: string;
|
|
243
|
+
/**
|
|
244
|
+
* Whether to scaffold the default axios request client into
|
|
245
|
+
* `<output>/request.ts` (skipped when that file already exists).
|
|
246
|
+
*
|
|
247
|
+
* Defaults to `true`, and to `false` when `clientImportTemplate` is
|
|
248
|
+
* provided without an explicit `client` value.
|
|
249
|
+
*
|
|
250
|
+
* @default true
|
|
251
|
+
*/
|
|
252
|
+
client?: boolean;
|
|
253
|
+
}
|
|
254
|
+
/** Combined configuration. */
|
|
255
|
+
export type SyntheticalConfig = Partial<ApiConfig & {
|
|
256
|
+
components: OpenAPIV3.Document["components"];
|
|
257
|
+
}>;
|
|
258
|
+
/** Configuration. */
|
|
259
|
+
export type Config = ApiConfig;
|
|
260
|
+
/**
|
|
261
|
+
* Request configuration.
|
|
262
|
+
*/
|
|
263
|
+
export interface RequestConfig<Path extends string = string, ParamName extends string = string, QueryName extends string = string, RequestDataOptional extends boolean = boolean> {
|
|
264
|
+
/** Interface path, starting with `/` */
|
|
265
|
+
path: Path;
|
|
266
|
+
/** Request method */
|
|
267
|
+
method: Method;
|
|
268
|
+
/** Request headers, all headers except Content-Type */
|
|
269
|
+
requestHeaders: Record<string, string>;
|
|
270
|
+
/** Request body type */
|
|
271
|
+
requestBodyType: RequestBodyType;
|
|
272
|
+
/** Response body type */
|
|
273
|
+
responseBodyType: ResponseBodyType;
|
|
274
|
+
/** List of path parameter names */
|
|
275
|
+
paramNames: ParamName[];
|
|
276
|
+
/** List of query parameter names */
|
|
277
|
+
queryNames: QueryName[];
|
|
278
|
+
/** Whether request data is optional */
|
|
279
|
+
requestDataOptional: RequestDataOptional;
|
|
280
|
+
/** JSON Schema for request data (only effective when JSON Schema generation is enabled) */
|
|
281
|
+
requestDataJsonSchema: JSONSchema4;
|
|
282
|
+
/** JSON Schema for response data (only effective when JSON Schema generation is enabled) */
|
|
283
|
+
responseDataJsonSchema: JSONSchema4;
|
|
284
|
+
/** Request function name */
|
|
285
|
+
requestFunctionName: string;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Request parameters.
|
|
289
|
+
*/
|
|
290
|
+
export interface RequestFunctionParams extends RequestConfig {
|
|
291
|
+
/** Raw data */
|
|
292
|
+
rawData: Record<string, any>;
|
|
293
|
+
/** Request data, excluding file data */
|
|
294
|
+
data: Record<string, any>;
|
|
295
|
+
/** Whether there is file data */
|
|
296
|
+
hasFileData: boolean;
|
|
297
|
+
/** Request file data */
|
|
298
|
+
fileData: Record<string, any>;
|
|
299
|
+
/** All request data, including data and fileData */
|
|
300
|
+
allData: Record<string, any>;
|
|
301
|
+
/** Get FormData instance for all request data (including files) */
|
|
302
|
+
getFormData: () => FormData;
|
|
303
|
+
}
|
|
304
|
+
/** Additional parameters of the request function */
|
|
305
|
+
export type RequestFunctionRestArgs<T extends (...args: any[]) => any> = T extends (payload: any, ...args: infer R) => any ? R : never;
|
|
306
|
+
/** Property definition */
|
|
307
|
+
export interface PropDefinition {
|
|
308
|
+
/** Property name */
|
|
309
|
+
name: string;
|
|
310
|
+
/** Required */
|
|
311
|
+
required: boolean;
|
|
312
|
+
/** Type */
|
|
313
|
+
type: JSONSchema4["type"];
|
|
314
|
+
/** Comment */
|
|
315
|
+
comment: string;
|
|
316
|
+
/** Whether the property is an array (used for multi-file upload fields) */
|
|
317
|
+
isArray?: boolean;
|
|
318
|
+
/** Allowed literal values for enum properties */
|
|
319
|
+
enum?: Array<string | number>;
|
|
320
|
+
}
|
|
321
|
+
/** Property definition list */
|
|
322
|
+
export type PropDefinitions = PropDefinition[];
|
|
323
|
+
/** Request function body generation template function */
|
|
324
|
+
export interface RequestFunctionTemplateProps {
|
|
325
|
+
baseURL?: string;
|
|
326
|
+
requestFunctionName: string;
|
|
327
|
+
requestDataTypeName: string;
|
|
328
|
+
extendedInterfaceInfo: ExtendedInterface;
|
|
329
|
+
responseDataTypeName: string;
|
|
330
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Log a plain message. */
|
|
2
|
+
export declare function log(message?: any, ...args: any[]): void;
|
|
3
|
+
/** Log an error message. */
|
|
4
|
+
export declare function error(message?: any, ...args: any[]): void;
|
|
5
|
+
/** Log an info message. */
|
|
6
|
+
export declare function info(message?: any, ...args: any[]): void;
|
|
7
|
+
/** Log a warning message. */
|
|
8
|
+
export declare function warn(message?: any, ...args: any[]): void;
|
|
9
|
+
/** Log a soft tip message with a prefix icon. */
|
|
10
|
+
export declare function tips(message?: any, ...args: any[]): void;
|
|
11
|
+
/** Log a success message. */
|
|
12
|
+
export declare function success(message?: any, ...args: any[]): void;
|
|
13
|
+
/** Print tabular data as a table. */
|
|
14
|
+
export declare function table(tabularData: any, properties?: ReadonlyArray<string>): void;
|
|
15
|
+
/** Print a separator line (or a blank line). */
|
|
16
|
+
export declare function line(blank?: boolean): void;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { AppendOptions } from "form-data";
|
|
2
|
+
import type { Config, RequestConfig, RequestFunctionParams } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Normalize user configuration into a config array and apply built-in
|
|
5
|
+
* defaults.
|
|
6
|
+
*
|
|
7
|
+
* Defaults:
|
|
8
|
+
* - `output` falls back to `src/api`.
|
|
9
|
+
* - `client` falls back to `true`, except when a custom
|
|
10
|
+
* `clientImportTemplate` is provided without an explicit `client` value —
|
|
11
|
+
* in that case the scaffolded client is skipped automatically, otherwise
|
|
12
|
+
* the generated `request.ts` would be dead code (the generated file
|
|
13
|
+
* imports the custom client instead).
|
|
14
|
+
*
|
|
15
|
+
* @param config Configuration
|
|
16
|
+
*/
|
|
17
|
+
export declare function defineConfig(config: Config | Config[]): Config[];
|
|
18
|
+
export declare class FileData<T = any> {
|
|
19
|
+
/**
|
|
20
|
+
* Original file data.
|
|
21
|
+
*/
|
|
22
|
+
private originalFileData;
|
|
23
|
+
/**
|
|
24
|
+
* Options.
|
|
25
|
+
*/
|
|
26
|
+
private options;
|
|
27
|
+
/**
|
|
28
|
+
* File data helper class, unified file upload for web, mini-program and other platforms.
|
|
29
|
+
*
|
|
30
|
+
* @param originalFileData Original file data
|
|
31
|
+
* @param options If using internal getFormData, options will be used by it
|
|
32
|
+
*/
|
|
33
|
+
constructor(originalFileData: T, options?: AppendOptions);
|
|
34
|
+
/**
|
|
35
|
+
* Get original file data.
|
|
36
|
+
*
|
|
37
|
+
* @returns Original file data
|
|
38
|
+
*/
|
|
39
|
+
getOriginalFileData(): T;
|
|
40
|
+
/**
|
|
41
|
+
* Get options.
|
|
42
|
+
*/
|
|
43
|
+
getOptions(): AppendOptions | undefined;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse request data, separating normal data and file data from request data.
|
|
47
|
+
*
|
|
48
|
+
* @param [requestData] Request data to parse
|
|
49
|
+
* @returns Object containing normal data (data) and file data (fileData), when data and fileData are empty objects, it means no such data exists
|
|
50
|
+
*/
|
|
51
|
+
export declare function parseRequestData(requestData?: any): {
|
|
52
|
+
data: any;
|
|
53
|
+
fileData: any;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Prepare parameters to be passed to the request function.
|
|
57
|
+
*/
|
|
58
|
+
export declare function prepare(requestConfig: RequestConfig, requestData: any): RequestFunctionParams;
|
|
59
|
+
/**
|
|
60
|
+
* Execute async function queue sequentially
|
|
61
|
+
* @param fns
|
|
62
|
+
* @param results
|
|
63
|
+
* @returns
|
|
64
|
+
*/
|
|
65
|
+
export declare const asyncFnArrayOrderRun: <T = any>(fns: (() => Promise<T>)[], results?: T[]) => Promise<T[]>;
|
|
@@ -121,7 +121,7 @@ function prepare(requestConfig, requestData) {
|
|
|
121
121
|
const useNodeFormData = !useNativeFormData && // https://github.com/fjc0k/vtils/blob/master/src/utils/inNodeJS.ts
|
|
122
122
|
typeof global === "object" && typeof global.process === "object" && typeof global.process.versions === "object" && global.process.versions.node != null;
|
|
123
123
|
const UniFormData = useNativeFormData ? FormData : useNodeFormData ? (
|
|
124
|
-
// eslint-disable-next-line @typescript-eslint/no-
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- isomorphic shim: conditional CJS require when native FormData is unavailable
|
|
125
125
|
require("form-data")
|
|
126
126
|
) : void 0;
|
|
127
127
|
if (!UniFormData) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { OpenAPIV3 } from "openapi-types";
|
|
2
|
+
import { Interface } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Convert an OpenAPI 3.x document into the internal `Interface[]` format.
|
|
5
|
+
*
|
|
6
|
+
* Reads OAS3 directly — no intermediate Swagger 2.0 `openapi3Format` step,
|
|
7
|
+
* no YApi platform fields (`_id`/`project_id`/`catid`/`add_time`/`up_time`),
|
|
8
|
+
* no module-level mutable state.
|
|
9
|
+
*
|
|
10
|
+
* @param data OpenAPI 3.x document (object or JSON string)
|
|
11
|
+
*/
|
|
12
|
+
export declare function openApiToInterfaces(data: OpenAPIV3.Document | string): Promise<{
|
|
13
|
+
interfaces: Interface[];
|
|
14
|
+
}>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Ora } from "ora";
|
|
2
|
+
declare class Spin {
|
|
3
|
+
spinnerInstance: Ora;
|
|
4
|
+
constructor();
|
|
5
|
+
clear(): void;
|
|
6
|
+
start(text?: string): void;
|
|
7
|
+
succeed(text?: string): void;
|
|
8
|
+
fail(text?: string): void;
|
|
9
|
+
render(): void;
|
|
10
|
+
frame(): void;
|
|
11
|
+
info(text?: string): void;
|
|
12
|
+
stop(): void;
|
|
13
|
+
}
|
|
14
|
+
export declare const spinnerInstance: Spin;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local replacements for the small subset of `vtils` helpers used by this
|
|
3
|
+
* project. `vtils` pulls in several deprecated dependencies (cuid, uuid,
|
|
4
|
+
* tough-cookie@0.12.1 with a ReDoS advisory) and is otherwise unmaintained,
|
|
5
|
+
* so these minimal local implementations keep the dependency tree clean.
|
|
6
|
+
*
|
|
7
|
+
* Behavior matches the upstream vtils functions for the call sites in this
|
|
8
|
+
* repository only; no attempt is made to be a drop-in replacement for the
|
|
9
|
+
* full vtils API.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Remove `undefined` from a type. Equivalent to vtils's `Defined<T>`.
|
|
13
|
+
*/
|
|
14
|
+
export type Defined<T> = Exclude<T, undefined>;
|
|
15
|
+
/**
|
|
16
|
+
* Wrap a value in an array unless it is already an array.
|
|
17
|
+
*/
|
|
18
|
+
export declare function castArray<T>(value: T | T[]): T[];
|
|
19
|
+
/**
|
|
20
|
+
* `Array.isArray` alias, kept for import symmetry with the other helpers.
|
|
21
|
+
*/
|
|
22
|
+
export declare const isArray: (arg: any) => arg is any[];
|
|
23
|
+
/**
|
|
24
|
+
* Check whether a value is a plain object (not null, not an array, not a
|
|
25
|
+
* function, not a primitive). Matches vtils `isObject` for the JSON-Schema
|
|
26
|
+
* values used in this project.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isObject(value: any): value is Record<string, any>;
|
|
29
|
+
/**
|
|
30
|
+
* Check whether a value is "empty": null/undefined, empty string, empty
|
|
31
|
+
* array, or an object with no own enumerable string-keyed properties.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isEmpty(value: any): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Iterate over the own enumerable string-keyed properties of an object,
|
|
36
|
+
* invoking `callback(value, key)` for each.
|
|
37
|
+
*/
|
|
38
|
+
export declare function forOwn<T extends object>(obj: T, callback: (value: T[keyof T], key: keyof T) => void): void;
|
|
39
|
+
/**
|
|
40
|
+
* Iterate over a collection (array or object), invoking `callback(value, key)`
|
|
41
|
+
* for each item. For arrays `key` is the numeric index. Types are intentionally
|
|
42
|
+
* loose (matching vtils) because call sites pass heterogeneous OpenAPI data.
|
|
43
|
+
*/
|
|
44
|
+
export declare function each(collection: any, callback: (value: any, key: any) => void): void;
|
|
45
|
+
/**
|
|
46
|
+
* Return the first item in a collection for which `predicate` returns a
|
|
47
|
+
* truthy value, or `undefined` if none matches.
|
|
48
|
+
*/
|
|
49
|
+
export declare function find(collection: any, predicate: (value: any, key: any) => boolean): any;
|
|
50
|
+
/**
|
|
51
|
+
* Tagged-template helper that strips the common leading whitespace from every
|
|
52
|
+
* line. Multi-line interpolations keep the indentation of the line they are
|
|
53
|
+
* embedded on (mirrors vtils `dedent`, which first runs `indent`).
|
|
54
|
+
*/
|
|
55
|
+
export declare function dedent(literals: TemplateStringsArray, ...interpolations: any[]): string;
|
package/dist/esm/core/cli.mjs
CHANGED
|
@@ -169,6 +169,7 @@ function loadConfigFile(discovered) {
|
|
|
169
169
|
if (kind === "ts") {
|
|
170
170
|
var _mod$default;
|
|
171
171
|
// tsx is registered at module load time.
|
|
172
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- user config files are loaded dynamically at runtime
|
|
172
173
|
var mod = require(filePath);
|
|
173
174
|
return normalizeConfig((_mod$default = mod.default) !== null && _mod$default !== void 0 ? _mod$default : mod);
|
|
174
175
|
}
|
|
@@ -33,7 +33,7 @@ import { getRequestDataJsonSchema, getResponseDataJsonSchema, jsonSchemaToTsCode
|
|
|
33
33
|
import { getOutputFilePath } from "../utils/getOutputPath.mjs";
|
|
34
34
|
import writeRequestClient from "./writeRequestClient.mjs";
|
|
35
35
|
// Default client import snippet placed at the top of generated files.
|
|
36
|
-
function defaultClientImportTemplate(
|
|
36
|
+
function defaultClientImportTemplate(_config) {
|
|
37
37
|
return "import request from './request'";
|
|
38
38
|
}
|
|
39
39
|
var getDataKeySetStr = function getDataKeySetStr(method) {
|
|
@@ -47,7 +47,6 @@ var getDataKeySetStr = function getDataKeySetStr(method) {
|
|
|
47
47
|
// request function can substitute path params from the incoming data object.
|
|
48
48
|
function handlePathParam(path) {
|
|
49
49
|
if (path.match(/\{(\w+)\}/)) {
|
|
50
|
-
// eslint-disable-next-line no-template-curly-in-string
|
|
51
50
|
return "`".concat(path.replace(/\{(\w+)\}/g, "${data.$1}"), "`");
|
|
52
51
|
}
|
|
53
52
|
return JSON.stringify(path);
|
|
@@ -4,7 +4,6 @@ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyri
|
|
|
4
4
|
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
|
5
5
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
6
6
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
7
|
-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
8
7
|
import fs from "fs-extra";
|
|
9
8
|
import { dedent } from "../utils/vtilsLite.mjs";
|
|
10
9
|
import { getOutputFilePath } from "../utils/getOutputPath.mjs";
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
export * from "json-schema";
|
|
3
|
+
import { JSONSchema4 } from "json-schema";
|
|
4
|
+
import { OpenAPIV3 } from "openapi-types";
|
|
5
|
+
import { ParsedPath } from "path";
|
|
6
|
+
/** Returns the client import snippet placed at the top of each generated file. */
|
|
7
|
+
export type ClientImportTemplate = () => string;
|
|
8
|
+
/** Interface definition */
|
|
9
|
+
export interface Interface {
|
|
10
|
+
/** Interface name */
|
|
11
|
+
title: string;
|
|
12
|
+
/** Request path */
|
|
13
|
+
path: string;
|
|
14
|
+
/** Request method, HEAD and OPTIONS are handled like GET, others like POST */
|
|
15
|
+
method: Method;
|
|
16
|
+
/** Path parameters */
|
|
17
|
+
req_params: Array<{
|
|
18
|
+
/** Name */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Description */
|
|
21
|
+
desc: string;
|
|
22
|
+
/** Example */
|
|
23
|
+
example: string;
|
|
24
|
+
/** Type (YApi-X) */
|
|
25
|
+
type?: RequestParamType;
|
|
26
|
+
}>;
|
|
27
|
+
/** GET only: query string */
|
|
28
|
+
req_query: Array<{
|
|
29
|
+
/** Name */
|
|
30
|
+
name: string;
|
|
31
|
+
/** Description */
|
|
32
|
+
desc: string;
|
|
33
|
+
/** Example */
|
|
34
|
+
example: string;
|
|
35
|
+
/** Required */
|
|
36
|
+
required: Required;
|
|
37
|
+
/** Type (YApi-X) */
|
|
38
|
+
type?: RequestQueryType;
|
|
39
|
+
}>;
|
|
40
|
+
/** POST only: request content type. No special handling needed for text, file, raw. */
|
|
41
|
+
req_body_type: RequestBodyType;
|
|
42
|
+
/** Whether it is json schema when `req_body_type = json` */
|
|
43
|
+
req_body_is_json_schema: boolean;
|
|
44
|
+
/** Request content when `req_body_type = form` */
|
|
45
|
+
req_body_form: Array<{
|
|
46
|
+
/** Name */
|
|
47
|
+
name: string;
|
|
48
|
+
/** Type */
|
|
49
|
+
type: RequestFormItemType;
|
|
50
|
+
/** Description */
|
|
51
|
+
desc: string;
|
|
52
|
+
/** Example */
|
|
53
|
+
example: string;
|
|
54
|
+
/** Required */
|
|
55
|
+
required: Required;
|
|
56
|
+
/**
|
|
57
|
+
* Whether the field accepts multiple files (a binary array in the
|
|
58
|
+
* OpenAPI schema, e.g. `files: {type: 'array', items: {format: 'binary'}}`).
|
|
59
|
+
* Only meaningful when `type` is `file`.
|
|
60
|
+
*/
|
|
61
|
+
isArray?: boolean;
|
|
62
|
+
/** Allowed literal values when the form field is an enum */
|
|
63
|
+
enum?: Array<string | number>;
|
|
64
|
+
}>;
|
|
65
|
+
/**
|
|
66
|
+
* Whether the form body is `multipart/form-data` (true) or
|
|
67
|
+
* `application/x-www-form-urlencoded` (false). Only set when
|
|
68
|
+
* `req_body_type = form`.
|
|
69
|
+
*/
|
|
70
|
+
req_body_multipart?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* JSON Schema fragment describing dynamic form fields (the
|
|
73
|
+
* `additionalProperties` of a multipart request schema). Used for
|
|
74
|
+
* runtime-named upload fields such as `evidence_0`, `evidence_1`, ...
|
|
75
|
+
*/
|
|
76
|
+
req_body_additional?: Record<string, any>;
|
|
77
|
+
/** Request content when `req_body_type = json` */
|
|
78
|
+
req_body_other: string;
|
|
79
|
+
/** Response data type */
|
|
80
|
+
res_body_type: ResponseBodyType;
|
|
81
|
+
/** Whether it is json schema when `res_body_type = json` */
|
|
82
|
+
res_body_is_json_schema: boolean;
|
|
83
|
+
/** Response data */
|
|
84
|
+
res_body: string;
|
|
85
|
+
[key: string]: any;
|
|
86
|
+
}
|
|
87
|
+
/** Category information */
|
|
88
|
+
export interface Category {
|
|
89
|
+
/** Category name */
|
|
90
|
+
name: string;
|
|
91
|
+
/** Category description */
|
|
92
|
+
desc: string;
|
|
93
|
+
}
|
|
94
|
+
/** Request method */
|
|
95
|
+
export declare enum Method {
|
|
96
|
+
GET = "GET",
|
|
97
|
+
POST = "POST",
|
|
98
|
+
PUT = "PUT",
|
|
99
|
+
DELETE = "DELETE",
|
|
100
|
+
HEAD = "HEAD",
|
|
101
|
+
OPTIONS = "OPTIONS",
|
|
102
|
+
PATCH = "PATCH"
|
|
103
|
+
}
|
|
104
|
+
/** Required */
|
|
105
|
+
export declare enum Required {
|
|
106
|
+
/** Not required */
|
|
107
|
+
false = "0",
|
|
108
|
+
/** Required */
|
|
109
|
+
true = "1"
|
|
110
|
+
}
|
|
111
|
+
/** Request body type */
|
|
112
|
+
export declare enum RequestBodyType {
|
|
113
|
+
/** Query string */
|
|
114
|
+
query = "query",
|
|
115
|
+
/** Form */
|
|
116
|
+
form = "form",
|
|
117
|
+
/** JSON */
|
|
118
|
+
json = "json",
|
|
119
|
+
/** Plain text */
|
|
120
|
+
text = "text",
|
|
121
|
+
/** File */
|
|
122
|
+
file = "file",
|
|
123
|
+
/** Raw data */
|
|
124
|
+
raw = "raw",
|
|
125
|
+
/** No request data */
|
|
126
|
+
none = "none"
|
|
127
|
+
}
|
|
128
|
+
/** Request path parameter type */
|
|
129
|
+
export declare enum RequestParamType {
|
|
130
|
+
/** String */
|
|
131
|
+
string = "string",
|
|
132
|
+
/** Number */
|
|
133
|
+
number = "number"
|
|
134
|
+
}
|
|
135
|
+
/** Request query parameter type */
|
|
136
|
+
export declare enum RequestQueryType {
|
|
137
|
+
/** String */
|
|
138
|
+
string = "string",
|
|
139
|
+
/** Number */
|
|
140
|
+
number = "number"
|
|
141
|
+
}
|
|
142
|
+
/** Request form item type */
|
|
143
|
+
export declare enum RequestFormItemType {
|
|
144
|
+
/** Plain text */
|
|
145
|
+
text = "text",
|
|
146
|
+
/** File */
|
|
147
|
+
file = "file"
|
|
148
|
+
}
|
|
149
|
+
/** Response body type */
|
|
150
|
+
export declare enum ResponseBodyType {
|
|
151
|
+
/** JSON */
|
|
152
|
+
json = "json",
|
|
153
|
+
/** Plain text */
|
|
154
|
+
text = "text",
|
|
155
|
+
/** XML */
|
|
156
|
+
xml = "xml",
|
|
157
|
+
/** Raw data */
|
|
158
|
+
raw = "raw"
|
|
159
|
+
}
|
|
160
|
+
/** Extended interface definition */
|
|
161
|
+
export interface ExtendedInterface extends Interface {
|
|
162
|
+
parsedPath: ParsedPath;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Generator configuration for one OpenAPI source.
|
|
166
|
+
*/
|
|
167
|
+
export interface ApiConfig {
|
|
168
|
+
/**
|
|
169
|
+
* The OpenAPI document to generate code from. Required.
|
|
170
|
+
*
|
|
171
|
+
* Accepts an http(s) URL or a local file path. Local files may be
|
|
172
|
+
* JSON (.json / .json5) or YAML (.yaml / .yml).
|
|
173
|
+
*
|
|
174
|
+
* @example 'http://localhost:3041/api-json'
|
|
175
|
+
* @example './openapi.json'
|
|
176
|
+
* @example './docs/openapi.yaml'
|
|
177
|
+
*/
|
|
178
|
+
input: string;
|
|
179
|
+
/**
|
|
180
|
+
* Output directory for generated files (relative or absolute path).
|
|
181
|
+
*
|
|
182
|
+
* Two files are written into it: `<name>.ts` (type declarations and
|
|
183
|
+
* request functions) and `request.ts` (the axios client, unless
|
|
184
|
+
* `client` is false or the file already exists).
|
|
185
|
+
*
|
|
186
|
+
* @default 'src/api'
|
|
187
|
+
*/
|
|
188
|
+
output?: string;
|
|
189
|
+
/**
|
|
190
|
+
* Base name of the generated types file: code is written to
|
|
191
|
+
* `<output>/<name>.ts`. Also serves as the source identifier for
|
|
192
|
+
* `apits gen -n <name>` filtering.
|
|
193
|
+
*
|
|
194
|
+
* Defaults to a name derived from `input`: the URL hostname
|
|
195
|
+
* (`http://localhost:3041/api-json` -> `localhost`) or the local file
|
|
196
|
+
* name without extension (`./user.openapi.yaml` -> `userOpenapi`).
|
|
197
|
+
* Duplicated derived names get an index suffix.
|
|
198
|
+
*/
|
|
199
|
+
name?: string;
|
|
200
|
+
/**
|
|
201
|
+
* Runtime `baseURL` baked into every generated request function.
|
|
202
|
+
*
|
|
203
|
+
* Prefix with `[code]:` to emit the value as code instead of a string
|
|
204
|
+
* literal, e.g. to read from an env var at runtime:
|
|
205
|
+
*
|
|
206
|
+
* - `baseURL: '[code]:process.env.BASE_URL'` -> `baseURL: process.env.BASE_URL`
|
|
207
|
+
* - `baseURL: 'http://localhost:3000'` -> `baseURL: "http://localhost:3000"`
|
|
208
|
+
*
|
|
209
|
+
* May also be a function receiving each API path and returning the
|
|
210
|
+
* baseURL to use for that path (or undefined to omit).
|
|
211
|
+
*/
|
|
212
|
+
baseURL?: ((path: string) => string | undefined) | string;
|
|
213
|
+
/**
|
|
214
|
+
* Returns the import snippet placed at the top of every generated file —
|
|
215
|
+
* use it to point at a custom request client instead of the scaffolded
|
|
216
|
+
* `request.ts`.
|
|
217
|
+
*
|
|
218
|
+
* Providing this option also flips the default of `client` to `false`,
|
|
219
|
+
* so no unused `request.ts` is scaffolded; set `client: true` explicitly
|
|
220
|
+
* to keep both.
|
|
221
|
+
*
|
|
222
|
+
* @default () => "import request from './request'"
|
|
223
|
+
*/
|
|
224
|
+
clientImportTemplate?: ClientImportTemplate;
|
|
225
|
+
/**
|
|
226
|
+
* Type used for the `extra` argument of every generated request
|
|
227
|
+
* function — the object spread into the underlying client call as
|
|
228
|
+
* per-request overrides (headers, signal, `responseType`, ...).
|
|
229
|
+
*
|
|
230
|
+
* Defaults to `AxiosRequestConfig`, in which case each generated file
|
|
231
|
+
* also imports that type from `axios`. When using a custom client via
|
|
232
|
+
* `clientImportTemplate`, set this to that client's config type and
|
|
233
|
+
* make sure `clientImportTemplate` imports it, e.g.:
|
|
234
|
+
*
|
|
235
|
+
* ```ts
|
|
236
|
+
* clientImportTemplate: () => "import {request, type RequestConfig} from '../fetch'",
|
|
237
|
+
* clientConfigType: 'RequestConfig',
|
|
238
|
+
* ```
|
|
239
|
+
*
|
|
240
|
+
* @default 'AxiosRequestConfig'
|
|
241
|
+
*/
|
|
242
|
+
clientConfigType?: string;
|
|
243
|
+
/**
|
|
244
|
+
* Whether to scaffold the default axios request client into
|
|
245
|
+
* `<output>/request.ts` (skipped when that file already exists).
|
|
246
|
+
*
|
|
247
|
+
* Defaults to `true`, and to `false` when `clientImportTemplate` is
|
|
248
|
+
* provided without an explicit `client` value.
|
|
249
|
+
*
|
|
250
|
+
* @default true
|
|
251
|
+
*/
|
|
252
|
+
client?: boolean;
|
|
253
|
+
}
|
|
254
|
+
/** Combined configuration. */
|
|
255
|
+
export type SyntheticalConfig = Partial<ApiConfig & {
|
|
256
|
+
components: OpenAPIV3.Document["components"];
|
|
257
|
+
}>;
|
|
258
|
+
/** Configuration. */
|
|
259
|
+
export type Config = ApiConfig;
|
|
260
|
+
/**
|
|
261
|
+
* Request configuration.
|
|
262
|
+
*/
|
|
263
|
+
export interface RequestConfig<Path extends string = string, ParamName extends string = string, QueryName extends string = string, RequestDataOptional extends boolean = boolean> {
|
|
264
|
+
/** Interface path, starting with `/` */
|
|
265
|
+
path: Path;
|
|
266
|
+
/** Request method */
|
|
267
|
+
method: Method;
|
|
268
|
+
/** Request headers, all headers except Content-Type */
|
|
269
|
+
requestHeaders: Record<string, string>;
|
|
270
|
+
/** Request body type */
|
|
271
|
+
requestBodyType: RequestBodyType;
|
|
272
|
+
/** Response body type */
|
|
273
|
+
responseBodyType: ResponseBodyType;
|
|
274
|
+
/** List of path parameter names */
|
|
275
|
+
paramNames: ParamName[];
|
|
276
|
+
/** List of query parameter names */
|
|
277
|
+
queryNames: QueryName[];
|
|
278
|
+
/** Whether request data is optional */
|
|
279
|
+
requestDataOptional: RequestDataOptional;
|
|
280
|
+
/** JSON Schema for request data (only effective when JSON Schema generation is enabled) */
|
|
281
|
+
requestDataJsonSchema: JSONSchema4;
|
|
282
|
+
/** JSON Schema for response data (only effective when JSON Schema generation is enabled) */
|
|
283
|
+
responseDataJsonSchema: JSONSchema4;
|
|
284
|
+
/** Request function name */
|
|
285
|
+
requestFunctionName: string;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Request parameters.
|
|
289
|
+
*/
|
|
290
|
+
export interface RequestFunctionParams extends RequestConfig {
|
|
291
|
+
/** Raw data */
|
|
292
|
+
rawData: Record<string, any>;
|
|
293
|
+
/** Request data, excluding file data */
|
|
294
|
+
data: Record<string, any>;
|
|
295
|
+
/** Whether there is file data */
|
|
296
|
+
hasFileData: boolean;
|
|
297
|
+
/** Request file data */
|
|
298
|
+
fileData: Record<string, any>;
|
|
299
|
+
/** All request data, including data and fileData */
|
|
300
|
+
allData: Record<string, any>;
|
|
301
|
+
/** Get FormData instance for all request data (including files) */
|
|
302
|
+
getFormData: () => FormData;
|
|
303
|
+
}
|
|
304
|
+
/** Additional parameters of the request function */
|
|
305
|
+
export type RequestFunctionRestArgs<T extends (...args: any[]) => any> = T extends (payload: any, ...args: infer R) => any ? R : never;
|
|
306
|
+
/** Property definition */
|
|
307
|
+
export interface PropDefinition {
|
|
308
|
+
/** Property name */
|
|
309
|
+
name: string;
|
|
310
|
+
/** Required */
|
|
311
|
+
required: boolean;
|
|
312
|
+
/** Type */
|
|
313
|
+
type: JSONSchema4["type"];
|
|
314
|
+
/** Comment */
|
|
315
|
+
comment: string;
|
|
316
|
+
/** Whether the property is an array (used for multi-file upload fields) */
|
|
317
|
+
isArray?: boolean;
|
|
318
|
+
/** Allowed literal values for enum properties */
|
|
319
|
+
enum?: Array<string | number>;
|
|
320
|
+
}
|
|
321
|
+
/** Property definition list */
|
|
322
|
+
export type PropDefinitions = PropDefinition[];
|
|
323
|
+
/** Request function body generation template function */
|
|
324
|
+
export interface RequestFunctionTemplateProps {
|
|
325
|
+
baseURL?: string;
|
|
326
|
+
requestFunctionName: string;
|
|
327
|
+
requestDataTypeName: string;
|
|
328
|
+
extendedInterfaceInfo: ExtendedInterface;
|
|
329
|
+
responseDataTypeName: string;
|
|
330
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Log a plain message. */
|
|
2
|
+
export declare function log(message?: any, ...args: any[]): void;
|
|
3
|
+
/** Log an error message. */
|
|
4
|
+
export declare function error(message?: any, ...args: any[]): void;
|
|
5
|
+
/** Log an info message. */
|
|
6
|
+
export declare function info(message?: any, ...args: any[]): void;
|
|
7
|
+
/** Log a warning message. */
|
|
8
|
+
export declare function warn(message?: any, ...args: any[]): void;
|
|
9
|
+
/** Log a soft tip message with a prefix icon. */
|
|
10
|
+
export declare function tips(message?: any, ...args: any[]): void;
|
|
11
|
+
/** Log a success message. */
|
|
12
|
+
export declare function success(message?: any, ...args: any[]): void;
|
|
13
|
+
/** Print tabular data as a table. */
|
|
14
|
+
export declare function table(tabularData: any, properties?: ReadonlyArray<string>): void;
|
|
15
|
+
/** Print a separator line (or a blank line). */
|
|
16
|
+
export declare function line(blank?: boolean): void;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Resolve the output file path for a generated file.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
6
5
|
import path from "path";
|
|
7
6
|
export var getOutputFilePath = function getOutputFilePath(config, file) {
|
|
8
7
|
var _path$parse = path.parse(config.output || ""),
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { AppendOptions } from "form-data";
|
|
2
|
+
import type { Config, RequestConfig, RequestFunctionParams } from "../types.mjs";
|
|
3
|
+
/**
|
|
4
|
+
* Normalize user configuration into a config array and apply built-in
|
|
5
|
+
* defaults.
|
|
6
|
+
*
|
|
7
|
+
* Defaults:
|
|
8
|
+
* - `output` falls back to `src/api`.
|
|
9
|
+
* - `client` falls back to `true`, except when a custom
|
|
10
|
+
* `clientImportTemplate` is provided without an explicit `client` value —
|
|
11
|
+
* in that case the scaffolded client is skipped automatically, otherwise
|
|
12
|
+
* the generated `request.ts` would be dead code (the generated file
|
|
13
|
+
* imports the custom client instead).
|
|
14
|
+
*
|
|
15
|
+
* @param config Configuration
|
|
16
|
+
*/
|
|
17
|
+
export declare function defineConfig(config: Config | Config[]): Config[];
|
|
18
|
+
export declare class FileData<T = any> {
|
|
19
|
+
/**
|
|
20
|
+
* Original file data.
|
|
21
|
+
*/
|
|
22
|
+
private originalFileData;
|
|
23
|
+
/**
|
|
24
|
+
* Options.
|
|
25
|
+
*/
|
|
26
|
+
private options;
|
|
27
|
+
/**
|
|
28
|
+
* File data helper class, unified file upload for web, mini-program and other platforms.
|
|
29
|
+
*
|
|
30
|
+
* @param originalFileData Original file data
|
|
31
|
+
* @param options If using internal getFormData, options will be used by it
|
|
32
|
+
*/
|
|
33
|
+
constructor(originalFileData: T, options?: AppendOptions);
|
|
34
|
+
/**
|
|
35
|
+
* Get original file data.
|
|
36
|
+
*
|
|
37
|
+
* @returns Original file data
|
|
38
|
+
*/
|
|
39
|
+
getOriginalFileData(): T;
|
|
40
|
+
/**
|
|
41
|
+
* Get options.
|
|
42
|
+
*/
|
|
43
|
+
getOptions(): AppendOptions | undefined;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse request data, separating normal data and file data from request data.
|
|
47
|
+
*
|
|
48
|
+
* @param [requestData] Request data to parse
|
|
49
|
+
* @returns Object containing normal data (data) and file data (fileData), when data and fileData are empty objects, it means no such data exists
|
|
50
|
+
*/
|
|
51
|
+
export declare function parseRequestData(requestData?: any): {
|
|
52
|
+
data: any;
|
|
53
|
+
fileData: any;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Prepare parameters to be passed to the request function.
|
|
57
|
+
*/
|
|
58
|
+
export declare function prepare(requestConfig: RequestConfig, requestData: any): RequestFunctionParams;
|
|
59
|
+
/**
|
|
60
|
+
* Execute async function queue sequentially
|
|
61
|
+
* @param fns
|
|
62
|
+
* @param results
|
|
63
|
+
* @returns
|
|
64
|
+
*/
|
|
65
|
+
export declare const asyncFnArrayOrderRun: <T = any>(fns: (() => Promise<T>)[], results?: T[]) => Promise<T[]>;
|
|
@@ -161,7 +161,7 @@ export function prepare(requestConfig, requestData) {
|
|
|
161
161
|
// https://github.com/fjc0k/vtils/blob/master/src/utils/inNodeJS.ts
|
|
162
162
|
(typeof global === "undefined" ? "undefined" : _typeof(global)) === "object" && _typeof(global.process) === "object" && _typeof(global.process.versions) === "object" && global.process.versions.node != null;
|
|
163
163
|
var UniFormData = useNativeFormData ? FormData : useNodeFormData ?
|
|
164
|
-
// eslint-disable-next-line @typescript-eslint/no-
|
|
164
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- isomorphic shim: conditional CJS require when native FormData is unavailable
|
|
165
165
|
require("form-data") : undefined;
|
|
166
166
|
if (!UniFormData) {
|
|
167
167
|
throw new Error("FormData is not supported in the current environment");
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { OpenAPIV3 } from "openapi-types";
|
|
2
|
+
import { Interface } from "../types.mjs";
|
|
3
|
+
/**
|
|
4
|
+
* Convert an OpenAPI 3.x document into the internal `Interface[]` format.
|
|
5
|
+
*
|
|
6
|
+
* Reads OAS3 directly — no intermediate Swagger 2.0 `openapi3Format` step,
|
|
7
|
+
* no YApi platform fields (`_id`/`project_id`/`catid`/`add_time`/`up_time`),
|
|
8
|
+
* no module-level mutable state.
|
|
9
|
+
*
|
|
10
|
+
* @param data OpenAPI 3.x document (object or JSON string)
|
|
11
|
+
*/
|
|
12
|
+
export declare function openApiToInterfaces(data: OpenAPIV3.Document | string): Promise<{
|
|
13
|
+
interfaces: Interface[];
|
|
14
|
+
}>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Ora } from "ora";
|
|
2
|
+
declare class Spin {
|
|
3
|
+
spinnerInstance: Ora;
|
|
4
|
+
constructor();
|
|
5
|
+
clear(): void;
|
|
6
|
+
start(text?: string): void;
|
|
7
|
+
succeed(text?: string): void;
|
|
8
|
+
fail(text?: string): void;
|
|
9
|
+
render(): void;
|
|
10
|
+
frame(): void;
|
|
11
|
+
info(text?: string): void;
|
|
12
|
+
stop(): void;
|
|
13
|
+
}
|
|
14
|
+
export declare const spinnerInstance: Spin;
|
|
15
|
+
export {};
|
package/dist/esm/utils/utils.mjs
CHANGED
|
@@ -94,6 +94,7 @@ export function processJsonSchema(jsonSchema) {
|
|
|
94
94
|
|
|
95
95
|
// Mock.toJSONSchema produces `properties` as an array, but JSONSchema4 expects an object.
|
|
96
96
|
if (isArray(jsonSchema.properties)) {
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- narrowing the array to the object shape here is intentional and type-safe at runtime
|
|
97
98
|
// @ts-ignore
|
|
98
99
|
jsonSchema.properties = jsonSchema.properties.reduce(function (props, js) {
|
|
99
100
|
props[js.name] = js;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local replacements for the small subset of `vtils` helpers used by this
|
|
3
|
+
* project. `vtils` pulls in several deprecated dependencies (cuid, uuid,
|
|
4
|
+
* tough-cookie@0.12.1 with a ReDoS advisory) and is otherwise unmaintained,
|
|
5
|
+
* so these minimal local implementations keep the dependency tree clean.
|
|
6
|
+
*
|
|
7
|
+
* Behavior matches the upstream vtils functions for the call sites in this
|
|
8
|
+
* repository only; no attempt is made to be a drop-in replacement for the
|
|
9
|
+
* full vtils API.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Remove `undefined` from a type. Equivalent to vtils's `Defined<T>`.
|
|
13
|
+
*/
|
|
14
|
+
export type Defined<T> = Exclude<T, undefined>;
|
|
15
|
+
/**
|
|
16
|
+
* Wrap a value in an array unless it is already an array.
|
|
17
|
+
*/
|
|
18
|
+
export declare function castArray<T>(value: T | T[]): T[];
|
|
19
|
+
/**
|
|
20
|
+
* `Array.isArray` alias, kept for import symmetry with the other helpers.
|
|
21
|
+
*/
|
|
22
|
+
export declare const isArray: (arg: any) => arg is any[];
|
|
23
|
+
/**
|
|
24
|
+
* Check whether a value is a plain object (not null, not an array, not a
|
|
25
|
+
* function, not a primitive). Matches vtils `isObject` for the JSON-Schema
|
|
26
|
+
* values used in this project.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isObject(value: any): value is Record<string, any>;
|
|
29
|
+
/**
|
|
30
|
+
* Check whether a value is "empty": null/undefined, empty string, empty
|
|
31
|
+
* array, or an object with no own enumerable string-keyed properties.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isEmpty(value: any): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Iterate over the own enumerable string-keyed properties of an object,
|
|
36
|
+
* invoking `callback(value, key)` for each.
|
|
37
|
+
*/
|
|
38
|
+
export declare function forOwn<T extends object>(obj: T, callback: (value: T[keyof T], key: keyof T) => void): void;
|
|
39
|
+
/**
|
|
40
|
+
* Iterate over a collection (array or object), invoking `callback(value, key)`
|
|
41
|
+
* for each item. For arrays `key` is the numeric index. Types are intentionally
|
|
42
|
+
* loose (matching vtils) because call sites pass heterogeneous OpenAPI data.
|
|
43
|
+
*/
|
|
44
|
+
export declare function each(collection: any, callback: (value: any, key: any) => void): void;
|
|
45
|
+
/**
|
|
46
|
+
* Return the first item in a collection for which `predicate` returns a
|
|
47
|
+
* truthy value, or `undefined` if none matches.
|
|
48
|
+
*/
|
|
49
|
+
export declare function find(collection: any, predicate: (value: any, key: any) => boolean): any;
|
|
50
|
+
/**
|
|
51
|
+
* Tagged-template helper that strips the common leading whitespace from every
|
|
52
|
+
* line. Multi-line interpolations keep the indentation of the line they are
|
|
53
|
+
* embedded on (mirrors vtils `dedent`, which first runs `indent`).
|
|
54
|
+
*/
|
|
55
|
+
export declare function dedent(literals: TemplateStringsArray, ...interpolations: any[]): string;
|
package/package.json
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devbie/apits",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"author": "
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"author": "worldzhy",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/worldzhy/newbie.git",
|
|
9
|
+
"directory": "packages/apits"
|
|
10
|
+
},
|
|
5
11
|
"main": "./dist/cjs/index.js",
|
|
6
12
|
"module": "./dist/esm/index.mjs",
|
|
7
13
|
"types": "./dist/cjs/index.d.ts",
|
|
8
14
|
"bin": {
|
|
9
|
-
"apits": "
|
|
15
|
+
"apits": "bin/apits"
|
|
10
16
|
},
|
|
11
17
|
"files": [
|
|
12
18
|
"bin",
|
|
@@ -14,20 +20,18 @@
|
|
|
14
20
|
],
|
|
15
21
|
"scripts": {
|
|
16
22
|
"build": "father build",
|
|
23
|
+
"format": "prettier --write .",
|
|
24
|
+
"format:check": "prettier --check .",
|
|
17
25
|
"gen": "rm -rf ./api & tsx test/gen.ts --type-check false gen",
|
|
18
26
|
"gen:api-1": "tsx test/gen.ts --type-check false gen -n api-1",
|
|
19
27
|
"init": "tsx test/gen.ts --type-check false init",
|
|
28
|
+
"lint": "eslint",
|
|
29
|
+
"lint:fix": "eslint --fix",
|
|
20
30
|
"publishOnly": "npm run build",
|
|
21
|
-
"release": "npm run build && standard-version && git push --follow-tags origin master && npm publish",
|
|
22
31
|
"requestTest": "tsx watch test/requestTest.ts --type-check false",
|
|
23
32
|
"test": "tsx test/index.ts",
|
|
24
33
|
"test2": "tsx watch test/json-schema-to-typescript.ts --type-check false"
|
|
25
34
|
},
|
|
26
|
-
"lint-staged": {
|
|
27
|
-
"src/**/*.ts": [
|
|
28
|
-
"eslint --fix"
|
|
29
|
-
]
|
|
30
|
-
},
|
|
31
35
|
"dependencies": {
|
|
32
36
|
"chalk": "^4.1.1",
|
|
33
37
|
"change-case": "^3.1.0",
|
|
@@ -52,16 +56,9 @@
|
|
|
52
56
|
"@types/json-schema": "^7.0.1",
|
|
53
57
|
"@types/json5": "^0.0.30",
|
|
54
58
|
"@types/node": "^18.7.14",
|
|
55
|
-
"@types/prompts": "^1.
|
|
59
|
+
"@types/prompts": "^1.0.4",
|
|
56
60
|
"@types/yargs": "^16.0.1",
|
|
57
|
-
"
|
|
58
|
-
"@typescript-eslint/parser": "^6.21.0",
|
|
59
|
-
"eslint": "^7.16.0",
|
|
60
|
-
"eslint-config-airbnb-base": "^15.0.0",
|
|
61
|
-
"eslint-config-prettier": "^9.1.2",
|
|
62
|
-
"eslint-plugin-prettier": "^5.5.7",
|
|
63
|
-
"father": "^4",
|
|
64
|
-
"standard-version": "^4.4.0"
|
|
61
|
+
"father": "^4"
|
|
65
62
|
},
|
|
66
63
|
"publishConfig": {
|
|
67
64
|
"access": "public",
|