storycrawler
Version:
Utilities to build Storybook crawling tools with Puppeteer
156 lines (155 loc) • 4.76 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StorybookConnection = void 0;
const cp = __importStar(require("child_process"));
const waitOn = require("wait-on");
const errors_1 = require("./errors");
const logger_1 = require("./logger");
function waitServer(url, timeout) {
if (!url.startsWith('http')) {
throw new errors_1.InvalidUrlError(url);
}
const resource = url.startsWith('https') ? url.replace(/^https/, 'https-get') : url.replace(/^http/, 'http-get');
return new Promise((resolve, reject) => {
waitOn({ resources: [resource], timeout }, err => {
if (err) {
if (err.message === 'Timeout') {
return reject(new errors_1.StorybookServerTimeoutError(timeout));
}
return reject(err);
}
resolve();
});
});
}
/**
*
* Represents a connection to Storybook server
*
* @example
*
* ```ts
* const connection = new StorybookConnection({ storybookUrl: 'http://localhost:9009' });
* await connection.connect();
* ```
*
* You can boot Storybook server via `serverCmd`
*
* ```ts
* const connection = new StorybookConnection({
* storybookUrl: 'http://localhost:9009',
* serverCmd: 'start-storybook -p 9009',
* });
* await connection.connect();
* ```
*
**/
class StorybookConnection {
static spawnCmd(command, options) {
const opt = {
...(options || {}),
shell: true,
};
const [cmd, ...args] = command.split(/\s+/);
return cp.spawn(cmd, args, opt);
}
/**
*
* @param opt Options for construction
* @param logger Logger instance
*
**/
constructor(opt, logger = new logger_1.Logger('silent')) {
this.opt = opt;
this.logger = logger;
this._status = 'DISCONNECTED';
}
/**
*
* @returns URL of Storybook server connecting
*
**/
get url() {
return this.opt.storybookUrl;
}
/**
*
* @returns {@link StorybookConnectionStatus}
*
**/
get status() {
return this._status;
}
/**
*
* Connect Storybook server
*
* @returns Promise of the connection that resolves after connected
*
* @remarks
* If the connection has `serverCmd`, this method boots the server as a child process.
*
**/
async connect() {
this._status = 'CONNECTING';
this.logger.log(`Wait for connecting storybook server ${this.logger.color.green(this.opt.storybookUrl)}.`);
if (this.opt.serverCmd) {
const stdio = this.logger.level === 'verbose' ? [0, 1, 2] : [];
this.proc = StorybookConnection.spawnCmd(this.opt.serverCmd, { stdio });
this.logger.debug('Server process created', this.proc.pid);
}
await waitServer(this.opt.storybookUrl, this.opt.serverTimeout || 10000);
if (this.opt.serverCmd) {
this.logger.debug('Storybook server started');
}
else {
this.logger.debug('Found Storybook server');
}
this._status = 'CONNECTED';
return this;
}
/**
*
* Disconnect to the Storybook server.
*
* @remarks
* If the connection has `serverCmd`, this method shutdowns it.
*
**/
async disconnect() {
if (!this.proc)
return;
try {
this.logger.debug('Shutdown storybook server', this.proc.pid);
this.proc.kill('SIGINT');
}
catch (e) {
// nothing todo
}
this._status = 'DISCONNECTED';
}
}
exports.StorybookConnection = StorybookConnection;