@suss/contract-storybook 0.30.0 → 0.31.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/dist/index.cjs +31 -88
- package/dist/index.js +40 -91
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -58,7 +58,7 @@ function generateSummariesFromStories(filePaths, options = {}) {
|
|
|
58
58
|
for (const sf of project.getSourceFiles()) {
|
|
59
59
|
const absPath = sf.getFilePath();
|
|
60
60
|
const relPath = import_node_path.default.relative(projectRoot, absPath);
|
|
61
|
-
const meta = extractMeta(sf);
|
|
61
|
+
const meta = extractMeta(sf, resolution);
|
|
62
62
|
if (meta === null) {
|
|
63
63
|
continue;
|
|
64
64
|
}
|
|
@@ -69,72 +69,22 @@ function generateSummariesFromStories(filePaths, options = {}) {
|
|
|
69
69
|
}
|
|
70
70
|
return summaries;
|
|
71
71
|
}
|
|
72
|
-
function extractMeta(sf) {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
for (const decl of defaultExport.getDeclarations()) {
|
|
78
|
-
const objLit = findMetaObjectLiteral(decl);
|
|
79
|
-
if (objLit === null) {
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
const componentProp = objLit.getProperty("component");
|
|
83
|
-
if (componentProp === void 0) {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
if (!componentProp.isKind(import_ts_morph.SyntaxKind.PropertyAssignment)) {
|
|
72
|
+
function extractMeta(sf, resolution) {
|
|
73
|
+
for (const exported of resolution.exportsOf(sf).get("default") ?? []) {
|
|
74
|
+
const meta = objectBehind(exported, resolution);
|
|
75
|
+
if (meta === null) {
|
|
87
76
|
continue;
|
|
88
77
|
}
|
|
89
|
-
const
|
|
90
|
-
if (
|
|
91
|
-
|
|
78
|
+
const component = (0, import_adapter_typescript.propertyOf)(meta, "component", resolution);
|
|
79
|
+
if (component !== null) {
|
|
80
|
+
return { componentName: component.getText() };
|
|
92
81
|
}
|
|
93
|
-
return { componentName: initializer.getText() };
|
|
94
|
-
}
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
function findMetaObjectLiteral(node) {
|
|
98
|
-
if (node.isKind(import_ts_morph.SyntaxKind.ExportAssignment)) {
|
|
99
|
-
return unwrapToObjectLiteral(node.getExpression());
|
|
100
|
-
}
|
|
101
|
-
if (node.isKind(import_ts_morph.SyntaxKind.VariableDeclaration)) {
|
|
102
|
-
const init = node.getInitializer();
|
|
103
|
-
return init === void 0 ? null : unwrapToObjectLiteral(init);
|
|
104
82
|
}
|
|
105
83
|
return null;
|
|
106
84
|
}
|
|
107
|
-
function
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
if (node.isKind(import_ts_morph.SyntaxKind.SatisfiesExpression)) {
|
|
112
|
-
return unwrapToObjectLiteral(node.getExpression());
|
|
113
|
-
}
|
|
114
|
-
if (node.isKind(import_ts_morph.SyntaxKind.ParenthesizedExpression)) {
|
|
115
|
-
return unwrapToObjectLiteral(node.getExpression());
|
|
116
|
-
}
|
|
117
|
-
if (node.isKind(import_ts_morph.SyntaxKind.AsExpression)) {
|
|
118
|
-
return unwrapToObjectLiteral(node.getExpression());
|
|
119
|
-
}
|
|
120
|
-
if (node.isKind(import_ts_morph.SyntaxKind.Identifier)) {
|
|
121
|
-
const sym = node.getSymbol();
|
|
122
|
-
if (sym === void 0) {
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
for (const d of sym.getDeclarations()) {
|
|
126
|
-
if (d.isKind(import_ts_morph.SyntaxKind.VariableDeclaration)) {
|
|
127
|
-
const init = d.getInitializer();
|
|
128
|
-
if (init !== void 0) {
|
|
129
|
-
const unwrapped = unwrapToObjectLiteral(init);
|
|
130
|
-
if (unwrapped !== null) {
|
|
131
|
-
return unwrapped;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return null;
|
|
85
|
+
function objectBehind(value, resolution) {
|
|
86
|
+
const resolved = resolution.resolveObject(value);
|
|
87
|
+
return resolved !== null && import_ts_morph.Node.isObjectLiteralExpression(resolved) ? resolved : null;
|
|
138
88
|
}
|
|
139
89
|
function extractStories(sf, resolution) {
|
|
140
90
|
const results = [];
|
|
@@ -143,43 +93,36 @@ function extractStories(sf, resolution) {
|
|
|
143
93
|
continue;
|
|
144
94
|
}
|
|
145
95
|
for (const decl of decls) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
const init = decl.getInitializer();
|
|
150
|
-
if (init === void 0) {
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
const objLit = unwrapToObjectLiteral(init);
|
|
154
|
-
if (objLit === null) {
|
|
96
|
+
const story = objectBehind(decl, resolution);
|
|
97
|
+
if (story === null) {
|
|
155
98
|
continue;
|
|
156
99
|
}
|
|
157
|
-
const argsProp = objLit.getProperty("args");
|
|
158
|
-
const args = {};
|
|
159
|
-
if (argsProp?.isKind(import_ts_morph.SyntaxKind.PropertyAssignment)) {
|
|
160
|
-
const argsInit = argsProp.getInitializer();
|
|
161
|
-
if (argsInit?.isKind(import_ts_morph.SyntaxKind.ObjectLiteralExpression)) {
|
|
162
|
-
for (const prop of argsInit.getProperties()) {
|
|
163
|
-
if (prop.isKind(import_ts_morph.SyntaxKind.PropertyAssignment)) {
|
|
164
|
-
const value = prop.getInitializer();
|
|
165
|
-
if (value !== void 0) {
|
|
166
|
-
args[prop.getName()] = value.getText();
|
|
167
|
-
}
|
|
168
|
-
} else if (prop.isKind(import_ts_morph.SyntaxKind.ShorthandPropertyAssignment)) {
|
|
169
|
-
args[prop.getName()] = prop.getName();
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
100
|
results.push({
|
|
175
101
|
name,
|
|
176
|
-
args,
|
|
102
|
+
args: storyArgs(story, resolution),
|
|
177
103
|
line: decl.getStartLineNumber()
|
|
178
104
|
});
|
|
179
105
|
}
|
|
180
106
|
}
|
|
181
107
|
return results;
|
|
182
108
|
}
|
|
109
|
+
function storyArgs(story, resolution) {
|
|
110
|
+
const args = {};
|
|
111
|
+
const written = (0, import_adapter_typescript.propertyOf)(story, "args", resolution);
|
|
112
|
+
const object = written === null ? null : (0, import_adapter_typescript.objectLiteralOf)(written, resolution);
|
|
113
|
+
if (object === null) {
|
|
114
|
+
return args;
|
|
115
|
+
}
|
|
116
|
+
for (const property of (0, import_adapter_typescript.propertiesOf)(object, resolution)) {
|
|
117
|
+
const name = (0, import_adapter_typescript.propertyNameOf)(property);
|
|
118
|
+
const value = (0, import_adapter_typescript.propertyValueOf)(property);
|
|
119
|
+
if (name === null || value === null) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
args[name] = (0, import_adapter_typescript.stringValueOf)(value, resolution) ?? value.getText();
|
|
123
|
+
}
|
|
124
|
+
return args;
|
|
125
|
+
}
|
|
183
126
|
function buildSummary(story, meta, filePath) {
|
|
184
127
|
const inputs = Object.entries(story.args).map(([name, value]) => ({
|
|
185
128
|
type: "parameter",
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import path from "path";
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
Node as N,
|
|
5
|
+
Project
|
|
6
6
|
} from "ts-morph";
|
|
7
7
|
import {
|
|
8
8
|
exportedDeclarationsOf,
|
|
9
|
-
|
|
9
|
+
objectLiteralOf,
|
|
10
|
+
propertiesOf,
|
|
11
|
+
propertyNameOf,
|
|
12
|
+
propertyOf,
|
|
13
|
+
propertyValueOf,
|
|
14
|
+
ResolutionStore,
|
|
15
|
+
stringValueOf
|
|
10
16
|
} from "@suss/adapter-typescript";
|
|
11
17
|
import { functionCallBinding } from "@suss/behavioral-ir";
|
|
12
18
|
function generateSummariesFromStories(filePaths, options = {}) {
|
|
@@ -30,7 +36,7 @@ function generateSummariesFromStories(filePaths, options = {}) {
|
|
|
30
36
|
for (const sf of project.getSourceFiles()) {
|
|
31
37
|
const absPath = sf.getFilePath();
|
|
32
38
|
const relPath = path.relative(projectRoot, absPath);
|
|
33
|
-
const meta = extractMeta(sf);
|
|
39
|
+
const meta = extractMeta(sf, resolution);
|
|
34
40
|
if (meta === null) {
|
|
35
41
|
continue;
|
|
36
42
|
}
|
|
@@ -41,72 +47,22 @@ function generateSummariesFromStories(filePaths, options = {}) {
|
|
|
41
47
|
}
|
|
42
48
|
return summaries;
|
|
43
49
|
}
|
|
44
|
-
function extractMeta(sf) {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
for (const decl of defaultExport.getDeclarations()) {
|
|
50
|
-
const objLit = findMetaObjectLiteral(decl);
|
|
51
|
-
if (objLit === null) {
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
const componentProp = objLit.getProperty("component");
|
|
55
|
-
if (componentProp === void 0) {
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
if (!componentProp.isKind(SyntaxKind.PropertyAssignment)) {
|
|
50
|
+
function extractMeta(sf, resolution) {
|
|
51
|
+
for (const exported of resolution.exportsOf(sf).get("default") ?? []) {
|
|
52
|
+
const meta = objectBehind(exported, resolution);
|
|
53
|
+
if (meta === null) {
|
|
59
54
|
continue;
|
|
60
55
|
}
|
|
61
|
-
const
|
|
62
|
-
if (
|
|
63
|
-
|
|
56
|
+
const component = propertyOf(meta, "component", resolution);
|
|
57
|
+
if (component !== null) {
|
|
58
|
+
return { componentName: component.getText() };
|
|
64
59
|
}
|
|
65
|
-
return { componentName: initializer.getText() };
|
|
66
|
-
}
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
function findMetaObjectLiteral(node) {
|
|
70
|
-
if (node.isKind(SyntaxKind.ExportAssignment)) {
|
|
71
|
-
return unwrapToObjectLiteral(node.getExpression());
|
|
72
|
-
}
|
|
73
|
-
if (node.isKind(SyntaxKind.VariableDeclaration)) {
|
|
74
|
-
const init = node.getInitializer();
|
|
75
|
-
return init === void 0 ? null : unwrapToObjectLiteral(init);
|
|
76
60
|
}
|
|
77
61
|
return null;
|
|
78
62
|
}
|
|
79
|
-
function
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
if (node.isKind(SyntaxKind.SatisfiesExpression)) {
|
|
84
|
-
return unwrapToObjectLiteral(node.getExpression());
|
|
85
|
-
}
|
|
86
|
-
if (node.isKind(SyntaxKind.ParenthesizedExpression)) {
|
|
87
|
-
return unwrapToObjectLiteral(node.getExpression());
|
|
88
|
-
}
|
|
89
|
-
if (node.isKind(SyntaxKind.AsExpression)) {
|
|
90
|
-
return unwrapToObjectLiteral(node.getExpression());
|
|
91
|
-
}
|
|
92
|
-
if (node.isKind(SyntaxKind.Identifier)) {
|
|
93
|
-
const sym = node.getSymbol();
|
|
94
|
-
if (sym === void 0) {
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
for (const d of sym.getDeclarations()) {
|
|
98
|
-
if (d.isKind(SyntaxKind.VariableDeclaration)) {
|
|
99
|
-
const init = d.getInitializer();
|
|
100
|
-
if (init !== void 0) {
|
|
101
|
-
const unwrapped = unwrapToObjectLiteral(init);
|
|
102
|
-
if (unwrapped !== null) {
|
|
103
|
-
return unwrapped;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return null;
|
|
63
|
+
function objectBehind(value, resolution) {
|
|
64
|
+
const resolved = resolution.resolveObject(value);
|
|
65
|
+
return resolved !== null && N.isObjectLiteralExpression(resolved) ? resolved : null;
|
|
110
66
|
}
|
|
111
67
|
function extractStories(sf, resolution) {
|
|
112
68
|
const results = [];
|
|
@@ -115,43 +71,36 @@ function extractStories(sf, resolution) {
|
|
|
115
71
|
continue;
|
|
116
72
|
}
|
|
117
73
|
for (const decl of decls) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
const init = decl.getInitializer();
|
|
122
|
-
if (init === void 0) {
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
const objLit = unwrapToObjectLiteral(init);
|
|
126
|
-
if (objLit === null) {
|
|
74
|
+
const story = objectBehind(decl, resolution);
|
|
75
|
+
if (story === null) {
|
|
127
76
|
continue;
|
|
128
77
|
}
|
|
129
|
-
const argsProp = objLit.getProperty("args");
|
|
130
|
-
const args = {};
|
|
131
|
-
if (argsProp?.isKind(SyntaxKind.PropertyAssignment)) {
|
|
132
|
-
const argsInit = argsProp.getInitializer();
|
|
133
|
-
if (argsInit?.isKind(SyntaxKind.ObjectLiteralExpression)) {
|
|
134
|
-
for (const prop of argsInit.getProperties()) {
|
|
135
|
-
if (prop.isKind(SyntaxKind.PropertyAssignment)) {
|
|
136
|
-
const value = prop.getInitializer();
|
|
137
|
-
if (value !== void 0) {
|
|
138
|
-
args[prop.getName()] = value.getText();
|
|
139
|
-
}
|
|
140
|
-
} else if (prop.isKind(SyntaxKind.ShorthandPropertyAssignment)) {
|
|
141
|
-
args[prop.getName()] = prop.getName();
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
78
|
results.push({
|
|
147
79
|
name,
|
|
148
|
-
args,
|
|
80
|
+
args: storyArgs(story, resolution),
|
|
149
81
|
line: decl.getStartLineNumber()
|
|
150
82
|
});
|
|
151
83
|
}
|
|
152
84
|
}
|
|
153
85
|
return results;
|
|
154
86
|
}
|
|
87
|
+
function storyArgs(story, resolution) {
|
|
88
|
+
const args = {};
|
|
89
|
+
const written = propertyOf(story, "args", resolution);
|
|
90
|
+
const object = written === null ? null : objectLiteralOf(written, resolution);
|
|
91
|
+
if (object === null) {
|
|
92
|
+
return args;
|
|
93
|
+
}
|
|
94
|
+
for (const property of propertiesOf(object, resolution)) {
|
|
95
|
+
const name = propertyNameOf(property);
|
|
96
|
+
const value = propertyValueOf(property);
|
|
97
|
+
if (name === null || value === null) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
args[name] = stringValueOf(value, resolution) ?? value.getText();
|
|
101
|
+
}
|
|
102
|
+
return args;
|
|
103
|
+
}
|
|
155
104
|
function buildSummary(story, meta, filePath) {
|
|
156
105
|
const inputs = Object.entries(story.args).map(([name, value]) => ({
|
|
157
106
|
type: "parameter",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/contract-storybook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Turn Storybook CSF stories into a suss contract and check the props they pass against the React components that receive them.",
|
|
6
6
|
"keywords": [
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"typecheck": "tsc --noEmit"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@suss/adapter-typescript": "0.
|
|
51
|
-
"@suss/behavioral-ir": "0.
|
|
50
|
+
"@suss/adapter-typescript": "0.31.1",
|
|
51
|
+
"@suss/behavioral-ir": "0.31.1"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"tsup": "*",
|