mirror of
https://github.com/storybookjs/storybook.git
synced 2025-03-31 05:03:21 +08:00
Merge pull request #16224 from storybookjs/16049-v7-composition
Core: Support composing stories in both v6 and v7 modes
This commit is contained in:
commit
2302ccbdc6
@ -5,9 +5,11 @@ import {
|
||||
StoriesRaw,
|
||||
StoryInput,
|
||||
StoriesHash,
|
||||
transformStoryIndexToStoriesHash,
|
||||
StoryIndexStory,
|
||||
} from '../lib/stories';
|
||||
|
||||
import { ModuleFn } from '../index';
|
||||
import { ModuleFn, StoryId } from '../index';
|
||||
|
||||
const { location, fetch } = global;
|
||||
|
||||
@ -19,6 +21,7 @@ type Versions = Record<string, string>;
|
||||
|
||||
export type SetRefData = Partial<
|
||||
Omit<ComposedRef, 'stories'> & {
|
||||
v: number;
|
||||
stories?: StoriesRaw;
|
||||
}
|
||||
>;
|
||||
@ -148,7 +151,7 @@ export const init: ModuleFn = ({ store, provider, singleStory }, { runCheck = tr
|
||||
//
|
||||
// then we fetch metadata if the above fetch succeeded
|
||||
|
||||
const loadedData: { error?: Error; stories?: StoriesRaw; loginUrl?: string } = {};
|
||||
const loadedData: { error?: Error; v?: number; stories?: StoriesRaw; loginUrl?: string } = {};
|
||||
const query = version ? `?version=${version}` : '';
|
||||
const credentials = isPublic ? 'omit' : 'include';
|
||||
|
||||
@ -209,18 +212,28 @@ export const init: ModuleFn = ({ store, provider, singleStory }, { runCheck = tr
|
||||
return refs;
|
||||
},
|
||||
|
||||
setRef: (id, { stories, ...rest }, ready = false) => {
|
||||
setRef: (id, { stories, v, ...rest }, ready = false) => {
|
||||
if (singleStory) return;
|
||||
const { storyMapper = defaultStoryMapper } = provider.getConfig();
|
||||
const ref = api.getRefs()[id];
|
||||
const after = stories
|
||||
? addRefIds(
|
||||
transformStoriesRawToStoriesHash(map(stories, ref, { storyMapper }), { provider }),
|
||||
ref
|
||||
)
|
||||
: undefined;
|
||||
|
||||
api.updateRef(id, { stories: after, ...rest, ready });
|
||||
let storiesHash: StoriesHash;
|
||||
|
||||
if (stories) {
|
||||
if (v === 2) {
|
||||
storiesHash = transformStoriesRawToStoriesHash(map(stories, ref, { storyMapper }), {
|
||||
provider,
|
||||
});
|
||||
} else if (!v) {
|
||||
throw new Error('Composition: Missing stories.json version');
|
||||
} else {
|
||||
const index = (stories as unknown) as Record<StoryId, StoryIndexStory>;
|
||||
storiesHash = transformStoryIndexToStoriesHash({ v, stories: index }, { provider });
|
||||
}
|
||||
storiesHash = addRefIds(storiesHash, ref);
|
||||
}
|
||||
|
||||
api.updateRef(id, { stories: storiesHash, ...rest, ready });
|
||||
},
|
||||
|
||||
updateRef: (id, data) => {
|
||||
|
@ -480,11 +480,15 @@ export const init: ModuleFn = ({
|
||||
const { ref } = getEventMetadata(this, fullAPI);
|
||||
fullAPI.updateStory(id, { ...update, prepared: true }, ref);
|
||||
|
||||
if (!store.getState().hasCalledSetOptions) {
|
||||
const { options } = update.parameters;
|
||||
checkDeprecatedOptionParameters(options);
|
||||
fullAPI.setOptions(options);
|
||||
store.setState({ hasCalledSetOptions: true });
|
||||
if (!ref) {
|
||||
if (!store.getState().hasCalledSetOptions) {
|
||||
const { options } = update.parameters;
|
||||
checkDeprecatedOptionParameters(options);
|
||||
fullAPI.setOptions(options);
|
||||
store.setState({ hasCalledSetOptions: true });
|
||||
}
|
||||
} else {
|
||||
fullAPI.updateRef(ref.id, { ready: true });
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -260,11 +260,11 @@ describe('Refs API', () => {
|
||||
setupResponses(
|
||||
{
|
||||
ok: true,
|
||||
response: async () => ({ stories: {} }),
|
||||
response: async () => ({ v: 2, stories: {} }),
|
||||
},
|
||||
{
|
||||
ok: true,
|
||||
response: async () => ({ stories: {} }),
|
||||
response: async () => ({ v: 3, stories: {} }),
|
||||
},
|
||||
{
|
||||
ok: true,
|
||||
@ -418,7 +418,7 @@ describe('Refs API', () => {
|
||||
},
|
||||
{
|
||||
ok: true,
|
||||
response: async () => ({ stories: {} }),
|
||||
response: async () => ({ v: 2, stories: {} }),
|
||||
},
|
||||
{
|
||||
ok: true,
|
||||
@ -621,4 +621,40 @@ describe('Refs API', () => {
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
it('errors on unknown version', async () => {
|
||||
// given
|
||||
const { api } = initRefs({ provider, store }, { runCheck: false });
|
||||
|
||||
setupResponses(
|
||||
{
|
||||
ok: true,
|
||||
response: async () => ({ v: 2, stories: {} }),
|
||||
},
|
||||
{
|
||||
ok: true,
|
||||
response: async () => ({ stories: {} }),
|
||||
},
|
||||
{
|
||||
ok: true,
|
||||
response: async () => {
|
||||
throw new Error('not ok');
|
||||
},
|
||||
},
|
||||
{
|
||||
ok: true,
|
||||
response: async () => ({
|
||||
versions: {},
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
await expect(
|
||||
api.checkRef({
|
||||
id: 'fake',
|
||||
url: 'https://example.com',
|
||||
title: 'Fake',
|
||||
})
|
||||
).rejects.toThrow('Composition: Missing stories.json version');
|
||||
});
|
||||
});
|
||||
|
@ -999,6 +999,7 @@ describe('stories API', () => {
|
||||
args: { c: 'd' },
|
||||
});
|
||||
});
|
||||
|
||||
it('sets options the first time it is called', async () => {
|
||||
const navigate = jest.fn();
|
||||
const store = createMockStore();
|
||||
@ -1026,6 +1027,38 @@ describe('stories API', () => {
|
||||
|
||||
expect(fullAPI.setOptions).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('sets the ref to ready when it is an external story', async () => {
|
||||
const navigate = jest.fn();
|
||||
const store = createMockStore();
|
||||
const fullAPI = Object.assign(new EventEmitter(), {
|
||||
setStories: jest.fn(),
|
||||
updateRef: jest.fn(),
|
||||
});
|
||||
|
||||
const { api, init } = initStories({ store, navigate, provider, fullAPI });
|
||||
Object.assign(fullAPI, api);
|
||||
|
||||
getEventMetadata.mockReturnValueOnce({
|
||||
sourceType: 'external',
|
||||
ref: { id: 'refId', stories: { 'a--1': { args: { a: 'b' } } } },
|
||||
});
|
||||
await init();
|
||||
|
||||
fullAPI.emit(STORY_PREPARED, {
|
||||
id: 'a--1',
|
||||
});
|
||||
|
||||
expect(fullAPI.updateRef.mock.calls.length).toBe(2);
|
||||
|
||||
expect(fullAPI.updateRef.mock.calls[0][1]).toEqual({
|
||||
stories: { 'a--1': { args: { a: 'b' }, prepared: true } },
|
||||
});
|
||||
|
||||
expect(fullAPI.updateRef.mock.calls[1][1]).toEqual({
|
||||
ready: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('v2 SET_STORIES event', () => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user