react-cosmos 6.2.4-canary.fb62804e.18 → 7.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/config.schema.json +16 -5
- package/dist/corePlugins/fixtureWatcherPlugin.js +22 -22
- package/dist/corePlugins/fixturesJsonPlugin.js +11 -11
- package/dist/corePlugins/httpProxyPlugin.js +9 -9
- package/dist/corePlugins/index.js +2 -0
- package/dist/corePlugins/openFilePlugin.js +3 -3
- package/dist/corePlugins/pluginEndpointPlugin.js +2 -2
- package/dist/corePlugins/portRetryPlugin.js +5 -5
- package/dist/corePlugins/remoteRendererUrlPlugin.d.ts +2 -0
- package/dist/corePlugins/remoteRendererUrlPlugin.js +9 -0
- package/dist/cosmosConfig/createCosmosConfig.js +3 -3
- package/dist/cosmosConfig/shared.d.ts +3 -1
- package/dist/cosmosConfig/types.d.ts +4 -2
- package/dist/cosmosPlugin/pluginConfigs.d.ts +2 -2
- package/dist/cosmosPlugin/pluginConfigs.js +2 -2
- package/dist/cosmosPlugin/types.d.ts +7 -7
- package/dist/devServer/expressApp.d.ts +2 -2
- package/dist/devServer/expressApp.js +6 -6
- package/dist/devServer/httpServer.d.ts +1 -1
- package/dist/devServer/httpServer.js +7 -27
- package/dist/devServer/httpsCreds.d.ts +7 -0
- package/dist/devServer/httpsCreds.js +24 -0
- package/dist/devServer/startDevServer.js +18 -16
- package/dist/export/generateExport.js +22 -22
- package/dist/getFixtures/getFixtures.d.ts +1 -1
- package/dist/getFixtures/getFixtures.js +10 -10
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/shared/applyServerConfigPlugins.d.ts +4 -4
- package/dist/shared/applyServerConfigPlugins.js +4 -4
- package/dist/shared/playgroundHtml.d.ts +2 -2
- package/dist/shared/playgroundHtml.js +12 -12
- package/dist/shared/playgroundUrl.d.ts +2 -1
- package/dist/shared/playgroundUrl.js +14 -5
- package/dist/shared/remoteRendererUrl.d.ts +2 -0
- package/dist/shared/remoteRendererUrl.js +21 -0
- package/dist/shared/serverAddress.d.ts +3 -0
- package/dist/shared/serverAddress.js +23 -0
- package/dist/shared/serverFixtureList.d.ts +1 -1
- package/dist/shared/serverFixtureList.js +3 -3
- package/dist/shared/staticServer.d.ts +2 -2
- package/dist/shared/webSocketUrl.d.ts +2 -0
- package/dist/shared/webSocketUrl.js +5 -0
- package/dist/testHelpers/mockConsole.js +13 -6
- package/dist/testHelpers/mockFs.d.ts +1 -1
- package/dist/testHelpers/mockFs.js +3 -3
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/userModules/fixtureWatcher.d.ts +1 -1
- package/dist/userModules/fixtureWatcher.js +3 -3
- package/dist/userModules/generateUserImports.d.ts +2 -2
- package/dist/userModules/generateUserImports.js +3 -5
- package/dist/userModules/userImportsLazyTemplate.js +4 -3
- package/dist/userModules/userImportsTemplate.js +4 -3
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
</p>
|
|
5
5
|
|
|
6
6
|
<p align="center">
|
|
7
|
-
<a aria-label="npm version" href="https://www.npmjs.com/package/react-cosmos"><img src="https://img.shields.io/npm/v/react-cosmos.svg?style=flat&colorA=000000&colorB=000000" alt="" /></a>
|
|
7
|
+
<a aria-label="npm version" href="https://www.npmjs.com/package/react-cosmos"><img src="https://img.shields.io/npm/v/react-cosmos/next.svg?style=flat&colorA=000000&colorB=000000" alt="" /></a>
|
|
8
8
|
<a aria-label="CI Status" href="https://github.com/react-cosmos/react-cosmos/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/react-cosmos/react-cosmos/test.yml?branch=main&style=flat&colorA=000000&colorB=000000" alt="" /></a>
|
|
9
9
|
<a aria-label="Codecov" href="https://app.codecov.io/gh/react-cosmos/react-cosmos"><img src="https://img.shields.io/codecov/c/github/react-cosmos/react-cosmos?colorA=000000&colorB=000000" alt="" /></a>
|
|
10
10
|
<a aria-label="Twitter" href="https://twitter.com/ReactCosmos"><img src="https://img.shields.io/badge/twitter-follow-%2300acee?colorA=000000&colorB=000000" alt="" /></a>
|
package/config.schema.json
CHANGED
|
@@ -71,8 +71,8 @@
|
|
|
71
71
|
"description": "Expose user imports and config required for the Cosmos renderer. Used with React Native and in custom integrations. When a path is specified it requires a file extension (eg. \"src/cosmos.imports.ts\"). [default: false]",
|
|
72
72
|
"anyOf": [{ "type": "string", "minLength": 1 }, { "type": "boolean" }]
|
|
73
73
|
},
|
|
74
|
-
"
|
|
75
|
-
"description": "Dev server
|
|
74
|
+
"host": {
|
|
75
|
+
"description": "Dev server host. Set to null to accept connections from any address that reaches the server. [default: null]",
|
|
76
76
|
"anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }]
|
|
77
77
|
},
|
|
78
78
|
"port": {
|
|
@@ -174,8 +174,8 @@
|
|
|
174
174
|
"description": "Path to Vite config. Set to false to disable reading it from the default path. [default: \"vite.config.js\" or \"vite.config.ts\"]",
|
|
175
175
|
"anyOf": [{ "type": "string", "minLength": 1 }, { "enum": [false] }]
|
|
176
176
|
},
|
|
177
|
-
"
|
|
178
|
-
"description": "
|
|
177
|
+
"mainScriptUrl": {
|
|
178
|
+
"description": "URL to custom main script (eg. \"/src/my-main.tsx\"). [default: detect main script URL]",
|
|
179
179
|
"anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }]
|
|
180
180
|
},
|
|
181
181
|
"port": {
|
|
@@ -216,12 +216,23 @@
|
|
|
216
216
|
"type": "object",
|
|
217
217
|
"additionalProperties": true,
|
|
218
218
|
"properties": {
|
|
219
|
+
"rendererPreview": {
|
|
220
|
+
"description": "Options for the renderer preview UI plugin.",
|
|
221
|
+
"type": "object",
|
|
222
|
+
"additionalProperties": false,
|
|
223
|
+
"properties": {
|
|
224
|
+
"backgroundColor": {
|
|
225
|
+
"description": "Background color of the iframe preview. [default: \"#fff\"]",
|
|
226
|
+
"type": "string"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
},
|
|
219
230
|
"responsivePreview": {
|
|
220
231
|
"type": "object",
|
|
221
232
|
"additionalProperties": false,
|
|
222
233
|
"properties": {
|
|
223
234
|
"devices": {
|
|
224
|
-
"description": "List of device viewports",
|
|
235
|
+
"description": "List of device viewports.",
|
|
225
236
|
"type": "array",
|
|
226
237
|
"items": {
|
|
227
238
|
"type": "object",
|
|
@@ -1,53 +1,53 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { pickRendererUrl
|
|
4
|
-
import { getPlaygroundUrl } from '../shared/playgroundUrl.js';
|
|
3
|
+
import { pickRendererUrl } from 'react-cosmos-core';
|
|
5
4
|
import { updateFixtureListCache } from '../shared/serverFixtureList.js';
|
|
5
|
+
import { getWebSocketUrl } from '../shared/webSocketUrl.js';
|
|
6
6
|
import { findUserModulePaths } from '../userModules/findUserModulePaths.js';
|
|
7
7
|
import { startFixtureWatcher } from '../userModules/fixtureWatcher.js';
|
|
8
8
|
import { generateUserImports } from '../userModules/generateUserImports.js';
|
|
9
9
|
import { moduleExists } from '../utils/fs.js';
|
|
10
10
|
export const fixtureWatcherPlugin = {
|
|
11
11
|
name: 'fixtureWatcher',
|
|
12
|
-
async devServer({
|
|
13
|
-
const exposeImports = shouldExposeImports(platform,
|
|
12
|
+
async devServer({ config, platform }) {
|
|
13
|
+
const exposeImports = shouldExposeImports(platform, config);
|
|
14
14
|
if (exposeImports) {
|
|
15
|
-
const modulePaths = await findUserModulePaths(
|
|
16
|
-
await generateImportsFile(
|
|
15
|
+
const modulePaths = await findUserModulePaths(config);
|
|
16
|
+
await generateImportsFile(platform, config, 'dev', modulePaths);
|
|
17
17
|
}
|
|
18
|
-
const watcher = await startFixtureWatcher(
|
|
19
|
-
const modulePaths = await findUserModulePaths(
|
|
20
|
-
updateFixtureListCache(
|
|
18
|
+
const watcher = await startFixtureWatcher(config, 'all', async () => {
|
|
19
|
+
const modulePaths = await findUserModulePaths(config);
|
|
20
|
+
updateFixtureListCache(config.rootDir, modulePaths.fixturePaths);
|
|
21
21
|
if (exposeImports) {
|
|
22
|
-
generateImportsFile(
|
|
22
|
+
generateImportsFile(platform, config, 'dev', modulePaths);
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
return async () => {
|
|
26
26
|
await watcher.close();
|
|
27
27
|
};
|
|
28
28
|
},
|
|
29
|
-
async export({
|
|
30
|
-
if (shouldExposeImports('web',
|
|
31
|
-
const modulePaths = await findUserModulePaths(
|
|
32
|
-
await generateImportsFile(
|
|
29
|
+
async export({ config }) {
|
|
30
|
+
if (shouldExposeImports('web', config)) {
|
|
31
|
+
const modulePaths = await findUserModulePaths(config);
|
|
32
|
+
await generateImportsFile('web', config, 'export', modulePaths);
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
};
|
|
36
|
-
function shouldExposeImports(platform,
|
|
37
|
-
return platform === 'native' || Boolean(
|
|
36
|
+
function shouldExposeImports(platform, config) {
|
|
37
|
+
return platform === 'native' || Boolean(config.exposeImports);
|
|
38
38
|
}
|
|
39
|
-
async function generateImportsFile(
|
|
40
|
-
const { exposeImports } =
|
|
39
|
+
async function generateImportsFile(platform, config, mode, modulePaths) {
|
|
40
|
+
const { exposeImports } = config;
|
|
41
41
|
const filePath = typeof exposeImports === 'string'
|
|
42
42
|
? exposeImports
|
|
43
|
-
: getDefaultFilePath(
|
|
43
|
+
: getDefaultFilePath(config.rootDir);
|
|
44
44
|
const typeScript = /\.tsx?$/.test(filePath);
|
|
45
45
|
const rendererConfig = {
|
|
46
|
-
|
|
47
|
-
rendererUrl: pickRendererUrl(
|
|
46
|
+
webSocketUrl: mode === 'dev' ? getWebSocketUrl(config) : null,
|
|
47
|
+
rendererUrl: platform === 'web' ? pickRendererUrl(config.rendererUrl, mode) : null,
|
|
48
48
|
};
|
|
49
49
|
const fileSource = generateUserImports({
|
|
50
|
-
|
|
50
|
+
config,
|
|
51
51
|
modulePaths,
|
|
52
52
|
rendererConfig,
|
|
53
53
|
relativeToDir: path.dirname(filePath),
|
|
@@ -6,29 +6,29 @@ import { findUserModulePaths } from '../userModules/findUserModulePaths.js';
|
|
|
6
6
|
import { importKeyPath } from '../userModules/shared.js';
|
|
7
7
|
export const fixturesJsonPlugin = {
|
|
8
8
|
name: 'fixturesJson',
|
|
9
|
-
devServer({
|
|
10
|
-
|
|
11
|
-
res.json(await createFixtureItems(
|
|
9
|
+
devServer({ config, app }) {
|
|
10
|
+
app.get('/cosmos.fixtures.json', async (_, res) => {
|
|
11
|
+
res.json(await createFixtureItems(config, 'dev'));
|
|
12
12
|
});
|
|
13
13
|
},
|
|
14
|
-
async export({
|
|
15
|
-
const { exportPath } =
|
|
16
|
-
const json = await createFixtureItems(
|
|
14
|
+
async export({ config }) {
|
|
15
|
+
const { exportPath } = config;
|
|
16
|
+
const json = await createFixtureItems(config, 'export');
|
|
17
17
|
await fs.writeFile(path.join(exportPath, 'cosmos.fixtures.json'), JSON.stringify(json, null, 2));
|
|
18
18
|
},
|
|
19
19
|
};
|
|
20
|
-
async function createFixtureItems(
|
|
21
|
-
const rendererUrl = pickRendererUrl(
|
|
20
|
+
async function createFixtureItems(config, mode) {
|
|
21
|
+
const rendererUrl = pickRendererUrl(config.rendererUrl, mode);
|
|
22
22
|
if (!rendererUrl) {
|
|
23
23
|
return {
|
|
24
24
|
rendererUrl: null,
|
|
25
25
|
fixtures: [],
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
const { fixturesDir, fixtureFileSuffix } =
|
|
29
|
-
const { fixturePaths } = await findUserModulePaths(
|
|
28
|
+
const { fixturesDir, fixtureFileSuffix } = config;
|
|
29
|
+
const { fixturePaths } = await findUserModulePaths(config);
|
|
30
30
|
const fixtures = fixturePaths.map(filePath => {
|
|
31
|
-
const relPath = importKeyPath(filePath,
|
|
31
|
+
const relPath = importKeyPath(filePath, config.rootDir);
|
|
32
32
|
const fixtureId = { path: relPath };
|
|
33
33
|
return {
|
|
34
34
|
filePath: relPath,
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
2
2
|
export const httpProxyPlugin = {
|
|
3
3
|
name: 'httpProxy',
|
|
4
|
-
devServer({
|
|
4
|
+
devServer({ config, platform, app }) {
|
|
5
5
|
if (platform !== 'web')
|
|
6
6
|
return;
|
|
7
|
-
const httpProxyConfig = getHttpProxyCosmosConfig(
|
|
7
|
+
const httpProxyConfig = getHttpProxyCosmosConfig(config);
|
|
8
8
|
Object.keys(httpProxyConfig).forEach(context => {
|
|
9
|
-
const
|
|
10
|
-
if (typeof
|
|
11
|
-
|
|
9
|
+
const value = httpProxyConfig[context];
|
|
10
|
+
if (typeof value === 'string') {
|
|
11
|
+
app.use(context, createProxyMiddleware(context, { target: value }));
|
|
12
12
|
}
|
|
13
|
-
else if (typeof
|
|
14
|
-
|
|
13
|
+
else if (typeof value === 'object') {
|
|
14
|
+
app.use(context, createProxyMiddleware(context, value));
|
|
15
15
|
}
|
|
16
16
|
});
|
|
17
17
|
},
|
|
18
18
|
};
|
|
19
|
-
function getHttpProxyCosmosConfig(
|
|
20
|
-
return (
|
|
19
|
+
function getHttpProxyCosmosConfig(config) {
|
|
20
|
+
return (config.httpProxy || {});
|
|
21
21
|
}
|
|
@@ -4,12 +4,14 @@ import { httpProxyPlugin } from './httpProxyPlugin.js';
|
|
|
4
4
|
import { openFilePlugin } from './openFilePlugin.js';
|
|
5
5
|
import { pluginEndpointPlugin } from './pluginEndpointPlugin.js';
|
|
6
6
|
import { portRetryPlugin } from './portRetryPlugin.js';
|
|
7
|
+
import { remoteRendererUrlPlugin } from './remoteRendererUrlPlugin.js';
|
|
7
8
|
export const coreServerPlugins = [
|
|
8
9
|
portRetryPlugin,
|
|
9
10
|
fixturesJsonPlugin,
|
|
10
11
|
httpProxyPlugin,
|
|
11
12
|
openFilePlugin,
|
|
12
13
|
pluginEndpointPlugin,
|
|
14
|
+
remoteRendererUrlPlugin,
|
|
13
15
|
];
|
|
14
16
|
// Omit starting chokidar in unit tests for performance reasons
|
|
15
17
|
if (process.env.VITEST_WORKER_ID === undefined) {
|
|
@@ -4,14 +4,14 @@ import open from 'open';
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
export const openFilePlugin = {
|
|
6
6
|
name: 'openFile',
|
|
7
|
-
devServer({
|
|
8
|
-
|
|
7
|
+
devServer({ config, app }) {
|
|
8
|
+
app.get('/_open', (req, res) => {
|
|
9
9
|
const { filePath, line, column } = getReqQuery(req);
|
|
10
10
|
if (!filePath) {
|
|
11
11
|
res.status(400).send(`File path missing`);
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
|
-
const absFilePath = resolveFilePath(
|
|
14
|
+
const absFilePath = resolveFilePath(config.rootDir, filePath);
|
|
15
15
|
if (!fs.existsSync(absFilePath)) {
|
|
16
16
|
res.status(404).send(`File not found at path: ${absFilePath}`);
|
|
17
17
|
return;
|
|
@@ -2,8 +2,8 @@ import path from 'node:path';
|
|
|
2
2
|
import { resolveSilent } from '../utils/resolveSilent.js';
|
|
3
3
|
export const pluginEndpointPlugin = {
|
|
4
4
|
name: 'pluginEndpoint',
|
|
5
|
-
devServer({
|
|
6
|
-
|
|
5
|
+
devServer({ app }) {
|
|
6
|
+
app.get('/_plugin/*.js', (req, res) => {
|
|
7
7
|
const modulePath = req.params['0'];
|
|
8
8
|
if (!modulePath) {
|
|
9
9
|
res.sendStatus(404);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { findNextAvailablePort } from '../shared/findNextAvailablePort.js';
|
|
2
2
|
export const portRetryPlugin = {
|
|
3
3
|
name: 'portRetry',
|
|
4
|
-
async config({
|
|
5
|
-
if (
|
|
6
|
-
return
|
|
4
|
+
async config({ config, mode }) {
|
|
5
|
+
if (mode === 'export') {
|
|
6
|
+
return config;
|
|
7
7
|
}
|
|
8
|
-
const { port, portRetries } =
|
|
8
|
+
const { port, portRetries } = config;
|
|
9
9
|
return {
|
|
10
|
-
...
|
|
10
|
+
...config,
|
|
11
11
|
port: portRetries ? await findNextAvailablePort(port, portRetries) : port,
|
|
12
12
|
};
|
|
13
13
|
},
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { getRemoteRendererUrl } from '../shared/remoteRendererUrl.js';
|
|
2
|
+
export const remoteRendererUrlPlugin = {
|
|
3
|
+
name: 'remoteRendererUrlPlugin',
|
|
4
|
+
devServer({ config, app }) {
|
|
5
|
+
app.get('/_cosmos/remote-renderer-url', (_, res) => {
|
|
6
|
+
res.send({ url: getRemoteRendererUrl(config) });
|
|
7
|
+
});
|
|
8
|
+
},
|
|
9
|
+
};
|
|
@@ -12,7 +12,7 @@ export function createCosmosConfig(rootDir, cosmosConfigInput = {}) {
|
|
|
12
12
|
fixtureFileSuffix: getFixtureFileSuffix(cosmosConfigInput),
|
|
13
13
|
fixturesDir: getFixturesDir(cosmosConfigInput),
|
|
14
14
|
globalImports: getGlobalImports(cosmosConfigInput, rootDir),
|
|
15
|
-
|
|
15
|
+
host: getHost(cosmosConfigInput),
|
|
16
16
|
https: getHttps(cosmosConfigInput),
|
|
17
17
|
httpsOptions: getHttpsOptions(cosmosConfigInput, rootDir),
|
|
18
18
|
ignore: getIgnore(cosmosConfigInput),
|
|
@@ -76,8 +76,8 @@ function getExposeImports(cosmosConfigInput, rootDir) {
|
|
|
76
76
|
? path.resolve(rootDir, exposeImports)
|
|
77
77
|
: exposeImports;
|
|
78
78
|
}
|
|
79
|
-
function
|
|
80
|
-
return hostname;
|
|
79
|
+
function getHost({ host = null, hostname = null }) {
|
|
80
|
+
return host ?? hostname;
|
|
81
81
|
}
|
|
82
82
|
function getPort(cosmosConfigInput) {
|
|
83
83
|
const cliArgs = getCliArgs();
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export declare function getCurrentDir(): string;
|
|
2
|
-
export declare function importConfigFile(cosmosConfigPath: string): Promise<Partial<import("./types.js").CosmosConfig
|
|
2
|
+
export declare function importConfigFile(cosmosConfigPath: string): Promise<Partial<import("./types.js").CosmosConfig & {
|
|
3
|
+
hostname: null | string;
|
|
4
|
+
}>>;
|
|
@@ -15,7 +15,7 @@ export type CosmosConfig = {
|
|
|
15
15
|
fixtureFileSuffix: string;
|
|
16
16
|
fixturesDir: string;
|
|
17
17
|
globalImports: string[];
|
|
18
|
-
|
|
18
|
+
host: null | string;
|
|
19
19
|
https: boolean;
|
|
20
20
|
httpsOptions: null | HttpsOptions;
|
|
21
21
|
ignore: string[];
|
|
@@ -34,5 +34,7 @@ export type CosmosConfig = {
|
|
|
34
34
|
};
|
|
35
35
|
};
|
|
36
36
|
export type CosmosDomConfigInput = Partial<CosmosDomConfig>;
|
|
37
|
-
export type CosmosConfigInput = Partial<CosmosConfig
|
|
37
|
+
export type CosmosConfigInput = Partial<CosmosConfig & {
|
|
38
|
+
hostname: null | string;
|
|
39
|
+
}>;
|
|
38
40
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CosmosPluginConfig } from 'react-cosmos-core';
|
|
2
2
|
import { CosmosConfig } from '../cosmosConfig/types.js';
|
|
3
3
|
type GetPluginConfigArgs = {
|
|
4
|
-
|
|
4
|
+
config: CosmosConfig;
|
|
5
5
|
relativePaths: boolean;
|
|
6
6
|
};
|
|
7
|
-
export declare function getPluginConfigs({
|
|
7
|
+
export declare function getPluginConfigs({ config, relativePaths, }: GetPluginConfigArgs): Promise<CosmosPluginConfig[]>;
|
|
8
8
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { findCosmosPluginConfigs } from './findCosmosPluginConfigs.js';
|
|
2
2
|
import { readCosmosPluginConfig } from './readCosmosPluginConfig.js';
|
|
3
|
-
export async function getPluginConfigs({
|
|
4
|
-
const { rootDir, detectLocalPlugins, disablePlugins, plugins, exportPath } =
|
|
3
|
+
export async function getPluginConfigs({ config, relativePaths, }) {
|
|
4
|
+
const { rootDir, detectLocalPlugins, disablePlugins, plugins, exportPath } = config;
|
|
5
5
|
if (disablePlugins)
|
|
6
6
|
return [];
|
|
7
7
|
const moduleConfigs = await Promise.all(plugins.map(configPath => readCosmosPluginConfig({ rootDir, configPath, relativePaths })));
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Express } from 'express';
|
|
2
2
|
import http from 'http';
|
|
3
|
-
import {
|
|
3
|
+
import { CosmosMode, MessageType } from 'react-cosmos-core';
|
|
4
4
|
import { CosmosConfig } from '../cosmosConfig/types.js';
|
|
5
5
|
export type CosmosPlatform = 'web' | 'native';
|
|
6
6
|
export type CosmosConfigPluginArgs = {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
config: CosmosConfig;
|
|
8
|
+
mode: CosmosMode;
|
|
9
9
|
platform: CosmosPlatform;
|
|
10
10
|
};
|
|
11
11
|
export type CosmosConfigPlugin = (args: CosmosConfigPluginArgs) => Promise<CosmosConfig> | CosmosConfig;
|
|
12
12
|
export type DevServerPluginArgs = {
|
|
13
|
-
|
|
13
|
+
config: CosmosConfig;
|
|
14
14
|
platform: CosmosPlatform;
|
|
15
15
|
httpServer: http.Server;
|
|
16
|
-
|
|
16
|
+
app: Express;
|
|
17
17
|
sendMessage(msg: MessageType): unknown;
|
|
18
18
|
};
|
|
19
19
|
export type DevServerPluginCleanupCallback = () => unknown;
|
|
@@ -21,7 +21,7 @@ export type DevServerPluginReturnValue = void | null | DevServerPluginCleanupCal
|
|
|
21
21
|
export type DevServerPluginReturn = DevServerPluginReturnValue | Promise<DevServerPluginReturnValue>;
|
|
22
22
|
export type DevServerPlugin = (args: DevServerPluginArgs) => DevServerPluginReturn;
|
|
23
23
|
export type ExportPluginArgs = {
|
|
24
|
-
|
|
24
|
+
config: CosmosConfig;
|
|
25
25
|
};
|
|
26
26
|
export type ExportPlugin = (args: ExportPluginArgs) => unknown;
|
|
27
27
|
export type CosmosServerPlugin = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Express } from 'express';
|
|
2
2
|
import { CosmosPluginConfig } from 'react-cosmos-core';
|
|
3
3
|
import { CosmosConfig } from '../cosmosConfig/types.js';
|
|
4
4
|
import { CosmosPlatform } from '../cosmosPlugin/types.js';
|
|
5
|
-
export declare function createExpressApp(platform: CosmosPlatform,
|
|
5
|
+
export declare function createExpressApp(platform: CosmosPlatform, config: CosmosConfig, pluginConfigs: CosmosPluginConfig[]): Promise<Express>;
|
|
@@ -2,18 +2,18 @@ import express from 'express';
|
|
|
2
2
|
import { getDevPlaygroundHtml } from '../shared/playgroundHtml.js';
|
|
3
3
|
import { getStaticPath } from '../shared/staticPath.js';
|
|
4
4
|
import { resolve } from '../utils/resolve.js';
|
|
5
|
-
export async function createExpressApp(platform,
|
|
5
|
+
export async function createExpressApp(platform, config, pluginConfigs) {
|
|
6
6
|
const app = express();
|
|
7
|
-
app.get('/', async (
|
|
8
|
-
res.send(await getDevPlaygroundHtml(platform,
|
|
7
|
+
app.get('/', async (_, res) => {
|
|
8
|
+
res.send(await getDevPlaygroundHtml(platform, config, pluginConfigs));
|
|
9
9
|
});
|
|
10
|
-
app.get('/playground.bundle.js', (
|
|
10
|
+
app.get('/playground.bundle.js', (_, res) => {
|
|
11
11
|
res.sendFile(resolve('react-cosmos-ui/dist/playground.bundle.js'));
|
|
12
12
|
});
|
|
13
|
-
app.get('/playground.bundle.js.map', (
|
|
13
|
+
app.get('/playground.bundle.js.map', (_, res) => {
|
|
14
14
|
res.sendFile(resolve('react-cosmos-ui/dist/playground.bundle.js.map'));
|
|
15
15
|
});
|
|
16
|
-
app.get('/_cosmos.ico', (
|
|
16
|
+
app.get('/_cosmos.ico', (_, res) => {
|
|
17
17
|
res.sendFile(getStaticPath('favicon.ico'));
|
|
18
18
|
});
|
|
19
19
|
return app;
|
|
@@ -2,7 +2,7 @@ import http from 'http';
|
|
|
2
2
|
import https from 'https';
|
|
3
3
|
import { CosmosConfig } from '../cosmosConfig/types.js';
|
|
4
4
|
type RequestListener = (request: http.IncomingMessage, response: http.ServerResponse) => void;
|
|
5
|
-
export declare function createHttpServer(
|
|
5
|
+
export declare function createHttpServer(config: CosmosConfig, requestListener: RequestListener): Promise<{
|
|
6
6
|
server: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | https.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
|
|
7
7
|
start: () => Promise<void>;
|
|
8
8
|
stop: () => Promise<void>;
|
|
@@ -1,42 +1,22 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
1
|
import http from 'http';
|
|
3
2
|
import https from 'https';
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const server = httpsEnabled
|
|
9
|
-
? https.createServer(await getHttpsOpts(cosmosConfig), requestListener)
|
|
3
|
+
import { getHttpsCreds } from './httpsCreds.js';
|
|
4
|
+
export async function createHttpServer(config, requestListener) {
|
|
5
|
+
const server = config.https
|
|
6
|
+
? https.createServer(await getHttpsCreds(config), requestListener)
|
|
10
7
|
: http.createServer(requestListener);
|
|
11
8
|
async function start() {
|
|
12
9
|
await new Promise(resolve => {
|
|
13
|
-
if (
|
|
14
|
-
server.listen(port, resolve);
|
|
10
|
+
if (config.host === null) {
|
|
11
|
+
server.listen(config.port, resolve);
|
|
15
12
|
}
|
|
16
13
|
else {
|
|
17
|
-
server.listen(port,
|
|
14
|
+
server.listen(config.port, config.host, resolve);
|
|
18
15
|
}
|
|
19
16
|
});
|
|
20
|
-
console.log(`[Cosmos] See you at ${getPlaygroundUrl(cosmosConfig)}`);
|
|
21
17
|
}
|
|
22
18
|
async function stop() {
|
|
23
19
|
await new Promise(resolve => server.close(resolve));
|
|
24
20
|
}
|
|
25
21
|
return { server, start, stop };
|
|
26
22
|
}
|
|
27
|
-
async function getHttpsOpts(cosmosConfig) {
|
|
28
|
-
const { httpsOptions } = cosmosConfig;
|
|
29
|
-
if (httpsOptions)
|
|
30
|
-
return {
|
|
31
|
-
key: fs.readFileSync(httpsOptions.keyPath, 'utf8'),
|
|
32
|
-
cert: fs.readFileSync(httpsOptions.certPath, 'utf8'),
|
|
33
|
-
};
|
|
34
|
-
console.log('[Cosmos] Generating HTTPS certificate');
|
|
35
|
-
return await new Promise((resolve, reject) => {
|
|
36
|
-
pem.createCertificate({ days: 1000, selfSigned: true }, (err, keys) => {
|
|
37
|
-
if (err)
|
|
38
|
-
return reject(err);
|
|
39
|
-
return resolve({ key: keys.serviceKey, cert: keys.certificate });
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import pem from 'pem';
|
|
3
|
+
let _cache;
|
|
4
|
+
export async function getHttpsCreds(config) {
|
|
5
|
+
const { httpsOptions } = config;
|
|
6
|
+
if (httpsOptions)
|
|
7
|
+
return {
|
|
8
|
+
key: fs.readFileSync(httpsOptions.keyPath, 'utf8'),
|
|
9
|
+
cert: fs.readFileSync(httpsOptions.certPath, 'utf8'),
|
|
10
|
+
};
|
|
11
|
+
if (_cache)
|
|
12
|
+
return _cache;
|
|
13
|
+
console.log('[Cosmos] Generating HTTPS certificate');
|
|
14
|
+
return await new Promise((resolve, reject) => {
|
|
15
|
+
pem.createCertificate({ days: 1000, selfSigned: true }, (err, keys) => {
|
|
16
|
+
if (err)
|
|
17
|
+
reject(err);
|
|
18
|
+
else {
|
|
19
|
+
_cache = { key: keys.serviceKey, cert: keys.certificate };
|
|
20
|
+
resolve(_cache);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -4,33 +4,34 @@ import { getPluginConfigs } from '../cosmosPlugin/pluginConfigs.js';
|
|
|
4
4
|
import { applyServerConfigPlugins } from '../shared/applyServerConfigPlugins.js';
|
|
5
5
|
import { getServerPlugins } from '../shared/getServerPlugins.js';
|
|
6
6
|
import { logPluginInfo } from '../shared/logPluginInfo.js';
|
|
7
|
+
import { logPlaygroundUrls } from '../shared/playgroundUrl.js';
|
|
7
8
|
import { serveStaticDir } from '../shared/staticServer.js';
|
|
8
9
|
import { createExpressApp } from './expressApp.js';
|
|
9
10
|
import { createHttpServer } from './httpServer.js';
|
|
10
11
|
import { createMessageHandler } from './messageHandler.js';
|
|
11
12
|
export async function startDevServer(platform) {
|
|
12
|
-
let
|
|
13
|
+
let config = await detectCosmosConfig();
|
|
13
14
|
logCosmosConfigInfo();
|
|
14
15
|
const pluginConfigs = await getPluginConfigs({
|
|
15
|
-
|
|
16
|
+
config,
|
|
16
17
|
// Absolute paths are required in dev mode because the dev server could
|
|
17
18
|
// run in a monorepo package that's not the root of the project and plugins
|
|
18
19
|
// could be installed in the root
|
|
19
20
|
relativePaths: false,
|
|
20
21
|
});
|
|
21
22
|
logPluginInfo(pluginConfigs);
|
|
22
|
-
const serverPlugins = await getServerPlugins(pluginConfigs,
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const serverPlugins = await getServerPlugins(pluginConfigs, config.rootDir);
|
|
24
|
+
config = await applyServerConfigPlugins({
|
|
25
|
+
config,
|
|
25
26
|
serverPlugins,
|
|
26
|
-
|
|
27
|
+
mode: 'dev',
|
|
27
28
|
platform,
|
|
28
29
|
});
|
|
29
|
-
const app = await createExpressApp(platform,
|
|
30
|
-
const httpServer = await createHttpServer(
|
|
30
|
+
const app = await createExpressApp(platform, config, pluginConfigs);
|
|
31
|
+
const httpServer = await createHttpServer(config, app);
|
|
31
32
|
const msgHandler = createMessageHandler(httpServer.server);
|
|
32
|
-
if (
|
|
33
|
-
serveStaticDir(app,
|
|
33
|
+
if (config.staticPath) {
|
|
34
|
+
serveStaticDir(app, config.staticPath, config.publicUrl);
|
|
34
35
|
}
|
|
35
36
|
// Make Playground available as soon as possible and show a loading screen
|
|
36
37
|
// while plugins are initializing
|
|
@@ -46,10 +47,10 @@ export async function startDevServer(platform) {
|
|
|
46
47
|
if (!plugin.devServer)
|
|
47
48
|
continue;
|
|
48
49
|
const pluginReturn = await plugin.devServer({
|
|
49
|
-
|
|
50
|
+
config,
|
|
50
51
|
platform,
|
|
51
52
|
httpServer: httpServer.server,
|
|
52
|
-
|
|
53
|
+
app,
|
|
53
54
|
sendMessage: msgHandler.sendMessage,
|
|
54
55
|
});
|
|
55
56
|
if (typeof pluginReturn === 'function') {
|
|
@@ -60,7 +61,7 @@ export async function startDevServer(platform) {
|
|
|
60
61
|
catch (err) {
|
|
61
62
|
// Log when a plugin fails to clean up, but continue to attempt
|
|
62
63
|
// to clean up the remaining plugins
|
|
63
|
-
console.log(`[Cosmos][
|
|
64
|
+
console.log(`[Cosmos][${plugin.name}] Dev server cleanup failed`);
|
|
64
65
|
console.log(err);
|
|
65
66
|
}
|
|
66
67
|
});
|
|
@@ -69,19 +70,20 @@ export async function startDevServer(platform) {
|
|
|
69
70
|
catch (err) {
|
|
70
71
|
// Abort starting server if a plugin init fails and attempt cleanup of all
|
|
71
72
|
// plugins that have already initialized
|
|
72
|
-
console.log(`[Cosmos][
|
|
73
|
+
console.log(`[Cosmos][${plugin.name}] Dev server init failed`);
|
|
73
74
|
cleanUp();
|
|
74
75
|
throw err;
|
|
75
76
|
}
|
|
76
77
|
}
|
|
78
|
+
logPlaygroundUrls(config);
|
|
77
79
|
return cleanUp;
|
|
78
80
|
}
|
|
79
81
|
function logCosmosConfigInfo() {
|
|
80
82
|
const cosmosConfigPath = detectCosmosConfigPath();
|
|
81
83
|
if (!cosmosConfigPath) {
|
|
82
|
-
console.log(`[Cosmos] Using default
|
|
84
|
+
console.log(`[Cosmos] Using default Cosmos config`);
|
|
83
85
|
return;
|
|
84
86
|
}
|
|
85
87
|
const relConfigPath = path.relative(process.cwd(), cosmosConfigPath);
|
|
86
|
-
console.log(`[Cosmos] Using
|
|
88
|
+
console.log(`[Cosmos] Using config found at ${relConfigPath}`);
|
|
87
89
|
}
|