1 | import global from 'global';
|
2 | import semver from '@storybook/semver';
|
3 | import memoize from 'memoizerific';
|
4 | import { version as currentVersion } from '../version';
|
5 | const {
|
6 | VERSIONCHECK
|
7 | } = global;
|
8 | const getVersionCheckData = memoize(1)(() => {
|
9 | try {
|
10 | return Object.assign({}, JSON.parse(VERSIONCHECK).data || {});
|
11 | } catch (e) {
|
12 | return {};
|
13 | }
|
14 | });
|
15 | export const init = ({
|
16 | store,
|
17 | mode,
|
18 | fullAPI
|
19 | }) => {
|
20 | const {
|
21 | dismissedVersionNotification
|
22 | } = store.getState();
|
23 | const state = {
|
24 | versions: Object.assign({
|
25 | current: {
|
26 | version: currentVersion
|
27 | }
|
28 | }, getVersionCheckData()),
|
29 | dismissedVersionNotification
|
30 | };
|
31 | const api = {
|
32 | getCurrentVersion: () => {
|
33 | const {
|
34 | versions: {
|
35 | current
|
36 | }
|
37 | } = store.getState();
|
38 | return current;
|
39 | },
|
40 | getLatestVersion: () => {
|
41 | const {
|
42 | versions: {
|
43 | latest,
|
44 | next,
|
45 | current
|
46 | }
|
47 | } = store.getState();
|
48 |
|
49 | if (current && semver.prerelease(current.version) && next) {
|
50 | return latest && semver.gt(latest.version, next.version) ? latest : next;
|
51 | }
|
52 |
|
53 | return latest;
|
54 | },
|
55 | versionUpdateAvailable: () => {
|
56 | const latest = api.getLatestVersion();
|
57 | const current = api.getCurrentVersion();
|
58 |
|
59 | if (latest) {
|
60 | if (!latest.version) {
|
61 | return true;
|
62 | }
|
63 |
|
64 | if (!current.version) {
|
65 | return true;
|
66 | }
|
67 |
|
68 | const onPrerelease = !!semver.prerelease(current.version);
|
69 | const actualCurrent = onPrerelease ? `${semver.major(current.version)}.${semver.minor(current.version)}.${semver.patch(current.version)}` : current.version;
|
70 | const diff = semver.diff(actualCurrent, latest.version);
|
71 | return semver.gt(latest.version, actualCurrent) && diff !== 'patch' && !diff.includes('pre');
|
72 | }
|
73 |
|
74 | return false;
|
75 | }
|
76 | };
|
77 |
|
78 | const initModule = async () => {
|
79 | const {
|
80 | versions = {}
|
81 | } = store.getState();
|
82 | const {
|
83 | latest,
|
84 | next
|
85 | } = getVersionCheckData();
|
86 | await store.setState({
|
87 | versions: Object.assign({}, versions, {
|
88 | latest,
|
89 | next
|
90 | })
|
91 | });
|
92 |
|
93 | if (api.versionUpdateAvailable()) {
|
94 | const latestVersion = api.getLatestVersion().version;
|
95 | const diff = semver.diff(versions.current.version, versions.latest.version);
|
96 |
|
97 | if (latestVersion !== dismissedVersionNotification && diff !== 'patch' && !semver.prerelease(latestVersion) && mode !== 'production') {
|
98 | fullAPI.addNotification({
|
99 | id: 'update',
|
100 | link: '/settings/about',
|
101 | content: {
|
102 | headline: `Storybook ${latestVersion} is available!`,
|
103 | subHeadline: `Your current version is: ${versions.current.version}`
|
104 | },
|
105 | icon: {
|
106 | name: 'book'
|
107 | },
|
108 |
|
109 | onClear() {
|
110 | store.setState({
|
111 | dismissedVersionNotification: latestVersion
|
112 | }, {
|
113 | persistence: 'permanent'
|
114 | });
|
115 | }
|
116 |
|
117 | });
|
118 | }
|
119 | }
|
120 | };
|
121 |
|
122 | return {
|
123 | init: initModule,
|
124 | state,
|
125 | api
|
126 | };
|
127 | }; |
\ | No newline at end of file |