UNPKG

creevey

Version:

Cross-browser screenshot testing tool for Storybook with fancy UI Runner

174 lines (139 loc) 6.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = _default; var _path = _interopRequireDefault(require("path")); var _codeFrame = require("@babel/code-frame"); var _loaderUtils = require("loader-utils"); var _schemaUtils = require("schema-utils"); var _parser = require("@babel/parser"); var _traverse = _interopRequireDefault(require("@babel/traverse")); var _generator = _interopRequireDefault(require("@babel/generator")); var _helpers = require("../../storybook/helpers"); var _helpers2 = require("../babel/helpers"); var _logger = require("../../logger"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function transform(ast) { (0, _traverse.default)(ast, { ..._helpers2.commonVisitor, ...(fileType == _helpers2.FileType.Preview ? _helpers2.previewVisitor : undefined), ...(fileType == _helpers2.FileType.Story ? _helpers2.storyVisitor : undefined), ...(isMDX ? _helpers2.mdxVisitor : undefined) }, undefined, { resourcePath, fileType, isMDX, // eslint-disable-next-line @typescript-eslint/no-explicit-any visitedTopPaths: new Set(), visitedBindings: new Set(), reexportedStories }); return (0, _generator.default)(ast, { retainLines: true }).code; } function toPosix(filePath) { return filePath.split(_path.default.win32.sep).join(_path.default.posix.sep).replace(/^[a-z]:/i, ''); } function getIssuerResource(context) { var _context$_module, _context$_module$issu; // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return return (_context$_module = context._module) === null || _context$_module === void 0 ? void 0 : (_context$_module$issu = _context$_module.issuer) === null || _context$_module$issu === void 0 ? void 0 : _context$_module$issu.resource; } function getIssuerConstructorName(context) { var _context$_module2, _context$_module2$iss, _context$_module2$iss2; // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return return (_context$_module2 = context._module) === null || _context$_module2 === void 0 ? void 0 : (_context$_module2$iss = _context$_module2.issuer) === null || _context$_module2$iss === void 0 ? void 0 : (_context$_module2$iss2 = _context$_module2$iss.constructor) === null || _context$_module2$iss2 === void 0 ? void 0 : _context$_module2$iss2.name; } function isEntry(context) { return getIssuerConstructorName(context) == 'MultiModule'; } function isPreview(context, options) { const { dir: resourceDir, name: resourceName } = _path.default.posix.parse(toPosix(context.resourcePath)); const storybookDir = typeof options.storybookDir == 'string' ? toPosix(options.storybookDir) : ''; const isConfigFile = resourceDir == storybookDir && (resourceName == 'preview' || resourceName == 'config'); if ((0, _helpers.isStorybookVersionLessThan)(6)) { return isEntry(context) && isConfigFile; } const issuerResource = getIssuerResource(context); return Boolean(issuerResource && entries.has(issuerResource) && isConfigFile); } function isStoryFile(context) { var _reexportedStories$ge, _context$_module3; const issuerResource = getIssuerResource(context); return getIssuerConstructorName(context) == 'ContextModule' || // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access Boolean(issuerResource && ((_reexportedStories$ge = reexportedStories.get(issuerResource)) === null || _reexportedStories$ge === void 0 ? void 0 : _reexportedStories$ge.has((_context$_module3 = context._module) === null || _context$_module3 === void 0 ? void 0 : _context$_module3.rawRequest))) || issuerResource == previewPath && _path.default.posix.parse(toPosix(previewPath)).name == 'config'; } // NOTE: non-story files before preview => issuer.resource is entry const schema = { type: 'object', properties: { debug: { type: 'boolean' }, storybookDir: { type: 'string' } } }; let fileType = _helpers2.FileType.Invalid; let isMDX = false; let previewPath = ''; let resourcePath = ''; const entries = new Set(); const stories = new Set(); const reexportedStories = new Map(); const isTest = process.env.__CREEVEY_ENV__ == 'test'; const defaultOptions = { debug: isTest, storybookDir: process.cwd() }; function _default(source) { const options = this ? (0, _loaderUtils.getOptions)(this) || defaultOptions : defaultOptions; (0, _schemaUtils.validate)(schema, options, { name: 'Creevey Stories Loader' }); fileType = _helpers2.FileType.Invalid; if (this) { const issuerResource = getIssuerResource(this); resourcePath = this.resourcePath; if (isStoryFile(this)) { fileType = _helpers2.FileType.Story; isMDX = _path.default.parse(resourcePath).ext == '.mdx'; stories.add(this.resourcePath); } else if (isPreview(this, options)) { fileType = _helpers2.FileType.Preview; previewPath = this.resourcePath; } else if (isEntry(this)) { fileType = _helpers2.FileType.Entry; entries.add(this.resourcePath); return source; } else if (issuerResource && stories.has(issuerResource) && options.debug) { _logger.logger.warn('Trying to transform possible non-story file', this.resourcePath, 'Please check the', issuerResource); // TODO Add link to docs, how creevey works and what user should do in this situation } } if (isTest && !Number.isNaN(Number(process.env.CREEVEY_LOADER_FILE_TYPE))) { fileType = Number(process.env.CREEVEY_LOADER_FILE_TYPE); } try { const ast = (0, _parser.parse)(source, { sourceType: 'module', plugins: ['classProperties', 'decorators-legacy', 'jsx', 'typescript'] }); return transform(ast); } catch (error) { this && _logger.logger.warn('Failed to transform file', this.resourcePath); if ('loc' in error) { _logger.logger.warn((0, _codeFrame.codeFrameColumns)(source, { start: error.loc }, { highlightCode: true })); } else { _logger.logger.warn(error); } return source; } }