Skip to content

Commit 1db3f29

Browse files
authored
Merge pull request #18 from HUxiaoAlinNG/master
fix: 完善重复引用逻辑
2 parents 6467bae + 78b7b27 commit 1db3f29

File tree

8 files changed

+196
-13
lines changed

8 files changed

+196
-13
lines changed

jest/common.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,27 @@ export namespace Param_1 {
3737
name: string;
3838
}
3939
}
40+
41+
export namespace ParamsRule {
42+
export interface Level {
43+
a?: boolean;
44+
b?: boolean;
45+
c?: boolean;
46+
d?: boolean;
47+
}
48+
49+
export enum PEnum {
50+
'enum0' = 'enum0'
51+
}
52+
53+
export interface PObject {
54+
a: Level;
55+
b?: PEnum;
56+
c?: PEnum[];
57+
}
58+
59+
export interface PAll {
60+
level?: Level;
61+
pObject?: PObject;
62+
}
63+
}

jest/namespace.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Param, Param_1 } from './common';
1+
import { Param, Param_1, ParamsRule } from './common';
22
import * as Type from './common';
33

44
export interface Namespace_1 {
@@ -18,3 +18,7 @@ export interface Namespace_4 {
1818
other2: Param_1.A;
1919
other3: Param_1.Label;
2020
}
21+
22+
export interface Namespace_5 {
23+
other1: ParamsRule.PAll
24+
}

src/__tests__/__snapshots__/namespace.test.ts.snap

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,77 @@ Object {
139139
"type": "object",
140140
}
141141
`;
142+
143+
exports[`namespace案例_5 1`] = `
144+
Object {
145+
"additionalProperties": false,
146+
"definitions": Object {
147+
"ParamsRule.Level": Object {
148+
"additionalProperties": false,
149+
"properties": Object {
150+
"a": Object {
151+
"type": "boolean",
152+
},
153+
"b": Object {
154+
"type": "boolean",
155+
},
156+
"c": Object {
157+
"type": "boolean",
158+
},
159+
"d": Object {
160+
"type": "boolean",
161+
},
162+
},
163+
"type": "object",
164+
},
165+
"ParamsRule.PAll": Object {
166+
"additionalProperties": false,
167+
"properties": Object {
168+
"level": Object {
169+
"$ref": "#/definitions/ParamsRule.Level",
170+
},
171+
"pObject": Object {
172+
"$ref": "#/definitions/ParamsRule.PObject",
173+
},
174+
},
175+
"type": "object",
176+
},
177+
"ParamsRule.PEnum": Object {
178+
"enum": Array [
179+
"enum0",
180+
],
181+
"type": "string",
182+
},
183+
"ParamsRule.PObject": Object {
184+
"additionalProperties": false,
185+
"properties": Object {
186+
"a": Object {
187+
"$ref": "#/definitions/ParamsRule.Level",
188+
},
189+
"b": Object {
190+
"$ref": "#/definitions/ParamsRule.PEnum",
191+
},
192+
"c": Object {
193+
"items": Object {
194+
"$ref": "#/definitions/ParamsRule.PEnum",
195+
},
196+
"type": "array",
197+
},
198+
},
199+
"required": Array [
200+
"a",
201+
],
202+
"type": "object",
203+
},
204+
},
205+
"properties": Object {
206+
"other1": Object {
207+
"$ref": "#/definitions/ParamsRule.PAll",
208+
},
209+
},
210+
"required": Array [
211+
"other1",
212+
],
213+
"type": "object",
214+
}
215+
`;

src/__tests__/__snapshots__/other.test.ts.snap

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,63 @@ Object {
270270
],
271271
"type": "number",
272272
},
273+
"ParamsRule.Level": Object {
274+
"additionalProperties": false,
275+
"properties": Object {
276+
"a": Object {
277+
"type": "boolean",
278+
},
279+
"b": Object {
280+
"type": "boolean",
281+
},
282+
"c": Object {
283+
"type": "boolean",
284+
},
285+
"d": Object {
286+
"type": "boolean",
287+
},
288+
},
289+
"type": "object",
290+
},
291+
"ParamsRule.PAll": Object {
292+
"additionalProperties": false,
293+
"properties": Object {
294+
"level": Object {
295+
"$ref": "#ParamsRule.Level",
296+
},
297+
"pObject": Object {
298+
"$ref": "#ParamsRule.PObject",
299+
},
300+
},
301+
"type": "object",
302+
},
303+
"ParamsRule.PEnum": Object {
304+
"enum": Array [
305+
"enum0",
306+
],
307+
"type": "string",
308+
},
309+
"ParamsRule.PObject": Object {
310+
"additionalProperties": false,
311+
"properties": Object {
312+
"a": Object {
313+
"$ref": "#ParamsRule.Level",
314+
},
315+
"b": Object {
316+
"$ref": "#ParamsRule.PEnum",
317+
},
318+
"c": Object {
319+
"items": Object {
320+
"$ref": "#ParamsRule.PEnum",
321+
},
322+
"type": "array",
323+
},
324+
},
325+
"required": Array [
326+
"a",
327+
],
328+
"type": "object",
329+
},
273330
},
274331
"/jest/other.ts": Object {
275332
"AAA": Object {

src/__tests__/namespace.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ test('namespace案例_3', () => {
2525
test('namespace案例_4', () => {
2626
expect(getSchema('Namespace_4')).toMatchSnapshot();
2727
});
28+
29+
test('namespace案例_5', () => {
30+
expect(getSchema('Namespace_5')).toMatchSnapshot();
31+
});

src/get-jsonschema-from-data.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,18 +312,25 @@ export default class genTypeSchema extends typescriptToFileDatas {
312312
// 兼容import外部引入与内部引用两种方式
313313
let $refJson = fileJson[firstKey] || fileJson[$refKey] || {};
314314
$refJson = _.cloneDeep($refJson)
315+
315316
if ((entry as any).keySet.has($refKey)) {
316317
(entry as any).refKeyTime[$refKey] = ((entry as any).refKeyTime[$refKey] || 0) + 1;
318+
// 处理namespace方式导入的types
319+
if ($refJson.type === ImportType.ImportNamespaceSpecifier) {
320+
$refKey = otherKeys.join('.');
321+
}
322+
item.$ref = `#/definitions/${$refKey}`;
317323
return $refJson;
318324
}
319325

320-
(entry as any).keySet.add($refKey);
321-
(entry as any).refKeyTime[$refKey] = ((entry as any).refKeyTime[$refKey] || 0) + 1;
322326
// 处理namespace方式导入的types
323327
if ($refJson.type === ImportType.ImportNamespaceSpecifier) {
324328
$refKey = otherKeys.join('.');
325329
}
326330

331+
(entry as any).keySet.add($refKey);
332+
(entry as any).refKeyTime[$refKey] = ((entry as any).refKeyTime[$refKey] || 0) + 1;
333+
327334
item.$ref = `#/definitions/${$refKey}`;
328335

329336
// fileJson[$refJson.$ref.replace(/#(\/definitions\/)?/, '')] 表示在本文件就能找到

src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,14 @@ export interface TypeAnnotationConfig {
4343
file?: string;
4444
attrKey?: string;
4545
refKey?: string;
46+
namespaces?: string[];
4647
}
4748

4849
export interface TSTypeAnnotationConfig {
4950
node: AnyOption;
5051
parentKey?: string;
5152
file?: string;
53+
namespaces?: string[];
5254
}
5355

5456
export type EntryType = { keySet: Set<string>; times: number };

src/typescript-to-file-datas.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export default class typescriptToFileDatas {
8181
parentJson: null | AnyOption,
8282
option: TSTypeAnnotationConfig,
8383
): void {
84-
const { node, parentKey, file } = option || {};
84+
const { node, parentKey, file, namespaces } = option || {};
8585

8686
const key = _.get(node, 'key.name') || _.get(node, 'key.value') || '';
8787
const required = !node.optional;
@@ -92,6 +92,7 @@ export default class typescriptToFileDatas {
9292
typeAnnotation: node.typeAnnotation,
9393
file,
9494
attrKey: key,
95+
namespaces,
9596
});
9697

9798
if (typeAnnotation && typeof typeAnnotation === 'object') {
@@ -338,7 +339,7 @@ export default class typescriptToFileDatas {
338339
}
339340
const key = _.get(path, 'node.key.name') || _.get(path, 'node.key.value');
340341

341-
_this.handleTSTypeAnnotation(json, null, { node: path.node, file });
342+
_this.handleTSTypeAnnotation(json, null, { node: path.node, file, namespaces, });
342343

343344
path.traverse({
344345
TSTypeLiteral(path: AnyOption) {
@@ -352,6 +353,7 @@ export default class typescriptToFileDatas {
352353
node: path.node,
353354
parentKey: key,
354355
file,
356+
namespaces,
355357
});
356358
},
357359
});
@@ -576,10 +578,12 @@ export default class typescriptToFileDatas {
576578
* @param {AnyOption} typeAnnotation
577579
* @returns {any} {string}
578580
*/
579-
getTypeName(typeName: AnyOption): string {
581+
getTypeName(typeName: AnyOption, namespaces?: string[]): string {
580582
const name = _.get(typeName, 'name');
581-
582583
if (name) {
584+
if (typeName.type === 'Identifier' && Array.isArray(namespaces) && namespaces.length) {
585+
return `${namespaces.join('.')}.${name}`
586+
}
583587
return name;
584588
}
585589
const { left, right } = typeName || {};
@@ -624,7 +628,7 @@ export default class typescriptToFileDatas {
624628
* @returns {any}
625629
*/
626630
transformTypeAnnotation(option: TypeAnnotationConfig): AnyOption | null {
627-
const { typeAnnotation, file, attrKey, refKey } = option || {};
631+
const { typeAnnotation, file, attrKey, refKey, namespaces } = option || {};
628632
if (!typeAnnotation) return null;
629633
const cType = _.get(typeAnnotation, 'type');
630634
if (!cType) return null;
@@ -648,17 +652,16 @@ export default class typescriptToFileDatas {
648652

649653
// 处理 Number/自定义 等类型
650654
if (cType === 'TSTypeReference') {
651-
const name = this.getTypeName(typeAnnotation.typeName);
652-
655+
const name = this.getTypeName(typeAnnotation.typeName, namespaces);
653656
const type = this.handleRelationTypes(name);
654-
655657
let items = null;
656658
if (typeAnnotation.typeParameters) {
657659
items = this.transformTypeAnnotation({
658660
typeAnnotation: typeAnnotation.typeParameters,
659661
file,
660662
attrKey,
661663
refKey: name,
664+
namespaces,
662665
});
663666
}
664667
// promise 特殊处理
@@ -698,7 +701,12 @@ export default class typescriptToFileDatas {
698701
if (cType === 'TSTypeParameterInstantiation') {
699702
const params: (AnyOption | null)[] = [];
700703
typeAnnotation.params.forEach((item: AnyOption) => {
701-
const res = this.transformTypeAnnotation({ typeAnnotation: item, file, attrKey });
704+
const res = this.transformTypeAnnotation({
705+
typeAnnotation: item,
706+
file,
707+
attrKey,
708+
namespaces,
709+
});
702710
if (res) {
703711
params.push(res);
704712
}
@@ -718,6 +726,7 @@ export default class typescriptToFileDatas {
718726
typeAnnotation: typeAnnotation.typeAnnotation,
719727
file,
720728
attrKey,
729+
namespaces,
721730
});
722731
}
723732

@@ -727,6 +736,7 @@ export default class typescriptToFileDatas {
727736
typeAnnotation: typeAnnotation.elementType,
728737
file,
729738
attrKey,
739+
namespaces,
730740
});
731741
return type ? { type: 'array', items: type } : null;
732742
}
@@ -737,6 +747,7 @@ export default class typescriptToFileDatas {
737747
typeAnnotation: typeAnnotation.typeAnnotation,
738748
file,
739749
attrKey,
750+
namespaces,
740751
});
741752
return type;
742753
}
@@ -745,7 +756,7 @@ export default class typescriptToFileDatas {
745756
const members = typeAnnotation.members || [];
746757
const json = { type: 'object', properties: {}, required: [] };
747758
members.forEach((item: AnyOption) => {
748-
this.handleTSTypeAnnotation(json, null, { node: item, file });
759+
this.handleTSTypeAnnotation(json, null, { node: item, file, namespaces, });
749760
});
750761

751762
this.formatJsonSchema(json);

0 commit comments

Comments
 (0)