@openmirai/typeforge 0.1.8 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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,48 +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
  }
141
- /** @deprecated Use `TypeforgeConfig`. */
142
- type OpenApiCodegenConfig = TypeforgeConfig;
227
+ /** Controls whether generated routes replace or preserve existing route entries. */
143
228
  type GenerationMode = "authoritative" | "merge";
229
+ /** Selects whether generated function names come from paths or OpenAPI operation IDs. */
144
230
  type NamingStrategy = "path" | "operationId";
231
+ /** Maps API query-parameter names to shared pagination and sorting types. */
145
232
  interface QueryExtendsConfig {
233
+ /**
234
+ * Name of the page-number query parameter.
235
+ * @defaultValue `"page"`
236
+ */
146
237
  page?: string;
238
+ /**
239
+ * Name of the page-size query parameter.
240
+ * @defaultValue `"limit"`
241
+ */
147
242
  limit?: string;
243
+ /**
244
+ * Name of the sort-field query parameter.
245
+ * @defaultValue `"sortBy"`
246
+ */
148
247
  sortBy?: string;
248
+ /**
249
+ * Name of the sort-direction query parameter.
250
+ * @defaultValue `"sortOrder"`
251
+ */
149
252
  sortOrder?: string;
253
+ /** Shared type that replaces matching page and limit properties. */
150
254
  paginationTypeName?: string;
255
+ /** Module specifier from which the shared pagination type is imported. */
151
256
  paginationImportPath?: string;
257
+ /** Generic shared type that replaces matching sort properties. */
152
258
  sortTypeName?: string;
259
+ /** Module specifier from which the shared sort type is imported. */
153
260
  sortImportPath?: string;
154
261
  }
262
+ /** Generation settings exported by an API source's `source.ts` file. */
155
263
  interface SourceConfig {
156
264
  /**
157
265
  * Project-relative directory for generated API function files.
@@ -163,13 +271,33 @@ interface SourceConfig {
163
271
  * Defaults to `<apiRoot>/<source>/generated/types`.
164
272
  */
165
273
  typesDir?: string;
274
+ /** Only generate operations whose paths start with this prefix. */
166
275
  pathPrefix?: string;
276
+ /** Exact OpenAPI paths to exclude from generation. */
167
277
  ignorePaths?: Array<string>;
278
+ /** Remove the leading `/api` segment from generated route names and values. */
168
279
  stripApiPrefix?: boolean;
280
+ /**
281
+ * Name of the generated route-target enum.
282
+ * @defaultValue `"RouteTargets"`
283
+ */
169
284
  routeEnumName?: string;
285
+ /** Whether route generation replaces the file or retains extra existing entries. */
170
286
  generationMode?: GenerationMode;
287
+ /**
288
+ * Strategy used to derive generated caller function names.
289
+ * @defaultValue `"path"`
290
+ */
171
291
  naming?: NamingStrategy;
292
+ /**
293
+ * Maximum schema expansion depth before recursive generation fails.
294
+ * @defaultValue `50`
295
+ */
172
296
  maxRenderDepth?: number;
297
+ /**
298
+ * Resolve `x-map-key-ref` extensions into typed `Record` keys.
299
+ * @defaultValue `true`
300
+ */
173
301
  resolveMapKeyRefs?: boolean;
174
302
  /**
175
303
  * Emit an envelope's `data` schema as the operation response type.
@@ -177,8 +305,9 @@ interface SourceConfig {
177
305
  * unwraps response envelopes before returning its `{ data }` value.
178
306
  */
179
307
  unwrapResponseData?: boolean;
308
+ /** Replace conventional pagination and sorting properties with shared local types. */
180
309
  queryExtends?: QueryExtendsConfig;
181
- /** When true, emit TanStack Query helpers for GET endpoints (requires query-scope.ts). */
310
+ /** Emit TanStack Query helpers for GET endpoints when `query-scope.ts` exists. */
182
311
  tanstackQuery?: boolean;
183
312
  /**
184
313
  * Explicit import base for generated function files pointing back to the
@@ -322,5 +451,4 @@ interface KnownTypeMatch {
322
451
  declare function loadKnownTypeRules(cwd: string, apiRoot: string): Array<KnownTypeRule>;
323
452
  declare function matchKnownType(schema: IRSchema, components: Record<string, IRSchema>, rules: Array<KnownTypeRule>): KnownTypeMatch | undefined;
324
453
  //#endregion
325
- export { type DeclarativeKnownTypeRule, type EnvelopeAnalysis, type EnvelopeMode, type EnvelopeShape, type GenerateOptions, type GenerateResult, type GenerationMode, type HTTPFetch, type HTTPFetchConfig, type HttpClient, type HttpMethod, type IR, type IROperation, type IRPath, type IRPathParam, type IRQueryParam, type IRRequestBody, type IRResponse, type IRSchema, type IRSchemaProperty, type IRSource, type InitOptions, type JsonArray, type JsonObject, type JsonPrimitive, type JsonValue, type KnownTypeRule, type NamingStrategy, type OpenApiCodegenConfig, type ProjectLayout, type QueryExtendsConfig, type QueryParams, RecursiveRefError, type SourceConfig, type SpecSource, type TypeforgeConfig, analyzeEnvelope, buildBaseResponseInterface, buildGenerateContext, defineSourceConfig, diffEnvelopeFields, generateForSource, initProject, loadKnownTypeRules, loadSpec, matchKnownType, parseSchema, parseSpec, parseUserBaseResponse, resolveSpecSource };
326
- //# sourceMappingURL=index.d.ts.map
454
+ export { type DeclarativeKnownTypeRule, type EnvelopeAnalysis, type EnvelopeMode, type EnvelopeShape, type GenerateOptions, type GenerateResult, type GenerationMode, type HTTPFetch, type HTTPFetchConfig, type HttpClient, type HttpMethod, type IR, type IROperation, type IRPath, type IRPathParam, type IRQueryParam, type IRRequestBody, type IRResponse, type IRSchema, type IRSchemaProperty, type IRSource, type InitOptions, type JsonArray, type JsonObject, type JsonPrimitive, type JsonValue, type KnownTypeRule, type NamingStrategy, type ProjectLayout, type QueryExtendsConfig, type QueryParams, RecursiveRefError, type SourceConfig, type SpecSource, type TypeforgeConfig, analyzeEnvelope, buildBaseResponseInterface, buildGenerateContext, defineSourceConfig, diffEnvelopeFields, generateForSource, initProject, loadKnownTypeRules, loadSpec, matchKnownType, parseSchema, parseSpec, parseUserBaseResponse, resolveSpecSource };
package/dist/index.js CHANGED
@@ -1,13 +1 @@
1
- import { a as resolveSpecSource, c as RecursiveRefError, d as analyzeEnvelope, f as buildBaseResponseInterface, i as loadSpec, l as parseSchema, m as parseUserBaseResponse, n as buildGenerateContext, o as loadKnownTypeRules, p as diffEnvelopeFields, r as generateForSource, s as matchKnownType, t as initProject, u as parseSpec } from "./init-BBNO0SYd.js";
2
- //#region src/config/define.ts
3
- /**
4
- * Identity helper for `source.ts`. Use it so the object is checked against
5
- * `SourceConfig` and editors can autocomplete fields.
6
- */
7
- function defineSourceConfig(config) {
8
- return config;
9
- }
10
- //#endregion
11
- export { RecursiveRefError, analyzeEnvelope, buildBaseResponseInterface, buildGenerateContext, defineSourceConfig, diffEnvelopeFields, generateForSource, initProject, loadKnownTypeRules, loadSpec, matchKnownType, parseSchema, parseSpec, parseUserBaseResponse, resolveSpecSource };
12
-
13
- //# sourceMappingURL=index.js.map
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};
@@ -29,5 +29,4 @@ declare function buildRouteFromRegistry<T extends RouteParamsShape>(routes: Rout
29
29
  type SearchParamValue = string | number | boolean;
30
30
  declare function appendSearchParams(baseUrl: string, params?: Record<string, SearchParamValue | null | undefined>): string;
31
31
  //#endregion
32
- export { type BuildRouteFn, type RouteBuilderFn, type RouteHandlers, type RouteKeyFromParams, type RouteParamsFor, type RouteParamsMap, type RouteParamsShape, type RouteRegistry, type RouteSearchParams, type SearchParamValue, appendSearchParams, buildRouteFromHandlers, buildRouteFromRegistry, createRouteHandlers };
33
- //# sourceMappingURL=index.d.ts.map
32
+ export { type BuildRouteFn, type RouteBuilderFn, type RouteHandlers, type RouteKeyFromParams, type RouteParamsFor, type RouteParamsMap, type RouteParamsShape, type RouteRegistry, type RouteSearchParams, type SearchParamValue, appendSearchParams, buildRouteFromHandlers, buildRouteFromRegistry, createRouteHandlers };
@@ -1,38 +1 @@
1
- //#region src/routes/search-params.ts
2
- function appendSearchParams(baseUrl, params) {
3
- if (params === void 0 || Object.keys(params).length === 0) return baseUrl;
4
- const [path, existingQuery] = baseUrl.split("?");
5
- const searchParams = new URLSearchParams(existingQuery ?? "");
6
- for (const [key, value] of Object.entries(params)) if (value !== null && value !== void 0) searchParams.set(key, String(value));
7
- const queryString = searchParams.toString();
8
- return queryString.length > 0 ? `${path}?${queryString}` : path ?? baseUrl;
9
- }
10
- //#endregion
11
- //#region src/routes/build.ts
12
- /** Mirrors FE getDynamicRoute, with RouteParams typing and encodeURIComponent. */
13
- function createRouteHandlers(targets) {
14
- return Object.fromEntries(Object.entries(targets).map(([key, value]) => {
15
- if (!/:[^/]+/.test(value)) return [key, value];
16
- return [key, (params, searchParams) => {
17
- let result = value;
18
- for (const [paramKey, paramValue] of Object.entries(params)) result = result.replaceAll(`:${paramKey}`, encodeURIComponent(String(paramValue)));
19
- return appendSearchParams(result, searchParams);
20
- }];
21
- }));
22
- }
23
- function buildRouteFromHandlers(routes) {
24
- const buildRoute = ((key, ...params) => {
25
- const route = routes[key];
26
- if (typeof route === "function") return route(params[0]);
27
- return route;
28
- });
29
- return buildRoute;
30
- }
31
- /** @deprecated Use createRouteHandlers + buildRouteFromHandlers instead. */
32
- function buildRouteFromRegistry(routes) {
33
- return buildRouteFromHandlers(routes);
34
- }
35
- //#endregion
36
- export { appendSearchParams, buildRouteFromHandlers, buildRouteFromRegistry, createRouteHandlers };
37
-
38
- //# sourceMappingURL=index.js.map
1
+ function e(e,t){if(t===void 0||Object.keys(t).length===0)return e;let[n,r]=e.split(`?`),i=new URLSearchParams(r??``);for(let[e,n]of Object.entries(t))n!=null&&i.set(e,String(n));let a=i.toString();return a.length>0?`${n}?${a}`:n??e}function t(t){return Object.fromEntries(Object.entries(t).map(([t,n])=>/:[^/]+/.test(n)?[t,(t,r)=>{let i=n;for(let[e,n]of Object.entries(t))i=i.replaceAll(`:${e}`,encodeURIComponent(String(n)));return e(i,r)}]:[t,n]))}function n(e){return((t,...n)=>{let r=e[t];return typeof r==`function`?r(n[0]):r})}function r(e){return n(e)}export{e as appendSearchParams,n as buildRouteFromHandlers,r as buildRouteFromRegistry,t as createRouteHandlers};
@@ -7,5 +7,4 @@ interface ZodLikeSchema<T> {
7
7
  }
8
8
  declare function createZodValidator<T>(schema: ZodLikeSchema<T>): ResponseValidator<T>;
9
9
  //#endregion
10
- export { type ResponseValidator, ZodLikeSchema, createZodValidator };
11
- //# sourceMappingURL=zod.d.ts.map
10
+ export { type ResponseValidator, ZodLikeSchema, createZodValidator };
@@ -1,8 +1 @@
1
- //#region src/validation/zod.ts
2
- function createZodValidator(schema) {
3
- return (value) => schema.parse(value);
4
- }
5
- //#endregion
6
- export { createZodValidator };
7
-
8
- //# sourceMappingURL=zod.js.map
1
+ function e(e){return t=>e.parse(t)}export{e as createZodValidator};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmirai/typeforge",
3
- "version": "0.1.8",
3
+ "version": "0.2.1",
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": {
@@ -12,11 +12,9 @@
12
12
  "url": "git+https://github.com/openmirai/typeforge.git"
13
13
  },
14
14
  "bin": {
15
- "openapi-codegen": "./dist/cli.js",
16
15
  "typeforge": "./dist/cli.js"
17
16
  },
18
17
  "files": [
19
- "assets/typeforge-logo.png",
20
18
  "dist"
21
19
  ],
22
20
  "type": "module",
@@ -59,6 +57,7 @@
59
57
  },
60
58
  "scripts": {
61
59
  "build": "tsdown",
60
+ "check:package": "node scripts/check-package.mjs",
62
61
  "typecheck": "tsc -p tsconfig.json --pretty false && tsc -p tsconfig.tools.json --pretty false",
63
62
  "format": "oxfmt --check .",
64
63
  "format:fix": "oxfmt --write .",
@@ -69,7 +68,7 @@
69
68
  "test:coverage": "vitest run --coverage",
70
69
  "prepare": "husky",
71
70
  "release": "release-it",
72
- "verify": "pnpm format && pnpm lint && pnpm typecheck && pnpm build && pnpm test:coverage"
71
+ "verify": "pnpm format && pnpm lint && pnpm typecheck && pnpm build && pnpm check:package && pnpm test:coverage"
73
72
  },
74
73
  "dependencies": {
75
74
  "chalk": "5.6.2"
Binary file
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/json/types.ts","../../../src/http/validate.ts","../../../src/http/types.ts","../../../src/adapters/axios/index.ts"],"mappings":";;KAUY;KAEA,cAAc,eAAe;;;KCZ7B,kBAAkB,MAAM,mBAAmB;;;UCOtC,gBACf,yBAAyB,aACzB;EAEA,SAAS;EACT,SAAS;EACT,UAAU;EACV,mBAAmB,kBAAkB;;UAGtB;EACf,IAAI,WAAW,yBAAyB,aACtC,eACA,SAAS,gBAAgB,SAAS,aACjC;IAAU,MAAM;;EACnB,KAAK,WAAW,iBAAiB,yBAAyB,aACxD,eACA,MAAM,OACN,SAAS,gBAAgB,SAAS,aACjC;IAAU,MAAM;;EACnB,IAAI,WAAW,iBAAiB,yBAAyB,aACvD,eACA,MAAM,OACN,SAAS,gBAAgB,SAAS,aACjC;IAAU,MAAM;;EACnB,MAAM,WAAW,iBAAiB,yBAAyB,aACzD,eACA,MAAM,OACN,SAAS,gBAAgB,SAAS,aACjC;IAAU,MAAM;;EACnB,OAAO,WAAW,yBAAyB,aACzC,eACA,SAAS,gBAAgB,SAAS,aACjC;IAAU,MAAM;;;;;iBCLL,mBAAmB,UAAU,gBAAgB"}