czh-api 1.0.5 → 1.0.7

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.
@@ -111,7 +111,7 @@ function getModuleName(path: string, pathPrefixes: Array<{ path: string; package
111
111
  return parts[0] || 'default';
112
112
  }
113
113
 
114
- function convertOpenApiTypeToTypeScript(openApiType: string | undefined): string {
114
+ function convertOpenApiTypeToTypeScript(openApiType: string | undefined): string {
115
115
  if (!openApiType) return 'any';
116
116
 
117
117
  switch (openApiType) {
@@ -125,88 +125,88 @@ function convertOpenApiTypeToTypeScript(openApiType: string | undefined): string
125
125
  return 'boolean';
126
126
  case 'string':
127
127
  return 'string';
128
- case 'number':
129
- return 'number';
130
- default:
131
- return openApiType;
132
- }
133
- }
134
-
135
- function resolveSchemaToTypeScript(
136
- schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined,
137
- allSchemas: { [key: string]: any }
138
- ): string {
139
- if (!schema) return 'any';
140
-
141
- if (isReferenceObject(schema)) {
142
- return getSchemaName(schema.$ref) || 'any';
143
- }
144
-
145
- if (schema.anyOf && Array.isArray(schema.anyOf) && schema.anyOf.length > 0) {
146
- const unionTypes = schema.anyOf
147
- .map(item => resolveSchemaToTypeScript(item as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject, allSchemas))
148
- .filter(Boolean);
149
- if (unionTypes.length > 0) {
150
- return [...new Set(unionTypes)].join(' | ');
151
- }
152
- }
153
-
154
- if (schema.oneOf && Array.isArray(schema.oneOf) && schema.oneOf.length > 0) {
155
- const unionTypes = schema.oneOf
156
- .map(item => resolveSchemaToTypeScript(item as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject, allSchemas))
157
- .filter(Boolean);
158
- if (unionTypes.length > 0) {
159
- return [...new Set(unionTypes)].join(' | ');
160
- }
161
- }
162
-
163
- if (schema.allOf && Array.isArray(schema.allOf) && schema.allOf.length > 0) {
164
- const intersectionTypes = schema.allOf
165
- .map(item => resolveSchemaToTypeScript(item as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject, allSchemas))
166
- .filter(Boolean);
167
- if (intersectionTypes.length > 0) {
168
- return [...new Set(intersectionTypes)].join(' & ');
169
- }
170
- }
171
-
172
- if (schema.type === 'array') {
173
- const itemType = resolveSchemaToTypeScript(
174
- schema.items as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined,
175
- allSchemas
176
- );
177
- return `${itemType || 'any'}[]`;
178
- }
179
-
180
- if (schema.type === 'object') {
181
- if (schema.properties && Object.keys(schema.properties).length > 0) {
182
- const requiredSet = new Set(schema.required || []);
183
- const inlineFields = Object.entries(schema.properties).map(([key, value]) => {
184
- const fieldType = resolveSchemaToTypeScript(
185
- value as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject,
186
- allSchemas
187
- );
188
- const optional = requiredSet.has(key) ? '' : '?';
189
- return `${key}${optional}: ${fieldType || 'any'}`;
190
- });
191
- return `{ ${inlineFields.join('; ')} }`;
192
- }
193
- if (schema.additionalProperties) {
194
- if (schema.additionalProperties === true) {
195
- return 'Record<string, any>';
196
- }
197
- const valueType = resolveSchemaToTypeScript(
198
- schema.additionalProperties as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject,
199
- allSchemas
200
- );
201
- return `Record<string, ${valueType || 'any'}>`;
202
- }
203
- return 'any';
204
- }
205
-
206
- const baseType = convertOpenApiTypeToTypeScript(schema.type);
207
- const nullable = schema.nullable ? ' | null' : '';
208
- return `${baseType}${nullable}`;
209
- }
128
+ case 'number':
129
+ return 'number';
130
+ default:
131
+ return openApiType;
132
+ }
133
+ }
134
+
135
+ function resolveSchemaToTypeScript(
136
+ schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined,
137
+ allSchemas: { [key: string]: any }
138
+ ): string {
139
+ if (!schema) return 'any';
140
+
141
+ if (isReferenceObject(schema)) {
142
+ return getSchemaName(schema.$ref) || 'any';
143
+ }
144
+
145
+ if (schema.anyOf && Array.isArray(schema.anyOf) && schema.anyOf.length > 0) {
146
+ const unionTypes = schema.anyOf
147
+ .map(item => resolveSchemaToTypeScript(item as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject, allSchemas))
148
+ .filter(Boolean);
149
+ if (unionTypes.length > 0) {
150
+ return [...new Set(unionTypes)].join(' | ');
151
+ }
152
+ }
153
+
154
+ if (schema.oneOf && Array.isArray(schema.oneOf) && schema.oneOf.length > 0) {
155
+ const unionTypes = schema.oneOf
156
+ .map(item => resolveSchemaToTypeScript(item as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject, allSchemas))
157
+ .filter(Boolean);
158
+ if (unionTypes.length > 0) {
159
+ return [...new Set(unionTypes)].join(' | ');
160
+ }
161
+ }
162
+
163
+ if (schema.allOf && Array.isArray(schema.allOf) && schema.allOf.length > 0) {
164
+ const intersectionTypes = schema.allOf
165
+ .map(item => resolveSchemaToTypeScript(item as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject, allSchemas))
166
+ .filter(Boolean);
167
+ if (intersectionTypes.length > 0) {
168
+ return [...new Set(intersectionTypes)].join(' & ');
169
+ }
170
+ }
171
+
172
+ if (schema.type === 'array') {
173
+ const itemType = resolveSchemaToTypeScript(
174
+ schema.items as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined,
175
+ allSchemas
176
+ );
177
+ return `${itemType || 'any'}[]`;
178
+ }
179
+
180
+ if (schema.type === 'object') {
181
+ if (schema.properties && Object.keys(schema.properties).length > 0) {
182
+ const requiredSet = new Set(schema.required || []);
183
+ const inlineFields = Object.entries(schema.properties).map(([key, value]) => {
184
+ const fieldType = resolveSchemaToTypeScript(
185
+ value as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject,
186
+ allSchemas
187
+ );
188
+ const optional = requiredSet.has(key) ? '' : '?';
189
+ return `${key}${optional}: ${fieldType || 'any'}`;
190
+ });
191
+ return `{ ${inlineFields.join('; ')} }`;
192
+ }
193
+ if (schema.additionalProperties) {
194
+ if (schema.additionalProperties === true) {
195
+ return 'Record<string, any>';
196
+ }
197
+ const valueType = resolveSchemaToTypeScript(
198
+ schema.additionalProperties as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject,
199
+ allSchemas
200
+ );
201
+ return `Record<string, ${valueType || 'any'}>`;
202
+ }
203
+ return 'any';
204
+ }
205
+
206
+ const baseType = convertOpenApiTypeToTypeScript(schema.type);
207
+ const nullable = schema.nullable ? ' | null' : '';
208
+ return `${baseType}${nullable}`;
209
+ }
210
210
 
211
211
  function extractJsdocParamsFromSchema(schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject, allSchemas: { [key: string]: any }): Required<Endpoint>['jsdocParams'] {
212
212
  const params: Required<Endpoint>['jsdocParams'] = [];
@@ -222,15 +222,19 @@ function extractJsdocParamsFromSchema(schema: OpenAPIV3.SchemaObject | OpenAPIV3
222
222
 
223
223
  if (targetSchema?.properties) {
224
224
  for (const propName in targetSchema.properties) {
225
- const prop = targetSchema.properties[propName] as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject;
226
- let propType = resolveSchemaToTypeScript(prop, allSchemas);
227
- const propDescription = isReferenceObject(prop)
228
- ? ((allSchemas[getSchemaName(prop.$ref)] as OpenAPIV3.SchemaObject | undefined)?.description || '')
229
- : (prop?.description || '');
225
+ const prop = targetSchema.properties[propName] as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject;
226
+ if (!prop) {
227
+ params.push({ name: propName, type: 'any', description: '', required: targetSchema.required?.includes(propName) });
228
+ continue;
229
+ }
230
+ let propType = resolveSchemaToTypeScript(prop, allSchemas);
231
+ const propDescription = isReferenceObject(prop)
232
+ ? ((allSchemas[getSchemaName(prop.$ref)] as OpenAPIV3.SchemaObject | undefined)?.description || '')
233
+ : (prop?.description || '');
230
234
 
231
235
  // 处理 anyOf 数组 (FastAPI 常用的联合类型)
232
- if (false && (prop as OpenAPIV3.SchemaObject).anyOf && Array.isArray((prop as OpenAPIV3.SchemaObject).anyOf)) {
233
- const types = (prop as OpenAPIV3.SchemaObject).anyOf!.map(item => {
236
+ if (false && (prop as OpenAPIV3.SchemaObject).anyOf && Array.isArray((prop as OpenAPIV3.SchemaObject).anyOf)) {
237
+ const types = (prop as OpenAPIV3.SchemaObject).anyOf!.map(item => {
234
238
  if (isReferenceObject(item)) {
235
239
  return getSchemaName(item.$ref);
236
240
  } else {
@@ -251,8 +255,8 @@ function extractJsdocParamsFromSchema(schema: OpenAPIV3.SchemaObject | OpenAPIV3
251
255
  }
252
256
  }
253
257
  // 处理 oneOf 数组
254
- else if (false && (prop as OpenAPIV3.SchemaObject).oneOf && Array.isArray((prop as OpenAPIV3.SchemaObject).oneOf)) {
255
- const types = (prop as OpenAPIV3.SchemaObject).oneOf!.map(item => {
258
+ else if (false && (prop as OpenAPIV3.SchemaObject).oneOf && Array.isArray((prop as OpenAPIV3.SchemaObject).oneOf)) {
259
+ const types = (prop as OpenAPIV3.SchemaObject).oneOf!.map(item => {
256
260
  if (isReferenceObject(item)) {
257
261
  return getSchemaName(item.$ref);
258
262
  } else {
@@ -273,26 +277,26 @@ function extractJsdocParamsFromSchema(schema: OpenAPIV3.SchemaObject | OpenAPIV3
273
277
  }
274
278
  }
275
279
  // 处理普通类型
276
- else if (false && (prop as OpenAPIV3.SchemaObject).type) {
277
- const propSchema: any = prop as any;
278
- if (propSchema.type === 'array' && propSchema.items) {
279
- if (isReferenceObject(propSchema.items)) {
280
- propType = `${getSchemaName(propSchema.items.$ref)}[]`;
281
- } else {
282
- const itemType = convertOpenApiTypeToTypeScript((propSchema.items as OpenAPIV3.SchemaObject).type);
283
- propType = `${itemType}[]`;
284
- }
285
- } else {
286
- propType = convertOpenApiTypeToTypeScript(propSchema.type);
287
- }
288
- }
289
-
290
- params.push({
291
- name: propName,
292
- type: propType || 'any',
293
- description: propDescription,
294
- required: targetSchema.required?.includes(propName)
295
- });
280
+ else if (false && (prop as OpenAPIV3.SchemaObject).type) {
281
+ const propSchema: any = prop as any;
282
+ if (propSchema.type === 'array' && propSchema.items) {
283
+ if (isReferenceObject(propSchema.items)) {
284
+ propType = `${getSchemaName(propSchema.items.$ref)}[]`;
285
+ } else {
286
+ const itemType = convertOpenApiTypeToTypeScript((propSchema.items as OpenAPIV3.SchemaObject).type);
287
+ propType = `${itemType}[]`;
288
+ }
289
+ } else {
290
+ propType = convertOpenApiTypeToTypeScript(propSchema.type);
291
+ }
292
+ }
293
+
294
+ params.push({
295
+ name: propName,
296
+ type: propType || 'any',
297
+ description: propDescription,
298
+ required: targetSchema.required?.includes(propName)
299
+ });
296
300
  }
297
301
  }
298
302
  return params;
@@ -452,7 +456,8 @@ export const processApi = (api: OpenAPI.Document, excludePaths: string[] = [], i
452
456
  } else if (isFormData && (param.in === 'query' || param.in === 'formData')) {
453
457
  // Collect params for the FormData body type
454
458
  if(!formDataSchema.properties) formDataSchema.properties = {};
455
- formDataSchema.properties[param.name] = param.schema as OpenAPIV3.SchemaObject;
459
+ const paramSchema = (param.schema || { type: (param as any).type || 'string', format: (param as any).format, description: param.description }) as OpenAPIV3.SchemaObject;
460
+ formDataSchema.properties[param.name] = paramSchema;
456
461
  if(param.required) {
457
462
  if(!formDataSchema.required) formDataSchema.required = [];
458
463
  formDataSchema.required.push(param.name);
@@ -460,7 +465,8 @@ export const processApi = (api: OpenAPI.Document, excludePaths: string[] = [], i
460
465
  } else if (param.in === 'path' || param.in === 'query') {
461
466
  // Always collect path params
462
467
  if(!paramsSchema.properties) paramsSchema.properties = {};
463
- paramsSchema.properties[param.name] = param.schema as OpenAPIV3.SchemaObject;
468
+ const paramSchema = (param.schema || { type: (param as any).type || 'string', format: (param as any).format, description: param.description }) as OpenAPIV3.SchemaObject;
469
+ paramsSchema.properties[param.name] = paramSchema;
464
470
  if(param.required) {
465
471
  if(!paramsSchema.required) paramsSchema.required = [];
466
472
  paramsSchema.required.push(param.name);
@@ -558,31 +564,31 @@ export const processApi = (api: OpenAPI.Document, excludePaths: string[] = [], i
558
564
  responseJsdocParams.push(...extractJsdocParamsFromSchema(schema, allSchemas));
559
565
  } else if (schema && !isReferenceObject(schema)) {
560
566
  const inlineSchema = schema as OpenAPIV3.SchemaObject;
561
- if (inlineSchema.type === 'object' || inlineSchema.properties) {
562
- // Generate a named type for inline response schema
563
- const typeName = `${functionName.charAt(0).toUpperCase() + functionName.slice(1)}Response`;
564
- responseTypeName = typeName;
565
- modules[moduleName].schemas[typeName] = inlineSchema;
566
- referencedTypes.push(typeName);
567
- responseJsdocParams.push(...extractJsdocParamsFromSchema(inlineSchema, allSchemas));
568
- } else if (inlineSchema.type === 'array' && inlineSchema.items) {
569
- if (isReferenceObject(inlineSchema.items)) {
570
- const itemSchemaName = getSchemaName(inlineSchema.items.$ref);
571
- // Prefer direct `ItemType[]` for array responses to avoid unnecessary alias schema compilation.
572
- responseTypeName = `${itemSchemaName}[]`;
573
- referencedTypes.push(itemSchemaName);
574
- addSchemaWithDependencies(itemSchemaName, modules[moduleName], allSchemas);
575
- responseJsdocParams.push(...extractJsdocParamsFromSchema(inlineSchema.items, allSchemas));
576
- } else {
577
- const typeName = `${functionName.charAt(0).toUpperCase() + functionName.slice(1)}Response`;
578
- responseTypeName = typeName;
579
- modules[moduleName].schemas[typeName] = inlineSchema;
580
- referencedTypes.push(typeName);
581
- responseJsdocParams.push(...extractJsdocParamsFromSchema(inlineSchema, allSchemas));
582
- }
583
- }
584
- }
585
- }
567
+ if (inlineSchema.type === 'object' || inlineSchema.properties) {
568
+ // Generate a named type for inline response schema
569
+ const typeName = `${functionName.charAt(0).toUpperCase() + functionName.slice(1)}Response`;
570
+ responseTypeName = typeName;
571
+ modules[moduleName].schemas[typeName] = inlineSchema;
572
+ referencedTypes.push(typeName);
573
+ responseJsdocParams.push(...extractJsdocParamsFromSchema(inlineSchema, allSchemas));
574
+ } else if (inlineSchema.type === 'array' && inlineSchema.items) {
575
+ if (isReferenceObject(inlineSchema.items)) {
576
+ const itemSchemaName = getSchemaName(inlineSchema.items.$ref);
577
+ // Prefer direct `ItemType[]` for array responses to avoid unnecessary alias schema compilation.
578
+ responseTypeName = `${itemSchemaName}[]`;
579
+ referencedTypes.push(itemSchemaName);
580
+ addSchemaWithDependencies(itemSchemaName, modules[moduleName], allSchemas);
581
+ responseJsdocParams.push(...extractJsdocParamsFromSchema(inlineSchema.items, allSchemas));
582
+ } else {
583
+ const typeName = `${functionName.charAt(0).toUpperCase() + functionName.slice(1)}Response`;
584
+ responseTypeName = typeName;
585
+ modules[moduleName].schemas[typeName] = inlineSchema;
586
+ referencedTypes.push(typeName);
587
+ responseJsdocParams.push(...extractJsdocParamsFromSchema(inlineSchema, allSchemas));
588
+ }
589
+ }
590
+ }
591
+ }
586
592
 
587
593
  // Convert path to template literal string for path parameters
588
594
  const urlTemplate = path.replace(/\{(\w+)\}/g, '${params.$1}');
@@ -610,4 +616,4 @@ export const processApi = (api: OpenAPI.Document, excludePaths: string[] = [], i
610
616
  }
611
617
 
612
618
  return modules;
613
- };
619
+ };