UNPKG

10.8 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.setConsoleOptions = setConsoleOptions;
7exports.withConsole = withConsole;
8
9var _window = _interopRequireDefault(require("global/window"));
10
11var _addonActions = require("@storybook/addon-actions");
12
13var _reactDecorator = require("./react-decorator");
14
15function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
17function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
18
19function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
20
21function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
22
23function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
24
25function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
26
27function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
28
29function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
30
31var logger = console;
32var cLogger = {
33 log: logger.log,
34 warn: logger.warn,
35 error: logger.error
36};
37/**
38 * @typedef {Object} addonOptions - This options could be passed to [withConsole]{@link #storybookaddon-consolewithconsoleoptionsorfn--function} or [setConsoleOptions]{@link #module_@storybook/addon-console.setConsoleOptions}
39 * @property {RegExp[]} [panelExclude = [/[HMR]/]] - Optional. Anything matched to at least one of regular expressions will be excluded from output to Action Logger Panel
40 * @property {RegExp[]} [panelInclude = []] - Optional. If set, only matched outputs will be shown in Action Logger. Higher priority than `panelExclude`.
41 * @property {RegExp[]} [consoleExclude = []] - Optional. Anything matched to at least one of regular expressions will be excluded from DevTool console output
42 * @property {RegExp[]} [consoleInclude = []] - Optional. If set, only matched outputs will be shown in console. Higher priority than `consoleExclude`.
43 * @property {string} [log = console] - Optional. The marker to display `console.log` outputs in Action Logger
44 * @property {string} [warn = warn] - Optional. The marker to display warnings in Action Logger
45 * @property {string} [error = error] - Optional. The marker to display errors in Action Logger
46 */
47
48var addonOptions = {
49 panelExclude: [/\[HMR\]/],
50 panelInclude: [],
51 consoleExclude: [],
52 consoleInclude: [],
53 log: 'console',
54 warn: 'warn',
55 error: 'error'
56};
57var currentOptions = addonOptions;
58
59var createLogger = function createLogger(options) {
60 return {
61 log: (0, _addonActions.action)(options.log),
62 warn: (0, _addonActions.action)(options.warn),
63 error: (0, _addonActions.action)(options.error)
64 };
65};
66
67var shouldDisplay = function shouldDisplay(messages, exclude, include) {
68 if (include.length) {
69 return messages.filter(function (mess) {
70 return typeof mess === 'string' ? include.find(function (regExp) {
71 return mess.match(regExp);
72 }) : false;
73 });
74 }
75
76 if (exclude.length) {
77 return messages.filter(function (mess) {
78 return typeof mess === 'string' ? !exclude.find(function (regExp) {
79 return mess.match(regExp);
80 }) : true;
81 });
82 }
83
84 return messages;
85};
86
87function setScope(options) {
88 var panelExclude = options.panelExclude,
89 panelInclude = options.panelInclude,
90 consoleExclude = options.consoleExclude,
91 consoleInclude = options.consoleInclude;
92 var aLogger = createLogger(options);
93
94 logger.log = function () {
95 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
96 args[_key] = arguments[_key];
97 }
98
99 var toPanel = shouldDisplay(args, panelExclude, panelInclude);
100 var toConsole = shouldDisplay(args, consoleExclude, consoleInclude);
101 if (toPanel.length) aLogger.log.apply(aLogger, _toConsumableArray(toPanel));
102 if (toConsole.length) cLogger.log.apply(cLogger, _toConsumableArray(toConsole));
103 };
104
105 logger.warn = function () {
106 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
107 args[_key2] = arguments[_key2];
108 }
109
110 var toPanel = shouldDisplay(args, panelExclude, panelInclude);
111 var toConsole = shouldDisplay(args, consoleExclude, consoleInclude);
112 if (toPanel.length) aLogger.warn.apply(aLogger, _toConsumableArray(toPanel));
113 if (toConsole.length) cLogger.warn.apply(cLogger, _toConsumableArray(toConsole));
114 };
115
116 logger.error = function () {
117 for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
118 args[_key3] = arguments[_key3];
119 }
120
121 var toPanel = shouldDisplay(args, panelExclude, panelInclude);
122 var toConsole = shouldDisplay(args, consoleExclude, consoleInclude);
123 if (toPanel.length) aLogger.error.apply(aLogger, _toConsumableArray(toPanel));
124 if (toConsole.length) cLogger.error.apply(cLogger, _toConsumableArray(toConsole));
125 };
126
127 _window.default.onerror = function () {
128 var toPanel = shouldDisplay([arguments.length <= 0 ? undefined : arguments[0]], panelExclude, panelInclude);
129 var toConsole = shouldDisplay([arguments.length <= 0 ? undefined : arguments[0]], consoleExclude, consoleInclude);
130 if (toPanel.length) aLogger.error.apply(aLogger, arguments);
131 if (toConsole.length) return false;
132 return true;
133 };
134}
135
136setScope(addonOptions);
137
138var detectOptions = function detectOptions(prop) {
139 if (!prop) return {};
140
141 if (_typeof(prop) === 'object') {
142 var _newOptions = _objectSpread({}, prop);
143
144 return _newOptions;
145 }
146
147 var newOptions = _objectSpread({}, prop(currentOptions)); // check: should it be currentOptions?
148
149
150 return newOptions;
151};
152/**
153 * This callback could be passed to {@link setConsoleOptions} or {@link withConsole}
154 *
155 * @example
156 * import { withConsole } from `@storybook/addon-console`;
157 *
158 * const optionsCallback = (options) => ({panelExclude: [...options.panelExclude, /Warning/]});
159 * addDecorator((storyFn, context) => withConsole(optionsCallback)(storyFn)(context));
160 *
161 * @callback optionsCallback
162 * @param {addonOptions} currentOptions - the current {@link addonOptions}
163 * @return {addonOptions} - new {@link addonOptions}
164 */
165
166/**
167 * Set addon options and returns a new one
168 * @param {addonOptions|optionsCallback} optionsOrFn
169 * @return {addonOptions}
170 * @see addonOptions
171 * @see optionsCallback
172 *
173 * @example
174import { setConsoleOptions } from '@storybook/addon-console';
175
176const panelExclude = setConsoleOptions({}).panelExclude;
177setConsoleOptions({
178 panelExclude: [...panelExclude, /deprecated/],
179});
180 */
181
182
183function setConsoleOptions(optionsOrFn) {
184 var newOptions = detectOptions(optionsOrFn);
185 currentOptions = _objectSpread({}, currentOptions, newOptions);
186 setScope(currentOptions);
187 return currentOptions;
188}
189
190function handleStoryLogs() {
191 switch (_window.default.STORYBOOK_ENV) {
192 case 'react':
193 return _reactDecorator.reactStory;
194
195 default:
196 logger.warn("Warning! withConsole doesn't support @storybook/".concat(_window.default.STORYBOOK_ENV, ". Use setConsoleOptions instead"));
197 return function (story) {
198 return story;
199 };
200 }
201}
202
203function addConsole(storyFn, context, consoleOptions) {
204 var prevOptions = _objectSpread({}, currentOptions);
205
206 var logNames = context ? {
207 log: "".concat(context.kind, "/").concat(context.story),
208 warn: "".concat(context.kind, "/").concat(context.story, " warn"),
209 error: "".concat(context.kind, "/").concat(context.story, " error")
210 } : {};
211
212 var options = _objectSpread({}, currentOptions, logNames, consoleOptions);
213
214 setScope(options);
215 var story = storyFn();
216 var wrapStory = handleStoryLogs();
217 var wrappedStory = wrapStory(story, function () {
218 return setScope(options);
219 }, function () {
220 return setScope(currentOptions);
221 });
222 currentOptions = prevOptions;
223 setScope(currentOptions);
224 return wrappedStory;
225}
226/**
227 * Wraps your stories with specified addon options.
228 * If you don't pass {`log`, `warn`, `error`} in options argument it'll create them from context for each story individually. Hence you'll see from what exact story you got a log or error. You can log from component's lifecycle methods or within your story.
229 * @param {addonOptions|optionsCallback} [optionsOrFn]
230 * @see [addonOptions]{@link #storybookaddon-consolesetconsoleoptionsoptionsorfn--addonoptions}
231 * @see [optionsCallback]{@link #storybookaddon-consoleoptionscallback--addonoptions}
232 * @return {function} wrappedStoryFn
233 *
234 * @example
235 * import { storiesOf } from '@storybook/react';
236 * import { withConsole } from '@storybook/addon-console';
237 *
238 * storiesOf('withConsole', module)
239 * .addDecorator((storyFn, context) => withConsole()(storyFn)(context))
240 * .add('with Log', () => <Button onClick={() => console.log('Data:', 1, 3, 4)}>Log Button</Button>)
241 * .add('with Warning', () => <Button onClick={() => console.warn('Data:', 1, 3, 4)}>Warn Button</Button>)
242 * .add('with Error', () => <Button onClick={() => console.error('Test Error')}>Error Button</Button>)
243 * .add('with Uncatched Error', () =>
244 * <Button onClick={() => console.log('Data:', T.buu.foo)}>Throw Button</Button>
245 * )
246 // Action Logger Panel:
247 // withConsole/with Log: ["Data:", 1, 3, 4]
248 // withConsole/with Warning warn: ["Data:", 1, 3, 4]
249 // withConsole/with Error error: ["Test Error"]
250 // withConsole/with Uncatched Error error: ["Uncaught TypeError: Cannot read property 'foo' of undefined", "http://localhost:9009/static/preview.bundle.js", 51180, 42, Object]
251 */
252
253
254function withConsole(optionsOrFn) {
255 var newOptions = detectOptions(optionsOrFn);
256 return function (storyFn) {
257 return function (context) {
258 return addConsole(storyFn, context, newOptions);
259 };
260 };
261}
\No newline at end of file