@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
package/index.js CHANGED
@@ -1,66 +1,34 @@
1
1
  'use strict';
2
2
 
3
3
  const path = require('path');
4
- const _ = require('lodash');
5
4
  const fs = require('fs-extra');
6
5
  const webpack = require('webpack');
7
6
  const WebpackDevServer = require('webpack-dev-server');
7
+ const { isUsingTypeScript } = require('@strapi/typescript-utils');
8
8
  const chalk = require('chalk');
9
- const chokidar = require('chokidar');
10
- const getWebpackConfig = require('./webpack.config');
11
9
 
12
- const getPkgPath = name => path.dirname(require.resolve(`${name}/package.json`));
10
+ const {
11
+ createCacheDir,
12
+ getCustomWebpackConfig,
13
+ shouldBuildAdmin,
14
+ watchAdminFiles,
15
+ } = require('./utils');
13
16
 
14
- const DEFAULT_PLUGINS = [
15
- 'content-type-builder',
16
- 'content-manager',
17
- 'upload',
18
- 'email',
19
- 'i18n',
20
- 'users-permissions',
21
- ];
17
+ async function build({ appDir, buildDestDir, env, forceBuild, optimize, options, plugins }) {
18
+ const buildAdmin = await shouldBuildAdmin({ appDir, plugins });
22
19
 
23
- function getCustomWebpackConfig(dir, config) {
24
- const adminConfigPath = path.join(dir, 'src', 'admin', 'webpack.config.js');
25
-
26
- let webpackConfig = getWebpackConfig(config);
27
-
28
- if (fs.existsSync(adminConfigPath)) {
29
- const webpackAdminConfig = require(path.resolve(adminConfigPath));
30
-
31
- if (_.isFunction(webpackAdminConfig)) {
32
- // Expose the devServer configuration
33
- if (config.devServer) {
34
- webpackConfig.devServer = config.devServer;
35
- }
36
-
37
- webpackConfig = webpackAdminConfig(webpackConfig, webpack);
38
-
39
- if (!webpackConfig) {
40
- console.error(
41
- `${chalk.red('Error:')} Nothing was returned from your custom webpack configuration`
42
- );
43
- process.exit(1);
44
- }
45
- }
46
- }
47
-
48
- return webpackConfig;
49
- }
50
-
51
- async function build({ plugins, dir, env, options, optimize, forceBuild }) {
52
- const buildAdmin = await shouldBuildAdmin({ dir, plugins });
20
+ const useTypeScript = await isUsingTypeScript(path.join(appDir, 'src', 'admin'), 'tsconfig.json');
53
21
 
54
22
  if (!buildAdmin && !forceBuild) {
55
23
  return;
56
24
  }
57
25
 
58
26
  // Create the cache dir containing the front-end files.
59
- await createCacheDir({ dir, plugins });
27
+ await createCacheDir({ appDir, plugins });
60
28
 
61
- const cacheDir = path.resolve(dir, '.cache');
29
+ const cacheDir = path.resolve(appDir, '.cache');
62
30
  const entry = path.resolve(cacheDir, 'admin', 'src');
63
- const dest = path.resolve(dir, 'build');
31
+ const dest = path.resolve(buildDestDir, 'build');
64
32
 
65
33
  // Roots for the @strapi/babel-plugin-switch-ee-ce
66
34
  const roots = {
@@ -70,15 +38,23 @@ async function build({ plugins, dir, env, options, optimize, forceBuild }) {
70
38
 
71
39
  const pluginsPath = Object.keys(plugins).map(pluginName => plugins[pluginName].pathToPlugin);
72
40
 
73
- const config = getCustomWebpackConfig(dir, {
74
- entry,
75
- pluginsPath,
41
+ // Either use the tsconfig file from the generated app or the one inside the .cache folder
42
+ // so we can develop plugins in TS while being in a JS app
43
+ const tsConfigFilePath = useTypeScript
44
+ ? path.join(appDir, 'src', 'admin', 'tsconfig.json')
45
+ : path.resolve(entry, 'tsconfig.json');
46
+
47
+ const config = getCustomWebpackConfig(appDir, {
48
+ appDir,
76
49
  cacheDir,
77
50
  dest,
51
+ entry,
78
52
  env,
79
- options,
80
53
  optimize,
54
+ options,
55
+ pluginsPath,
81
56
  roots,
57
+ tsConfigFilePath,
82
58
  });
83
59
 
84
60
  const compiler = webpack(config);
@@ -109,115 +85,24 @@ async function build({ plugins, dir, env, options, optimize, forceBuild }) {
109
85
  });
110
86
  }
111
87
 
112
- async function createPluginsJs(plugins, dest) {
113
- const pluginsArray = plugins.map(({ pathToPlugin, name }) => {
114
- const shortName = _.camelCase(name);
115
-
116
- /**
117
- * path.join, on windows, it uses backslashes to resolve path.
118
- * The problem is that Webpack does not windows paths
119
- * With this tool, we need to rely on "/" and not "\".
120
- * This is the reason why '..\\..\\..\\node_modules\\@strapi\\plugin-content-type-builder/strapi-admin.js' was not working.
121
- * The regexp at line 105 aims to replace the windows backslashes by standard slash so that webpack can deal with them.
122
- * Backslash looks to work only for absolute paths with webpack => https://webpack.js.org/concepts/module-resolution/#absolute-paths
123
- */
124
- const realPath = path
125
- .join(path.relative(path.resolve(dest, 'admin', 'src'), pathToPlugin), 'strapi-admin.js')
126
- .replace(/\\/g, '/');
127
-
128
- return {
129
- name,
130
- pathToPlugin: realPath,
131
- shortName,
132
- };
133
- });
134
-
135
- const content = `
136
- ${pluginsArray
137
- .map(({ pathToPlugin, shortName }) => {
138
- const req = `'${pathToPlugin}'`;
139
-
140
- return `import ${shortName} from ${req};`;
141
- })
142
- .join('\n')}
143
-
144
-
145
- const plugins = {
146
- ${[...pluginsArray]
147
- .map(({ name, shortName }) => {
148
- return ` '${name}': ${shortName},`;
149
- })
150
- .join('\n')}
151
- };
152
-
153
- export default plugins;
154
- `;
155
-
156
- return fs.writeFile(path.resolve(dest, 'admin', 'src', 'plugins.js'), content);
157
- }
158
-
159
- async function clean({ dir }) {
160
- const buildDir = path.join(dir, 'build');
161
- const cacheDir = path.join(dir, '.cache');
88
+ async function clean({ appDir, buildDestDir }) {
89
+ // FIXME rename admin build dir and path to build dir
90
+ const buildDir = path.join(buildDestDir, 'build');
91
+ // .cache dir is always located at the root of the app
92
+ const cacheDir = path.join(appDir, '.cache');
162
93
 
163
94
  fs.removeSync(buildDir);
164
95
  fs.removeSync(cacheDir);
165
96
  }
166
97
 
167
- async function copyAdmin(dest) {
168
- const adminPath = getPkgPath('@strapi/admin');
169
-
170
- // TODO copy ee folders for plugins
171
- await fs.copy(path.resolve(adminPath, 'ee', 'admin'), path.resolve(dest, 'ee', 'admin'));
172
-
173
- await fs.ensureDir(path.resolve(dest, 'config'));
174
- await fs.copy(path.resolve(adminPath, 'admin'), path.resolve(dest, 'admin'));
175
-
176
- // Copy package.json
177
- await fs.copy(path.resolve(adminPath, 'package.json'), path.resolve(dest, 'package.json'));
178
- }
179
-
180
- async function createCacheDir({ dir, plugins }) {
181
- const cacheDir = path.resolve(dir, '.cache');
182
-
183
- const pluginsWithFront = Object.keys(plugins)
184
- .filter(pluginName => {
185
- const pluginInfo = plugins[pluginName];
186
- return fs.existsSync(path.resolve(pluginInfo.pathToPlugin, 'strapi-admin.js'));
187
- })
188
- .map(name => ({ name, ...plugins[name] }));
189
-
190
- // create .cache dir
191
- await fs.emptyDir(cacheDir);
192
-
193
- // copy admin core code
194
- await copyAdmin(cacheDir);
195
-
196
- // Copy app.js
197
- const customAdminConfigFilePath = path.join(dir, 'src', 'admin', 'app.js');
198
-
199
- if (fs.existsSync(customAdminConfigFilePath)) {
200
- await fs.copy(customAdminConfigFilePath, path.resolve(cacheDir, 'admin', 'src', 'app.js'));
201
- }
202
-
203
- // Copy admin extensions folder
204
- const adminExtensionFolder = path.join(dir, 'src', 'admin', 'extensions');
205
-
206
- if (fs.existsSync(adminExtensionFolder)) {
207
- await fs.copy(adminExtensionFolder, path.resolve(cacheDir, 'admin', 'src', 'extensions'));
208
- }
209
-
210
- // create plugins.js with plugins requires
211
- await createPluginsJs(pluginsWithFront, cacheDir);
212
- }
213
-
214
- async function watchAdmin({ plugins, dir, host, port, browser, options }) {
98
+ async function watchAdmin({ appDir, browser, buildDestDir, host, options, plugins, port }) {
99
+ const useTypeScript = await isUsingTypeScript(path.join(appDir, 'src', 'admin'), 'tsconfig.json');
215
100
  // Create the cache dir containing the front-end files.
216
- const cacheDir = path.join(dir, '.cache');
217
- await createCacheDir({ dir, plugins });
101
+ const cacheDir = path.join(appDir, '.cache');
102
+ await createCacheDir({ appDir, plugins });
218
103
 
219
104
  const entry = path.join(cacheDir, 'admin', 'src');
220
- const dest = path.join(dir, 'build');
105
+ const dest = path.join(buildDestDir, 'build');
221
106
  const env = 'development';
222
107
 
223
108
  // Roots for the @strapi/babel-plugin-switch-ee-ce
@@ -228,14 +113,20 @@ async function watchAdmin({ plugins, dir, host, port, browser, options }) {
228
113
 
229
114
  const pluginsPath = Object.keys(plugins).map(pluginName => plugins[pluginName].pathToPlugin);
230
115
 
116
+ // Either use the tsconfig file from the generated app or the one inside the .cache folder
117
+ // so we can develop plugins in TS while being in a JS app
118
+ const tsConfigFilePath = useTypeScript
119
+ ? path.join(appDir, 'src', 'admin', 'tsconfig.json')
120
+ : path.resolve(entry, 'tsconfig.json');
121
+
231
122
  const args = {
232
- entry,
123
+ appDir,
233
124
  cacheDir,
234
- pluginsPath,
235
125
  dest,
126
+ entry,
236
127
  env,
237
- port,
238
128
  options,
129
+ pluginsPath,
239
130
  roots,
240
131
  devServer: {
241
132
  port,
@@ -246,7 +137,6 @@ async function watchAdmin({ plugins, dir, host, port, browser, options }) {
246
137
  warnings: false,
247
138
  },
248
139
  },
249
-
250
140
  open: browser === 'true' ? true : browser,
251
141
  devMiddleware: {
252
142
  publicPath: options.adminPath,
@@ -256,9 +146,10 @@ async function watchAdmin({ plugins, dir, host, port, browser, options }) {
256
146
  disableDotRule: true,
257
147
  },
258
148
  },
149
+ tsConfigFilePath,
259
150
  };
260
151
 
261
- const webpackConfig = getCustomWebpackConfig(dir, args);
152
+ const webpackConfig = getCustomWebpackConfig(appDir, args);
262
153
 
263
154
  const compiler = webpack(webpackConfig);
264
155
 
@@ -279,90 +170,7 @@ async function watchAdmin({ plugins, dir, host, port, browser, options }) {
279
170
 
280
171
  runServer();
281
172
 
282
- watchFiles(dir);
283
- }
284
-
285
- /**
286
- * Listen to files change and copy the changed files in the .cache/admin folder
287
- * when using the dev mode
288
- * @param {string} dir
289
- */
290
- async function watchFiles(dir) {
291
- const cacheDir = path.join(dir, '.cache');
292
- const appExtensionFile = path.join(dir, 'src', 'admin', 'app.js');
293
- const extensionsPath = path.join(dir, 'src', 'admin', 'extensions');
294
-
295
- // Only watch the admin/app.js file and the files that are in the ./admin/extensions/folder
296
- const filesToWatch = [appExtensionFile, extensionsPath];
297
-
298
- const watcher = chokidar.watch(filesToWatch, {
299
- ignoreInitial: true,
300
- ignorePermissionErrors: true,
301
- });
302
-
303
- watcher.on('all', async (event, filePath) => {
304
- const isAppFile = filePath.includes(appExtensionFile);
305
-
306
- // The app.js file needs to be copied in the .cache/admin/src/app.js and the other ones needs to
307
- // be copied in the .cache/admin/src/extensions folder
308
- const targetPath = isAppFile
309
- ? path.join(path.normalize(filePath.split(appExtensionFile)[1]), 'app.js')
310
- : path.join('extensions', path.normalize(filePath.split(extensionsPath)[1]));
311
-
312
- const destFolder = path.join(cacheDir, 'admin', 'src');
313
-
314
- if (event === 'unlink' || event === 'unlinkDir') {
315
- // Remove the file or folder
316
- // We need to copy the original files when deleting an override one
317
- try {
318
- fs.removeSync(path.join(destFolder, targetPath));
319
- } catch (err) {
320
- console.log('An error occured while deleting the file', err);
321
- }
322
- } else {
323
- // In any other case just copy the file into the .cache/admin/src folder
324
- try {
325
- await fs.copy(filePath, path.join(destFolder, targetPath));
326
- } catch (err) {
327
- console.log(err);
328
- }
329
- }
330
- });
331
- }
332
-
333
- const hasCustomAdminCode = async dir => {
334
- const customAdminPath = path.join(dir, 'src', 'admin');
335
- const customAdminConfigFile = path.join(customAdminPath, 'app.js');
336
- const customAdminWebpackFile = path.join(customAdminPath, 'webpack.config.js');
337
-
338
- const hasCustomConfigFile = await fs.pathExists(customAdminConfigFile);
339
- const hasCustomWebpackFile = await fs.pathExists(customAdminWebpackFile);
340
-
341
- return hasCustomConfigFile || hasCustomWebpackFile;
342
- };
343
-
344
- /**
345
- * Checks if the project's installed plugins are not the same as a default one.
346
- * @param {Object} plugins
347
- * @returns {boolean}
348
- */
349
- const hasNonDefaultPlugins = plugins => {
350
- // List of plugins that are not the ones installed in a generated app
351
- const installedPlugins = Object.keys(plugins).filter(x => !DEFAULT_PLUGINS.includes(x));
352
-
353
- // List of default plugins uninstalled from a generated app
354
- const missingPlugins = DEFAULT_PLUGINS.filter(x => !Object.keys(plugins).includes(x));
355
-
356
- const diff = [...installedPlugins, ...missingPlugins];
357
-
358
- return diff.length > 0;
359
- };
360
-
361
- async function shouldBuildAdmin({ dir, plugins }) {
362
- const appHasCustomAdminCode = await hasCustomAdminCode(dir);
363
- const appHasNonDefaultPlugins = hasNonDefaultPlugins(plugins);
364
-
365
- return appHasCustomAdminCode || appHasNonDefaultPlugins;
173
+ watchAdminFiles(appDir, useTypeScript);
366
174
  }
367
175
 
368
176
  module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/admin",
3
- "version": "4.2.1-alpha.0",
3
+ "version": "4.3.0-beta.2",
4
4
  "description": "Strapi Admin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,6 +28,7 @@
28
28
  "develop:webpack": "cross-env NODE_ENV=development webpack serve --config webpack.config.dev.js --progress profile",
29
29
  "prepublishOnly": "yarn build",
30
30
  "build": "rimraf build && node ./scripts/build.js",
31
+ "build:mesure": "rimraf build && cross-env MESURE_BUILD_SPEED=true node ./scripts/build.js",
31
32
  "test": "echo \"no tests yet\"",
32
33
  "test:unit": "jest --verbose",
33
34
  "test:front": "cross-env IS_EE=true jest --config ./jest.config.front.js",
@@ -40,7 +41,7 @@
40
41
  "@babel/plugin-transform-runtime": "7.16.7",
41
42
  "@babel/polyfill": "7.12.1",
42
43
  "@babel/preset-env": "7.16.7",
43
- "@babel/preset-react": "7.16.7",
44
+ "@babel/preset-react": "7.18.6",
44
45
  "@babel/runtime": "7.16.7",
45
46
  "@casl/ability": "^5.4.3",
46
47
  "@fingerprintjs/fingerprintjs": "3.3.2",
@@ -48,27 +49,30 @@
48
49
  "@fortawesome/fontawesome-svg-core": "^1.2.35",
49
50
  "@fortawesome/free-brands-svg-icons": "^5.15.3",
50
51
  "@fortawesome/free-solid-svg-icons": "^5.15.3",
51
- "@fortawesome/react-fontawesome": "^0.1.14",
52
- "@strapi/babel-plugin-switch-ee-ce": "4.2.1-alpha.0",
53
- "@strapi/design-system": "1.1.1",
54
- "@strapi/helper-plugin": "4.2.1-alpha.0",
55
- "@strapi/icons": "1.1.1",
56
- "@strapi/utils": "4.2.1-alpha.0",
52
+ "@fortawesome/react-fontawesome": "^0.2.0",
53
+ "@pmmmwh/react-refresh-webpack-plugin": "0.5.7",
54
+ "@strapi/babel-plugin-switch-ee-ce": "4.3.0-beta.2",
55
+ "@strapi/design-system": "1.2.0",
56
+ "@strapi/helper-plugin": "4.3.0-beta.2",
57
+ "@strapi/icons": "1.2.0",
58
+ "@strapi/typescript-utils": "4.3.0-beta.2",
59
+ "@strapi/utils": "4.3.0-beta.2",
57
60
  "axios": "0.24.0",
58
- "babel-loader": "8.2.3",
61
+ "babel-loader": "8.2.5",
59
62
  "babel-plugin-styled-components": "2.0.2",
60
63
  "bcryptjs": "2.4.3",
61
64
  "chalk": "^4.1.1",
62
65
  "chokidar": "^3.5.1",
63
- "codemirror": "^5.61.0",
66
+ "codemirror": "^5.65.6",
64
67
  "cross-env": "^7.0.3",
65
68
  "css-loader": "6.5.1",
66
- "date-fns": "2.22.1",
69
+ "date-fns": "2.28.0",
67
70
  "dotenv": "8.5.1",
68
- "esbuild-loader": "2.18.0",
71
+ "esbuild-loader": "^2.19.0",
69
72
  "execa": "^1.0.0",
70
73
  "fast-deep-equal": "3.1.3",
71
74
  "font-awesome": "^4.7.0",
75
+ "fork-ts-checker-webpack-plugin": "7.2.1",
72
76
  "formik": "^2.2.6",
73
77
  "fs-extra": "10.0.0",
74
78
  "highlight.js": "^10.4.1",
@@ -96,14 +100,14 @@
96
100
  "markdown-it-sup": "1.0.0",
97
101
  "match-sorter": "^4.0.2",
98
102
  "mini-css-extract-plugin": "2.4.4",
99
- "moment": "^2.29.1",
103
+ "moment": "^2.29.4",
100
104
  "node-polyfill-webpack-plugin": "1.1.4",
101
105
  "p-map": "4.0.0",
102
106
  "passport-local": "1.0.0",
103
107
  "prop-types": "^15.7.2",
104
108
  "qs": "6.10.1",
105
109
  "react": "^17.0.2",
106
- "react-copy-to-clipboard": "^5.0.3",
110
+ "react-copy-to-clipboard": "^5.1.0",
107
111
  "react-dnd": "^14.0.2",
108
112
  "react-dnd-html5-backend": "^14.0.0",
109
113
  "react-dom": "^17.0.2",
@@ -112,7 +116,8 @@
112
116
  "react-helmet": "^6.1.0",
113
117
  "react-intl": "5.20.2",
114
118
  "react-query": "3.24.3",
115
- "react-redux": "7.2.3",
119
+ "react-redux": "7.2.8",
120
+ "react-refresh": "0.11.0",
116
121
  "react-router": "5.2.0",
117
122
  "react-router-dom": "5.2.0",
118
123
  "react-select": "^4.0.2",
@@ -121,24 +126,26 @@
121
126
  "redux-saga": "^0.16.0",
122
127
  "reselect": "^4.0.0",
123
128
  "rimraf": "3.0.2",
124
- "sanitize-html": "2.4.0",
125
- "semver": "7.3.5",
129
+ "sanitize-html": "2.7.0",
130
+ "semver": "7.3.7",
126
131
  "sift": "13.5.0",
127
132
  "style-loader": "3.3.1",
128
133
  "styled-components": "5.3.3",
129
- "webpack": "5.65.0",
130
- "webpack-cli": "4.9.1",
131
- "webpack-dev-server": "4.7.3",
132
- "webpackbar": "5.0.0-3",
134
+ "webpack": "^5.73.0",
135
+ "webpack-cli": "^4.10.0",
136
+ "webpack-dev-server": "^4.9.3",
137
+ "webpackbar": "^5.0.2",
133
138
  "yup": "^0.32.9"
134
139
  },
135
140
  "devDependencies": {
136
- "duplicate-dependencies-webpack-plugin": "0.2.0",
137
- "webpack-bundle-analyzer": "4.4.1"
141
+ "duplicate-dependencies-webpack-plugin": "^1.0.2",
142
+ "glob": "8.0.3",
143
+ "speed-measure-webpack-plugin": "1.5.0",
144
+ "webpack-bundle-analyzer": "^4.5.0"
138
145
  },
139
146
  "engines": {
140
147
  "node": ">=14.19.1 <=16.x.x",
141
148
  "npm": ">=6.0.0"
142
149
  },
143
- "gitHead": "90bd3b9e294a69cd9538bde4e2e853e6de60f238"
150
+ "gitHead": "42aba356ad1b0751584d3b375e83baa4a2c18f65"
144
151
  }
package/scripts/build.js CHANGED
@@ -3,7 +3,11 @@
3
3
  const path = require('path');
4
4
  const webpack = require('webpack');
5
5
  const { isObject } = require('lodash');
6
+ // eslint-disable-next-line node/no-extraneous-require
7
+ const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
8
+
6
9
  const webpackConfig = require('../webpack.config');
10
+ const getPluginsPath = require('../utils/get-plugins-path');
7
11
  const {
8
12
  getCorePluginsPath,
9
13
  getPluginToInstallPath,
@@ -12,29 +16,41 @@ const {
12
16
 
13
17
  const PLUGINS_TO_INSTALL = ['i18n', 'users-permissions'];
14
18
 
19
+ // Wrapper that outputs the webpack speed
20
+ const smp = new SpeedMeasurePlugin();
21
+
15
22
  const buildAdmin = async () => {
16
23
  const entry = path.join(__dirname, '..', 'admin', 'src');
17
24
  const dest = path.join(__dirname, '..', 'build');
25
+ const tsConfigFilePath = path.join(__dirname, '..', 'admin', 'src', 'tsconfig.json');
26
+
18
27
  const corePlugins = getCorePluginsPath();
19
28
  const plugins = getPluginToInstallPath(PLUGINS_TO_INSTALL);
20
29
  const allPlugins = { ...corePlugins, ...plugins };
30
+ const pluginsPath = getPluginsPath();
21
31
 
22
32
  await createPluginsFile(allPlugins);
23
33
 
24
34
  const args = {
25
35
  entry,
26
36
  dest,
27
- cacheDir: path.resolve(__dirname, '..'),
28
- pluginsPath: [path.resolve(__dirname, '../../../../packages')],
37
+ cacheDir: path.join(__dirname, '..'),
38
+ pluginsPath,
29
39
  env: 'production',
30
40
  optimize: true,
31
41
  options: {
32
42
  backend: 'http://localhost:1337',
33
43
  adminPath: '/admin/',
34
44
  },
45
+ tsConfigFilePath,
35
46
  };
36
47
 
37
- const compiler = webpack(webpackConfig(args));
48
+ const config =
49
+ process.env.MEASURE_BUILD_SPEED === 'true'
50
+ ? smp.wrap(webpackConfig(args))
51
+ : webpackConfig(args);
52
+
53
+ const compiler = webpack(config);
38
54
 
39
55
  console.log('Building the admin panel');
40
56
 
@@ -5,6 +5,7 @@ const execa = require('execa');
5
5
  const _ = require('lodash');
6
6
  const { exists } = require('fs-extra');
7
7
  const { ValidationError } = require('@strapi/utils').errors;
8
+ const { isUsingTypeScript } = require('@strapi/typescript-utils');
8
9
  // eslint-disable-next-line node/no-extraneous-require
9
10
  const ee = require('@strapi/strapi/lib/utils/ee');
10
11
 
@@ -81,10 +82,31 @@ module.exports = {
81
82
  return projectSettingsService.updateProjectSettings({ ...body, ...formatedFiles });
82
83
  },
83
84
 
85
+ async telemetryProperties(ctx) {
86
+ // If the telemetry is disabled, ignore the request and return early
87
+ if (strapi.telemetry.isDisabled) {
88
+ ctx.status = 204;
89
+ return;
90
+ }
91
+
92
+ const useTypescriptOnServer = await isUsingTypeScript(strapi.dirs.app.root);
93
+ const useTypescriptOnAdmin = await isUsingTypeScript(
94
+ path.join(strapi.dirs.app.root, 'src', 'admin')
95
+ );
96
+
97
+ return {
98
+ data: {
99
+ useTypescriptOnServer,
100
+ useTypescriptOnAdmin,
101
+ },
102
+ };
103
+ },
104
+
84
105
  async information() {
85
106
  const currentEnvironment = strapi.config.get('environment');
86
107
  const autoReload = strapi.config.get('autoReload', false);
87
108
  const strapiVersion = strapi.config.get('info.strapi', null);
109
+ const dependencies = strapi.config.get('info.dependencies', {});
88
110
  const nodeVersion = process.version;
89
111
  const communityEdition = !strapi.EE;
90
112
  const useYarn = await exists(path.join(process.cwd(), 'yarn.lock'));
@@ -94,6 +116,7 @@ module.exports = {
94
116
  currentEnvironment,
95
117
  autoReload,
96
118
  strapiVersion,
119
+ dependencies,
97
120
  nodeVersion,
98
121
  communityEdition,
99
122
  useYarn,
@@ -3,4 +3,5 @@
3
3
  module.exports = {
4
4
  isAuthenticatedAdmin: require('./isAuthenticatedAdmin'),
5
5
  hasPermissions: require('./hasPermissions'),
6
+ isTelemetryEnabled: require('./isTelemetryEnabled'),
6
7
  };
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ const { createPolicy } = require('@strapi/utils').policy;
4
+
5
+ /**
6
+ * This policy is used for routes dealing with telemetry and analytics content.
7
+ * It will fails when the telemetry has been disabled on the server.
8
+ */
9
+ module.exports = createPolicy({
10
+ name: 'admin::isTelemetryEnabled',
11
+ handler(_ctx, _config, { strapi }) {
12
+ if (strapi.telemetry.isDisabled) {
13
+ return false;
14
+ }
15
+ },
16
+ });
@@ -49,6 +49,14 @@ module.exports = [
49
49
  policies: ['admin::isAuthenticatedAdmin'],
50
50
  },
51
51
  },
52
+ {
53
+ method: 'GET',
54
+ path: '/telemetry-properties',
55
+ handler: 'admin.telemetryProperties',
56
+ config: {
57
+ auth: false,
58
+ },
59
+ },
52
60
  {
53
61
  method: 'GET',
54
62
  path: '/plugins',
@@ -5,7 +5,7 @@ const fse = require('fs-extra');
5
5
  const koaStatic = require('koa-static');
6
6
 
7
7
  const registerAdminPanelRoute = ({ strapi }) => {
8
- let buildDir = resolve(strapi.dirs.root, 'build');
8
+ let buildDir = resolve(strapi.dirs.dist.root, 'build');
9
9
 
10
10
  if (!fse.pathExistsSync(buildDir)) {
11
11
  buildDir = resolve(__dirname, '../../build');