@openmirai/typeforge 0.2.0 → 0.2.2
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/adapters/axios/index.d.ts +12 -0
- package/dist/adapters/fetch/index.d.ts +16 -0
- package/dist/cli.js +1 -1
- package/dist/http/types.d.ts +11 -0
- package/dist/index.d.ts +132 -1
- package/dist/index.js +1 -1
- package/dist/init-CqBQsEHz.js +134 -0
- package/package.json +2 -1
- package/dist/init-UsJVICy2.js +0 -129
|
@@ -7,31 +7,43 @@ type QueryParams = Record<string, QueryParamValue>;
|
|
|
7
7
|
type ResponseValidator<T> = (value: unknown) => T;
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/http/types.d.ts
|
|
10
|
+
/** Per-request options accepted by every Typeforge HTTP adapter method. */
|
|
10
11
|
interface HTTPFetchConfig<TParams extends object = QueryParams, TResponse = unknown> {
|
|
12
|
+
/** Abort signal forwarded to the underlying HTTP client. */
|
|
11
13
|
signal?: AbortSignal;
|
|
14
|
+
/** Query parameters serialized by the HTTP adapter. */
|
|
12
15
|
params?: TParams;
|
|
16
|
+
/** Request headers merged with adapter-level defaults. */
|
|
13
17
|
headers?: Record<string, string>;
|
|
18
|
+
/** Optional runtime validator applied to the response payload. */
|
|
14
19
|
validateResponse?: ResponseValidator<TResponse>;
|
|
15
20
|
}
|
|
21
|
+
/** Transport contract consumed by Typeforge-generated API callers. */
|
|
16
22
|
interface HTTPFetch {
|
|
23
|
+
/** Send a GET request and return its typed response payload. */
|
|
17
24
|
get<TResponse, TParams extends object = QueryParams>(route: string, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
18
25
|
data: TResponse;
|
|
19
26
|
}>;
|
|
27
|
+
/** Send a POST request with a typed body and return its typed response payload. */
|
|
20
28
|
post<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
21
29
|
data: TResponse;
|
|
22
30
|
}>;
|
|
31
|
+
/** Send a PUT request with a typed body and return its typed response payload. */
|
|
23
32
|
put<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
24
33
|
data: TResponse;
|
|
25
34
|
}>;
|
|
35
|
+
/** Send a PATCH request with a typed body and return its typed response payload. */
|
|
26
36
|
patch<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
27
37
|
data: TResponse;
|
|
28
38
|
}>;
|
|
39
|
+
/** Send a DELETE request and return its typed response payload. */
|
|
29
40
|
delete<TResponse, TParams extends object = QueryParams>(route: string, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
30
41
|
data: TResponse;
|
|
31
42
|
}>;
|
|
32
43
|
}
|
|
33
44
|
//#endregion
|
|
34
45
|
//#region src/adapters/axios/index.d.ts
|
|
46
|
+
/** Create an `HTTPFetch` implementation backed by an Axios instance. */
|
|
35
47
|
declare function createAxiosAdapter(instance: AxiosInstance): HTTPFetch;
|
|
36
48
|
//#endregion
|
|
37
49
|
export { type HTTPFetch, type HTTPFetchConfig, createAxiosAdapter };
|
|
@@ -6,36 +6,52 @@ type QueryParams = Record<string, QueryParamValue>;
|
|
|
6
6
|
type ResponseValidator<T> = (value: unknown) => T;
|
|
7
7
|
//#endregion
|
|
8
8
|
//#region src/http/types.d.ts
|
|
9
|
+
/** Per-request options accepted by every Typeforge HTTP adapter method. */
|
|
9
10
|
interface HTTPFetchConfig<TParams extends object = QueryParams, TResponse = unknown> {
|
|
11
|
+
/** Abort signal forwarded to the underlying HTTP client. */
|
|
10
12
|
signal?: AbortSignal;
|
|
13
|
+
/** Query parameters serialized by the HTTP adapter. */
|
|
11
14
|
params?: TParams;
|
|
15
|
+
/** Request headers merged with adapter-level defaults. */
|
|
12
16
|
headers?: Record<string, string>;
|
|
17
|
+
/** Optional runtime validator applied to the response payload. */
|
|
13
18
|
validateResponse?: ResponseValidator<TResponse>;
|
|
14
19
|
}
|
|
20
|
+
/** Transport contract consumed by Typeforge-generated API callers. */
|
|
15
21
|
interface HTTPFetch {
|
|
22
|
+
/** Send a GET request and return its typed response payload. */
|
|
16
23
|
get<TResponse, TParams extends object = QueryParams>(route: string, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
17
24
|
data: TResponse;
|
|
18
25
|
}>;
|
|
26
|
+
/** Send a POST request with a typed body and return its typed response payload. */
|
|
19
27
|
post<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
20
28
|
data: TResponse;
|
|
21
29
|
}>;
|
|
30
|
+
/** Send a PUT request with a typed body and return its typed response payload. */
|
|
22
31
|
put<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
23
32
|
data: TResponse;
|
|
24
33
|
}>;
|
|
34
|
+
/** Send a PATCH request with a typed body and return its typed response payload. */
|
|
25
35
|
patch<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
26
36
|
data: TResponse;
|
|
27
37
|
}>;
|
|
38
|
+
/** Send a DELETE request and return its typed response payload. */
|
|
28
39
|
delete<TResponse, TParams extends object = QueryParams>(route: string, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
29
40
|
data: TResponse;
|
|
30
41
|
}>;
|
|
31
42
|
}
|
|
32
43
|
//#endregion
|
|
33
44
|
//#region src/adapters/fetch/index.d.ts
|
|
45
|
+
/** Options for the Fetch-based `HTTPFetch` adapter. */
|
|
34
46
|
interface FetchAdapterOptions {
|
|
47
|
+
/** Base URL prepended to every generated route. */
|
|
35
48
|
baseURL?: string;
|
|
49
|
+
/** Headers included with every request unless overridden per request. */
|
|
36
50
|
headers?: Record<string, string>;
|
|
51
|
+
/** Fetch implementation to use, such as a test double or platform polyfill. */
|
|
37
52
|
fetch?: typeof fetch;
|
|
38
53
|
}
|
|
54
|
+
/** Create an `HTTPFetch` implementation backed by the Fetch API. */
|
|
39
55
|
declare function createFetchAdapter(options?: FetchAdapterOptions): HTTPFetch;
|
|
40
56
|
//#endregion
|
|
41
57
|
export { FetchAdapterOptions, type HTTPFetch, type HTTPFetchConfig, createFetchAdapter };
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{g as e,h as t,r as n,t as r}from"./init-
|
|
2
|
+
import{g as e,h as t,r as n,t as r}from"./init-CqBQsEHz.js";import{realpathSync as i}from"node:fs";import{pathToFileURL as a}from"node:url";function o(e){let t={sources:[]},n=[];for(let r=0;r<e.length;r+=1){let i=e[r];if(i!==void 0){if(i===`--check`){t.check=!0;continue}if(i===`--accept-base`){t.acceptBase=!0;continue}if(i===`--all`){t.all=!0;continue}if(i.startsWith(`--source=`)){let e=i.slice(9);t.sources.push(e),t.source===void 0&&(t.source=e);continue}if(i===`--source`){let n=e[r+1];n!==void 0&&(t.sources.push(n),t.source===void 0&&(t.source=n),r+=1);continue}if(i.startsWith(`--spec=`)){t.spec=i.slice(7);continue}if(i===`--spec`){let n=e[r+1];n!==void 0&&(t.spec=n,r+=1);continue}if(i.startsWith(`--client=`)){let e=i.slice(9);(e===`axios`||e===`fetch`||e===`custom`)&&(t.client=e);continue}if(i===`--client`){let n=e[r+1];(n===`axios`||n===`fetch`||n===`custom`)&&(t.client=n,r+=1);continue}if(i.startsWith(`--layout=`)){let e=i.slice(9);(e===`monolith`||e===`packages`)&&(t.layout=e);continue}if(i===`--layout`){let n=e[r+1];(n===`monolith`||n===`packages`)&&(t.layout=n,r+=1);continue}i.startsWith(`-`)||n.push(i)}}let r=n[0];return r!==void 0&&(t.command=r),t}function s(){process.stdout.write(`typeforge — headless OpenAPI TypeScript codegen
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
5
|
typeforge init --source <key> --client axios|fetch|custom [--layout monolith|packages]
|
package/dist/http/types.d.ts
CHANGED
|
@@ -4,25 +4,36 @@ type QueryParamValue = string | number | boolean | null | undefined;
|
|
|
4
4
|
type QueryParams = Record<string, QueryParamValue>;
|
|
5
5
|
//#endregion
|
|
6
6
|
//#region src/http/types.d.ts
|
|
7
|
+
/** Per-request options accepted by every Typeforge HTTP adapter method. */
|
|
7
8
|
interface HTTPFetchConfig<TParams extends object = QueryParams, TResponse = unknown> {
|
|
9
|
+
/** Abort signal forwarded to the underlying HTTP client. */
|
|
8
10
|
signal?: AbortSignal;
|
|
11
|
+
/** Query parameters serialized by the HTTP adapter. */
|
|
9
12
|
params?: TParams;
|
|
13
|
+
/** Request headers merged with adapter-level defaults. */
|
|
10
14
|
headers?: Record<string, string>;
|
|
15
|
+
/** Optional runtime validator applied to the response payload. */
|
|
11
16
|
validateResponse?: ResponseValidator<TResponse>;
|
|
12
17
|
}
|
|
18
|
+
/** Transport contract consumed by Typeforge-generated API callers. */
|
|
13
19
|
interface HTTPFetch {
|
|
20
|
+
/** Send a GET request and return its typed response payload. */
|
|
14
21
|
get<TResponse, TParams extends object = QueryParams>(route: string, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
15
22
|
data: TResponse;
|
|
16
23
|
}>;
|
|
24
|
+
/** Send a POST request with a typed body and return its typed response payload. */
|
|
17
25
|
post<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
18
26
|
data: TResponse;
|
|
19
27
|
}>;
|
|
28
|
+
/** Send a PUT request with a typed body and return its typed response payload. */
|
|
20
29
|
put<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
21
30
|
data: TResponse;
|
|
22
31
|
}>;
|
|
32
|
+
/** Send a PATCH request with a typed body and return its typed response payload. */
|
|
23
33
|
patch<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
24
34
|
data: TResponse;
|
|
25
35
|
}>;
|
|
36
|
+
/** Send a DELETE request and return its typed response payload. */
|
|
26
37
|
delete<TResponse, TParams extends object = QueryParams>(route: string, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
27
38
|
data: TResponse;
|
|
28
39
|
}>;
|
package/dist/index.d.ts
CHANGED
|
@@ -9,64 +9,134 @@ type QueryParamValue = string | number | boolean | null | undefined;
|
|
|
9
9
|
type QueryParams = Record<string, QueryParamValue>;
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/parser/types.d.ts
|
|
12
|
+
/** Intermediate representation of all parsed OpenAPI sources. */
|
|
12
13
|
interface IR {
|
|
14
|
+
/** Parsed API sources. */
|
|
13
15
|
sources: Array<IRSource>;
|
|
14
16
|
}
|
|
17
|
+
/** Parsed paths and component schemas for one OpenAPI source. */
|
|
15
18
|
interface IRSource {
|
|
19
|
+
/** Source key from the Typeforge project configuration. */
|
|
16
20
|
key: string;
|
|
21
|
+
/** Parsed API paths. */
|
|
17
22
|
paths: Array<IRPath>;
|
|
23
|
+
/** Reusable schemas declared by the source specification. */
|
|
18
24
|
components: {
|
|
19
25
|
schemas: Record<string, IRSchema>;
|
|
20
26
|
};
|
|
21
27
|
}
|
|
28
|
+
/** An OpenAPI path and its supported operations. */
|
|
22
29
|
interface IRPath {
|
|
30
|
+
/** Path template as written in the OpenAPI document. */
|
|
23
31
|
path: string;
|
|
32
|
+
/** Filesystem-safe path used for generated output. */
|
|
24
33
|
cleanPath: string;
|
|
34
|
+
/** Supported HTTP operations on this path. */
|
|
25
35
|
operations: Array<IROperation>;
|
|
26
36
|
}
|
|
37
|
+
/** A parsed OpenAPI operation. */
|
|
27
38
|
interface IROperation {
|
|
39
|
+
/** HTTP method for the operation. */
|
|
28
40
|
method: HttpMethod;
|
|
41
|
+
/** Explicit OpenAPI operation identifier, when provided. */
|
|
29
42
|
operationId?: string;
|
|
43
|
+
/** Short operation summary from the OpenAPI document. */
|
|
44
|
+
summary?: string;
|
|
45
|
+
/** Detailed operation description from the OpenAPI document. */
|
|
46
|
+
description?: string;
|
|
47
|
+
/** Whether the OpenAPI operation is deprecated. */
|
|
48
|
+
deprecated?: boolean;
|
|
49
|
+
/** Parameters substituted into the route path. */
|
|
30
50
|
pathParams: Array<IRPathParam>;
|
|
51
|
+
/** Parameters serialized into the query string. */
|
|
31
52
|
queryParams: Array<IRQueryParam>;
|
|
53
|
+
/** JSON request body, when the operation accepts one. */
|
|
32
54
|
requestBody?: IRRequestBody;
|
|
55
|
+
/** Declared operation responses. */
|
|
33
56
|
responses: Array<IRResponse>;
|
|
34
57
|
}
|
|
58
|
+
/** HTTP methods supported by the Typeforge generator. */
|
|
35
59
|
type HttpMethod = "get" | "post" | "put" | "patch" | "delete";
|
|
60
|
+
/** Parsed path parameter metadata. */
|
|
36
61
|
interface IRPathParam {
|
|
62
|
+
/** Parameter name. */
|
|
37
63
|
name: string;
|
|
64
|
+
/** OpenAPI parameter description. */
|
|
65
|
+
description?: string;
|
|
66
|
+
/** Whether the parameter is deprecated. */
|
|
67
|
+
deprecated?: boolean;
|
|
68
|
+
/** Parameter value schema. */
|
|
38
69
|
schema: IRSchema;
|
|
39
70
|
}
|
|
71
|
+
/** Parsed query parameter metadata. */
|
|
40
72
|
interface IRQueryParam {
|
|
73
|
+
/** Parameter name. */
|
|
41
74
|
name: string;
|
|
75
|
+
/** Whether callers must provide the parameter. */
|
|
42
76
|
required: boolean;
|
|
77
|
+
/** OpenAPI parameter description. */
|
|
78
|
+
description?: string;
|
|
79
|
+
/** Whether the parameter is deprecated. */
|
|
80
|
+
deprecated?: boolean;
|
|
81
|
+
/** Parameter value schema. */
|
|
43
82
|
schema: IRSchema;
|
|
44
83
|
}
|
|
84
|
+
/** Parsed request-body metadata. */
|
|
45
85
|
interface IRRequestBody {
|
|
86
|
+
/** Whether callers must provide the request body. */
|
|
46
87
|
required: boolean;
|
|
88
|
+
/** OpenAPI request-body description. */
|
|
89
|
+
description?: string;
|
|
90
|
+
/** JSON request-body schema. */
|
|
47
91
|
schema: IRSchema;
|
|
48
92
|
}
|
|
93
|
+
/** Parsed response metadata for one status code. */
|
|
49
94
|
interface IRResponse {
|
|
95
|
+
/** OpenAPI response status key, such as `"200"` or `"default"`. */
|
|
50
96
|
statusCode: string;
|
|
97
|
+
/** OpenAPI response description. */
|
|
98
|
+
description?: string;
|
|
99
|
+
/** JSON response schema, when one is declared. */
|
|
51
100
|
schema?: IRSchema;
|
|
52
101
|
}
|
|
102
|
+
/** Typeforge's normalized representation of an OpenAPI schema. */
|
|
53
103
|
interface IRSchema {
|
|
104
|
+
/** Normalized schema construct used by the TypeScript renderer. */
|
|
54
105
|
kind: "object" | "array" | "string" | "number" | "boolean" | "null" | "unknown" | "ref" | "oneOf" | "anyOf" | "allOf";
|
|
106
|
+
/** Referenced component name for `ref` schemas. */
|
|
55
107
|
ref?: string;
|
|
108
|
+
/** Element schema for arrays. */
|
|
56
109
|
items?: IRSchema;
|
|
110
|
+
/** Named fields for object schemas. */
|
|
57
111
|
properties?: Record<string, IRSchemaProperty>;
|
|
112
|
+
/** Required object-property names from the source schema. */
|
|
58
113
|
required?: Array<string>;
|
|
114
|
+
/** Allowed literal values. */
|
|
59
115
|
enum?: Array<JsonPrimitive>;
|
|
116
|
+
/** Schema for arbitrary object values, or whether they are allowed. */
|
|
60
117
|
additionalProperties?: IRSchema | boolean;
|
|
118
|
+
/** Exclusive union alternatives. */
|
|
61
119
|
oneOf?: Array<IRSchema>;
|
|
120
|
+
/** Non-exclusive union alternatives. */
|
|
62
121
|
anyOf?: Array<IRSchema>;
|
|
122
|
+
/** Intersected schema parts. */
|
|
63
123
|
allOf?: Array<IRSchema>;
|
|
124
|
+
/** OpenAPI scalar format, such as `uuid` or `date-time`. */
|
|
64
125
|
format?: string;
|
|
126
|
+
/** Whether the schema also accepts `null`. */
|
|
65
127
|
nullable?: boolean;
|
|
128
|
+
/** Human-readable OpenAPI schema description. */
|
|
129
|
+
description?: string;
|
|
130
|
+
/** Whether the OpenAPI schema is deprecated. */
|
|
131
|
+
deprecated?: boolean;
|
|
132
|
+
/** Extension that identifies the schema used for object map keys. */
|
|
66
133
|
"x-map-key-ref"?: string;
|
|
67
134
|
}
|
|
135
|
+
/** A normalized object property and its requiredness. */
|
|
68
136
|
interface IRSchemaProperty {
|
|
137
|
+
/** Property value schema. */
|
|
69
138
|
schema: IRSchema;
|
|
139
|
+
/** Whether the containing object requires the property. */
|
|
70
140
|
required: boolean;
|
|
71
141
|
}
|
|
72
142
|
//#endregion
|
|
@@ -110,46 +180,86 @@ declare function resolveSpecSource(sourceKey: string, opts: {
|
|
|
110
180
|
type ResponseValidator<T> = (value: unknown) => T;
|
|
111
181
|
//#endregion
|
|
112
182
|
//#region src/http/types.d.ts
|
|
183
|
+
/** Per-request options accepted by every Typeforge HTTP adapter method. */
|
|
113
184
|
interface HTTPFetchConfig<TParams extends object = QueryParams, TResponse = unknown> {
|
|
185
|
+
/** Abort signal forwarded to the underlying HTTP client. */
|
|
114
186
|
signal?: AbortSignal;
|
|
187
|
+
/** Query parameters serialized by the HTTP adapter. */
|
|
115
188
|
params?: TParams;
|
|
189
|
+
/** Request headers merged with adapter-level defaults. */
|
|
116
190
|
headers?: Record<string, string>;
|
|
191
|
+
/** Optional runtime validator applied to the response payload. */
|
|
117
192
|
validateResponse?: ResponseValidator<TResponse>;
|
|
118
193
|
}
|
|
194
|
+
/** Transport contract consumed by Typeforge-generated API callers. */
|
|
119
195
|
interface HTTPFetch {
|
|
196
|
+
/** Send a GET request and return its typed response payload. */
|
|
120
197
|
get<TResponse, TParams extends object = QueryParams>(route: string, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
121
198
|
data: TResponse;
|
|
122
199
|
}>;
|
|
200
|
+
/** Send a POST request with a typed body and return its typed response payload. */
|
|
123
201
|
post<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
124
202
|
data: TResponse;
|
|
125
203
|
}>;
|
|
204
|
+
/** Send a PUT request with a typed body and return its typed response payload. */
|
|
126
205
|
put<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
127
206
|
data: TResponse;
|
|
128
207
|
}>;
|
|
208
|
+
/** Send a PATCH request with a typed body and return its typed response payload. */
|
|
129
209
|
patch<TResponse, TBody = unknown, TParams extends object = QueryParams>(route: string, body: TBody, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
130
210
|
data: TResponse;
|
|
131
211
|
}>;
|
|
212
|
+
/** Send a DELETE request and return its typed response payload. */
|
|
132
213
|
delete<TResponse, TParams extends object = QueryParams>(route: string, config?: HTTPFetchConfig<TParams, TResponse>): Promise<{
|
|
133
214
|
data: TResponse;
|
|
134
215
|
}>;
|
|
135
216
|
}
|
|
136
217
|
//#endregion
|
|
137
218
|
//#region src/config/types.d.ts
|
|
219
|
+
/** Project-wide Typeforge settings loaded from `typeforge.json` or package.json. */
|
|
138
220
|
interface TypeforgeConfig {
|
|
221
|
+
/**
|
|
222
|
+
* Root directory containing HTTP adapters and named API sources.
|
|
223
|
+
* @defaultValue `"src/api"`
|
|
224
|
+
*/
|
|
139
225
|
apiRoot?: string;
|
|
140
226
|
}
|
|
227
|
+
/** Controls whether generated routes replace or preserve existing route entries. */
|
|
141
228
|
type GenerationMode = "authoritative" | "merge";
|
|
229
|
+
/** Selects whether generated function names come from paths or OpenAPI operation IDs. */
|
|
142
230
|
type NamingStrategy = "path" | "operationId";
|
|
231
|
+
/** Maps API query-parameter names to shared pagination and sorting types. */
|
|
143
232
|
interface QueryExtendsConfig {
|
|
233
|
+
/**
|
|
234
|
+
* Name of the page-number query parameter.
|
|
235
|
+
* @defaultValue `"page"`
|
|
236
|
+
*/
|
|
144
237
|
page?: string;
|
|
238
|
+
/**
|
|
239
|
+
* Name of the page-size query parameter.
|
|
240
|
+
* @defaultValue `"limit"`
|
|
241
|
+
*/
|
|
145
242
|
limit?: string;
|
|
243
|
+
/**
|
|
244
|
+
* Name of the sort-field query parameter.
|
|
245
|
+
* @defaultValue `"sortBy"`
|
|
246
|
+
*/
|
|
146
247
|
sortBy?: string;
|
|
248
|
+
/**
|
|
249
|
+
* Name of the sort-direction query parameter.
|
|
250
|
+
* @defaultValue `"sortOrder"`
|
|
251
|
+
*/
|
|
147
252
|
sortOrder?: string;
|
|
253
|
+
/** Shared type that replaces matching page and limit properties. */
|
|
148
254
|
paginationTypeName?: string;
|
|
255
|
+
/** Module specifier from which the shared pagination type is imported. */
|
|
149
256
|
paginationImportPath?: string;
|
|
257
|
+
/** Generic shared type that replaces matching sort properties. */
|
|
150
258
|
sortTypeName?: string;
|
|
259
|
+
/** Module specifier from which the shared sort type is imported. */
|
|
151
260
|
sortImportPath?: string;
|
|
152
261
|
}
|
|
262
|
+
/** Generation settings exported by an API source's `source.ts` file. */
|
|
153
263
|
interface SourceConfig {
|
|
154
264
|
/**
|
|
155
265
|
* Project-relative directory for generated API function files.
|
|
@@ -161,13 +271,33 @@ interface SourceConfig {
|
|
|
161
271
|
* Defaults to `<apiRoot>/<source>/generated/types`.
|
|
162
272
|
*/
|
|
163
273
|
typesDir?: string;
|
|
274
|
+
/** Only generate operations whose paths start with this prefix. */
|
|
164
275
|
pathPrefix?: string;
|
|
276
|
+
/** Exact OpenAPI paths to exclude from generation. */
|
|
165
277
|
ignorePaths?: Array<string>;
|
|
278
|
+
/** Remove the leading `/api` segment from generated route names and values. */
|
|
166
279
|
stripApiPrefix?: boolean;
|
|
280
|
+
/**
|
|
281
|
+
* Name of the generated route-target enum.
|
|
282
|
+
* @defaultValue `"RouteTargets"`
|
|
283
|
+
*/
|
|
167
284
|
routeEnumName?: string;
|
|
285
|
+
/** Whether route generation replaces the file or retains extra existing entries. */
|
|
168
286
|
generationMode?: GenerationMode;
|
|
287
|
+
/**
|
|
288
|
+
* Strategy used to derive generated caller function names.
|
|
289
|
+
* @defaultValue `"path"`
|
|
290
|
+
*/
|
|
169
291
|
naming?: NamingStrategy;
|
|
292
|
+
/**
|
|
293
|
+
* Maximum schema expansion depth before recursive generation fails.
|
|
294
|
+
* @defaultValue `50`
|
|
295
|
+
*/
|
|
170
296
|
maxRenderDepth?: number;
|
|
297
|
+
/**
|
|
298
|
+
* Resolve `x-map-key-ref` extensions into typed `Record` keys.
|
|
299
|
+
* @defaultValue `true`
|
|
300
|
+
*/
|
|
171
301
|
resolveMapKeyRefs?: boolean;
|
|
172
302
|
/**
|
|
173
303
|
* Emit an envelope's `data` schema as the operation response type.
|
|
@@ -175,8 +305,9 @@ interface SourceConfig {
|
|
|
175
305
|
* unwraps response envelopes before returning its `{ data }` value.
|
|
176
306
|
*/
|
|
177
307
|
unwrapResponseData?: boolean;
|
|
308
|
+
/** Replace conventional pagination and sorting properties with shared local types. */
|
|
178
309
|
queryExtends?: QueryExtendsConfig;
|
|
179
|
-
/**
|
|
310
|
+
/** Emit TanStack Query helpers for GET endpoints when `query-scope.ts` exists. */
|
|
180
311
|
tanstackQuery?: boolean;
|
|
181
312
|
/**
|
|
182
313
|
* Explicit import base for generated function files pointing back to the
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,c as t,d as n,f as r,i,l as a,m as o,n as s,o as c,p as l,r as u,s as d,t as f,u as p}from"./init-
|
|
1
|
+
import{a as e,c as t,d as n,f as r,i,l as a,m as o,n as s,o as c,p as l,r as u,s as d,t as f,u as p}from"./init-CqBQsEHz.js";function m(e){return e}export{t as RecursiveRefError,n as analyzeEnvelope,r as buildBaseResponseInterface,s as buildGenerateContext,m as defineSourceConfig,l as diffEnvelopeFields,u as generateForSource,f as initProject,c as loadKnownTypeRules,i as loadSpec,d as matchKnownType,a as parseSchema,p as parseSpec,o as parseUserBaseResponse,e as resolveSpecSource};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import{existsSync as e,mkdirSync as t,readFileSync as n,readdirSync as r,statSync as i,writeFileSync as a}from"node:fs";import{dirname as o,join as s,parse as c,relative as l,resolve as u}from"node:path";import d from"chalk";import{mkdir as f,readFile as p,writeFile as m}from"node:fs/promises";function h(e){return e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`}function g(e){return e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?!0:Array.isArray(e)?e.every(g):typeof e==`object`&&e?Object.values(e).every(g):!1}function _(e){return g(e)&&typeof e==`object`&&!!e&&!Array.isArray(e)}function v(e){return Array.isArray(e)&&e.every(g)}function y(e){let t=JSON.parse(e);if(!g(t))throw TypeError(`JSON text did not parse to a valid JSON value`);return t}function b(e){let t=y(e);if(!_(t))throw TypeError(`JSON text did not parse to a JSON object`);return t}function x(e){return v(e)?e.filter(h):[]}function S(t){if(!e(t))return{};try{let e=b(n(t,`utf8`)),r={};return typeof e.apiRoot==`string`&&(r.apiRoot=e.apiRoot),r}catch{return{}}}function C(t){if(!e(t))return{};try{let e=b(n(t,`utf8`)).typeforge;if(typeof e!=`object`||!e||Array.isArray(e))return{};let r={};return typeof e.apiRoot==`string`&&(r.apiRoot=e.apiRoot),r}catch{return{}}}function w(e){let t=e.match(/defineSourceConfig\s*(?:<[^>]*>)?\s*\(\s*\{([\s\S]*)\}\s*\)/);return t?.[1]===void 0?e:`{${t[1]}}`}function T(e){let t=w(e),n={},r=t.match(/pathPrefix:\s*["'`]([^"'`]+)["'`]/);r?.[1]!==void 0&&(n.pathPrefix=r[1]);let i=t.match(/functionsDir:\s*["'`]([^"'`]+)["'`]/);i?.[1]!==void 0&&(n.functionsDir=i[1]);let a=t.match(/typesDir:\s*["'`]([^"'`]+)["'`]/);a?.[1]!==void 0&&(n.typesDir=a[1]);let o=t.match(/ignorePaths:\s*\[([\s\S]*?)\]/);if(o?.[1]!==void 0){let e=[...o[1].matchAll(/["'`]([^"'`]+)["'`]/g)].map(e=>e[1]).filter(e=>e!==void 0);e.length>0&&(n.ignorePaths=e)}/stripApiPrefix:\s*true/.test(t)&&(n.stripApiPrefix=!0);let s=t.match(/routeEnumName:\s*["'`]([^"'`]+)["'`]/);s?.[1]!==void 0&&(n.routeEnumName=s[1]);let c=t.match(/generationMode:\s*["'`](authoritative|merge)["'`]/);(c?.[1]===`authoritative`||c?.[1]===`merge`)&&(n.generationMode=c[1]);let l=t.match(/naming:\s*["'`](path|operationId)["'`]/);(l?.[1]===`path`||l?.[1]===`operationId`)&&(n.naming=l[1]),/resolveMapKeyRefs:\s*false/.test(t)&&(n.resolveMapKeyRefs=!1),/unwrapResponseData:\s*true/.test(t)&&(n.unwrapResponseData=!0),/tanstackQuery:\s*true/.test(t)&&(n.tanstackQuery=!0);let u=t.match(/importBase:\s*["'`]([^"'`]+)["'`]/);u?.[1]!==void 0&&(n.importBase=u[1]);let d=t.match(/maxRenderDepth:\s*(\d+)/)?.[1];d!==void 0&&(n.maxRenderDepth=Number.parseInt(d,10));let f=E(t);f!==void 0&&(n.queryExtends=f);let p=t.match(/spec:\s*["'`]([^"'`]+)["'`]/);return p?.[1]!==void 0&&(n.spec=p[1]),n}function E(e){let t=e.match(/queryExtends:\s*\{([\s\S]*?)\}/)?.[1];if(t===void 0)return;let n={},r=e=>t.match(RegExp(`${e}:\\s*["'\`]([^"'\`]+)["'\`]`))?.[1],i=r(`page`),a=r(`limit`),o=r(`sortBy`),s=r(`sortOrder`),c=r(`paginationTypeName`),l=r(`paginationImportPath`),u=r(`sortTypeName`),d=r(`sortImportPath`);return i!==void 0&&(n.page=i),a!==void 0&&(n.limit=a),o!==void 0&&(n.sortBy=o),s!==void 0&&(n.sortOrder=s),c!==void 0&&(n.paginationTypeName=c),l!==void 0&&(n.paginationImportPath=l),u!==void 0&&(n.sortTypeName=u),d!==void 0&&(n.sortImportPath=d),Object.keys(n).length>0?n:void 0}function D(e){let t=S(u(e,`typeforge.json`)),n=C(u(e,`package.json`));return{apiRoot:t.apiRoot??n.apiRoot??`src/api`}}function ee(t,r,i){let a=u(t,r,i,`source.ts`);return e(a)?T(n(a,`utf8`)):{}}function te(t,r){let i=u(t,r,`models.ts`);if(e(i))return n(i,`utf8`)}function ne(t,n){return e(u(t,n,`query-scope.ts`))}function re(t,r){let i=u(t,r,`http.ts`);if(!e(i))return`injected`;let a=n(i,`utf8`);return/export\s+(const|function)\s+httpFetch\b/.test(a)||/export\s*\{[^}]*\bhttpFetch\b/.test(a)?`singleton`:`injected`}function ie(t,n){let a=u(t,n);return e(a)?r(a).filter(t=>{let n=s(a,t);return i(n).isDirectory()?e(s(n,`source.ts`)):!1}):[]}function ae(e){let t=``,n=0,r=e.length,i=!1;for(;n<r;){let a=e[n];if(i){t+=a,a===`\\`?(n++,n<r&&(t+=e[n])):a===`"`&&(i=!1),n++;continue}if(a===`"`){i=!0,t+=a,n++;continue}if(a===`/`&&e[n+1]===`/`){for(;n<r&&e[n]!==`
|
|
2
|
+
`;)n++;continue}if(a===`/`&&e[n+1]===`*`){for(n+=2;n<r&&(e[n]!==`*`||e[n+1]!==`/`);)n++;n+=2;continue}t+=a,n++}return t.replace(/,(\s*[}\]])/g,`$1`)}function oe(e){let t=u(e),n=c(t).root;for(;;){let e=se(t);if(e!==void 0)return e;if(t===n)return;t=o(t)}}function se(t){let r=u(t,`tsconfig.json`);if(e(r))try{let e=JSON.parse(ae(n(r,`utf8`)));if(typeof e!=`object`||!e||Array.isArray(e))return;let i=e.compilerOptions;if(typeof i!=`object`||!i||Array.isArray(i))return;let a=i,o=a.paths;if(typeof o!=`object`||!o||Array.isArray(o))return;let s=typeof a.baseUrl==`string`?a.baseUrl:`.`,c={};for(let[e,t]of Object.entries(o))Array.isArray(t)&&t.every(e=>typeof e==`string`)&&(c[e]=t);return Object.keys(c).length===0?void 0:{baseDir:t,paths:c,resolvedBaseUrl:u(t,s)}}catch{return}}function ce(e,t){for(let[n,r]of Object.entries(t.paths))for(let i of r)if(n.endsWith(`/*`)&&i.endsWith(`/*`)){let r=n.slice(0,-2),a=i.slice(0,-2),o=u(t.resolvedBaseUrl,a);if(e.startsWith(`${o}/`))return`${r}/${e.slice(o.length+1)}`;if(e===o)return r}else if(!n.includes(`*`)&&!i.includes(`*`)){let r=u(t.resolvedBaseUrl,i);if(le(e)===le(r))return n}}function le(e){return e.replace(/\.(d\.ts|ts|js)$/,``)}function O(e){return e.replace(/\.d\.ts$/,``).replace(/\.ts$/,``)}function ue(e,t){let n=o(O(e)),r=O(t),i=l(n,r).replace(/\\/g,`/`);return i.startsWith(`.`)?i:`./${i}`}function de(e){let{fromAbsolutePath:t,toAbsolutePath:n,importBase:r,generatedDir:i,tsconfigPaths:a}=e;if(r!==void 0&&i!==void 0){let e=i.replace(/\/$/,``),t=O(n);if(t.startsWith(`${e}/`))return`${r}/${t.slice(e.length+1)}`;if(t===e)return r}let o=ue(t,n);if(a!==void 0&&(o.match(/\.\.\//g)??[]).length>=3){let e=ce(n,a);if(e!==void 0)return e}return o}function fe(e,t,n){return s(e,t,`${n}.ts`)}function pe(e){return e.split(`/`).filter(Boolean).map(e=>e.replace(/[{}]/g,``).replace(/[^a-zA-Z0-9]/g,`_`).toUpperCase()).join(`_`)}function me(e,t=!1){return(t?e.replace(/^\/api\//,`/`):e).replace(/\{(\w+)\}/g,`:$1`)}function he(e,t){let n=e.split(`/`).filter(Boolean).map(e=>e.replace(/[{[\]}/]/g,``).split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``)).join(``);return`${t===`get`?`get`:t}${n}`}function ge(e){return e.kind===`array`?`array`:e.kind===`object`?`object`:e.kind===`ref`?`ref:${e.ref??`unknown`}`:e.kind===`oneOf`||e.kind===`anyOf`||e.kind===`allOf`?e.kind:e.enum!==void 0&&e.enum.length>0?`enum`:e.kind}function _e(e){let t=Number.parseInt(e,10);return!Number.isNaN(t)&&t>=200&&t<300}function ve(e){return e.enum!==void 0&&e.enum.length>0?e.enum.map(e=>JSON.stringify(e)).join(` | `):e.kind===`number`?`number`:e.kind===`boolean`?`boolean`:`string`}function ye(e){let t=new Map;for(let n of e.operations)for(let e of n.pathParams)t.has(e.name)||t.set(e.name,e.schema);return t}function be(e,t){let n=e.get(t);return n===void 0?`string`:ve(n)}function xe(e,t){let n=e.split(`/`).filter(Boolean).map(e=>e.replace(/[{[\]}/]/g,``).split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``)).join(``);return`${t.toUpperCase()}${n}`}function Se(e){let t=e.requestBody?.schema;return t!==void 0&&!Ce(t)}function Ce(e){return e.kind===`unknown`?!0:e.kind===`object`?e.properties===void 0||Object.keys(e.properties).length===0:!1}function we(e){return e.responses.find(e=>_e(e.statusCode)&&e.schema!==void 0)?.schema}function Te(e){return e.trim().replaceAll(`\r
|
|
3
|
+
`,`
|
|
4
|
+
`).replaceAll(`\r`,`
|
|
5
|
+
`).replaceAll(`*/`,`*\\/`).split(`
|
|
6
|
+
`)}function k(e,t=``){let n=e.description===void 0?[]:Te(e.description),r=n.some(e=>e.length>0),i=e.deprecated===!0;if(!r&&!i)return[];if(n.length===1&&!i)return[`${t}/** ${n[0]} */`];let a=[`${t}/**`];if(r)for(let e of n)a.push(`${t} *${e.length>0?` ${e}`:``}`);return i&&(r&&a.push(`${t} *`),a.push(`${t} * @deprecated`)),a.push(`${t} */`),a}function Ee(e){return(e.match(/\{([^}]+)\}/g)??[]).map(e=>e.slice(1,-1))}function De(e,t,n){let r=e.replace(/\{([^}]+)\}/g,`[$1]`).split(`/`).filter(Boolean).join(`/`),i=fe(n.functionsDir,e,t.toUpperCase()),a=s(n.typesDir,r,t.toUpperCase());return de({fromAbsolutePath:i,generatedDir:n.generatedDir,toAbsolutePath:a,...n.importBase===void 0?{}:{importBase:n.importBase},...n.tsconfigPaths===void 0?{}:{tsconfigPaths:n.tsconfigPaths}})}function Oe(e,t,n){let r=fe(t.functionsDir,e,n.toUpperCase()),i=s(t.generatedDir,`runtime`);return de({fromAbsolutePath:r,generatedDir:t.generatedDir,toAbsolutePath:i,...t.importBase===void 0?{}:{importBase:t.importBase},...t.tsconfigPaths===void 0?{}:{tsconfigPaths:t.tsconfigPaths}})}function ke(e,t,n){let r=e.pathParams.find(e=>e.name===n);return be(r===void 0?t:new Map([[n,r.schema]]),n)}function A(e,t,n=!1){let r={},i=e??t;return i!==void 0&&(r.description=i),n&&(r.deprecated=!0),r}function Ae(e){let t=[];for(let n of e.paths)for(let r of n.operations)t.push({content:je(n,r,e),relativePath:`${n.cleanPath}/${r.method.toUpperCase()}.ts`});return t}function je(e,t,n){let r=t.method,i=he(e.cleanPath,r),a=pe(e.path),o=xe(e.cleanPath,r),s=Ee(e.path),c=ye(e),l=`${Me(i)}Props`,u=`${Me(i)}QueryOptionsProps`,d=r!==`get`&&Se(t),f=t.queryParams.length>0,p=De(e.cleanPath,r,n),m=Oe(e.cleanPath,n,r),h=[`// Auto-generated from OpenAPI spec`,`// Path: ${r.toUpperCase()} ${e.path}`,`// DO NOT EDIT - This file is automatically generated`,``];h.push(`import type {`),h.push(` ${o}Response,`),f&&h.push(` ${o}Params,`),d&&h.push(` ${o}Body,`),h.push(`} from "${p}";`),h.push(``);let g=n.hasQueryScope?`, RouteTargets`:``;n.httpMode===`singleton`?h.push(`import { httpFetch, Routes${g}${n.hasQueryScope?`, getQueryScopeKey, queryOptions`:``} } from "${m}";`):h.push(`import { Routes${g}${n.hasQueryScope?`, getQueryScopeKey, queryOptions`:``} } from "${m}";`);let _=n.httpMode===`injected`?`HTTPFetch, `:``,v=f?``:`, QueryParams`;h.push(`import type { ${_}HTTPFetchConfig${v}${n.hasQueryScope?`, QueryScope`:``} } from "${m}";`),h.push(``),h.push(...k(A(t.description,t.summary,t.deprecated===!0))),h.push(`export interface ${l} {`),n.httpMode===`injected`&&h.push(` http: HTTPFetch;`);for(let e of s){let n=t.pathParams.find(t=>t.name===e);n!==void 0&&h.push(...k(A(n.description,n.schema.description,n.deprecated===!0||n.schema.deprecated===!0),` `)),h.push(` ${e}: ${ke(t,c,e)};`)}if(f){let e=t.queryParams.some(e=>e.required)?``:`?`;h.push(` params${e}: ${o}Params;`)}if(d){let e=t.requestBody;e!==void 0&&h.push(...k(A(e.description,e.schema.description),` `)),h.push(` body: ${o}Body;`)}let y=f?`Omit<HTTPFetchConfig<${o}Params, ${o}Response>, "params" | "signal">`:`Omit<HTTPFetchConfig<QueryParams, ${o}Response>, "params" | "signal">`;h.push(` config?: ${y};`),h.push(` signal?: AbortSignal;`),h.push(`}`),h.push(``),r===`get`&&n.hasQueryScope&&(h.push(`export interface ${u} extends ${l} {`),h.push(` queryScope: QueryScope;`),h.push(`}`),h.push(``));let b=n.httpMode===`singleton`?`httpFetch`:`props.http`,x=[...n.httpMode===`injected`?[`http`]:[],...s.map(e=>e),...f?[`params`]:[],...d?[`body`]:[],`config`,`signal`];h.push(`export async function ${i}(props: ${l}): Promise<${o}Response> {`),x.length>0&&(h.push(` const { ${x.join(`, `)} } = props;`),h.push(``));let S=`Routes.${a}`;s.length>0&&(S=`Routes.${a}({ ${s.map(e=>`${e}`).join(`, `)} })`);let C=f?`{ ...config, params, signal }`:`{ ...config, signal }`,w=f?`<${o}Response, ${o}Params>`:`<${o}Response>`,T=`<${o}Response, ${d?`${o}Body`:`undefined`}${f?`, ${o}Params`:``}>`,E=d?`body`:`undefined`,D=f?`{ ...config, params, signal }`:`{ ...config, signal }`;switch(r){case`get`:h.push(` const { data } = await ${b}.get${w}(${S}, ${C});`);break;case`post`:h.push(` const { data } = await ${b}.post${T}(${S}, ${E}, ${D});`);break;case`put`:h.push(` const { data } = await ${b}.put${T}(${S}, ${E}, ${D});`);break;case`patch`:h.push(` const { data } = await ${b}.patch${T}(${S}, ${E}, ${D});`);break;case`delete`:{let e=C;d&&(e=f?`{ ...config, data: body, params, signal }`:`{ ...config, data: body, signal }`),h.push(` const { data } = await ${b}.delete${w}(${S}, ${e});`);break}}if(h.push(` return data;`),h.push(`}`),r===`get`&&n.hasQueryScope){let e=`${i}QueryOptions`;h.push(``),h.push(`export function ${e}(props: ${u}) {`),h.push(` const { ${f?`params, `:``}queryScope } = props;`),h.push(` return queryOptions({`),h.push(` queryKey: [RouteTargets.${a}, ...getQueryScopeKey(queryScope)${s.length>0?`, ${s.map(e=>`props.${e}`).join(`, `)}`:``}${f?`, params`:``}],`),h.push(` queryFn: ({ signal }) => ${i}({ ...props, signal }).then((data) => data),`),s.length>0&&h.push(` enabled: [${s.map(e=>`props.${e}`).join(`, `)}].every(Boolean),`),h.push(` });`),h.push(`}`)}return h.push(``),h.join(`
|
|
7
|
+
`)}function Me(e){return e.charAt(0).toUpperCase()+e.slice(1)}function Ne(e){let t=[`// Auto-generated from OpenAPI spec`,`// DO NOT EDIT - This file is automatically generated`,``,`export type { HTTPFetch, HTTPFetchConfig, QueryParams } from "../../http";`];return e.httpMode===`singleton`&&t.push(`export { httpFetch } from "../../http";`),t.push(`export { Routes, RouteTargets, buildRoute } from "./routes";`),e.hasQueryScope&&(t.push(`export type { QueryScope } from "../../query-scope";`),t.push(`export { getQueryScopeKey } from "../../query-scope";`),t.push(`export { queryOptions } from "@tanstack/react-query";`)),t.push(``),t.join(`
|
|
8
|
+
`)}function Pe(e){return(e.match(/\{([^}]+)\}/g)??[]).map(e=>e.slice(1,-1))}function Fe(e){let t=new Set,n=[];for(let r of e.paths){let i=pe(r.path);t.has(i)||(t.add(i),n.push({enumName:i,pathParamNames:Pe(r.path),pathParamSchemas:ye(r),routeValue:me(r.path,e.stripApiPrefix===!0)}))}return n}function Ie(e){let t=[`export type RouteParams = {`];for(let n of e){if(n.pathParamNames.length===0){t.push(` ${n.enumName}: undefined;`);continue}t.push(` ${n.enumName}: {`);for(let e of n.pathParamNames)t.push(` ${e}: ${be(n.pathParamSchemas,e)};`);t.push(` };`)}return t.push(`};`,`export type RouteKey = keyof RouteParams;`,``),t}function Le(e){let t=Fe(e),n=[`// Auto-generated from OpenAPI spec`,`// DO NOT EDIT - This file is automatically generated`,``,`import {`,` buildRouteFromHandlers,`,` createRouteHandlers,`,`} from "@openmirai/typeforge/routes";`,``,...Ie(t),`export enum ${e.routeEnumName} {`];for(let e of t)n.push(` ${e.enumName} = "${e.routeValue}",`);return n.push(`}`,``),e.routeEnumName!==`RouteTargets`&&(n.push(`export { ${e.routeEnumName} as RouteTargets };`),n.push(``)),n.push(`export const Routes = createRouteHandlers<RouteParams>(${e.routeEnumName});`),n.push(`export const buildRoute = buildRouteFromHandlers<RouteParams>(Routes);`,``),n.join(`
|
|
9
|
+
`)}function Re(e,t,n,r){let i=ze(e,n),a=ze(t,n);if(r!==void 0)for(let[e,t]of i.entries())t.startsWith(r)&&!a.has(e)&&i.delete(e);return Le({paths:[...new Map([...i,...a]).entries()].map(([,e])=>({cleanPath:e.replace(/:[^/]+/g,e=>`{${e.slice(1)}}`),operations:[],path:e.includes(`:`)?e.replace(/:([^/]+)/g,`{$1}`):e})),routeEnumName:n,stripApiPrefix:!1})}function ze(e,t){let n=new Map,r=e.indexOf(`export enum ${t} {`);if(r===-1)return n;let i=e.slice(r),a=i.indexOf(`}`);if(a===-1)return n;let o=i.slice(0,a),s=/(\w+)\s*=\s*"([^"]+)"/g,c;for(;(c=s.exec(o))!==null;){let e=c[1],t=c[2];e!==void 0&&t!==void 0&&n.set(e,t)}return n}function j(e,t){if(e.kind!==`ref`||e.ref===void 0)return e;let n=e.ref.split(`/`).pop();return n===void 0||t[n]===void 0?{kind:`unknown`}:t[n]}function M(e,t,n=new Set){if(e.kind===`object`)return e;if(e.kind===`ref`){let r=Be(e);if(r===void 0||n.has(r))return;let i=t[r];return i===void 0?void 0:M(i,t,new Set([...n,r]))}if(e.kind!==`allOf`||e.allOf===void 0)return;let r={},i=new Set;for(let a of e.allOf){let e=M(a,t,n);if(e?.properties===void 0)return;for(let[t,n]of Object.entries(e.properties)){let e=r[t];r[t]=e===void 0?{...n}:{required:e.required||n.required,schema:JSON.stringify(e.schema)===JSON.stringify(n.schema)?e.schema:{allOf:[e.schema,n.schema],kind:`allOf`}},n.required&&i.add(t)}}return{kind:`object`,properties:r,required:[...i]}}function Be(e){if(e.kind===`ref`&&e.ref!==void 0)return e.ref.split(`/`).pop()}function Ve(e,t){return e.kind===`ref`?j(e,t):e}function N(e,t){if(e===void 0)return;let n=M(e,t);if(n?.properties===void 0)return;let r=[];for(let[e,i]of Object.entries(n.properties))r.push({kind:e===`data`?`generic`:ge(Ve(i.schema,t)),name:e,required:i.required});return r.sort((e,t)=>e.name.localeCompare(t.name)),{fields:r,schema:n}}function P(e){return JSON.stringify(e.fields.map(e=>({kind:e.kind,name:e.name,required:e.required})))}function He(e,t,n){let r=N(e,t);return r!==void 0&&P(r)===P(n)}const Ue=new Set([`error`,`message`,`requestId`,`success`,`timestamp`]);function F(e){let t=new Set(e.fields.map(e=>e.name));return t.has(`data`)?!0:t.has(`success`)?[...t].every(e=>Ue.has(e)):!1}function We(e,t){let n=N(e,t);return n!==void 0&&F(n)}function Ge(e){let t=[];for(let n of e.paths)for(let r of n.operations){let i=r.responses.find(e=>_e(e.statusCode)&&e.schema!==void 0);if(i?.schema===void 0)continue;let a=N(i.schema,e.components.schemas);a!==void 0&&t.push({method:r.method.toUpperCase(),path:n.path,shape:a})}return t}function Ke(e){let t=Ge(e),n=new Map;for(let e of t){let t=P(e.shape),r=n.get(t)??[];r.push(e),n.set(t,r)}if(t.length===0)return{groups:n,mode:`raw`,operations:t};if(n.size===1){let e=t[0]?.shape;return e!==void 0&&F(e)?{groups:n,mode:`shared`,operations:t,shared:e}:{groups:n,mode:`raw`,operations:t}}let r=[...n.entries()].filter(([,e])=>{let t=e[0];return t!==void 0&&F(t.shape)});if(r.length===0)return{groups:n,mode:`raw`,operations:t};if(r.length===1){let e=r[0],i=e?.[1][0];if(e!==void 0&&e[1].length===t.length&&i!==void 0)return{groups:n,mode:`shared`,operations:t,shared:i.shape}}return{groups:n,mode:`mixed`,operations:t}}function qe(e){if(e.shared!==void 0)return e.shared;if(e.mode!==`mixed`)return;let t,n=0;for(let r of e.groups.values()){let e=r[0];e===void 0||!F(e.shape)||e.shape.fields.some(e=>e.name===`data`)&&r.length>n&&(n=r.length,t=e.shape)}return t}function Je(e){let t=e.match(/export\s+interface\s+BaseResponse\s*<[^>]*>\s*\{([\s\S]*?)\}/);if(t===null){let t=e.match(/export\s+interface\s+BaseResponse\s*\{([\s\S]*?)\}/);return t===null?void 0:Ye(t[1])}return Ye(t[1])}function Ye(e){let t=[],n=/^\s*(\w+)(\?)?:\s*([^;]+);/gm,r;for(;(r=n.exec(e))!==null;){let[,e,n,i]=r;e!==void 0&&i!==void 0&&t.push({kind:i.trim().replace(/\s+/g,` `),name:e,required:n===void 0})}return t.sort((e,t)=>e.name.localeCompare(t.name)),{fields:t,sourcePath:`models.ts`}}function Xe(e,t){let n=[],r=new Map(e.fields.filter(e=>e.name!==`data`).map(e=>[e.name,e])),i=new Map(t.fields.filter(e=>e.name!==`data`&&e.name!==`T`).map(e=>[e.name,e]));for(let[e,t]of r.entries()){let r=i.get(e);if(r===void 0){n.push({field:e,issue:`missing`,spec:t});continue}t.required!==r.required&&n.push({field:e,issue:`required-changed`,spec:t,user:r}),t.kind!==r.kind&&e!==`data`&&n.push({field:e,issue:`type-changed`,spec:t,user:r})}for(let[e,t]of i.entries())r.has(e)||n.push({field:e,issue:`extra`,user:t});return n}function Ze(e,t,n){return t===void 0?`unknown`:e.kind===`generic`?n:e.kind}function Qe(e,t=`T`){let n=[`export interface BaseResponse<${t}> {`];for(let r of e.fields){let i=e.schema.properties?.[r.name];if(i!==void 0&&n.push(...k({...i.schema.description===void 0?{}:{description:i.schema.description},...i.schema.deprecated===!0?{deprecated:!0}:{}},` `)),r.name===`data`){n.push(` data?: ${t};`);continue}let a=r.required?``:`?`,o=Ze(r,i,t);n.push(` ${r.name}${a}: ${o};`)}return n.push(`}`),n.join(`
|
|
10
|
+
`)}const $e=[`get`,`post`,`put`,`patch`,`delete`];function et(e){return v(e)?e.filter(_):[]}function tt(e){return e.split(`/`).at(-1)??e}function nt(e){return e.replace(/^\//,``).replace(/\{([^}]+)\}/g,`[$1]`)}function I(e){return typeof e.description==`string`?e.description:void 0}function rt(e,t){let n=I(e);return n!==void 0&&(t.description=n),e.deprecated===!0&&(t.deprecated=!0),t}function L(e){return _(e)?rt(e,it(e)):{kind:`unknown`}}function it(e){if(typeof e.$ref==`string`)return{kind:`ref`,ref:tt(e.$ref)};if(v(e.oneOf)&&e.oneOf.length>0)return{kind:`oneOf`,oneOf:e.oneOf.map(L)};if(v(e.anyOf)&&e.anyOf.length>0)return{anyOf:e.anyOf.map(L),kind:`anyOf`};if(v(e.allOf)&&e.allOf.length>0)return{allOf:e.allOf.map(L),kind:`allOf`};let t=typeof e.type==`string`?e.type:void 0,n=e.nullable===!0;if(t===`array`){let t={kind:`array`};return e.items!==void 0&&(t.items=L(e.items)),n&&(t.nullable=!0),t}if(t===`object`||t===void 0&&(_(e.properties)||e.additionalProperties!==void 0))return at(e,n);if(t===`integer`||t===`number`){let t={kind:`number`};return typeof e.format==`string`&&(t.format=e.format),n&&(t.nullable=!0),Array.isArray(e.enum)&&(t.enum=x(e.enum)),typeof e[`x-map-key-ref`]==`string`&&(t[`x-map-key-ref`]=e[`x-map-key-ref`]),t}if(t===`string`){let t={kind:`string`};return typeof e.format==`string`&&(t.format=e.format),n&&(t.nullable=!0),Array.isArray(e.enum)&&(t.enum=x(e.enum)),typeof e[`x-map-key-ref`]==`string`&&(t[`x-map-key-ref`]=e[`x-map-key-ref`]),t}if(t===`boolean`){let e={kind:`boolean`};return n&&(e.nullable=!0),e}return t===`null`?{kind:`null`}:{kind:`unknown`}}function at(e,t){let n={kind:`object`};if(t&&(n.nullable=!0),_(e.properties)){let t=v(e.required)?e.required.filter(e=>typeof e==`string`):[],r={};for(let[n,i]of Object.entries(e.properties))r[n]={required:t.includes(n),schema:L(i)};n.properties=r,t.length>0&&(n.required=t)}return e.additionalProperties!==void 0&&(n.additionalProperties=typeof e.additionalProperties==`boolean`?e.additionalProperties:L(e.additionalProperties)),typeof e[`x-map-key-ref`]==`string`&&(n[`x-map-key-ref`]=e[`x-map-key-ref`]),n}function ot(e){if(_(e.schema))return L(e.schema);let t={};return e.enum!==void 0&&(t.enum=e.enum),typeof e.format==`string`&&(t.format=e.format),typeof e.type==`string`&&(t.type=e.type),L(t)}function st(e,t){let n={},r=_(e.definitions)?e.definitions:{};for(let[e,t]of Object.entries(r))n[e]=L(t);let i=lt(e,`swagger2`,t);return{components:{schemas:n},key:``,paths:i}}function ct(e,t){let n={},r=_(e.components)?e.components:{},i=_(r.schemas)?r.schemas:{};for(let[e,t]of Object.entries(i))n[e]=L(t);let a=lt(e,`openapi3`,t);return{components:{schemas:n},key:``,paths:a}}function lt(e,t,n){let r=[],i=e.paths;if(!_(i))return r;for(let[e,a]of Object.entries(i)){if(n.pathPrefix!==void 0&&!e.startsWith(n.pathPrefix)||n.ignorePaths?.includes(e)||!_(a))continue;let i=et(a.parameters),o=[];for(let e of $e){let n=a[e];if(!_(n))continue;let r=pt(e,n,i,t);o.push(r)}o.length>0&&r.push({cleanPath:nt(e),operations:o,path:e})}return r}function ut(e,t){let n=new Map;for(let t of e)typeof t.name==`string`&&n.set(t.name,t);for(let e of t)typeof e.name==`string`&&n.set(e.name,e);return[...n.values()]}function dt(e){return _(e.schema)?L(e.schema):{kind:`unknown`}}function ft(e,t){return t===`openapi3`?dt(e):ot(e)}function pt(e,t,n,r){let i=ut(n,et(t.parameters)),a=[],o=[];for(let e of i)if(typeof e.name==`string`){if(e.in===`path`){let t={name:e.name,schema:ft(e,r)},n=I(e);n!==void 0&&(t.description=n),e.deprecated===!0&&(t.deprecated=!0),a.push(t)}else if(e.in===`query`){let t={name:e.name,required:e.required===!0,schema:ft(e,r)},n=I(e);n!==void 0&&(t.description=n),e.deprecated===!0&&(t.deprecated=!0),o.push(t)}}let s=r===`swagger2`?mt(i):ht(t),c={method:e,pathParams:a,queryParams:o,responses:gt(t,r)};typeof t.operationId==`string`&&(c.operationId=t.operationId),typeof t.summary==`string`&&(c.summary=t.summary);let l=I(t);return l!==void 0&&(c.description=l),t.deprecated===!0&&(c.deprecated=!0),s!==void 0&&(c.requestBody=s),c}function mt(e){let t=e.find(e=>e.in===`body`);if(t===void 0)return;let n=_(t.schema)?L(t.schema):{kind:`unknown`},r={required:t.required===!0,schema:n},i=I(t);return i!==void 0&&(r.description=i),r}function ht(e){if(!_(e.requestBody))return;let t=e.requestBody,n=_(t.content)?t.content:{},r=_(n[`application/json`])?n[`application/json`]:{},i=_(r.schema)?L(r.schema):{kind:`unknown`},a={required:t.required===!0,schema:i},o=I(t);return o!==void 0&&(a.description=o),a}function gt(e,t){let n=[];if(!_(e.responses))return n;for(let[r,i]of Object.entries(e.responses)){if(!_(i)){n.push({statusCode:r});continue}let e={statusCode:r},a=I(i);if(a!==void 0&&(e.description=a),t===`swagger2`)_(i.schema)&&(e.schema=L(i.schema));else{let t=_(i.content)?i.content:{},n=_(t[`application/json`])?t[`application/json`]:{};_(n.schema)&&(e.schema=L(n.schema))}n.push(e)}return n}function _t(e,t){if(!_(e))return{components:{schemas:{}},key:``,paths:[]};let n={};return t.pathPrefix!==void 0&&(n.pathPrefix=t.pathPrefix),t.ignorePaths!==void 0&&(n.ignorePaths=t.ignorePaths),e.swagger===`2.0`?st(e,n):typeof e.openapi==`string`&&e.openapi.startsWith(`3.`)?ct(e,n):{components:{schemas:{}},key:``,paths:[]}}function vt(){return process.env.NO_COLOR===void 0&&process.stdout.isTTY===!0}function R(e,t){return vt()?e(t):t}function z(e){return R(d.bold,e)}function B(e){return R(d.red,e)}function V(e){return R(d.dim,e)}function H(e){return R(d.cyan,e)}function U(e){return R(d.yellow,e)}function yt(e){return R(d.white,e)}var W=class extends Error{cycle;schemaPath;sourceKey;constructor(e,t,n){super(bt(e,t,n)),this.name=`RecursiveRefError`,this.cycle=t,this.schemaPath=n,this.sourceKey=e}};function bt(e,t,n){return[z(B(`typeforge: recursive schema reference in source "${e}"`)),``,z(`Cycle:`),` ${t.join(` → `)}`,``,z(`At:`),V(` ${n}`),``,z(`Fix:`),` • Add a known-type override in known-types.ts for this shape, or`,` • Simplify the OpenAPI schema to remove the circular reference`,H(` • typeforge generate --source ${e} --spec <path>`)].join(`
|
|
11
|
+
`)}function xt(e,t){let n=e.kind===`ref`?j(e,t):e;return n.kind===`object`?n:void 0}function St(e){return e.slice().toSorted((e,t)=>e.localeCompare(t))}function Ct(e,t,n){let r=xt(e,t);if(r?.properties===void 0)return!1;let i=St(Object.keys(r.properties)),a=St(n);return i.length===a.length&&i.every((e,t)=>e===a[t])}function wt(e,t,n){let r=xt(e,t);if(r?.properties===void 0)return!1;let i=Object.keys(r.properties);if(n.maxPropertyCount!==void 0&&i.length>n.maxPropertyCount||n.exactProperties!==void 0&&!Ct(e,t,n.exactProperties))return!1;if(n.requireProperties!==void 0){for(let e of n.requireProperties)if(!(e in r.properties))return!1}if(n.excludeProperties!==void 0){for(let e of n.excludeProperties)if(e in r.properties)return!1}return n.exactProperties!==void 0||n.requireProperties!==void 0}function G(e){if(e===void 0)return;let t=[...e.matchAll(/["'`]([^"'`]+)["'`]/g)].map(e=>e[1]);return t.length>0?t:void 0}function Tt(e){let t=[],n=e.matchAll(/\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}/g);for(let e of n){let n=e[1];if(n===void 0||!n.includes(`typeName`))continue;let r=n.match(/name:\s*["'`]([^"'`]+)["'`]/)?.[1],i=n.match(/typeName:\s*["'`]([^"'`]+)["'`]/)?.[1];if(r===void 0||i===void 0)continue;let a={name:r,typeName:i},o=n.match(/importPath:\s*(null|["'`]([^"'`]*)["'`])/)?.[2];n.includes(`importPath: null`)?a.importPath=null:o!==void 0&&(a.importPath=o);let s=G(n.match(/exactProperties:\s*\[([\s\S]*?)\]/)?.[1]);s!==void 0&&(a.exactProperties=s);let c=G(n.match(/requireProperties:\s*\[([\s\S]*?)\]/)?.[1]);c!==void 0&&(a.requireProperties=c);let l=G(n.match(/excludeProperties:\s*\[([\s\S]*?)\]/)?.[1]);l!==void 0&&(a.excludeProperties=l);let u=n.match(/maxPropertyCount:\s*(\d+)/)?.[1];u!==void 0&&(a.maxPropertyCount=Number.parseInt(u,10)),t.push(a)}return t}function Et(t,r){let i=u(t,r,`known-types.ts`);return e(i)?Tt(n(i,`utf8`)).map(e=>({importPath:e.importPath??null,matcher:(t,n)=>wt(t,n,e),name:e.name,typeName:e.typeName})):[]}function Dt(e,t){return Et(e,t)}function Ot(e,t,n){for(let r of n)if(r.matcher(e,t))return{importPath:r.importPath,rule:r,typeName:r.typeName}}function K(e){return` `.repeat(e)}function kt(e){return typeof e==`string`?JSON.stringify(e):typeof e==`number`||typeof e==`boolean`?String(e):e===null?`null`:`unknown`}function At(e){return[...new Set(e.map(kt))].join(` | `)}function q(e,t){return t.nullable===!0?`${e} | null`:e}function jt(e){return decodeURIComponent(e.replace(/~1/g,`/`).replace(/~0/g,`~`))}function Mt(e,t){if(Array.isArray(e)){let n=Number(t);return!Number.isInteger(n)||n<0||n>=e.length?void 0:e[n]}if(_(e)&&t in e)return e[t]}function Nt(e,t){if(!t.startsWith(`#/`))return;let n=e;for(let e of t.slice(2).split(`/`).map(jt))if(n=n===void 0?void 0:Mt(n,e),n===void 0)return;return L(n)}function Pt(e,t){let n=e[`x-map-key-ref`];if(n===void 0)return`string`;if(t.rawSpec!==void 0){let e=Nt(t.rawSpec,n);if(e!==void 0)return X(e,{...t,depth:(t.depth??0)+1})}let r=n.split(`/`).pop();return r!==void 0&&t.components[r]!==void 0?X(t.components[r],{...t,depth:(t.depth??0)+1}):`string`}function Ft(e,t){let n=[...e.refStack??[],t];throw new W(e.sourceKey??`unknown`,n,e.schemaPath??t)}function J(e,t){let n=e.schemaPath??`schema`;return{...e,schemaPath:`${n}.${t}`}}function Y(e,t){let n={},r=new Set,i=e;for(;i!==void 0&&(n.description===void 0&&i.description?.trim().length&&(n.description=i.description),i.deprecated===!0&&(n.deprecated=!0),!(i.kind!==`ref`||i.ref===void 0||r.has(i.ref)));)r.add(i.ref),i=t[i.ref];return n}function X(e,t){let n=t.depth??0,r=t.maxDepth??50;if(n>r)throw new W(t.sourceKey??`unknown`,t.refStack??[],`${t.schemaPath??`schema`} (max depth ${r} exceeded)`);let i={...t,depth:n+1},a=t.knownTypes??[];if(a.length>0){let n=Ot(e,t.components,a);if(n!==void 0)return t.knownTypeImports!==void 0&&!t.knownTypeImports.has(n.typeName)&&t.knownTypeImports.set(n.typeName,n.importPath),q(n.typeName,e)}if(e.enum!==void 0&&e.enum.length>0)return q(At(e.enum),e);if(e.kind===`ref`){let n=Be(e);if(n===void 0)return`unknown`;let r=t.visitedRefs??new Set,a=t.refStack??[];return r.has(n)&&Ft(t,n),X(j(e,t.components),{...i,refStack:[...a,n],visitedRefs:new Set([...r,n])})}switch(e.kind){case`string`:return q(`string`,e);case`number`:return q(`number`,e);case`boolean`:return q(`boolean`,e);case`null`:return`null`;case`unknown`:return`unknown`;case`array`:{let t=e.items===void 0?`unknown`:X(e.items,J(i,`[]`));return q(t===`TiptapDocument`?`TiptapDocument`:`${t.includes(` | `)?`(${t})`:t}[]`,e)}case`object`:{if(e.properties===void 0)return e.additionalProperties===!0?q(`Record<string, unknown>`,e):typeof e.additionalProperties==`object`&&e.additionalProperties!==null?q(`Record<${t.resolveMapKeyRefs!==!1&&e[`x-map-key-ref`]!==void 0?Pt(e,t):`string`}, ${X(e.additionalProperties,J(i,`value`))}>`,e):q(`Record<string, unknown>`,e);let r=[`{`];for(let[a,o]of Object.entries(e.properties)){let e=o.required?``:`?`,s=X(o.schema,J(i,a));r.push(...k(Y(o.schema,t.components),K(n+1))),r.push(`${K(n+1)}${a}${e}: ${s};`)}return r.push(`${K(n)}}`),q(r.join(`
|
|
12
|
+
`),e)}case`oneOf`:case`anyOf`:{let t=e[e.kind];if(t===void 0||t.length===0)return`unknown`;let n=t.map(e=>X(e,i)),r=n.filter(e=>e!==`Record<string, unknown>`);return q((r.length>0?r:n).join(` | `),e)}case`allOf`:{let t=e.allOf;return t===void 0||t.length===0?`unknown`:q(t.map(e=>X(e,i)).join(` & `),e)}default:return`unknown`}}function Z(e,t,n){let r={components:e.source.components.schemas,knownTypeImports:n,knownTypes:e.knownTypes??[],maxDepth:e.maxRenderDepth??50,resolveMapKeyRefs:e.resolveMapKeyRefs!==!1,schemaPath:t};return e.sourceKey!==void 0&&(r.sourceKey=e.sourceKey),e.rawSpec!==void 0&&(r.rawSpec=e.rawSpec),r}function It(e){let t=[],n=new Map;for(let[t,r]of e.entries()){let e=n.get(r)??[];e.push(t),n.set(r,e)}for(let[e,r]of n.entries())e!==null&&t.push(`import type { ${r.join(`, `)} } from "${e}";`);return t}function Q(e,t){let n={},r=e.find(e=>e!==void 0&&e.trim().length>0);return r!==void 0&&(n.description=r),t&&(n.deprecated=!0),n}function $(e,t){let n=k(t);return n.length===0?e:[...n,e].join(`
|
|
13
|
+
`)}function Lt(e,t,n,r){if(t.queryParams.length===0)return;let i=n.queryExtends,a=i?.page??`page`,o=i?.limit??`limit`,s=i?.sortBy??`sortBy`,c=i?.sortOrder??`sortOrder`,l=t.queryParams.some(e=>e.name===a),u=t.queryParams.some(e=>e.name===o),d=t.queryParams.find(e=>e.name===s),f=t.queryParams.some(e=>e.name===c),p=l&&u,m=d!==void 0&&f,h=new Set([p?a:void 0,p?o:void 0,m?s:void 0,m?c:void 0].filter(e=>e!==void 0)),g=t.queryParams.filter(e=>!h.has(e.name)),_=[];if(m&&d!==void 0&&d.schema.enum!==void 0&&d.schema.enum.length>0&&i?.sortTypeName!==void 0){let e=[...new Set(d.schema.enum.map(e=>JSON.stringify(e)))].join(` | `);_.push(`${i.sortTypeName}<${e}>`),i.sortImportPath!==void 0&&r.set(i.sortTypeName,i.sortImportPath)}if(p&&i?.paginationTypeName!==void 0&&(_.push(i.paginationTypeName),i.paginationImportPath!==void 0&&r.set(i.paginationTypeName,i.paginationImportPath)),_.length>0&&g.length===0)return $(`export type ${e}Params = ${_.join(` & `)};`,Q([],t.deprecated===!0));let v=[];v.push(...k(Q([],t.deprecated===!0))),_.length>0?v.push(`export interface ${e}Params extends ${_.join(`, `)} {`):v.push(`export interface ${e}Params {`);for(let t of g)Rt(t,v,n,r,e);return v.push(`}`),v.join(`
|
|
14
|
+
`)}function Rt(e,t,n,r,i){let a=e.required?``:`?`,o=X(e.schema,Z(n,`${i}Params.${e.name}`,r)),s=Y(e.schema,n.source.components.schemas);t.push(...k(Q([e.description,s.description],e.deprecated===!0||s.deprecated===!0),` `)),t.push(` ${e.name}${a}: ${o};`)}function zt(e,t,n,r){if(!Se(t)||t.requestBody===void 0)return;let i=X(t.requestBody.schema,Z(n,`${e}Body`,r)),a=Y(t.requestBody.schema,n.source.components.schemas),o=Q([t.requestBody.description,a.description],t.deprecated===!0||a.deprecated===!0);return i.startsWith(`{`)?$(`export interface ${e}Body ${i}`,o):$(`export type ${e}Body = ${i};`,o)}function Bt(e,t){return M(e,t)??e}function Vt(e,t,n,r,i,a){let o=we(t);if(o===void 0)return`export type ${e}Response = unknown;`;let s=Bt(o,n.source.components.schemas),c=s.kind===`object`&&s.properties?.data!==void 0?s.properties.data.schema:void 0,l=s.kind===`object`&&s.properties?.success!==void 0&&We(o,n.source.components.schemas);return n.unwrapResponseData===!0&&l?c===void 0?`export type ${e}Response = null;`:`export type ${e}Response = ${X(c,Z(n,`${e}Response.data`,i))};`:c===void 0?`export type ${e}Response = ${X(o,Z(n,`${e}Response`,i))};`:r===`shared`||r===`mixed`&&n.sharedEnvelope!==void 0&&He(o,n.source.components.schemas,n.sharedEnvelope)?`export type ${e}Response = import("${a}").BaseResponse<${X(c,Z(n,`${e}Response.data`,i))}> & Omit<${X(o,Z(n,`${e}Response`,i))}, "data">;`:`export type ${e}Response = ${X(o,Z(n,`${e}Response`,i))};`}function Ht(e,t,n,r,i,a){let o=we(t),s=o===void 0?t.responses.find(e=>e.statusCode.startsWith(`2`)):t.responses.find(e=>e.schema===o),c=o===void 0?{}:Y(o,n.source.components.schemas),l=Q([c.description,s?.description],t.deprecated===!0||c.deprecated===!0);return $(Vt(e,t,n,r,i,a),l)}function Ut(e){let t=[];for(let n of e.source.paths)for(let r of n.operations){let i=xe(n.cleanPath,r.method),a=new Map,o=[`// Auto-generated from OpenAPI spec`,`// Path: ${r.method.toUpperCase()} ${n.path}`,`// DO NOT EDIT - This file is automatically generated`,``],s=Lt(i,r,e,a);s!==void 0&&o.push(s,``);let c=zt(i,r,e,a);c!==void 0&&o.push(c,``);let l=de({fromAbsolutePath:`${e.typesDir}/${n.cleanPath}/${r.method.toUpperCase()}.d.ts`,toAbsolutePath:e.baseFile.replace(/\.d\.ts$/,``).replace(/\.ts$/,``),...e.tsconfigPaths===void 0?{}:{tsconfigPaths:e.tsconfigPaths}});o.push(Ht(i,r,e,e.envelopeMode,a,l));let u=It(a),d=[...u,...u.length>0?[``]:[],...o].join(`
|
|
15
|
+
`).trimEnd();t.push({content:`${d}\n`,relativePath:`${n.cleanPath}/${r.method.toUpperCase()}.d.ts`})}return t}function Wt(e){return[`// Auto-generated from OpenAPI spec`,`// DO NOT EDIT - This file is automatically generated`,``,Qe(e),``].join(`
|
|
16
|
+
`)}function Gt(e,t,n,r,i,a=[]){let o=[z(B(`typeforge: base response mismatch in source "${e}"`)),``];o.push(z(`Spec envelope:`));for(let e of t.fields)o.push(` ${e.name}${e.required?``:`?`}: ${e.kind}`);o.push(``),o.push(z(`Your ${n} BaseResponse:`)),o.push(r),o.push(``),o.push(z(`Conflicts:`));for(let e of i)e.issue===`missing`?o.push(U(` • ${e.field}: present in spec, missing in your type`)):e.issue===`extra`?o.push(U(` • ${e.field}: extra field in your type`)):e.issue===`type-changed`?o.push(U(` • ${e.field}: spec is ${e.spec?.kind}, your type is ${e.user?.kind}`)):o.push(U(` • ${e.field}: required/optional mismatch`));if(a.length>0){o.push(``),o.push(V(`Also not matching the spec envelope:`));for(let e of a.slice(0,3))o.push(V(` ${e.method} ${e.path}`))}return o.push(``),o.push(z(`Fix:`)),o.push(` • Update models.ts to match the spec, or`),o.push(H(` • typeforge generate --source ${e} --spec <path> --accept-base`)),o.join(`
|
|
17
|
+
`)}function Kt(e,t,n,r){let i=`${` `.repeat(e+1)}:${`${` `.repeat(Math.max(n-t,1))}|`}`;return r===void 0?i:`${i}\n${` `.repeat(e+n+3)}\`${V(`-- ${r}`)}`}function qt(e){return[V(` ,-[${e.file}:${e.line}:${e.column}]`),yt(`${String(e.line).padStart(4,` `)} | ${e.source}`),Kt(7+e.highlightStart,e.highlightStart,e.highlightEnd,e.label),V(" `----")].join(`
|
|
18
|
+
`)}function Jt(e){let t=[` ${(e.severity??`error`)===`error`?B(`×`):U(`!`)} ${z(`${e.code}`)}: ${e.message}`];return e.snippet!==void 0&&t.push(qt(e.snippet)),e.help!==void 0&&t.push(` ${V(`help:`)} ${e.help}`),t.join(`
|
|
19
|
+
`)}function Yt(e,t){return[z(e),...t.map(e=>` ${H(e)}`)].join(`
|
|
20
|
+
`)}async function Xt(e){let t;switch(e.kind){case`file`:t=u(e.path);break;case`local-override`:t=u(e.path);break;case`env`:{let n=process.env[e.varName];if(n===void 0)throw Error(`Environment variable ${e.varName} is not set`);t=u(n);break}}return y(await p(t,`utf8`))}function Zt(t,r){if(r.specFlag!==void 0)return{kind:`file`,path:r.specFlag};let i=`OPENAPI_SPEC_${t.toUpperCase().replace(/-/g,`_`)}`;if(process.env[i]!==void 0)return{kind:`env`,varName:i};if(r.sourceConfigSpec!==void 0)return{kind:`file`,path:r.sourceConfigSpec};let a=r.localOverridePath??`./typeforge.local.json`;if(e(a))try{let e=b(n(a,`utf8`))[t];if(typeof e==`string`)return{kind:`local-override`,path:e}}catch{}if(r.snapshotPath!==void 0&&e(r.snapshotPath))return{kind:`file`,path:r.snapshotPath};throw Error($t(t,i,r,a))}function Qt(t){return t===void 0?V(`not configured`):e(t)?V(`found at ${t}`):V(`not found at ${t}`)}function $t(t,n,r,i){let a=r.specFlag===void 0?V(`not provided`):r.specFlag,o=V(`not set`),s=r.sourceConfigSpec===void 0?V(`not set in source.ts`):r.sourceConfigSpec,c=e(i)?V(`found at ${i} (no entry for "${t}")`):V(`not found at ${i}`),{snapshotPath:l}=r,u=Qt(l),d=[` --spec flag: ${a}`,` ${n} env: ${o}`,` source.ts spec: ${s}`,` local override: ${c}`,` committed snapshot: ${u}`].join(`
|
|
21
|
+
`),f=[`typeforge generate --source ${t} --spec ./path/to/swagger.json`,`export ${n}=./path/to/swagger.json`];return[Jt({code:`typeforge/spec-not-found`,help:`Provide one of the resolution paths above, for example with --spec or an env var.`,message:`No OpenAPI spec found for source "${t}"`,severity:`error`}),``,z(`Tried:`),d,``,Yt(`Fix:`,f)].join(`
|
|
22
|
+
`)}async function en(e,t=!1){let n=[];for(let r of e){await f(o(r.path),{recursive:!0});let e;try{e=await p(r.path,`utf8`)}catch{e=void 0}e!==r.content&&(n.push(r.path),t||await m(r.path,r.content,`utf8`))}return{changed:n,written:t?0:n.length}}function tn(e,t){let n=D(e).apiRoot??`src/api`,r=ee(e,n,t),i=u(e,n,t),a=s(i,`generated`),c=r.functionsDir===void 0?s(a,`functions`):u(e,r.functionsDir),l=r.typesDir===void 0?s(a,`types`):u(e,r.typesDir);return{apiRoot:n,baseFile:r.typesDir===void 0?s(a,`base.ts`):s(o(l),`base.d.ts`),cwd:e,functionsDir:c,generatedDir:a,hasQueryScope:r.tanstackQuery===!0&&ne(e,n),httpMode:re(e,n),routesFile:s(a,`routes.ts`),snapshotPath:s(i,`spec.json`),sourceConfig:r,sourceDir:i,sourceKey:t,typesDir:l}}function nn(e,t,n){let r=Ke(t);if(r.mode!==`shared`||r.shared===void 0)return{mode:r.mode};let i=te(e.cwd,e.apiRoot);if(i===void 0)return{mode:r.mode};let a=Je(i);if(a===void 0)return{mode:r.mode};let o=Xe(r.shared,a);if(o.length===0||n)return{mode:r.mode};let s=a.fields.map(e=>` ${e.name}${e.required?``:`?`}: ${e.kind};`).join(`
|
|
23
|
+
`);return{error:Gt(e.sourceKey,r.shared,a.sourcePath,s,o),mode:r.mode}}function rn(t,r,i){let o=u(t,r,`models.ts`);if(!e(o))return;let s=n(o,`utf8`).replace(/export\s+interface\s+BaseResponse\s*<[^>]*>\s*\{[\s\S]*?\}/,i);a(o,s,`utf8`)}async function an(t){let r=t.cwd??process.cwd(),i=tn(r,t.sourceKey),a={snapshotPath:i.snapshotPath};t.specFlag!==void 0&&(a.specFlag=t.specFlag),i.sourceConfig.spec!==void 0&&(a.sourceConfigSpec=i.sourceConfig.spec);let o=await Xt(Zt(t.sourceKey,a)),c={};i.sourceConfig.ignorePaths!==void 0&&(c.ignorePaths=i.sourceConfig.ignorePaths),i.sourceConfig.pathPrefix!==void 0&&(c.pathPrefix=i.sourceConfig.pathPrefix);let l=_t(o,c);l.key=t.sourceKey;let u=nn(i,l,t.acceptBase===!0);if(u.error!==void 0)throw Error(u.error);let d=Ke(l),f=[],p=qe(d);p!==void 0&&(f.push({content:Wt(p),path:i.baseFile}),t.acceptBase===!0&&rn(r,i.apiRoot,Qe(p)));let m={baseFile:i.baseFile,envelopeMode:d.mode,knownTypes:Dt(r,i.apiRoot),source:l,sourceKey:t.sourceKey,typesDir:i.typesDir};i.sourceConfig.resolveMapKeyRefs!==void 0&&(m.resolveMapKeyRefs=i.sourceConfig.resolveMapKeyRefs),i.sourceConfig.unwrapResponseData!==void 0&&(m.unwrapResponseData=i.sourceConfig.unwrapResponseData),p!==void 0&&(m.sharedEnvelope=p);let h=oe(i.typesDir);h!==void 0&&(m.tsconfigPaths=h),i.sourceConfig.maxRenderDepth!==void 0&&(m.maxRenderDepth=i.sourceConfig.maxRenderDepth),i.sourceConfig.queryExtends!==void 0&&(m.queryExtends=i.sourceConfig.queryExtends),_(o)&&(m.rawSpec=o);let g=Ut(m);for(let e of g)f.push({content:e.content,path:s(i.typesDir,e.relativePath)});let v=i.sourceConfig.routeEnumName??`RouteTargets`,y={paths:l.paths,routeEnumName:v};i.sourceConfig.stripApiPrefix===!0&&(y.stripApiPrefix=!0);let b=Le(y),x=b;i.sourceConfig.generationMode===`merge`&&e(i.routesFile)&&(x=Re(n(i.routesFile,`utf8`),b,v,i.sourceConfig.pathPrefix)),f.push({content:x,path:i.routesFile}),f.push({content:Ne({hasQueryScope:i.hasQueryScope,httpMode:i.httpMode}),path:s(i.generatedDir,`runtime.ts`)});let S=oe(i.functionsDir),C={functionsDir:i.functionsDir,generatedDir:i.generatedDir,hasQueryScope:i.hasQueryScope,httpMode:i.httpMode,paths:l.paths,routeEnumName:v,typesDir:i.typesDir};i.sourceConfig.importBase===void 0?S!==void 0&&(C.tsconfigPaths=S):C.importBase=i.sourceConfig.importBase;let w=Ae(C);for(let e of w)f.push({content:e.content,path:s(i.functionsDir,e.relativePath)});return{changed:(await en(f,t.check===!0)).changed,check:t.check===!0,files:f.length,sourceKey:t.sourceKey}}function on(e){return e===`packages`?`packages/utils/src/api`:`src/api`}function sn(n,r){return e(n)?`skipped`:(t(s(n,`..`),{recursive:!0}),a(n,r,`utf8`),`created`)}function cn(n){let r=n.cwd??process.cwd(),i=n.layout??`monolith`,o=u(r,`typeforge.json`),c=D(r),l=e(o)?c.apiRoot??`src/api`:on(i),d=u(r,l),f=s(d,n.sourceKey),p=`import type { HTTPFetch, HTTPFetchConfig } from "@openmirai/typeforge/http";
|
|
24
|
+
|
|
25
|
+
export type { HTTPFetch, HTTPFetchConfig };
|
|
26
|
+
|
|
27
|
+
export const httpFetch: HTTPFetch = {
|
|
28
|
+
delete: async <TResponse>(
|
|
29
|
+
_route: string,
|
|
30
|
+
_config?: HTTPFetchConfig
|
|
31
|
+
): Promise<{ data: TResponse }> => {
|
|
32
|
+
throw new Error("Implement httpFetch.delete");
|
|
33
|
+
},
|
|
34
|
+
get: async <TResponse>(
|
|
35
|
+
_route: string,
|
|
36
|
+
_config?: HTTPFetchConfig
|
|
37
|
+
): Promise<{ data: TResponse }> => {
|
|
38
|
+
throw new Error("Implement httpFetch.get");
|
|
39
|
+
},
|
|
40
|
+
patch: async <TResponse, TBody = unknown>(
|
|
41
|
+
_route: string,
|
|
42
|
+
_body: TBody,
|
|
43
|
+
_config?: HTTPFetchConfig
|
|
44
|
+
): Promise<{ data: TResponse }> => {
|
|
45
|
+
throw new Error("Implement httpFetch.patch");
|
|
46
|
+
},
|
|
47
|
+
post: async <TResponse, TBody = unknown>(
|
|
48
|
+
_route: string,
|
|
49
|
+
_body: TBody,
|
|
50
|
+
_config?: HTTPFetchConfig
|
|
51
|
+
): Promise<{ data: TResponse }> => {
|
|
52
|
+
throw new Error("Implement httpFetch.post");
|
|
53
|
+
},
|
|
54
|
+
put: async <TResponse, TBody = unknown>(
|
|
55
|
+
_route: string,
|
|
56
|
+
_body: TBody,
|
|
57
|
+
_config?: HTTPFetchConfig
|
|
58
|
+
): Promise<{ data: TResponse }> => {
|
|
59
|
+
throw new Error("Implement httpFetch.put");
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
`;n.client===`axios`?p=`import axiosBase from "axios";
|
|
63
|
+
import { createAxiosAdapter } from "@openmirai/typeforge/adapters/axios";
|
|
64
|
+
|
|
65
|
+
const axios = axiosBase.create({
|
|
66
|
+
baseURL: process.env.NEXT_PUBLIC_API_URL,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
axios.interceptors.request.use(
|
|
70
|
+
async (config) => {
|
|
71
|
+
// Add auth headers, tracing, or Content-Type defaults here.
|
|
72
|
+
return config;
|
|
73
|
+
},
|
|
74
|
+
(error) => Promise.reject(error),
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
axios.interceptors.response.use(
|
|
78
|
+
(response) => response,
|
|
79
|
+
(error) => Promise.reject(error),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
export const httpFetch = createAxiosAdapter(axios);
|
|
83
|
+
export { axios };
|
|
84
|
+
export type { HTTPFetch, HTTPFetchConfig } from "@openmirai/typeforge/adapters/axios";
|
|
85
|
+
`:n.client===`fetch`&&(p=`import { createFetchAdapter } from "@openmirai/typeforge/adapters/fetch";
|
|
86
|
+
|
|
87
|
+
export const httpFetch = createFetchAdapter({
|
|
88
|
+
baseURL: process.env.NEXT_PUBLIC_API_URL,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
export type { HTTPFetch, HTTPFetchConfig } from "@openmirai/typeforge/adapters/fetch";
|
|
92
|
+
`);let m=[],h=[],g=s(d,`http.ts`);sn(g,p)===`created`?m.push(g):h.push(g);let _=s(f,`source.ts`);sn(_,`import { defineSourceConfig } from "@openmirai/typeforge";
|
|
93
|
+
|
|
94
|
+
export default defineSourceConfig({
|
|
95
|
+
// Path to the OpenAPI spec file, relative to the project root.
|
|
96
|
+
// Set this so \`typeforge generate --source <key>\` (or --all) works
|
|
97
|
+
// without a per-invocation --spec flag.
|
|
98
|
+
// spec: "./specs/acme.json",
|
|
99
|
+
pathPrefix: "/api/acme/v3",
|
|
100
|
+
stripApiPrefix: true,
|
|
101
|
+
routeEnumName: "RouteTargets",
|
|
102
|
+
generationMode: "authoritative",
|
|
103
|
+
naming: "path",
|
|
104
|
+
ignorePaths: [],
|
|
105
|
+
maxRenderDepth: 50,
|
|
106
|
+
resolveMapKeyRefs: true,
|
|
107
|
+
queryExtends: {
|
|
108
|
+
page: "page",
|
|
109
|
+
limit: "limit",
|
|
110
|
+
sortBy: "sortBy",
|
|
111
|
+
sortOrder: "sortOrder",
|
|
112
|
+
paginationTypeName: "OffsetLimitQuery",
|
|
113
|
+
paginationImportPath: "./pagination",
|
|
114
|
+
sortTypeName: "SortParams",
|
|
115
|
+
sortImportPath: "./pagination",
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
`)===`created`?m.push(_):h.push(_);let v=s(d,`known-types.ts`);sn(v,`/** Map OpenAPI object shapes to your own TypeScript types by property pattern. */
|
|
119
|
+
export const knownTypes = [
|
|
120
|
+
// {
|
|
121
|
+
// name: "BlobAsset",
|
|
122
|
+
// typeName: "BlobAsset",
|
|
123
|
+
// importPath: "./blob/types",
|
|
124
|
+
// exactProperties: ["id", "url", "file"],
|
|
125
|
+
// },
|
|
126
|
+
// {
|
|
127
|
+
// name: "TiptapNode",
|
|
128
|
+
// typeName: "TiptapNode",
|
|
129
|
+
// importPath: "./tiptap/types",
|
|
130
|
+
// requireProperties: ["type"],
|
|
131
|
+
// excludeProperties: ["courseCount"],
|
|
132
|
+
// },
|
|
133
|
+
];
|
|
134
|
+
`)===`created`?m.push(v):h.push(v);let y=u(r,`typeforge.json`);return e(y)||(a(y,`${JSON.stringify({apiRoot:l},null,2)}\n`,`utf8`),m.push(y)),t(s(f,`generated`),{recursive:!0}),{created:m,skipped:h}}export{Zt as a,W as c,Ke as d,Qe as f,D as g,ie as h,Xt as i,L as l,Je as m,tn as n,Dt as o,Xe as p,an as r,Ot as s,cn as t,_t as u};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmirai/typeforge",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Typeforge: headless OpenAPI to TypeScript codegen CLI and HTTPFetch runtime",
|
|
5
5
|
"homepage": "https://github.com/openmirai/typeforge#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"type": "module",
|
|
21
21
|
"sideEffects": false,
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
22
23
|
"exports": {
|
|
23
24
|
".": {
|
|
24
25
|
"types": "./dist/index.d.ts",
|
package/dist/init-UsJVICy2.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import{existsSync as e,mkdirSync as t,readFileSync as n,readdirSync as r,statSync as i,writeFileSync as a}from"node:fs";import{dirname as o,join as s,parse as c,relative as l,resolve as u}from"node:path";import d from"chalk";import{mkdir as f,readFile as p,writeFile as m}from"node:fs/promises";function h(e){return e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`}function g(e){return e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?!0:Array.isArray(e)?e.every(g):typeof e==`object`&&e?Object.values(e).every(g):!1}function _(e){return g(e)&&typeof e==`object`&&!!e&&!Array.isArray(e)}function v(e){return Array.isArray(e)&&e.every(g)}function y(e){let t=JSON.parse(e);if(!g(t))throw TypeError(`JSON text did not parse to a valid JSON value`);return t}function b(e){let t=y(e);if(!_(t))throw TypeError(`JSON text did not parse to a JSON object`);return t}function x(e){return v(e)?e.filter(h):[]}function S(t){if(!e(t))return{};try{let e=b(n(t,`utf8`)),r={};return typeof e.apiRoot==`string`&&(r.apiRoot=e.apiRoot),r}catch{return{}}}function C(t){if(!e(t))return{};try{let e=b(n(t,`utf8`)).typeforge;if(typeof e!=`object`||!e||Array.isArray(e))return{};let r={};return typeof e.apiRoot==`string`&&(r.apiRoot=e.apiRoot),r}catch{return{}}}function w(e){let t=e.match(/defineSourceConfig\s*(?:<[^>]*>)?\s*\(\s*\{([\s\S]*)\}\s*\)/);return t?.[1]===void 0?e:`{${t[1]}}`}function T(e){let t=w(e),n={},r=t.match(/pathPrefix:\s*["'`]([^"'`]+)["'`]/);r?.[1]!==void 0&&(n.pathPrefix=r[1]);let i=t.match(/functionsDir:\s*["'`]([^"'`]+)["'`]/);i?.[1]!==void 0&&(n.functionsDir=i[1]);let a=t.match(/typesDir:\s*["'`]([^"'`]+)["'`]/);a?.[1]!==void 0&&(n.typesDir=a[1]);let o=t.match(/ignorePaths:\s*\[([\s\S]*?)\]/);if(o?.[1]!==void 0){let e=[...o[1].matchAll(/["'`]([^"'`]+)["'`]/g)].map(e=>e[1]).filter(e=>e!==void 0);e.length>0&&(n.ignorePaths=e)}/stripApiPrefix:\s*true/.test(t)&&(n.stripApiPrefix=!0);let s=t.match(/routeEnumName:\s*["'`]([^"'`]+)["'`]/);s?.[1]!==void 0&&(n.routeEnumName=s[1]);let c=t.match(/generationMode:\s*["'`](authoritative|merge)["'`]/);(c?.[1]===`authoritative`||c?.[1]===`merge`)&&(n.generationMode=c[1]);let l=t.match(/naming:\s*["'`](path|operationId)["'`]/);(l?.[1]===`path`||l?.[1]===`operationId`)&&(n.naming=l[1]),/resolveMapKeyRefs:\s*false/.test(t)&&(n.resolveMapKeyRefs=!1),/unwrapResponseData:\s*true/.test(t)&&(n.unwrapResponseData=!0),/tanstackQuery:\s*true/.test(t)&&(n.tanstackQuery=!0);let u=t.match(/importBase:\s*["'`]([^"'`]+)["'`]/);u?.[1]!==void 0&&(n.importBase=u[1]);let d=t.match(/maxRenderDepth:\s*(\d+)/)?.[1];d!==void 0&&(n.maxRenderDepth=Number.parseInt(d,10));let f=E(t);f!==void 0&&(n.queryExtends=f);let p=t.match(/spec:\s*["'`]([^"'`]+)["'`]/);return p?.[1]!==void 0&&(n.spec=p[1]),n}function E(e){let t=e.match(/queryExtends:\s*\{([\s\S]*?)\}/)?.[1];if(t===void 0)return;let n={},r=e=>t.match(RegExp(`${e}:\\s*["'\`]([^"'\`]+)["'\`]`))?.[1],i=r(`page`),a=r(`limit`),o=r(`sortBy`),s=r(`sortOrder`),c=r(`paginationTypeName`),l=r(`paginationImportPath`),u=r(`sortTypeName`),d=r(`sortImportPath`);return i!==void 0&&(n.page=i),a!==void 0&&(n.limit=a),o!==void 0&&(n.sortBy=o),s!==void 0&&(n.sortOrder=s),c!==void 0&&(n.paginationTypeName=c),l!==void 0&&(n.paginationImportPath=l),u!==void 0&&(n.sortTypeName=u),d!==void 0&&(n.sortImportPath=d),Object.keys(n).length>0?n:void 0}function D(e){let t=S(u(e,`typeforge.json`)),n=C(u(e,`package.json`));return{apiRoot:t.apiRoot??n.apiRoot??`src/api`}}function ee(t,r,i){let a=u(t,r,i,`source.ts`);return e(a)?T(n(a,`utf8`)):{}}function te(t,r){let i=u(t,r,`models.ts`);if(e(i))return n(i,`utf8`)}function ne(t,n){return e(u(t,n,`query-scope.ts`))}function re(t,r){let i=u(t,r,`http.ts`);if(!e(i))return`injected`;let a=n(i,`utf8`);return/export\s+(const|function)\s+httpFetch\b/.test(a)||/export\s*\{[^}]*\bhttpFetch\b/.test(a)?`singleton`:`injected`}function ie(t,n){let a=u(t,n);return e(a)?r(a).filter(t=>{let n=s(a,t);return i(n).isDirectory()?e(s(n,`source.ts`)):!1}):[]}function ae(e){let t=``,n=0,r=e.length,i=!1;for(;n<r;){let a=e[n];if(i){t+=a,a===`\\`?(n++,n<r&&(t+=e[n])):a===`"`&&(i=!1),n++;continue}if(a===`"`){i=!0,t+=a,n++;continue}if(a===`/`&&e[n+1]===`/`){for(;n<r&&e[n]!==`
|
|
2
|
-
`;)n++;continue}if(a===`/`&&e[n+1]===`*`){for(n+=2;n<r&&(e[n]!==`*`||e[n+1]!==`/`);)n++;n+=2;continue}t+=a,n++}return t.replace(/,(\s*[}\]])/g,`$1`)}function oe(e){let t=u(e),n=c(t).root;for(;;){let e=se(t);if(e!==void 0)return e;if(t===n)return;t=o(t)}}function se(t){let r=u(t,`tsconfig.json`);if(e(r))try{let e=JSON.parse(ae(n(r,`utf8`)));if(typeof e!=`object`||!e||Array.isArray(e))return;let i=e.compilerOptions;if(typeof i!=`object`||!i||Array.isArray(i))return;let a=i,o=a.paths;if(typeof o!=`object`||!o||Array.isArray(o))return;let s=typeof a.baseUrl==`string`?a.baseUrl:`.`,c={};for(let[e,t]of Object.entries(o))Array.isArray(t)&&t.every(e=>typeof e==`string`)&&(c[e]=t);return Object.keys(c).length===0?void 0:{baseDir:t,paths:c,resolvedBaseUrl:u(t,s)}}catch{return}}function ce(e,t){for(let[n,r]of Object.entries(t.paths))for(let i of r)if(n.endsWith(`/*`)&&i.endsWith(`/*`)){let r=n.slice(0,-2),a=i.slice(0,-2),o=u(t.resolvedBaseUrl,a);if(e.startsWith(`${o}/`))return`${r}/${e.slice(o.length+1)}`;if(e===o)return r}else if(!n.includes(`*`)&&!i.includes(`*`)){let r=u(t.resolvedBaseUrl,i);if(O(e)===O(r))return n}}function O(e){return e.replace(/\.(d\.ts|ts|js)$/,``)}function k(e){return e.replace(/\.d\.ts$/,``).replace(/\.ts$/,``)}function le(e,t){let n=o(k(e)),r=k(t),i=l(n,r).replace(/\\/g,`/`);return i.startsWith(`.`)?i:`./${i}`}function A(e){let{fromAbsolutePath:t,toAbsolutePath:n,importBase:r,generatedDir:i,tsconfigPaths:a}=e;if(r!==void 0&&i!==void 0){let e=i.replace(/\/$/,``),t=k(n);if(t.startsWith(`${e}/`))return`${r}/${t.slice(e.length+1)}`;if(t===e)return r}let o=le(t,n);if(a!==void 0&&(o.match(/\.\.\//g)??[]).length>=3){let e=ce(n,a);if(e!==void 0)return e}return o}function ue(e,t,n){return s(e,t,`${n}.ts`)}function de(e){return e.split(`/`).filter(Boolean).map(e=>e.replace(/[{}]/g,``).replace(/[^a-zA-Z0-9]/g,`_`).toUpperCase()).join(`_`)}function fe(e,t=!1){return(t?e.replace(/^\/api\//,`/`):e).replace(/\{(\w+)\}/g,`:$1`)}function pe(e,t){let n=e.split(`/`).filter(Boolean).map(e=>e.replace(/[{[\]}/]/g,``).split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``)).join(``);return`${t===`get`?`get`:t}${n}`}function me(e){return e.kind===`array`?`array`:e.kind===`object`?`object`:e.kind===`ref`?`ref:${e.ref??`unknown`}`:e.kind===`oneOf`||e.kind===`anyOf`||e.kind===`allOf`?e.kind:e.enum!==void 0&&e.enum.length>0?`enum`:e.kind}function he(e){let t=Number.parseInt(e,10);return!Number.isNaN(t)&&t>=200&&t<300}function ge(e){return e.enum!==void 0&&e.enum.length>0?e.enum.map(e=>JSON.stringify(e)).join(` | `):e.kind===`number`?`number`:e.kind===`boolean`?`boolean`:`string`}function _e(e){let t=new Map;for(let n of e.operations)for(let e of n.pathParams)t.has(e.name)||t.set(e.name,e.schema);return t}function ve(e,t){let n=e.get(t);return n===void 0?`string`:ge(n)}function ye(e,t){let n=e.split(`/`).filter(Boolean).map(e=>e.replace(/[{[\]}/]/g,``).split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``)).join(``);return`${t.toUpperCase()}${n}`}function be(e){let t=e.requestBody?.schema;return t!==void 0&&!xe(t)}function xe(e){return e.kind===`unknown`?!0:e.kind===`object`?e.properties===void 0||Object.keys(e.properties).length===0:!1}function Se(e){return e.responses.find(e=>he(e.statusCode)&&e.schema!==void 0)?.schema}function Ce(e){return(e.match(/\{([^}]+)\}/g)??[]).map(e=>e.slice(1,-1))}function we(e,t,n){let r=e.replace(/\{([^}]+)\}/g,`[$1]`).split(`/`).filter(Boolean).join(`/`),i=ue(n.functionsDir,e,t.toUpperCase()),a=s(n.typesDir,r,t.toUpperCase());return A({fromAbsolutePath:i,generatedDir:n.generatedDir,toAbsolutePath:a,...n.importBase===void 0?{}:{importBase:n.importBase},...n.tsconfigPaths===void 0?{}:{tsconfigPaths:n.tsconfigPaths}})}function Te(e,t,n){let r=ue(t.functionsDir,e,n.toUpperCase()),i=s(t.generatedDir,`runtime`);return A({fromAbsolutePath:r,generatedDir:t.generatedDir,toAbsolutePath:i,...t.importBase===void 0?{}:{importBase:t.importBase},...t.tsconfigPaths===void 0?{}:{tsconfigPaths:t.tsconfigPaths}})}function Ee(e,t,n){let r=e.pathParams.find(e=>e.name===n);return ve(r===void 0?t:new Map([[n,r.schema]]),n)}function De(e){let t=[];for(let n of e.paths)for(let r of n.operations)t.push({content:Oe(n,r,e),relativePath:`${n.cleanPath}/${r.method.toUpperCase()}.ts`});return t}function Oe(e,t,n){let r=t.method,i=pe(e.cleanPath,r),a=de(e.path),o=ye(e.cleanPath,r),s=Ce(e.path),c=_e(e),l=`${ke(i)}Props`,u=`${ke(i)}QueryOptionsProps`,d=r!==`get`&&be(t),f=t.queryParams.length>0,p=we(e.cleanPath,r,n),m=Te(e.cleanPath,n,r),h=[`// Auto-generated from OpenAPI spec`,`// Path: ${r.toUpperCase()} ${e.path}`,`// DO NOT EDIT - This file is automatically generated`,``];h.push(`import type {`),h.push(` ${o}Response,`),f&&h.push(` ${o}Params,`),d&&h.push(` ${o}Body,`),h.push(`} from "${p}";`),h.push(``);let g=n.hasQueryScope?`, RouteTargets`:``;n.httpMode===`singleton`?h.push(`import { httpFetch, Routes${g}${n.hasQueryScope?`, getQueryScopeKey, queryOptions`:``} } from "${m}";`):h.push(`import { Routes${g}${n.hasQueryScope?`, getQueryScopeKey, queryOptions`:``} } from "${m}";`);let _=n.httpMode===`injected`?`HTTPFetch, `:``,v=f?``:`, QueryParams`;h.push(`import type { ${_}HTTPFetchConfig${v}${n.hasQueryScope?`, QueryScope`:``} } from "${m}";`),h.push(``),h.push(`export interface ${l} {`),n.httpMode===`injected`&&h.push(` http: HTTPFetch;`);for(let e of s)h.push(` ${e}: ${Ee(t,c,e)};`);if(f){let e=t.queryParams.some(e=>e.required)?``:`?`;h.push(` params${e}: ${o}Params;`)}d&&h.push(` body: ${o}Body;`);let y=f?`Omit<HTTPFetchConfig<${o}Params, ${o}Response>, "params" | "signal">`:`Omit<HTTPFetchConfig<QueryParams, ${o}Response>, "params" | "signal">`;h.push(` config?: ${y};`),h.push(` signal?: AbortSignal;`),h.push(`}`),h.push(``),r===`get`&&n.hasQueryScope&&(h.push(`export interface ${u} extends ${l} {`),h.push(` queryScope: QueryScope;`),h.push(`}`),h.push(``));let b=n.httpMode===`singleton`?`httpFetch`:`props.http`,x=[...n.httpMode===`injected`?[`http`]:[],...s.map(e=>e),...f?[`params`]:[],...d?[`body`]:[],`config`,`signal`];h.push(`export async function ${i}(props: ${l}): Promise<${o}Response> {`),x.length>0&&(h.push(` const { ${x.join(`, `)} } = props;`),h.push(``));let S=`Routes.${a}`;s.length>0&&(S=`Routes.${a}({ ${s.map(e=>`${e}`).join(`, `)} })`);let C=f?`{ ...config, params, signal }`:`{ ...config, signal }`,w=f?`<${o}Response, ${o}Params>`:`<${o}Response>`,T=`<${o}Response, ${d?`${o}Body`:`undefined`}${f?`, ${o}Params`:``}>`,E=d?`body`:`undefined`,D=f?`{ ...config, params, signal }`:`{ ...config, signal }`;switch(r){case`get`:h.push(` const { data } = await ${b}.get${w}(${S}, ${C});`);break;case`post`:h.push(` const { data } = await ${b}.post${T}(${S}, ${E}, ${D});`);break;case`put`:h.push(` const { data } = await ${b}.put${T}(${S}, ${E}, ${D});`);break;case`patch`:h.push(` const { data } = await ${b}.patch${T}(${S}, ${E}, ${D});`);break;case`delete`:{let e=C;d&&(e=f?`{ ...config, data: body, params, signal }`:`{ ...config, data: body, signal }`),h.push(` const { data } = await ${b}.delete${w}(${S}, ${e});`);break}}if(h.push(` return data;`),h.push(`}`),r===`get`&&n.hasQueryScope){let e=`${i}QueryOptions`;h.push(``),h.push(`export function ${e}(props: ${u}) {`),h.push(` const { ${f?`params, `:``}queryScope } = props;`),h.push(` return queryOptions({`),h.push(` queryKey: [RouteTargets.${a}, ...getQueryScopeKey(queryScope)${s.length>0?`, ${s.map(e=>`props.${e}`).join(`, `)}`:``}${f?`, params`:``}],`),h.push(` queryFn: ({ signal }) => ${i}({ ...props, signal }).then((data) => data),`),s.length>0&&h.push(` enabled: [${s.map(e=>`props.${e}`).join(`, `)}].every(Boolean),`),h.push(` });`),h.push(`}`)}return h.push(``),h.join(`
|
|
3
|
-
`)}function ke(e){return e.charAt(0).toUpperCase()+e.slice(1)}function Ae(e){let t=[`// Auto-generated from OpenAPI spec`,`// DO NOT EDIT - This file is automatically generated`,``,`export type { HTTPFetch, HTTPFetchConfig, QueryParams } from "../../http";`];return e.httpMode===`singleton`&&t.push(`export { httpFetch } from "../../http";`),t.push(`export { Routes, RouteTargets, buildRoute } from "./routes";`),e.hasQueryScope&&(t.push(`export type { QueryScope } from "../../query-scope";`),t.push(`export { getQueryScopeKey } from "../../query-scope";`),t.push(`export { queryOptions } from "@tanstack/react-query";`)),t.push(``),t.join(`
|
|
4
|
-
`)}function je(e){return(e.match(/\{([^}]+)\}/g)??[]).map(e=>e.slice(1,-1))}function Me(e){let t=new Set,n=[];for(let r of e.paths){let i=de(r.path);t.has(i)||(t.add(i),n.push({enumName:i,pathParamNames:je(r.path),pathParamSchemas:_e(r),routeValue:fe(r.path,e.stripApiPrefix===!0)}))}return n}function Ne(e){let t=[`export type RouteParams = {`];for(let n of e){if(n.pathParamNames.length===0){t.push(` ${n.enumName}: undefined;`);continue}t.push(` ${n.enumName}: {`);for(let e of n.pathParamNames)t.push(` ${e}: ${ve(n.pathParamSchemas,e)};`);t.push(` };`)}return t.push(`};`,`export type RouteKey = keyof RouteParams;`,``),t}function Pe(e){let t=Me(e),n=[`// Auto-generated from OpenAPI spec`,`// DO NOT EDIT - This file is automatically generated`,``,`import {`,` buildRouteFromHandlers,`,` createRouteHandlers,`,`} from "@openmirai/typeforge/routes";`,``,...Ne(t),`export enum ${e.routeEnumName} {`];for(let e of t)n.push(` ${e.enumName} = "${e.routeValue}",`);return n.push(`}`,``),e.routeEnumName!==`RouteTargets`&&(n.push(`export { ${e.routeEnumName} as RouteTargets };`),n.push(``)),n.push(`export const Routes = createRouteHandlers<RouteParams>(${e.routeEnumName});`),n.push(`export const buildRoute = buildRouteFromHandlers<RouteParams>(Routes);`,``),n.join(`
|
|
5
|
-
`)}function Fe(e,t,n,r){let i=j(e,n),a=j(t,n);if(r!==void 0)for(let[e,t]of i.entries())t.startsWith(r)&&!a.has(e)&&i.delete(e);return Pe({paths:[...new Map([...i,...a]).entries()].map(([,e])=>({cleanPath:e.replace(/:[^/]+/g,e=>`{${e.slice(1)}}`),operations:[],path:e.includes(`:`)?e.replace(/:([^/]+)/g,`{$1}`):e})),routeEnumName:n,stripApiPrefix:!1})}function j(e,t){let n=new Map,r=e.indexOf(`export enum ${t} {`);if(r===-1)return n;let i=e.slice(r),a=i.indexOf(`}`);if(a===-1)return n;let o=i.slice(0,a),s=/(\w+)\s*=\s*"([^"]+)"/g,c;for(;(c=s.exec(o))!==null;){let e=c[1],t=c[2];e!==void 0&&t!==void 0&&n.set(e,t)}return n}function M(e,t){if(e.kind!==`ref`||e.ref===void 0)return e;let n=e.ref.split(`/`).pop();return n===void 0||t[n]===void 0?{kind:`unknown`}:t[n]}function N(e,t,n=new Set){if(e.kind===`object`)return e;if(e.kind===`ref`){let r=Ie(e);if(r===void 0||n.has(r))return;let i=t[r];return i===void 0?void 0:N(i,t,new Set([...n,r]))}if(e.kind!==`allOf`||e.allOf===void 0)return;let r={},i=new Set;for(let a of e.allOf){let e=N(a,t,n);if(e?.properties===void 0)return;for(let[t,n]of Object.entries(e.properties)){let e=r[t];r[t]=e===void 0?{...n}:{required:e.required||n.required,schema:JSON.stringify(e.schema)===JSON.stringify(n.schema)?e.schema:{allOf:[e.schema,n.schema],kind:`allOf`}},n.required&&i.add(t)}}return{kind:`object`,properties:r,required:[...i]}}function Ie(e){if(e.kind===`ref`&&e.ref!==void 0)return e.ref.split(`/`).pop()}function Le(e,t){return e.kind===`ref`?M(e,t):e}function P(e,t){if(e===void 0)return;let n=N(e,t);if(n?.properties===void 0)return;let r=[];for(let[e,i]of Object.entries(n.properties))r.push({kind:e===`data`?`generic`:me(Le(i.schema,t)),name:e,required:i.required});return r.sort((e,t)=>e.name.localeCompare(t.name)),{fields:r,schema:n}}function F(e){return JSON.stringify(e.fields.map(e=>({kind:e.kind,name:e.name,required:e.required})))}function Re(e,t,n){let r=P(e,t);return r!==void 0&&F(r)===F(n)}const ze=new Set([`error`,`message`,`requestId`,`success`,`timestamp`]);function I(e){let t=new Set(e.fields.map(e=>e.name));return t.has(`data`)?!0:t.has(`success`)?[...t].every(e=>ze.has(e)):!1}function Be(e,t){let n=P(e,t);return n!==void 0&&I(n)}function Ve(e){let t=[];for(let n of e.paths)for(let r of n.operations){let i=r.responses.find(e=>he(e.statusCode)&&e.schema!==void 0);if(i?.schema===void 0)continue;let a=P(i.schema,e.components.schemas);a!==void 0&&t.push({method:r.method.toUpperCase(),path:n.path,shape:a})}return t}function L(e){let t=Ve(e),n=new Map;for(let e of t){let t=F(e.shape),r=n.get(t)??[];r.push(e),n.set(t,r)}if(t.length===0)return{groups:n,mode:`raw`,operations:t};if(n.size===1){let e=t[0]?.shape;return e!==void 0&&I(e)?{groups:n,mode:`shared`,operations:t,shared:e}:{groups:n,mode:`raw`,operations:t}}let r=[...n.entries()].filter(([,e])=>{let t=e[0];return t!==void 0&&I(t.shape)});if(r.length===0)return{groups:n,mode:`raw`,operations:t};if(r.length===1){let e=r[0],i=e?.[1][0];if(e!==void 0&&e[1].length===t.length&&i!==void 0)return{groups:n,mode:`shared`,operations:t,shared:i.shape}}return{groups:n,mode:`mixed`,operations:t}}function He(e){if(e.shared!==void 0)return e.shared;if(e.mode!==`mixed`)return;let t,n=0;for(let r of e.groups.values()){let e=r[0];e===void 0||!I(e.shape)||e.shape.fields.some(e=>e.name===`data`)&&r.length>n&&(n=r.length,t=e.shape)}return t}function Ue(e){let t=e.match(/export\s+interface\s+BaseResponse\s*<[^>]*>\s*\{([\s\S]*?)\}/);if(t===null){let t=e.match(/export\s+interface\s+BaseResponse\s*\{([\s\S]*?)\}/);return t===null?void 0:We(t[1])}return We(t[1])}function We(e){let t=[],n=/^\s*(\w+)(\?)?:\s*([^;]+);/gm,r;for(;(r=n.exec(e))!==null;){let[,e,n,i]=r;e!==void 0&&i!==void 0&&t.push({kind:i.trim().replace(/\s+/g,` `),name:e,required:n===void 0})}return t.sort((e,t)=>e.name.localeCompare(t.name)),{fields:t,sourcePath:`models.ts`}}function Ge(e,t){let n=[],r=new Map(e.fields.filter(e=>e.name!==`data`).map(e=>[e.name,e])),i=new Map(t.fields.filter(e=>e.name!==`data`&&e.name!==`T`).map(e=>[e.name,e]));for(let[e,t]of r.entries()){let r=i.get(e);if(r===void 0){n.push({field:e,issue:`missing`,spec:t});continue}t.required!==r.required&&n.push({field:e,issue:`required-changed`,spec:t,user:r}),t.kind!==r.kind&&e!==`data`&&n.push({field:e,issue:`type-changed`,spec:t,user:r})}for(let[e,t]of i.entries())r.has(e)||n.push({field:e,issue:`extra`,user:t});return n}function Ke(e,t,n){return t===void 0?`unknown`:e.kind===`generic`?n:e.kind}function R(e,t=`T`){let n=[`export interface BaseResponse<${t}> {`];for(let r of e.fields){if(r.name===`data`){n.push(` data?: ${t};`);continue}let i=r.required?``:`?`,a=e.schema.properties?.[r.name],o=Ke(r,a,t);n.push(` ${r.name}${i}: ${o};`)}return n.push(`}`),n.join(`
|
|
6
|
-
`)}const qe=[`get`,`post`,`put`,`patch`,`delete`];function Je(e){return v(e)?e.filter(_):[]}function Ye(e){return e.split(`/`).at(-1)??e}function Xe(e){return e.replace(/^\//,``).replace(/\{([^}]+)\}/g,`[$1]`)}function z(e){if(!_(e))return{kind:`unknown`};if(typeof e.$ref==`string`)return{kind:`ref`,ref:Ye(e.$ref)};if(v(e.oneOf)&&e.oneOf.length>0)return{kind:`oneOf`,oneOf:e.oneOf.map(z)};if(v(e.anyOf)&&e.anyOf.length>0)return{anyOf:e.anyOf.map(z),kind:`anyOf`};if(v(e.allOf)&&e.allOf.length>0)return{allOf:e.allOf.map(z),kind:`allOf`};let t=typeof e.type==`string`?e.type:void 0,n=e.nullable===!0;if(t===`array`){let t={kind:`array`};return e.items!==void 0&&(t.items=z(e.items)),n&&(t.nullable=!0),t}if(t===`object`||t===void 0&&(_(e.properties)||e.additionalProperties!==void 0))return Ze(e,n);if(t===`integer`||t===`number`){let t={kind:`number`};return typeof e.format==`string`&&(t.format=e.format),n&&(t.nullable=!0),Array.isArray(e.enum)&&(t.enum=x(e.enum)),typeof e[`x-map-key-ref`]==`string`&&(t[`x-map-key-ref`]=e[`x-map-key-ref`]),t}if(t===`string`){let t={kind:`string`};return typeof e.format==`string`&&(t.format=e.format),n&&(t.nullable=!0),Array.isArray(e.enum)&&(t.enum=x(e.enum)),typeof e[`x-map-key-ref`]==`string`&&(t[`x-map-key-ref`]=e[`x-map-key-ref`]),t}if(t===`boolean`){let e={kind:`boolean`};return n&&(e.nullable=!0),e}return t===`null`?{kind:`null`}:{kind:`unknown`}}function Ze(e,t){let n={kind:`object`};if(t&&(n.nullable=!0),_(e.properties)){let t=v(e.required)?e.required.filter(e=>typeof e==`string`):[],r={};for(let[n,i]of Object.entries(e.properties))r[n]={required:t.includes(n),schema:z(i)};n.properties=r,t.length>0&&(n.required=t)}return e.additionalProperties!==void 0&&(n.additionalProperties=typeof e.additionalProperties==`boolean`?e.additionalProperties:z(e.additionalProperties)),typeof e[`x-map-key-ref`]==`string`&&(n[`x-map-key-ref`]=e[`x-map-key-ref`]),n}function Qe(e){if(_(e.schema))return z(e.schema);let t={};return e.enum!==void 0&&(t.enum=e.enum),typeof e.format==`string`&&(t.format=e.format),typeof e.type==`string`&&(t.type=e.type),z(t)}function $e(e,t){let n={},r=_(e.definitions)?e.definitions:{};for(let[e,t]of Object.entries(r))n[e]=z(t);let i=tt(e,`swagger2`,t);return{components:{schemas:n},key:``,paths:i}}function et(e,t){let n={},r=_(e.components)?e.components:{},i=_(r.schemas)?r.schemas:{};for(let[e,t]of Object.entries(i))n[e]=z(t);let a=tt(e,`openapi3`,t);return{components:{schemas:n},key:``,paths:a}}function tt(e,t,n){let r=[],i=e.paths;if(!_(i))return r;for(let[e,a]of Object.entries(i)){if(n.pathPrefix!==void 0&&!e.startsWith(n.pathPrefix)||n.ignorePaths?.includes(e)||!_(a))continue;let i=Je(a.parameters),o=[];for(let e of qe){let n=a[e];if(!_(n))continue;let r=at(e,n,i,t);o.push(r)}o.length>0&&r.push({cleanPath:Xe(e),operations:o,path:e})}return r}function nt(e,t){let n=new Map;for(let t of e)typeof t.name==`string`&&n.set(t.name,t);for(let e of t)typeof e.name==`string`&&n.set(e.name,e);return[...n.values()]}function rt(e){return _(e.schema)?z(e.schema):{kind:`unknown`}}function it(e,t){return t===`openapi3`?rt(e):Qe(e)}function at(e,t,n,r){let i=nt(n,Je(t.parameters)),a=[],o=[];for(let e of i)typeof e.name==`string`&&(e.in===`path`?a.push({name:e.name,schema:it(e,r)}):e.in===`query`&&o.push({name:e.name,required:e.required===!0,schema:it(e,r)}));let s=r===`swagger2`?ot(i):st(t),c={method:e,pathParams:a,queryParams:o,responses:ct(t,r)};return typeof t.operationId==`string`&&(c.operationId=t.operationId),s!==void 0&&(c.requestBody=s),c}function ot(e){let t=e.find(e=>e.in===`body`);if(t===void 0)return;let n=_(t.schema)?z(t.schema):{kind:`unknown`};return{required:t.required===!0,schema:n}}function st(e){if(!_(e.requestBody))return;let t=e.requestBody,n=_(t.content)?t.content:{},r=_(n[`application/json`])?n[`application/json`]:{},i=_(r.schema)?z(r.schema):{kind:`unknown`};return{required:t.required===!0,schema:i}}function ct(e,t){let n=[];if(!_(e.responses))return n;for(let[r,i]of Object.entries(e.responses)){if(!_(i)){n.push({statusCode:r});continue}let e={statusCode:r};if(t===`swagger2`)_(i.schema)&&(e.schema=z(i.schema));else{let t=_(i.content)?i.content:{},n=_(t[`application/json`])?t[`application/json`]:{};_(n.schema)&&(e.schema=z(n.schema))}n.push(e)}return n}function lt(e,t){if(!_(e))return{components:{schemas:{}},key:``,paths:[]};let n={};return t.pathPrefix!==void 0&&(n.pathPrefix=t.pathPrefix),t.ignorePaths!==void 0&&(n.ignorePaths=t.ignorePaths),e.swagger===`2.0`?$e(e,n):typeof e.openapi==`string`&&e.openapi.startsWith(`3.`)?et(e,n):{components:{schemas:{}},key:``,paths:[]}}function ut(){return process.env.NO_COLOR===void 0&&process.stdout.isTTY===!0}function B(e,t){return ut()?e(t):t}function V(e){return B(d.bold,e)}function H(e){return B(d.red,e)}function U(e){return B(d.dim,e)}function W(e){return B(d.cyan,e)}function G(e){return B(d.yellow,e)}function dt(e){return B(d.white,e)}var K=class extends Error{cycle;schemaPath;sourceKey;constructor(e,t,n){super(ft(e,t,n)),this.name=`RecursiveRefError`,this.cycle=t,this.schemaPath=n,this.sourceKey=e}};function ft(e,t,n){return[V(H(`typeforge: recursive schema reference in source "${e}"`)),``,V(`Cycle:`),` ${t.join(` → `)}`,``,V(`At:`),U(` ${n}`),``,V(`Fix:`),` • Add a known-type override in known-types.ts for this shape, or`,` • Simplify the OpenAPI schema to remove the circular reference`,W(` • typeforge generate --source ${e} --spec <path>`)].join(`
|
|
7
|
-
`)}function pt(e,t){let n=e.kind===`ref`?M(e,t):e;return n.kind===`object`?n:void 0}function mt(e){return e.slice().toSorted((e,t)=>e.localeCompare(t))}function ht(e,t,n){let r=pt(e,t);if(r?.properties===void 0)return!1;let i=mt(Object.keys(r.properties)),a=mt(n);return i.length===a.length&&i.every((e,t)=>e===a[t])}function gt(e,t,n){let r=pt(e,t);if(r?.properties===void 0)return!1;let i=Object.keys(r.properties);if(n.maxPropertyCount!==void 0&&i.length>n.maxPropertyCount||n.exactProperties!==void 0&&!ht(e,t,n.exactProperties))return!1;if(n.requireProperties!==void 0){for(let e of n.requireProperties)if(!(e in r.properties))return!1}if(n.excludeProperties!==void 0){for(let e of n.excludeProperties)if(e in r.properties)return!1}return n.exactProperties!==void 0||n.requireProperties!==void 0}function q(e){if(e===void 0)return;let t=[...e.matchAll(/["'`]([^"'`]+)["'`]/g)].map(e=>e[1]);return t.length>0?t:void 0}function _t(e){let t=[],n=e.matchAll(/\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}/g);for(let e of n){let n=e[1];if(n===void 0||!n.includes(`typeName`))continue;let r=n.match(/name:\s*["'`]([^"'`]+)["'`]/)?.[1],i=n.match(/typeName:\s*["'`]([^"'`]+)["'`]/)?.[1];if(r===void 0||i===void 0)continue;let a={name:r,typeName:i},o=n.match(/importPath:\s*(null|["'`]([^"'`]*)["'`])/)?.[2];n.includes(`importPath: null`)?a.importPath=null:o!==void 0&&(a.importPath=o);let s=q(n.match(/exactProperties:\s*\[([\s\S]*?)\]/)?.[1]);s!==void 0&&(a.exactProperties=s);let c=q(n.match(/requireProperties:\s*\[([\s\S]*?)\]/)?.[1]);c!==void 0&&(a.requireProperties=c);let l=q(n.match(/excludeProperties:\s*\[([\s\S]*?)\]/)?.[1]);l!==void 0&&(a.excludeProperties=l);let u=n.match(/maxPropertyCount:\s*(\d+)/)?.[1];u!==void 0&&(a.maxPropertyCount=Number.parseInt(u,10)),t.push(a)}return t}function vt(t,r){let i=u(t,r,`known-types.ts`);return e(i)?_t(n(i,`utf8`)).map(e=>({importPath:e.importPath??null,matcher:(t,n)=>gt(t,n,e),name:e.name,typeName:e.typeName})):[]}function yt(e,t){return vt(e,t)}function bt(e,t,n){for(let r of n)if(r.matcher(e,t))return{importPath:r.importPath,rule:r,typeName:r.typeName}}function xt(e){return` `.repeat(e)}function St(e){return typeof e==`string`?JSON.stringify(e):typeof e==`number`||typeof e==`boolean`?String(e):e===null?`null`:`unknown`}function Ct(e){return[...new Set(e.map(St))].join(` | `)}function J(e,t){return t.nullable===!0?`${e} | null`:e}function wt(e){return decodeURIComponent(e.replace(/~1/g,`/`).replace(/~0/g,`~`))}function Tt(e,t){if(Array.isArray(e)){let n=Number(t);return!Number.isInteger(n)||n<0||n>=e.length?void 0:e[n]}if(_(e)&&t in e)return e[t]}function Et(e,t){if(!t.startsWith(`#/`))return;let n=e;for(let e of t.slice(2).split(`/`).map(wt))if(n=n===void 0?void 0:Tt(n,e),n===void 0)return;return z(n)}function Dt(e,t){let n=e[`x-map-key-ref`];if(n===void 0)return`string`;if(t.rawSpec!==void 0){let e=Et(t.rawSpec,n);if(e!==void 0)return X(e,{...t,depth:(t.depth??0)+1})}let r=n.split(`/`).pop();return r!==void 0&&t.components[r]!==void 0?X(t.components[r],{...t,depth:(t.depth??0)+1}):`string`}function Ot(e,t){let n=[...e.refStack??[],t];throw new K(e.sourceKey??`unknown`,n,e.schemaPath??t)}function Y(e,t){let n=e.schemaPath??`schema`;return{...e,schemaPath:`${n}.${t}`}}function X(e,t){let n=t.depth??0,r=t.maxDepth??50;if(n>r)throw new K(t.sourceKey??`unknown`,t.refStack??[],`${t.schemaPath??`schema`} (max depth ${r} exceeded)`);let i={...t,depth:n+1},a=t.knownTypes??[];if(a.length>0){let n=bt(e,t.components,a);if(n!==void 0)return t.knownTypeImports!==void 0&&!t.knownTypeImports.has(n.typeName)&&t.knownTypeImports.set(n.typeName,n.importPath),J(n.typeName,e)}if(e.enum!==void 0&&e.enum.length>0)return J(Ct(e.enum),e);if(e.kind===`ref`){let n=Ie(e);if(n===void 0)return`unknown`;let r=t.visitedRefs??new Set,a=t.refStack??[];return r.has(n)&&Ot(t,n),X(M(e,t.components),{...i,refStack:[...a,n],visitedRefs:new Set([...r,n])})}switch(e.kind){case`string`:return J(`string`,e);case`number`:return J(`number`,e);case`boolean`:return J(`boolean`,e);case`null`:return`null`;case`unknown`:return`unknown`;case`array`:{let t=e.items===void 0?`unknown`:X(e.items,Y(i,`[]`));return J(t===`TiptapDocument`?`TiptapDocument`:`${t.includes(` | `)?`(${t})`:t}[]`,e)}case`object`:{if(e.properties===void 0)return e.additionalProperties===!0?J(`Record<string, unknown>`,e):typeof e.additionalProperties==`object`&&e.additionalProperties!==null?J(`Record<${t.resolveMapKeyRefs!==!1&&e[`x-map-key-ref`]!==void 0?Dt(e,t):`string`}, ${X(e.additionalProperties,Y(i,`value`))}>`,e):J(`Record<string, unknown>`,e);let r=[`{`];for(let[t,a]of Object.entries(e.properties)){let e=a.required?``:`?`,o=X(a.schema,Y(i,t));r.push(`${xt(n+1)}${t}${e}: ${o};`)}return r.push(`${xt(n)}}`),J(r.join(`
|
|
8
|
-
`),e)}case`oneOf`:case`anyOf`:{let t=e[e.kind];if(t===void 0||t.length===0)return`unknown`;let n=t.map(e=>X(e,i)),r=n.filter(e=>e!==`Record<string, unknown>`);return J((r.length>0?r:n).join(` | `),e)}case`allOf`:{let t=e.allOf;return t===void 0||t.length===0?`unknown`:J(t.map(e=>X(e,i)).join(` & `),e)}default:return`unknown`}}function Z(e,t,n){let r={components:e.source.components.schemas,knownTypeImports:n,knownTypes:e.knownTypes??[],maxDepth:e.maxRenderDepth??50,resolveMapKeyRefs:e.resolveMapKeyRefs!==!1,schemaPath:t};return e.sourceKey!==void 0&&(r.sourceKey=e.sourceKey),e.rawSpec!==void 0&&(r.rawSpec=e.rawSpec),r}function kt(e){let t=[],n=new Map;for(let[t,r]of e.entries()){let e=n.get(r)??[];e.push(t),n.set(r,e)}for(let[e,r]of n.entries())e!==null&&t.push(`import type { ${r.join(`, `)} } from "${e}";`);return t}function At(e,t,n,r){if(t.queryParams.length===0)return;let i=n.queryExtends,a=i?.page??`page`,o=i?.limit??`limit`,s=i?.sortBy??`sortBy`,c=i?.sortOrder??`sortOrder`,l=t.queryParams.some(e=>e.name===a),u=t.queryParams.some(e=>e.name===o),d=t.queryParams.find(e=>e.name===s),f=t.queryParams.some(e=>e.name===c),p=l&&u,m=d!==void 0&&f,h=new Set([p?a:void 0,p?o:void 0,m?s:void 0,m?c:void 0].filter(e=>e!==void 0)),g=t.queryParams.filter(e=>!h.has(e.name)),_=[];if(m&&d!==void 0&&d.schema.enum!==void 0&&d.schema.enum.length>0&&i?.sortTypeName!==void 0){let e=[...new Set(d.schema.enum.map(e=>JSON.stringify(e)))].join(` | `);_.push(`${i.sortTypeName}<${e}>`),i.sortImportPath!==void 0&&r.set(i.sortTypeName,i.sortImportPath)}if(p&&i?.paginationTypeName!==void 0&&(_.push(i.paginationTypeName),i.paginationImportPath!==void 0&&r.set(i.paginationTypeName,i.paginationImportPath)),_.length>0&&g.length===0)return`export type ${e}Params = ${_.join(` & `)};`;let v=[];_.length>0?v.push(`export interface ${e}Params extends ${_.join(`, `)} {`):v.push(`export interface ${e}Params {`);for(let t of g)jt(t,v,n,r,e);return v.push(`}`),v.join(`
|
|
9
|
-
`)}function jt(e,t,n,r,i){let a=e.required?``:`?`,o=X(e.schema,Z(n,`${i}Params.${e.name}`,r));t.push(` ${e.name}${a}: ${o};`)}function Mt(e,t,n,r){if(!be(t)||t.requestBody===void 0)return;let i=X(t.requestBody.schema,Z(n,`${e}Body`,r));return i.startsWith(`{`)?`export interface ${e}Body ${i}`:`export type ${e}Body = ${i};`}function Nt(e,t){return N(e,t)??e}function Pt(e,t,n,r,i,a){let o=Se(t);if(o===void 0)return`export type ${e}Response = unknown;`;let s=Nt(o,n.source.components.schemas),c=s.kind===`object`&&s.properties?.data!==void 0?s.properties.data.schema:void 0,l=s.kind===`object`&&s.properties?.success!==void 0&&Be(o,n.source.components.schemas);return n.unwrapResponseData===!0&&l?c===void 0?`export type ${e}Response = null;`:`export type ${e}Response = ${X(c,Z(n,`${e}Response.data`,i))};`:c===void 0?`export type ${e}Response = ${X(o,Z(n,`${e}Response`,i))};`:r===`shared`||r===`mixed`&&n.sharedEnvelope!==void 0&&Re(o,n.source.components.schemas,n.sharedEnvelope)?`export type ${e}Response = import("${a}").BaseResponse<${X(c,Z(n,`${e}Response.data`,i))}> & Omit<${X(o,Z(n,`${e}Response`,i))}, "data">;`:`export type ${e}Response = ${X(o,Z(n,`${e}Response`,i))};`}function Ft(e){let t=[];for(let n of e.source.paths)for(let r of n.operations){let i=ye(n.cleanPath,r.method),a=new Map,o=[`// Auto-generated from OpenAPI spec`,`// Path: ${r.method.toUpperCase()} ${n.path}`,`// DO NOT EDIT - This file is automatically generated`,``],s=At(i,r,e,a);s!==void 0&&o.push(s,``);let c=Mt(i,r,e,a);c!==void 0&&o.push(c,``);let l=A({fromAbsolutePath:`${e.typesDir}/${n.cleanPath}/${r.method.toUpperCase()}.d.ts`,toAbsolutePath:e.baseFile.replace(/\.d\.ts$/,``).replace(/\.ts$/,``),...e.tsconfigPaths===void 0?{}:{tsconfigPaths:e.tsconfigPaths}});o.push(Pt(i,r,e,e.envelopeMode,a,l));let u=kt(a),d=[...u,...u.length>0?[``]:[],...o].join(`
|
|
10
|
-
`).trimEnd();t.push({content:`${d}\n`,relativePath:`${n.cleanPath}/${r.method.toUpperCase()}.d.ts`})}return t}function It(e){return[`// Auto-generated from OpenAPI spec`,`// DO NOT EDIT - This file is automatically generated`,``,R(e),``].join(`
|
|
11
|
-
`)}function Lt(e,t,n,r,i,a=[]){let o=[V(H(`typeforge: base response mismatch in source "${e}"`)),``];o.push(V(`Spec envelope:`));for(let e of t.fields)o.push(` ${e.name}${e.required?``:`?`}: ${e.kind}`);o.push(``),o.push(V(`Your ${n} BaseResponse:`)),o.push(r),o.push(``),o.push(V(`Conflicts:`));for(let e of i)e.issue===`missing`?o.push(G(` • ${e.field}: present in spec, missing in your type`)):e.issue===`extra`?o.push(G(` • ${e.field}: extra field in your type`)):e.issue===`type-changed`?o.push(G(` • ${e.field}: spec is ${e.spec?.kind}, your type is ${e.user?.kind}`)):o.push(G(` • ${e.field}: required/optional mismatch`));if(a.length>0){o.push(``),o.push(U(`Also not matching the spec envelope:`));for(let e of a.slice(0,3))o.push(U(` ${e.method} ${e.path}`))}return o.push(``),o.push(V(`Fix:`)),o.push(` • Update models.ts to match the spec, or`),o.push(W(` • typeforge generate --source ${e} --spec <path> --accept-base`)),o.join(`
|
|
12
|
-
`)}function Rt(e,t,n,r){let i=`${` `.repeat(e+1)}:${`${` `.repeat(Math.max(n-t,1))}|`}`;return r===void 0?i:`${i}\n${` `.repeat(e+n+3)}\`${U(`-- ${r}`)}`}function zt(e){return[U(` ,-[${e.file}:${e.line}:${e.column}]`),dt(`${String(e.line).padStart(4,` `)} | ${e.source}`),Rt(7+e.highlightStart,e.highlightStart,e.highlightEnd,e.label),U(" `----")].join(`
|
|
13
|
-
`)}function Bt(e){let t=[` ${(e.severity??`error`)===`error`?H(`×`):G(`!`)} ${V(`${e.code}`)}: ${e.message}`];return e.snippet!==void 0&&t.push(zt(e.snippet)),e.help!==void 0&&t.push(` ${U(`help:`)} ${e.help}`),t.join(`
|
|
14
|
-
`)}function Vt(e,t){return[V(e),...t.map(e=>` ${W(e)}`)].join(`
|
|
15
|
-
`)}async function Q(e){let t;switch(e.kind){case`file`:t=u(e.path);break;case`local-override`:t=u(e.path);break;case`env`:{let n=process.env[e.varName];if(n===void 0)throw Error(`Environment variable ${e.varName} is not set`);t=u(n);break}}return y(await p(t,`utf8`))}function Ht(t,r){if(r.specFlag!==void 0)return{kind:`file`,path:r.specFlag};let i=`OPENAPI_SPEC_${t.toUpperCase().replace(/-/g,`_`)}`;if(process.env[i]!==void 0)return{kind:`env`,varName:i};if(r.sourceConfigSpec!==void 0)return{kind:`file`,path:r.sourceConfigSpec};let a=r.localOverridePath??`./typeforge.local.json`;if(e(a))try{let e=b(n(a,`utf8`))[t];if(typeof e==`string`)return{kind:`local-override`,path:e}}catch{}if(r.snapshotPath!==void 0&&e(r.snapshotPath))return{kind:`file`,path:r.snapshotPath};throw Error(Wt(t,i,r,a))}function Ut(t){return t===void 0?U(`not configured`):e(t)?U(`found at ${t}`):U(`not found at ${t}`)}function Wt(t,n,r,i){let a=r.specFlag===void 0?U(`not provided`):r.specFlag,o=U(`not set`),s=r.sourceConfigSpec===void 0?U(`not set in source.ts`):r.sourceConfigSpec,c=e(i)?U(`found at ${i} (no entry for "${t}")`):U(`not found at ${i}`),{snapshotPath:l}=r,u=Ut(l),d=[` --spec flag: ${a}`,` ${n} env: ${o}`,` source.ts spec: ${s}`,` local override: ${c}`,` committed snapshot: ${u}`].join(`
|
|
16
|
-
`),f=[`typeforge generate --source ${t} --spec ./path/to/swagger.json`,`export ${n}=./path/to/swagger.json`];return[Bt({code:`typeforge/spec-not-found`,help:`Provide one of the resolution paths above, for example with --spec or an env var.`,message:`No OpenAPI spec found for source "${t}"`,severity:`error`}),``,V(`Tried:`),d,``,Vt(`Fix:`,f)].join(`
|
|
17
|
-
`)}async function Gt(e,t=!1){let n=[];for(let r of e){await f(o(r.path),{recursive:!0});let e;try{e=await p(r.path,`utf8`)}catch{e=void 0}e!==r.content&&(n.push(r.path),t||await m(r.path,r.content,`utf8`))}return{changed:n,written:t?0:n.length}}function Kt(e,t){let n=D(e).apiRoot??`src/api`,r=ee(e,n,t),i=u(e,n,t),a=s(i,`generated`),c=r.functionsDir===void 0?s(a,`functions`):u(e,r.functionsDir),l=r.typesDir===void 0?s(a,`types`):u(e,r.typesDir);return{apiRoot:n,baseFile:r.typesDir===void 0?s(a,`base.ts`):s(o(l),`base.d.ts`),cwd:e,functionsDir:c,generatedDir:a,hasQueryScope:r.tanstackQuery===!0&&ne(e,n),httpMode:re(e,n),routesFile:s(a,`routes.ts`),snapshotPath:s(i,`spec.json`),sourceConfig:r,sourceDir:i,sourceKey:t,typesDir:l}}function qt(e,t,n){let r=L(t);if(r.mode!==`shared`||r.shared===void 0)return{mode:r.mode};let i=te(e.cwd,e.apiRoot);if(i===void 0)return{mode:r.mode};let a=Ue(i);if(a===void 0)return{mode:r.mode};let o=Ge(r.shared,a);if(o.length===0||n)return{mode:r.mode};let s=a.fields.map(e=>` ${e.name}${e.required?``:`?`}: ${e.kind};`).join(`
|
|
18
|
-
`);return{error:Lt(e.sourceKey,r.shared,a.sourcePath,s,o),mode:r.mode}}function Jt(t,r,i){let o=u(t,r,`models.ts`);if(!e(o))return;let s=n(o,`utf8`).replace(/export\s+interface\s+BaseResponse\s*<[^>]*>\s*\{[\s\S]*?\}/,i);a(o,s,`utf8`)}async function Yt(t){let r=t.cwd??process.cwd(),i=Kt(r,t.sourceKey),a={snapshotPath:i.snapshotPath};t.specFlag!==void 0&&(a.specFlag=t.specFlag),i.sourceConfig.spec!==void 0&&(a.sourceConfigSpec=i.sourceConfig.spec);let o=await Q(Ht(t.sourceKey,a)),c={};i.sourceConfig.ignorePaths!==void 0&&(c.ignorePaths=i.sourceConfig.ignorePaths),i.sourceConfig.pathPrefix!==void 0&&(c.pathPrefix=i.sourceConfig.pathPrefix);let l=lt(o,c);l.key=t.sourceKey;let u=qt(i,l,t.acceptBase===!0);if(u.error!==void 0)throw Error(u.error);let d=L(l),f=[],p=He(d);p!==void 0&&(f.push({content:It(p),path:i.baseFile}),t.acceptBase===!0&&Jt(r,i.apiRoot,R(p)));let m={baseFile:i.baseFile,envelopeMode:d.mode,knownTypes:yt(r,i.apiRoot),source:l,sourceKey:t.sourceKey,typesDir:i.typesDir};i.sourceConfig.resolveMapKeyRefs!==void 0&&(m.resolveMapKeyRefs=i.sourceConfig.resolveMapKeyRefs),i.sourceConfig.unwrapResponseData!==void 0&&(m.unwrapResponseData=i.sourceConfig.unwrapResponseData),p!==void 0&&(m.sharedEnvelope=p);let h=oe(i.typesDir);h!==void 0&&(m.tsconfigPaths=h),i.sourceConfig.maxRenderDepth!==void 0&&(m.maxRenderDepth=i.sourceConfig.maxRenderDepth),i.sourceConfig.queryExtends!==void 0&&(m.queryExtends=i.sourceConfig.queryExtends),_(o)&&(m.rawSpec=o);let g=Ft(m);for(let e of g)f.push({content:e.content,path:s(i.typesDir,e.relativePath)});let v=i.sourceConfig.routeEnumName??`RouteTargets`,y={paths:l.paths,routeEnumName:v};i.sourceConfig.stripApiPrefix===!0&&(y.stripApiPrefix=!0);let b=Pe(y),x=b;i.sourceConfig.generationMode===`merge`&&e(i.routesFile)&&(x=Fe(n(i.routesFile,`utf8`),b,v,i.sourceConfig.pathPrefix)),f.push({content:x,path:i.routesFile}),f.push({content:Ae({hasQueryScope:i.hasQueryScope,httpMode:i.httpMode}),path:s(i.generatedDir,`runtime.ts`)});let S=oe(i.functionsDir),C={functionsDir:i.functionsDir,generatedDir:i.generatedDir,hasQueryScope:i.hasQueryScope,httpMode:i.httpMode,paths:l.paths,routeEnumName:v,typesDir:i.typesDir};i.sourceConfig.importBase===void 0?S!==void 0&&(C.tsconfigPaths=S):C.importBase=i.sourceConfig.importBase;let w=De(C);for(let e of w)f.push({content:e.content,path:s(i.functionsDir,e.relativePath)});return{changed:(await Gt(f,t.check===!0)).changed,check:t.check===!0,files:f.length,sourceKey:t.sourceKey}}function Xt(e){return e===`packages`?`packages/utils/src/api`:`src/api`}function $(n,r){return e(n)?`skipped`:(t(s(n,`..`),{recursive:!0}),a(n,r,`utf8`),`created`)}function Zt(n){let r=n.cwd??process.cwd(),i=n.layout??`monolith`,o=u(r,`typeforge.json`),c=D(r),l=e(o)?c.apiRoot??`src/api`:Xt(i),d=u(r,l),f=s(d,n.sourceKey),p=`import type { HTTPFetch, HTTPFetchConfig } from "@openmirai/typeforge/http";
|
|
19
|
-
|
|
20
|
-
export type { HTTPFetch, HTTPFetchConfig };
|
|
21
|
-
|
|
22
|
-
export const httpFetch: HTTPFetch = {
|
|
23
|
-
delete: async <TResponse>(
|
|
24
|
-
_route: string,
|
|
25
|
-
_config?: HTTPFetchConfig
|
|
26
|
-
): Promise<{ data: TResponse }> => {
|
|
27
|
-
throw new Error("Implement httpFetch.delete");
|
|
28
|
-
},
|
|
29
|
-
get: async <TResponse>(
|
|
30
|
-
_route: string,
|
|
31
|
-
_config?: HTTPFetchConfig
|
|
32
|
-
): Promise<{ data: TResponse }> => {
|
|
33
|
-
throw new Error("Implement httpFetch.get");
|
|
34
|
-
},
|
|
35
|
-
patch: async <TResponse, TBody = unknown>(
|
|
36
|
-
_route: string,
|
|
37
|
-
_body: TBody,
|
|
38
|
-
_config?: HTTPFetchConfig
|
|
39
|
-
): Promise<{ data: TResponse }> => {
|
|
40
|
-
throw new Error("Implement httpFetch.patch");
|
|
41
|
-
},
|
|
42
|
-
post: async <TResponse, TBody = unknown>(
|
|
43
|
-
_route: string,
|
|
44
|
-
_body: TBody,
|
|
45
|
-
_config?: HTTPFetchConfig
|
|
46
|
-
): Promise<{ data: TResponse }> => {
|
|
47
|
-
throw new Error("Implement httpFetch.post");
|
|
48
|
-
},
|
|
49
|
-
put: async <TResponse, TBody = unknown>(
|
|
50
|
-
_route: string,
|
|
51
|
-
_body: TBody,
|
|
52
|
-
_config?: HTTPFetchConfig
|
|
53
|
-
): Promise<{ data: TResponse }> => {
|
|
54
|
-
throw new Error("Implement httpFetch.put");
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
`;n.client===`axios`?p=`import axiosBase from "axios";
|
|
58
|
-
import { createAxiosAdapter } from "@openmirai/typeforge/adapters/axios";
|
|
59
|
-
|
|
60
|
-
const axios = axiosBase.create({
|
|
61
|
-
baseURL: process.env.NEXT_PUBLIC_API_URL,
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
axios.interceptors.request.use(
|
|
65
|
-
async (config) => {
|
|
66
|
-
// Add auth headers, tracing, or Content-Type defaults here.
|
|
67
|
-
return config;
|
|
68
|
-
},
|
|
69
|
-
(error) => Promise.reject(error),
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
axios.interceptors.response.use(
|
|
73
|
-
(response) => response,
|
|
74
|
-
(error) => Promise.reject(error),
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
export const httpFetch = createAxiosAdapter(axios);
|
|
78
|
-
export { axios };
|
|
79
|
-
export type { HTTPFetch, HTTPFetchConfig } from "@openmirai/typeforge/adapters/axios";
|
|
80
|
-
`:n.client===`fetch`&&(p=`import { createFetchAdapter } from "@openmirai/typeforge/adapters/fetch";
|
|
81
|
-
|
|
82
|
-
export const httpFetch = createFetchAdapter({
|
|
83
|
-
baseURL: process.env.NEXT_PUBLIC_API_URL,
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
export type { HTTPFetch, HTTPFetchConfig } from "@openmirai/typeforge/adapters/fetch";
|
|
87
|
-
`);let m=[],h=[],g=s(d,`http.ts`);$(g,p)===`created`?m.push(g):h.push(g);let _=s(f,`source.ts`);$(_,`import { defineSourceConfig } from "@openmirai/typeforge";
|
|
88
|
-
|
|
89
|
-
export default defineSourceConfig({
|
|
90
|
-
// Path to the OpenAPI spec file, relative to the project root.
|
|
91
|
-
// Set this so \`typeforge generate --source <key>\` (or --all) works
|
|
92
|
-
// without a per-invocation --spec flag.
|
|
93
|
-
// spec: "./specs/acme.json",
|
|
94
|
-
pathPrefix: "/api/acme/v3",
|
|
95
|
-
stripApiPrefix: true,
|
|
96
|
-
routeEnumName: "RouteTargets",
|
|
97
|
-
generationMode: "authoritative",
|
|
98
|
-
naming: "path",
|
|
99
|
-
ignorePaths: [],
|
|
100
|
-
maxRenderDepth: 50,
|
|
101
|
-
resolveMapKeyRefs: true,
|
|
102
|
-
queryExtends: {
|
|
103
|
-
page: "page",
|
|
104
|
-
limit: "limit",
|
|
105
|
-
sortBy: "sortBy",
|
|
106
|
-
sortOrder: "sortOrder",
|
|
107
|
-
paginationTypeName: "OffsetLimitQuery",
|
|
108
|
-
paginationImportPath: "./pagination",
|
|
109
|
-
sortTypeName: "SortParams",
|
|
110
|
-
sortImportPath: "./pagination",
|
|
111
|
-
},
|
|
112
|
-
});
|
|
113
|
-
`)===`created`?m.push(_):h.push(_);let v=s(d,`known-types.ts`);$(v,`/** Map OpenAPI object shapes to your own TypeScript types by property pattern. */
|
|
114
|
-
export const knownTypes = [
|
|
115
|
-
// {
|
|
116
|
-
// name: "BlobAsset",
|
|
117
|
-
// typeName: "BlobAsset",
|
|
118
|
-
// importPath: "./blob/types",
|
|
119
|
-
// exactProperties: ["id", "url", "file"],
|
|
120
|
-
// },
|
|
121
|
-
// {
|
|
122
|
-
// name: "TiptapNode",
|
|
123
|
-
// typeName: "TiptapNode",
|
|
124
|
-
// importPath: "./tiptap/types",
|
|
125
|
-
// requireProperties: ["type"],
|
|
126
|
-
// excludeProperties: ["courseCount"],
|
|
127
|
-
// },
|
|
128
|
-
];
|
|
129
|
-
`)===`created`?m.push(v):h.push(v);let y=u(r,`typeforge.json`);return e(y)||(a(y,`${JSON.stringify({apiRoot:l},null,2)}\n`,`utf8`),m.push(y)),t(s(f,`generated`),{recursive:!0}),{created:m,skipped:h}}export{Ht as a,K as c,L as d,R as f,D as g,ie as h,Q as i,z as l,Ue as m,Kt as n,yt as o,Ge as p,Yt as r,bt as s,Zt as t,lt as u};
|