Merge remote-tracking branch 'origin/releases/4.15.2' into releases/4.15.3

This commit is contained in:
Mark Kaylor 2023-11-08 14:13:14 +01:00
commit 0ca0dff7b4
29 changed files with 300 additions and 144 deletions

View File

@ -9,6 +9,7 @@ const build: StrapiCommand = ({ command, ctx }) => {
command command
.command('build') .command('build')
.option('-d, --debug', 'Enable debugging mode with verbose logs', false) .option('-d, --debug', 'Enable debugging mode with verbose logs', false)
.option('--ignore-prompts', 'Ignore all prompts', false)
.option('--minify', 'Minify the output', true) .option('--minify', 'Minify the output', true)
.option('--no-optimization', '[deprecated]: use minify instead') .option('--no-optimization', '[deprecated]: use minify instead')
.option('--silent', "Don't log anything", false) .option('--silent', "Don't log anything", false)
@ -31,7 +32,9 @@ const develop: StrapiCommand = ({ command, ctx }) => {
.alias('dev') .alias('dev')
.option('-d, --debug', 'Enable debugging mode with verbose logs', false) .option('-d, --debug', 'Enable debugging mode with verbose logs', false)
.option('--silent', "Don't log anything", false) .option('--silent', "Don't log anything", false)
.option('--ignore-prompts', 'Ignore all prompts', false)
.option('--polling', 'Watch for file changes in network directories', false) .option('--polling', 'Watch for file changes in network directories', false)
.option('--watch-admin', 'Watch the admin panel for hot changes', false)
.option( .option(
'--no-build', '--no-build',
'[deprecated]: there is middleware for the server, it is no longer a separate process' '[deprecated]: there is middleware for the server, it is no longer a separate process'

View File

@ -10,6 +10,10 @@ import { getTimer } from './core/timer';
import type { CLIContext } from '@strapi/strapi'; import type { CLIContext } from '@strapi/strapi';
interface BuildOptions extends CLIContext { interface BuildOptions extends CLIContext {
/**
* @default false
*/
ignorePrompts?: boolean;
/** /**
* Minify the output * Minify the output
* *
@ -31,13 +35,15 @@ interface BuildOptions extends CLIContext {
* *
* @description Builds the admin panel of the strapi application. * @description Builds the admin panel of the strapi application.
*/ */
const build = async ({ logger, cwd, tsconfig, ...options }: BuildOptions) => { const build = async ({ logger, cwd, tsconfig, ignorePrompts, ...options }: BuildOptions) => {
const timer = getTimer(); const timer = getTimer();
const { didInstall } = await checkRequiredDependencies({ cwd, logger }).catch((err) => { const { didInstall } = await checkRequiredDependencies({ cwd, logger, ignorePrompts }).catch(
logger.error(err.message); (err) => {
process.exit(1); logger.error(err.message);
}); process.exit(1);
}
);
if (didInstall) { if (didInstall) {
return; return;

View File

@ -15,8 +15,8 @@ import { getPackageManager } from './managers';
const PEER_DEPS = { const PEER_DEPS = {
react: '^18.0.0', react: '^18.0.0',
'react-dom': '^18.0.0', 'react-dom': '^18.0.0',
'react-router-dom': '^5.0.0', 'react-router-dom': '^5.2.0',
'styled-components': '^5.0.0', 'styled-components': '^5.2.1',
}; };
interface CheckRequiredDependenciesResult { interface CheckRequiredDependenciesResult {
@ -41,7 +41,11 @@ interface DepToInstall {
const checkRequiredDependencies = async ({ const checkRequiredDependencies = async ({
cwd, cwd,
logger, logger,
}: Pick<BuildOptions, 'cwd' | 'logger'>): Promise<CheckRequiredDependenciesResult> => { ignorePrompts,
}: Pick<
BuildOptions,
'cwd' | 'logger' | 'ignorePrompts'
>): Promise<CheckRequiredDependenciesResult> => {
const pkg = await readPkgUp({ cwd }); const pkg = await readPkgUp({ cwd });
if (!pkg) { if (!pkg) {
@ -102,7 +106,7 @@ const checkRequiredDependencies = async ({
/** /**
* temporary until V5 when we _will_ be enforcing these dependencies as required. * temporary until V5 when we _will_ be enforcing these dependencies as required.
*/ */
if (process.env.NODE_ENV !== 'development') { if (process.env.NODE_ENV !== 'development' || ignorePrompts) {
return { didInstall: false }; return { didInstall: false };
} }

View File

@ -5,13 +5,6 @@ import { getModule, PackageJson } from './dependencies';
import { loadFile } from './files'; import { loadFile } from './files';
import { BuildContext, CreateBuildContextArgs } from '../createBuildContext'; import { BuildContext, CreateBuildContextArgs } from '../createBuildContext';
const CORE_PLUGINS = [
'@strapi/plugin-content-manager',
'@strapi/plugin-content-type-builder',
'@strapi/plugin-email',
'@strapi/plugin-upload',
];
interface PluginMeta { interface PluginMeta {
name: string; name: string;
pathToPlugin: string; pathToPlugin: string;
@ -46,24 +39,6 @@ export const getEnabledPlugins = async ({
}: Pick<BuildContext, 'cwd' | 'logger' | 'strapi'>) => { }: Pick<BuildContext, 'cwd' | 'logger' | 'strapi'>) => {
const plugins: Record<string, PluginMeta> = {}; const plugins: Record<string, PluginMeta> = {};
logger.debug('Core plugins', os.EOL, CORE_PLUGINS);
for (const plugin of CORE_PLUGINS) {
const pkg = await getModule(plugin, cwd);
if (pkg && validatePackageIsPlugin(pkg)) {
/**
* We know there's a name because these are our packages.
*/
const name = (pkg.strapi.name || pkg.name)!;
plugins[name] = {
name,
pathToPlugin: plugin,
};
}
}
/** /**
* This is the list of dependencies that are installed in the user's project. * This is the list of dependencies that are installed in the user's project.
* It will include libraries like "react", so we need to collect the ones that * It will include libraries like "react", so we need to collect the ones that

View File

@ -5,7 +5,6 @@ import syncFs from 'node:fs';
import camelCase from 'lodash/camelCase'; import camelCase from 'lodash/camelCase';
import browserslist from 'browserslist'; import browserslist from 'browserslist';
import strapiFactory, { CLIContext } from '@strapi/strapi'; import strapiFactory, { CLIContext } from '@strapi/strapi';
import type { Strapi } from '@strapi/types';
import { getConfigUrls } from '@strapi/utils'; import { getConfigUrls } from '@strapi/utils';
import { getStrapiAdminEnvVars, loadEnv } from './core/env'; import { getStrapiAdminEnvVars, loadEnv } from './core/env';
@ -14,6 +13,7 @@ import { isError } from './core/errors';
import type { BuildOptions } from './build'; import type { BuildOptions } from './build';
import { DevelopOptions } from './develop'; import { DevelopOptions } from './develop';
import { getEnabledPlugins } from './core/plugins'; import { getEnabledPlugins } from './core/plugins';
import { Strapi } from '@strapi/types';
interface BuildContext { interface BuildContext {
/** /**
@ -75,6 +75,7 @@ interface BuildContext {
} }
interface CreateBuildContextArgs extends CLIContext { interface CreateBuildContextArgs extends CLIContext {
strapi?: Strapi;
options?: BuildContext['options']; options?: BuildContext['options'];
} }
@ -89,16 +90,24 @@ const createBuildContext = async ({
cwd, cwd,
logger, logger,
tsconfig, tsconfig,
strapi,
options = {}, options = {},
}: CreateBuildContextArgs) => { }: CreateBuildContextArgs) => {
const strapiInstance = strapiFactory({ /**
// Directories * If you make a new strapi instance when one already exists,
appDir: cwd, * you will overwrite the global and the app will _most likely_
distDir: tsconfig?.config.options.outDir ?? '', * crash and die.
// Options */
autoReload: true, const strapiInstance =
serveAdminPanel: false, strapi ??
}); strapiFactory({
// Directories
appDir: cwd,
distDir: tsconfig?.config.options.outDir ?? '',
// Options
autoReload: true,
serveAdminPanel: false,
});
const { serverUrl, adminPath } = getConfigUrls(strapiInstance.config, true); const { serverUrl, adminPath } = getConfigUrls(strapiInstance.config, true);

View File

@ -7,29 +7,78 @@ import cluster from 'node:cluster';
import { getTimer } from './core/timer'; import { getTimer } from './core/timer';
import { checkRequiredDependencies } from './core/dependencies'; import { checkRequiredDependencies } from './core/dependencies';
import { createBuildContext } from './createBuildContext'; import { createBuildContext } from './createBuildContext';
import { watch as watchWebpack } from './webpack/watch'; import { WebpackWatcher, watch as watchWebpack } from './webpack/watch';
import { build as buildWebpack } from './webpack/build';
import EE from '@strapi/strapi/dist/utils/ee'; import EE from '@strapi/strapi/dist/utils/ee';
import { writeStaticClientFiles } from './staticFiles'; import { writeStaticClientFiles } from './staticFiles';
import strapiFactory from '@strapi/strapi';
interface DevelopOptions extends CLIContext { interface DevelopOptions extends CLIContext {
/**
* @default false
*/
ignorePrompts?: boolean;
polling?: boolean; polling?: boolean;
open?: boolean; open?: boolean;
watchAdmin?: boolean;
} }
const develop = async ({ cwd, polling, logger, tsconfig, ...options }: DevelopOptions) => { const develop = async ({
cwd,
polling,
logger,
tsconfig,
ignorePrompts,
watchAdmin,
...options
}: DevelopOptions) => {
const timer = getTimer(); const timer = getTimer();
if (cluster.isPrimary) { if (cluster.isPrimary) {
const { didInstall } = await checkRequiredDependencies({ cwd, logger }).catch((err) => { const { didInstall } = await checkRequiredDependencies({ cwd, logger, ignorePrompts }).catch(
logger.error(err.message); (err) => {
process.exit(1); logger.error(err.message);
}); process.exit(1);
}
);
if (didInstall) { if (didInstall) {
return; return;
} }
/**
* IF we're not watching the admin we're going to build it, this makes
* sure that at least the admin is built for users & they can interact
* with the application.
*/
if (!watchAdmin) {
timer.start('createBuildContext');
const contextSpinner = logger.spinner(`Building build context`).start();
console.log('');
const ctx = await createBuildContext({
cwd,
logger,
tsconfig,
options,
});
const contextDuration = timer.end('createBuildContext');
contextSpinner.text = `Building build context (${contextDuration}ms)`;
contextSpinner.succeed();
timer.start('creatingAdmin');
const adminSpinner = logger.spinner(`Creating admin`).start();
EE.init(cwd);
await writeStaticClientFiles(ctx);
await buildWebpack(ctx);
const adminDuration = timer.end('creatingAdmin');
adminSpinner.text = `Creating admin (${adminDuration}ms)`;
adminSpinner.succeed();
}
cluster.on('message', async (worker, message) => { cluster.on('message', async (worker, message) => {
switch (message) { switch (message) {
case 'reload': { case 'reload': {
@ -66,32 +115,48 @@ const develop = async ({ cwd, polling, logger, tsconfig, ...options }: DevelopOp
compilingTsSpinner.succeed(); compilingTsSpinner.succeed();
} }
timer.start('createBuildContext'); const strapi = strapiFactory({
const contextSpinner = logger.spinner(`Building build context`).start(); appDir: cwd,
console.log(''); distDir: tsconfig?.config.options.outDir ?? '',
autoReload: true,
const ctx = await createBuildContext({ serveAdminPanel: !watchAdmin,
cwd,
logger,
tsconfig,
options,
}); });
const contextDuration = timer.end('createBuildContext');
contextSpinner.text = `Building build context (${contextDuration}ms)`;
contextSpinner.succeed();
timer.start('creatingAdmin'); let webpackWatcher: WebpackWatcher | undefined;
const adminSpinner = logger.spinner(`Creating admin`).start();
EE.init(cwd); /**
await writeStaticClientFiles(ctx); * If we're watching the admin panel then we're going to attach the watcher
await watchWebpack(ctx); * as a strapi middleware.
*/
if (watchAdmin) {
timer.start('createBuildContext');
const contextSpinner = logger.spinner(`Building build context`).start();
console.log('');
const adminDuration = timer.end('creatingAdmin'); const ctx = await createBuildContext({
adminSpinner.text = `Creating admin (${adminDuration}ms)`; cwd,
adminSpinner.succeed(); logger,
strapi,
tsconfig,
options,
});
const contextDuration = timer.end('createBuildContext');
contextSpinner.text = `Building build context (${contextDuration}ms)`;
contextSpinner.succeed();
const strapiInstance = await ctx.strapi.load(); timer.start('creatingAdmin');
const adminSpinner = logger.spinner(`Creating admin`).start();
EE.init(cwd);
await writeStaticClientFiles(ctx);
webpackWatcher = await watchWebpack(ctx);
const adminDuration = timer.end('creatingAdmin');
adminSpinner.text = `Creating admin (${adminDuration}ms)`;
adminSpinner.succeed();
}
const strapiInstance = await strapi.load();
timer.start('generatingTS'); timer.start('generatingTS');
const generatingTsSpinner = logger.spinner(`Generating types`).start(); const generatingTsSpinner = logger.spinner(`Generating types`).start();
@ -164,7 +229,12 @@ const develop = async ({ cwd, polling, logger, tsconfig, ...options }: DevelopOp
'child process has the kill message, destroying the strapi instance and sending the killed process message' 'child process has the kill message, destroying the strapi instance and sending the killed process message'
); );
await watcher.close(); await watcher.close();
await strapiInstance.destroy(); await strapiInstance.destroy();
if (webpackWatcher) {
webpackWatcher.close();
}
process.send?.('killed'); process.send?.('killed');
break; break;
} }

View File

@ -4,6 +4,7 @@ import outdent from 'outdent';
import { format } from 'prettier'; import { format } from 'prettier';
import { createElement } from 'react'; import { createElement } from 'react';
import { renderToStaticMarkup } from 'react-dom/server'; import { renderToStaticMarkup } from 'react-dom/server';
import { DefaultDocument as Document } from '../../admin/src/components/DefaultDocument';
import type { BuildContext } from './createBuildContext'; import type { BuildContext } from './createBuildContext';
@ -26,7 +27,7 @@ const getEntryModule = ({ plugins }: EntryModuleArgs): string => {
* Any modifications made will be discarded. * Any modifications made will be discarded.
*/ */
${pluginsImport} ${pluginsImport}
import { renderAdmin } from "@strapi/admin/strapi-admin" import { renderAdmin } from "@strapi/strapi/admin"
renderAdmin( renderAdmin(
document.getElementById("strapi"), document.getElementById("strapi"),
@ -38,21 +39,11 @@ const getEntryModule = ({ plugins }: EntryModuleArgs): string => {
`; `;
}; };
const getDefaultDocumentComponent = () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires, node/no-missing-require
const { DefaultDocument } = require('@strapi/admin/strapi-admin');
return DefaultDocument;
};
/** /**
* TODO: Here in the future we could add the ability * TODO: Here in the future we could add the ability
* to load a user's Document component? * to load a user's Document component?
*/ */
const getDocumentHTML = ({ logger }: Pick<BuildContext, 'logger'>) => { const getDocumentHTML = async ({ logger }: Pick<BuildContext, 'logger'>) => {
const Document = getDefaultDocumentComponent();
logger.debug('Got the default document');
const result = renderToStaticMarkup(createElement(Document)); const result = renderToStaticMarkup(createElement(Document));
logger.debug('Rendered the HTML'); logger.debug('Rendered the HTML');
@ -84,7 +75,9 @@ const writeStaticClientFiles = async (ctx: BuildContext) => {
await fs.mkdir(ctx.runtimeDir, { recursive: true }); await fs.mkdir(ctx.runtimeDir, { recursive: true });
ctx.logger.debug('Created the runtime directory'); ctx.logger.debug('Created the runtime directory');
const indexHtml = decorateHTMLWithAutoGeneratedWarning(getDocumentHTML({ logger: ctx.logger })); const indexHtml = decorateHTMLWithAutoGeneratedWarning(
await getDocumentHTML({ logger: ctx.logger })
);
await fs.writeFile( await fs.writeFile(
path.join(ctx.runtimeDir, 'index.html'), path.join(ctx.runtimeDir, 'index.html'),

View File

@ -33,12 +33,23 @@ const resolveBaseConfig = async (ctx: BuildContext) => {
module: { module: {
rules: [ rules: [
{ {
test: /\.(t|j)sx?$/, test: /\.(ts|tsx)$/,
loader: require.resolve('esbuild-loader'), loader: require.resolve('esbuild-loader'),
options: { options: {
loader: 'tsx', loader: 'tsx',
jsx: 'automatic',
target, target,
jsx: 'automatic',
},
},
{
test: /\.(js|jsx|mjs)$/,
use: {
loader: require.resolve('esbuild-loader'),
options: {
loader: 'jsx',
target,
jsx: 'automatic',
},
}, },
}, },
{ {

View File

@ -1,19 +1,24 @@
import os from 'node:os'; import os from 'node:os';
import path from 'node:path'; import path from 'node:path';
import { promisify } from 'node:util';
import webpackDevMiddleware from 'webpack-dev-middleware'; import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware'; import webpackHotMiddleware from 'webpack-hot-middleware';
import { webpack } from 'webpack'; import { webpack } from 'webpack';
import type { BuildContext } from '../createBuildContext'; import type { BuildContext } from '../createBuildContext';
import { mergeConfigWithUserConfig, resolveDevelopmentConfig } from './config'; import { mergeConfigWithUserConfig, resolveDevelopmentConfig } from './config';
import { Common } from '@strapi/types'; import { Common, Strapi } from '@strapi/types';
const watch = async (ctx: BuildContext) => { interface WebpackWatcher {
close(): Promise<void>;
}
const watch = async (ctx: BuildContext): Promise<WebpackWatcher> => {
const config = await resolveDevelopmentConfig(ctx); const config = await resolveDevelopmentConfig(ctx);
const finalConfig = await mergeConfigWithUserConfig(config, ctx); const finalConfig = await mergeConfigWithUserConfig(config, ctx);
ctx.logger.debug('Final webpack config:', os.EOL, finalConfig); ctx.logger.debug('Final webpack config:', os.EOL, finalConfig);
return new Promise((res) => { return new Promise<WebpackWatcher>((res) => {
const compiler = webpack(finalConfig); const compiler = webpack(finalConfig);
const devMiddleware = webpackDevMiddleware(compiler); const devMiddleware = webpackDevMiddleware(compiler);
@ -91,9 +96,18 @@ const watch = async (ctx: BuildContext) => {
]); ]);
devMiddleware.waitUntilValid(() => { devMiddleware.waitUntilValid(() => {
res(true); res({
async close() {
await Promise.all([
promisify(devMiddleware.close.bind(devMiddleware))(),
hotMiddleware.close(),
promisify(compiler.close.bind(compiler))(),
]);
},
});
}); });
}); });
}; };
export { watch }; export { watch };
export type { WebpackWatcher };

View File

@ -75,6 +75,7 @@
"@radix-ui/react-context": "1.0.1", "@radix-ui/react-context": "1.0.1",
"@radix-ui/react-toolbar": "1.0.4", "@radix-ui/react-toolbar": "1.0.4",
"@reduxjs/toolkit": "1.9.7", "@reduxjs/toolkit": "1.9.7",
"@strapi/data-transfer": "4.15.1",
"@strapi/design-system": "1.13.0", "@strapi/design-system": "1.13.0",
"@strapi/helper-plugin": "4.15.1", "@strapi/helper-plugin": "4.15.1",
"@strapi/icons": "1.13.0", "@strapi/icons": "1.13.0",
@ -95,6 +96,7 @@
"css-loader": "^6.8.1", "css-loader": "^6.8.1",
"date-fns": "2.30.0", "date-fns": "2.30.0",
"dotenv": "14.2.0", "dotenv": "14.2.0",
"esbuild": "0.19.2",
"esbuild-loader": "^2.21.0", "esbuild-loader": "^2.21.0",
"esbuild-register": "3.5.0", "esbuild-register": "3.5.0",
"execa": "5.1.1", "execa": "5.1.1",
@ -171,7 +173,6 @@
}, },
"devDependencies": { "devDependencies": {
"@strapi/admin-test-utils": "4.15.1", "@strapi/admin-test-utils": "4.15.1",
"@strapi/data-transfer": "4.15.1",
"@strapi/pack-up": "workspace:*", "@strapi/pack-up": "workspace:*",
"@strapi/strapi": "4.15.1", "@strapi/strapi": "4.15.1",
"@testing-library/dom": "9.2.0", "@testing-library/dom": "9.2.0",
@ -188,7 +189,11 @@
}, },
"peerDependencies": { "peerDependencies": {
"@strapi/data-transfer": "4.15.1", "@strapi/data-transfer": "4.15.1",
"@strapi/strapi": "^4.3.4" "@strapi/strapi": "^4.3.4",
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "^5.2.0",
"styled-components": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0 <=20.x.x", "node": ">=18.0.0 <=20.x.x",

View File

@ -1,10 +1,5 @@
{ {
"extends": "tsconfig/base.json", "extends": "tsconfig/client.json",
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler",
"noEmit": true
},
"include": ["_internal", "packup.config.ts"], "include": ["_internal", "packup.config.ts"],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }

View File

@ -77,8 +77,8 @@
"@strapi/strapi": "^4.0.0", "@strapi/strapi": "^4.0.0",
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "5.3.3" "styled-components": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0 <=20.x.x", "node": ">=18.0.0 <=20.x.x",

View File

@ -5,7 +5,7 @@ import { configs, createLogger } from '@strapi/logger';
import strapiFactory from '@strapi/strapi'; import strapiFactory from '@strapi/strapi';
import ora from 'ora'; import ora from 'ora';
import { merge } from 'lodash/fp'; import { merge } from 'lodash/fp';
import type { LoadedStrapi } from '@strapi/types'; import type { LoadedStrapi, Strapi } from '@strapi/types';
import { readableBytes, exitWith } from './helpers'; import { readableBytes, exitWith } from './helpers';
import { getParseListWithChoices, parseInteger, confirmMessage } from './commander'; import { getParseListWithChoices, parseInteger, confirmMessage } from './commander';
@ -148,7 +148,9 @@ const setSignalHandler = async (
}); });
}; };
const createStrapiInstance = async (opts: { logLevel?: string } = {}) => { const createStrapiInstance = async (
opts: { logLevel?: string } = {}
): Promise<Strapi & Required<Strapi>> => {
try { try {
const appContext = await strapiFactory.compile(); const appContext = await strapiFactory.compile();
const app = strapiFactory({ ...opts, ...appContext }); const app = strapiFactory({ ...opts, ...appContext });

View File

@ -81,8 +81,8 @@
"koa": "2.13.4", "koa": "2.13.4",
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "5.3.3" "styled-components": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0 <=20.x.x", "node": ">=18.0.0 <=20.x.x",

View File

@ -100,8 +100,8 @@
"@strapi/icons": "1.13.0", "@strapi/icons": "1.13.0",
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "^5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "^5.3.3" "styled-components": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0 <=20.x.x", "node": ">=18.0.0 <=20.x.x",

View File

@ -64,6 +64,30 @@
"url": "https://strapi.io" "url": "https://strapi.io"
} }
], ],
"exports": {
".": {
"types": "./dist/index.d.ts",
"source": "./src/index.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js",
"default": "./dist/index.js"
},
"./dist/utils/ee": {
"types": "./dist/utils/ee.d.ts",
"source": "./src/utils/ee.ts",
"import": "./dist/utils/ee.mjs",
"require": "./dist/utils/ee.js",
"default": "./dist/utils/ee.js"
},
"./admin": {
"types": "./dist/admin.d.ts",
"source": "./src/admin.ts",
"import": "./dist/admin.mjs",
"require": "./dist/admin.js",
"default": "./dist/admin.js"
},
"./package.json": "./package.json"
},
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.mjs", "module": "./dist/index.mjs",
"source": "./src/index.ts", "source": "./src/index.ts",

View File

@ -4,13 +4,28 @@ import { builtinModules } from 'node:module';
export default defineConfig({ export default defineConfig({
bundles: [ bundles: [
{
source: './src/index.ts',
import: './dist/index.js',
require: './dist/index.js',
types: './dist/index.d.ts',
runtime: 'node',
},
{ {
source: './src/cli.ts', source: './src/cli.ts',
require: './dist/cli.js', require: './dist/cli.js',
runtime: 'node', runtime: 'node',
}, },
{
source: './src/admin.ts',
import: './dist/admin.js',
require: './dist/admin.js',
types: './dist/index.d.ts',
runtime: 'web',
},
], ],
exports: {},
dist: './dist',
externals: [...builtinModules], externals: [...builtinModules],
preserveModules: true, preserveModules: true,
runtime: 'node',
}); });

View File

@ -0,0 +1,21 @@
import { RenderAdminArgs, renderAdmin } from '@strapi/admin/strapi-admin';
// @ts-expect-error No types, yet.
import contentTypeBuilder from '@strapi/plugin-content-type-builder/strapi-admin';
import email from '@strapi/plugin-email/strapi-admin';
// @ts-expect-error No types, yet.
import upload from '@strapi/plugin-upload/strapi-admin';
const render = (mountNode: HTMLElement | null, { plugins }: RenderAdminArgs) => {
return renderAdmin(mountNode, {
plugins: {
'content-type-builder': contentTypeBuilder,
// @ts-expect-error TODO: fix this
email,
upload,
...plugins,
},
});
};
export { render as renderAdmin };
export type { RenderAdminArgs };

View File

@ -12,6 +12,10 @@ interface ActionOptions extends BuildCLIOptions {
export default async ({ force, ...opts }: ActionOptions) => { export default async ({ force, ...opts }: ActionOptions) => {
const logger = createLogger({ debug: opts.debug, silent: opts.silent, timestamp: false }); const logger = createLogger({ debug: opts.debug, silent: opts.silent, timestamp: false });
try { try {
/**
* ALWAYS set production for using plugin build CLI.
*/
process.env.NODE_ENV = 'production';
/** /**
* Notify users this is an experimental command and get them to approve first * Notify users this is an experimental command and get them to approve first
* this can be opted out by setting the argument --yes * this can be opted out by setting the argument --yes

View File

@ -85,8 +85,8 @@
"@strapi/strapi": "^4.0.0", "@strapi/strapi": "^4.0.0",
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "5.3.3" "styled-components": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0 <=20.x.x", "node": ">=18.0.0 <=20.x.x",

View File

@ -23,8 +23,8 @@
"peerDependencies": { "peerDependencies": {
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "^5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "^5.3.6" "styled-components": "^5.2.1"
}, },
"author": { "author": {
"name": "A Strapi developer" "name": "A Strapi developer"

View File

@ -28,8 +28,8 @@
"peerDependencies": { "peerDependencies": {
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "^5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "^5.3.6" "styled-components": "^5.2.1"
}, },
"author": { "author": {
"name": "A Strapi developer" "name": "A Strapi developer"

View File

@ -76,8 +76,8 @@
"@strapi/strapi": "^4.4.0", "@strapi/strapi": "^4.4.0",
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "5.3.3" "styled-components": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0 <=20.x.x", "node": ">=18.0.0 <=20.x.x",

View File

@ -80,8 +80,8 @@
"@strapi/strapi": "^4.0.0", "@strapi/strapi": "^4.0.0",
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "5.3.3" "styled-components": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0 <=20.x.x", "node": ">=18.0.0 <=20.x.x",

View File

@ -73,8 +73,8 @@
"@strapi/strapi": "^4.0.0", "@strapi/strapi": "^4.0.0",
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "5.3.3" "styled-components": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0 <=20.x.x", "node": ">=18.0.0 <=20.x.x",

View File

@ -76,8 +76,8 @@
"@strapi/strapi": "^4.0.0", "@strapi/strapi": "^4.0.0",
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "5.3.3" "styled-components": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0 <=20.x.x", "node": ">=18.0.0 <=20.x.x",

View File

@ -60,8 +60,8 @@
"@strapi/strapi": "^4.0.0", "@strapi/strapi": "^4.0.0",
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "5.3.3" "styled-components": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0 <=20.x.x", "node": ">=18.0.0 <=20.x.x",

View File

@ -83,8 +83,8 @@
"@strapi/strapi": "4.0.0", "@strapi/strapi": "4.0.0",
"react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "5.3.4", "react-router-dom": "^5.2.0",
"styled-components": "5.3.3" "styled-components": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0 <=20.x.x", "node": ">=18.0.0 <=20.x.x",

View File

@ -8673,6 +8673,7 @@ __metadata:
css-loader: "npm:^6.8.1" css-loader: "npm:^6.8.1"
date-fns: "npm:2.30.0" date-fns: "npm:2.30.0"
dotenv: "npm:14.2.0" dotenv: "npm:14.2.0"
esbuild: "npm:0.19.2"
esbuild-loader: "npm:^2.21.0" esbuild-loader: "npm:^2.21.0"
esbuild-register: "npm:3.5.0" esbuild-register: "npm:3.5.0"
execa: "npm:5.1.1" execa: "npm:5.1.1"
@ -8751,6 +8752,10 @@ __metadata:
peerDependencies: peerDependencies:
"@strapi/data-transfer": 4.15.1 "@strapi/data-transfer": 4.15.1
"@strapi/strapi": ^4.3.4 "@strapi/strapi": ^4.3.4
react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0
react-router-dom: ^5.2.0
styled-components: ^5.2.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -8962,8 +8967,8 @@ __metadata:
"@strapi/icons": 1.13.0 "@strapi/icons": 1.13.0
react: ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0
react-router-dom: ^5.3.4 react-router-dom: ^5.2.0
styled-components: ^5.3.3 styled-components: ^5.2.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -9102,8 +9107,8 @@ __metadata:
"@strapi/strapi": ^4.4.0 "@strapi/strapi": ^4.4.0
react: ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0
react-router-dom: 5.3.4 react-router-dom: ^5.2.0
styled-components: 5.3.3 styled-components: ^5.2.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -9150,8 +9155,8 @@ __metadata:
"@strapi/strapi": ^4.0.0 "@strapi/strapi": ^4.0.0
react: ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0
react-router-dom: 5.3.4 react-router-dom: ^5.2.0
styled-components: 5.3.3 styled-components: ^5.2.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -9191,8 +9196,8 @@ __metadata:
"@strapi/strapi": ^4.0.0 "@strapi/strapi": ^4.0.0
react: ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0
react-router-dom: 5.3.4 react-router-dom: ^5.2.0
styled-components: 5.3.3 styled-components: ^5.2.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -9225,8 +9230,8 @@ __metadata:
koa: 2.13.4 koa: 2.13.4
react: ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0
react-router-dom: 5.3.4 react-router-dom: ^5.2.0
styled-components: 5.3.3 styled-components: ^5.2.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -9263,8 +9268,8 @@ __metadata:
"@strapi/strapi": ^4.0.0 "@strapi/strapi": ^4.0.0
react: ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0
react-router-dom: 5.3.4 react-router-dom: ^5.2.0
styled-components: 5.3.3 styled-components: ^5.2.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -9298,8 +9303,8 @@ __metadata:
"@strapi/strapi": ^4.0.0 "@strapi/strapi": ^4.0.0
react: ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0
react-router-dom: 5.3.4 react-router-dom: ^5.2.0
styled-components: 5.3.3 styled-components: ^5.2.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -9321,8 +9326,8 @@ __metadata:
"@strapi/strapi": ^4.0.0 "@strapi/strapi": ^4.0.0
react: ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0
react-router-dom: 5.3.4 react-router-dom: ^5.2.0
styled-components: 5.3.3 styled-components: ^5.2.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -9370,8 +9375,8 @@ __metadata:
"@strapi/strapi": ^4.0.0 "@strapi/strapi": ^4.0.0
react: ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0
react-router-dom: 5.3.4 react-router-dom: ^5.2.0
styled-components: 5.3.3 styled-components: ^5.2.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -9413,8 +9418,8 @@ __metadata:
"@strapi/strapi": 4.0.0 "@strapi/strapi": 4.0.0
react: ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0
react-router-dom: 5.3.4 react-router-dom: ^5.2.0
styled-components: 5.3.3 styled-components: ^5.2.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft