diff --git a/jest.config.front.js b/jest.config.front.js index a7b652ba57..168fa3b07b 100644 --- a/jest.config.front.js +++ b/jest.config.front.js @@ -38,14 +38,16 @@ module.exports = { __webpack_public_path__: 'http://localhost:4000', strapi: { backendURL: 'http://localhost:1337', + isEE: false, + features: [], + projectType: 'Community', }, BACKEND_URL: 'http://localhost:1337', ADMIN_PATH: '/admin', 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_UPDATE_NOTIFICATION': 'false', + // FIXME create a clean config file }, moduleDirectories: [ 'node_modules', diff --git a/packages/core/admin/admin/src/components/LeftMenu/compos/Footer/index.js b/packages/core/admin/admin/src/components/LeftMenu/compos/Footer/index.js index 1e8a3ceb33..17ad753299 100644 --- a/packages/core/admin/admin/src/components/LeftMenu/compos/Footer/index.js +++ b/packages/core/admin/admin/src/components/LeftMenu/compos/Footer/index.js @@ -10,7 +10,7 @@ import { useAppInfos } from '@strapi/helper-plugin'; import Wrapper, { A } from './Wrapper'; function LeftMenuFooter() { - const projectType = process.env.STRAPI_ADMIN_PROJECT_TYPE; + const projectType = strapi.projectType; const { strapiVersion } = useAppInfos(); return ( diff --git a/packages/core/admin/admin/src/index.js b/packages/core/admin/admin/src/index.js index f6f31686f6..2dbc1d6c50 100644 --- a/packages/core/admin/admin/src/index.js +++ b/packages/core/admin/admin/src/index.js @@ -10,6 +10,10 @@ import appReducers from './reducers'; window.strapi = { backendURL: process.env.STRAPI_ADMIN_BACKEND_URL, isEE: false, + features: { + SSO: 'sso', + }, + projectType: 'Community', }; const appConfig = { @@ -38,11 +42,18 @@ const run = async () => { try { const { data: { - data: { isEE }, + data: { isEE, features }, }, } = await axiosInstance.get('/admin/project-type'); 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) { console.error(err); } diff --git a/packages/core/admin/controllers/__tests__/admin.test.js b/packages/core/admin/controllers/__tests__/admin.test.js index 445efc13b4..41addef785 100644 --- a/packages/core/admin/controllers/__tests__/admin.test.js +++ b/packages/core/admin/controllers/__tests__/admin.test.js @@ -1,5 +1,22 @@ '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'); describe('Admin Controller', () => { diff --git a/packages/core/admin/controllers/admin.js b/packages/core/admin/controllers/admin.js index af2a8053a8..d8d3afb7c4 100644 --- a/packages/core/admin/controllers/admin.js +++ b/packages/core/admin/controllers/admin.js @@ -3,6 +3,10 @@ const execa = require('execa'); 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-_]+$/; /** @@ -21,7 +25,7 @@ module.exports = { // When removing this we need to update the /admin/src/index.js file // where we set the strapi.window.isEE value async getProjectType() { - return { data: { isEE: strapi.EE } }; + return { data: { isEE: strapi.EE, features: features.getEnabled() } }; }, async init() { diff --git a/packages/core/admin/ee/admin/components/Users/ModalCreateBody/utils/formDataModel.js b/packages/core/admin/ee/admin/components/Users/ModalCreateBody/utils/formDataModel.js index 214f9cf9b6..c1db4d08c9 100644 --- a/packages/core/admin/ee/admin/components/Users/ModalCreateBody/utils/formDataModel.js +++ b/packages/core/admin/ee/admin/components/Users/ModalCreateBody/utils/formDataModel.js @@ -1,6 +1,6 @@ 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, } diff --git a/packages/core/admin/ee/admin/components/Users/ModalCreateBody/utils/roleSettingsForm.js b/packages/core/admin/ee/admin/components/Users/ModalCreateBody/utils/roleSettingsForm.js index c1868cd6a9..f636ae819e 100644 --- a/packages/core/admin/ee/admin/components/Users/ModalCreateBody/utils/roleSettingsForm.js +++ b/packages/core/admin/ee/admin/components/Users/ModalCreateBody/utils/roleSettingsForm.js @@ -1,6 +1,6 @@ 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: { label: 'Settings.permissions.users.form.sso', diff --git a/packages/core/admin/ee/admin/hooks/useSettingsMenu/utils/customGlobalLinks.js b/packages/core/admin/ee/admin/hooks/useSettingsMenu/utils/customGlobalLinks.js index b6ff34c07f..ec5e790c8b 100644 --- a/packages/core/admin/ee/admin/hooks/useSettingsMenu/utils/customGlobalLinks.js +++ b/packages/core/admin/ee/admin/hooks/useSettingsMenu/utils/customGlobalLinks.js @@ -1,6 +1,6 @@ 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' }, diff --git a/packages/core/admin/ee/admin/pages/AuthPage/components/Login/index.js b/packages/core/admin/ee/admin/pages/AuthPage/components/Login/index.js index 88006bb65c..cc9ce8020e 100644 --- a/packages/core/admin/ee/admin/pages/AuthPage/components/Login/index.js +++ b/packages/core/admin/ee/admin/pages/AuthPage/components/Login/index.js @@ -16,7 +16,7 @@ import { import { useAuthProviders } from '../../../../hooks'; 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 { isLoading, data: providers } = useAuthProviders({ ssoEnabled }); diff --git a/packages/core/admin/ee/admin/pages/AuthPage/components/Providers/index.js b/packages/core/admin/ee/admin/pages/AuthPage/components/Providers/index.js index 1ef32729b9..920c245036 100644 --- a/packages/core/admin/ee/admin/pages/AuthPage/components/Providers/index.js +++ b/packages/core/admin/ee/admin/pages/AuthPage/components/Providers/index.js @@ -16,7 +16,7 @@ const ProviderWrapper = styled.div` `; 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 { formatMessage } = useIntl(); diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/utils/customRoutes.js b/packages/core/admin/ee/admin/pages/SettingsPage/utils/customRoutes.js index 50a153c76d..10ebd519a4 100644 --- a/packages/core/admin/ee/admin/pages/SettingsPage/utils/customRoutes.js +++ b/packages/core/admin/ee/admin/pages/SettingsPage/utils/customRoutes.js @@ -1,6 +1,6 @@ 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, diff --git a/packages/core/admin/env.js b/packages/core/admin/env.js index b3249821bb..6c96f57ecb 100644 --- a/packages/core/admin/env.js +++ b/packages/core/admin/env.js @@ -12,7 +12,7 @@ if (fs.existsSync(dotenvFilePath)) { const STRAPI_ADMIN = /^STRAPI_ADMIN_/i; -const getClientEnvironment = (useEE, options) => { +const getClientEnvironment = options => { const raw = Object.keys(process.env) .filter(key => STRAPI_ADMIN.test(key)) .reduce( @@ -25,8 +25,6 @@ const getClientEnvironment = (useEE, options) => { ADMIN_PATH: options.adminPath, NODE_ENV: options.env || 'development', 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_UPDATE_NOTIFICATION: 'true', } diff --git a/packages/core/admin/index.js b/packages/core/admin/index.js index e1efd2d401..63a5d62ab6 100644 --- a/packages/core/admin/index.js +++ b/packages/core/admin/index.js @@ -7,8 +7,6 @@ const webpack = require('webpack'); const WebpackDevServer = require('webpack-dev-server'); const chalk = require('chalk'); 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 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) { const adminConfigPath = path.join(dir, 'admin', 'admin.config.js'); - let webpackConfig = getWebpackConfig({ useEE: hasEE({ dir }), ...config }); + let webpackConfig = getWebpackConfig(config); if (fs.existsSync(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 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 = { entry, dest, env, port, options, + roots, }; const opts = { diff --git a/packages/core/admin/scripts/build.js b/packages/core/admin/scripts/build.js index ed71db647d..f9f7056f8c 100644 --- a/packages/core/admin/scripts/build.js +++ b/packages/core/admin/scripts/build.js @@ -16,9 +16,7 @@ const buildAdmin = async () => { options: { backend: 'http://localhost:1337', adminPath: '/admin/', - features: [], }, - useEE: false, }; const compiler = webpack(webpackConfig(args)); diff --git a/packages/core/admin/webpack.config.dev.js b/packages/core/admin/webpack.config.dev.js index fa3b9279d7..d2a4f9255c 100644 --- a/packages/core/admin/webpack.config.dev.js +++ b/packages/core/admin/webpack.config.dev.js @@ -18,17 +18,13 @@ module.exports = () => { const options = { backend: 'http://localhost:1337', adminPath: '/admin/', - features: process.env.STRAPI_ADMIN_ENABLED_EE_FEATURES || ['sso'], }; - const useEE = process.env.STRAPI_DISABLE_EE === 'true' ? false : true; - const args = { entry, dest, env, options, - useEE, }; const config = webpackConfig(args); diff --git a/packages/core/admin/webpack.config.js b/packages/core/admin/webpack.config.js index b292467dfd..6acf203c6b 100644 --- a/packages/core/admin/webpack.config.js +++ b/packages/core/admin/webpack.config.js @@ -12,7 +12,6 @@ const alias = require('./webpack.alias'); const getClientEnvironment = require('./env'); module.exports = ({ - useEE, entry, dest, env, @@ -29,7 +28,7 @@ module.exports = ({ }) => { const isProduction = env === 'production'; - const envVariables = getClientEnvironment(useEE, { ...options, env }); + const envVariables = getClientEnvironment({ ...options, env }); const webpackPlugins = isProduction ? [ diff --git a/packages/core/helper-plugin/lib/src/hooks/useTracking/index.js b/packages/core/helper-plugin/lib/src/hooks/useTracking/index.js index 3a0f33c079..cf0a41b00e 100644 --- a/packages/core/helper-plugin/lib/src/hooks/useTracking/index.js +++ b/packages/core/helper-plugin/lib/src/hooks/useTracking/index.js @@ -11,7 +11,7 @@ const useTracking = () => { try { axios.post('https://analytics.strapi.io/track', { event, - properties: { ...properties, projectType: process.env.STRAPI_ADMIN_PROJECT_TYPE }, + properties: { ...properties, projectType: strapi.projectType }, uuid, }); } catch (err) { diff --git a/packages/core/strapi/lib/commands/build.js b/packages/core/strapi/lib/commands/build.js index 24161a78e8..2073e66649 100644 --- a/packages/core/strapi/lib/commands/build.js +++ b/packages/core/strapi/lib/commands/build.js @@ -34,7 +34,6 @@ module.exports = async ({ clean, optimization }) => { options: { backend: serverUrl, adminPath: addSlash(adminPath), - features: ee.isEE ? ee.features.getEnabled() : [], }, }) .then(() => { diff --git a/packages/utils/babel-plugin-switch-ee-ce/README.md b/packages/utils/babel-plugin-switch-ee-ce/README.md index e69de29bb2..a822d3a6be 100644 --- a/packages/utils/babel-plugin-switch-ee-ce/README.md +++ b/packages/utils/babel-plugin-switch-ee-ce/README.md @@ -0,0 +1,3 @@ +# Strapi babel plugin switch EE CE + +This plugin allows to switch from EE to CE at runtime. diff --git a/packages/utils/babel-plugin-switch-ee-ce/lib/index.js b/packages/utils/babel-plugin-switch-ee-ce/lib/index.js index f5bfa75f52..27aaac5262 100644 --- a/packages/utils/babel-plugin-switch-ee-ce/lib/index.js +++ b/packages/utils/babel-plugin-switch-ee-ce/lib/index.js @@ -1,5 +1,7 @@ 'use strict'; +// Widely inspired from https://github.com/tleunen/babel-plugin-module-resolver/tree/master/src + const transformImport = require('./transformers/import'); const normalizeOptions = require('./normalizeOptions'); diff --git a/packages/utils/babel-plugin-switch-ee-ce/lib/mapToRelative.js b/packages/utils/babel-plugin-switch-ee-ce/lib/mapToRelative.js index b259618c6b..9d1c0e4f0a 100644 --- a/packages/utils/babel-plugin-switch-ee-ce/lib/mapToRelative.js +++ b/packages/utils/babel-plugin-switch-ee-ce/lib/mapToRelative.js @@ -1,5 +1,7 @@ 'use strict'; +// From https://github.com/tleunen/babel-plugin-module-resolver/blob/master/src/mapToRelative.js + const path = require('path'); const { toPosixPath } = require('./utils'); diff --git a/packages/utils/babel-plugin-switch-ee-ce/lib/normalizeOptions.js b/packages/utils/babel-plugin-switch-ee-ce/lib/normalizeOptions.js index 294893632d..15662e74b4 100644 --- a/packages/utils/babel-plugin-switch-ee-ce/lib/normalizeOptions.js +++ b/packages/utils/babel-plugin-switch-ee-ce/lib/normalizeOptions.js @@ -1,5 +1,7 @@ 'use strict'; +// Adapted from https://github.com/tleunen/babel-plugin-module-resolver/blob/master/src/normalizeOptions.js + const path = require('path'); const { createSelector } = require('reselect'); diff --git a/packages/utils/babel-plugin-switch-ee-ce/lib/resolvePath.js b/packages/utils/babel-plugin-switch-ee-ce/lib/resolvePath.js index af6a811bb7..1405738041 100644 --- a/packages/utils/babel-plugin-switch-ee-ce/lib/resolvePath.js +++ b/packages/utils/babel-plugin-switch-ee-ce/lib/resolvePath.js @@ -1,5 +1,7 @@ 'use strict'; +// Adapted from https://github.com/tleunen/babel-plugin-module-resolver/blob/master/src/resolvePath.js + const path = require('path'); const normalizeOptions = require('./normalizeOptions'); const mapToRelative = require('./mapToRelative'); diff --git a/packages/utils/babel-plugin-switch-ee-ce/lib/utils.js b/packages/utils/babel-plugin-switch-ee-ce/lib/utils.js index e02d5f7261..3cad1240d0 100644 --- a/packages/utils/babel-plugin-switch-ee-ce/lib/utils.js +++ b/packages/utils/babel-plugin-switch-ee-ce/lib/utils.js @@ -1,5 +1,7 @@ 'use strict'; +// From https://github.com/tleunen/babel-plugin-module-resolver/blob/master/src/utils.js + const path = require('path'); const resolve = require('resolve'); @@ -48,7 +50,6 @@ const isRelativePath = nodePath => { module.exports = { nodeResolvePath, - replaceExtension, stripExtension, toPosixPath, diff --git a/test/config/front/strapi.js b/test/config/front/strapi.js index dcd4e5f059..2e2996048e 100644 --- a/test/config/front/strapi.js +++ b/test/config/front/strapi.js @@ -7,35 +7,18 @@ // Setup the strapi function global variable +// FIXME create a better jest setup 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 ; - } - } - - return hoistNonReactStatics(HocInjector, WrappedComponent); -}; - -// FIXME -global.process.env.STRAPI_ADMIN_ENABLED_EE_FEATURES = []; global.process.env.ADMIN_PATH = '/admin/'; global.strapi = { backendURL: 'http://localhost:1337', - injectReducer: hoc, - injectSaga: hoc, - notification: { - error: jest.fn(), - info: jest.fn(), - success: jest.fn(), - warning: jest.fn(), + isEE: false, + features: { + SSO: 'sso', + allFeatures: [], + isEnabled: () => false, }, + projectType: 'Community', };