diff --git a/code/lib/manager-api/src/index.tsx b/code/lib/manager-api/src/index.tsx
index 1c1798830583..c9098edc3844 100644
--- a/code/lib/manager-api/src/index.tsx
+++ b/code/lib/manager-api/src/index.tsx
@@ -305,6 +305,7 @@ function ManagerConsumer
({
const comboData = filterer.current(managerContext);
const comboDataArray = useMemo(() => {
+ // @ts-expect-error (No overload matches this call)
return [...Object.entries(comboData).reduce((acc, keyval) => acc.concat(keyval), [])];
}, [managerContext.state]);
@@ -412,6 +413,7 @@ export function useSharedState(stateId: string, defaultState?: S) {
useEffect(() => {
if (quicksync) {
+ // @ts-expect-error (Argument of type 'S | undefined' is not assignable)
api.setAddonState(stateId, defaultState);
}
}, [quicksync]);
diff --git a/code/lib/manager-api/src/lib/store-setup.ts b/code/lib/manager-api/src/lib/store-setup.ts
index 3ee481a35013..c29a0b2ad282 100644
--- a/code/lib/manager-api/src/lib/store-setup.ts
+++ b/code/lib/manager-api/src/lib/store-setup.ts
@@ -5,9 +5,11 @@ import { parse, stringify } from 'telejson';
// setting up the store, overriding set and get to use telejson
export default (_: any) => {
_.fn('set', function (key: string, data: object) {
+ // @ts-expect-error('this' implicitly has type 'any')
return _.set(this._area, this._in(key), stringify(data, { maxDepth: 50 }));
});
_.fn('get', function (key: string, alt: string) {
+ // @ts-expect-error('this' implicitly has type 'any')
const value = _.get(this._area, this._in(key));
return value !== null ? parse(value) : alt || value;
});
diff --git a/code/lib/manager-api/src/lib/stories.ts b/code/lib/manager-api/src/lib/stories.ts
index 0ed013cd9ebc..dffc3dd45a86 100644
--- a/code/lib/manager-api/src/lib/stories.ts
+++ b/code/lib/manager-api/src/lib/stories.ts
@@ -21,7 +21,6 @@ import type {
API_HashEntry,
SetStoriesPayload,
StoryIndexV2,
- Renderer,
} from '@storybook/types';
// eslint-disable-next-line import/no-cycle
import { type API, combineParameters, type State } from '../index';
diff --git a/code/lib/manager-api/src/modules/channel.ts b/code/lib/manager-api/src/modules/channel.ts
index c83c342c5253..0ab1dc910087 100644
--- a/code/lib/manager-api/src/modules/channel.ts
+++ b/code/lib/manager-api/src/modules/channel.ts
@@ -56,12 +56,12 @@ export const init: ModuleFn = ({ provider }) => {
const api: SubAPI = {
getChannel: () => provider.channel,
on: (type, handler) => {
- provider.channel.on(type, handler);
+ provider.channel?.on(type, handler);
- return () => provider.channel.off(type, handler);
+ return () => provider.channel?.off(type, handler);
},
- off: (type, handler) => provider.channel.off(type, handler),
- once: (type, handler) => provider.channel.once(type, handler),
+ off: (type, handler) => provider.channel?.off(type, handler),
+ once: (type, handler) => provider.channel?.once(type, handler),
emit: (type, data, ...args) => {
if (
data?.options?.target &&
@@ -73,7 +73,7 @@ export const init: ModuleFn = ({ provider }) => {
? `storybook-ref-${data.options.target}`
: 'storybook-preview-iframe';
}
- provider.channel.emit(type, data, ...args);
+ provider.channel?.emit(type, data, ...args);
},
collapseAll: () => {
api.emit(STORIES_COLLAPSE_ALL, {});
diff --git a/code/lib/manager-api/src/modules/globals.ts b/code/lib/manager-api/src/modules/globals.ts
index 17c35bbb7224..e9f33a75e202 100644
--- a/code/lib/manager-api/src/modules/globals.ts
+++ b/code/lib/manager-api/src/modules/globals.ts
@@ -35,14 +35,14 @@ export interface SubAPI {
export const init: ModuleFn = ({ store, fullAPI, provider }) => {
const api: SubAPI = {
getGlobals() {
- return store.getState().globals;
+ return store.getState().globals as Globals;
},
getGlobalTypes() {
- return store.getState().globalTypes;
+ return store.getState().globalTypes as GlobalTypes;
},
updateGlobals(newGlobals) {
// Only emit the message to the local ref
- provider.channel.emit(UPDATE_GLOBALS, {
+ provider.channel?.emit(UPDATE_GLOBALS, {
globals: newGlobals,
options: {
target: 'storybook-preview-iframe',
@@ -62,7 +62,7 @@ export const init: ModuleFn = ({ store, fullAPI, provider }) =
}
};
- provider.channel.on(
+ provider.channel?.on(
GLOBALS_UPDATED,
function handleGlobalsUpdated(this: any, { globals }: { globals: Globals }) {
const { ref } = getEventMetadata(this, fullAPI)!;
@@ -78,7 +78,7 @@ export const init: ModuleFn = ({ store, fullAPI, provider }) =
);
// Emitted by the preview on initialization
- provider.channel.on(
+ provider.channel?.on(
SET_GLOBALS,
function handleSetStories(this: any, { globals, globalTypes }: SetGlobalsPayload) {
const { ref } = getEventMetadata(this, fullAPI)!;
diff --git a/code/lib/manager-api/src/modules/layout.ts b/code/lib/manager-api/src/modules/layout.ts
index a7d529868613..7c8401e3c173 100644
--- a/code/lib/manager-api/src/modules/layout.ts
+++ b/code/lib/manager-api/src/modules/layout.ts
@@ -385,7 +385,7 @@ export const init: ModuleFn = ({ store, provider, singleStory
const persisted = pick(store.getState(), 'layout', 'selectedPanel');
- provider.channel.on(SET_CONFIG, () => {
+ provider.channel?.on(SET_CONFIG, () => {
api.setOptions(merge(api.getInitialOptions(), persisted));
});
diff --git a/code/lib/manager-api/src/modules/refs.ts b/code/lib/manager-api/src/modules/refs.ts
index f1d52c2adf65..8a5159e9fdb9 100644
--- a/code/lib/manager-api/src/modules/refs.ts
+++ b/code/lib/manager-api/src/modules/refs.ts
@@ -295,6 +295,7 @@ export const init: ModuleFn = (
)
: storyIndex;
+ // @ts-expect-error (could be undefined)
index = transformStoryIndexToStoriesHash(storyIndex, {
provider,
docsOptions,
diff --git a/code/lib/manager-api/src/modules/shortcuts.ts b/code/lib/manager-api/src/modules/shortcuts.ts
index 25f9d14095c6..d050028f8b8b 100644
--- a/code/lib/manager-api/src/modules/shortcuts.ts
+++ b/code/lib/manager-api/src/modules/shortcuts.ts
@@ -392,7 +392,7 @@ export const init: ModuleFn = ({ store, fullAPI, provider }) => {
});
// Also listen to keydown events sent over the channel
- provider.channel.on(PREVIEW_KEYDOWN, (data: { event: KeyboardEventLike }) => {
+ provider.channel?.on(PREVIEW_KEYDOWN, (data: { event: KeyboardEventLike }) => {
api.handleKeydownEvent(data.event);
});
};
diff --git a/code/lib/manager-api/src/modules/stories.ts b/code/lib/manager-api/src/modules/stories.ts
index 828eabe1aa0c..b4a027f9be1c 100644
--- a/code/lib/manager-api/src/modules/stories.ts
+++ b/code/lib/manager-api/src/modules/stories.ts
@@ -93,7 +93,7 @@ export interface SubAPI {
* @param {string} [refsId] - The ID of the refs to use for resolving the story.
* @returns {API_HashEntry} - The hash entry corresponding to the given story ID.
*/
- resolveStory: (storyId: StoryId, refsId?: string) => API_HashEntry;
+ resolveStory: (storyId: StoryId, refsId?: string) => API_HashEntry | undefined;
/**
* Selects the first story to display in the Storybook UI.
*
@@ -322,9 +322,10 @@ export const init: ModuleFn = ({
resolveStory: (storyId, refId) => {
const { refs, index } = store.getState();
if (refId && !refs[refId]) {
- return null;
+ return undefined;
}
if (refId) {
+ // @ts-expect-error (possibly undefined)
return refs[refId].index ? refs[refId].index[storyId] : undefined;
}
return index ? index[storyId] : undefined;
@@ -353,7 +354,7 @@ export const init: ModuleFn = ({
},
getCurrentParameter: (parameterName) => {
const { storyId, refId } = store.getState();
- const parameters = api.getParameters({ storyId, refId }, parameterName);
+ const parameters = api.getParameters({ storyId, refId: refId as string }, parameterName);
// FIXME Returning falsey parameters breaks a bunch of toolbars code,
// so this strange logic needs to be here until various client code is updated.
return parameters || undefined;
@@ -368,6 +369,11 @@ export const init: ModuleFn = ({
}
const hash = refId ? refs[refId].index || {} : index;
+
+ if (!hash) {
+ return;
+ }
+
const result = api.findSiblingStoryId(storyId, hash, direction, true);
if (result) {
@@ -384,6 +390,11 @@ export const init: ModuleFn = ({
}
const hash = story.refId ? refs[story.refId].index : index;
+
+ if (!hash) {
+ return;
+ }
+
const result = api.findSiblingStoryId(storyId, hash, direction, false);
if (result) {
@@ -392,6 +403,9 @@ export const init: ModuleFn = ({
},
selectFirstStory: () => {
const { index } = store.getState();
+ if (!index) {
+ return;
+ }
const firstStory = Object.keys(index).find((id) => index[id].type === 'story');
if (firstStory) {
@@ -409,6 +423,10 @@ export const init: ModuleFn = ({
const kindSlug = storyId?.split('--', 2)[0];
+ if (!hash) {
+ return;
+ }
+
if (!name) {
// Find the entry (group, component or story) that is referred to
const entry = titleOrId ? hash[titleOrId] || hash[sanitize(titleOrId)] : hash[kindSlug];
@@ -491,15 +509,15 @@ export const init: ModuleFn = ({
},
updateStoryArgs: (story, updatedArgs) => {
const { id: storyId, refId } = story;
- provider.channel.emit(UPDATE_STORY_ARGS, {
+ provider.channel?.emit(UPDATE_STORY_ARGS, {
storyId,
updatedArgs,
options: { target: refId },
});
},
- resetStoryArgs: (story, argNames?: [string]) => {
+ resetStoryArgs: (story, argNames) => {
const { id: storyId, refId } = story;
- provider.channel.emit(RESET_STORY_ARGS, {
+ provider.channel?.emit(RESET_STORY_ARGS, {
storyId,
argNames,
options: { target: refId },
@@ -519,7 +537,7 @@ export const init: ModuleFn = ({
}
await api.setIndex(storyIndex);
- } catch (err) {
+ } catch (err: any) {
await store.setState({ indexError: err });
}
},
@@ -547,6 +565,9 @@ export const init: ModuleFn = ({
): Promise => {
if (!ref) {
const { index } = store.getState();
+ if (!index) {
+ return;
+ }
index[storyId] = {
...index[storyId],
...update,
@@ -568,6 +589,9 @@ export const init: ModuleFn = ({
): Promise => {
if (!ref) {
const { index } = store.getState();
+ if (!index) {
+ return;
+ }
index[docsId] = {
...index[docsId],
...update,
@@ -643,7 +667,7 @@ export const init: ModuleFn = ({
// On initial load, the local iframe will select the first story (or other "selection specifier")
// and emit STORY_SPECIFIED with the id. We need to ensure we respond to this change.
- provider.channel.on(
+ provider.channel?.on(
STORY_SPECIFIED,
function handler(
this: any,
@@ -664,7 +688,7 @@ export const init: ModuleFn = ({
state.path === '/' || state.viewMode === 'story' || state.viewMode === 'docs';
const stateHasSelection = state.viewMode && state.storyId;
const stateSelectionDifferent = state.viewMode !== viewMode || state.storyId !== storyId;
- const { type } = state.index[state.storyId] || {};
+ const { type } = state.index?.[state.storyId] || {};
const isStory = !(type === 'root' || type === 'component' || type === 'group');
/**
@@ -677,7 +701,7 @@ export const init: ModuleFn = ({
if (isCanvasRoute) {
if (stateHasSelection && stateSelectionDifferent && isStory) {
// The manager state is correct, the preview state is lagging behind
- provider.channel.emit(SET_CURRENT_STORY, {
+ provider.channel?.emit(SET_CURRENT_STORY, {
storyId: state.storyId,
viewMode: state.viewMode,
});
@@ -694,12 +718,12 @@ export const init: ModuleFn = ({
// Until the ref has a selection, it will not render anything (e.g. while waiting for
// the preview.js file or the index to load). Once it has a selection, it will render its own
// preparing spinner.
- provider.channel.on(CURRENT_STORY_WAS_SET, function handler(this: any) {
+ provider.channel?.on(CURRENT_STORY_WAS_SET, function handler(this: any) {
const { ref } = getEventMetadata(this, fullAPI)!;
api.setPreviewInitialized(ref);
});
- provider.channel.on(STORY_CHANGED, function handler(this: any) {
+ provider.channel?.on(STORY_CHANGED, function handler(this: any) {
const { sourceType } = getEventMetadata(this, fullAPI)!;
if (sourceType === 'local') {
@@ -711,7 +735,7 @@ export const init: ModuleFn = ({
}
});
- provider.channel.on(
+ provider.channel?.on(
STORY_PREPARED,
function handler(this: any, { id, ...update }: StoryPreparedPayload) {
const { ref, sourceType } = getEventMetadata(this, fullAPI)!;
@@ -728,6 +752,10 @@ export const init: ModuleFn = ({
if (sourceType === 'local') {
const { storyId, index, refId } = store.getState();
+ if (!index) {
+ return;
+ }
+
// create a list of related stories to be preloaded
const toBePreloaded = Array.from(
new Set([
@@ -736,7 +764,7 @@ export const init: ModuleFn = ({
])
).filter(Boolean);
- provider.channel.emit(PRELOAD_ENTRIES, {
+ provider.channel?.emit(PRELOAD_ENTRIES, {
ids: toBePreloaded,
options: { target: refId },
});
@@ -744,7 +772,7 @@ export const init: ModuleFn = ({
}
);
- provider.channel.on(
+ provider.channel?.on(
DOCS_PREPARED,
function handler(this: any, { id, ...update }: DocsPreparedPayload) {
const { ref } = getEventMetadata(this, fullAPI)!;
@@ -752,7 +780,7 @@ export const init: ModuleFn = ({
}
);
- provider.channel.on(SET_INDEX, function handler(this: any, index: API_PreparedStoryIndex) {
+ provider.channel?.on(SET_INDEX, function handler(this: any, index: API_PreparedStoryIndex) {
const { ref } = getEventMetadata(this, fullAPI)!;
if (!ref) {
@@ -765,7 +793,7 @@ export const init: ModuleFn = ({
});
// For composition back-compatibilty
- provider.channel.on(SET_STORIES, function handler(this: any, data: SetStoriesPayload) {
+ provider.channel?.on(SET_STORIES, function handler(this: any, data: SetStoriesPayload) {
const { ref } = getEventMetadata(this, fullAPI)!;
const setStoriesData = data.v ? denormalizeStoryParameters(data) : data.stories;
@@ -776,7 +804,7 @@ export const init: ModuleFn = ({
}
});
- provider.channel.on(
+ provider.channel?.on(
SELECT_STORY,
function handler(
this: any,
@@ -806,7 +834,7 @@ export const init: ModuleFn = ({
}
);
- provider.channel.on(
+ provider.channel?.on(
STORY_ARGS_UPDATED,
function handleStoryArgsUpdated(
this: any,
@@ -818,17 +846,17 @@ export const init: ModuleFn = ({
);
// When there's a preview error, we don't show it in the manager, but simply
- provider.channel.on(CONFIG_ERROR, function handleConfigError(this: any, err: any) {
+ provider.channel?.on(CONFIG_ERROR, function handleConfigError(this: any, err: any) {
const { ref } = getEventMetadata(this, fullAPI)!;
api.setPreviewInitialized(ref);
});
- provider.channel.on(STORY_MISSING, function handleConfigError(this: any, err: any) {
+ provider.channel?.on(STORY_MISSING, function handleConfigError(this: any, err: any) {
const { ref } = getEventMetadata(this, fullAPI)!;
api.setPreviewInitialized(ref);
});
- provider.channel.on(SET_CONFIG, () => {
+ provider.channel?.on(SET_CONFIG, () => {
const config = provider.getConfig();
if (config?.sidebar?.filters) {
store.setState({
@@ -845,7 +873,7 @@ export const init: ModuleFn = ({
return {
api,
state: {
- storyId: initialStoryId,
+ storyId: initialStoryId as string,
viewMode: initialViewMode,
hasCalledSetOptions: false,
previewInitialized: false,
@@ -854,7 +882,7 @@ export const init: ModuleFn = ({
},
init: async () => {
if (FEATURES?.storyStoreV7) {
- provider.channel.on(STORY_INDEX_INVALIDATED, () => api.fetchIndex());
+ provider.channel?.on(STORY_INDEX_INVALIDATED, () => api.fetchIndex());
await api.fetchIndex();
}
},
diff --git a/code/lib/manager-api/src/modules/url.ts b/code/lib/manager-api/src/modules/url.ts
index 27d8cef5258f..e9431f04a1f5 100644
--- a/code/lib/manager-api/src/modules/url.ts
+++ b/code/lib/manager-api/src/modules/url.ts
@@ -10,7 +10,7 @@ import { queryFromLocation, buildArgsParam } from '@storybook/router';
import { dequal as deepEqual } from 'dequal';
import { global } from '@storybook/global';
-import type { API_Layout, API_UI } from '@storybook/types';
+import type { API_Layout, API_UI, Args } from '@storybook/types';
import type { ModuleArgs, ModuleFn } from '../lib/types';
import { defaultLayoutState } from './layout';
@@ -101,7 +101,7 @@ const initialUrlSupport = ({
};
export interface QueryParams {
- [key: string]: string | null;
+ [key: string]: string | undefined;
}
/**
@@ -185,7 +185,7 @@ export const init: ModuleFn = (moduleArgs) => {
};
if (!deepEqual(customQueryParams, update)) {
store.setState({ customQueryParams: update });
- provider.channel.emit(UPDATE_QUERY_PARAMS, update);
+ provider.channel?.emit(UPDATE_QUERY_PARAMS, update);
}
},
navigateUrl(url, options) {
@@ -204,15 +204,15 @@ export const init: ModuleFn = (moduleArgs) => {
if (currentStory?.type !== 'story') return;
const { args, initialArgs } = currentStory;
- const argsString = buildArgsParam(initialArgs, args);
+ const argsString = buildArgsParam(initialArgs, args as Args);
navigateTo(path, { ...queryParams, args: argsString }, { replace: true });
api.setQueryParams({ args: argsString });
};
- provider.channel.on(SET_CURRENT_STORY, () => updateArgsParam());
+ provider.channel?.on(SET_CURRENT_STORY, () => updateArgsParam());
let handleOrId: any;
- provider.channel.on(STORY_ARGS_UPDATED, () => {
+ provider.channel?.on(STORY_ARGS_UPDATED, () => {
if ('requestIdleCallback' in globalWindow) {
if (handleOrId) globalWindow.cancelIdleCallback(handleOrId);
handleOrId = globalWindow.requestIdleCallback(updateArgsParam, { timeout: 1000 });
@@ -222,14 +222,14 @@ export const init: ModuleFn = (moduleArgs) => {
}
});
- provider.channel.on(GLOBALS_UPDATED, ({ globals, initialGlobals }: any) => {
+ provider.channel?.on(GLOBALS_UPDATED, ({ globals, initialGlobals }: any) => {
const { path, queryParams } = api.getUrlState();
const globalsString = buildArgsParam(initialGlobals, globals);
navigateTo(path, { ...queryParams, globals: globalsString }, { replace: true });
api.setQueryParams({ globals: globalsString });
});
- provider.channel.on(NAVIGATE_URL, (url: string, options: NavigateOptions) => {
+ provider.channel?.on(NAVIGATE_URL, (url: string, options: NavigateOptions) => {
api.navigateUrl(url, options);
});
diff --git a/code/lib/manager-api/src/modules/versions.ts b/code/lib/manager-api/src/modules/versions.ts
index 15a8a724e651..a230da3a501f 100644
--- a/code/lib/manager-api/src/modules/versions.ts
+++ b/code/lib/manager-api/src/modules/versions.ts
@@ -62,16 +62,16 @@ export const init: ModuleFn = ({ store }) => {
const {
versions: { current },
} = store.getState();
- return current;
+ return current as API_Version;
},
getLatestVersion: () => {
const {
versions: { latest, next, current },
} = store.getState();
if (current && semver.prerelease(current.version) && next) {
- return latest && semver.gt(latest.version, next.version) ? latest : next;
+ return (latest && semver.gt(latest.version, next.version) ? latest : next) as API_Version;
}
- return latest;
+ return latest as API_Version;
},
versionUpdateAvailable: () => {
const latest = api.getLatestVersion();
@@ -110,7 +110,7 @@ export const init: ModuleFn = ({ store }) => {
const { latest, next } = getVersionCheckData();
await store.setState({
- versions: { ...versions, latest, next },
+ versions: { ...versions, latest, next } as API_Versions & API_UnknownEntries,
});
};
diff --git a/code/lib/manager-api/src/modules/whatsnew.ts b/code/lib/manager-api/src/modules/whatsnew.ts
index 27488f702d2e..ab460aa11486 100644
--- a/code/lib/manager-api/src/modules/whatsnew.ts
+++ b/code/lib/manager-api/src/modules/whatsnew.ts
@@ -47,7 +47,7 @@ export const init: ModuleFn = ({ fullAPI, store, provider }) => {
...state.whatsNewData,
disableWhatsNewNotifications: !state.whatsNewData.disableWhatsNewNotifications,
});
- provider.channel.emit(TOGGLE_WHATS_NEW_NOTIFICATIONS, {
+ provider.channel?.emit(TOGGLE_WHATS_NEW_NOTIFICATIONS, {
disableWhatsNewNotifications: state.whatsNewData.disableWhatsNewNotifications,
});
}
@@ -55,17 +55,17 @@ export const init: ModuleFn = ({ fullAPI, store, provider }) => {
};
function getLatestWhatsNewPost(): Promise {
- provider.channel.emit(REQUEST_WHATS_NEW_DATA);
+ provider.channel?.emit(REQUEST_WHATS_NEW_DATA);
return new Promise((resolve) =>
- provider.channel.once(RESULT_WHATS_NEW_DATA, ({ data }: { data: WhatsNewData }) =>
+ provider.channel?.once(RESULT_WHATS_NEW_DATA, ({ data }: { data: WhatsNewData }) =>
resolve(data)
)
);
}
function setWhatsNewCache(cache: WhatsNewCache): void {
- provider.channel.emit(SET_WHATS_NEW_CACHE, cache);
+ provider.channel?.emit(SET_WHATS_NEW_CACHE, cache);
}
const initModule = async () => {