1 | const _excluded = ["stories", "v"];
|
2 |
|
3 | function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
4 |
|
5 | function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
6 |
|
7 | function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
8 |
|
9 | import "core-js/modules/es.array.reduce.js";
|
10 | import global from 'global';
|
11 | import dedent from 'ts-dedent';
|
12 | import { transformStoriesRawToStoriesHash, transformStoryIndexToStoriesHash } from '../lib/stories';
|
13 | const {
|
14 | location,
|
15 | fetch
|
16 | } = global;
|
17 |
|
18 | const findFilename = /(\/((?:[^\/]+?)\.[^\/]+?)|\/)$/;
|
19 | export const getSourceType = (source, refId) => {
|
20 | const {
|
21 | origin: localOrigin,
|
22 | pathname: localPathname
|
23 | } = location;
|
24 | const {
|
25 | origin: sourceOrigin,
|
26 | pathname: sourcePathname
|
27 | } = new URL(source);
|
28 | const localFull = `${localOrigin + localPathname}`.replace(findFilename, '');
|
29 | const sourceFull = `${sourceOrigin + sourcePathname}`.replace(findFilename, '');
|
30 |
|
31 | if (localFull === sourceFull) {
|
32 | return ['local', sourceFull];
|
33 | }
|
34 |
|
35 | if (refId || source) {
|
36 | return ['external', sourceFull];
|
37 | }
|
38 |
|
39 | return [null, null];
|
40 | };
|
41 | export const defaultStoryMapper = (b, a) => {
|
42 | return Object.assign({}, a, {
|
43 | kind: a.kind.replace('|', '/')
|
44 | });
|
45 | };
|
46 |
|
47 | const addRefIds = (input, ref) => {
|
48 | return Object.entries(input).reduce((acc, [id, item]) => {
|
49 | return Object.assign({}, acc, {
|
50 | [id]: Object.assign({}, item, {
|
51 | refId: ref.id
|
52 | })
|
53 | });
|
54 | }, {});
|
55 | };
|
56 |
|
57 | const handle = async request => {
|
58 | if (request) {
|
59 | return Promise.resolve(request).then(response => response.ok ? response.json() : {}).catch(error => ({
|
60 | error
|
61 | }));
|
62 | }
|
63 |
|
64 | return {};
|
65 | };
|
66 |
|
67 | const map = (input, ref, options) => {
|
68 | const {
|
69 | storyMapper
|
70 | } = options;
|
71 |
|
72 | if (storyMapper) {
|
73 | return Object.entries(input).reduce((acc, [id, item]) => {
|
74 | return Object.assign({}, acc, {
|
75 | [id]: storyMapper(ref, item)
|
76 | });
|
77 | }, {});
|
78 | }
|
79 |
|
80 | return input;
|
81 | };
|
82 |
|
83 | export const init = ({
|
84 | store,
|
85 | provider,
|
86 | singleStory
|
87 | }, {
|
88 | runCheck = true
|
89 | } = {}) => {
|
90 | const api = {
|
91 | findRef: source => {
|
92 | const refs = api.getRefs();
|
93 | return Object.values(refs).find(({
|
94 | url
|
95 | }) => url.match(source));
|
96 | },
|
97 | changeRefVersion: (id, url) => {
|
98 | const {
|
99 | versions,
|
100 | title
|
101 | } = api.getRefs()[id];
|
102 | const ref = {
|
103 | id,
|
104 | url,
|
105 | versions,
|
106 | title,
|
107 | stories: {}
|
108 | };
|
109 | api.checkRef(ref);
|
110 | },
|
111 | changeRefState: (id, ready) => {
|
112 | const _api$getRefs = api.getRefs(),
|
113 | {
|
114 | [id]: ref
|
115 | } = _api$getRefs,
|
116 | updated = _objectWithoutPropertiesLoose(_api$getRefs, [id].map(_toPropertyKey));
|
117 |
|
118 | updated[id] = Object.assign({}, ref, {
|
119 | ready
|
120 | });
|
121 | store.setState({
|
122 | refs: updated
|
123 | });
|
124 | },
|
125 | checkRef: async ref => {
|
126 | const {
|
127 | id,
|
128 | url,
|
129 | version,
|
130 | type
|
131 | } = ref;
|
132 | const isPublic = type === 'server-checked';
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 | const loadedData = {};
|
145 | const query = version ? `?version=${version}` : '';
|
146 | const credentials = isPublic ? 'omit' : 'include';
|
147 |
|
148 |
|
149 |
|
150 | const storiesFetch = await fetch(`${url}/stories.json${query}`, {
|
151 | headers: {
|
152 | Accept: 'application/json'
|
153 | },
|
154 | credentials
|
155 | });
|
156 |
|
157 | if (!storiesFetch.ok && !isPublic) {
|
158 | loadedData.error = {
|
159 | message: dedent`
|
160 | Error: Loading of ref failed
|
161 | at fetch (lib/api/src/modules/refs.ts)
|
162 |
|
163 | URL: ${url}
|
164 |
|
165 | We weren't able to load the above URL,
|
166 | it's possible a CORS error happened.
|
167 |
|
168 | Please check your dev-tools network tab.
|
169 | `
|
170 | };
|
171 | } else if (storiesFetch.ok) {
|
172 | const [stories, metadata] = await Promise.all([handle(storiesFetch), handle(fetch(`${url}/metadata.json${query}`, {
|
173 | headers: {
|
174 | Accept: 'application/json'
|
175 | },
|
176 | credentials,
|
177 | cache: 'no-cache'
|
178 | }).catch(() => false))]);
|
179 | Object.assign(loadedData, Object.assign({}, stories, metadata));
|
180 | }
|
181 |
|
182 | const versions = ref.versions && Object.keys(ref.versions).length ? ref.versions : loadedData.versions;
|
183 | await api.setRef(id, Object.assign({
|
184 | id,
|
185 | url
|
186 | }, loadedData, versions ? {
|
187 | versions
|
188 | } : {}, {
|
189 | error: loadedData.error,
|
190 | type: !loadedData.stories ? 'auto-inject' : 'lazy'
|
191 | }));
|
192 | },
|
193 | getRefs: () => {
|
194 | const {
|
195 | refs = {}
|
196 | } = store.getState();
|
197 | return refs;
|
198 | },
|
199 | setRef: (id, _ref, ready = false) => {
|
200 | let {
|
201 | stories,
|
202 | v
|
203 | } = _ref,
|
204 | rest = _objectWithoutPropertiesLoose(_ref, _excluded);
|
205 |
|
206 | if (singleStory) return;
|
207 | const {
|
208 | storyMapper = defaultStoryMapper
|
209 | } = provider.getConfig();
|
210 | const ref = api.getRefs()[id];
|
211 | let storiesHash;
|
212 |
|
213 | if (stories) {
|
214 | if (v === 2) {
|
215 | storiesHash = transformStoriesRawToStoriesHash(map(stories, ref, {
|
216 | storyMapper
|
217 | }), {
|
218 | provider
|
219 | });
|
220 | } else if (!v) {
|
221 | throw new Error('Composition: Missing stories.json version');
|
222 | } else {
|
223 | const index = stories;
|
224 | storiesHash = transformStoryIndexToStoriesHash({
|
225 | v,
|
226 | stories: index
|
227 | }, {
|
228 | provider
|
229 | });
|
230 | }
|
231 |
|
232 | storiesHash = addRefIds(storiesHash, ref);
|
233 | }
|
234 |
|
235 | api.updateRef(id, Object.assign({
|
236 | stories: storiesHash
|
237 | }, rest, {
|
238 | ready
|
239 | }));
|
240 | },
|
241 | updateRef: (id, data) => {
|
242 | const _api$getRefs2 = api.getRefs(),
|
243 | {
|
244 | [id]: ref
|
245 | } = _api$getRefs2,
|
246 | updated = _objectWithoutPropertiesLoose(_api$getRefs2, [id].map(_toPropertyKey));
|
247 |
|
248 | updated[id] = Object.assign({}, ref, data);
|
249 |
|
250 |
|
251 | const ordered = Object.keys(initialState).reduce((obj, key) => {
|
252 | obj[key] = updated[key];
|
253 | return obj;
|
254 | }, {});
|
255 |
|
256 |
|
257 | store.setState({
|
258 | refs: ordered
|
259 | });
|
260 | }
|
261 | };
|
262 | const refs = !singleStory && provider.getConfig().refs || {};
|
263 | const initialState = refs;
|
264 |
|
265 | if (runCheck) {
|
266 | Object.entries(refs).forEach(([k, v]) => {
|
267 | api.checkRef(v);
|
268 | });
|
269 | }
|
270 |
|
271 | return {
|
272 | api,
|
273 | state: {
|
274 | refs: initialState
|
275 | }
|
276 | };
|
277 | }; |
\ | No newline at end of file |