@storybook/react 6.5.0-alpha.46 → 6.5.0-alpha.49
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/cjs/client/docs/config.js +29 -0
- package/dist/cjs/client/docs/extractArgTypes.js +54 -0
- package/dist/cjs/client/docs/extractProps.js +77 -0
- package/dist/cjs/client/docs/jsxDecorator.js +277 -0
- package/dist/cjs/client/docs/lib/captions.js +18 -0
- package/dist/cjs/client/docs/lib/componentTypes.js +24 -0
- package/dist/cjs/client/docs/lib/defaultValues/createDefaultValue.js +81 -0
- package/dist/cjs/client/docs/lib/defaultValues/createFromRawDefaultProp.js +225 -0
- package/dist/cjs/client/docs/lib/defaultValues/generateArray.js +29 -0
- package/dist/cjs/client/docs/lib/defaultValues/generateObject.js +29 -0
- package/dist/cjs/client/docs/lib/defaultValues/index.js +37 -0
- package/dist/cjs/client/docs/lib/defaultValues/prettyIdentifier.js +34 -0
- package/dist/cjs/client/docs/lib/generateCode.js +89 -0
- package/dist/cjs/client/docs/lib/index.js +63 -0
- package/dist/cjs/client/docs/lib/inspection/acornParser.js +254 -0
- package/dist/cjs/client/docs/lib/inspection/index.js +37 -0
- package/dist/cjs/client/docs/lib/inspection/inspectValue.js +26 -0
- package/dist/cjs/client/docs/lib/inspection/types.js +19 -0
- package/dist/cjs/client/docs/lib/isHtmlTag.js +18 -0
- package/dist/cjs/client/docs/propTypes/createType.js +469 -0
- package/dist/cjs/client/docs/propTypes/generateFuncSignature.js +78 -0
- package/dist/cjs/client/docs/propTypes/handleProp.js +54 -0
- package/dist/cjs/client/docs/propTypes/rawDefaultPropResolvers.js +47 -0
- package/dist/cjs/client/docs/propTypes/sortProps.js +37 -0
- package/dist/cjs/client/docs/react-argtypes.stories.js +129 -0
- package/dist/cjs/client/docs/typeScript/handleProp.js +38 -0
- package/dist/cjs/server/{framework-preset-react-docgen.js → framework-preset-react-docs.js} +19 -9
- package/dist/cjs/server/preset.js +1 -1
- package/dist/esm/client/docs/config.js +16 -0
- package/dist/esm/client/docs/extractArgTypes.js +39 -0
- package/dist/esm/client/docs/extractProps.js +54 -0
- package/dist/esm/client/docs/jsxDecorator.js +218 -0
- package/dist/esm/client/docs/lib/captions.js +6 -0
- package/dist/esm/client/docs/lib/componentTypes.js +9 -0
- package/dist/esm/client/docs/lib/defaultValues/createDefaultValue.js +67 -0
- package/dist/esm/client/docs/lib/defaultValues/createFromRawDefaultProp.js +191 -0
- package/dist/esm/client/docs/lib/defaultValues/generateArray.js +19 -0
- package/dist/esm/client/docs/lib/defaultValues/generateObject.js +19 -0
- package/dist/esm/client/docs/lib/defaultValues/index.js +2 -0
- package/dist/esm/client/docs/lib/defaultValues/prettyIdentifier.js +22 -0
- package/dist/esm/client/docs/lib/generateCode.js +68 -0
- package/dist/esm/client/docs/lib/index.js +4 -0
- package/dist/esm/client/docs/lib/inspection/acornParser.js +213 -0
- package/dist/esm/client/docs/lib/inspection/index.js +2 -0
- package/dist/esm/client/docs/lib/inspection/inspectValue.js +16 -0
- package/dist/esm/client/docs/lib/inspection/types.js +12 -0
- package/dist/esm/client/docs/lib/isHtmlTag.js +6 -0
- package/dist/esm/client/docs/propTypes/createType.js +449 -0
- package/dist/esm/client/docs/propTypes/generateFuncSignature.js +62 -0
- package/dist/esm/client/docs/propTypes/handleProp.js +39 -0
- package/dist/esm/client/docs/propTypes/rawDefaultPropResolvers.js +32 -0
- package/dist/esm/client/docs/propTypes/sortProps.js +24 -0
- package/dist/esm/client/docs/react-argtypes.stories.js +97 -0
- package/dist/esm/client/docs/typeScript/handleProp.js +27 -0
- package/dist/esm/server/{framework-preset-react-docgen.js → framework-preset-react-docs.js} +13 -9
- package/dist/esm/server/preset.js +1 -1
- package/dist/modern/client/docs/config.js +14 -0
- package/dist/modern/client/docs/extractArgTypes.js +38 -0
- package/dist/modern/client/docs/extractProps.js +42 -0
- package/dist/modern/client/docs/jsxDecorator.js +177 -0
- package/dist/modern/client/docs/lib/captions.js +6 -0
- package/dist/modern/client/docs/lib/componentTypes.js +2 -0
- package/dist/modern/client/docs/lib/defaultValues/createDefaultValue.js +72 -0
- package/dist/modern/client/docs/lib/defaultValues/createFromRawDefaultProp.js +181 -0
- package/dist/modern/client/docs/lib/defaultValues/generateArray.js +21 -0
- package/dist/modern/client/docs/lib/defaultValues/generateObject.js +21 -0
- package/dist/modern/client/docs/lib/defaultValues/index.js +2 -0
- package/dist/modern/client/docs/lib/defaultValues/prettyIdentifier.js +24 -0
- package/dist/modern/client/docs/lib/generateCode.js +59 -0
- package/dist/modern/client/docs/lib/index.js +4 -0
- package/dist/modern/client/docs/lib/inspection/acornParser.js +211 -0
- package/dist/modern/client/docs/lib/inspection/index.js +2 -0
- package/dist/modern/client/docs/lib/inspection/inspectValue.js +15 -0
- package/dist/modern/client/docs/lib/inspection/types.js +12 -0
- package/dist/modern/client/docs/lib/isHtmlTag.js +4 -0
- package/dist/modern/client/docs/propTypes/createType.js +446 -0
- package/dist/modern/client/docs/propTypes/generateFuncSignature.js +57 -0
- package/dist/modern/client/docs/propTypes/handleProp.js +39 -0
- package/dist/modern/client/docs/propTypes/rawDefaultPropResolvers.js +31 -0
- package/dist/modern/client/docs/propTypes/sortProps.js +14 -0
- package/dist/modern/client/docs/react-argtypes.stories.js +54 -0
- package/dist/modern/client/docs/typeScript/handleProp.js +28 -0
- package/dist/modern/server/{framework-preset-react-docgen.js → framework-preset-react-docs.js} +13 -9
- package/dist/modern/server/preset.js +1 -1
- package/dist/ts3.4/client/docs/config.d.ts +13 -0
- package/dist/ts3.4/client/docs/extractArgTypes.d.ts +2 -0
- package/dist/ts3.4/client/docs/extractProps.d.ts +5 -0
- package/dist/ts3.4/client/docs/jsxDecorator.d.ts +23 -0
- package/dist/ts3.4/client/docs/lib/captions.d.ts +6 -0
- package/dist/ts3.4/client/docs/lib/componentTypes.d.ts +2 -0
- package/dist/ts3.4/client/docs/lib/defaultValues/createDefaultValue.d.ts +2 -0
- package/dist/ts3.4/client/docs/lib/defaultValues/createFromRawDefaultProp.d.ts +11 -0
- package/dist/ts3.4/client/docs/lib/defaultValues/generateArray.d.ts +3 -0
- package/dist/ts3.4/client/docs/lib/defaultValues/generateObject.d.ts +3 -0
- package/dist/ts3.4/client/docs/lib/defaultValues/index.d.ts +2 -0
- package/dist/ts3.4/client/docs/lib/defaultValues/prettyIdentifier.d.ts +4 -0
- package/dist/ts3.4/client/docs/lib/generateCode.d.ts +3 -0
- package/dist/ts3.4/client/docs/lib/index.d.ts +4 -0
- package/dist/ts3.4/client/docs/lib/inspection/acornParser.d.ts +7 -0
- package/dist/ts3.4/client/docs/lib/inspection/index.d.ts +2 -0
- package/dist/ts3.4/client/docs/lib/inspection/inspectValue.d.ts +2 -0
- package/dist/ts3.4/client/docs/lib/inspection/types.d.ts +50 -0
- package/dist/ts3.4/client/docs/lib/isHtmlTag.d.ts +1 -0
- package/dist/ts3.4/client/docs/propTypes/createType.d.ts +2 -0
- package/dist/ts3.4/client/docs/propTypes/generateFuncSignature.d.ts +4 -0
- package/dist/ts3.4/client/docs/propTypes/handleProp.d.ts +5 -0
- package/dist/ts3.4/client/docs/propTypes/rawDefaultPropResolvers.d.ts +1 -0
- package/dist/ts3.4/client/docs/propTypes/sortProps.d.ts +4 -0
- package/dist/ts3.4/client/docs/react-argtypes.stories.d.ts +1 -0
- package/dist/ts3.4/client/docs/typeScript/handleProp.d.ts +3 -0
- package/dist/ts3.4/server/framework-preset-react-docs.d.ts +6 -0
- package/dist/ts3.9/client/docs/config.d.ts +13 -0
- package/dist/ts3.9/client/docs/extractArgTypes.d.ts +2 -0
- package/dist/ts3.9/client/docs/extractProps.d.ts +5 -0
- package/dist/ts3.9/client/docs/jsxDecorator.d.ts +23 -0
- package/dist/ts3.9/client/docs/lib/captions.d.ts +6 -0
- package/dist/ts3.9/client/docs/lib/componentTypes.d.ts +2 -0
- package/dist/ts3.9/client/docs/lib/defaultValues/createDefaultValue.d.ts +2 -0
- package/dist/ts3.9/client/docs/lib/defaultValues/createFromRawDefaultProp.d.ts +11 -0
- package/dist/ts3.9/client/docs/lib/defaultValues/generateArray.d.ts +3 -0
- package/dist/ts3.9/client/docs/lib/defaultValues/generateObject.d.ts +3 -0
- package/dist/ts3.9/client/docs/lib/defaultValues/index.d.ts +2 -0
- package/dist/ts3.9/client/docs/lib/defaultValues/prettyIdentifier.d.ts +4 -0
- package/dist/ts3.9/client/docs/lib/generateCode.d.ts +3 -0
- package/dist/ts3.9/client/docs/lib/index.d.ts +4 -0
- package/dist/ts3.9/client/docs/lib/inspection/acornParser.d.ts +7 -0
- package/dist/ts3.9/client/docs/lib/inspection/index.d.ts +2 -0
- package/dist/ts3.9/client/docs/lib/inspection/inspectValue.d.ts +2 -0
- package/dist/ts3.9/client/docs/lib/inspection/types.d.ts +50 -0
- package/dist/ts3.9/client/docs/lib/isHtmlTag.d.ts +1 -0
- package/dist/ts3.9/client/docs/propTypes/createType.d.ts +2 -0
- package/dist/ts3.9/client/docs/propTypes/generateFuncSignature.d.ts +4 -0
- package/dist/ts3.9/client/docs/propTypes/handleProp.d.ts +5 -0
- package/dist/ts3.9/client/docs/propTypes/rawDefaultPropResolvers.d.ts +1 -0
- package/dist/ts3.9/client/docs/propTypes/sortProps.d.ts +4 -0
- package/dist/ts3.9/client/docs/react-argtypes.stories.d.ts +1 -0
- package/dist/ts3.9/client/docs/typeScript/handleProp.d.ts +3 -0
- package/dist/ts3.9/client/preview/types-6-0.d.ts +3 -3
- package/dist/ts3.9/client/preview/types-7-0.d.ts +2 -2
- package/dist/ts3.9/server/framework-preset-react-docs.d.ts +6 -0
- package/dist/ts3.9/server/options.d.ts +1 -1
- package/dist/ts3.9/server/preset.d.ts +1 -1
- package/package.json +21 -11
- package/types/index.ts +1 -1
- package/dist/ts3.4/server/framework-preset-react-docgen.d.ts +0 -5
- package/dist/ts3.9/server/framework-preset-react-docgen.d.ts +0 -5
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import isPlainObject from 'lodash/isPlainObject';
|
|
2
|
+
import isFunction from 'lodash/isFunction';
|
|
3
|
+
import isString from 'lodash/isString'; // @ts-ignore
|
|
4
|
+
|
|
5
|
+
import reactElementToJSXString from 'react-element-to-jsx-string';
|
|
6
|
+
import { createSummaryValue, isTooLongForDefaultValueSummary } from '@storybook/docs-tools';
|
|
7
|
+
import { inspectValue } from '../inspection';
|
|
8
|
+
import { generateObject } from './generateObject';
|
|
9
|
+
import { generateArray } from './generateArray';
|
|
10
|
+
import { getPrettyElementIdentifier, getPrettyFuncIdentifier } from './prettyIdentifier';
|
|
11
|
+
import { OBJECT_CAPTION, FUNCTION_CAPTION, ELEMENT_CAPTION } from '../captions';
|
|
12
|
+
import { isHtmlTag } from '../isHtmlTag';
|
|
13
|
+
|
|
14
|
+
function isReactElement(element) {
|
|
15
|
+
return element.$$typeof != null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function extractFunctionName(func, propName) {
|
|
19
|
+
const {
|
|
20
|
+
name
|
|
21
|
+
} = func; // Comparison with the prop name is to discard inferred function names.
|
|
22
|
+
|
|
23
|
+
if (name !== '' && name !== 'anonymous' && name !== propName) {
|
|
24
|
+
return name;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const stringResolver = rawDefaultProp => {
|
|
31
|
+
return createSummaryValue(JSON.stringify(rawDefaultProp));
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
function generateReactObject(rawDefaultProp) {
|
|
35
|
+
const {
|
|
36
|
+
type
|
|
37
|
+
} = rawDefaultProp;
|
|
38
|
+
const {
|
|
39
|
+
displayName
|
|
40
|
+
} = type;
|
|
41
|
+
const jsx = reactElementToJSXString(rawDefaultProp, {});
|
|
42
|
+
|
|
43
|
+
if (displayName != null) {
|
|
44
|
+
const prettyIdentifier = getPrettyElementIdentifier(displayName);
|
|
45
|
+
return createSummaryValue(prettyIdentifier, jsx);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (isString(type)) {
|
|
49
|
+
// This is an HTML element.
|
|
50
|
+
if (isHtmlTag(type)) {
|
|
51
|
+
const jsxCompact = reactElementToJSXString(rawDefaultProp, {
|
|
52
|
+
tabStop: 0
|
|
53
|
+
});
|
|
54
|
+
const jsxSummary = jsxCompact.replace(/\r?\n|\r/g, '');
|
|
55
|
+
|
|
56
|
+
if (!isTooLongForDefaultValueSummary(jsxSummary)) {
|
|
57
|
+
return createSummaryValue(jsxSummary);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return createSummaryValue(ELEMENT_CAPTION, jsx);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const objectResolver = rawDefaultProp => {
|
|
66
|
+
if (isReactElement(rawDefaultProp) && rawDefaultProp.type != null) {
|
|
67
|
+
return generateReactObject(rawDefaultProp);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (isPlainObject(rawDefaultProp)) {
|
|
71
|
+
const inspectionResult = inspectValue(JSON.stringify(rawDefaultProp));
|
|
72
|
+
return generateObject(inspectionResult);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (Array.isArray(rawDefaultProp)) {
|
|
76
|
+
const inspectionResult = inspectValue(JSON.stringify(rawDefaultProp));
|
|
77
|
+
return generateArray(inspectionResult);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return createSummaryValue(OBJECT_CAPTION);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const functionResolver = (rawDefaultProp, propDef) => {
|
|
84
|
+
let isElement = false;
|
|
85
|
+
let inspectionResult; // Try to display the name of the component. The body of the component is omitted since the code has been transpiled.
|
|
86
|
+
|
|
87
|
+
if (isFunction(rawDefaultProp.render)) {
|
|
88
|
+
isElement = true;
|
|
89
|
+
} else if (rawDefaultProp.prototype != null && isFunction(rawDefaultProp.prototype.render)) {
|
|
90
|
+
isElement = true;
|
|
91
|
+
} else {
|
|
92
|
+
let innerElement;
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
inspectionResult = inspectValue(rawDefaultProp.toString());
|
|
96
|
+
const {
|
|
97
|
+
hasParams,
|
|
98
|
+
params
|
|
99
|
+
} = inspectionResult.inferredType;
|
|
100
|
+
|
|
101
|
+
if (hasParams) {
|
|
102
|
+
// It might be a functional component accepting props.
|
|
103
|
+
if (params.length === 1 && params[0].type === 'ObjectPattern') {
|
|
104
|
+
innerElement = rawDefaultProp({});
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
innerElement = rawDefaultProp();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (innerElement != null) {
|
|
111
|
+
if (isReactElement(innerElement)) {
|
|
112
|
+
isElement = true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} catch (e) {// do nothing.
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const funcName = extractFunctionName(rawDefaultProp, propDef.name);
|
|
120
|
+
|
|
121
|
+
if (funcName != null) {
|
|
122
|
+
if (isElement) {
|
|
123
|
+
return createSummaryValue(getPrettyElementIdentifier(funcName));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (inspectionResult != null) {
|
|
127
|
+
inspectionResult = inspectValue(rawDefaultProp.toString());
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const {
|
|
131
|
+
hasParams
|
|
132
|
+
} = inspectionResult.inferredType;
|
|
133
|
+
return createSummaryValue(getPrettyFuncIdentifier(funcName, hasParams));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return createSummaryValue(isElement ? ELEMENT_CAPTION : FUNCTION_CAPTION);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const defaultResolver = rawDefaultProp => {
|
|
140
|
+
return createSummaryValue(rawDefaultProp.toString());
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const DEFAULT_TYPE_RESOLVERS = {
|
|
144
|
+
string: stringResolver,
|
|
145
|
+
object: objectResolver,
|
|
146
|
+
function: functionResolver,
|
|
147
|
+
default: defaultResolver
|
|
148
|
+
};
|
|
149
|
+
export function createTypeResolvers(customResolvers = {}) {
|
|
150
|
+
return Object.assign({}, DEFAULT_TYPE_RESOLVERS, customResolvers);
|
|
151
|
+
} // When react-docgen cannot provide a defaultValue we take it from the raw defaultProp.
|
|
152
|
+
// It works fine for types that are not transpiled. For the types that are transpiled, we can only provide partial support.
|
|
153
|
+
// This means that:
|
|
154
|
+
// - The detail might not be available.
|
|
155
|
+
// - Identifiers might not be "prettified" for all the types.
|
|
156
|
+
|
|
157
|
+
export function createDefaultValueFromRawDefaultProp(rawDefaultProp, propDef, typeResolvers = DEFAULT_TYPE_RESOLVERS) {
|
|
158
|
+
try {
|
|
159
|
+
// Keep the extra () otherwise it will fail for functions.
|
|
160
|
+
switch (typeof rawDefaultProp) {
|
|
161
|
+
case 'string':
|
|
162
|
+
return typeResolvers.string(rawDefaultProp, propDef);
|
|
163
|
+
|
|
164
|
+
case 'object':
|
|
165
|
+
return typeResolvers.object(rawDefaultProp, propDef);
|
|
166
|
+
|
|
167
|
+
case 'function':
|
|
168
|
+
{
|
|
169
|
+
return typeResolvers.function(rawDefaultProp, propDef);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
default:
|
|
173
|
+
return typeResolvers.default(rawDefaultProp, propDef);
|
|
174
|
+
}
|
|
175
|
+
} catch (e) {
|
|
176
|
+
// eslint-disable-next-line no-console
|
|
177
|
+
console.error(e);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createSummaryValue, isTooLongForDefaultValueSummary } from '@storybook/docs-tools';
|
|
2
|
+
import { ARRAY_CAPTION } from '../captions';
|
|
3
|
+
import { generateArrayCode } from '../generateCode';
|
|
4
|
+
export function generateArray({
|
|
5
|
+
inferredType,
|
|
6
|
+
ast
|
|
7
|
+
}) {
|
|
8
|
+
const {
|
|
9
|
+
depth
|
|
10
|
+
} = inferredType;
|
|
11
|
+
|
|
12
|
+
if (depth <= 2) {
|
|
13
|
+
const compactArray = generateArrayCode(ast, true);
|
|
14
|
+
|
|
15
|
+
if (!isTooLongForDefaultValueSummary(compactArray)) {
|
|
16
|
+
return createSummaryValue(compactArray);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return createSummaryValue(ARRAY_CAPTION, generateArrayCode(ast));
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createSummaryValue, isTooLongForDefaultValueSummary } from '@storybook/docs-tools';
|
|
2
|
+
import { OBJECT_CAPTION } from '../captions';
|
|
3
|
+
import { generateObjectCode } from '../generateCode';
|
|
4
|
+
export function generateObject({
|
|
5
|
+
inferredType,
|
|
6
|
+
ast
|
|
7
|
+
}) {
|
|
8
|
+
const {
|
|
9
|
+
depth
|
|
10
|
+
} = inferredType;
|
|
11
|
+
|
|
12
|
+
if (depth === 1) {
|
|
13
|
+
const compactObject = generateObjectCode(ast, true);
|
|
14
|
+
|
|
15
|
+
if (!isTooLongForDefaultValueSummary(compactObject)) {
|
|
16
|
+
return createSummaryValue(compactObject);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return createSummaryValue(OBJECT_CAPTION, generateObjectCode(ast));
|
|
21
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { InspectionType } from '../inspection';
|
|
2
|
+
export function getPrettyIdentifier(inferredType) {
|
|
3
|
+
const {
|
|
4
|
+
type,
|
|
5
|
+
identifier
|
|
6
|
+
} = inferredType;
|
|
7
|
+
|
|
8
|
+
switch (type) {
|
|
9
|
+
case InspectionType.FUNCTION:
|
|
10
|
+
return getPrettyFuncIdentifier(identifier, inferredType.hasParams);
|
|
11
|
+
|
|
12
|
+
case InspectionType.ELEMENT:
|
|
13
|
+
return getPrettyElementIdentifier(identifier);
|
|
14
|
+
|
|
15
|
+
default:
|
|
16
|
+
return identifier;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function getPrettyFuncIdentifier(identifier, hasArguments) {
|
|
20
|
+
return hasArguments ? `${identifier}( ... )` : `${identifier}()`;
|
|
21
|
+
}
|
|
22
|
+
export function getPrettyElementIdentifier(identifier) {
|
|
23
|
+
return `<${identifier} />`;
|
|
24
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { generate } from 'escodegen';
|
|
2
|
+
import dedent from 'ts-dedent';
|
|
3
|
+
const BASIC_OPTIONS = {
|
|
4
|
+
format: {
|
|
5
|
+
indent: {
|
|
6
|
+
style: ' '
|
|
7
|
+
},
|
|
8
|
+
semicolons: false
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const COMPACT_OPTIONS = Object.assign({}, BASIC_OPTIONS, {
|
|
12
|
+
format: {
|
|
13
|
+
newline: ''
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
const PRETTY_OPTIONS = Object.assign({}, BASIC_OPTIONS);
|
|
17
|
+
export function generateCode(ast, compact = false) {
|
|
18
|
+
return generate(ast, compact ? COMPACT_OPTIONS : PRETTY_OPTIONS);
|
|
19
|
+
}
|
|
20
|
+
export function generateObjectCode(ast, compact = false) {
|
|
21
|
+
return !compact ? generateCode(ast) : generateCompactObjectCode(ast);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function generateCompactObjectCode(ast) {
|
|
25
|
+
let result = generateCode(ast, true); // Cannot get escodegen to add a space before the last } with the compact mode settings.
|
|
26
|
+
// Fix it until a better solution is found.
|
|
27
|
+
|
|
28
|
+
if (!result.endsWith(' }')) {
|
|
29
|
+
result = `${result.slice(0, -1)} }`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function generateArrayCode(ast, compact = false) {
|
|
36
|
+
return !compact ? generateMultilineArrayCode(ast) : generateCompactArrayCode(ast);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function generateMultilineArrayCode(ast) {
|
|
40
|
+
let result = generateCode(ast); // escodegen add extra spacing before the closing bracket of a multiple line array with a nested object.
|
|
41
|
+
// Fix it until a better solution is found.
|
|
42
|
+
|
|
43
|
+
if (result.endsWith(' }]')) {
|
|
44
|
+
result = dedent(result);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function generateCompactArrayCode(ast) {
|
|
51
|
+
let result = generateCode(ast, true); // escodegen add extra an extra before the opening bracket of a compact array that contains primitive values.
|
|
52
|
+
// Fix it until a better solution is found.
|
|
53
|
+
|
|
54
|
+
if (result.startsWith('[ ')) {
|
|
55
|
+
result = result.replace('[ ', '[');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { Parser } from 'acorn';
|
|
2
|
+
import jsx from 'acorn-jsx';
|
|
3
|
+
import * as acornWalk from 'acorn-walk';
|
|
4
|
+
import { InspectionType } from './types';
|
|
5
|
+
const ACORN_WALK_VISITORS = Object.assign({}, acornWalk.base, {
|
|
6
|
+
JSXElement: () => {}
|
|
7
|
+
});
|
|
8
|
+
const acornParser = Parser.extend(jsx()); // Cannot use "estree.Identifier" type because this function also support "JSXIdentifier".
|
|
9
|
+
|
|
10
|
+
function extractIdentifierName(identifierNode) {
|
|
11
|
+
return identifierNode != null ? identifierNode.name : null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function filterAncestors(ancestors) {
|
|
15
|
+
return ancestors.filter(x => x.type === 'ObjectExpression' || x.type === 'ArrayExpression');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function calculateNodeDepth(node) {
|
|
19
|
+
const depths = [];
|
|
20
|
+
acornWalk.ancestor( // @ts-ignore
|
|
21
|
+
node, {
|
|
22
|
+
ObjectExpression(_, ancestors) {
|
|
23
|
+
depths.push(filterAncestors(ancestors).length);
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
ArrayExpression(_, ancestors) {
|
|
27
|
+
depths.push(filterAncestors(ancestors).length);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
}, ACORN_WALK_VISITORS);
|
|
31
|
+
return Math.max(...depths);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function parseIdentifier(identifierNode) {
|
|
35
|
+
return {
|
|
36
|
+
inferredType: {
|
|
37
|
+
type: InspectionType.IDENTIFIER,
|
|
38
|
+
identifier: extractIdentifierName(identifierNode)
|
|
39
|
+
},
|
|
40
|
+
ast: identifierNode
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function parseLiteral(literalNode) {
|
|
45
|
+
return {
|
|
46
|
+
inferredType: {
|
|
47
|
+
type: InspectionType.LITERAL
|
|
48
|
+
},
|
|
49
|
+
ast: literalNode
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function parseFunction(funcNode) {
|
|
54
|
+
let innerJsxElementNode; // If there is at least a JSXElement in the body of the function, then it's a React component.
|
|
55
|
+
|
|
56
|
+
acornWalk.simple( // @ts-ignore
|
|
57
|
+
funcNode.body, {
|
|
58
|
+
JSXElement(node) {
|
|
59
|
+
innerJsxElementNode = node;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
}, ACORN_WALK_VISITORS);
|
|
63
|
+
const isJsx = innerJsxElementNode != null;
|
|
64
|
+
const inferredType = {
|
|
65
|
+
type: isJsx ? InspectionType.ELEMENT : InspectionType.FUNCTION,
|
|
66
|
+
params: funcNode.params,
|
|
67
|
+
hasParams: funcNode.params.length !== 0
|
|
68
|
+
};
|
|
69
|
+
const identifierName = extractIdentifierName(funcNode.id);
|
|
70
|
+
|
|
71
|
+
if (identifierName != null) {
|
|
72
|
+
inferredType.identifier = identifierName;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
inferredType,
|
|
77
|
+
ast: funcNode
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function parseClass(classNode) {
|
|
82
|
+
let innerJsxElementNode; // If there is at least a JSXElement in the body of the class, then it's a React component.
|
|
83
|
+
|
|
84
|
+
acornWalk.simple( // @ts-ignore
|
|
85
|
+
classNode.body, {
|
|
86
|
+
JSXElement(node) {
|
|
87
|
+
innerJsxElementNode = node;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
}, ACORN_WALK_VISITORS);
|
|
91
|
+
const inferredType = {
|
|
92
|
+
type: innerJsxElementNode != null ? InspectionType.ELEMENT : InspectionType.CLASS,
|
|
93
|
+
identifier: extractIdentifierName(classNode.id)
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
inferredType,
|
|
97
|
+
ast: classNode
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function parseJsxElement(jsxElementNode) {
|
|
102
|
+
const inferredType = {
|
|
103
|
+
type: InspectionType.ELEMENT
|
|
104
|
+
};
|
|
105
|
+
const identifierName = extractIdentifierName(jsxElementNode.openingElement.name);
|
|
106
|
+
|
|
107
|
+
if (identifierName != null) {
|
|
108
|
+
inferredType.identifier = identifierName;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
inferredType,
|
|
113
|
+
ast: jsxElementNode
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function parseCall(callNode) {
|
|
118
|
+
const identifierNode = callNode.callee.type === 'MemberExpression' ? callNode.callee.property : callNode.callee;
|
|
119
|
+
const identifierName = extractIdentifierName(identifierNode);
|
|
120
|
+
|
|
121
|
+
if (identifierName === 'shape') {
|
|
122
|
+
return parseObject(callNode.arguments[0]);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function parseObject(objectNode) {
|
|
129
|
+
return {
|
|
130
|
+
inferredType: {
|
|
131
|
+
type: InspectionType.OBJECT,
|
|
132
|
+
depth: calculateNodeDepth(objectNode)
|
|
133
|
+
},
|
|
134
|
+
ast: objectNode
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function parseArray(arrayNode) {
|
|
139
|
+
return {
|
|
140
|
+
inferredType: {
|
|
141
|
+
type: InspectionType.ARRAY,
|
|
142
|
+
depth: calculateNodeDepth(arrayNode)
|
|
143
|
+
},
|
|
144
|
+
ast: arrayNode
|
|
145
|
+
};
|
|
146
|
+
} // Cannot set "expression" type to "estree.Expression" because the type doesn't include JSX.
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
function parseExpression(expression) {
|
|
150
|
+
switch (expression.type) {
|
|
151
|
+
case 'Identifier':
|
|
152
|
+
return parseIdentifier(expression);
|
|
153
|
+
|
|
154
|
+
case 'Literal':
|
|
155
|
+
return parseLiteral(expression);
|
|
156
|
+
|
|
157
|
+
case 'FunctionExpression':
|
|
158
|
+
case 'ArrowFunctionExpression':
|
|
159
|
+
return parseFunction(expression);
|
|
160
|
+
|
|
161
|
+
case 'ClassExpression':
|
|
162
|
+
return parseClass(expression);
|
|
163
|
+
|
|
164
|
+
case 'JSXElement':
|
|
165
|
+
return parseJsxElement(expression);
|
|
166
|
+
|
|
167
|
+
case 'CallExpression':
|
|
168
|
+
return parseCall(expression);
|
|
169
|
+
|
|
170
|
+
case 'ObjectExpression':
|
|
171
|
+
return parseObject(expression);
|
|
172
|
+
|
|
173
|
+
case 'ArrayExpression':
|
|
174
|
+
return parseArray(expression);
|
|
175
|
+
|
|
176
|
+
default:
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function parse(value) {
|
|
182
|
+
const ast = acornParser.parse(`(${value})`);
|
|
183
|
+
let parsingResult = {
|
|
184
|
+
inferredType: {
|
|
185
|
+
type: InspectionType.UNKNOWN
|
|
186
|
+
},
|
|
187
|
+
ast
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
if (ast.body[0] != null) {
|
|
191
|
+
const rootNode = ast.body[0];
|
|
192
|
+
|
|
193
|
+
switch (rootNode.type) {
|
|
194
|
+
case 'ExpressionStatement':
|
|
195
|
+
{
|
|
196
|
+
const expressionResult = parseExpression(rootNode.expression);
|
|
197
|
+
|
|
198
|
+
if (expressionResult != null) {
|
|
199
|
+
parsingResult = expressionResult;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
default:
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return parsingResult;
|
|
211
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { parse } from './acornParser';
|
|
2
|
+
import { InspectionType } from './types';
|
|
3
|
+
export function inspectValue(value) {
|
|
4
|
+
try {
|
|
5
|
+
const parsingResult = parse(value);
|
|
6
|
+
return Object.assign({}, parsingResult);
|
|
7
|
+
} catch (e) {// do nothing.
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
inferredType: {
|
|
12
|
+
type: InspectionType.UNKNOWN
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export let InspectionType;
|
|
2
|
+
|
|
3
|
+
(function (InspectionType) {
|
|
4
|
+
InspectionType["IDENTIFIER"] = "Identifier";
|
|
5
|
+
InspectionType["LITERAL"] = "Literal";
|
|
6
|
+
InspectionType["OBJECT"] = "Object";
|
|
7
|
+
InspectionType["ARRAY"] = "Array";
|
|
8
|
+
InspectionType["FUNCTION"] = "Function";
|
|
9
|
+
InspectionType["CLASS"] = "Class";
|
|
10
|
+
InspectionType["ELEMENT"] = "Element";
|
|
11
|
+
InspectionType["UNKNOWN"] = "Unknown";
|
|
12
|
+
})(InspectionType || (InspectionType = {}));
|