Skip to content

Commit

Permalink
Merge pull request #24069 from subhajit20/subhajit/strict-ts-manager-api
Browse files Browse the repository at this point in the history
Build: Migrate `@storybook/manager-api`  to strict TS
  • Loading branch information
ndelangen authored Nov 29, 2023
2 parents 8d3a3b6 + 33eed07 commit a0c55d8
Show file tree
Hide file tree
Showing 21 changed files with 279 additions and 230 deletions.
20 changes: 11 additions & 9 deletions code/lib/manager-api/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export { default as merge } from './lib/merge';
export type { Options as StoreOptions, Listener as ChannelListener };
export { ActiveTabs };

export const ManagerContext = createContext({ api: undefined, state: getInitialState({}) });
export const ManagerContext = createContext({ api: undefined!, state: getInitialState({}!) });

export type State = layout.SubState &
stories.SubState &
Expand Down Expand Up @@ -206,7 +206,7 @@ class ManagerProvider extends Component<ManagerProviderProps, State> {
);

// Create our initial state by combining the initial state of all modules, then overlaying any saved state
const state = getInitialState(this.state, ...this.modules.map((m) => m.state));
const state = getInitialState(this.state, ...this.modules.map((m) => m.state!));

// Get our API by combining the APIs exported by each module
const api: API = Object.assign(this.api, { navigate }, ...this.modules.map((m) => m.api));
Expand All @@ -223,10 +223,10 @@ class ManagerProvider extends Component<ManagerProviderProps, State> {
path: props.path,
refId: props.refId,
viewMode: props.viewMode,
storyId: props.storyId,
storyId: props.storyId!,
};
}
return null;
return null!;
}

shouldComponentUpdate(nextProps: ManagerProviderProps, nextState: State): boolean {
Expand All @@ -245,7 +245,7 @@ class ManagerProvider extends Component<ManagerProviderProps, State> {
initModules = () => {
// Now every module has had a chance to set its API, call init on each module which gives it
// a chance to do things that call other modules' APIs.
this.modules.forEach((module) => {
this.modules.forEach((module: any) => {
if ('init' in module) {
module.init();
}
Expand Down Expand Up @@ -305,11 +305,12 @@ function ManagerConsumer<P = Combo>({
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]);

return useMemo(() => {
const Child = renderer.current as FC<P>;
const Child: any = renderer.current as FC<P>;

return <Child {...comboData} />;
}, comboDataArray);
Expand Down Expand Up @@ -381,14 +382,14 @@ export const useChannel = (eventMap: API_EventMap, deps: any[] = []) => {

export function useStoryPrepared(storyId?: StoryId) {
const api = useStorybookApi();
return api.isPrepared(storyId);
return api.isPrepared(storyId!);
}

export function useParameter<S>(parameterKey: string, defaultValue?: S) {
const api = useStorybookApi();

const result = api.getCurrentParameter<S>(parameterKey);
return orDefault<S>(result, defaultValue);
return orDefault<S>(result, defaultValue!);
}

// cache for taking care of HMR
Expand All @@ -412,6 +413,7 @@ export function useSharedState<S>(stateId: string, defaultState?: S) {

useEffect(() => {
if (quicksync) {
// @ts-expect-error (Argument of type 'S | undefined' is not assignable)
api.setAddonState<S>(stateId, defaultState);
}
}, [quicksync]);
Expand Down Expand Up @@ -490,7 +492,7 @@ export function useArgs(): [Args, (newArgs: Args) => void, (argNames?: string[])
[data, resetStoryArgs]
);

return [args, updateArgs, resetArgs];
return [args!, updateArgs, resetArgs];
}

export function useGlobals(): [Args, (newGlobals: Args) => void] {
Expand Down
7 changes: 3 additions & 4 deletions code/lib/manager-api/src/lib/addons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class AddonStore {
this.setChannel(mockChannel());
}

return this.channel;
return this.channel!;
};

/**
Expand Down Expand Up @@ -105,11 +105,10 @@ export class AddonStore {
| Addon_TypesEnum.experimental_PAGE
| Addon_TypesEnum.experimental_SIDEBAR_BOTTOM
| Addon_TypesEnum.experimental_SIDEBAR_TOP
>(type: T): Addon_Collection<Addon_TypesMapping[T]> {
>(type: T): Addon_Collection<Addon_TypesMapping[T]> | any {
if (!this.elements[type]) {
this.elements[type] = {};
}
// @ts-expect-error (Kaspar told me to do this)
return this.elements[type];
}

Expand Down Expand Up @@ -185,7 +184,7 @@ export class AddonStore {
};

loadAddons = (api: any) => {
Object.values(this.loaders).forEach((value) => value(api));
Object.values(this.loaders).forEach((value: any) => value(api));
};
}

Expand Down
4 changes: 2 additions & 2 deletions code/lib/manager-api/src/lib/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ interface Meta {

export const getEventMetadata = (context: Meta, fullAPI: API) => {
const { source, refId, type } = context;
const [sourceType, sourceLocation] = getSourceType(source, refId);
const [sourceType, sourceLocation] = getSourceType(source!, refId);

const ref =
refId && fullAPI.getRefs()[refId] ? fullAPI.getRefs()[refId] : fullAPI.findRef(sourceLocation);
refId && fullAPI.getRefs()[refId] ? fullAPI.getRefs()[refId] : fullAPI.findRef(sourceLocation!);

const meta = {
source,
Expand Down
2 changes: 1 addition & 1 deletion code/lib/manager-api/src/lib/shortcut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const eventMatchesShortcut = (
e: KeyboardEventLike,
shortcut: API_KeyCollection
): boolean => {
return shortcutMatchesShortcut(eventToShortcut(e), shortcut);
return shortcutMatchesShortcut(eventToShortcut(e)!, shortcut);
};

export const keyToSymbol = (key: string): string => {
Expand Down
2 changes: 2 additions & 0 deletions code/lib/manager-api/src/lib/store-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
Expand Down
26 changes: 13 additions & 13 deletions code/lib/manager-api/src/lib/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const transformSetStoriesStoryDataToPreparedStoryIndex = (
...base,
};
} else {
const { argTypes, args, initialArgs } = story;
const { argTypes, args, initialArgs }: any = story;
acc[id] = {
type: 'story',
...base,
Expand Down Expand Up @@ -109,7 +109,7 @@ export const transformStoryIndexV3toV4 = (index: StoryIndexV3): API_PreparedStor
const countByTitle = countBy(Object.values(index.stories), 'title');
return {
v: 4,
entries: Object.values(index.stories).reduce((acc, entry) => {
entries: Object.values(index.stories).reduce((acc, entry: any) => {
let type: IndexEntry['type'] = 'story';
if (
entry.parameters?.docsOnly ||
Expand Down Expand Up @@ -143,7 +143,7 @@ type ToStoriesHashOptions = {
export const transformStoryIndexToStoriesHash = (
input: API_PreparedStoryIndex | StoryIndexV2 | StoryIndexV3,
{ provider, docsOptions, filters, status }: ToStoriesHashOptions
): API_IndexHash => {
): API_IndexHash | any => {
if (!input.v) {
throw new Error('Composition: Missing stories.json version');
}
Expand All @@ -153,10 +153,10 @@ export const transformStoryIndexToStoriesHash = (
index = index.v === 3 ? transformStoryIndexV3toV4(index as any) : index;
index = index as API_PreparedStoryIndex;

const entryValues = Object.values(index.entries).filter((entry) => {
const entryValues = Object.values(index.entries).filter((entry: any) => {
let result = true;

Object.values(filters).forEach((filter) => {
Object.values(filters).forEach((filter: any) => {
if (result === false) {
return;
}
Expand All @@ -167,11 +167,11 @@ export const transformStoryIndexToStoriesHash = (
});

const { sidebar = {} } = provider.getConfig();
const { showRoots, collapsedRoots = [], renderLabel } = sidebar;
const { showRoots, collapsedRoots = [], renderLabel }: any = sidebar;

const setShowRoots = typeof showRoots !== 'undefined';

const storiesHashOutOfOrder = entryValues.reduce((acc, item) => {
const storiesHashOutOfOrder = entryValues.reduce((acc: any, item: any) => {
if (docsOptions.docsMode && item.type !== 'docs') {
return acc;
}
Expand All @@ -185,7 +185,7 @@ export const transformStoryIndexToStoriesHash = (
// Now create a "path" or sub id for each name
const paths = names.reduce((list, name, idx) => {
const parent = idx > 0 && list[idx - 1];
const id = sanitize(parent ? `${parent}-${name}` : name);
const id = sanitize(parent ? `${parent}-${name}` : name!);

if (parent === id) {
throw new Error(
Expand All @@ -201,7 +201,7 @@ export const transformStoryIndexToStoriesHash = (
}, [] as string[]);

// Now, let's add an entry to the hash for each path/name pair
paths.forEach((id, idx) => {
paths.forEach((id: any, idx: any) => {
// The child is the next path, OR the story/docs entry itself
const childId = paths[idx + 1] || item.id;

Expand Down Expand Up @@ -284,7 +284,7 @@ export const transformStoryIndexToStoriesHash = (
}, {} as API_IndexHash);

// This function adds a "root" or "orphan" and all of its descendents to the hash.
function addItem(acc: API_IndexHash, item: API_HashEntry) {
function addItem(acc: API_IndexHash | any, item: API_HashEntry | any) {
// If we were already inserted as part of a group, that's great.
if (acc[item.id]) {
return acc;
Expand All @@ -293,18 +293,18 @@ export const transformStoryIndexToStoriesHash = (
acc[item.id] = item;
// Ensure we add the children depth-first *before* inserting any other entries
if (item.type === 'root' || item.type === 'group' || item.type === 'component') {
item.children.forEach((childId) => addItem(acc, storiesHashOutOfOrder[childId]));
item.children.forEach((childId: any) => addItem(acc, storiesHashOutOfOrder[childId]));
}
return acc;
}

// We'll do two passes over the data, adding all the orphans, then all the roots
const orphanHash = Object.values(storiesHashOutOfOrder)
.filter((i) => i.type !== 'root' && !i.parent)
.filter((i: any) => i.type !== 'root' && !i.parent)
.reduce(addItem, {});

return Object.values(storiesHashOutOfOrder)
.filter((i) => i.type === 'root')
.filter((i: any) => i.type === 'root')
.reduce(addItem, orphanHash);
};

Expand Down
8 changes: 4 additions & 4 deletions code/lib/manager-api/src/modules/addons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export interface SubAPI {
export function ensurePanel(panels: API_Panels, selectedPanel?: string, currentPanel?: string) {
const keys = Object.keys(panels);

if (keys.indexOf(selectedPanel) >= 0) {
if (keys.indexOf(selectedPanel!) >= 0) {
return selectedPanel;
}

Expand All @@ -95,7 +95,7 @@ export function ensurePanel(panels: API_Panels, selectedPanel?: string, currentP
return currentPanel;
}

export const init: ModuleFn<SubAPI, SubState> = ({ provider, store, fullAPI }) => {
export const init: ModuleFn<SubAPI, SubState> = ({ provider, store, fullAPI }): any => {
const api: SubAPI = {
getElements: (type) => provider.getElements(type),
getPanels: () => api.getElements(Addon_TypesEnum.PANEL),
Expand All @@ -112,7 +112,7 @@ export const init: ModuleFn<SubAPI, SubState> = ({ provider, store, fullAPI }) =

const filteredPanels: Addon_Collection<Addon_BaseType> = {};
Object.entries(allPanels).forEach(([id, panel]) => {
const { paramKey } = panel;
const { paramKey }: any = panel;
if (paramKey && parameters && parameters[paramKey] && parameters[paramKey].disable) {
return;
}
Expand All @@ -121,7 +121,7 @@ export const init: ModuleFn<SubAPI, SubState> = ({ provider, store, fullAPI }) =

return filteredPanels;
},
getSelectedPanel: () => {
getSelectedPanel: (): any => {
const { selectedPanel } = store.getState();
return ensurePanel(api.getElements(Addon_TypesEnum.PANEL), selectedPanel, selectedPanel);
},
Expand Down
10 changes: 5 additions & 5 deletions code/lib/manager-api/src/modules/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ export const init: ModuleFn<SubAPI, SubState> = ({ 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 &&
Expand All @@ -73,7 +73,7 @@ export const init: ModuleFn<SubAPI, SubState> = ({ 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, {});
Expand Down
18 changes: 9 additions & 9 deletions code/lib/manager-api/src/modules/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ export interface SubAPI {
export const init: ModuleFn<SubAPI, SubState> = ({ 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',
Expand All @@ -62,10 +62,10 @@ export const init: ModuleFn<SubAPI, SubState> = ({ store, fullAPI, provider }) =
}
};

provider.channel.on(
provider.channel?.on(
GLOBALS_UPDATED,
function handleGlobalsUpdated({ globals }: { globals: Globals }) {
const { ref } = getEventMetadata(this, fullAPI);
function handleGlobalsUpdated(this: any, { globals }: { globals: Globals }) {
const { ref } = getEventMetadata(this, fullAPI)!;

if (!ref) {
updateGlobals(globals);
Expand All @@ -78,10 +78,10 @@ export const init: ModuleFn<SubAPI, SubState> = ({ store, fullAPI, provider }) =
);

// Emitted by the preview on initialization
provider.channel.on(
provider.channel?.on(
SET_GLOBALS,
function handleSetStories({ globals, globalTypes }: SetGlobalsPayload) {
const { ref } = getEventMetadata(this, fullAPI);
function handleSetStories(this: any, { globals, globalTypes }: SetGlobalsPayload) {
const { ref } = getEventMetadata(this, fullAPI)!;
const currentGlobals = store.getState()?.globals;

if (!ref) {
Expand Down
2 changes: 1 addition & 1 deletion code/lib/manager-api/src/modules/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ export const init: ModuleFn<SubAPI, SubState> = ({ 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));
});

Expand Down
Loading

0 comments on commit a0c55d8

Please sign in to comment.