-
-
Notifications
You must be signed in to change notification settings - Fork 9.1k
/
extract.ts
83 lines (67 loc) · 2.33 KB
/
extract.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import path from 'path';
import { writeFile } from 'fs-extra';
import puppeteerCore from 'puppeteer-core';
import express from 'express';
import getPort from 'get-port';
import { logger } from '@storybook/node-logger';
const read = async (url: string) => {
const browser = await usePuppeteerBrowser();
const page = await browser.newPage();
await page.goto(url);
await page.waitForFunction(
'window.__STORYBOOK_STORY_STORE__ && window.__STORYBOOK_STORY_STORE__.extract && window.__STORYBOOK_STORY_STORE__.extract()'
);
const data = JSON.parse(
await page.evaluate(async () => {
// eslint-disable-next-line no-undef
return JSON.stringify(window.__STORYBOOK_STORY_STORE__.getStoriesJsonData(), null, 2);
})
);
setImmediate(() => {
browser.close();
});
return data;
};
const useLocation: (input: string) => Promise<[string, () => void]> = async (input: string) => {
if (input.match(/^http/)) {
return [input, async () => {}];
}
const app = express();
app.use(express.static(input));
const port = await getPort();
return new Promise((resolve) => {
const server = app.listen(port, () => {
const result = `http://localhost:${port}/iframe.html`;
logger.info(`connecting to: ${result}`);
resolve([result, server.close.bind(server)]);
});
});
};
const usePuppeteerBrowser: () => Promise<puppeteerCore.Browser> = async () => {
const args = ['--no-sandbox ', '--disable-setuid-sandbox'];
try {
return await puppeteerCore.launch({ args });
} catch (e) {
// it's not installed
logger.info('installing puppeteer...');
return new Promise((resolve, reject) => {
// eslint-disable-next-line global-require
require('child_process').exec(
`node ${require.resolve(path.join('puppeteer-core', 'install.js'))}`,
(error: any) => (error ? reject(error) : resolve(puppeteerCore.launch({ args })))
);
});
}
};
export async function extract(input: string, targetPath: string) {
if (input && targetPath) {
const [location, exit] = await useLocation(input);
const data = await read(location);
await writeFile(targetPath, JSON.stringify(data, null, 2));
await exit();
} else {
throw new Error(
'Extract: please specify a path where your built-storybook is (can be a public url) and a target directory'
);
}
}