Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Migrate core to TypeScript #12839

Merged
merged 21 commits into from
Nov 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
31ba8b8
refactor(core): migrate `manager` to TS
gaetanmaisse Sep 28, 2020
adc3121
refactor: export `Config` from `addons` as it is used in a public fun…
gaetanmaisse Sep 28, 2020
28eb524
refactor: improve typings of `Provider`
gaetanmaisse Sep 28, 2020
e71835c
refactor(core): migrate `utils` to TS
gaetanmaisse Sep 28, 2020
c59c21c
refactor(core): migrate `common` to TS
gaetanmaisse Oct 20, 2020
8388b19
refactor(core): migrate `config` to TS
gaetanmaisse Oct 20, 2020
9cb4887
refactor(core): migrate `presets.js` to TS
gaetanmaisse Oct 20, 2020
7e0ea97
refactor(core): migrate `manager` to TS
gaetanmaisse Oct 20, 2020
fb9f801
refactor(core): migrate `preview` to TS
gaetanmaisse Oct 20, 2020
1b8a469
refactor(core): migrate `cli` to TS
gaetanmaisse Oct 20, 2020
02eb42b
refactor(core): migrate root `server` directory to TS
gaetanmaisse Oct 20, 2020
5e15935
refactor(core): add `@storybook/ui` to typings
gaetanmaisse Oct 20, 2020
784c321
refactor(core): improve typings of `server/utils`
gaetanmaisse Oct 21, 2020
3239d25
refactor(core): improve typings of `server/common`
gaetanmaisse Oct 26, 2020
0d08492
refactor(core): introduce a `types.ts` file to centralize some types …
gaetanmaisse Oct 26, 2020
1394788
refactor(core): improve typings of `server/cli`
gaetanmaisse Oct 27, 2020
47863bc
refactor(core): improve typings of dev build and dev server
gaetanmaisse Oct 30, 2020
87da256
docs(core): add a note about internal WIP types that must not be expo…
gaetanmaisse Nov 3, 2020
f85e888
fix(core): fix type of `addons` property in StorybookConfig
gaetanmaisse Nov 3, 2020
6a01f37
chore: add a log to know the level of concurrency in publishing task
gaetanmaisse Nov 3, 2020
d2cbbb7
ci: try to fix `publish` job by limiting the number of concurrent tasks
gaetanmaisse Nov 3, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/addons/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ interface Elements {
[key: string]: Collection;
}

interface Config {
export interface Config {
theme?: ThemeVars;
[key: string]: any;
}
Expand Down
13 changes: 13 additions & 0 deletions lib/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,19 @@
"webpack-virtual-modules": "^0.2.2"
},
"devDependencies": {
"@types/case-sensitive-paths-webpack-plugin": "^2.1.4",
"@types/connect": "^3.4.33",
"@types/cpy": "^7.1.3",
"@types/dotenv-webpack": "^3.0.0",
"@types/interpret": "^1.1.1",
"@types/ip": "^1.1.0",
"@types/mock-fs": "^4.10.0",
"@types/react-dev-utils": "^9.0.4",
"@types/serve-favicon": "^2.5.0",
"@types/terser-webpack-plugin": "^5.0.0",
"@types/webpack-dev-middleware": "^3.7.2",
"@types/webpack-hot-middleware": "^2.25.3",
"@types/webpack-virtual-modules": "^0.1.0",
"mock-fs": "^4.12.0"
},
"peerDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const importPolyfills = () => {
if (!window.fetch) {
// manually patch window.fetch;
// see issue: <https://github.com/developit/unfetch/issues/101#issuecomment-454451035>
const patch = ({ default: fetch }) => {
const patch = ({ default: fetch }: any) => {
window.fetch = fetch;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { Provider } from '@storybook/ui';
import addons from '@storybook/addons';
import addons, { AddonStore, Channel, Config, Types } from '@storybook/addons';
import createChannel from '@storybook/channel-postmessage';
import Events from '@storybook/core-events';

export default class ReactProvider extends Provider {
private addons: AddonStore;

private channel: Channel;

constructor() {
super();

Expand All @@ -16,15 +20,15 @@ export default class ReactProvider extends Provider {
this.channel = channel;
}

getElements(type) {
getElements(type: Types) {
return this.addons.getElements(type);
}

getConfig() {
getConfig(): Config {
return this.addons.getConfig();
}

handleAPI(api) {
handleAPI(api: unknown) {
this.addons.loadAddons(api);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,40 @@ import prettyTime from 'pretty-hrtime';
import inquirer from 'inquirer';
import detectFreePort from 'detect-port';

import { Stats } from 'webpack';
import { storybookDevServer } from './dev-server';
import { getDevCli } from './cli';
import { DevCliOptions, getDevCli } from './cli';
import { resolvePathInStorybookCache } from './utils/resolve-path-in-sb-cache';
import { ReleaseNotesData, VersionCheck, PackageJson, LoadOptions } from './types';

const cache = Cache({
basePath: resolvePathInStorybookCache('dev-server'),
ns: 'storybook', // Optional. A grouping namespace for items.
});

const writeStats = async (name, stats) => {
const writeStats = async (name: string, stats: Stats) => {
await fs.writeFile(
resolvePathInStorybookCache(`public/${name}-stats.json`),
JSON.stringify(stats.toJson(), null, 2),
'utf8'
);
};

const getFreePort = (port) =>
const getFreePort = (port: number) =>
detectFreePort(port).catch((error) => {
logger.error(error);
process.exit(-1);
});

const updateCheck = async (version) => {
const updateCheck = async (version: string): Promise<VersionCheck> => {
let result;
const time = Date.now();
try {
const fromCache = await cache.get('lastUpdateCheck', { success: false, time: 0 });

// if last check was more then 24h ago
if (time - 86400000 > fromCache.time) {
const fromFetch = await Promise.race([
const fromFetch: any = await Promise.race([
fetch(`https://storybook.js.org/versions.json?current=${version}`),
// if fetch is too slow, we won't wait for it
new Promise((res, rej) => global.setTimeout(rej, 1500)),
Expand All @@ -63,13 +65,13 @@ const updateCheck = async (version) => {
// For this reason, we convert the actual version of the build here so that
// every place that relies on this data can reference the version of the
// release notes that we expect to use.
const getReleaseNotesVersion = (version) => {
const getReleaseNotesVersion = (version: string): string => {
const { major, minor } = semver.parse(version);
const { version: releaseNotesVersion } = semver.coerce(`${major}.${minor}`);
return releaseNotesVersion;
};

const getReleaseNotesFailedState = (version) => {
const getReleaseNotesFailedState = (version: string) => {
return {
success: false,
currentVersion: getReleaseNotesVersion(version),
Expand All @@ -79,7 +81,10 @@ const getReleaseNotesFailedState = (version) => {

export const RELEASE_NOTES_CACHE_KEY = 'releaseNotesData';

export const getReleaseNotesData = async (currentVersionToParse, fileSystemCache) => {
export const getReleaseNotesData = async (
currentVersionToParse: string,
fileSystemCache: any
): Promise<ReleaseNotesData> => {
let result;
try {
const fromCache = await fileSystemCache.get('releaseNotesData', []);
Expand Down Expand Up @@ -119,7 +124,7 @@ export const getReleaseNotesData = async (currentVersionToParse, fileSystemCache
return result;
};

function createUpdateMessage(updateInfo, version) {
function createUpdateMessage(updateInfo: VersionCheck, version: string): string {
let updateMessage;

try {
Expand All @@ -143,7 +148,14 @@ function createUpdateMessage(updateInfo, version) {
return updateMessage;
}

function outputStartupInformation(options) {
function outputStartupInformation(options: {
updateInfo: VersionCheck;
version: string;
address: string;
networkAddress: string;
managerTotalTime: [number, number];
previewTotalTime: [number, number];
}) {
const {
updateInfo,
version,
Expand Down Expand Up @@ -173,6 +185,7 @@ function outputStartupInformation(options) {
'right-mid': '',
middle: '',
},
// @ts-ignore
paddingLeft: 0,
paddingRight: 0,
paddingTop: 0,
Expand Down Expand Up @@ -200,12 +213,12 @@ function outputStartupInformation(options) {

${serveMessage.toString()}${updateMessage ? `\n\n${updateMessage}` : ''}
`,
{ borderStyle: 'round', padding: 1, borderColor: '#F1618C' }
{ borderStyle: 'round', padding: 1, borderColor: '#F1618C' } as any
)
);
}

async function outputStats(previewStats, managerStats) {
async function outputStats(previewStats: Stats, managerStats: Stats) {
if (previewStats) {
await writeStats('preview', previewStats);
}
Expand All @@ -215,7 +228,16 @@ async function outputStats(previewStats, managerStats) {
);
}

export async function buildDevStandalone(options) {
export async function buildDevStandalone(
options: DevCliOptions &
LoadOptions & {
packageJson: PackageJson;
ignorePreview: boolean;
docsMode: boolean;
configDir: string;
cache: any;
}
) {
try {
const { packageJson, versionUpdates, releaseNotes } = options;
const { version } = packageJson;
Expand Down Expand Up @@ -243,7 +265,9 @@ export async function buildDevStandalone(options) {

/* eslint-disable no-param-reassign */
options.port = port;
// @ts-ignore
options.versionCheck = updateInfo;
// @ts-ignore
options.releaseNotesData = releaseNotesData;
/* eslint-enable no-param-reassign */

Expand All @@ -258,8 +282,9 @@ export async function buildDevStandalone(options) {

if (options.smokeTest) {
await outputStats(previewStats, managerStats);
const managerWarnings = managerStats.toJson().warnings.length > 0;
const previewWarnings = !options.ignorePreview && previewStats.toJson().warnings.length > 0;
const managerWarnings = (managerStats as any).toJson().warnings.length > 0;
const previewWarnings =
!options.ignorePreview && (previewStats as any).toJson().warnings.length > 0;
process.exit(managerWarnings || previewWarnings ? 1 : 0);
return;
}
Expand All @@ -277,12 +302,12 @@ export async function buildDevStandalone(options) {
npmLog.heading = '';

if (error instanceof Error) {
if (error.error) {
logger.error(error.error);
} else if (error.stats && error.stats.compilation.errors) {
error.stats.compilation.errors.forEach((e) => logger.plain(e));
if ((error as any).error) {
logger.error((error as any).error);
} else if ((error as any).stats && (error as any).stats.compilation.errors) {
(error as any).stats.compilation.errors.forEach((e: any) => logger.plain(e));
} else {
logger.error(error);
logger.error(error as any);
}
}
logger.line();
Expand All @@ -305,14 +330,17 @@ export async function buildDevStandalone(options) {
}
}

export async function buildDev({ packageJson, ...loadOptions }) {
export async function buildDev({
packageJson,
...loadOptions
}: { packageJson: PackageJson } & LoadOptions) {
const cliOptions = await getDevCli(packageJson);

await buildDevStandalone({
...cliOptions,
...loadOptions,
packageJson,
configDir: loadOptions.configDir || cliOptions.configDir || './.storybook',
configDir: (loadOptions as any).configDir || cliOptions.configDir || './.storybook',
ignorePreview: !!cliOptions.previewUrl,
docsMode: !!cliOptions.docs,
cache,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import loadManagerConfig from './manager/manager-config';
import { logConfig } from './logConfig';
import { getPrebuiltDir } from './utils/prebuilt-manager';

async function compileManager(managerConfig, managerStartTime) {
async function compileManager(managerConfig: any, managerStartTime: [number, number]) {
logger.info('=> Compiling manager..');

return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -45,7 +45,7 @@ async function compileManager(managerConfig, managerStartTime) {
});
}

async function watchPreview(previewConfig) {
async function watchPreview(previewConfig: any) {
logger.info('=> Compiling preview in watch mode..');

return new Promise(() => {
Expand All @@ -67,7 +67,7 @@ async function watchPreview(previewConfig) {
});
}

async function compilePreview(previewConfig, previewStartTime) {
async function compilePreview(previewConfig: any, previewStartTime: [number, number]) {
logger.info('=> Compiling preview..');

return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -100,13 +100,14 @@ async function compilePreview(previewConfig, previewStartTime) {
});
}

async function copyAllStaticFiles(staticDir, outputDir) {
async function copyAllStaticFiles(staticDir: any[] | undefined, outputDir: string) {
if (staticDir && staticDir.length) {
await Promise.all(
staticDir.map(async (dir) => {
const [currentStaticDir, staticEndpoint] = dir.split(':').concat('/');
const localStaticPath = path.resolve(currentStaticDir);

// @ts-ignore
if (await !fs.exists(localStaticPath)) {
logger.error(`Error: no such directory to load static files: ${localStaticPath}`);
process.exit(-1);
Expand All @@ -118,7 +119,7 @@ async function copyAllStaticFiles(staticDir, outputDir) {
}
}

async function buildManager(configType, outputDir, configDir, options) {
async function buildManager(configType: any, outputDir: string, configDir: string, options: any) {
logger.info('=> Building manager..');
const managerStartTime = process.hrtime();

Expand All @@ -138,7 +139,7 @@ async function buildManager(configType, outputDir, configDir, options) {
return compileManager(managerConfig, managerStartTime);
}

async function buildPreview(configType, outputDir, packageJson, options) {
async function buildPreview(configType: any, outputDir: string, packageJson: any, options: any) {
const { watch, debugWebpack } = options;

logger.info('=> Building preview..');
Expand All @@ -165,7 +166,7 @@ async function buildPreview(configType, outputDir, packageJson, options) {
return compilePreview(previewConfig, previewStartTime);
}

export async function buildStaticStandalone(options) {
export async function buildStaticStandalone(options: any) {
const { staticDir, configDir, packageJson } = options;

const configType = 'PRODUCTION';
Expand Down Expand Up @@ -197,7 +198,7 @@ export async function buildStaticStandalone(options) {
logger.info(`=> Output directory: ${outputDir}`);
}

export function buildStatic({ packageJson, ...loadOptions }) {
export function buildStatic({ packageJson, ...loadOptions }: any) {
const cliOptions = getProdCli(packageJson);

return buildStaticStandalone({
Expand Down
34 changes: 29 additions & 5 deletions lib/core/src/server/cli/dev.js → lib/core/src/server/cli/dev.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
import program from 'commander';
import program, { CommanderStatic } from 'commander';
import chalk from 'chalk';
import { logger } from '@storybook/node-logger';
import { parseList, getEnvConfig, checkDeprecatedFlags } from './utils';

async function getCLI(packageJson) {
export interface DevCliOptions {
port?: number;
host?: number;
staticDir?: string[];
configDir?: string;
https?: boolean;
sslCa?: string[];
sslCert?: string;
sslKey?: string;
smokeTest?: boolean;
ci?: boolean;
loglevel?: string;
quiet?: boolean;
versionUpdates?: boolean;
releaseNotes?: boolean;
dll?: boolean;
docs?: boolean;
docsDll?: boolean;
uiDll?: boolean;
debugWebpack?: boolean;
previewUrl?: string;
}

export async function getDevCli(packageJson: {
version: string;
name: string;
}): Promise<CommanderStatic & DevCliOptions> {
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

program
Expand Down Expand Up @@ -72,8 +98,6 @@ async function getCLI(packageJson) {
program.port = parseInt(program.port, 10);
}

checkDeprecatedFlags(program);
checkDeprecatedFlags(program as DevCliOptions);
return { ...program };
}

export default getCLI;