@xyd-js/sources 0.0.0-build
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/CHANGELOG.md +9 -0
- package/ISSUES.md +10 -0
- package/LICENSE +21 -0
- package/README.md +3 -0
- package/TODO.md +9 -0
- package/__fixtures__/-1.typescript/package.json +5 -0
- package/__fixtures__/-1.typescript/src/index.ts +0 -0
- package/__fixtures__/-1.typescript/src/settings.ts +592 -0
- package/__fixtures__/-1.typescript/tsconfig.json +8 -0
- package/__fixtures__/-2.react.basic/1.flat-interface.output.json +114 -0
- package/__fixtures__/-2.react.basic/2.file-connect-interface.output.json +60 -0
- package/__fixtures__/-2.react.basic/2a.file-connect-interface-advanced.output.json +92 -0
- package/__fixtures__/-2.react.basic/3.props-as-variants.output.json +166 -0
- package/__fixtures__/-2.react.basic/4.outside-interface.output.json +60 -0
- package/__fixtures__/-2.react.basic/5.inline-props.output.json +60 -0
- package/__fixtures__/-2.react.basic/5.outside-inline-props.output.json +60 -0
- package/__fixtures__/-2.react.basic/5a.inline-props+outside.output.json +60 -0
- package/__fixtures__/-2.react.basic/5b.inline-props+interfaces.output.json +92 -0
- package/__fixtures__/-2.react.basic/package.json +4 -0
- package/__fixtures__/-2.react.basic/src/1.flat-interface.tsx +41 -0
- package/__fixtures__/-2.react.basic/src/2.file-connect-interface.tsx +28 -0
- package/__fixtures__/-2.react.basic/src/2a.file-connect-interace+advanced.tsx +54 -0
- package/__fixtures__/-2.react.basic/src/3.props-as-variants.tsx +67 -0
- package/__fixtures__/-2.react.basic/src/4.outside-interface.tsx +13 -0
- package/__fixtures__/-2.react.basic/src/4.outside-interface2.ts +15 -0
- package/__fixtures__/-2.react.basic/src/5.inline-props.tsx +19 -0
- package/__fixtures__/-2.react.basic/src/5a.inline-props+outside.tsx +19 -0
- package/__fixtures__/-2.react.basic/src/5b.inline-props+interfaces.tsx +62 -0
- package/__fixtures__/-2.react.basic/src/index.ts +0 -0
- package/__fixtures__/-2.react.basic/tsconfig.json +8 -0
- package/__tests__/sourcesToUniform.test.ts +167 -0
- package/__tests__/testResolvePropertySymbol.ts +838 -0
- package/__tests__/types.ts +12 -0
- package/__tests__/utils.ts +108 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/react.cjs +237 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +6 -0
- package/dist/react.d.ts +6 -0
- package/dist/react.js +212 -0
- package/dist/react.js.map +1 -0
- package/dist/ts.cjs +1794 -0
- package/dist/ts.cjs.map +1 -0
- package/dist/ts.d.cts +14 -0
- package/dist/ts.d.ts +14 -0
- package/dist/ts.js +1760 -0
- package/dist/ts.js.map +1 -0
- package/package.json +41 -0
- package/packages/react/index.ts +1 -0
- package/packages/react/uniformToReactUniform.ts +275 -0
- package/packages/ts/SignatureText.ts +233 -0
- package/packages/ts/TypeDocTransformer.ts +1519 -0
- package/packages/ts/__fixtures__/packages/package-a/package.json +4 -0
- package/packages/ts/__fixtures__/packages/package-a/src/index.ts +56 -0
- package/packages/ts/__fixtures__/packages/package-a/tsconfig.json +23 -0
- package/packages/ts/__fixtures__/packages/package-b/package.json +7 -0
- package/packages/ts/__fixtures__/packages/package-b/src/billing.ts +193 -0
- package/packages/ts/__fixtures__/packages/package-b/src/index.ts +8 -0
- package/packages/ts/__fixtures__/packages/package-b/tsconfig.json +20 -0
- package/packages/ts/__fixtures__/packages2/package-a/package.json +4 -0
- package/packages/ts/__fixtures__/packages2/package-a/src/index.ts +496 -0
- package/packages/ts/__fixtures__/packages2/package-a/tsconfig.json +6 -0
- package/packages/ts/__fixtures__/packages3/package-a/package.json +4 -0
- package/packages/ts/__fixtures__/packages3/package-a/src/index.ts +488 -0
- package/packages/ts/__fixtures__/packages3/package-a/tsconfig.json +6 -0
- package/packages/ts/__fixtures__/packages3/project.json +171 -0
- package/packages/ts/__fixtures__/react/react-a/package.json +5 -0
- package/packages/ts/__fixtures__/react/react-a/src/TestAbc.tsx +90 -0
- package/packages/ts/__fixtures__/react/react-a/src/TestBasic.tsx +27 -0
- package/packages/ts/__fixtures__/react/react-a/src/TestNamedParameters.tsx +27 -0
- package/packages/ts/__fixtures__/react/react-a/src/TestNamedParameters2.tsx +26 -0
- package/packages/ts/__fixtures__/react/react-a/src/TestUnion.tsx +32 -0
- package/packages/ts/__fixtures__/react/react-a/src/index.ts +1 -0
- package/packages/ts/__fixtures__/react/react-a/tsconfig.json +8 -0
- package/packages/ts/__fixtures__/references-output-project.json +344 -0
- package/packages/ts/__fixtures__/references-output-react.json +68 -0
- package/packages/ts/__fixtures__/references-output.json +129 -0
- package/packages/ts/__tests__/sourcesToUniform.test.ts +106 -0
- package/packages/ts/context.ts +0 -0
- package/packages/ts/converterts/ts-class.ts +0 -0
- package/packages/ts/converterts/ts-enum.ts +0 -0
- package/packages/ts/converterts/ts-function.ts +0 -0
- package/packages/ts/converterts/ts-interface.ts +0 -0
- package/packages/ts/converterts/ts-type.ts +0 -0
- package/packages/ts/index.ts +129 -0
- package/packages/ts/ts-core.ts +0 -0
- package/packages/ts/uniformToMiniUniform.ts +486 -0
- package/src/index.ts +0 -0
- package/test-cmd/index.ts +62 -0
- package/tsconfig.json +38 -0
- package/tsup.config.ts +39 -0
- package/vitest.config.ts +34 -0
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFINED_DEFINITION_PROPERTY_TYPE,
|
|
3
|
+
Definition, DefinitionProperty,
|
|
4
|
+
Reference,
|
|
5
|
+
TypeDocReferenceContext
|
|
6
|
+
} from "@xyd-js/uniform";
|
|
7
|
+
|
|
8
|
+
// TODO: in the future translation system
|
|
9
|
+
const TXT = {
|
|
10
|
+
Properties: "Properties",
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// TODO: primite types for different langauges
|
|
14
|
+
// Map of primitive types that can be merged
|
|
15
|
+
const PRIMITIVE_TYPES = new Set(['string', 'number', 'boolean']);
|
|
16
|
+
|
|
17
|
+
type RefsBySymbolId = { [symbolId: string]: Reference };
|
|
18
|
+
|
|
19
|
+
// TODO: name it eager and move to uniform plugins
|
|
20
|
+
/**
|
|
21
|
+
* `uniformToMiniUniform` converts a list of references into a mini uniform format.
|
|
22
|
+
*/
|
|
23
|
+
export function uniformToMiniUniform(
|
|
24
|
+
rootSymbolName: string,
|
|
25
|
+
references: Reference<TypeDocReferenceContext>[],
|
|
26
|
+
): Reference[] {
|
|
27
|
+
const output: Reference[] = []
|
|
28
|
+
const refBySymbolId: RefsBySymbolId = {}
|
|
29
|
+
|
|
30
|
+
// 1. collect all references by symbolId
|
|
31
|
+
for (const reference of references) {
|
|
32
|
+
const ctx = reference.context
|
|
33
|
+
|
|
34
|
+
if (ctx?.symbolId) {
|
|
35
|
+
if (reference.context?.meta?.some(m => m.name === "internal" && m.value === "true")) {
|
|
36
|
+
continue // Skip internal references
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// TODO: check if still has issues with circular references
|
|
40
|
+
refBySymbolId[ctx.symbolId] = JSON.parse(JSON.stringify(reference)); // Deep clone to avoid circular references
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 2. process references by rootSymbolName
|
|
45
|
+
for (const reference of references) {
|
|
46
|
+
const ctx = reference.context
|
|
47
|
+
|
|
48
|
+
if (ctx?.symbolName !== rootSymbolName) {
|
|
49
|
+
continue
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const miniRef: Reference = {
|
|
53
|
+
...reference,
|
|
54
|
+
title: ctx?.symbolName || reference.title,
|
|
55
|
+
canonical: "",
|
|
56
|
+
context: ctx,
|
|
57
|
+
definitions: [],
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const def of reference.definitions) {
|
|
61
|
+
const miniDef: Definition = {
|
|
62
|
+
...def,
|
|
63
|
+
title: TXT.Properties,
|
|
64
|
+
properties: [],
|
|
65
|
+
symbolDef: {
|
|
66
|
+
...def.symbolDef || {},
|
|
67
|
+
canonical: "", // TODO: support canonical in the future
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const defProperties = def?.rootProperty ? [def.rootProperty] : def.properties || []
|
|
72
|
+
|
|
73
|
+
definitionMiniPropsPassThrough(
|
|
74
|
+
refBySymbolId,
|
|
75
|
+
defProperties,
|
|
76
|
+
miniDef,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
miniRef.definitions.push(miniDef)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
output.push(miniRef)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return output
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* `definitionMiniPropsPassThrough` processes the properties of a definition and resolves them into a mini definition.
|
|
90
|
+
*/
|
|
91
|
+
function definitionMiniPropsPassThrough(
|
|
92
|
+
refBySymbolId: RefsBySymbolId,
|
|
93
|
+
defProperties: DefinitionProperty[],
|
|
94
|
+
miniDef: Definition,
|
|
95
|
+
options?: {
|
|
96
|
+
paramProps?: boolean,
|
|
97
|
+
}
|
|
98
|
+
) {
|
|
99
|
+
for (let property of defProperties) {
|
|
100
|
+
property = {
|
|
101
|
+
...property,
|
|
102
|
+
symbolDef: {
|
|
103
|
+
...property.symbolDef || {},
|
|
104
|
+
canonical: "", // TODO: support canonical in the future
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 1. resolve the property and all its nested properties
|
|
109
|
+
const resolvedProperty = resolveProperty(refBySymbolId, property, options)
|
|
110
|
+
|
|
111
|
+
miniDef.properties.push({
|
|
112
|
+
...resolvedProperty,
|
|
113
|
+
symbolDef: {
|
|
114
|
+
...resolvedProperty.symbolDef || {},
|
|
115
|
+
canonical: "", // TODO: support canonical in the future
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* `resolveProperty` recursively resolves a property and its nested properties.
|
|
123
|
+
*/
|
|
124
|
+
function resolveProperty(
|
|
125
|
+
refBySymbolId: { [symbolId: string]: Reference },
|
|
126
|
+
property: DefinitionProperty,
|
|
127
|
+
options?: {
|
|
128
|
+
paramProps?: boolean,
|
|
129
|
+
depth?: number,
|
|
130
|
+
visited?: Set<string>
|
|
131
|
+
}
|
|
132
|
+
): DefinitionProperty {
|
|
133
|
+
property = {
|
|
134
|
+
...property,
|
|
135
|
+
symbolDef: {
|
|
136
|
+
...property.symbolDef || {},
|
|
137
|
+
canonical: "", // TODO: support canonical in the future
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Initialize depth and visited set if not provided
|
|
141
|
+
const depth = options?.depth || 0;
|
|
142
|
+
const visited = options?.visited || new Set<string>();
|
|
143
|
+
|
|
144
|
+
// Prevent infinite recursion by limiting depth and tracking visited types
|
|
145
|
+
if (depth > 10) {
|
|
146
|
+
console.warn('Maximum recursion depth reached for property:', property.name);
|
|
147
|
+
return property;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (property?.properties?.length) {
|
|
151
|
+
return property
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const resolvedPropertyProps: DefinitionProperty[] = []
|
|
155
|
+
const resolvedProperty: DefinitionProperty = {
|
|
156
|
+
...property,
|
|
157
|
+
properties: resolvedPropertyProps,
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// 1. handle array types
|
|
161
|
+
if (property.type === DEFINED_DEFINITION_PROPERTY_TYPE.ARRAY) {
|
|
162
|
+
if (property.ofProperty) {
|
|
163
|
+
const resolvedRootProperty = resolveProperty(
|
|
164
|
+
refBySymbolId,
|
|
165
|
+
property.ofProperty,
|
|
166
|
+
options
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
resolvedProperty.ofProperty = resolvedRootProperty
|
|
170
|
+
|
|
171
|
+
return resolvedProperty
|
|
172
|
+
} else {
|
|
173
|
+
console.warn(`Property ${property.name} is an array but has no ofProperty defined, using type only`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return property
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 2. handle symbolDef.id references
|
|
180
|
+
const symbolId = property?.symbolDef?.id;
|
|
181
|
+
if (symbolId) {
|
|
182
|
+
// 3. if symbolId is a string, resolve the reference
|
|
183
|
+
if (typeof symbolId === 'string') {
|
|
184
|
+
if (visited.has(symbolId)) {
|
|
185
|
+
return resolvedProperty;
|
|
186
|
+
}
|
|
187
|
+
visited.add(symbolId);
|
|
188
|
+
|
|
189
|
+
const refSymbol = refBySymbolId[symbolId];
|
|
190
|
+
const refSymbolDefinition = refSymbol?.definitions?.[0];
|
|
191
|
+
const refSymbolDefinitionProps = refSymbolDefinition?.properties || [];
|
|
192
|
+
|
|
193
|
+
if (!refSymbol) {
|
|
194
|
+
console.warn(`Reference for symbol ${symbolId} not found, using type only`);
|
|
195
|
+
return resolvedProperty;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// If the referenced type has properties, resolve them
|
|
199
|
+
if (refSymbolDefinitionProps.length) {
|
|
200
|
+
// Recursively resolve each property
|
|
201
|
+
for (const prop of refSymbolDefinitionProps) {
|
|
202
|
+
const resolvedProp = resolveProperty(refBySymbolId, prop, {
|
|
203
|
+
...options,
|
|
204
|
+
depth: depth + 1,
|
|
205
|
+
visited: new Set(visited)
|
|
206
|
+
});
|
|
207
|
+
resolvedPropertyProps.push(resolvedProp);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
} else if (refSymbolDefinition.rootProperty) {
|
|
211
|
+
const resolvedProp = resolveProperty(refBySymbolId, refSymbolDefinition.rootProperty, {
|
|
212
|
+
...options,
|
|
213
|
+
depth: depth + 1,
|
|
214
|
+
visited: new Set(visited)
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
resolvedProperty.ofProperty = resolvedProp;
|
|
218
|
+
} else {
|
|
219
|
+
console.warn(`Reference for symbol ${symbolId} has no properties, using type and description only`);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (!resolvedProperty.description) {
|
|
223
|
+
resolvedProperty.description = refSymbol.description || '';
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return resolvedProperty;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// TODO: in the future only symbolId as []? but currently it handles a cases when e.g: `string | Settings`
|
|
230
|
+
// 4. if property is resolve union type
|
|
231
|
+
const isResolveUnion = isResolveUnionRef(property)
|
|
232
|
+
if (isResolveUnion) {
|
|
233
|
+
resolvedProperty.type = DEFINED_DEFINITION_PROPERTY_TYPE.UNION;
|
|
234
|
+
const unionProps = handleUnionTypes(
|
|
235
|
+
refBySymbolId,
|
|
236
|
+
property,
|
|
237
|
+
options
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
if (unionProps.length > 1) {
|
|
241
|
+
resolvedProperty.properties = unionProps;
|
|
242
|
+
} else {
|
|
243
|
+
resolvedProperty.ofProperty = unionProps[0];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Try to create a short merged type
|
|
247
|
+
const shortType = shortMergedType(resolvedProperty);
|
|
248
|
+
|
|
249
|
+
if (shortType) {
|
|
250
|
+
return shortType;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return resolvedProperty
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return property
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* `shortMergedType` attempts to simplify a union type by merging properties into a single type string.
|
|
262
|
+
*/
|
|
263
|
+
function shortMergedType(property: DefinitionProperty): DefinitionProperty | null {
|
|
264
|
+
property = {
|
|
265
|
+
...property,
|
|
266
|
+
symbolDef: {
|
|
267
|
+
...property.symbolDef || {},
|
|
268
|
+
canonical: "", // TODO: support canonical in the future
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// 1. only handle union types
|
|
272
|
+
if (property.type !== DEFINED_DEFINITION_PROPERTY_TYPE.UNION) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const properties = property.ofProperty ? [property.ofProperty] : property.properties || [];
|
|
277
|
+
|
|
278
|
+
// 2. process nested properties first
|
|
279
|
+
const processedProperties = properties.map(prop => {
|
|
280
|
+
// 3. if this property is also a union, try to simplify it
|
|
281
|
+
if (prop.type === DEFINED_DEFINITION_PROPERTY_TYPE.UNION) {
|
|
282
|
+
const shortType = shortMergedType(prop);
|
|
283
|
+
if (shortType) {
|
|
284
|
+
return shortType;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// 4. check one level of prop.properties e.g {type: "Example": properties: [{name: "a", type: "string"}, {name: "b", type: "number"}]}
|
|
289
|
+
const shortType = shortMergedType({
|
|
290
|
+
name: "",
|
|
291
|
+
description: "",
|
|
292
|
+
type: DEFINED_DEFINITION_PROPERTY_TYPE.UNION,
|
|
293
|
+
properties: prop.properties,
|
|
294
|
+
ofProperty: prop.ofProperty,
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
if (shortType) {
|
|
298
|
+
return shortType
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return prop;
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
if (!processedProperties?.length) {
|
|
305
|
+
return null
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// 5. check if all properties are either string literals or primitive types
|
|
309
|
+
const hasOnlySimpleTypes = processedProperties.every(prop => {
|
|
310
|
+
// 6. check for string literals (type starts and ends with quotes)
|
|
311
|
+
if (isLiteralValues(prop.type)) {
|
|
312
|
+
return true
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// 7. check for primitive types also
|
|
316
|
+
return PRIMITIVE_TYPES.has(prop.type);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
if (!hasOnlySimpleTypes) {
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// 8. create merged type string
|
|
324
|
+
const types = processedProperties.map(prop => prop.type);
|
|
325
|
+
const mergedType = types.join(' | ');
|
|
326
|
+
|
|
327
|
+
return {
|
|
328
|
+
...property,
|
|
329
|
+
type: mergedType,
|
|
330
|
+
properties: []
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* @todo: in the future typedoc uniform should handle more union types like `$$union`
|
|
336
|
+
*
|
|
337
|
+
* `handleUnionTypes` processes union types from a definition property.
|
|
338
|
+
*/
|
|
339
|
+
function handleUnionTypes(
|
|
340
|
+
refBySymbolId: { [symbolId: string]: Reference },
|
|
341
|
+
property: DefinitionProperty,
|
|
342
|
+
options?: {
|
|
343
|
+
depth?: number,
|
|
344
|
+
}
|
|
345
|
+
): DefinitionProperty[] {
|
|
346
|
+
property = {
|
|
347
|
+
...property,
|
|
348
|
+
symbolDef: {
|
|
349
|
+
...property.symbolDef || {},
|
|
350
|
+
canonical: "", // TODO: support canonical in the future
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
const symbolIds = Array.isArray(property.symbolDef?.id) ? property.symbolDef.id : [];
|
|
354
|
+
const typeString = property.type
|
|
355
|
+
|
|
356
|
+
const properties: DefinitionProperty[] = [];
|
|
357
|
+
const unionTypeStringsMap: { [key: string]: boolean } = (typeString || "").split("|")
|
|
358
|
+
.map(t => t.trim())
|
|
359
|
+
.reduce((acc, type) => ({
|
|
360
|
+
...acc,
|
|
361
|
+
[type]: true
|
|
362
|
+
}), {});
|
|
363
|
+
|
|
364
|
+
// 1. if we have symbolDef.id array, process those firsi
|
|
365
|
+
if (symbolIds.length > 0) {
|
|
366
|
+
for (const symbolId of symbolIds) {
|
|
367
|
+
const refSymbol = refBySymbolId[symbolId];
|
|
368
|
+
const refSymbolDefinition = refSymbol?.definitions?.[0];
|
|
369
|
+
const ctx = refSymbol?.context as TypeDocReferenceContext;
|
|
370
|
+
|
|
371
|
+
if (refSymbolDefinition) {
|
|
372
|
+
unionTypeStringsMap[ctx.symbolName] = false
|
|
373
|
+
|
|
374
|
+
const propProperties: DefinitionProperty[] = [];
|
|
375
|
+
const prop: DefinitionProperty = {
|
|
376
|
+
name: ctx.symbolName || '',
|
|
377
|
+
type: ctx.symbolName || '',
|
|
378
|
+
description: refSymbol.description || '',
|
|
379
|
+
properties: propProperties,
|
|
380
|
+
symbolDef: {
|
|
381
|
+
id: symbolId,
|
|
382
|
+
canonical: "", // TODO: support canonical in the future
|
|
383
|
+
},
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (refSymbolDefinition.properties.length) {
|
|
387
|
+
for (const prop of refSymbolDefinition.properties) {
|
|
388
|
+
const resolvedProp = resolveProperty(
|
|
389
|
+
refBySymbolId,
|
|
390
|
+
prop,
|
|
391
|
+
options
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
propProperties.push(resolvedProp)
|
|
395
|
+
}
|
|
396
|
+
} else if (refSymbolDefinition.rootProperty) {
|
|
397
|
+
const resolvedProp = resolveProperty(
|
|
398
|
+
refBySymbolId,
|
|
399
|
+
refSymbolDefinition.rootProperty,
|
|
400
|
+
options
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
const shouldMergeUnion = resolvedProp.type === DEFINED_DEFINITION_PROPERTY_TYPE.UNION &&
|
|
404
|
+
resolvedProp.ofProperty?.type &&
|
|
405
|
+
!resolvedProp.properties?.length
|
|
406
|
+
|
|
407
|
+
if (shouldMergeUnion) {
|
|
408
|
+
prop.ofProperty = resolvedProp.ofProperty
|
|
409
|
+
} else {
|
|
410
|
+
prop.ofProperty = resolvedProp
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
properties.push(prop)
|
|
415
|
+
|
|
416
|
+
if (!prop.description) {
|
|
417
|
+
prop.description = refSymbol.description || '';
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// TODO: in the future it should be done via uniform in xyd-sources?
|
|
424
|
+
// 2. then process any remaining types from the type string
|
|
425
|
+
for (const type of Object.keys(unionTypeStringsMap)) {
|
|
426
|
+
const ok = unionTypeStringsMap[type]
|
|
427
|
+
if (!ok) {
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
properties.push({
|
|
432
|
+
name: type,
|
|
433
|
+
type: type,
|
|
434
|
+
description: '',
|
|
435
|
+
properties: []
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
return properties
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* `isResolveUnionRef` checks if the property should be resolved as a union type.
|
|
444
|
+
* It checks if the symbolDef.id is an array or if the type contains a union string to resolve, except literal values.
|
|
445
|
+
*
|
|
446
|
+
* @example: {symbolDef: {id: []}, type: `string | number`}
|
|
447
|
+
* @example: {symbolDef: {id: ["1"]}, type: `string | Logo`}
|
|
448
|
+
* @example: {symbolDef: {id: ["1", "2"]}, type: `Icon | Logo`}
|
|
449
|
+
*/
|
|
450
|
+
function isResolveUnionRef(property: DefinitionProperty): boolean {
|
|
451
|
+
const symbolId = property?.symbolDef?.id
|
|
452
|
+
|
|
453
|
+
const symbolIsArr = (Array.isArray(symbolId) && symbolId.length)
|
|
454
|
+
if (symbolIsArr) {
|
|
455
|
+
return true
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const hasUnionString = (property.type && property.type.includes("|"))
|
|
459
|
+
|
|
460
|
+
if (hasUnionString) {
|
|
461
|
+
const literalValues = isLiteralValues(property.type)
|
|
462
|
+
|
|
463
|
+
if (literalValues) {
|
|
464
|
+
return false // If all types are literal values, do not resolve as union
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return true
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
return false
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* `isLiteralValues` checks if the type is a literal value like: `"opener" | "cosmo" | "picasso"`
|
|
475
|
+
*
|
|
476
|
+
* @example: `"opener" | "cosmo" | "picasso"` - returns true
|
|
477
|
+
* @example: `string | "number` - returns false
|
|
478
|
+
*/
|
|
479
|
+
function isLiteralValues(type: string) {
|
|
480
|
+
const types = type.split("|").map(t => t.trim())
|
|
481
|
+
|
|
482
|
+
return types.every(t =>
|
|
483
|
+
(t.startsWith('"') && t.endsWith('"')) ||
|
|
484
|
+
(t.startsWith("'") && t.endsWith("'"))
|
|
485
|
+
)
|
|
486
|
+
}
|
package/src/index.ts
ADDED
|
File without changes
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
|
|
4
|
+
import * as TypeDoc from 'typedoc';
|
|
5
|
+
import type {TypeDocOptions} from "typedoc";
|
|
6
|
+
//@ts-ignore
|
|
7
|
+
import {PluginOptions} from 'typedoc-plugin-markdown'
|
|
8
|
+
|
|
9
|
+
import {typedocToUniform} from "../src/TypeDocTransformer"
|
|
10
|
+
|
|
11
|
+
async function generateDocs() {
|
|
12
|
+
const options = {
|
|
13
|
+
entryPoints: [
|
|
14
|
+
"example/package-a",
|
|
15
|
+
// "example/package-b",
|
|
16
|
+
],
|
|
17
|
+
plugin: [
|
|
18
|
+
"typedoc-plugin-markdown"
|
|
19
|
+
],
|
|
20
|
+
readme: "none",
|
|
21
|
+
disableSources: true,
|
|
22
|
+
entryPointStrategy: TypeDoc.EntryPointStrategy.Packages,
|
|
23
|
+
|
|
24
|
+
indexFormat: "table",
|
|
25
|
+
useCodeBlocks: true,
|
|
26
|
+
} satisfies Partial<PluginOptions | TypeDocOptions>;
|
|
27
|
+
|
|
28
|
+
const app = await TypeDoc.Application.bootstrapWithPlugins(options);
|
|
29
|
+
const project = await app.convert()
|
|
30
|
+
|
|
31
|
+
if (!project) {
|
|
32
|
+
throw new Error('Failed to generate documentation.');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const jsonOutput = await app.serializer.projectToObject(project, path.resolve("./example"));
|
|
36
|
+
fs.writeFileSync('docs.json', JSON.stringify(jsonOutput, null, 2));
|
|
37
|
+
|
|
38
|
+
await app.generateOutputs(project);
|
|
39
|
+
// await app.generateJson(project, 'docs.json');
|
|
40
|
+
|
|
41
|
+
{
|
|
42
|
+
const projectRaw = fs.readFileSync('docs.json', 'utf-8');
|
|
43
|
+
const projectJson = JSON.parse(projectRaw);
|
|
44
|
+
const ref = typedocToUniform(
|
|
45
|
+
path.resolve("./example"),
|
|
46
|
+
projectJson
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
fs.writeFileSync('references_todo.json', JSON.stringify(ref, null, 2));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// {
|
|
53
|
+
// const loader = new SignatureTextLoader(
|
|
54
|
+
// path.resolve('./example/package-a/src/index.ts')
|
|
55
|
+
// );
|
|
56
|
+
//
|
|
57
|
+
// // TODO: some issues if line number higher than file lines
|
|
58
|
+
// const signature = signatureTextByLine(loader, 15);
|
|
59
|
+
// }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
generateDocs().catch(console.error);
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"jsx": "react-jsx",
|
|
4
|
+
"paths": {
|
|
5
|
+
"@xyd-js/uniform": [
|
|
6
|
+
"../xyd-uniform"
|
|
7
|
+
]
|
|
8
|
+
},
|
|
9
|
+
"target": "ES2020",
|
|
10
|
+
"module": "ESNext",
|
|
11
|
+
"moduleResolution": "node",
|
|
12
|
+
"strict": true,
|
|
13
|
+
"esModuleInterop": true,
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"forceConsistentCasingInFileNames": true,
|
|
16
|
+
"outDir": "./dist",
|
|
17
|
+
"declaration": true,
|
|
18
|
+
"declarationMap": true,
|
|
19
|
+
"incremental": true,
|
|
20
|
+
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo",
|
|
21
|
+
"resolveJsonModule": true
|
|
22
|
+
// Add this line
|
|
23
|
+
},
|
|
24
|
+
"include": [
|
|
25
|
+
"__fixtures__/**/*.ts",
|
|
26
|
+
"__fixtures__/**/*.tsx",
|
|
27
|
+
"__tests__/**/*.ts",
|
|
28
|
+
"__tests__/**/*.tsx",
|
|
29
|
+
"packages/**/*.ts",
|
|
30
|
+
"packages/**/*.tsx",
|
|
31
|
+
"src/**/*.ts",
|
|
32
|
+
"src/**/*.tsx"
|
|
33
|
+
],
|
|
34
|
+
"exclude": [
|
|
35
|
+
"node_modules",
|
|
36
|
+
"dist"
|
|
37
|
+
]
|
|
38
|
+
}
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {defineConfig, Options} from 'tsup';
|
|
2
|
+
|
|
3
|
+
const config: Options = {
|
|
4
|
+
entry: {
|
|
5
|
+
index: 'src/index.ts',
|
|
6
|
+
react: 'packages/react/index.ts',
|
|
7
|
+
ts: 'packages/ts/index.ts',
|
|
8
|
+
},
|
|
9
|
+
format: ['esm', 'cjs'], // Output both ESM and CJS formats
|
|
10
|
+
target: 'node16', // Ensure compatibility with Node.js 16
|
|
11
|
+
dts: {
|
|
12
|
+
entry: {
|
|
13
|
+
index: 'src/index.ts',
|
|
14
|
+
react: 'packages/react/index.ts',
|
|
15
|
+
ts: 'packages/ts/index.ts',
|
|
16
|
+
},
|
|
17
|
+
resolve: true, // Resolve external types
|
|
18
|
+
},
|
|
19
|
+
splitting: false, // Disable code splitting
|
|
20
|
+
sourcemap: true, // Generate source maps
|
|
21
|
+
clean: true, // Clean the output directory before each build
|
|
22
|
+
esbuildOptions: (options) => {
|
|
23
|
+
options.platform = 'node'; // Ensure the platform is set to Node.js
|
|
24
|
+
options.external = [
|
|
25
|
+
'react',
|
|
26
|
+
'fs',
|
|
27
|
+
'path',
|
|
28
|
+
'node:fs',
|
|
29
|
+
'node:fs/promises',
|
|
30
|
+
'typescript', // Mark typescript as external
|
|
31
|
+
'codehike',
|
|
32
|
+
'unist-util-visit',
|
|
33
|
+
'@mdx-js/mdx'
|
|
34
|
+
]; // Mark these modules as external
|
|
35
|
+
options.loader = { '.js': 'jsx' }; // Ensure proper handling of .js files
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default defineConfig(config);
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {defineConfig} from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: 'node',
|
|
7
|
+
include: [
|
|
8
|
+
'__tests__/*.ts',
|
|
9
|
+
'__tests__/**/*.ts',
|
|
10
|
+
'src/**/*.test.ts',
|
|
11
|
+
'packages/ts/**/*.test.ts'
|
|
12
|
+
],
|
|
13
|
+
coverage: {
|
|
14
|
+
provider: 'v8',
|
|
15
|
+
reporter: ['text', 'json', 'html'],
|
|
16
|
+
include: [
|
|
17
|
+
'__tests__/*.ts',
|
|
18
|
+
'__tests__/**/*.ts',
|
|
19
|
+
'src/**/*.ts',
|
|
20
|
+
'packages/ts/**/*.ts'
|
|
21
|
+
],
|
|
22
|
+
exclude: [
|
|
23
|
+
'__tests__/*.test.ts',
|
|
24
|
+
'__tests__/*.d.ts',
|
|
25
|
+
'__tests__/**/*.test.ts',
|
|
26
|
+
'__tests__/**/*.d.ts',
|
|
27
|
+
'src/**/*.test.ts',
|
|
28
|
+
'src/**/*.d.ts',
|
|
29
|
+
'packages/ts/**/*.test.ts',
|
|
30
|
+
'packages/ts/**/*.d.ts'
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|