@strapi/admin 4.2.1-alpha.0 → 4.3.0-beta.2

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.
Files changed (180) hide show
  1. package/admin/src/app.js +7 -4
  2. package/admin/src/components/OverlayBlocker/index.js +4 -0
  3. package/admin/src/content-manager/components/DynamicTable/CellContent/utils/hasContent.js +1 -1
  4. package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +10 -16
  5. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/cleanData.js +1 -0
  6. package/admin/src/content-manager/components/SelectMany/index.js +2 -4
  7. package/admin/src/content-manager/components/SelectWrapper/index.js +1 -13
  8. package/admin/src/content-manager/components/Wysiwyg/EditorStylesContainer.js +1 -1
  9. package/admin/src/content-manager/pages/ListView/index.js +2 -2
  10. package/admin/src/hooks/{useFetchInstalledPlugins → useFetchEnabledPlugins}/index.js +4 -4
  11. package/admin/src/hooks/{useFetchInstalledPlugins → useFetchEnabledPlugins}/utils/api.js +2 -2
  12. package/admin/src/hooks/useFetchMarketplaceProviders/index.js +1 -1
  13. package/admin/src/pages/Admin/index.js +15 -5
  14. package/admin/src/pages/App/constants.js +1 -0
  15. package/admin/src/pages/App/index.js +17 -3
  16. package/admin/src/pages/App/reducer.js +22 -0
  17. package/admin/src/pages/InstalledPluginsPage/Plugins.js +2 -2
  18. package/admin/src/pages/MarketplacePage/components/NpmPackageCard/index.js +7 -8
  19. package/admin/src/pages/MarketplacePage/components/NpmPackagesGrid/index.js +9 -3
  20. package/admin/src/pages/MarketplacePage/index.js +9 -39
  21. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/FromUrlForm.js +7 -3
  22. package/admin/src/reducers.js +4 -2
  23. package/admin/src/translations/en.json +2 -0
  24. package/admin/src/translations/hi.json +699 -0
  25. package/admin/src/translations/languageNativeNames.js +2 -0
  26. package/admin/src/translations/pl.json +238 -233
  27. package/admin/src/translations/sa.json +698 -0
  28. package/admin/src/translations/zh-Hans.json +28 -1
  29. package/admin/src/tsconfig.json +10 -0
  30. package/build/20.9e5a98b6.chunk.js +308 -0
  31. package/build/{9115.623dc4f7.chunk.js → 2336.cb1c0d6e.chunk.js} +1 -1
  32. package/build/2863.bf3c1eff.chunk.js +194 -0
  33. package/build/3531.ef1d2cfc.chunk.js +10 -0
  34. package/build/413.d5986568.chunk.js +284 -0
  35. package/build/{4715.4588fdf5.chunk.js → 4715.a6e62860.chunk.js} +8 -8
  36. package/build/5250.9988a0ad.chunk.js +12 -0
  37. package/build/{9158.e48d88af.chunk.js → 5520.9dcd6a9f.chunk.js} +32 -32
  38. package/build/5833.970a963d.chunk.js +112 -0
  39. package/build/6925.fb35248e.chunk.js +761 -0
  40. package/build/8773.16dea88d.chunk.js +327 -0
  41. package/build/{7757.f6eb5e92.chunk.js → 9166.5c585d7c.chunk.js} +25 -25
  42. package/build/9262.25aa12a5.chunk.js +1 -0
  43. package/build/Admin-authenticatedApp.d38dc4dd.chunk.js +80 -0
  44. package/build/Admin_homePage.e3571a75.chunk.js +71 -0
  45. package/build/Admin_marketplace.284bf8fc.chunk.js +11 -0
  46. package/build/Admin_pluginsPage.8537476f.chunk.js +1 -0
  47. package/build/{Admin_profilePage.249cbfc9.chunk.js → Admin_profilePage.b7f85e78.chunk.js} +2 -2
  48. package/build/Admin_settingsPage.858ef0d7.chunk.js +178 -0
  49. package/build/admin-edit-roles-page.33647266.chunk.js +1 -0
  50. package/build/admin-edit-users.8cd7519b.chunk.js +10 -0
  51. package/build/admin-users.6581eec5.chunk.js +11 -0
  52. package/build/{api-tokens-edit-page.3e453fc1.chunk.js → api-tokens-create-page.efa1d2aa.chunk.js} +1 -1
  53. package/build/api-tokens-edit-page.6101f051.chunk.js +1 -0
  54. package/build/{api-tokens-list-page.872c3800.chunk.js → api-tokens-list-page.782e872f.chunk.js} +2 -2
  55. package/build/{codemirror-css.98490df3.chunk.js → codemirror-css.4e2bbed3.chunk.js} +2 -2
  56. package/build/{codemirror-javacript.cafbda9c.chunk.js → codemirror-javacript.41bdefda.chunk.js} +1 -1
  57. package/build/codemirror-theme.a82cae4e.chunk.js +34 -0
  58. package/build/content-manager.adf6fc82.chunk.js +1182 -0
  59. package/build/content-type-builder-translation-pl-json.4a42349b.chunk.js +1 -0
  60. package/build/content-type-builder.366a3b10.chunk.js +142 -0
  61. package/build/{cropper-css.0055cd53.chunk.js → cropper-css.12fe038c.chunk.js} +4 -4
  62. package/build/{email-settings-page.1f235173.chunk.js → email-settings-page.d72e7f4c.chunk.js} +2 -2
  63. package/build/email-translation-pl-json.a03bcf98.chunk.js +1 -0
  64. package/build/{en-json.0a5ba154.chunk.js → en-json.729eb94d.chunk.js} +1 -1
  65. package/build/{fontawesome-css-all.b88d464e.chunk.js → fontawesome-css-all.15068c6e.chunk.js} +3 -3
  66. package/build/{fontawesome-css.a92a7b6c.chunk.js → fontawesome-css.418f40da.chunk.js} +2 -2
  67. package/build/hi-json.b4ae16d1.chunk.js +1 -0
  68. package/build/highlight.js.af2de364.chunk.js +86 -0
  69. package/build/i18n-settings-page.8803df0b.chunk.js +101 -0
  70. package/build/i18n-translation-pl-json.cea5bf23.chunk.js +1 -0
  71. package/build/index.html +1 -1
  72. package/build/main.689d6439.js +8688 -0
  73. package/build/pl-json.4d11f53d.chunk.js +1 -0
  74. package/build/runtime~main.308a7c41.js +2 -0
  75. package/build/sa-json.be504091.chunk.js +1 -0
  76. package/build/sso-settings-page.2bae79df.chunk.js +1 -0
  77. package/build/{upload-settings.4ee2f135.chunk.js → upload-settings.f1e587c0.chunk.js} +6 -6
  78. package/build/upload-translation-de-json.745613c0.chunk.js +1 -0
  79. package/build/upload-translation-dk-json.cb25dcf0.chunk.js +1 -0
  80. package/build/upload-translation-en-json.fddec9a6.chunk.js +1 -0
  81. package/build/upload-translation-es-json.1f344b53.chunk.js +1 -0
  82. package/build/upload-translation-fr-json.e21c0c7a.chunk.js +1 -0
  83. package/build/upload-translation-he-json.4ce77b7b.chunk.js +1 -0
  84. package/build/upload-translation-it-json.5ce11e0b.chunk.js +1 -0
  85. package/build/upload-translation-ja-json.22afae44.chunk.js +1 -0
  86. package/build/upload-translation-ko-json.9a2c21cb.chunk.js +1 -0
  87. package/build/upload-translation-ms-json.0605d6da.chunk.js +1 -0
  88. package/build/upload-translation-pl-json.c1f86b50.chunk.js +1 -0
  89. package/build/upload-translation-pt-BR-json.95686cfb.chunk.js +1 -0
  90. package/build/upload-translation-ru-json.37bd1546.chunk.js +1 -0
  91. package/build/upload-translation-sk-json.b03d4904.chunk.js +1 -0
  92. package/build/upload-translation-th-json.64dd70ce.chunk.js +1 -0
  93. package/build/upload-translation-uk-json.1328cb3e.chunk.js +1 -0
  94. package/build/{upload-translation-zh-Hans-json.c9622577.chunk.js → upload-translation-zh-Hans-json.6832ff81.chunk.js} +1 -1
  95. package/build/upload-translation-zh-json.ee8fba96.chunk.js +1 -0
  96. package/build/upload.1346f4b1.chunk.js +7 -0
  97. package/build/{users-advanced-settings-page.747b2ec1.chunk.js → users-advanced-settings-page.f38654fc.chunk.js} +1 -1
  98. package/build/users-email-settings-page.824a3cdb.chunk.js +101 -0
  99. package/build/users-permissions-translation-en-json.765abf48.chunk.js +1 -0
  100. package/build/users-permissions-translation-pl-json.1dbdd4a1.chunk.js +1 -0
  101. package/build/users-providers-settings-page.82a4ba58.chunk.js +101 -0
  102. package/build/{users-roles-settings-page.1bf4ffc5.chunk.js → users-roles-settings-page.1206751f.chunk.js} +3 -3
  103. package/build/{webhook-edit-page.142b23ac.chunk.js → webhook-edit-page.5c9bada0.chunk.js} +2 -2
  104. package/build/{webhook-list-page.671582a0.chunk.js → webhook-list-page.822927af.chunk.js} +1 -1
  105. package/build/zh-Hans-json.cbc69f3d.chunk.js +1 -0
  106. package/index.js +47 -239
  107. package/package.json +31 -24
  108. package/scripts/build.js +19 -3
  109. package/server/controllers/admin.js +23 -0
  110. package/server/policies/index.js +1 -0
  111. package/server/policies/isTelemetryEnabled.js +16 -0
  112. package/server/routes/admin.js +8 -0
  113. package/server/routes/serve-admin-panel.js +1 -1
  114. package/utils/create-cache-dir.js +131 -0
  115. package/utils/get-custom-app-config-file.js +28 -0
  116. package/utils/get-custom-webpack-config.js +38 -0
  117. package/utils/get-plugins-path.js +26 -0
  118. package/utils/index.js +13 -0
  119. package/utils/should-build-admin.js +52 -0
  120. package/utils/watch-admin-files.js +59 -0
  121. package/webpack.config.js +34 -6
  122. package/admin/src/content-manager/components/SelectWrapper/ClearIndicator.js +0 -18
  123. package/admin/src/content-manager/components/SelectWrapper/DropdownIndicator.js +0 -24
  124. package/admin/src/content-manager/components/SelectWrapper/IconBox.js +0 -20
  125. package/admin/src/content-manager/components/SelectWrapper/IndicatorSeparator.js +0 -3
  126. package/admin/src/content-manager/components/SelectWrapper/utils/getSelectStyles.js +0 -92
  127. package/admin/src/pages/MarketplacePage/utils/api.js +0 -9
  128. package/build/2758.9475712b.chunk.js +0 -162
  129. package/build/2912.dd031292.chunk.js +0 -253
  130. package/build/4982.c57c5675.chunk.js +0 -308
  131. package/build/6925.fafef528.chunk.js +0 -761
  132. package/build/7197.47565569.chunk.js +0 -113
  133. package/build/7589.77ef4fbf.chunk.js +0 -194
  134. package/build/7841.9e9cf739.chunk.js +0 -253
  135. package/build/8681.aec05472.chunk.js +0 -163
  136. package/build/9298.cb3b6bc1.chunk.js +0 -334
  137. package/build/948.d64fb515.chunk.js +0 -2
  138. package/build/Admin-authenticatedApp.63a5061a.chunk.js +0 -80
  139. package/build/Admin_homePage.447df176.chunk.js +0 -71
  140. package/build/Admin_marketplace.8a503eec.chunk.js +0 -11
  141. package/build/Admin_pluginsPage.91a96fa5.chunk.js +0 -1
  142. package/build/Admin_settingsPage.0d138832.chunk.js +0 -180
  143. package/build/admin-edit-roles-page.7c2c9752.chunk.js +0 -1
  144. package/build/admin-edit-users.b835bc48.chunk.js +0 -11
  145. package/build/admin-users.19900b75.chunk.js +0 -12
  146. package/build/api-tokens-create-page.8d299dde.chunk.js +0 -1
  147. package/build/codemirror-theme.b3c64617.chunk.js +0 -34
  148. package/build/content-manager.002bfd99.chunk.js +0 -1204
  149. package/build/content-type-builder-translation-pl-json.a866acda.chunk.js +0 -1
  150. package/build/content-type-builder.a0450dfe.chunk.js +0 -141
  151. package/build/email-translation-pl-json.6da50d0f.chunk.js +0 -1
  152. package/build/highlight.js.9d8ef460.chunk.js +0 -86
  153. package/build/i18n-settings-page.06e88cf2.chunk.js +0 -101
  154. package/build/main.e3a13431.js +0 -8404
  155. package/build/pl-json.f65302c2.chunk.js +0 -1
  156. package/build/runtime~main.dacf1aff.js +0 -2
  157. package/build/sso-settings-page.a7c2e854.chunk.js +0 -1
  158. package/build/upload-translation-de-json.b642da08.chunk.js +0 -1
  159. package/build/upload-translation-dk-json.fc61df13.chunk.js +0 -1
  160. package/build/upload-translation-en-json.59269508.chunk.js +0 -1
  161. package/build/upload-translation-es-json.8ec935ef.chunk.js +0 -1
  162. package/build/upload-translation-fr-json.eb9b4f84.chunk.js +0 -1
  163. package/build/upload-translation-he-json.c226f2dc.chunk.js +0 -1
  164. package/build/upload-translation-it-json.8e58456e.chunk.js +0 -1
  165. package/build/upload-translation-ja-json.1378a2e7.chunk.js +0 -1
  166. package/build/upload-translation-ko-json.5e06e112.chunk.js +0 -1
  167. package/build/upload-translation-ms-json.dc3bf0d7.chunk.js +0 -1
  168. package/build/upload-translation-pl-json.6071e38c.chunk.js +0 -1
  169. package/build/upload-translation-pt-BR-json.7e8d9550.chunk.js +0 -1
  170. package/build/upload-translation-ru-json.da2529f3.chunk.js +0 -1
  171. package/build/upload-translation-sk-json.bfdf4f09.chunk.js +0 -1
  172. package/build/upload-translation-th-json.6a48b826.chunk.js +0 -1
  173. package/build/upload-translation-uk-json.6fb09148.chunk.js +0 -1
  174. package/build/upload-translation-zh-json.711f804b.chunk.js +0 -1
  175. package/build/upload.0d4153e8.chunk.js +0 -105
  176. package/build/users-email-settings-page.8b9a266d.chunk.js +0 -1
  177. package/build/users-permissions-translation-en-json.3fe86528.chunk.js +0 -1
  178. package/build/users-permissions-translation-pl-json.3c4fe81c.chunk.js +0 -1
  179. package/build/users-providers-settings-page.fc9d8f9d.chunk.js +0 -1
  180. package/build/zh-Hans-json.c84ce330.chunk.js +0 -1
@@ -0,0 +1,131 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const _ = require('lodash');
5
+ const fs = require('fs-extra');
6
+ const tsUtils = require('@strapi/typescript-utils');
7
+ const getCustomAppConfigFile = require('./get-custom-app-config-file');
8
+
9
+ const getPkgPath = name => path.dirname(require.resolve(`${name}/package.json`));
10
+
11
+ async function createPluginsJs(plugins, dest) {
12
+ const pluginsArray = plugins.map(({ pathToPlugin, name }) => {
13
+ const shortName = _.camelCase(name);
14
+
15
+ /**
16
+ * path.join, on windows, it uses backslashes to resolve path.
17
+ * The problem is that Webpack does not windows paths
18
+ * With this tool, we need to rely on "/" and not "\".
19
+ * This is the reason why '..\\..\\..\\node_modules\\@strapi\\plugin-content-type-builder/strapi-admin.js' was not working.
20
+ * The regexp at line 105 aims to replace the windows backslashes by standard slash so that webpack can deal with them.
21
+ * Backslash looks to work only for absolute paths with webpack => https://webpack.js.org/concepts/module-resolution/#absolute-paths
22
+ */
23
+ const realPath = path
24
+ .join(path.relative(path.resolve(dest, 'admin', 'src'), pathToPlugin), 'strapi-admin.js')
25
+ .replace(/\\/g, '/');
26
+
27
+ return {
28
+ name,
29
+ pathToPlugin: realPath,
30
+ shortName,
31
+ };
32
+ });
33
+
34
+ const content = `
35
+ ${pluginsArray
36
+ .map(({ pathToPlugin, shortName }) => {
37
+ const req = `'${pathToPlugin}'`;
38
+
39
+ return `import ${shortName} from ${req};`;
40
+ })
41
+ .join('\n')}
42
+
43
+
44
+ const plugins = {
45
+ ${[...pluginsArray]
46
+ .map(({ name, shortName }) => {
47
+ return ` '${name}': ${shortName},`;
48
+ })
49
+ .join('\n')}
50
+ };
51
+
52
+ export default plugins;
53
+ `;
54
+
55
+ return fs.writeFile(path.resolve(dest, 'admin', 'src', 'plugins.js'), content);
56
+ }
57
+
58
+ async function copyAdmin(dest) {
59
+ const adminPath = getPkgPath('@strapi/admin');
60
+
61
+ // TODO copy ee folders for plugins
62
+ await fs.copy(path.resolve(adminPath, 'ee', 'admin'), path.resolve(dest, 'ee', 'admin'));
63
+
64
+ await fs.ensureDir(path.resolve(dest, 'config'));
65
+ await fs.copy(path.resolve(adminPath, 'admin'), path.resolve(dest, 'admin'));
66
+
67
+ // Copy package.json
68
+ await fs.copy(path.resolve(adminPath, 'package.json'), path.resolve(dest, 'package.json'));
69
+ }
70
+
71
+ async function createCacheDir({ appDir, plugins }) {
72
+ const cacheDir = path.resolve(appDir, '.cache');
73
+
74
+ const useTypeScript = await tsUtils.isUsingTypeScript(
75
+ path.join(appDir, 'src', 'admin'),
76
+ 'tsconfig.json'
77
+ );
78
+
79
+ const pluginsWithFront = Object.keys(plugins)
80
+ .filter(pluginName => {
81
+ const pluginInfo = plugins[pluginName];
82
+ return fs.existsSync(path.resolve(pluginInfo.pathToPlugin, 'strapi-admin.js'));
83
+ })
84
+ .map(name => ({ name, ...plugins[name] }));
85
+
86
+ // create .cache dir
87
+ await fs.emptyDir(cacheDir);
88
+
89
+ // copy admin core code
90
+ await copyAdmin(cacheDir);
91
+
92
+ // Retrieve the custom config file extension
93
+ const customAdminAppConfigFile = await getCustomAppConfigFile(appDir, useTypeScript);
94
+
95
+ if (customAdminAppConfigFile) {
96
+ const defaultAdminConfigFilePath = path.resolve(cacheDir, 'admin', 'src', 'app.js');
97
+ const customAdminAppConfigFilePath = path.join(
98
+ appDir,
99
+ 'src',
100
+ 'admin',
101
+ customAdminAppConfigFile
102
+ );
103
+ const dest = path.resolve(cacheDir, 'admin', 'src', customAdminAppConfigFile);
104
+
105
+ if (useTypeScript) {
106
+ // Remove the default config file
107
+ await fs.remove(defaultAdminConfigFilePath);
108
+ // Copy the custom one
109
+ await fs.copy(customAdminAppConfigFilePath, dest);
110
+ } else {
111
+ await fs.copy(customAdminAppConfigFilePath, dest);
112
+ }
113
+ }
114
+
115
+ // Copy admin extensions folder
116
+ const adminExtensionFolder = path.join(appDir, 'src', 'admin', 'extensions');
117
+
118
+ if (fs.existsSync(adminExtensionFolder)) {
119
+ await fs.copy(adminExtensionFolder, path.resolve(cacheDir, 'admin', 'src', 'extensions'));
120
+ }
121
+
122
+ // create plugins.js with plugins requires
123
+ await createPluginsJs(pluginsWithFront, cacheDir);
124
+
125
+ // create the tsconfig.json file so we can develop plugins in ts while being in a JS project
126
+ if (!useTypeScript) {
127
+ await tsUtils.admin.createTSConfigFile(cacheDir);
128
+ }
129
+ }
130
+
131
+ module.exports = createCacheDir;
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ const { join } = require('path');
4
+ const fse = require('fs-extra');
5
+ const { isUsingTypeScript } = require('@strapi/typescript-utils');
6
+
7
+ /**
8
+ * Retrieve the custom admin entry file name
9
+ * @param {String} dir - Directory of the admin panel
10
+ * @returns String
11
+ */
12
+ const getCustomAppConfigFile = async dir => {
13
+ const adminSrcPath = join(dir, 'src', 'admin');
14
+ const useTypeScript = await isUsingTypeScript(adminSrcPath, 'tsconfig.json');
15
+
16
+ const files = await fse.readdir(adminSrcPath);
17
+
18
+ const appJsx = files.find(file => /^app.jsx?$/.test(file));
19
+ const appTsx = files.find(file => /^app.tsx?$/.test(file));
20
+
21
+ if (useTypeScript) {
22
+ return appTsx || appJsx;
23
+ }
24
+
25
+ return appJsx;
26
+ };
27
+
28
+ module.exports = getCustomAppConfigFile;
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const chalk = require('chalk');
5
+ const _ = require('lodash');
6
+ const webpack = require('webpack');
7
+ const fs = require('fs-extra');
8
+ const getWebpackConfig = require('../webpack.config');
9
+
10
+ const getCustomWebpackConfig = (dir, config) => {
11
+ const adminConfigPath = path.join(dir, 'src', 'admin', 'webpack.config.js');
12
+
13
+ let webpackConfig = getWebpackConfig(config);
14
+
15
+ if (fs.existsSync(adminConfigPath)) {
16
+ const webpackAdminConfig = require(path.resolve(adminConfigPath));
17
+
18
+ if (_.isFunction(webpackAdminConfig)) {
19
+ // Expose the devServer configuration
20
+ if (config.devServer) {
21
+ webpackConfig.devServer = config.devServer;
22
+ }
23
+
24
+ webpackConfig = webpackAdminConfig(webpackConfig, webpack);
25
+
26
+ if (!webpackConfig) {
27
+ console.error(
28
+ `${chalk.red('Error:')} Nothing was returned from your custom webpack configuration`
29
+ );
30
+ process.exit(1);
31
+ }
32
+ }
33
+ }
34
+
35
+ return webpackConfig;
36
+ };
37
+
38
+ module.exports = getCustomWebpackConfig;
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ const { join, resolve } = require('path');
4
+ const fs = require('fs-extra');
5
+ const glob = require('glob');
6
+
7
+ // Only for dev environement
8
+ const getPluginsPath = () => {
9
+ const rootPath = resolve(__dirname, '..', join('..', '..', '..', 'packages'));
10
+ const corePath = join(rootPath, 'core', '*');
11
+ const pluginsPath = join(rootPath, 'plugins', '*');
12
+ const corePackageDirs = glob.sync(corePath);
13
+ const pluginsPackageDirs = glob.sync(pluginsPath);
14
+
15
+ const packageDirs = [...corePackageDirs, ...pluginsPackageDirs].filter(dir => {
16
+ const isCoreAdmin = dir.includes('packages/core/admin');
17
+ const pathToEntryPoint = join(dir, 'admin', 'src', 'index.js');
18
+ const doesAdminFolderExist = fs.pathExistsSync(pathToEntryPoint);
19
+
20
+ return !isCoreAdmin && doesAdminFolderExist;
21
+ });
22
+
23
+ return packageDirs.map(dir => resolve(__dirname, '..', join(dir, 'admin', 'src')));
24
+ };
25
+
26
+ module.exports = getPluginsPath;
package/utils/index.js ADDED
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const createCacheDir = require('./create-cache-dir');
4
+ const getCustomWebpackConfig = require('./get-custom-webpack-config');
5
+ const shouldBuildAdmin = require('./should-build-admin');
6
+ const watchAdminFiles = require('./watch-admin-files');
7
+
8
+ module.exports = {
9
+ createCacheDir,
10
+ getCustomWebpackConfig,
11
+ shouldBuildAdmin,
12
+ watchAdminFiles,
13
+ };
@@ -0,0 +1,52 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const fs = require('fs-extra');
5
+ const getCustomAppConfigFile = require('./get-custom-app-config-file');
6
+
7
+ const DEFAULT_PLUGINS = [
8
+ 'content-type-builder',
9
+ 'content-manager',
10
+ 'upload',
11
+ 'email',
12
+ 'i18n',
13
+ 'users-permissions',
14
+ ];
15
+
16
+ /**
17
+ * Checks if the project's installed plugins are not the same as a default one.
18
+ * @param {Object} plugins
19
+ * @returns {boolean}
20
+ */
21
+ const hasNonDefaultPlugins = plugins => {
22
+ // List of plugins that are not the ones installed in a generated app
23
+ const installedPlugins = Object.keys(plugins).filter(x => !DEFAULT_PLUGINS.includes(x));
24
+
25
+ // List of default plugins uninstalled from a generated app
26
+ const missingPlugins = DEFAULT_PLUGINS.filter(x => !Object.keys(plugins).includes(x));
27
+
28
+ const diff = [...installedPlugins, ...missingPlugins];
29
+
30
+ return diff.length > 0;
31
+ };
32
+
33
+ const hasCustomAdminCode = async dir => {
34
+ const customAdminPath = path.join(dir, 'src', 'admin');
35
+
36
+ const customAdminAppConfigFile = await getCustomAppConfigFile(dir);
37
+ const customAdminWebpackFile = path.join(customAdminPath, 'webpack.config.js');
38
+
39
+ const hasCustomConfigFile = !!customAdminAppConfigFile;
40
+ const hasCustomWebpackFile = await fs.pathExists(customAdminWebpackFile);
41
+
42
+ return hasCustomConfigFile || hasCustomWebpackFile;
43
+ };
44
+
45
+ const shouldBuildAdmin = async ({ appDir, plugins }) => {
46
+ const appHasCustomAdminCode = await hasCustomAdminCode(appDir);
47
+ const appHasNonDefaultPlugins = hasNonDefaultPlugins(plugins);
48
+
49
+ return appHasCustomAdminCode || appHasNonDefaultPlugins;
50
+ };
51
+
52
+ module.exports = shouldBuildAdmin;
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const fs = require('fs-extra');
5
+ const chokidar = require('chokidar');
6
+ const { isUsingTypeScript } = require('@strapi/typescript-utils');
7
+
8
+ /**
9
+ * Listen to files change and copy the changed files in the .cache/admin folder
10
+ * when using the dev mode
11
+ * @param {string} dir
12
+ */
13
+ async function watchAdminFiles(dir) {
14
+ const useTypeScript = await isUsingTypeScript(path.join(dir, 'src', 'admin'), 'tsconfig.json');
15
+
16
+ const cacheDir = path.join(dir, '.cache');
17
+ const targetExtensionFile = useTypeScript ? 'app.tsx' : 'app.js';
18
+ const appExtensionFile = path.join(dir, 'src', 'admin', targetExtensionFile);
19
+ const extensionsPath = path.join(dir, 'src', 'admin', 'extensions');
20
+
21
+ // Only watch the admin/app.js file and the files that are in the ./admin/extensions/folder
22
+ const filesToWatch = [appExtensionFile, extensionsPath];
23
+
24
+ const watcher = chokidar.watch(filesToWatch, {
25
+ ignoreInitial: true,
26
+ ignorePermissionErrors: true,
27
+ });
28
+
29
+ watcher.on('all', async (event, filePath) => {
30
+ const isAppFile = filePath.includes(appExtensionFile);
31
+
32
+ // The app.js file needs to be copied in the .cache/admin/src/app.js and the other ones needs to
33
+ // be copied in the .cache/admin/src/extensions folder
34
+ const targetPath = isAppFile
35
+ ? path.join(path.normalize(filePath.split(appExtensionFile)[1]), targetExtensionFile)
36
+ : path.join('extensions', path.normalize(filePath.split(extensionsPath)[1]));
37
+
38
+ const destFolder = path.join(cacheDir, 'admin', 'src');
39
+
40
+ if (event === 'unlink' || event === 'unlinkDir') {
41
+ // Remove the file or folder
42
+ // We need to copy the original files when deleting an override one
43
+ try {
44
+ fs.removeSync(path.join(destFolder, targetPath));
45
+ } catch (err) {
46
+ console.log('An error occured while deleting the file', err);
47
+ }
48
+ } else {
49
+ // In any other case just copy the file into the .cache/admin/src folder
50
+ try {
51
+ await fs.copy(filePath, path.join(destFolder, targetPath));
52
+ } catch (err) {
53
+ console.log(err);
54
+ }
55
+ }
56
+ });
57
+ }
58
+
59
+ module.exports = watchAdminFiles;
package/webpack.config.js CHANGED
@@ -4,22 +4,25 @@ const path = require('path');
4
4
  const fse = require('fs-extra');
5
5
  const webpack = require('webpack');
6
6
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
7
+ const ForkTsCheckerPlugin = require('fork-ts-checker-webpack-plugin');
7
8
  const HtmlWebpackPlugin = require('html-webpack-plugin');
8
9
  const { ESBuildMinifyPlugin } = require('esbuild-loader');
9
10
  const WebpackBar = require('webpackbar');
10
11
  const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
12
+ const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
13
+
11
14
  const alias = require('./webpack.alias');
12
15
  const getClientEnvironment = require('./env');
13
16
 
14
17
  const EE_REGEX = /from.* ['"]ee_else_ce\//;
15
18
 
16
19
  module.exports = ({
17
- entry,
18
20
  cacheDir,
19
- pluginsPath,
20
21
  dest,
22
+ entry,
21
23
  env,
22
24
  optimize,
25
+ pluginsPath,
23
26
  options = {
24
27
  backend: 'http://localhost:1337',
25
28
  adminPath: '/admin/',
@@ -29,6 +32,7 @@ module.exports = ({
29
32
  eeRoot: './ee/admin',
30
33
  ceRoot: './admin/src',
31
34
  },
35
+ tsConfigFilePath,
32
36
  }) => {
33
37
  const isProduction = env === 'production';
34
38
 
@@ -49,6 +53,9 @@ module.exports = ({
49
53
  ]
50
54
  : [];
51
55
 
56
+ // Directly inject a polyfill in the webpack entry point before the entry point
57
+ // FIXME: I have noticed a bug regarding the helper-plugin and esbuild-loader
58
+ // The only I could fix it was to inject the babel polyfill
52
59
  const babelPolyfill = '@babel/polyfill/dist/polyfill.min.js';
53
60
 
54
61
  return {
@@ -79,6 +86,16 @@ module.exports = ({
79
86
  },
80
87
  module: {
81
88
  rules: [
89
+ {
90
+ test: /\.tsx?$/,
91
+ loader: require.resolve('esbuild-loader'),
92
+ include: [cacheDir, ...pluginsPath],
93
+ exclude: /node_modules/,
94
+ options: {
95
+ loader: 'tsx',
96
+ target: 'es2015',
97
+ },
98
+ },
82
99
  {
83
100
  test: /\.m?jsx?$/,
84
101
  include: cacheDir,
@@ -94,6 +111,10 @@ module.exports = ({
94
111
  try {
95
112
  const fileContent = fse.readFileSync(filePath).toString();
96
113
 
114
+ if (fileContent.match(/from.* ['"]ee_else_ce\//)) {
115
+ return true;
116
+ }
117
+
97
118
  return EE_REGEX.test(fileContent);
98
119
  } catch (e) {
99
120
  return false;
@@ -190,7 +211,7 @@ module.exports = ({
190
211
  resolve: {
191
212
  alias,
192
213
  symlinks: false,
193
- extensions: ['.js', '.jsx', '.react.js'],
214
+ extensions: ['.js', '.jsx', '.react.js', '.ts', '.tsx'],
194
215
  mainFields: ['browser', 'jsnext:main', 'main'],
195
216
  modules: ['node_modules', path.resolve(__dirname, 'node_modules')],
196
217
  },
@@ -198,13 +219,20 @@ module.exports = ({
198
219
  new HtmlWebpackPlugin({
199
220
  inject: true,
200
221
  template: path.resolve(__dirname, 'index.html'),
201
- // FIXME
202
- // favicon: path.resolve(__dirname, 'admin/src/favicon.ico'),
203
222
  }),
204
223
  new webpack.DefinePlugin(envVariables),
205
224
 
206
225
  new NodePolyfillPlugin(),
226
+
227
+ new ForkTsCheckerPlugin({
228
+ typescript: {
229
+ configFile: tsConfigFilePath,
230
+ },
231
+ }),
232
+
233
+ !isProduction && process.env.REACT_REFRESH !== 'false' && new ReactRefreshWebpackPlugin(),
234
+
207
235
  ...webpackPlugins,
208
- ],
236
+ ].filter(Boolean),
209
237
  };
210
238
  };
@@ -1,18 +0,0 @@
1
- import React from 'react';
2
- import { components } from 'react-select';
3
- import Cross from '@strapi/icons/Cross';
4
- import IconBox from './IconBox';
5
-
6
- const ClearIndicator = props => {
7
- const Component = components.ClearIndicator;
8
-
9
- return (
10
- <Component {...props}>
11
- <IconBox as="button" type="button">
12
- <Cross />
13
- </IconBox>
14
- </Component>
15
- );
16
- };
17
-
18
- export default ClearIndicator;
@@ -1,24 +0,0 @@
1
- import React from 'react';
2
- import styled from 'styled-components';
3
- import CarretDown from '@strapi/icons/CarretDown';
4
- import IconBox from './IconBox';
5
-
6
- export const CarretBox = styled(IconBox)`
7
- display: flex;
8
- background: none;
9
- border: none;
10
-
11
- svg {
12
- width: ${6 / 16}rem;
13
- }
14
- `;
15
-
16
- const DropdownIndicator = () => {
17
- return (
18
- <CarretBox as="button" type="button" paddingRight={3}>
19
- <CarretDown />
20
- </CarretBox>
21
- );
22
- };
23
-
24
- export default DropdownIndicator;
@@ -1,20 +0,0 @@
1
- import styled from 'styled-components';
2
- import { Box } from '@strapi/design-system/Box';
3
-
4
- export const IconBox = styled(Box)`
5
- background: transparent;
6
- border: none;
7
- position: relative;
8
- z-index: 1;
9
-
10
- svg {
11
- height: ${11 / 16}rem;
12
- width: ${11 / 16}rem;
13
- }
14
-
15
- svg path {
16
- fill: ${({ theme }) => theme.colors.neutral600};
17
- }
18
- `;
19
-
20
- export default IconBox;
@@ -1,3 +0,0 @@
1
- const IndicatorSeparator = () => null;
2
-
3
- export default IndicatorSeparator;
@@ -1,92 +0,0 @@
1
- const getSelectStyles = theme => {
2
- return {
3
- clearIndicator: base => ({ ...base, padding: 0, paddingRight: theme.spaces[3] }),
4
- container: base => ({
5
- ...base,
6
- background: theme.colors.neutral0,
7
- fontFamily: 'Arial',
8
- lineHeight: 'normal',
9
- }),
10
- control: (base, state) => {
11
- let border;
12
- let borderBottom;
13
- let backgroundColor;
14
-
15
- if (state.isFocused) {
16
- border = `1px solid ${theme.colors.primary600} !important`;
17
- } else {
18
- border = `1px solid ${theme.colors.neutral200} !important`;
19
- }
20
-
21
- if (state.menuIsOpen === true) {
22
- borderBottom = `1px solid ${theme.colors.primary600} !important`;
23
- }
24
-
25
- if (state.isDisabled) {
26
- backgroundColor = '#fafafb !important';
27
- }
28
-
29
- return {
30
- ...base,
31
- fontSize: 14,
32
- height: 40,
33
- border,
34
- outline: 0,
35
- boxShadow: 0,
36
- borderRadius: '2px !important',
37
- borderBottom,
38
- backgroundColor,
39
- borderTopLeftRadius: '4px !important',
40
- borderTopRightRadius: '4px !important',
41
- borderBottomLeftRadius: '4px !important',
42
- borderBottomRightRadius: '4px !important',
43
- };
44
- },
45
- indicatorContainer: base => ({ ...base, padding: 0, paddingRight: theme.spaces[3] }),
46
- input: base => ({ ...base, margin: 0, padding: 0, color: theme.colors.neutral800 }),
47
- menu: base => {
48
- return {
49
- ...base,
50
- width: '100%',
51
- marginTop: theme.spaces[1],
52
- backgroundColor: theme.colors.neutral0,
53
- color: theme.colors.neutral800,
54
- borderRadius: '4px !important',
55
- borderTopLeftRadius: '4px !important',
56
- borderTopRightRadius: '4px !important',
57
- border: `1px solid ${theme.colors.neutral200} !important`,
58
- boxShadow: 0,
59
- fontSize: '14px',
60
- fontFamily: 'Arial',
61
- zIndex: 2,
62
- };
63
- },
64
- menuList: base => ({
65
- ...base,
66
- paddingLeft: theme.spaces[1],
67
- paddingTop: theme.spaces[1],
68
- paddingRight: theme.spaces[1],
69
- paddingBottom: theme.spaces[1],
70
- }),
71
- option: (base, state) => {
72
- let backgroundColor = base.backgroundColor;
73
-
74
- if (state.isFocused) {
75
- backgroundColor = theme.colors.primary100;
76
- }
77
-
78
- return { ...base, lineHeight: theme.spaces[5], backgroundColor, borderRadius: 4 };
79
- },
80
- placeholder: base => ({ ...base, marginLeft: 0 }),
81
- singleValue: base => ({ ...base, marginLeft: 0, color: theme.colors.neutral800 }),
82
- valueContainer: base => ({
83
- ...base,
84
- padding: 0,
85
- paddingLeft: theme.spaces[4],
86
- marginLeft: 0,
87
- marginRight: 0,
88
- }),
89
- };
90
- };
91
-
92
- export default getSelectStyles;
@@ -1,9 +0,0 @@
1
- import { axiosInstance } from '../../../core/utils';
2
-
3
- const fetchAppInformation = async () => {
4
- const { data } = await axiosInstance.get('/admin/information');
5
-
6
- return data;
7
- };
8
-
9
- export { fetchAppInformation };