@atlaskit/forge-react-types 0.14.0 → 0.14.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/CHANGELOG.md +88 -83
- package/LICENSE.md +6 -8
- package/dist/types/components/__generated__/ButtonProps.codegen.d.ts +1 -1
- package/dist/types/components/__generated__/CheckboxGroupProps.codegen.d.ts +2 -2
- package/dist/types/components/__generated__/DatePickerProps.codegen.d.ts +1 -1
- package/dist/types/components/__generated__/FormProps.codegen.d.ts +2 -2
- package/dist/types/components/__generated__/IconProps.codegen.d.ts +2 -2
- package/dist/types/components/__generated__/ListItemProps.codegen.d.ts +2 -2
- package/dist/types/components/__generated__/ListProps.codegen.d.ts +2 -2
- package/dist/types/components/__generated__/types.codegen.d.ts +2 -2
- package/dist/types-ts4.5/components/__generated__/ButtonProps.codegen.d.ts +1 -1
- package/dist/types-ts4.5/components/__generated__/CheckboxGroupProps.codegen.d.ts +2 -2
- package/dist/types-ts4.5/components/__generated__/DatePickerProps.codegen.d.ts +1 -1
- package/dist/types-ts4.5/components/__generated__/FormProps.codegen.d.ts +2 -2
- package/dist/types-ts4.5/components/__generated__/IconProps.codegen.d.ts +2 -2
- package/dist/types-ts4.5/components/__generated__/ListItemProps.codegen.d.ts +2 -2
- package/dist/types-ts4.5/components/__generated__/ListProps.codegen.d.ts +2 -2
- package/dist/types-ts4.5/components/__generated__/types.codegen.d.ts +2 -2
- package/package.json +7 -9
- package/scripts/codegen/codeGenerator.ts +306 -347
- package/scripts/codegen/componentPropTypes.ts +167 -212
- package/scripts/codegen-runner.ts +4 -4
- package/src/components/__generated__/ButtonProps.codegen.tsx +358 -358
- package/src/components/__generated__/CheckboxGroupProps.codegen.tsx +8 -8
- package/src/components/__generated__/DatePickerProps.codegen.tsx +12 -12
- package/src/components/__generated__/FormProps.codegen.tsx +4 -4
- package/src/components/__generated__/IconProps.codegen.tsx +364 -364
- package/src/components/__generated__/ListItemProps.codegen.tsx +3 -3
- package/src/components/__generated__/ListProps.codegen.tsx +4 -4
- package/src/components/__generated__/types.codegen.ts +20 -20
- package/src/index.ts +58 -58
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
type Symbol,
|
|
4
|
+
type SourceFile,
|
|
5
|
+
type TypeAliasDeclaration,
|
|
6
|
+
type ImportDeclaration,
|
|
7
7
|
} from 'ts-morph';
|
|
8
8
|
|
|
9
9
|
const getNames = (symbol: Symbol) => {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const name = symbol.getName();
|
|
11
|
+
return [name, symbol.getAliasedSymbol()?.getName() ?? name];
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
const getDeclaration = (symbol: Symbol) => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
return declaration;
|
|
15
|
+
const declaration = symbol.getDeclarations()[0];
|
|
16
|
+
if (!declaration) {
|
|
17
|
+
throw new Error('Could not find declaration for symbol: ' + symbol.getName());
|
|
18
|
+
}
|
|
19
|
+
return declaration;
|
|
22
20
|
};
|
|
23
21
|
|
|
24
22
|
/**
|
|
@@ -29,22 +27,18 @@ const getDeclaration = (symbol: Symbol) => {
|
|
|
29
27
|
* that was extracted from the component index file.
|
|
30
28
|
* @return {Symbol} the base component symbol that is defined in the source file.
|
|
31
29
|
*/
|
|
32
|
-
const getBaseComponentSymbol = (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
componentSymbol.getName(),
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
return symbol;
|
|
30
|
+
const getBaseComponentSymbol = (componentSymbol: Symbol, sourceFile: SourceFile) => {
|
|
31
|
+
const symbol = sourceFile.getExportSymbols().find((symbol) => {
|
|
32
|
+
// The base component symbol can be aliased, so we need to check both the
|
|
33
|
+
// symbol name and the aliased symbol name.
|
|
34
|
+
return getNames(componentSymbol).includes(symbol.getName());
|
|
35
|
+
});
|
|
36
|
+
if (!symbol) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
'Could not find base component symbol for component: ' + componentSymbol.getName(),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
return symbol;
|
|
48
42
|
};
|
|
49
43
|
|
|
50
44
|
/**
|
|
@@ -57,20 +51,17 @@ const getBaseComponentSymbol = (
|
|
|
57
51
|
*
|
|
58
52
|
* This function will extract the PlatformButtonProps type declaration.
|
|
59
53
|
*/
|
|
60
|
-
const getDependentTypeDeclarations = (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
return declarations;
|
|
73
|
-
}, [] as Array<TypeAliasDeclaration>);
|
|
54
|
+
const getDependentTypeDeclarations = (baseComponentPropSymbol: Symbol, sourceFile: SourceFile) => {
|
|
55
|
+
return sourceFile.getTypeAliases().reduce((declarations, typeAlias) => {
|
|
56
|
+
const typeAliasName = typeAlias.getName();
|
|
57
|
+
if (
|
|
58
|
+
typeAliasName !== baseComponentPropSymbol.getName() &&
|
|
59
|
+
getDeclaration(baseComponentPropSymbol).getText().includes(typeAliasName)
|
|
60
|
+
) {
|
|
61
|
+
declarations.push(typeAlias);
|
|
62
|
+
}
|
|
63
|
+
return declarations;
|
|
64
|
+
}, [] as Array<TypeAliasDeclaration>);
|
|
74
65
|
};
|
|
75
66
|
|
|
76
67
|
/**
|
|
@@ -83,20 +74,20 @@ const getDependentTypeDeclarations = (
|
|
|
83
74
|
* }
|
|
84
75
|
*/
|
|
85
76
|
const getImportedNames = (importDeclaration: ImportDeclaration) => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
77
|
+
return {
|
|
78
|
+
default: importDeclaration.getDefaultImport()?.getText() ?? null,
|
|
79
|
+
named: importDeclaration
|
|
80
|
+
.getNamedImports()
|
|
81
|
+
.map((specifier) => {
|
|
82
|
+
return specifier.getAliasNode()?.getText() ?? specifier.getName();
|
|
83
|
+
})
|
|
84
|
+
.filter((name) => !!name) as string[],
|
|
85
|
+
};
|
|
95
86
|
};
|
|
96
87
|
|
|
97
88
|
const isTokenUsed = (token: string, codes: string[]) => {
|
|
98
|
-
|
|
99
|
-
|
|
89
|
+
const check = new RegExp(`\\b${token}\\b`);
|
|
90
|
+
return codes.some((code) => check.test(code));
|
|
100
91
|
};
|
|
101
92
|
|
|
102
93
|
/**
|
|
@@ -105,163 +96,146 @@ const isTokenUsed = (token: string, codes: string[]) => {
|
|
|
105
96
|
* This is for solving the edge case raised from DynamicTableProps.
|
|
106
97
|
*/
|
|
107
98
|
class ImportDeclarationProxy {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
.join(', ');
|
|
147
|
-
}
|
|
148
|
-
return `${importStatement}{ ${importedNames} } from '${packageName}';`;
|
|
149
|
-
}
|
|
99
|
+
private readonly base: ImportDeclaration;
|
|
100
|
+
|
|
101
|
+
private removedNamedImports = new Set<string>();
|
|
102
|
+
|
|
103
|
+
constructor(base: ImportDeclaration) {
|
|
104
|
+
this.base = base;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
public removeNamedImport(namedImport: string) {
|
|
108
|
+
const target = this.base
|
|
109
|
+
.getNamedImports()
|
|
110
|
+
.find((tar) => [tar.getName(), tar.getAliasNode()?.getText()].includes(namedImport));
|
|
111
|
+
if (target) {
|
|
112
|
+
this.removedNamedImports.add(namedImport);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public getText() {
|
|
117
|
+
const code = this.base.getText();
|
|
118
|
+
const match = code.match(/^(import |import type ){(.+)} from ['"](.+)['"];$/);
|
|
119
|
+
if (!match) {
|
|
120
|
+
return this.base.getText();
|
|
121
|
+
}
|
|
122
|
+
let [_, importStatement, importedNames, packageName] = match;
|
|
123
|
+
importedNames = importedNames.trim();
|
|
124
|
+
|
|
125
|
+
if (isSharedUIKit2TypesImport(this.base)) {
|
|
126
|
+
packageName = './types.codegen';
|
|
127
|
+
}
|
|
128
|
+
if (this.removedNamedImports.size > 0) {
|
|
129
|
+
importedNames = importedNames!
|
|
130
|
+
.split(',')
|
|
131
|
+
.map((text) => text.trim())
|
|
132
|
+
.filter((text) => !this.removedNamedImports.has(text))
|
|
133
|
+
.join(', ');
|
|
134
|
+
}
|
|
135
|
+
return `${importStatement}{ ${importedNames} } from '${packageName}';`;
|
|
136
|
+
}
|
|
150
137
|
}
|
|
151
138
|
|
|
152
139
|
const isSharedUIKit2TypesImport = (importDeclaration: ImportDeclaration) => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
);
|
|
140
|
+
return (
|
|
141
|
+
importDeclaration.isTypeOnly() && importDeclaration.getModuleSpecifierValue() === '../../types'
|
|
142
|
+
);
|
|
157
143
|
};
|
|
158
144
|
|
|
159
145
|
const extractImportDeclarations = (
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
146
|
+
sourceFile: SourceFile,
|
|
147
|
+
componentPropSymbol: Symbol,
|
|
148
|
+
dependentTypeDeclarations: TypeAliasDeclaration[],
|
|
163
149
|
) => {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
});
|
|
205
|
-
if (used) {
|
|
206
|
-
declarations.push(declarationProxy);
|
|
207
|
-
}
|
|
208
|
-
return declarations;
|
|
209
|
-
}, []);
|
|
150
|
+
const componentDeclarationCode = getDeclaration(componentPropSymbol).getText();
|
|
151
|
+
|
|
152
|
+
const targetCodes = [
|
|
153
|
+
componentDeclarationCode,
|
|
154
|
+
...dependentTypeDeclarations.map((typeAlias) => typeAlias.getText()).filter((code) => !!code),
|
|
155
|
+
];
|
|
156
|
+
return sourceFile
|
|
157
|
+
.getImportDeclarations()
|
|
158
|
+
.filter((declaration) => {
|
|
159
|
+
const moduleSpecifier = declaration.getModuleSpecifierValue();
|
|
160
|
+
// only keep dependencies from
|
|
161
|
+
// - @atlaskit
|
|
162
|
+
// - react
|
|
163
|
+
// - or '../../types'
|
|
164
|
+
return (
|
|
165
|
+
moduleSpecifier.startsWith('@atlaskit/') ||
|
|
166
|
+
moduleSpecifier === 'react' ||
|
|
167
|
+
isSharedUIKit2TypesImport(declaration)
|
|
168
|
+
);
|
|
169
|
+
})
|
|
170
|
+
.reduce<ImportDeclarationProxy[]>((declarations, declaration) => {
|
|
171
|
+
// further filter out the the imports that are not used in the component specified.
|
|
172
|
+
const importedNames = getImportedNames(declaration);
|
|
173
|
+
const declarationProxy = new ImportDeclarationProxy(declaration);
|
|
174
|
+
let used = false;
|
|
175
|
+
if (importedNames.default && isTokenUsed(importedNames.default, targetCodes)) {
|
|
176
|
+
used = true;
|
|
177
|
+
}
|
|
178
|
+
importedNames.named.forEach((namedImport) => {
|
|
179
|
+
if (isTokenUsed(namedImport, targetCodes)) {
|
|
180
|
+
used = true;
|
|
181
|
+
} else {
|
|
182
|
+
declarationProxy.removeNamedImport(namedImport);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
if (used) {
|
|
186
|
+
declarations.push(declarationProxy);
|
|
187
|
+
}
|
|
188
|
+
return declarations;
|
|
189
|
+
}, []);
|
|
210
190
|
};
|
|
211
191
|
|
|
212
192
|
const getTypeDeclarationCodeFromImport = (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
193
|
+
sourceFile: SourceFile,
|
|
194
|
+
packageName: string,
|
|
195
|
+
typeName: string,
|
|
216
196
|
) => {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
?.getText();
|
|
253
|
-
if (!typeDeclarationCode) {
|
|
254
|
-
return null;
|
|
255
|
-
}
|
|
256
|
-
if (importTypeSymbol.getName() !== typeName) {
|
|
257
|
-
return `${typeDeclarationCode}
|
|
197
|
+
const importDeclaration = sourceFile.getImportDeclarationOrThrow(packageName);
|
|
198
|
+
const importSpecifier = importDeclaration
|
|
199
|
+
.getNamedImports()
|
|
200
|
+
.find(
|
|
201
|
+
(specifier) =>
|
|
202
|
+
specifier.getName() === typeName || specifier.getAliasNode()?.getText() === typeName,
|
|
203
|
+
);
|
|
204
|
+
const importTypeSymbol = importSpecifier?.getSymbol()?.getAliasedSymbol();
|
|
205
|
+
if (!importTypeSymbol) {
|
|
206
|
+
throw new Error(`Could not find type for ${typeName} in ${packageName}`);
|
|
207
|
+
}
|
|
208
|
+
const importSourcePath = importTypeSymbol
|
|
209
|
+
.getDeclarations()[0]
|
|
210
|
+
.getType()
|
|
211
|
+
.getText()
|
|
212
|
+
.match(/import\("(.+)"\)/)?.[1];
|
|
213
|
+
if (!importSourcePath) {
|
|
214
|
+
throw new Error(`Could not find import source for ${typeName} in ${packageName}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const importSource = sourceFile.getProject().addSourceFileAtPath(importSourcePath + '.ts');
|
|
218
|
+
try {
|
|
219
|
+
const typeDeclarationCode = importSource
|
|
220
|
+
.getExportSymbols()
|
|
221
|
+
.find(
|
|
222
|
+
(symbol) =>
|
|
223
|
+
symbol.getName() === typeName || symbol.getName() === importTypeSymbol.getName(),
|
|
224
|
+
)
|
|
225
|
+
?.getDeclarations()[0]
|
|
226
|
+
?.getText();
|
|
227
|
+
if (!typeDeclarationCode) {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
if (importTypeSymbol.getName() !== typeName) {
|
|
231
|
+
return `${typeDeclarationCode}
|
|
258
232
|
type ${typeName} = ${importTypeSymbol.getName()};
|
|
259
233
|
`;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
234
|
+
}
|
|
235
|
+
return typeDeclarationCode;
|
|
236
|
+
} finally {
|
|
237
|
+
sourceFile.getProject().removeSourceFile(importSource);
|
|
238
|
+
}
|
|
265
239
|
};
|
|
266
240
|
|
|
267
241
|
/**
|
|
@@ -270,178 +244,163 @@ type ${typeName} = ${importTypeSymbol.getName()};
|
|
|
270
244
|
* types and not on any other package types.
|
|
271
245
|
*/
|
|
272
246
|
const resolveExternalTypesCode = (
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
247
|
+
sourceFile: SourceFile,
|
|
248
|
+
componentPropSymbol: Symbol,
|
|
249
|
+
dependentTypeDeclarations: TypeAliasDeclaration[],
|
|
276
250
|
) => {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
);
|
|
317
|
-
})
|
|
318
|
-
.filter((code) => !!code)
|
|
319
|
-
.join('\n');
|
|
320
|
-
|
|
321
|
-
return !!declarationCode ? declarationCode : null;
|
|
251
|
+
// resolve types from @atlassian/forge-ui-types
|
|
252
|
+
const forgeUITypesImports = sourceFile.getImportDeclarations().filter((declaration) => {
|
|
253
|
+
const moduleSpecifier = declaration.getModuleSpecifierValue();
|
|
254
|
+
return moduleSpecifier === '@atlassian/forge-ui-types';
|
|
255
|
+
});
|
|
256
|
+
if (forgeUITypesImports.length === 0) {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// only the type name that are used in the component prop type should be
|
|
261
|
+
// resolved
|
|
262
|
+
const targetImportedTypeNames = forgeUITypesImports.reduce<string[]>(
|
|
263
|
+
(importedTypeNames, imports) => {
|
|
264
|
+
const names = getImportedNames(imports);
|
|
265
|
+
const targetCodes = [
|
|
266
|
+
getDeclaration(componentPropSymbol).getText(),
|
|
267
|
+
...dependentTypeDeclarations.map((typeAlias) => typeAlias.getText()),
|
|
268
|
+
];
|
|
269
|
+
[names.default, ...names.named].forEach((importName) => {
|
|
270
|
+
if (
|
|
271
|
+
importName &&
|
|
272
|
+
!importedTypeNames.includes(importName) &&
|
|
273
|
+
isTokenUsed(importName, targetCodes)
|
|
274
|
+
) {
|
|
275
|
+
importedTypeNames.push(importName);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
return importedTypeNames;
|
|
279
|
+
},
|
|
280
|
+
[],
|
|
281
|
+
);
|
|
282
|
+
const declarationCode = targetImportedTypeNames
|
|
283
|
+
.map((typeName) => {
|
|
284
|
+
return getTypeDeclarationCodeFromImport(sourceFile, '@atlassian/forge-ui-types', typeName);
|
|
285
|
+
})
|
|
286
|
+
.filter((code) => !!code)
|
|
287
|
+
.join('\n');
|
|
288
|
+
|
|
289
|
+
return !!declarationCode ? declarationCode : null;
|
|
322
290
|
};
|
|
323
291
|
|
|
324
292
|
type CodeConsolidator = (context: {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
293
|
+
sourceFile: SourceFile;
|
|
294
|
+
importCode?: string | null;
|
|
295
|
+
externalTypesCode?: string | null;
|
|
296
|
+
dependentTypeCode?: string | null;
|
|
297
|
+
componentPropCode?: string | null;
|
|
330
298
|
}) => string;
|
|
331
299
|
|
|
332
300
|
const consolidateCodeSections: CodeConsolidator = ({
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
301
|
+
importCode,
|
|
302
|
+
externalTypesCode,
|
|
303
|
+
dependentTypeCode,
|
|
304
|
+
componentPropCode,
|
|
337
305
|
}) => {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
306
|
+
return [importCode, externalTypesCode, dependentTypeCode, componentPropCode]
|
|
307
|
+
.filter((code) => !!code)
|
|
308
|
+
.join('\n\n');
|
|
341
309
|
};
|
|
342
310
|
|
|
343
311
|
const baseGenerateComponentPropTypeSourceCode = (
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
312
|
+
componentPropSymbol: Symbol,
|
|
313
|
+
sourceFile: SourceFile,
|
|
314
|
+
customConsolidator?: CodeConsolidator,
|
|
347
315
|
) => {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
importCode,
|
|
386
|
-
externalTypesCode,
|
|
387
|
-
dependentTypeCode,
|
|
388
|
-
componentPropCode,
|
|
389
|
-
});
|
|
316
|
+
// 1) extract the prop types from the source file
|
|
317
|
+
const baseComponentPropSymbol = getBaseComponentSymbol(componentPropSymbol, sourceFile);
|
|
318
|
+
|
|
319
|
+
// 2) from the prop type code further extract other relevant types in the source file
|
|
320
|
+
const dependentTypeDeclarations = getDependentTypeDeclarations(
|
|
321
|
+
baseComponentPropSymbol,
|
|
322
|
+
sourceFile,
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
// 3) extract the import statement
|
|
326
|
+
const importDeclarations = extractImportDeclarations(
|
|
327
|
+
sourceFile,
|
|
328
|
+
baseComponentPropSymbol,
|
|
329
|
+
dependentTypeDeclarations,
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
// 4) resolve other types definition (not part of the ADS components)
|
|
333
|
+
const externalTypesCode = resolveExternalTypesCode(
|
|
334
|
+
sourceFile,
|
|
335
|
+
baseComponentPropSymbol,
|
|
336
|
+
dependentTypeDeclarations,
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
// 5) generate the source file
|
|
340
|
+
const importCode = importDeclarations.map((declaration) => declaration.getText()).join('\n');
|
|
341
|
+
const dependentTypeCode = dependentTypeDeclarations
|
|
342
|
+
.map((typeAlias) => typeAlias.getText())
|
|
343
|
+
.join('\n');
|
|
344
|
+
const componentPropCode = getDeclaration(baseComponentPropSymbol).getText();
|
|
345
|
+
|
|
346
|
+
return (customConsolidator ?? consolidateCodeSections)({
|
|
347
|
+
sourceFile,
|
|
348
|
+
importCode,
|
|
349
|
+
externalTypesCode,
|
|
350
|
+
dependentTypeCode,
|
|
351
|
+
componentPropCode,
|
|
352
|
+
});
|
|
390
353
|
};
|
|
391
354
|
|
|
392
355
|
const boxPropsCodeConsolidator: CodeConsolidator = ({
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
356
|
+
sourceFile,
|
|
357
|
+
importCode,
|
|
358
|
+
externalTypesCode,
|
|
359
|
+
dependentTypeCode,
|
|
360
|
+
componentPropCode,
|
|
398
361
|
}) => {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
.join('\n\n');
|
|
427
|
-
} finally {
|
|
428
|
-
sourceFile.getProject().removeSourceFile(utilsFile);
|
|
429
|
-
}
|
|
362
|
+
const xcssValidator = sourceFile.getVariableDeclarationOrThrow('xcssValidator').getText();
|
|
363
|
+
|
|
364
|
+
const utilsFile = sourceFile
|
|
365
|
+
.getProject()
|
|
366
|
+
.addSourceFileAtPath(require.resolve('@atlassian/forge-ui/utils/xcssValidate'));
|
|
367
|
+
try {
|
|
368
|
+
const xcssValidatorDeclarationCode = utilsFile.getEmitOutput({
|
|
369
|
+
emitOnlyDtsFiles: true,
|
|
370
|
+
}).compilerObject.outputFiles[0].text;
|
|
371
|
+
const xcssValidatorVariableDeclarationCode = [
|
|
372
|
+
xcssValidatorDeclarationCode,
|
|
373
|
+
`const ${xcssValidator};`,
|
|
374
|
+
].join('\n');
|
|
375
|
+
|
|
376
|
+
return [
|
|
377
|
+
'/* eslint-disable @atlaskit/design-system/ensure-design-token-usage/preview */',
|
|
378
|
+
importCode,
|
|
379
|
+
xcssValidatorVariableDeclarationCode,
|
|
380
|
+
externalTypesCode,
|
|
381
|
+
dependentTypeCode,
|
|
382
|
+
componentPropCode,
|
|
383
|
+
]
|
|
384
|
+
.filter((code) => !!code)
|
|
385
|
+
.join('\n\n');
|
|
386
|
+
} finally {
|
|
387
|
+
sourceFile.getProject().removeSourceFile(utilsFile);
|
|
388
|
+
}
|
|
430
389
|
};
|
|
431
390
|
|
|
432
391
|
const codeConsolidators: Record<string, CodeConsolidator> = {
|
|
433
|
-
|
|
392
|
+
BoxProps: boxPropsCodeConsolidator,
|
|
434
393
|
};
|
|
435
394
|
|
|
436
395
|
const generateComponentPropTypeSourceCode = (
|
|
437
|
-
|
|
438
|
-
|
|
396
|
+
componentPropSymbol: Symbol,
|
|
397
|
+
sourceFile: SourceFile,
|
|
439
398
|
) => {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
399
|
+
return baseGenerateComponentPropTypeSourceCode(
|
|
400
|
+
componentPropSymbol,
|
|
401
|
+
sourceFile,
|
|
402
|
+
codeConsolidators[componentPropSymbol.getName()],
|
|
403
|
+
);
|
|
445
404
|
};
|
|
446
405
|
|
|
447
406
|
export { generateComponentPropTypeSourceCode };
|