@strapi/admin 4.2.0-beta.3 → 4.2.1-alpha.0

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 (160) hide show
  1. package/admin/src/app.js +4 -7
  2. package/admin/src/components/ConfigurationsProvider/index.js +51 -0
  3. package/admin/src/components/ConfigurationsProvider/reducer.js +28 -0
  4. package/admin/src/components/LeftMenu/index.js +12 -2
  5. package/admin/src/components/Providers/index.js +8 -4
  6. package/admin/src/components/UnauthenticatedLogo/index.js +4 -2
  7. package/admin/src/hooks/useFetchMarketplaceProviders/index.js +23 -0
  8. package/admin/src/hooks/useFetchMarketplaceProviders/utils/api.js +11 -0
  9. package/admin/src/pages/Admin/index.js +5 -15
  10. package/admin/src/pages/App/index.js +9 -18
  11. package/admin/src/pages/MarketplacePage/components/{EmptyPluginSearch/EmptyPluginGrid.js → EmptyNpmPackageSearch/EmptyNpmPackageGrid.js} +1 -1
  12. package/admin/src/pages/MarketplacePage/components/{EmptyPluginSearch → EmptyNpmPackageSearch}/index.js +6 -4
  13. package/admin/src/pages/MarketplacePage/components/{PluginCard → NpmPackageCard}/InstallPluginButton.js +0 -0
  14. package/admin/src/pages/MarketplacePage/components/{PluginCard → NpmPackageCard}/index.js +22 -10
  15. package/admin/src/pages/MarketplacePage/components/NpmPackagesGrid/index.js +42 -0
  16. package/admin/src/pages/MarketplacePage/components/PageHeader/index.js +12 -5
  17. package/admin/src/pages/MarketplacePage/index.js +99 -37
  18. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/index.js +85 -0
  19. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/init.js +13 -0
  20. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/reducer.js +43 -0
  21. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/index.js +118 -0
  22. package/admin/src/pages/{App → SettingsPage/pages/ApplicationInfosPage/components/LogoInput}/reducer.js +13 -7
  23. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/stepper.js +25 -0
  24. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/AddLogoDialog.js +67 -0
  25. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/FromComputerForm.js +176 -0
  26. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/FromUrlForm.js +82 -0
  27. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/ImageCardAsset.js +51 -0
  28. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/PendingLogoDialog.js +97 -0
  29. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/index.js +85 -0
  30. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/reducer.js +28 -0
  31. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/index.js +153 -91
  32. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/api.js +16 -0
  33. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/constants.js +3 -0
  34. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/getFormData.js +17 -0
  35. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/parseFileMetadatas.js +76 -0
  36. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/prefixAllUrls.js +17 -0
  37. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/urlToFile.js +21 -0
  38. package/admin/src/reducers.js +2 -4
  39. package/admin/src/translations/en.json +33 -3
  40. package/admin/src/translations/pl.json +264 -12
  41. package/admin/src/translations/vi.json +17 -17
  42. package/build/1856.6a94980b.chunk.js +172 -0
  43. package/build/2077.5456ccd1.chunk.js +194 -0
  44. package/build/2758.9475712b.chunk.js +162 -0
  45. package/build/2912.dd031292.chunk.js +253 -0
  46. package/build/4715.4588fdf5.chunk.js +385 -0
  47. package/build/4800.d3ebc81d.chunk.js +1 -0
  48. package/build/4982.c57c5675.chunk.js +308 -0
  49. package/build/7197.47565569.chunk.js +113 -0
  50. package/build/{6229.a5cca9f2.chunk.js → 7589.77ef4fbf.chunk.js} +2 -2
  51. package/build/{210.014495c1.chunk.js → 7757.f6eb5e92.chunk.js} +58 -58
  52. package/build/7841.9e9cf739.chunk.js +253 -0
  53. package/build/8681.aec05472.chunk.js +163 -0
  54. package/build/9066.2847fdff.chunk.js +101 -0
  55. package/build/{4073.41ac1235.chunk.js → 9115.623dc4f7.chunk.js} +1 -1
  56. package/build/9158.e48d88af.chunk.js +503 -0
  57. package/build/{7191.3bde3cbf.chunk.js → 9298.cb3b6bc1.chunk.js} +112 -113
  58. package/build/9420.ba035f29.chunk.js +508 -0
  59. package/build/948.d64fb515.chunk.js +2 -0
  60. package/build/Admin-authenticatedApp.63a5061a.chunk.js +80 -0
  61. package/build/{Admin_homePage.f157e33e.chunk.js → Admin_homePage.447df176.chunk.js} +2 -2
  62. package/build/Admin_marketplace.8a503eec.chunk.js +11 -0
  63. package/build/Admin_pluginsPage.91a96fa5.chunk.js +1 -0
  64. package/build/{Admin_profilePage.62c203ad.chunk.js → Admin_profilePage.249cbfc9.chunk.js} +2 -2
  65. package/build/Admin_settingsPage.0d138832.chunk.js +180 -0
  66. package/build/{admin-edit-roles-page.94e1403b.chunk.js → admin-edit-roles-page.7c2c9752.chunk.js} +1 -1
  67. package/build/admin-edit-users.b835bc48.chunk.js +11 -0
  68. package/build/admin-users.19900b75.chunk.js +12 -0
  69. package/build/api-tokens-create-page.8d299dde.chunk.js +1 -0
  70. package/build/api-tokens-edit-page.3e453fc1.chunk.js +1 -0
  71. package/build/{api-tokens-list-page.340750a6.chunk.js → api-tokens-list-page.872c3800.chunk.js} +1 -1
  72. package/build/{codemirror-css.b467b1de.chunk.js → codemirror-css.98490df3.chunk.js} +2 -2
  73. package/build/{codemirror-javacript.41bdefda.chunk.js → codemirror-javacript.cafbda9c.chunk.js} +1 -1
  74. package/build/codemirror-theme.b3c64617.chunk.js +34 -0
  75. package/build/{content-manager.6cdcfb6e.chunk.js → content-manager.002bfd99.chunk.js} +16 -16
  76. package/build/content-type-builder.a0450dfe.chunk.js +141 -0
  77. package/build/{cropper-css.ecc0d670.chunk.js → cropper-css.0055cd53.chunk.js} +2 -2
  78. package/build/email-settings-page.1f235173.chunk.js +103 -0
  79. package/build/en-json.0a5ba154.chunk.js +1 -0
  80. package/build/{fontawesome-css-all.04f33619.chunk.js → fontawesome-css-all.b88d464e.chunk.js} +3 -3
  81. package/build/{fontawesome-css.477ba714.chunk.js → fontawesome-css.a92a7b6c.chunk.js} +2 -2
  82. package/build/highlight.js.9d8ef460.chunk.js +86 -0
  83. package/build/i18n-settings-page.06e88cf2.chunk.js +101 -0
  84. package/build/index.html +1 -1
  85. package/build/main.e3a13431.js +8404 -0
  86. package/build/pl-json.f65302c2.chunk.js +1 -0
  87. package/build/{runtime~main.e7611418.js → runtime~main.dacf1aff.js} +2 -2
  88. package/build/sso-settings-page.a7c2e854.chunk.js +1 -0
  89. package/build/upload-settings.4ee2f135.chunk.js +101 -0
  90. package/build/upload.0d4153e8.chunk.js +105 -0
  91. package/build/users-advanced-settings-page.747b2ec1.chunk.js +101 -0
  92. package/build/users-email-settings-page.8b9a266d.chunk.js +1 -0
  93. package/build/users-providers-settings-page.fc9d8f9d.chunk.js +1 -0
  94. package/build/{users-roles-settings-page.988ebc3b.chunk.js → users-roles-settings-page.1bf4ffc5.chunk.js} +2 -2
  95. package/build/vi-json.bf3424be.chunk.js +1 -0
  96. package/build/webhook-edit-page.142b23ac.chunk.js +23 -0
  97. package/build/webhook-list-page.671582a0.chunk.js +133 -0
  98. package/index.js +239 -53
  99. package/package.json +8 -12
  100. package/scripts/build.js +3 -17
  101. package/server/config/admin-actions.js +14 -0
  102. package/server/controllers/admin.js +29 -12
  103. package/server/policies/index.js +0 -1
  104. package/server/routes/admin.js +28 -9
  105. package/server/routes/serve-admin-panel.js +1 -1
  106. package/server/services/index.js +1 -0
  107. package/server/services/project-settings.js +173 -0
  108. package/server/utils/index.d.ts +2 -0
  109. package/server/validation/project-settings.js +39 -0
  110. package/webpack.alias.js +30 -19
  111. package/webpack.config.js +5 -28
  112. package/admin/src/pages/App/constants.js +0 -1
  113. package/admin/src/tsconfig.json +0 -10
  114. package/build/1709.ceed0e18.chunk.js +0 -503
  115. package/build/1856.521a99fd.chunk.js +0 -172
  116. package/build/20.cf744c35.chunk.js +0 -308
  117. package/build/2077.51485bfb.chunk.js +0 -194
  118. package/build/2135.95ee6de1.chunk.js +0 -162
  119. package/build/2524.688d0355.chunk.js +0 -1
  120. package/build/2912.79c2b3c8.chunk.js +0 -253
  121. package/build/4715.77e04177.chunk.js +0 -385
  122. package/build/4761.3eabdf46.chunk.js +0 -101
  123. package/build/6281.f10a7e3a.chunk.js +0 -1
  124. package/build/7009.79fce86d.chunk.js +0 -164
  125. package/build/7841.f0e7d629.chunk.js +0 -253
  126. package/build/7863.bc7a8f3a.chunk.js +0 -112
  127. package/build/9420.cb0b75e8.chunk.js +0 -508
  128. package/build/Admin-authenticatedApp.4ce8d292.chunk.js +0 -80
  129. package/build/Admin_marketplace.1e3393c9.chunk.js +0 -11
  130. package/build/Admin_pluginsPage.788fb2f6.chunk.js +0 -1
  131. package/build/Admin_settingsPage.924a7816.chunk.js +0 -170
  132. package/build/admin-edit-users.6c2bf718.chunk.js +0 -10
  133. package/build/admin-users.e03db115.chunk.js +0 -11
  134. package/build/api-tokens-create-page.787ab302.chunk.js +0 -1
  135. package/build/api-tokens-edit-page.e4010c0c.chunk.js +0 -1
  136. package/build/codemirror-theme.cf9f9eb6.chunk.js +0 -34
  137. package/build/content-type-builder.e73879b9.chunk.js +0 -141
  138. package/build/email-settings-page.f67d13b2.chunk.js +0 -103
  139. package/build/en-json.3e1a222e.chunk.js +0 -1
  140. package/build/highlight.js.3381ffc3.chunk.js +0 -86
  141. package/build/i18n-settings-page.6b67cb75.chunk.js +0 -101
  142. package/build/main.45472ea9.js +0 -8404
  143. package/build/pl-json.94f05d2c.chunk.js +0 -1
  144. package/build/sso-settings-page.e9034e22.chunk.js +0 -1
  145. package/build/upload-settings.3db55de0.chunk.js +0 -101
  146. package/build/upload.070c189b.chunk.js +0 -105
  147. package/build/users-advanced-settings-page.a23cda17.chunk.js +0 -101
  148. package/build/users-email-settings-page.0a096388.chunk.js +0 -1
  149. package/build/users-providers-settings-page.bfe7755a.chunk.js +0 -1
  150. package/build/vi-json.3d14e91e.chunk.js +0 -1
  151. package/build/webhook-edit-page.2fa94db3.chunk.js +0 -23
  152. package/build/webhook-list-page.b594db49.chunk.js +0 -133
  153. package/server/policies/isTelemetryEnabled.js +0 -16
  154. package/utils/create-cache-dir.js +0 -161
  155. package/utils/get-custom-app-config-file.js +0 -23
  156. package/utils/get-custom-webpack-config.js +0 -38
  157. package/utils/get-plugins-path.js +0 -26
  158. package/utils/index.js +0 -13
  159. package/utils/should-build-admin.js +0 -52
  160. package/utils/watch-admin-files.js +0 -59
@@ -5,10 +5,14 @@ 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');
9
8
  // eslint-disable-next-line node/no-extraneous-require
10
9
  const ee = require('@strapi/strapi/lib/utils/ee');
11
10
 
11
+ const {
12
+ validateUpdateProjectSettings,
13
+ validateUpdateProjectSettingsFiles,
14
+ validateUpdateProjectSettingsImagesDimensions,
15
+ } = require('../validation/project-settings');
12
16
  const { getService } = require('../utils');
13
17
 
14
18
  const PLUGIN_NAME_REGEX = /^[A-Za-z][A-Za-z0-9-_]+$/;
@@ -40,6 +44,7 @@ module.exports = {
40
44
  async init() {
41
45
  let uuid = strapi.config.get('uuid', false);
42
46
  const hasAdmin = await getService('user').exists();
47
+ const { menuLogo } = await getService('project-settings').getProjectSettings();
43
48
  // set to null if telemetryDisabled flag not avaialble in package.json
44
49
  const telemetryDisabled = strapi.config.get('packageJsonStrapi.telemetryDisabled', null);
45
50
 
@@ -47,23 +52,35 @@ module.exports = {
47
52
  uuid = false;
48
53
  }
49
54
 
50
- return { data: { uuid, hasAdmin } };
51
- },
52
-
53
- async telemetryProperties() {
54
- const useTypescriptOnServer = await isUsingTypeScript(strapi.dirs.app.root);
55
- const useTypescriptOnAdmin = await isUsingTypeScript(
56
- path.join(strapi.dirs.app.root, 'src', 'admin')
57
- );
58
-
59
55
  return {
60
56
  data: {
61
- useTypescriptOnServer,
62
- useTypescriptOnAdmin,
57
+ uuid,
58
+ hasAdmin,
59
+ menuLogo: menuLogo ? menuLogo.url : null,
63
60
  },
64
61
  };
65
62
  },
66
63
 
64
+ async getProjectSettings() {
65
+ return getService('project-settings').getProjectSettings();
66
+ },
67
+
68
+ async updateProjectSettings(ctx) {
69
+ const projectSettingsService = getService('project-settings');
70
+
71
+ const {
72
+ request: { files, body },
73
+ } = ctx;
74
+
75
+ await validateUpdateProjectSettings(body);
76
+ await validateUpdateProjectSettingsFiles(files);
77
+
78
+ const formatedFiles = await projectSettingsService.parseFilesData(files);
79
+ await validateUpdateProjectSettingsImagesDimensions(formatedFiles);
80
+
81
+ return projectSettingsService.updateProjectSettings({ ...body, ...formatedFiles });
82
+ },
83
+
67
84
  async information() {
68
85
  const currentEnvironment = strapi.config.get('environment');
69
86
  const autoReload = strapi.config.get('autoReload', false);
@@ -3,5 +3,4 @@
3
3
  module.exports = {
4
4
  isAuthenticatedAdmin: require('./isAuthenticatedAdmin'),
5
5
  hasPermissions: require('./hasPermissions'),
6
- isTelemetryEnabled: require('./isTelemetryEnabled'),
7
6
  };
@@ -7,6 +7,34 @@ module.exports = [
7
7
  handler: 'admin.init',
8
8
  config: { auth: false },
9
9
  },
10
+ {
11
+ method: 'GET',
12
+ path: '/project-settings',
13
+ handler: 'admin.getProjectSettings',
14
+ config: {
15
+ policies: [
16
+ 'admin::isAuthenticatedAdmin',
17
+ {
18
+ name: 'admin::hasPermissions',
19
+ config: { actions: ['admin::project-settings.read'] },
20
+ },
21
+ ],
22
+ },
23
+ },
24
+ {
25
+ method: 'POST',
26
+ path: '/project-settings',
27
+ handler: 'admin.updateProjectSettings',
28
+ config: {
29
+ policies: [
30
+ 'admin::isAuthenticatedAdmin',
31
+ {
32
+ name: 'admin::hasPermissions',
33
+ config: { actions: ['admin::project-settings.update'] },
34
+ },
35
+ ],
36
+ },
37
+ },
10
38
  {
11
39
  method: 'GET',
12
40
  path: '/project-type',
@@ -21,15 +49,6 @@ module.exports = [
21
49
  policies: ['admin::isAuthenticatedAdmin'],
22
50
  },
23
51
  },
24
- {
25
- method: 'GET',
26
- path: '/telemetry-properties',
27
- handler: 'admin.telemetryProperties',
28
- config: {
29
- auth: false,
30
- policies: ['admin::isTelemetryEnabled'],
31
- },
32
- },
33
52
  {
34
53
  method: 'GET',
35
54
  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.dist.root, 'build');
8
+ let buildDir = resolve(strapi.dirs.root, 'build');
9
9
 
10
10
  if (!fse.pathExistsSync(buildDir)) {
11
11
  buildDir = resolve(__dirname, '../../build');
@@ -13,4 +13,5 @@ module.exports = {
13
13
  auth: require('./auth'),
14
14
  action: require('./action'),
15
15
  'api-token': require('./api-token'),
16
+ 'project-settings': require('./project-settings'),
16
17
  };
@@ -0,0 +1,173 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const { pick } = require('lodash');
5
+
6
+ const PROJECT_SETTINGS_FILE_INPUTS = ['menuLogo'];
7
+ const DEFAULT_PROJECT_SETTINGS = {
8
+ menuLogo: null,
9
+ };
10
+
11
+ const parseFilesData = async files => {
12
+ const formatedFilesData = {};
13
+
14
+ await Promise.all(
15
+ PROJECT_SETTINGS_FILE_INPUTS.map(async inputName => {
16
+ const file = files[inputName];
17
+
18
+ // Skip empty file inputs
19
+ if (!file) {
20
+ return;
21
+ }
22
+
23
+ const getStream = () => fs.createReadStream(file.path);
24
+
25
+ // Add formated data for the upload provider
26
+ formatedFilesData[inputName] = strapi
27
+ .plugin('upload')
28
+ .service('upload')
29
+ .formatFileInfo({
30
+ filename: file.name,
31
+ type: file.type,
32
+ size: file.size,
33
+ });
34
+
35
+ // Add image dimensions
36
+ Object.assign(
37
+ formatedFilesData[inputName],
38
+ await strapi
39
+ .plugin('upload')
40
+ .service('image-manipulation')
41
+ .getDimensions({ getStream })
42
+ );
43
+
44
+ // Add file path, and stream
45
+ Object.assign(formatedFilesData[inputName], {
46
+ stream: getStream(),
47
+ tmpPath: file.path,
48
+ provider: strapi.config.get('plugin.upload').provider,
49
+ });
50
+ })
51
+ );
52
+
53
+ return formatedFilesData;
54
+ };
55
+
56
+ const getProjectSettings = async () => {
57
+ const store = strapi.store({ type: 'core', name: 'admin' });
58
+ const projectSettings = {
59
+ ...DEFAULT_PROJECT_SETTINGS,
60
+ ...(await store.get({ key: 'project-settings' })),
61
+ };
62
+
63
+ // Filter file input fields
64
+ PROJECT_SETTINGS_FILE_INPUTS.forEach(inputName => {
65
+ if (!projectSettings[inputName]) {
66
+ return;
67
+ }
68
+
69
+ projectSettings[inputName] = pick(projectSettings[inputName], [
70
+ 'name',
71
+ 'url',
72
+ 'width',
73
+ 'height',
74
+ 'ext',
75
+ 'size',
76
+ ]);
77
+ });
78
+
79
+ return projectSettings;
80
+ };
81
+
82
+ const uploadFiles = async (files = {}) => {
83
+ // Call the provider upload function for each file
84
+ return Promise.all(
85
+ Object.values(files)
86
+ .filter(file => file.stream instanceof fs.ReadStream)
87
+ .map(file => strapi.plugin('upload').provider.uploadStream(file))
88
+ );
89
+ };
90
+
91
+ const deleteOldFiles = async ({ previousSettings, newSettings }) => {
92
+ return Promise.all(
93
+ PROJECT_SETTINGS_FILE_INPUTS.map(async inputName => {
94
+ // Skip if the store doesn't contain project settings
95
+ if (!previousSettings) {
96
+ return;
97
+ }
98
+
99
+ // Skip if there was no previous file
100
+ if (!previousSettings[inputName]) {
101
+ return;
102
+ }
103
+
104
+ // Skip if the file was not changed
105
+ if (
106
+ newSettings[inputName] &&
107
+ previousSettings[inputName].hash === newSettings[inputName].hash
108
+ ) {
109
+ return;
110
+ }
111
+
112
+ // Skip if the file was not uploaded with the current provider
113
+ if (strapi.config.get('plugin.upload').provider !== previousSettings[inputName].provider) {
114
+ return;
115
+ }
116
+
117
+ // There was a previous file and an new file was uploaded
118
+ // Remove the previous file
119
+ strapi.plugin('upload').provider.delete(previousSettings[inputName]);
120
+ })
121
+ );
122
+ };
123
+
124
+ const updateProjectSettings = async newSettings => {
125
+ const store = strapi.store({ type: 'core', name: 'admin' });
126
+ const previousSettings = await store.get({ key: 'project-settings' });
127
+ const files = pick(newSettings, PROJECT_SETTINGS_FILE_INPUTS);
128
+
129
+ await uploadFiles(files);
130
+
131
+ PROJECT_SETTINGS_FILE_INPUTS.forEach(inputName => {
132
+ // If the user input exists but is not a formdata "file" remove it
133
+ if (newSettings[inputName] !== undefined && !(typeof newSettings[inputName] === 'object')) {
134
+ newSettings[inputName] = null;
135
+ return;
136
+ }
137
+
138
+ // If the user input is undefined reuse previous setting (do not update field)
139
+ if (!newSettings[inputName]) {
140
+ newSettings[inputName] = previousSettings[inputName];
141
+ return;
142
+ }
143
+
144
+ // Update the file
145
+ newSettings[inputName] = pick(newSettings[inputName], [
146
+ 'name',
147
+ 'hash',
148
+ 'url',
149
+ 'width',
150
+ 'height',
151
+ 'ext',
152
+ 'size',
153
+ 'provider',
154
+ ]);
155
+ });
156
+
157
+ // No await to proceed asynchronously
158
+ deleteOldFiles({ previousSettings, newSettings });
159
+
160
+ await store.set({
161
+ key: 'project-settings',
162
+ value: { ...previousSettings, ...newSettings },
163
+ });
164
+
165
+ return getProjectSettings();
166
+ };
167
+
168
+ module.exports = {
169
+ deleteOldFiles,
170
+ parseFilesData,
171
+ getProjectSettings,
172
+ updateProjectSettings,
173
+ };
@@ -6,6 +6,7 @@ import * as metrics from '../services/metrics';
6
6
  import * as token from '../services/token';
7
7
  import * as auth from '../services/auth';
8
8
  import * as apiToken from '../services/api-token';
9
+ import * as projectSettings from '../services/project-settings';
9
10
 
10
11
  type S = {
11
12
  role: typeof role;
@@ -16,6 +17,7 @@ type S = {
16
17
  auth: typeof auth;
17
18
  metrics: typeof metrics;
18
19
  'api-token': typeof apiToken;
20
+ 'project-settings': typeof projectSettings;
19
21
  };
20
22
 
21
23
  export function getService<T extends keyof S>(name: T): S[T];
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ const { yup, validateYupSchemaSync } = require('@strapi/utils');
4
+
5
+ const MAX_IMAGE_WIDTH = 750;
6
+ const MAX_IMAGE_HEIGHT = MAX_IMAGE_WIDTH;
7
+ const MAX_IMAGE_FILE_SIZE = 1024 * 1024; // 1Mo
8
+ const ALLOWED_IMAGE_FILE_TYPES = ['image/jpeg', 'image/png', 'image/svg+xml'];
9
+
10
+ const updateProjectSettings = yup
11
+ .object({
12
+ menuLogo: yup.string(),
13
+ })
14
+ .noUnknown();
15
+
16
+ const updateProjectSettingsFiles = yup
17
+ .object({
18
+ menuLogo: yup.object({
19
+ name: yup.string(),
20
+ type: yup.string().oneOf(ALLOWED_IMAGE_FILE_TYPES),
21
+ size: yup.number().max(MAX_IMAGE_FILE_SIZE),
22
+ }),
23
+ })
24
+ .noUnknown();
25
+
26
+ const updateProjectSettingsImagesDimensions = yup.object({
27
+ menuLogo: yup.object({
28
+ width: yup.number().max(MAX_IMAGE_WIDTH),
29
+ height: yup.number().max(MAX_IMAGE_HEIGHT),
30
+ }),
31
+ });
32
+
33
+ module.exports = {
34
+ validateUpdateProjectSettings: validateYupSchemaSync(updateProjectSettings),
35
+ validateUpdateProjectSettingsFiles: validateYupSchemaSync(updateProjectSettingsFiles),
36
+ validateUpdateProjectSettingsImagesDimensions: validateYupSchemaSync(
37
+ updateProjectSettingsImagesDimensions
38
+ ),
39
+ };
package/webpack.alias.js CHANGED
@@ -2,18 +2,19 @@
2
2
 
3
3
  const path = require('path');
4
4
 
5
- const alias = [
6
- 'object-assign',
7
- 'whatwg-fetch',
5
+ const aliasExactMatch = [
6
+ '@strapi/design-system',
7
+ '@strapi/helper-plugin',
8
+ '@strapi/icons',
8
9
  '@fortawesome/fontawesome-svg-core',
9
10
  '@fortawesome/free-solid-svg-icons',
11
+ 'date-fns',
12
+ 'formik',
10
13
  'history',
11
- 'hoist-non-react-statics',
12
14
  'immer',
13
- 'invariant',
15
+ 'qs',
14
16
  'lodash',
15
17
  'moment',
16
- 'qs',
17
18
  'react',
18
19
  'react-copy-to-clipboard',
19
20
  'react-dnd',
@@ -24,6 +25,7 @@ const alias = [
24
25
  'react-helmet',
25
26
  'react-is',
26
27
  'react-intl',
28
+ 'react-query',
27
29
  'react-redux',
28
30
  'react-router',
29
31
  'react-router-dom',
@@ -32,20 +34,29 @@ const alias = [
32
34
  'redux',
33
35
  'reselect',
34
36
  'styled-components',
37
+ 'whatwg-fetch',
35
38
  'yup',
36
39
  ];
37
40
 
38
- module.exports = alias.reduce(
39
- (acc, curr) => {
40
- acc[`${curr}$`] = require.resolve(curr);
41
+ const alias = [
42
+ 'react-select/animated',
43
+ 'react-select/async',
44
+ 'react-select/async-creatable',
45
+ 'react-select/base',
46
+ 'react-select/creatable',
47
+ ];
48
+
49
+ // See https://webpack.js.org/configuration/resolve/
50
+ module.exports = {
51
+ ...alias.reduce((acc, name) => {
52
+ acc[name] = require.resolve(name);
41
53
  return acc;
42
- },
43
- {
44
- 'react-select/animated': require.resolve('react-select/animated'),
45
- 'react-select/async': require.resolve('react-select/async'),
46
- 'react-select/async-creatable': require.resolve('react-select/async-creatable'),
47
- 'react-select/base': require.resolve('react-select/base'),
48
- 'react-select/creatable': require.resolve('react-select/creatable'),
49
- ee_else_ce: path.resolve(__dirname),
50
- }
51
- );
54
+ }, {}),
55
+
56
+ ...aliasExactMatch.reduce((acc, name) => {
57
+ acc[`${name}$`] = require.resolve(name);
58
+ return acc;
59
+ }, {}),
60
+
61
+ ee_else_ce: path.resolve(__dirname),
62
+ };
package/webpack.config.js CHANGED
@@ -4,7 +4,6 @@ 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');
8
7
  const HtmlWebpackPlugin = require('html-webpack-plugin');
9
8
  const { ESBuildMinifyPlugin } = require('esbuild-loader');
10
9
  const WebpackBar = require('webpackbar');
@@ -15,12 +14,12 @@ const getClientEnvironment = require('./env');
15
14
  const EE_REGEX = /from.* ['"]ee_else_ce\//;
16
15
 
17
16
  module.exports = ({
17
+ entry,
18
18
  cacheDir,
19
+ pluginsPath,
19
20
  dest,
20
- entry,
21
21
  env,
22
22
  optimize,
23
- pluginsPath,
24
23
  options = {
25
24
  backend: 'http://localhost:1337',
26
25
  adminPath: '/admin/',
@@ -30,7 +29,6 @@ module.exports = ({
30
29
  eeRoot: './ee/admin',
31
30
  ceRoot: './admin/src',
32
31
  },
33
- tsConfigFilePath,
34
32
  }) => {
35
33
  const isProduction = env === 'production';
36
34
 
@@ -51,9 +49,6 @@ module.exports = ({
51
49
  ]
52
50
  : [];
53
51
 
54
- // Directly inject a polyfill in the webpack entry point before the entry point
55
- // FIXME: I have noticed a bug regarding the helper-plugin and esbuild-loader
56
- // The only I could fix it was to inject the babel polyfill
57
52
  const babelPolyfill = '@babel/polyfill/dist/polyfill.min.js';
58
53
 
59
54
  return {
@@ -84,16 +79,6 @@ module.exports = ({
84
79
  },
85
80
  module: {
86
81
  rules: [
87
- {
88
- test: /\.tsx?$/,
89
- loader: require.resolve('esbuild-loader'),
90
- include: [cacheDir, ...pluginsPath],
91
- exclude: /node_modules/,
92
- options: {
93
- loader: 'tsx',
94
- target: 'es2015',
95
- },
96
- },
97
82
  {
98
83
  test: /\.m?jsx?$/,
99
84
  include: cacheDir,
@@ -109,10 +94,6 @@ module.exports = ({
109
94
  try {
110
95
  const fileContent = fse.readFileSync(filePath).toString();
111
96
 
112
- if (fileContent.match(/from.* ['"]ee_else_ce\//)) {
113
- return true;
114
- }
115
-
116
97
  return EE_REGEX.test(fileContent);
117
98
  } catch (e) {
118
99
  return false;
@@ -209,7 +190,7 @@ module.exports = ({
209
190
  resolve: {
210
191
  alias,
211
192
  symlinks: false,
212
- extensions: ['.js', '.jsx', '.react.js', '.ts', '.tsx'],
193
+ extensions: ['.js', '.jsx', '.react.js'],
213
194
  mainFields: ['browser', 'jsnext:main', 'main'],
214
195
  modules: ['node_modules', path.resolve(__dirname, 'node_modules')],
215
196
  },
@@ -217,16 +198,12 @@ module.exports = ({
217
198
  new HtmlWebpackPlugin({
218
199
  inject: true,
219
200
  template: path.resolve(__dirname, 'index.html'),
201
+ // FIXME
202
+ // favicon: path.resolve(__dirname, 'admin/src/favicon.ico'),
220
203
  }),
221
204
  new webpack.DefinePlugin(envVariables),
222
205
 
223
206
  new NodePolyfillPlugin(),
224
-
225
- new ForkTsCheckerPlugin({
226
- typescript: {
227
- configFile: tsConfigFilePath,
228
- },
229
- }),
230
207
  ...webpackPlugins,
231
208
  ],
232
209
  };
@@ -1 +0,0 @@
1
- export const SET_APP_RUNTIME_STATUS = 'StrapiAdmin/APP/SET_APP_RUNTIME_STATUS';
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "@strapi/typescript-utils/lib/configs/admin",
3
-
4
- "include": [
5
- "./",
6
- "../../../**/admin/src/**/*",
7
- "../../../../plugins/documentation/admin/src/**/*"
8
- ],
9
- "exclude": ["node_modules", "**/*.test.js", "*.js"]
10
- }