@onlook/storybook-plugin 0.3.3 → 0.3.5
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 +21 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +237 -33
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -76,6 +76,27 @@ Screenshots are saved to `.storybook-cache/screenshots/`.
|
|
|
76
76
|
|
|
77
77
|
The plugin auto-disables when `CHROMATIC` or `CI` environment variables are set.
|
|
78
78
|
|
|
79
|
+
## Publishing
|
|
80
|
+
|
|
81
|
+
Three release paths:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# 1. Ship the current version to npm as `latest` (default dist-tag).
|
|
85
|
+
bun run publish-pkg
|
|
86
|
+
|
|
87
|
+
# 2. Ship under the `next` dist-tag — for testing against preview deploys
|
|
88
|
+
# without affecting consumers pinned to ^x.y.z ranges. Consumers opt in
|
|
89
|
+
# via `@onlook/storybook-plugin@next`.
|
|
90
|
+
bun run publish-pkg:next
|
|
91
|
+
|
|
92
|
+
# 3. Promote a previously-published version to `latest`. Reads the version
|
|
93
|
+
# from package.json, so bump first if you want to promote something else.
|
|
94
|
+
bun run promote-latest
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The typical flow for risky changes: `publish-pkg:next` → test against a
|
|
98
|
+
Vercel preview deploy → `promote-latest` once confident.
|
|
99
|
+
|
|
79
100
|
## License
|
|
80
101
|
|
|
81
102
|
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PluginOption } from 'vite';
|
|
2
|
+
import { Indexer } from 'storybook/internal/types';
|
|
2
3
|
|
|
3
4
|
type OnlookPluginOptions = {
|
|
4
5
|
/** Storybook port (default: 6006) */
|
|
@@ -8,4 +9,6 @@ type OnlookPluginOptions = {
|
|
|
8
9
|
};
|
|
9
10
|
declare function storybookOnlookPlugin(options?: OnlookPluginOptions): PluginOption[];
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
declare const tolerantCsfIndexer: Indexer;
|
|
13
|
+
|
|
14
|
+
export { type OnlookPluginOptions, storybookOnlookPlugin, tolerantCsfIndexer };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import fs5, { existsSync } from 'fs';
|
|
2
|
+
import path5, { dirname, join, relative } from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import generateModule from '@babel/generator';
|
|
5
5
|
import { parse } from '@babel/parser';
|
|
@@ -7,6 +7,8 @@ import traverseModule from '@babel/traverse';
|
|
|
7
7
|
import * as t from '@babel/types';
|
|
8
8
|
import crypto from 'crypto';
|
|
9
9
|
import { chromium } from 'playwright';
|
|
10
|
+
import { createRequire } from 'module';
|
|
11
|
+
import { readCsf } from 'storybook/internal/csf-tools';
|
|
10
12
|
|
|
11
13
|
// src/storybook-onlook-plugin.ts
|
|
12
14
|
function componentLocPlugin(options = {}) {
|
|
@@ -31,7 +33,7 @@ function componentLocPlugin(options = {}) {
|
|
|
31
33
|
sourceFilename: filepath
|
|
32
34
|
});
|
|
33
35
|
let mutated = false;
|
|
34
|
-
const relativePath =
|
|
36
|
+
const relativePath = path5.relative(root, filepath);
|
|
35
37
|
traverse(ast, {
|
|
36
38
|
JSXElement(nodePath) {
|
|
37
39
|
const opening = nodePath.node.openingElement;
|
|
@@ -68,9 +70,9 @@ function componentLocPlugin(options = {}) {
|
|
|
68
70
|
}
|
|
69
71
|
};
|
|
70
72
|
}
|
|
71
|
-
var CACHE_DIR =
|
|
72
|
-
var SCREENSHOTS_DIR =
|
|
73
|
-
var MANIFEST_PATH =
|
|
73
|
+
var CACHE_DIR = path5.join(process.cwd(), ".storybook-cache");
|
|
74
|
+
var SCREENSHOTS_DIR = path5.join(CACHE_DIR, "screenshots");
|
|
75
|
+
var MANIFEST_PATH = path5.join(CACHE_DIR, "manifest.json");
|
|
74
76
|
var VIEWPORT_WIDTH = 1920;
|
|
75
77
|
var VIEWPORT_HEIGHT = 1080;
|
|
76
78
|
var MIN_COMPONENT_WIDTH = 420;
|
|
@@ -78,30 +80,30 @@ var MIN_COMPONENT_HEIGHT = 280;
|
|
|
78
80
|
|
|
79
81
|
// src/utils/fileSystem/fileSystem.ts
|
|
80
82
|
function ensureCacheDirectories() {
|
|
81
|
-
if (!
|
|
82
|
-
|
|
83
|
+
if (!fs5.existsSync(CACHE_DIR)) {
|
|
84
|
+
fs5.mkdirSync(CACHE_DIR, { recursive: true });
|
|
83
85
|
}
|
|
84
|
-
if (!
|
|
85
|
-
|
|
86
|
+
if (!fs5.existsSync(SCREENSHOTS_DIR)) {
|
|
87
|
+
fs5.mkdirSync(SCREENSHOTS_DIR, { recursive: true });
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
function computeFileHash(filePath) {
|
|
89
|
-
if (!
|
|
91
|
+
if (!fs5.existsSync(filePath)) {
|
|
90
92
|
return "";
|
|
91
93
|
}
|
|
92
|
-
const content =
|
|
94
|
+
const content = fs5.readFileSync(filePath, "utf-8");
|
|
93
95
|
return crypto.createHash("sha256").update(content).digest("hex");
|
|
94
96
|
}
|
|
95
97
|
function loadManifest() {
|
|
96
|
-
if (
|
|
97
|
-
const content =
|
|
98
|
+
if (fs5.existsSync(MANIFEST_PATH)) {
|
|
99
|
+
const content = fs5.readFileSync(MANIFEST_PATH, "utf-8");
|
|
98
100
|
return JSON.parse(content);
|
|
99
101
|
}
|
|
100
102
|
return { stories: {} };
|
|
101
103
|
}
|
|
102
104
|
function saveManifest(manifest) {
|
|
103
105
|
ensureCacheDirectories();
|
|
104
|
-
|
|
106
|
+
fs5.writeFileSync(MANIFEST_PATH, JSON.stringify(manifest, null, 2));
|
|
105
107
|
}
|
|
106
108
|
function updateManifest(storyId, sourcePath, fileHash, boundingBox) {
|
|
107
109
|
const manifest = loadManifest();
|
|
@@ -127,8 +129,8 @@ async function getBrowser() {
|
|
|
127
129
|
return browser;
|
|
128
130
|
}
|
|
129
131
|
function getScreenshotPath(storyId, theme) {
|
|
130
|
-
const storyDir =
|
|
131
|
-
return
|
|
132
|
+
const storyDir = path5.join(SCREENSHOTS_DIR, storyId);
|
|
133
|
+
return path5.join(storyDir, `${theme}.png`);
|
|
132
134
|
}
|
|
133
135
|
async function captureScreenshotBuffer(storyId, theme, width = VIEWPORT_WIDTH, height = VIEWPORT_HEIGHT, storybookUrl = "http://localhost:6006", timeoutMs = 3e4) {
|
|
134
136
|
const browser2 = await getBrowser();
|
|
@@ -215,9 +217,9 @@ async function captureScreenshotBuffer(storyId, theme, width = VIEWPORT_WIDTH, h
|
|
|
215
217
|
async function generateScreenshot(storyId, theme, storybookUrl = "http://localhost:6006", timeoutMs = 3e4) {
|
|
216
218
|
try {
|
|
217
219
|
ensureCacheDirectories();
|
|
218
|
-
const storyDir =
|
|
219
|
-
if (!
|
|
220
|
-
|
|
220
|
+
const storyDir = path5.join(SCREENSHOTS_DIR, storyId);
|
|
221
|
+
if (!fs5.existsSync(storyDir)) {
|
|
222
|
+
fs5.mkdirSync(storyDir, { recursive: true });
|
|
221
223
|
}
|
|
222
224
|
const screenshotPath = getScreenshotPath(storyId, theme);
|
|
223
225
|
const { buffer, boundingBox } = await captureScreenshotBuffer(
|
|
@@ -228,7 +230,7 @@ async function generateScreenshot(storyId, theme, storybookUrl = "http://localho
|
|
|
228
230
|
storybookUrl,
|
|
229
231
|
timeoutMs
|
|
230
232
|
);
|
|
231
|
-
|
|
233
|
+
fs5.writeFileSync(screenshotPath, buffer);
|
|
232
234
|
return { path: screenshotPath, boundingBox };
|
|
233
235
|
} catch (error) {
|
|
234
236
|
console.error(`Error generating screenshot for ${storyId} (${theme}):`, error);
|
|
@@ -255,7 +257,7 @@ async function fetchStorybookIndex() {
|
|
|
255
257
|
}
|
|
256
258
|
function getStoriesForFile(filePath) {
|
|
257
259
|
if (!cachedIndex) return [];
|
|
258
|
-
const fileName =
|
|
260
|
+
const fileName = path5.basename(filePath);
|
|
259
261
|
return Object.values(cachedIndex.entries).filter((entry) => entry.type === "story" && entry.importPath.endsWith(fileName)).map((entry) => entry.id);
|
|
260
262
|
}
|
|
261
263
|
async function regenerateScreenshotsForFiles(files) {
|
|
@@ -320,6 +322,196 @@ function handleStoryFileChange({ file, modules }) {
|
|
|
320
322
|
return modules;
|
|
321
323
|
}
|
|
322
324
|
}
|
|
325
|
+
function buildLucideExportMap(barrelSource, barrelRelativeDir) {
|
|
326
|
+
const ast = parse(barrelSource, { sourceType: "module" });
|
|
327
|
+
const map = /* @__PURE__ */ new Map();
|
|
328
|
+
for (const node of ast.program.body) {
|
|
329
|
+
if (node.type !== "ExportNamedDeclaration") continue;
|
|
330
|
+
if (!node.source) continue;
|
|
331
|
+
const rawSource = node.source.value;
|
|
332
|
+
const subpath = path5.posix.join(barrelRelativeDir, rawSource.replace(/^\.\//, ""));
|
|
333
|
+
for (const spec of node.specifiers) {
|
|
334
|
+
if (spec.type !== "ExportSpecifier") continue;
|
|
335
|
+
const exportedName = spec.exported.type === "Identifier" ? spec.exported.name : null;
|
|
336
|
+
if (!exportedName) continue;
|
|
337
|
+
const localName = spec.local.name;
|
|
338
|
+
if (localName === "default") {
|
|
339
|
+
map.set(exportedName, { kind: "default", subpath });
|
|
340
|
+
} else {
|
|
341
|
+
map.set(exportedName, { kind: "named", subpath, name: localName });
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return map;
|
|
346
|
+
}
|
|
347
|
+
function transformLucideImports(code, filepath, exportMap) {
|
|
348
|
+
if (!code.includes("lucide-react")) return null;
|
|
349
|
+
if (!/\bimport\b[^;]*['"]lucide-react['"]/.test(code)) return null;
|
|
350
|
+
const traverse = traverseModule.default ?? traverseModule;
|
|
351
|
+
const generate = generateModule.default ?? generateModule;
|
|
352
|
+
const ast = parse(code, {
|
|
353
|
+
sourceType: "module",
|
|
354
|
+
plugins: ["jsx", "typescript"],
|
|
355
|
+
sourceFilename: filepath
|
|
356
|
+
});
|
|
357
|
+
let mutated = false;
|
|
358
|
+
traverse(ast, {
|
|
359
|
+
ImportDeclaration(nodePath) {
|
|
360
|
+
const node = nodePath.node;
|
|
361
|
+
if (node.source.value !== "lucide-react") return;
|
|
362
|
+
if (node.importKind === "type") return;
|
|
363
|
+
const rewritten = [];
|
|
364
|
+
const preserved = [];
|
|
365
|
+
for (const spec of node.specifiers) {
|
|
366
|
+
if (spec.type !== "ImportSpecifier") {
|
|
367
|
+
preserved.push(spec);
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
if (spec.importKind === "type") {
|
|
371
|
+
preserved.push(spec);
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
const importedName = spec.imported.type === "Identifier" ? spec.imported.name : null;
|
|
375
|
+
if (!importedName) {
|
|
376
|
+
preserved.push(spec);
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
const resolution = exportMap.get(importedName);
|
|
380
|
+
if (!resolution) {
|
|
381
|
+
preserved.push(spec);
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
const subpathSource = t.stringLiteral(`lucide-react/${resolution.subpath}`);
|
|
385
|
+
if (resolution.kind === "default") {
|
|
386
|
+
rewritten.push(
|
|
387
|
+
t.importDeclaration(
|
|
388
|
+
[t.importDefaultSpecifier(t.identifier(spec.local.name))],
|
|
389
|
+
subpathSource
|
|
390
|
+
)
|
|
391
|
+
);
|
|
392
|
+
} else {
|
|
393
|
+
rewritten.push(
|
|
394
|
+
t.importDeclaration(
|
|
395
|
+
[
|
|
396
|
+
t.importSpecifier(
|
|
397
|
+
t.identifier(spec.local.name),
|
|
398
|
+
t.identifier(resolution.name)
|
|
399
|
+
)
|
|
400
|
+
],
|
|
401
|
+
subpathSource
|
|
402
|
+
)
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (rewritten.length === 0) return;
|
|
407
|
+
mutated = true;
|
|
408
|
+
if (preserved.length > 0) {
|
|
409
|
+
const residual = t.importDeclaration(preserved, t.stringLiteral("lucide-react"));
|
|
410
|
+
nodePath.replaceWithMultiple([...rewritten, residual]);
|
|
411
|
+
} else {
|
|
412
|
+
nodePath.replaceWithMultiple(rewritten);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
if (!mutated) return null;
|
|
417
|
+
const output = generate(
|
|
418
|
+
ast,
|
|
419
|
+
{ retainLines: true, sourceMaps: true, sourceFileName: filepath },
|
|
420
|
+
code
|
|
421
|
+
);
|
|
422
|
+
return { code: output.code, map: output.map };
|
|
423
|
+
}
|
|
424
|
+
async function resolveLucideBarrel(config) {
|
|
425
|
+
try {
|
|
426
|
+
const resolver = config.createResolver({ asSrc: false });
|
|
427
|
+
const resolved = await resolver("lucide-react", path5.join(config.root, "index.js"));
|
|
428
|
+
if (resolved && fs5.existsSync(resolved)) return resolved;
|
|
429
|
+
} catch {
|
|
430
|
+
}
|
|
431
|
+
try {
|
|
432
|
+
const req = createRequire(path5.join(config.root, "package.json"));
|
|
433
|
+
return req.resolve("lucide-react");
|
|
434
|
+
} catch {
|
|
435
|
+
return null;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
function computeBarrelRelativeDir(barrelPath) {
|
|
439
|
+
let dir = path5.dirname(barrelPath);
|
|
440
|
+
while (dir !== path5.dirname(dir)) {
|
|
441
|
+
const pj = path5.join(dir, "package.json");
|
|
442
|
+
if (fs5.existsSync(pj)) {
|
|
443
|
+
try {
|
|
444
|
+
const pkg = JSON.parse(fs5.readFileSync(pj, "utf-8"));
|
|
445
|
+
if (pkg.name === "lucide-react") {
|
|
446
|
+
const rel = path5.relative(dir, barrelPath).split(path5.sep).join("/");
|
|
447
|
+
return `${path5.posix.dirname(rel)}/`;
|
|
448
|
+
}
|
|
449
|
+
} catch {
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
dir = path5.dirname(dir);
|
|
453
|
+
}
|
|
454
|
+
return null;
|
|
455
|
+
}
|
|
456
|
+
var PLUGIN_NAME = "onbook-lucide-barrel";
|
|
457
|
+
function lucideBarrelPlugin() {
|
|
458
|
+
let exportMap = /* @__PURE__ */ new Map();
|
|
459
|
+
let enabled = false;
|
|
460
|
+
let warnedTransformOnce = false;
|
|
461
|
+
return {
|
|
462
|
+
name: PLUGIN_NAME,
|
|
463
|
+
enforce: "pre",
|
|
464
|
+
apply: "serve",
|
|
465
|
+
config() {
|
|
466
|
+
return {
|
|
467
|
+
optimizeDeps: {
|
|
468
|
+
exclude: ["lucide-react"]
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
},
|
|
472
|
+
async configResolved(config) {
|
|
473
|
+
const barrelPath = await resolveLucideBarrel(config);
|
|
474
|
+
if (!barrelPath) {
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
const relativeDir = computeBarrelRelativeDir(barrelPath);
|
|
478
|
+
if (!relativeDir) {
|
|
479
|
+
config.logger.warn(
|
|
480
|
+
`[${PLUGIN_NAME}] Could not locate lucide-react package root from ${barrelPath}; plugin is a no-op.`
|
|
481
|
+
);
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
try {
|
|
485
|
+
const source = fs5.readFileSync(barrelPath, "utf-8");
|
|
486
|
+
exportMap = buildLucideExportMap(source, relativeDir);
|
|
487
|
+
enabled = true;
|
|
488
|
+
} catch (e) {
|
|
489
|
+
config.logger.warn(
|
|
490
|
+
`[${PLUGIN_NAME}] Failed to parse lucide-react barrel at ${barrelPath}: ${e instanceof Error ? e.message : String(e)}`
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
},
|
|
494
|
+
transform(code, id) {
|
|
495
|
+
if (!enabled) return null;
|
|
496
|
+
const filepath = id.split("?", 1)[0];
|
|
497
|
+
if (!filepath || filepath.includes("node_modules")) return null;
|
|
498
|
+
if (!/\.(tsx?|jsx?)$/.test(filepath)) return null;
|
|
499
|
+
try {
|
|
500
|
+
const result = transformLucideImports(code, filepath, exportMap);
|
|
501
|
+
if (!result) return null;
|
|
502
|
+
return { code: result.code, map: result.map };
|
|
503
|
+
} catch (e) {
|
|
504
|
+
if (!warnedTransformOnce) {
|
|
505
|
+
warnedTransformOnce = true;
|
|
506
|
+
console.warn(
|
|
507
|
+
`[${PLUGIN_NAME}] Transform error for ${id}: ${e instanceof Error ? e.message : String(e)} (further errors suppressed)`
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
}
|
|
323
515
|
function findGitRoot(startPath) {
|
|
324
516
|
let currentPath = startPath;
|
|
325
517
|
while (currentPath !== dirname(currentPath)) {
|
|
@@ -345,7 +537,7 @@ var DEFAULT_ALLOWED_ORIGINS = [
|
|
|
345
537
|
var serveMetadataAndScreenshots = (req, res, next) => {
|
|
346
538
|
if (req.url === "/onbook-index.json") {
|
|
347
539
|
console.log("[STORYBOOK_PLUGIN] Serving /onbook-index.json endpoint");
|
|
348
|
-
const manifestPath =
|
|
540
|
+
const manifestPath = path5.join(process.cwd(), ".storybook-cache", "manifest.json");
|
|
349
541
|
const cacheBuster = Date.now();
|
|
350
542
|
console.log("[STORYBOOK_PLUGIN] Fetching http://localhost:6006/index.json");
|
|
351
543
|
fetch(`http://localhost:6006/index.json?_t=${cacheBuster}`, {
|
|
@@ -362,7 +554,7 @@ var serveMetadataAndScreenshots = (req, res, next) => {
|
|
|
362
554
|
});
|
|
363
555
|
return response.json();
|
|
364
556
|
}).then((indexData) => {
|
|
365
|
-
const manifest =
|
|
557
|
+
const manifest = fs5.existsSync(manifestPath) ? JSON.parse(fs5.readFileSync(manifestPath, "utf-8")) : { stories: {} };
|
|
366
558
|
const defaultBoundingBox = { width: 1920, height: 1080 };
|
|
367
559
|
for (const [storyId, entry] of Object.entries(indexData.entries || {})) {
|
|
368
560
|
const manifestEntry = manifest.stories?.[storyId];
|
|
@@ -430,7 +622,7 @@ var serveMetadataAndScreenshots = (req, res, next) => {
|
|
|
430
622
|
return;
|
|
431
623
|
}
|
|
432
624
|
if (req.url?.startsWith("/screenshots/")) {
|
|
433
|
-
const screenshotPath =
|
|
625
|
+
const screenshotPath = path5.join(
|
|
434
626
|
process.cwd(),
|
|
435
627
|
".storybook-cache",
|
|
436
628
|
req.url.replace("/screenshots/", "screenshots/")
|
|
@@ -439,11 +631,11 @@ var serveMetadataAndScreenshots = (req, res, next) => {
|
|
|
439
631
|
const storyId = urlParts[0];
|
|
440
632
|
const themeFile = urlParts[1];
|
|
441
633
|
const theme = themeFile?.replace(".png", "");
|
|
442
|
-
if (
|
|
634
|
+
if (fs5.existsSync(screenshotPath)) {
|
|
443
635
|
res.setHeader("Content-Type", "image/png");
|
|
444
636
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
445
637
|
res.setHeader("Cache-Control", "public, max-age=3600");
|
|
446
|
-
|
|
638
|
+
fs5.createReadStream(screenshotPath).pipe(res);
|
|
447
639
|
return;
|
|
448
640
|
}
|
|
449
641
|
if (storyId && theme && (theme === "light" || theme === "dark")) {
|
|
@@ -451,16 +643,16 @@ var serveMetadataAndScreenshots = (req, res, next) => {
|
|
|
451
643
|
`[STORYBOOK_PLUGIN] Generating screenshot on-demand: ${storyId}/${theme}`
|
|
452
644
|
);
|
|
453
645
|
captureScreenshotBuffer(storyId, theme).then(({ buffer }) => {
|
|
454
|
-
const storyDir =
|
|
646
|
+
const storyDir = path5.join(
|
|
455
647
|
process.cwd(),
|
|
456
648
|
".storybook-cache",
|
|
457
649
|
"screenshots",
|
|
458
650
|
storyId
|
|
459
651
|
);
|
|
460
|
-
if (!
|
|
461
|
-
|
|
652
|
+
if (!fs5.existsSync(storyDir)) {
|
|
653
|
+
fs5.mkdirSync(storyDir, { recursive: true });
|
|
462
654
|
}
|
|
463
|
-
|
|
655
|
+
fs5.writeFileSync(screenshotPath, buffer);
|
|
464
656
|
res.setHeader("Content-Type", "image/png");
|
|
465
657
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
466
658
|
res.setHeader("Cache-Control", "public, max-age=3600");
|
|
@@ -536,7 +728,19 @@ function storybookOnlookPlugin(options = {}) {
|
|
|
536
728
|
},
|
|
537
729
|
handleHotUpdate: handleStoryFileChange
|
|
538
730
|
};
|
|
539
|
-
return [componentLocPlugin(), mainPlugin];
|
|
731
|
+
return [lucideBarrelPlugin(), componentLocPlugin(), mainPlugin];
|
|
540
732
|
}
|
|
733
|
+
var tolerantCsfIndexer = {
|
|
734
|
+
test: /(stories|story)\.(m?js|ts)x?$/,
|
|
735
|
+
createIndex: async (fileName, options) => {
|
|
736
|
+
try {
|
|
737
|
+
return (await readCsf(fileName, options)).parse().indexInputs;
|
|
738
|
+
} catch (err) {
|
|
739
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
740
|
+
console.warn("[onbook] Skipping broken story file:", fileName, msg);
|
|
741
|
+
return [];
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
};
|
|
541
745
|
|
|
542
|
-
export { storybookOnlookPlugin };
|
|
746
|
+
export { storybookOnlookPlugin, tolerantCsfIndexer };
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlook/storybook-plugin",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
|
-
"onlook-storybook": "
|
|
6
|
+
"onlook-storybook": "dist/cli/index.js"
|
|
7
7
|
},
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
@@ -29,7 +29,9 @@
|
|
|
29
29
|
"typecheck": "tsc --noEmit",
|
|
30
30
|
"prepublishOnly": "bun run build && bun scripts/prepublish.ts",
|
|
31
31
|
"postpublish": "bun scripts/postpublish.ts",
|
|
32
|
-
"publish-pkg": "npm publish"
|
|
32
|
+
"publish-pkg": "npm publish",
|
|
33
|
+
"publish-pkg:next": "npm publish --tag next",
|
|
34
|
+
"promote-latest": "npm dist-tag add @onlook/storybook-plugin@$(node -p \"require('./package.json').version\") latest"
|
|
33
35
|
},
|
|
34
36
|
"dependencies": {
|
|
35
37
|
"@babel/generator": "^7.26.9",
|
|
@@ -45,6 +47,7 @@
|
|
|
45
47
|
"@types/babel__traverse": "^7.20.6",
|
|
46
48
|
"@types/node": "^22.15.32",
|
|
47
49
|
"bun-types": "^1.3.5",
|
|
50
|
+
"storybook": "^10.1.11",
|
|
48
51
|
"tsup": "^8.5.1",
|
|
49
52
|
"typescript": "5.8.3",
|
|
50
53
|
"vite": "^6.3.5"
|
|
@@ -53,6 +56,7 @@
|
|
|
53
56
|
"access": "public"
|
|
54
57
|
},
|
|
55
58
|
"peerDependencies": {
|
|
59
|
+
"storybook": "^10.0.0",
|
|
56
60
|
"vite": "^5.0.0 || ^6.0.0"
|
|
57
61
|
}
|
|
58
62
|
}
|