/
url.js
58 lines (53 loc) · 1.78 KB
/
url.js
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
import { history, document } from 'global';
import qs from 'qs';
import { toId } from '@storybook/csf';
export function pathToId(path) {
const match = (path || '').match(/^\/story\/(.+)/);
if (!match) {
throw new Error(`Invalid path '${path}', must start with '/story/'`);
}
return match[1];
}
export const setPath = ({ storyId, viewMode }) => {
const { path, selectedKind, selectedStory, ...rest } = qs.parse(document.location.search, {
ignoreQueryPrefix: true,
});
const newPath = `${document.location.pathname}?${qs.stringify({
...rest,
id: storyId,
viewMode,
})}`;
history.replaceState({}, '', newPath);
};
export const getIdFromLegacyQuery = ({ path, selectedKind, selectedStory }, storyStore) => {
if (path) {
return pathToId(path);
}
if (selectedKind && selectedStory) {
// Look up the story ID inside the story store, since as of 5.3, the
// Story ID is not necessarily a direct function of its kind/name.
const story = storyStore.getRawStory(selectedKind, selectedStory);
if (story) {
return story.id;
}
// this will preserve existing behavior of showing a "not found" screen,
// but the inputs will be preserved in the query param to help debugging
return toId(selectedKind, selectedStory);
}
return undefined;
};
export const parseQueryParameters = search => {
const { id } = qs.parse(search, { ignoreQueryPrefix: true });
return id;
};
export const initializePath = storyStore => {
const query = qs.parse(document.location.search, { ignoreQueryPrefix: true });
let { id: storyId, viewMode } = query; // eslint-disable-line prefer-const
if (!storyId) {
storyId = getIdFromLegacyQuery(query, storyStore);
if (storyId) {
setPath({ storyId, viewMode });
}
}
return { storyId, viewMode };
};