@emulsify/core 4.4.0 → 4.5.0
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/README.md +10 -1
- package/config/a11y-wcag22.js +11 -0
- package/config/vite/plugins/assets/source-file-index.js +6 -12
- package/config/vite/plugins/twig/twig-module.js +35 -258
- package/config/vite/utils/source-directory-skips.js +13 -0
- package/config/vite/utils/twig-component-resolver.js +316 -0
- package/package.json +31 -28
- package/scripts/a11y.js +88 -9
- package/scripts/audit/checks/twig-references.js +16 -5
- package/scripts/audit/lib/story-ast.js +392 -0
- package/scripts/audit/lib/story-render-paths.js +600 -0
- package/scripts/audit/lib/story-selection.js +190 -0
- package/scripts/audit/lib/twig.js +361 -51
- package/scripts/audit-twig-stories.js +73 -3
|
@@ -18,6 +18,12 @@ import {
|
|
|
18
18
|
formatAuditJsonErrorReport,
|
|
19
19
|
formatAuditJsonReport,
|
|
20
20
|
} from './audit/report.js';
|
|
21
|
+
import {
|
|
22
|
+
findRenderTwigBindings,
|
|
23
|
+
findTwigTemplateBindings,
|
|
24
|
+
parseStoryModule,
|
|
25
|
+
} from './audit/lib/story-ast.js';
|
|
26
|
+
import { classifyStoryRenderPaths } from './audit/lib/story-render-paths.js';
|
|
21
27
|
import { lineNumberAt } from './lib/text.js';
|
|
22
28
|
|
|
23
29
|
const STORY_GLOB = '**/*.stories.{js,jsx,ts,tsx}';
|
|
@@ -115,13 +121,13 @@ export function findDirectTemplateReturns(source, templateNames = []) {
|
|
|
115
121
|
}
|
|
116
122
|
|
|
117
123
|
/**
|
|
118
|
-
* Analyze one Storybook story
|
|
124
|
+
* Analyze one Storybook story with the legacy regex implementation.
|
|
119
125
|
*
|
|
120
126
|
* @param {string} source - Story source.
|
|
121
|
-
* @param {string}
|
|
127
|
+
* @param {string} filePath - Story file path.
|
|
122
128
|
* @returns {object} Story analysis.
|
|
123
129
|
*/
|
|
124
|
-
|
|
130
|
+
function analyzeStorySourceWithRegex(source, filePath) {
|
|
125
131
|
const twigImports = findTwigImports(source);
|
|
126
132
|
const templateNames = twigImports.map((item) => item.name);
|
|
127
133
|
const hasRenderTwig = importsRenderTwig(source);
|
|
@@ -160,6 +166,70 @@ export function analyzeStorySource(source, filePath = '') {
|
|
|
160
166
|
};
|
|
161
167
|
}
|
|
162
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Analyze one Storybook story source string.
|
|
171
|
+
*
|
|
172
|
+
* @param {string} source - Story source.
|
|
173
|
+
* @param {string} [filePath=''] - Story file path.
|
|
174
|
+
* @returns {object} Story analysis.
|
|
175
|
+
*/
|
|
176
|
+
export function analyzeStorySource(source, filePath = '') {
|
|
177
|
+
const parsed = parseStoryModule(source, filePath);
|
|
178
|
+
if (!parsed) return analyzeStorySourceWithRegex(source, filePath);
|
|
179
|
+
|
|
180
|
+
const twigImports = findTwigTemplateBindings(parsed.ast);
|
|
181
|
+
const renderTwigNames = findRenderTwigBindings(parsed.ast);
|
|
182
|
+
const hasRenderTwig = renderTwigNames.size > 0;
|
|
183
|
+
const reasons = [];
|
|
184
|
+
|
|
185
|
+
if (!twigImports.length) {
|
|
186
|
+
return {
|
|
187
|
+
filePath,
|
|
188
|
+
twigImports,
|
|
189
|
+
hasRenderTwig,
|
|
190
|
+
directTemplateReturns: [],
|
|
191
|
+
reasons,
|
|
192
|
+
shouldUpgrade: false,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const classification = classifyStoryRenderPaths(parsed.ast, {
|
|
197
|
+
templateNames: twigImports.map((item) => item.name),
|
|
198
|
+
renderTwigNames,
|
|
199
|
+
});
|
|
200
|
+
const fallbackLine = Number.isInteger(twigImports[0]?.line)
|
|
201
|
+
? twigImports[0].line
|
|
202
|
+
: 1;
|
|
203
|
+
const directTemplateReturns = classification.legacy.map((item) => ({
|
|
204
|
+
name: item.name || twigImports[0].name,
|
|
205
|
+
line: Number.isInteger(item.line) ? item.line : fallbackLine,
|
|
206
|
+
}));
|
|
207
|
+
|
|
208
|
+
if (!hasRenderTwig && classification.legacy.length) {
|
|
209
|
+
reasons.push('imports Twig templates without renderTwig()');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (classification.legacy.length) {
|
|
213
|
+
reasons.push('appears to return Twig HTML strings directly');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (reasons.length && !directTemplateReturns.length) {
|
|
217
|
+
directTemplateReturns.push({
|
|
218
|
+
name: twigImports[0].name,
|
|
219
|
+
line: fallbackLine,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
filePath,
|
|
225
|
+
twigImports,
|
|
226
|
+
hasRenderTwig,
|
|
227
|
+
directTemplateReturns,
|
|
228
|
+
reasons,
|
|
229
|
+
shouldUpgrade: reasons.length > 0,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
163
233
|
/**
|
|
164
234
|
* Resolve Storybook source roots for the project.
|
|
165
235
|
*
|