@onlook/storybook-plugin 0.4.0-beta.0 → 0.4.0-beta.10
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 +1 -1
- package/dist/cli/index.js +199 -52
- package/dist/index.d.ts +94 -21
- package/dist/index.js +835 -235
- package/dist/preset/index.d.ts +10 -0
- package/dist/preset/index.js +1345 -0
- package/dist/preview/index.d.ts +156 -0
- package/dist/preview/index.js +302 -0
- package/dist/screenshot-service/index.d.ts +0 -6
- package/dist/screenshot-service/index.js +197 -50
- package/dist/screenshot-service/utils/browser/index.d.ts +0 -6
- package/dist/screenshot-service/utils/browser/index.js +83 -14
- package/dist/storybook-onlook-plugin-CigILdDb.d.ts +61 -0
- package/package.json +19 -9
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
1
2
|
import crypto from 'crypto';
|
|
2
3
|
import fs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
4
|
+
import path, { join, dirname } from 'path';
|
|
5
|
+
import { execFile } from 'child_process';
|
|
6
|
+
import { createRequire as createRequire$1 } from 'module';
|
|
7
|
+
import { promisify } from 'util';
|
|
4
8
|
import { chromium } from 'playwright';
|
|
5
9
|
|
|
6
|
-
|
|
10
|
+
globalThis.require = createRequire(import.meta.url);
|
|
7
11
|
var CACHE_DIR = path.join(process.cwd(), ".storybook-cache");
|
|
8
12
|
var SCREENSHOTS_DIR = path.join(CACHE_DIR, "screenshots");
|
|
9
13
|
var MANIFEST_PATH = path.join(CACHE_DIR, "manifest.json");
|
|
@@ -53,24 +57,88 @@ function updateManifest(storyId, sourcePath, fileHash, boundingBox) {
|
|
|
53
57
|
};
|
|
54
58
|
saveManifest(manifest);
|
|
55
59
|
}
|
|
56
|
-
var
|
|
60
|
+
var execFileAsync = promisify(execFile);
|
|
61
|
+
var require2 = createRequire$1(import.meta.url);
|
|
62
|
+
var browserPromise = null;
|
|
63
|
+
var installPromise = null;
|
|
64
|
+
var isMissingExecutableError = (err) => {
|
|
65
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
66
|
+
return msg.includes("Executable doesn't exist") || msg.includes("Please run the following command to download new browsers") || // Older playwright revisions phrase the version-mismatch case differently.
|
|
67
|
+
/chromium-\d+\/chrome-linux\/chrome/i.test(msg);
|
|
68
|
+
};
|
|
69
|
+
function resolvePlaywrightCli() {
|
|
70
|
+
const pkgJson = require2.resolve("playwright-core/package.json");
|
|
71
|
+
return join(dirname(pkgJson), "cli.js");
|
|
72
|
+
}
|
|
73
|
+
async function installChromium() {
|
|
74
|
+
if (!installPromise) {
|
|
75
|
+
installPromise = (async () => {
|
|
76
|
+
const cliPath = resolvePlaywrightCli();
|
|
77
|
+
console.log(
|
|
78
|
+
`[STORYBOOK_PLUGIN] chromium binary missing \u2014 installing via ${cliPath}`
|
|
79
|
+
);
|
|
80
|
+
try {
|
|
81
|
+
const { stdout, stderr } = await execFileAsync(
|
|
82
|
+
process.execPath,
|
|
83
|
+
[cliPath, "install", "--force", "chromium"],
|
|
84
|
+
{ timeout: 5 * 60 * 1e3, maxBuffer: 32 * 1024 * 1024 }
|
|
85
|
+
);
|
|
86
|
+
if (stdout)
|
|
87
|
+
console.log(`[STORYBOOK_PLUGIN] playwright install: ${stdout.slice(-1e3)}`);
|
|
88
|
+
if (stderr)
|
|
89
|
+
console.log(
|
|
90
|
+
`[STORYBOOK_PLUGIN] playwright install stderr: ${stderr.slice(-1e3)}`
|
|
91
|
+
);
|
|
92
|
+
console.log("[STORYBOOK_PLUGIN] chromium installed");
|
|
93
|
+
} catch (err) {
|
|
94
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
95
|
+
console.error(`[STORYBOOK_PLUGIN] chromium install FAILED: ${detail}`);
|
|
96
|
+
throw new Error(`Playwright chromium install failed: ${detail}`);
|
|
97
|
+
} finally {
|
|
98
|
+
installPromise = null;
|
|
99
|
+
}
|
|
100
|
+
})();
|
|
101
|
+
}
|
|
102
|
+
return installPromise;
|
|
103
|
+
}
|
|
104
|
+
async function launchWithSelfHeal() {
|
|
105
|
+
try {
|
|
106
|
+
return await chromium.launch({ headless: true });
|
|
107
|
+
} catch (err) {
|
|
108
|
+
if (!isMissingExecutableError(err)) throw err;
|
|
109
|
+
console.log("[STORYBOOK_PLUGIN] launch failed, attempting self-heal install");
|
|
110
|
+
await installChromium();
|
|
111
|
+
try {
|
|
112
|
+
return await chromium.launch({ headless: true });
|
|
113
|
+
} catch (postInstallErr) {
|
|
114
|
+
const detail = postInstallErr instanceof Error ? postInstallErr.message : String(postInstallErr);
|
|
115
|
+
console.error(
|
|
116
|
+
`[STORYBOOK_PLUGIN] launch still failing after install \u2014 likely path or libs issue: ${detail}`
|
|
117
|
+
);
|
|
118
|
+
throw new Error(
|
|
119
|
+
`Playwright chromium is unavailable in this sandbox (install ran but launch still failed): ${detail}`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
57
124
|
async function getBrowser() {
|
|
58
|
-
if (!
|
|
59
|
-
|
|
60
|
-
|
|
125
|
+
if (!browserPromise) {
|
|
126
|
+
browserPromise = launchWithSelfHeal().catch((err) => {
|
|
127
|
+
browserPromise = null;
|
|
128
|
+
throw err;
|
|
61
129
|
});
|
|
62
130
|
}
|
|
63
|
-
return
|
|
131
|
+
return browserPromise;
|
|
64
132
|
}
|
|
65
133
|
async function closeBrowser() {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
134
|
+
const pending = browserPromise;
|
|
135
|
+
if (!pending) return;
|
|
136
|
+
browserPromise = null;
|
|
137
|
+
try {
|
|
138
|
+
const b = await pending;
|
|
139
|
+
await b.close();
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.error("Error closing browser:", error);
|
|
74
142
|
}
|
|
75
143
|
}
|
|
76
144
|
function getScreenshotPath(storyId, theme) {
|
|
@@ -82,8 +150,8 @@ function screenshotExists(storyId, theme) {
|
|
|
82
150
|
return fs.existsSync(screenshotPath);
|
|
83
151
|
}
|
|
84
152
|
async function captureScreenshotBuffer(storyId, theme, width = VIEWPORT_WIDTH, height = VIEWPORT_HEIGHT, storybookUrl = "http://localhost:6006", timeoutMs = 3e4) {
|
|
85
|
-
const
|
|
86
|
-
const context = await
|
|
153
|
+
const browser = await getBrowser();
|
|
154
|
+
const context = await browser.newContext({
|
|
87
155
|
viewport: { width, height },
|
|
88
156
|
deviceScaleFactor: 2
|
|
89
157
|
});
|
|
@@ -188,6 +256,61 @@ async function generateScreenshot(storyId, theme, storybookUrl = "http://localho
|
|
|
188
256
|
}
|
|
189
257
|
|
|
190
258
|
// src/screenshot-service/screenshot-service.ts
|
|
259
|
+
var ONBOOK_PROXY_TOKEN = process.env.ONBOOK_PROXY_TOKEN ?? null;
|
|
260
|
+
var ONBOOK_BROADCAST_URL = process.env.ONBOOK_BROADCAST_URL ?? null;
|
|
261
|
+
var PROGRESS_TIMEOUT_MS = 3e3;
|
|
262
|
+
async function broadcastScreenshotProgress(completed, total) {
|
|
263
|
+
if (!ONBOOK_PROXY_TOKEN || !ONBOOK_BROADCAST_URL) return;
|
|
264
|
+
const percent = total > 0 ? Math.min(100, Math.floor(completed / total * 100)) : null;
|
|
265
|
+
try {
|
|
266
|
+
await fetch(ONBOOK_BROADCAST_URL, {
|
|
267
|
+
method: "POST",
|
|
268
|
+
headers: {
|
|
269
|
+
Authorization: `Bearer ${ONBOOK_PROXY_TOKEN}`,
|
|
270
|
+
"Content-Type": "application/json"
|
|
271
|
+
},
|
|
272
|
+
body: JSON.stringify({
|
|
273
|
+
event: {
|
|
274
|
+
type: "SANDBOX_PHASE_PROGRESS",
|
|
275
|
+
phase: "generating_screenshots",
|
|
276
|
+
completed,
|
|
277
|
+
total,
|
|
278
|
+
percent,
|
|
279
|
+
label: "Capturing stories"
|
|
280
|
+
}
|
|
281
|
+
}),
|
|
282
|
+
signal: AbortSignal.timeout(PROGRESS_TIMEOUT_MS)
|
|
283
|
+
});
|
|
284
|
+
} catch {
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
var StoryTimeoutError = class extends Error {
|
|
288
|
+
constructor(storyId, timeoutMs) {
|
|
289
|
+
super(`Story ${storyId} timed out after ${timeoutMs / 1e3}s`);
|
|
290
|
+
this.storyId = storyId;
|
|
291
|
+
this.timeoutMs = timeoutMs;
|
|
292
|
+
this.name = "StoryTimeoutError";
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
async function captureBothThemes(storyId, storybookUrl, timeoutMs, storyTimeoutMs) {
|
|
296
|
+
let timer;
|
|
297
|
+
try {
|
|
298
|
+
return await Promise.race([
|
|
299
|
+
Promise.all([
|
|
300
|
+
generateScreenshot(storyId, "light", storybookUrl, timeoutMs),
|
|
301
|
+
generateScreenshot(storyId, "dark", storybookUrl, timeoutMs)
|
|
302
|
+
]),
|
|
303
|
+
new Promise((_, reject) => {
|
|
304
|
+
timer = setTimeout(
|
|
305
|
+
() => reject(new StoryTimeoutError(storyId, storyTimeoutMs)),
|
|
306
|
+
storyTimeoutMs
|
|
307
|
+
);
|
|
308
|
+
})
|
|
309
|
+
]);
|
|
310
|
+
} finally {
|
|
311
|
+
if (timer) clearTimeout(timer);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
191
314
|
async function generateAllScreenshots(stories, storybookUrl = "http://localhost:6006", concurrency = 10, offset = 0, total, skipExisting = false, timeoutMs = 3e4) {
|
|
192
315
|
const displayTotal = total ?? offset + stories.length;
|
|
193
316
|
console.log(
|
|
@@ -198,58 +321,82 @@ async function generateAllScreenshots(stories, storybookUrl = "http://localhost:
|
|
|
198
321
|
for (let i = 0; i < stories.length; i += BATCH_SIZE) {
|
|
199
322
|
batches.push(stories.slice(i, i + BATCH_SIZE));
|
|
200
323
|
}
|
|
324
|
+
const storyTimeout = timeoutMs * 2 + 1e4;
|
|
201
325
|
let completed = 0;
|
|
326
|
+
void broadcastScreenshotProgress(0, displayTotal);
|
|
202
327
|
for (const batch of batches) {
|
|
203
328
|
await Promise.all(
|
|
204
329
|
batch.map(async (story) => {
|
|
205
330
|
if (skipExisting && screenshotExists(story.id, "light") && screenshotExists(story.id, "dark")) {
|
|
206
331
|
completed++;
|
|
207
|
-
const
|
|
208
|
-
console.log(`[${
|
|
332
|
+
const absoluteIndex2 = offset + completed;
|
|
333
|
+
console.log(`[${absoluteIndex2}/${displayTotal}] Skipped (exists) ${story.id}`);
|
|
209
334
|
return;
|
|
210
335
|
}
|
|
211
|
-
|
|
212
|
-
let
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
336
|
+
let lightResult = null;
|
|
337
|
+
let darkResult = null;
|
|
338
|
+
let lastError;
|
|
339
|
+
const startedAt = Date.now();
|
|
340
|
+
let attempts = 0;
|
|
341
|
+
const maxAttempts = 2;
|
|
342
|
+
while (attempts < maxAttempts) {
|
|
343
|
+
attempts++;
|
|
344
|
+
try {
|
|
345
|
+
[lightResult, darkResult] = await captureBothThemes(
|
|
346
|
+
story.id,
|
|
347
|
+
storybookUrl,
|
|
348
|
+
timeoutMs,
|
|
349
|
+
storyTimeout
|
|
350
|
+
);
|
|
351
|
+
lastError = void 0;
|
|
352
|
+
break;
|
|
353
|
+
} catch (error) {
|
|
354
|
+
lastError = error;
|
|
355
|
+
if (!(error instanceof StoryTimeoutError) || attempts >= maxAttempts) {
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
console.warn(
|
|
359
|
+
`[screenshot] Retrying ${story.id} after timeout (attempt ${attempts + 1}/${maxAttempts})`
|
|
360
|
+
);
|
|
235
361
|
}
|
|
236
|
-
|
|
237
|
-
|
|
362
|
+
}
|
|
363
|
+
completed++;
|
|
364
|
+
const absoluteIndex = offset + completed;
|
|
365
|
+
const durationMs = Date.now() - startedAt;
|
|
366
|
+
if (lightResult && darkResult) {
|
|
367
|
+
const fileHash = computeFileHash(story.importPath);
|
|
368
|
+
updateManifest(story.id, story.importPath, fileHash, lightResult.boundingBox);
|
|
238
369
|
console.log(
|
|
239
|
-
`[${absoluteIndex}/${displayTotal}] Generated screenshots for ${story.id}
|
|
370
|
+
`[${absoluteIndex}/${displayTotal}] Generated screenshots for ${story.id}`,
|
|
371
|
+
{ storyId: story.id, attempts, durationMs, outcome: "ok" }
|
|
240
372
|
);
|
|
241
|
-
}
|
|
242
|
-
completed++;
|
|
243
|
-
const absoluteIndex = offset + completed;
|
|
373
|
+
} else if (lastError) {
|
|
244
374
|
console.error(
|
|
245
375
|
`[${absoluteIndex}/${displayTotal}] \u26A0\uFE0F Failed ${story.id}:`,
|
|
246
|
-
|
|
376
|
+
lastError instanceof Error ? lastError.message : lastError,
|
|
377
|
+
{
|
|
378
|
+
storyId: story.id,
|
|
379
|
+
attempts,
|
|
380
|
+
durationMs,
|
|
381
|
+
outcome: lastError instanceof StoryTimeoutError ? "timeout" : "error"
|
|
382
|
+
}
|
|
247
383
|
);
|
|
384
|
+
} else {
|
|
385
|
+
console.warn(`[${absoluteIndex}/${displayTotal}] Partial result ${story.id}`, {
|
|
386
|
+
storyId: story.id,
|
|
387
|
+
attempts,
|
|
388
|
+
durationMs,
|
|
389
|
+
outcome: "partial",
|
|
390
|
+
hasLight: !!lightResult,
|
|
391
|
+
hasDark: !!darkResult
|
|
392
|
+
});
|
|
248
393
|
}
|
|
249
394
|
})
|
|
250
395
|
);
|
|
396
|
+
void broadcastScreenshotProgress(offset + completed, displayTotal);
|
|
251
397
|
}
|
|
252
398
|
await closeBrowser();
|
|
399
|
+
void broadcastScreenshotProgress(displayTotal, displayTotal);
|
|
253
400
|
console.log("Screenshot generation complete!");
|
|
254
401
|
}
|
|
255
402
|
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { Browser } from 'playwright';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Initialize browser instance
|
|
5
|
-
*/
|
|
6
3
|
declare function getBrowser(): Promise<Browser>;
|
|
7
|
-
/**
|
|
8
|
-
* Close browser instance
|
|
9
|
-
*/
|
|
10
4
|
declare function closeBrowser(): Promise<void>;
|
|
11
5
|
|
|
12
6
|
export { closeBrowser, getBrowser };
|
|
@@ -1,24 +1,93 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { execFile } from 'child_process';
|
|
3
|
+
import { createRequire as createRequire$1 } from 'module';
|
|
4
|
+
import { join, dirname } from 'path';
|
|
5
|
+
import { promisify } from 'util';
|
|
1
6
|
import { chromium } from 'playwright';
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
var
|
|
8
|
+
globalThis.require = createRequire(import.meta.url);
|
|
9
|
+
var execFileAsync = promisify(execFile);
|
|
10
|
+
var require2 = createRequire$1(import.meta.url);
|
|
11
|
+
var browserPromise = null;
|
|
12
|
+
var installPromise = null;
|
|
13
|
+
var isMissingExecutableError = (err) => {
|
|
14
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
15
|
+
return msg.includes("Executable doesn't exist") || msg.includes("Please run the following command to download new browsers") || // Older playwright revisions phrase the version-mismatch case differently.
|
|
16
|
+
/chromium-\d+\/chrome-linux\/chrome/i.test(msg);
|
|
17
|
+
};
|
|
18
|
+
function resolvePlaywrightCli() {
|
|
19
|
+
const pkgJson = require2.resolve("playwright-core/package.json");
|
|
20
|
+
return join(dirname(pkgJson), "cli.js");
|
|
21
|
+
}
|
|
22
|
+
async function installChromium() {
|
|
23
|
+
if (!installPromise) {
|
|
24
|
+
installPromise = (async () => {
|
|
25
|
+
const cliPath = resolvePlaywrightCli();
|
|
26
|
+
console.log(
|
|
27
|
+
`[STORYBOOK_PLUGIN] chromium binary missing \u2014 installing via ${cliPath}`
|
|
28
|
+
);
|
|
29
|
+
try {
|
|
30
|
+
const { stdout, stderr } = await execFileAsync(
|
|
31
|
+
process.execPath,
|
|
32
|
+
[cliPath, "install", "--force", "chromium"],
|
|
33
|
+
{ timeout: 5 * 60 * 1e3, maxBuffer: 32 * 1024 * 1024 }
|
|
34
|
+
);
|
|
35
|
+
if (stdout)
|
|
36
|
+
console.log(`[STORYBOOK_PLUGIN] playwright install: ${stdout.slice(-1e3)}`);
|
|
37
|
+
if (stderr)
|
|
38
|
+
console.log(
|
|
39
|
+
`[STORYBOOK_PLUGIN] playwright install stderr: ${stderr.slice(-1e3)}`
|
|
40
|
+
);
|
|
41
|
+
console.log("[STORYBOOK_PLUGIN] chromium installed");
|
|
42
|
+
} catch (err) {
|
|
43
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
44
|
+
console.error(`[STORYBOOK_PLUGIN] chromium install FAILED: ${detail}`);
|
|
45
|
+
throw new Error(`Playwright chromium install failed: ${detail}`);
|
|
46
|
+
} finally {
|
|
47
|
+
installPromise = null;
|
|
48
|
+
}
|
|
49
|
+
})();
|
|
50
|
+
}
|
|
51
|
+
return installPromise;
|
|
52
|
+
}
|
|
53
|
+
async function launchWithSelfHeal() {
|
|
54
|
+
try {
|
|
55
|
+
return await chromium.launch({ headless: true });
|
|
56
|
+
} catch (err) {
|
|
57
|
+
if (!isMissingExecutableError(err)) throw err;
|
|
58
|
+
console.log("[STORYBOOK_PLUGIN] launch failed, attempting self-heal install");
|
|
59
|
+
await installChromium();
|
|
60
|
+
try {
|
|
61
|
+
return await chromium.launch({ headless: true });
|
|
62
|
+
} catch (postInstallErr) {
|
|
63
|
+
const detail = postInstallErr instanceof Error ? postInstallErr.message : String(postInstallErr);
|
|
64
|
+
console.error(
|
|
65
|
+
`[STORYBOOK_PLUGIN] launch still failing after install \u2014 likely path or libs issue: ${detail}`
|
|
66
|
+
);
|
|
67
|
+
throw new Error(
|
|
68
|
+
`Playwright chromium is unavailable in this sandbox (install ran but launch still failed): ${detail}`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
5
73
|
async function getBrowser() {
|
|
6
|
-
if (!
|
|
7
|
-
|
|
8
|
-
|
|
74
|
+
if (!browserPromise) {
|
|
75
|
+
browserPromise = launchWithSelfHeal().catch((err) => {
|
|
76
|
+
browserPromise = null;
|
|
77
|
+
throw err;
|
|
9
78
|
});
|
|
10
79
|
}
|
|
11
|
-
return
|
|
80
|
+
return browserPromise;
|
|
12
81
|
}
|
|
13
82
|
async function closeBrowser() {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
83
|
+
const pending = browserPromise;
|
|
84
|
+
if (!pending) return;
|
|
85
|
+
browserPromise = null;
|
|
86
|
+
try {
|
|
87
|
+
const b = await pending;
|
|
88
|
+
await b.close();
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error("Error closing browser:", error);
|
|
22
91
|
}
|
|
23
92
|
}
|
|
24
93
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Plugin, PluginOption } from 'vite';
|
|
2
|
+
|
|
3
|
+
/** One module the engine asked us to substitute with a deferred-throw stand-in. */
|
|
4
|
+
type EnvContainmentSubstitution = {
|
|
5
|
+
/**
|
|
6
|
+
* Path of the throwing module relative to the project root (the directory
|
|
7
|
+
* `storybook dev` runs from), posix separators, extension included —
|
|
8
|
+
* e.g. `src/env.ts`. Alias (`@/env`), relative (`../env`), and absolute
|
|
9
|
+
* imports that resolve to this file are all intercepted.
|
|
10
|
+
*/
|
|
11
|
+
module: string;
|
|
12
|
+
/**
|
|
13
|
+
* Best-effort named exports of the real module. The stand-in re-exports
|
|
14
|
+
* each (plus a default export, always) so static ESM bindings keep
|
|
15
|
+
* resolving. Names that aren't valid identifiers are skipped.
|
|
16
|
+
*/
|
|
17
|
+
exports?: string[];
|
|
18
|
+
/** Env keys the module validates — carried into the containment marker. */
|
|
19
|
+
envKeys?: string[];
|
|
20
|
+
/** Recognized schema library (`t3` | `zod` | `valibot`) — diagnostics only. */
|
|
21
|
+
schemaKind?: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* The `envContainment` plugin-options surface. Written by the preflight
|
|
25
|
+
* engine into `.storybook/main.*` (`storybookOnlookPlugin({ envContainment })`).
|
|
26
|
+
* Mirrored structurally as `EnvContainmentValue` in
|
|
27
|
+
* `packages/preflight/src/checks/storybook/patch.ts` — keep the shapes in sync.
|
|
28
|
+
*/
|
|
29
|
+
type EnvContainmentOptions = {
|
|
30
|
+
/** Modules to replace with deferred-throw stand-ins. */
|
|
31
|
+
substitute?: EnvContainmentSubstitution[];
|
|
32
|
+
/**
|
|
33
|
+
* Env key → placeholder value. Each key is injected via Vite `define` as
|
|
34
|
+
* both `process.env.<KEY>` and `import.meta.env.<KEY>`.
|
|
35
|
+
*/
|
|
36
|
+
define?: Record<string, string>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Build the env-containment Vite plugin. Returns `null` when the options
|
|
40
|
+
* carry no work — callers spread it conditionally so a config without
|
|
41
|
+
* `envContainment` behaves exactly as before this plugin existed.
|
|
42
|
+
*/
|
|
43
|
+
declare function envContainmentPlugin(options: EnvContainmentOptions | undefined): Plugin | null;
|
|
44
|
+
|
|
45
|
+
type OnlookPluginOptions = {
|
|
46
|
+
/** Storybook port (default: 6006) */
|
|
47
|
+
port?: number;
|
|
48
|
+
/** Additional allowed origins for CORS (merged with defaults) */
|
|
49
|
+
allowedOrigins?: string[];
|
|
50
|
+
hmr?: {
|
|
51
|
+
protocol?: 'ws' | 'wss';
|
|
52
|
+
clientPort?: number;
|
|
53
|
+
};
|
|
54
|
+
storyGlobs?: string[];
|
|
55
|
+
tailwindEntryCss?: string | false;
|
|
56
|
+
envContainment?: EnvContainmentOptions;
|
|
57
|
+
moduleLoadCatchAll?: boolean;
|
|
58
|
+
};
|
|
59
|
+
declare function storybookOnlookPlugin(options?: OnlookPluginOptions): PluginOption[];
|
|
60
|
+
|
|
61
|
+
export { type EnvContainmentOptions as E, type OnlookPluginOptions as O, type EnvContainmentSubstitution as a, envContainmentPlugin as e, storybookOnlookPlugin as s };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlook/storybook-plugin",
|
|
3
|
-
"version": "0.4.0-beta.
|
|
3
|
+
"version": "0.4.0-beta.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"onlook-storybook": "./dist/cli/index.js"
|
|
@@ -10,6 +10,14 @@
|
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"default": "./dist/index.js"
|
|
12
12
|
},
|
|
13
|
+
"./preset": {
|
|
14
|
+
"types": "./dist/preset/index.d.ts",
|
|
15
|
+
"default": "./dist/preset/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./preview": {
|
|
18
|
+
"types": "./dist/preview/index.d.ts",
|
|
19
|
+
"default": "./dist/preview/index.js"
|
|
20
|
+
},
|
|
13
21
|
"./screenshot-service": {
|
|
14
22
|
"types": "./dist/screenshot-service/index.d.ts",
|
|
15
23
|
"default": "./dist/screenshot-service/index.js"
|
|
@@ -24,25 +32,26 @@
|
|
|
24
32
|
"README.md"
|
|
25
33
|
],
|
|
26
34
|
"scripts": {
|
|
27
|
-
"build": "tsup",
|
|
35
|
+
"build": "rm -rf dist && tsup",
|
|
28
36
|
"clean": "git clean -xdf .cache .turbo dist node_modules",
|
|
29
37
|
"typecheck": "tsc --noEmit",
|
|
30
38
|
"prepublishOnly": "bun run build && bun scripts/prepublish.ts",
|
|
31
39
|
"postpublish": "bun scripts/postpublish.ts",
|
|
32
|
-
"publish-pkg": "
|
|
40
|
+
"publish-pkg": "bun publish",
|
|
41
|
+
"publish-beta": "bun publish --tag beta"
|
|
33
42
|
},
|
|
34
43
|
"dependencies": {
|
|
35
44
|
"@babel/generator": "^7.26.9",
|
|
36
|
-
"@babel/parser": "^7.
|
|
45
|
+
"@babel/parser": "^7.29.3",
|
|
37
46
|
"@babel/traverse": "^7.26.9",
|
|
38
|
-
"@babel/types": "^7.
|
|
47
|
+
"@babel/types": "^7.29.0",
|
|
39
48
|
"@drizzle-team/brocli": "^0.11.0",
|
|
40
|
-
"@takuma-ru/auto-story-generator": "^0.4.0",
|
|
41
49
|
"playwright": "^1.52.0",
|
|
42
|
-
"
|
|
50
|
+
"playwright-core": "^1.52.0",
|
|
51
|
+
"storybook": "^10.1.11"
|
|
43
52
|
},
|
|
44
53
|
"devDependencies": {
|
|
45
|
-
"@onbook/tsconfig": "
|
|
54
|
+
"@onbook/tsconfig": "0.1.0",
|
|
46
55
|
"@types/babel__generator": "^7.6.8",
|
|
47
56
|
"@types/babel__traverse": "^7.20.6",
|
|
48
57
|
"@types/node": "^22.15.32",
|
|
@@ -55,6 +64,7 @@
|
|
|
55
64
|
"access": "public"
|
|
56
65
|
},
|
|
57
66
|
"peerDependencies": {
|
|
58
|
-
"
|
|
67
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
68
|
+
"vite": ">=5.0.0"
|
|
59
69
|
}
|
|
60
70
|
}
|