mirror of
https://github.com/strapi/strapi.git
synced 2025-10-22 05:24:22 +00:00
Merge pull request #10569 from strapi/core/switch-plan
Allow to switch plan at runtime
This commit is contained in:
commit
c4adf3790a
@ -38,14 +38,16 @@ module.exports = {
|
|||||||
__webpack_public_path__: 'http://localhost:4000',
|
__webpack_public_path__: 'http://localhost:4000',
|
||||||
strapi: {
|
strapi: {
|
||||||
backendURL: 'http://localhost:1337',
|
backendURL: 'http://localhost:1337',
|
||||||
|
isEE: false,
|
||||||
|
features: [],
|
||||||
|
projectType: 'Community',
|
||||||
},
|
},
|
||||||
BACKEND_URL: 'http://localhost:1337',
|
BACKEND_URL: 'http://localhost:1337',
|
||||||
ADMIN_PATH: '/admin',
|
ADMIN_PATH: '/admin',
|
||||||
NODE_ENV: 'test',
|
NODE_ENV: 'test',
|
||||||
'process.env.STRAPI_ADMIN_ENABLED_EE_FEATURES': [],
|
|
||||||
STRAPI_ADMIN_ENABLED_EE_FEATURES: [],
|
|
||||||
'process.env.STRAPI_ADMIN_SHOW_TUTORIALS': 'false',
|
'process.env.STRAPI_ADMIN_SHOW_TUTORIALS': 'false',
|
||||||
'process.env.STRAPI_ADMIN_UPDATE_NOTIFICATION': 'false',
|
'process.env.STRAPI_ADMIN_UPDATE_NOTIFICATION': 'false',
|
||||||
|
// FIXME create a clean config file
|
||||||
},
|
},
|
||||||
moduleDirectories: [
|
moduleDirectories: [
|
||||||
'node_modules',
|
'node_modules',
|
||||||
|
@ -10,7 +10,7 @@ import { useAppInfos } from '@strapi/helper-plugin';
|
|||||||
import Wrapper, { A } from './Wrapper';
|
import Wrapper, { A } from './Wrapper';
|
||||||
|
|
||||||
function LeftMenuFooter() {
|
function LeftMenuFooter() {
|
||||||
const projectType = process.env.STRAPI_ADMIN_PROJECT_TYPE;
|
const projectType = strapi.projectType;
|
||||||
const { strapiVersion } = useAppInfos();
|
const { strapiVersion } = useAppInfos();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -10,6 +10,10 @@ import appReducers from './reducers';
|
|||||||
window.strapi = {
|
window.strapi = {
|
||||||
backendURL: process.env.STRAPI_ADMIN_BACKEND_URL,
|
backendURL: process.env.STRAPI_ADMIN_BACKEND_URL,
|
||||||
isEE: false,
|
isEE: false,
|
||||||
|
features: {
|
||||||
|
SSO: 'sso',
|
||||||
|
},
|
||||||
|
projectType: 'Community',
|
||||||
};
|
};
|
||||||
|
|
||||||
const appConfig = {
|
const appConfig = {
|
||||||
@ -38,11 +42,18 @@ const run = async () => {
|
|||||||
try {
|
try {
|
||||||
const {
|
const {
|
||||||
data: {
|
data: {
|
||||||
data: { isEE },
|
data: { isEE, features },
|
||||||
},
|
},
|
||||||
} = await axiosInstance.get('/admin/project-type');
|
} = await axiosInstance.get('/admin/project-type');
|
||||||
|
|
||||||
window.strapi.isEE = isEE;
|
window.strapi.isEE = isEE;
|
||||||
|
window.strapi.features = {
|
||||||
|
...window.strapi.features,
|
||||||
|
allFeatures: features,
|
||||||
|
isEnabled: f => features.includes(f),
|
||||||
|
};
|
||||||
|
|
||||||
|
window.strapi.projectType = isEE ? 'Enterprise' : 'Community';
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,22 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
jest.mock('@strapi/strapi/lib/utils/ee', () => {
|
||||||
|
const eeModule = () => false;
|
||||||
|
|
||||||
|
Object.assign(eeModule, {
|
||||||
|
features: {
|
||||||
|
isEnabled() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
getEnabled() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return eeModule;
|
||||||
|
});
|
||||||
|
|
||||||
const adminController = require('../admin');
|
const adminController = require('../admin');
|
||||||
|
|
||||||
describe('Admin Controller', () => {
|
describe('Admin Controller', () => {
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
const execa = require('execa');
|
const execa = require('execa');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
// eslint-disable-next-line node/no-extraneous-require
|
||||||
|
const { features } = require('@strapi/strapi/lib/utils/ee');
|
||||||
|
|
||||||
const PLUGIN_NAME_REGEX = /^[A-Za-z][A-Za-z0-9-_]+$/;
|
const PLUGIN_NAME_REGEX = /^[A-Za-z][A-Za-z0-9-_]+$/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,7 +25,7 @@ module.exports = {
|
|||||||
// When removing this we need to update the /admin/src/index.js file
|
// When removing this we need to update the /admin/src/index.js file
|
||||||
// where we set the strapi.window.isEE value
|
// where we set the strapi.window.isEE value
|
||||||
async getProjectType() {
|
async getProjectType() {
|
||||||
return { data: { isEE: strapi.EE } };
|
return { data: { isEE: strapi.EE, features: features.getEnabled() } };
|
||||||
},
|
},
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import baseModel from '../../../../../../admin/src/components/Users/ModalCreateBody/utils/formDataModel';
|
import baseModel from '../../../../../../admin/src/components/Users/ModalCreateBody/utils/formDataModel';
|
||||||
|
|
||||||
const ssoInputsModel = process.env.STRAPI_ADMIN_ENABLED_EE_FEATURES.includes('sso')
|
const ssoInputsModel = strapi.features.isEnabled(strapi.features.SSO)
|
||||||
? {
|
? {
|
||||||
useSSORegistration: true,
|
useSSORegistration: true,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import baseForm from '../../../../../../admin/src/components/Users/ModalCreateBody/utils/roleSettingsForm';
|
import baseForm from '../../../../../../admin/src/components/Users/ModalCreateBody/utils/roleSettingsForm';
|
||||||
|
|
||||||
const ssoInputs = process.env.STRAPI_ADMIN_ENABLED_EE_FEATURES.includes('sso')
|
const ssoInputs = strapi.features.isEnabled(strapi.features.SSO)
|
||||||
? {
|
? {
|
||||||
useSSORegistration: {
|
useSSORegistration: {
|
||||||
label: 'Settings.permissions.users.form.sso',
|
label: 'Settings.permissions.users.form.sso',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import adminPermissions from '../../../../../admin/src/permissions';
|
import adminPermissions from '../../../../../admin/src/permissions';
|
||||||
|
|
||||||
const ssoGlobalRoutes = process.env.STRAPI_ADMIN_ENABLED_EE_FEATURES.includes('sso')
|
const ssoGlobalRoutes = strapi.features.isEnabled(strapi.features.SSO)
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
intlLabel: { id: 'Settings.sso.title', defaultMessage: 'Single Sign-On' },
|
intlLabel: { id: 'Settings.sso.title', defaultMessage: 'Single Sign-On' },
|
||||||
|
@ -16,7 +16,7 @@ import {
|
|||||||
import { useAuthProviders } from '../../../../hooks';
|
import { useAuthProviders } from '../../../../hooks';
|
||||||
|
|
||||||
const Login = loginProps => {
|
const Login = loginProps => {
|
||||||
const ssoEnabled = process.env.STRAPI_ADMIN_ENABLED_EE_FEATURES.includes('sso');
|
const ssoEnabled = strapi.features.isEnabled(strapi.features.SSO);
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { isLoading, data: providers } = useAuthProviders({ ssoEnabled });
|
const { isLoading, data: providers } = useAuthProviders({ ssoEnabled });
|
||||||
|
@ -16,7 +16,7 @@ const ProviderWrapper = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const Providers = () => {
|
const Providers = () => {
|
||||||
const ssoEnabled = process.env.STRAPI_ADMIN_ENABLED_EE_FEATURES.includes('sso');
|
const ssoEnabled = strapi.features.isEnabled(strapi.features.SSO);
|
||||||
|
|
||||||
const { push } = useHistory();
|
const { push } = useHistory();
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import SingleSignOn from '../SingleSignOn';
|
import SingleSignOn from '../SingleSignOn';
|
||||||
|
|
||||||
const ssoRoutes = process.env.STRAPI_ADMIN_ENABLED_EE_FEATURES.includes('sso')
|
const ssoRoutes = strapi.features.isEnabled(strapi.features.SSO)
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
Component: SingleSignOn,
|
Component: SingleSignOn,
|
||||||
|
@ -12,7 +12,7 @@ if (fs.existsSync(dotenvFilePath)) {
|
|||||||
|
|
||||||
const STRAPI_ADMIN = /^STRAPI_ADMIN_/i;
|
const STRAPI_ADMIN = /^STRAPI_ADMIN_/i;
|
||||||
|
|
||||||
const getClientEnvironment = (useEE, options) => {
|
const getClientEnvironment = options => {
|
||||||
const raw = Object.keys(process.env)
|
const raw = Object.keys(process.env)
|
||||||
.filter(key => STRAPI_ADMIN.test(key))
|
.filter(key => STRAPI_ADMIN.test(key))
|
||||||
.reduce(
|
.reduce(
|
||||||
@ -25,8 +25,6 @@ const getClientEnvironment = (useEE, options) => {
|
|||||||
ADMIN_PATH: options.adminPath,
|
ADMIN_PATH: options.adminPath,
|
||||||
NODE_ENV: options.env || 'development',
|
NODE_ENV: options.env || 'development',
|
||||||
STRAPI_ADMIN_BACKEND_URL: options.backend,
|
STRAPI_ADMIN_BACKEND_URL: options.backend,
|
||||||
STRAPI_ADMIN_ENABLED_EE_FEATURES: options.features,
|
|
||||||
STRAPI_ADMIN_PROJECT_TYPE: useEE ? 'Enterprise' : 'Community',
|
|
||||||
STRAPI_ADMIN_SHOW_TUTORIALS: 'true',
|
STRAPI_ADMIN_SHOW_TUTORIALS: 'true',
|
||||||
STRAPI_ADMIN_UPDATE_NOTIFICATION: 'true',
|
STRAPI_ADMIN_UPDATE_NOTIFICATION: 'true',
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,6 @@ const webpack = require('webpack');
|
|||||||
const WebpackDevServer = require('webpack-dev-server');
|
const WebpackDevServer = require('webpack-dev-server');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const chokidar = require('chokidar');
|
const chokidar = require('chokidar');
|
||||||
// eslint-disable-next-line node/no-extraneous-require
|
|
||||||
const hasEE = require('@strapi/strapi/lib/utils/ee');
|
|
||||||
const getWebpackConfig = require('./webpack.config');
|
const getWebpackConfig = require('./webpack.config');
|
||||||
|
|
||||||
const getPkgPath = name => path.dirname(require.resolve(`${name}/package.json`));
|
const getPkgPath = name => path.dirname(require.resolve(`${name}/package.json`));
|
||||||
@ -16,7 +14,7 @@ const getPkgPath = name => path.dirname(require.resolve(`${name}/package.json`))
|
|||||||
function getCustomWebpackConfig(dir, config) {
|
function getCustomWebpackConfig(dir, config) {
|
||||||
const adminConfigPath = path.join(dir, 'admin', 'admin.config.js');
|
const adminConfigPath = path.join(dir, 'admin', 'admin.config.js');
|
||||||
|
|
||||||
let webpackConfig = getWebpackConfig({ useEE: hasEE({ dir }), ...config });
|
let webpackConfig = getWebpackConfig(config);
|
||||||
|
|
||||||
if (fs.existsSync(adminConfigPath)) {
|
if (fs.existsSync(adminConfigPath)) {
|
||||||
const adminConfig = require(path.resolve(adminConfigPath));
|
const adminConfig = require(path.resolve(adminConfigPath));
|
||||||
@ -242,12 +240,21 @@ async function watchAdmin({ dir, host, port, browser, options }) {
|
|||||||
const dest = path.join(dir, 'build');
|
const dest = path.join(dir, 'build');
|
||||||
const env = 'development';
|
const env = 'development';
|
||||||
|
|
||||||
|
const cacheDir = path.join(dir, '.cache');
|
||||||
|
|
||||||
|
// Roots for the @strapi/babel-plugin-switch-ee-ce
|
||||||
|
const roots = {
|
||||||
|
eeRoot: path.resolve(cacheDir, 'ee', 'admin'),
|
||||||
|
ceRoot: path.resolve(cacheDir, 'admin', 'src'),
|
||||||
|
};
|
||||||
|
|
||||||
const args = {
|
const args = {
|
||||||
entry,
|
entry,
|
||||||
dest,
|
dest,
|
||||||
env,
|
env,
|
||||||
port,
|
port,
|
||||||
options,
|
options,
|
||||||
|
roots,
|
||||||
};
|
};
|
||||||
|
|
||||||
const opts = {
|
const opts = {
|
||||||
|
@ -16,9 +16,7 @@ const buildAdmin = async () => {
|
|||||||
options: {
|
options: {
|
||||||
backend: 'http://localhost:1337',
|
backend: 'http://localhost:1337',
|
||||||
adminPath: '/admin/',
|
adminPath: '/admin/',
|
||||||
features: [],
|
|
||||||
},
|
},
|
||||||
useEE: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const compiler = webpack(webpackConfig(args));
|
const compiler = webpack(webpackConfig(args));
|
||||||
|
@ -18,17 +18,13 @@ module.exports = () => {
|
|||||||
const options = {
|
const options = {
|
||||||
backend: 'http://localhost:1337',
|
backend: 'http://localhost:1337',
|
||||||
adminPath: '/admin/',
|
adminPath: '/admin/',
|
||||||
features: process.env.STRAPI_ADMIN_ENABLED_EE_FEATURES || ['sso'],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const useEE = process.env.STRAPI_DISABLE_EE === 'true' ? false : true;
|
|
||||||
|
|
||||||
const args = {
|
const args = {
|
||||||
entry,
|
entry,
|
||||||
dest,
|
dest,
|
||||||
env,
|
env,
|
||||||
options,
|
options,
|
||||||
useEE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const config = webpackConfig(args);
|
const config = webpackConfig(args);
|
||||||
|
@ -12,7 +12,6 @@ const alias = require('./webpack.alias');
|
|||||||
const getClientEnvironment = require('./env');
|
const getClientEnvironment = require('./env');
|
||||||
|
|
||||||
module.exports = ({
|
module.exports = ({
|
||||||
useEE,
|
|
||||||
entry,
|
entry,
|
||||||
dest,
|
dest,
|
||||||
env,
|
env,
|
||||||
@ -29,7 +28,7 @@ module.exports = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const isProduction = env === 'production';
|
const isProduction = env === 'production';
|
||||||
|
|
||||||
const envVariables = getClientEnvironment(useEE, { ...options, env });
|
const envVariables = getClientEnvironment({ ...options, env });
|
||||||
|
|
||||||
const webpackPlugins = isProduction
|
const webpackPlugins = isProduction
|
||||||
? [
|
? [
|
||||||
|
@ -11,7 +11,7 @@ const useTracking = () => {
|
|||||||
try {
|
try {
|
||||||
axios.post('https://analytics.strapi.io/track', {
|
axios.post('https://analytics.strapi.io/track', {
|
||||||
event,
|
event,
|
||||||
properties: { ...properties, projectType: process.env.STRAPI_ADMIN_PROJECT_TYPE },
|
properties: { ...properties, projectType: strapi.projectType },
|
||||||
uuid,
|
uuid,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -34,7 +34,6 @@ module.exports = async ({ clean, optimization }) => {
|
|||||||
options: {
|
options: {
|
||||||
backend: serverUrl,
|
backend: serverUrl,
|
||||||
adminPath: addSlash(adminPath),
|
adminPath: addSlash(adminPath),
|
||||||
features: ee.isEE ? ee.features.getEnabled() : [],
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
# Strapi babel plugin switch EE CE
|
||||||
|
|
||||||
|
This plugin allows to switch from EE to CE at runtime.
|
@ -1,5 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
// Widely inspired from https://github.com/tleunen/babel-plugin-module-resolver/tree/master/src
|
||||||
|
|
||||||
const transformImport = require('./transformers/import');
|
const transformImport = require('./transformers/import');
|
||||||
const normalizeOptions = require('./normalizeOptions');
|
const normalizeOptions = require('./normalizeOptions');
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
// From https://github.com/tleunen/babel-plugin-module-resolver/blob/master/src/mapToRelative.js
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const { toPosixPath } = require('./utils');
|
const { toPosixPath } = require('./utils');
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
// Adapted from https://github.com/tleunen/babel-plugin-module-resolver/blob/master/src/normalizeOptions.js
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { createSelector } = require('reselect');
|
const { createSelector } = require('reselect');
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
// Adapted from https://github.com/tleunen/babel-plugin-module-resolver/blob/master/src/resolvePath.js
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const normalizeOptions = require('./normalizeOptions');
|
const normalizeOptions = require('./normalizeOptions');
|
||||||
const mapToRelative = require('./mapToRelative');
|
const mapToRelative = require('./mapToRelative');
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
// From https://github.com/tleunen/babel-plugin-module-resolver/blob/master/src/utils.js
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const resolve = require('resolve');
|
const resolve = require('resolve');
|
||||||
|
|
||||||
@ -48,7 +50,6 @@ const isRelativePath = nodePath => {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
nodeResolvePath,
|
nodeResolvePath,
|
||||||
|
|
||||||
replaceExtension,
|
replaceExtension,
|
||||||
stripExtension,
|
stripExtension,
|
||||||
toPosixPath,
|
toPosixPath,
|
||||||
|
@ -7,35 +7,18 @@
|
|||||||
|
|
||||||
// Setup the strapi function global variable
|
// Setup the strapi function global variable
|
||||||
|
|
||||||
|
// FIXME create a better jest setup
|
||||||
import '@testing-library/jest-dom/extend-expect';
|
import '@testing-library/jest-dom/extend-expect';
|
||||||
|
|
||||||
const React = require('react');
|
|
||||||
const hoistNonReactStatics = require('hoist-non-react-statics');
|
|
||||||
|
|
||||||
const hoc = () => WrappedComponent => {
|
|
||||||
class HocInjector extends React.Component {
|
|
||||||
static WrappedComponent = WrappedComponent;
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return <WrappedComponent {...this.props} />;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hoistNonReactStatics(HocInjector, WrappedComponent);
|
|
||||||
};
|
|
||||||
|
|
||||||
// FIXME
|
|
||||||
global.process.env.STRAPI_ADMIN_ENABLED_EE_FEATURES = [];
|
|
||||||
global.process.env.ADMIN_PATH = '/admin/';
|
global.process.env.ADMIN_PATH = '/admin/';
|
||||||
|
|
||||||
global.strapi = {
|
global.strapi = {
|
||||||
backendURL: 'http://localhost:1337',
|
backendURL: 'http://localhost:1337',
|
||||||
injectReducer: hoc,
|
isEE: false,
|
||||||
injectSaga: hoc,
|
features: {
|
||||||
notification: {
|
SSO: 'sso',
|
||||||
error: jest.fn(),
|
allFeatures: [],
|
||||||
info: jest.fn(),
|
isEnabled: () => false,
|
||||||
success: jest.fn(),
|
|
||||||
warning: jest.fn(),
|
|
||||||
},
|
},
|
||||||
|
projectType: 'Community',
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user