@sit-onyx/storybook-utils 1.0.0-beta.101 → 1.0.0-beta.103
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/package.json +7 -6
- package/src/preview.spec.ts +4 -1
- package/src/preview.ts +67 -43
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sit-onyx/storybook-utils",
|
|
3
3
|
"description": "Storybook utilities for Vue",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.103",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Schwarz IT KG",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -31,17 +31,18 @@
|
|
|
31
31
|
"prettier": ">= 3.0.0",
|
|
32
32
|
"storybook": ">= 9.0.0",
|
|
33
33
|
"vue-component-type-helpers": ">= 2",
|
|
34
|
-
"@sit-onyx/
|
|
35
|
-
"@sit-onyx/icons": "^1.0.0-beta.
|
|
34
|
+
"@sit-onyx/flags": "^1.0.0-beta.7",
|
|
35
|
+
"@sit-onyx/icons": "^1.0.0-beta.25",
|
|
36
|
+
"@sit-onyx/shared": "^1.0.0-beta.4"
|
|
36
37
|
},
|
|
37
38
|
"dependencies": {
|
|
38
39
|
"deepmerge-ts": "^7.1.5"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
|
-
"storybook": "^9.
|
|
42
|
+
"storybook": "^9.1.1",
|
|
42
43
|
"vue": "3.5.18",
|
|
43
|
-
"vue-component-type-helpers": "^3.0.
|
|
44
|
-
"@sit-onyx/icons": "^1.0.0-beta.
|
|
44
|
+
"vue-component-type-helpers": "^3.0.5",
|
|
45
|
+
"@sit-onyx/icons": "^1.0.0-beta.25",
|
|
45
46
|
"@sit-onyx/shared": "^1.0.0-beta.4"
|
|
46
47
|
},
|
|
47
48
|
"scripts": {
|
package/src/preview.spec.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { flagDE } from "@sit-onyx/flags";
|
|
1
2
|
import { iconBellRing, iconCalendar, iconPlaceholder } from "@sit-onyx/icons";
|
|
2
3
|
import { describe, expect, test } from "vitest";
|
|
3
4
|
import { replaceAll, sourceCodeTransformer } from "./preview.js";
|
|
@@ -6,7 +7,7 @@ describe("preview.ts", () => {
|
|
|
6
7
|
test("should transform source code and add icon/onyx imports", async () => {
|
|
7
8
|
// ACT
|
|
8
9
|
const sourceCode = await sourceCodeTransformer(`<template>
|
|
9
|
-
<OnyxTest icon='${iconPlaceholder}' test='${iconBellRing}' :obj="{foo:'${replaceAll(iconCalendar, '"', "\\'")}'}" />
|
|
10
|
+
<OnyxTest icon='${iconPlaceholder}' test='${iconBellRing}' :obj="{foo:'${replaceAll(iconCalendar, '"', "\\'")}'}" flag='${flagDE}' />
|
|
10
11
|
<OnyxOtherComponent />
|
|
11
12
|
<OnyxComp>Test</OnyxComp>
|
|
12
13
|
</template>`);
|
|
@@ -15,6 +16,7 @@ describe("preview.ts", () => {
|
|
|
15
16
|
expect(sourceCode).toBe(`<script lang="ts" setup>
|
|
16
17
|
import { OnyxComp, OnyxOtherComponent, OnyxTest } from "sit-onyx";
|
|
17
18
|
import { iconBellRing, iconCalendar, iconPlaceholder } from "@sit-onyx/icons";
|
|
19
|
+
import { flagDE } from "@sit-onyx/flags";
|
|
18
20
|
</script>
|
|
19
21
|
|
|
20
22
|
<template>
|
|
@@ -22,6 +24,7 @@ import { iconBellRing, iconCalendar, iconPlaceholder } from "@sit-onyx/icons";
|
|
|
22
24
|
:icon="iconPlaceholder"
|
|
23
25
|
:test="iconBellRing"
|
|
24
26
|
:obj="{foo:iconCalendar}"
|
|
27
|
+
:flag="flagDE"
|
|
25
28
|
/>
|
|
26
29
|
<OnyxOtherComponent />
|
|
27
30
|
<OnyxComp>Test</OnyxComp>
|
package/src/preview.ts
CHANGED
|
@@ -132,65 +132,89 @@ export const createPreview = <T extends Preview = Preview>(
|
|
|
132
132
|
* @see https://storybook.js.org/docs/react/api/doc-block-source
|
|
133
133
|
*/
|
|
134
134
|
export const sourceCodeTransformer = async (originalSourceCode: string): Promise<string> => {
|
|
135
|
-
const ALL_ICONS = await import("@sit-onyx/icons");
|
|
136
|
-
|
|
137
135
|
let code = originalSourceCode;
|
|
138
136
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const singleQuotedIconContent = `'${replaceAll(iconContent, '"', "\\'")}'`;
|
|
146
|
-
const escapedIconContent = `"${replaceAll(iconContent, '"', '\\"')}"`;
|
|
147
|
-
|
|
148
|
-
if (code.includes(iconContent)) {
|
|
149
|
-
usedIcons.add(iconName);
|
|
150
|
-
|
|
151
|
-
code = code.replace(
|
|
152
|
-
new RegExp(` (\\S+)=['"]${escapeRegExp(iconContent)}['"]`),
|
|
153
|
-
` :$1="${iconName}"`,
|
|
154
|
-
);
|
|
155
|
-
} else if (code.includes(singleQuotedIconContent)) {
|
|
156
|
-
// support icons inside objects
|
|
157
|
-
usedIcons.add(iconName);
|
|
158
|
-
code = code.replace(singleQuotedIconContent, iconName);
|
|
159
|
-
} else if (code.includes(escapedIconContent)) {
|
|
160
|
-
// support icons inside objects
|
|
161
|
-
usedIcons.add(iconName);
|
|
162
|
-
code = code.replace(escapedIconContent, iconName);
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
if (usedIcons.size > 0) {
|
|
167
|
-
additionalImports.push(
|
|
168
|
-
`import { ${Array.from(usedIcons.values()).sort().join(", ")} } from "@sit-onyx/icons";`,
|
|
169
|
-
);
|
|
170
|
-
}
|
|
137
|
+
/**
|
|
138
|
+
* A list of additional JavaScript imports to be added at the top of the source code.
|
|
139
|
+
*
|
|
140
|
+
* key = module/package name to import from, value: set of imports to import from the package
|
|
141
|
+
*/
|
|
142
|
+
const additionalImports = new Map<string, Set<string>>();
|
|
171
143
|
|
|
172
144
|
// add imports for all used onyx components
|
|
173
145
|
// Set is used here to only include unique components if they are used multiple times
|
|
174
|
-
const usedOnyxComponents =
|
|
175
|
-
|
|
176
|
-
|
|
146
|
+
const usedOnyxComponents = new Set(
|
|
147
|
+
Array.from(code.matchAll(/<(Onyx\w+)(?:\s*\/?)/g)).map((match) => match[1]),
|
|
148
|
+
);
|
|
149
|
+
additionalImports.set("sit-onyx", usedOnyxComponents);
|
|
177
150
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
151
|
+
/**
|
|
152
|
+
* List of npm packages to replace the source code with.
|
|
153
|
+
* The source code will be checked for any import of the package and (if its used), the code will be replaced by the corresponding import.
|
|
154
|
+
*/
|
|
155
|
+
const packagesToReplace = [
|
|
156
|
+
{ name: "@sit-onyx/icons", data: await import("@sit-onyx/icons") },
|
|
157
|
+
{ name: "@sit-onyx/flags", data: await import("@sit-onyx/flags") },
|
|
158
|
+
];
|
|
159
|
+
|
|
160
|
+
packagesToReplace.forEach((_package) => {
|
|
161
|
+
Object.entries(_package.data).forEach(([name, content]) => {
|
|
162
|
+
const singleQuotedContent = `'${replaceAll(content, '"', "\\'")}'`;
|
|
163
|
+
const escapedContent = `"${replaceAll(content, '"', '\\"')}"`;
|
|
164
|
+
|
|
165
|
+
const imports = additionalImports.get(_package.name) ?? new Set<string>();
|
|
166
|
+
|
|
167
|
+
if (code.includes(content)) {
|
|
168
|
+
imports.add(name);
|
|
169
|
+
|
|
170
|
+
code = code.replace(
|
|
171
|
+
new RegExp(` (\\S+)=['"]${escapeRegExp(content)}['"]`),
|
|
172
|
+
` :$1="${name}"`,
|
|
173
|
+
);
|
|
174
|
+
} else if (code.includes(singleQuotedContent)) {
|
|
175
|
+
// support values inside objects
|
|
176
|
+
imports.add(name);
|
|
177
|
+
code = code.replace(singleQuotedContent, name);
|
|
178
|
+
} else if (code.includes(escapedContent)) {
|
|
179
|
+
// support values inside objects
|
|
180
|
+
imports.add(name);
|
|
181
|
+
code = code.replace(escapedContent, name);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
additionalImports.set(_package.name, imports);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// remove imports without any data so we don't add empty imports
|
|
189
|
+
additionalImports.forEach((value, key) => {
|
|
190
|
+
if (!value.size) additionalImports.delete(key);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// generate the source code for the additional imports and add them to the top of the code snippet
|
|
194
|
+
if (additionalImports.size > 0) {
|
|
195
|
+
const additionalImportsCode = Array.from(additionalImports.entries()).reduce(
|
|
196
|
+
(code, [packageName, imports]) => {
|
|
197
|
+
if (imports.size) {
|
|
198
|
+
code.push(
|
|
199
|
+
`import { ${Array.from(imports.values()).sort().join(", ")} } from "${packageName}";`,
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
return code;
|
|
203
|
+
},
|
|
204
|
+
[] as string[],
|
|
205
|
+
);
|
|
181
206
|
|
|
182
|
-
if (additionalImports.length > 1) {
|
|
183
207
|
if (code.startsWith("<script")) {
|
|
184
208
|
const index = code.indexOf("\n");
|
|
185
209
|
const hasOtherImports = code.includes("import {");
|
|
186
210
|
code =
|
|
187
211
|
code.slice(0, index) +
|
|
188
|
-
|
|
212
|
+
additionalImportsCode.join("\n") +
|
|
189
213
|
(!hasOtherImports ? "\n" : "") +
|
|
190
214
|
code.slice(index);
|
|
191
215
|
} else {
|
|
192
216
|
code = `<script lang="ts" setup>
|
|
193
|
-
${
|
|
217
|
+
${additionalImportsCode.join("\n")}
|
|
194
218
|
</script>
|
|
195
219
|
|
|
196
220
|
${code}`;
|