@strapi/admin 4.13.3 → 4.14.0-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 (72) hide show
  1. package/admin/src/hooks/useAdminRoles/index.js +17 -7
  2. package/admin/src/hooks/useAdminUsers/useAdminUsers.js +16 -7
  3. package/admin/src/hooks/useContentTypes/useContentTypes.js +18 -7
  4. package/build/1227.ec336799.chunk.js +1 -0
  5. package/build/{3483.19381b40.chunk.js → 3483.f6b2439f.chunk.js} +1 -1
  6. package/build/4174.4587c7f6.chunk.js +1 -0
  7. package/build/6266.53be9ea3.chunk.js +124 -0
  8. package/build/7897.eac204a4.chunk.js +6 -0
  9. package/build/{Admin-authenticatedApp.796792a8.chunk.js → Admin-authenticatedApp.d200a4ee.chunk.js} +1 -1
  10. package/build/{admin-app.2a8615ab.chunk.js → admin-app.582877a3.chunk.js} +11 -11
  11. package/build/admin-edit-roles-page.0aa65505.chunk.js +267 -0
  12. package/build/admin-edit-users.9215912a.chunk.js +10 -0
  13. package/build/admin-roles-list.824a50de.chunk.js +22 -0
  14. package/build/admin-users.f6b3c643.chunk.js +11 -0
  15. package/build/audit-logs-settings-page.be2cb4dd.chunk.js +1 -0
  16. package/build/{content-manager.f448efdf.chunk.js → content-manager.06a2f7ec.chunk.js} +39 -39
  17. package/build/index.html +1 -1
  18. package/build/review-workflows-settings-create-view.604cffa0.chunk.js +1 -0
  19. package/build/review-workflows-settings-edit-view.73c57f07.chunk.js +1 -0
  20. package/build/review-workflows-settings-list-view.7e300ecb.chunk.js +56 -0
  21. package/build/{runtime~main.d2b8d4a1.js → runtime~main.9de029f4.js} +2 -2
  22. package/build/sso-settings-page.94373f78.chunk.js +1 -0
  23. package/ee/admin/content-manager/pages/EditView/InformationBox/components/StageSelect/StageSelect.js +65 -53
  24. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/actions/index.js +50 -5
  25. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/Stage.js +227 -19
  26. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/WorkflowAttributes/WorkflowAttributes.js +8 -23
  27. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/constants.js +6 -0
  28. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/hooks/useReviewWorkflows.js +17 -7
  29. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/hooks/useReviewWorkflowsStages.js +36 -0
  30. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/CreateView.js +68 -19
  31. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/EditView.js +105 -35
  32. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/reducer/index.js +68 -27
  33. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/selectors.js +45 -0
  34. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/utils/validateWorkflow.js +20 -0
  35. package/ee/server/config/admin-actions.js +6 -0
  36. package/ee/server/constants/workflows.js +13 -0
  37. package/ee/server/content-types/workflow-stage/index.js +6 -0
  38. package/ee/server/controllers/workflows/index.js +41 -16
  39. package/ee/server/controllers/workflows/stages/index.js +93 -6
  40. package/ee/server/routes/review-workflows.js +10 -9
  41. package/ee/server/services/index.js +1 -0
  42. package/ee/server/services/review-workflows/stage-permissions.js +60 -0
  43. package/ee/server/services/review-workflows/stages.js +83 -12
  44. package/ee/server/services/review-workflows/workflows/index.js +20 -7
  45. package/ee/server/validation/review-workflows.js +11 -0
  46. package/package.json +8 -8
  47. package/scripts/build.js +2 -3
  48. package/scripts/create-dev-plugins-file.js +2 -3
  49. package/server/content-types/Permission.js +6 -0
  50. package/server/domain/permission/index.js +11 -2
  51. package/server/services/role.js +12 -4
  52. package/server/validation/action-provider.js +1 -1
  53. package/server/validation/common-validators.js +92 -100
  54. package/server/validation/permission.js +0 -3
  55. package/utils/create-cache-dir.js +5 -102
  56. package/utils/plugins.js +217 -0
  57. package/webpack.config.js +2 -2
  58. package/build/1227.9f37e1dc.chunk.js +0 -1
  59. package/build/2237.b832ae6e.chunk.js +0 -114
  60. package/build/4174.f1f39e40.chunk.js +0 -1
  61. package/build/4724.aea5c8c1.chunk.js +0 -6
  62. package/build/admin-edit-roles-page.38a6c863.chunk.js +0 -267
  63. package/build/admin-edit-users.545fc882.chunk.js +0 -10
  64. package/build/admin-roles-list.1e2e814d.chunk.js +0 -22
  65. package/build/admin-users.b8ea5677.chunk.js +0 -11
  66. package/build/audit-logs-settings-page.96f9d608.chunk.js +0 -1
  67. package/build/review-workflows-settings-create-view.4a156a19.chunk.js +0 -1
  68. package/build/review-workflows-settings-edit-view.ce984d1f.chunk.js +0 -1
  69. package/build/review-workflows-settings-list-view.419b8deb.chunk.js +0 -56
  70. package/build/sso-settings-page.45153df5.chunk.js +0 -1
  71. package/utils/create-plugins-exclude-path.js +0 -20
  72. package/utils/get-plugins.js +0 -110
@@ -89,112 +89,103 @@ const fieldsPropertyValidation = (action) =>
89
89
  checkNilFields(action)
90
90
  );
91
91
 
92
+ const permission = yup
93
+ .object()
94
+ .shape({
95
+ action: yup
96
+ .string()
97
+ .required()
98
+ .test('action-validity', 'action is not an existing permission action', function (actionId) {
99
+ // If the action field is Nil, ignore the test and let the required check handle the error
100
+ if (isNil(actionId)) {
101
+ return true;
102
+ }
103
+
104
+ return !!getActionFromProvider(actionId);
105
+ }),
106
+ actionParameters: yup.object().nullable(),
107
+ subject: yup
108
+ .string()
109
+ .nullable()
110
+ .test('subject-validity', 'Invalid subject submitted', function (subject) {
111
+ const action = getActionFromProvider(this.options.parent.action);
112
+
113
+ if (!action) {
114
+ return true;
115
+ }
116
+
117
+ if (isNil(action.subjects)) {
118
+ return isNil(subject);
119
+ }
120
+
121
+ if (isArray(action.subjects)) {
122
+ return action.subjects.includes(subject);
123
+ }
124
+
125
+ return false;
126
+ }),
127
+ properties: yup
128
+ .object()
129
+ .test('properties-structure', 'Invalid property set at ${path}', function (properties) {
130
+ const action = getActionFromProvider(this.options.parent.action);
131
+ const hasNoProperties = isEmpty(properties) || isNil(properties);
132
+
133
+ if (!has('options.applyToProperties', action)) {
134
+ return hasNoProperties;
135
+ }
136
+
137
+ if (hasNoProperties) {
138
+ return true;
139
+ }
140
+
141
+ const { applyToProperties } = action.options;
142
+
143
+ if (!isArray(applyToProperties)) {
144
+ return false;
145
+ }
146
+
147
+ return Object.keys(properties).every((property) => applyToProperties.includes(property));
148
+ })
149
+ .test(
150
+ 'fields-property',
151
+ 'Invalid fields property at ${path}',
152
+ async function (properties = {}) {
153
+ const action = getActionFromProvider(this.options.parent.action);
154
+
155
+ if (!action || !properties) {
156
+ return true;
157
+ }
158
+
159
+ if (!actionDomain.appliesToProperty('fields', action)) {
160
+ return true;
161
+ }
162
+
163
+ try {
164
+ await fieldsPropertyValidation(action).validate(properties.fields, {
165
+ strict: true,
166
+ abortEarly: false,
167
+ });
168
+ return true;
169
+ } catch (e) {
170
+ // Propagate fieldsPropertyValidation error with updated path
171
+ throw this.createError({
172
+ message: e.message,
173
+ path: `${this.path}.fields`,
174
+ });
175
+ }
176
+ }
177
+ ),
178
+ conditions: yup.array().of(yup.string()),
179
+ })
180
+ .noUnknown();
181
+
92
182
  const updatePermissions = yup
93
183
  .object()
94
184
  .shape({
95
185
  permissions: yup
96
186
  .array()
97
187
  .required()
98
- .of(
99
- yup
100
- .object()
101
- .shape({
102
- action: yup
103
- .string()
104
- .required()
105
- .test(
106
- 'action-validity',
107
- 'action is not an existing permission action',
108
- function (actionId) {
109
- // If the action field is Nil, ignore the test and let the required check handle the error
110
- if (isNil(actionId)) {
111
- return true;
112
- }
113
-
114
- return !!getActionFromProvider(actionId);
115
- }
116
- ),
117
- subject: yup
118
- .string()
119
- .nullable()
120
- .test('subject-validity', 'Invalid subject submitted', function (subject) {
121
- const action = getActionFromProvider(this.options.parent.action);
122
-
123
- if (!action) {
124
- return true;
125
- }
126
-
127
- if (isNil(action.subjects)) {
128
- return isNil(subject);
129
- }
130
-
131
- if (isArray(action.subjects)) {
132
- return action.subjects.includes(subject);
133
- }
134
-
135
- return false;
136
- }),
137
- properties: yup
138
- .object()
139
- .test(
140
- 'properties-structure',
141
- 'Invalid property set at ${path}',
142
- function (properties) {
143
- const action = getActionFromProvider(this.options.parent.action);
144
- const hasNoProperties = isEmpty(properties) || isNil(properties);
145
-
146
- if (!has('options.applyToProperties', action)) {
147
- return hasNoProperties;
148
- }
149
-
150
- if (hasNoProperties) {
151
- return true;
152
- }
153
-
154
- const { applyToProperties } = action.options;
155
-
156
- if (!isArray(applyToProperties)) {
157
- return false;
158
- }
159
-
160
- return Object.keys(properties).every((property) =>
161
- applyToProperties.includes(property)
162
- );
163
- }
164
- )
165
- .test(
166
- 'fields-property',
167
- 'Invalid fields property at ${path}',
168
- async function (properties = {}) {
169
- const action = getActionFromProvider(this.options.parent.action);
170
-
171
- if (!action || !properties) {
172
- return true;
173
- }
174
-
175
- if (!actionDomain.appliesToProperty('fields', action)) {
176
- return true;
177
- }
178
-
179
- try {
180
- await fieldsPropertyValidation(action).validate(properties.fields, {
181
- strict: true,
182
- abortEarly: false,
183
- });
184
- return true;
185
- } catch (e) {
186
- // Propagate fieldsPropertyValidation error with updated path
187
- throw this.createError({
188
- message: e.message,
189
- path: `${this.path}.fields`,
190
- });
191
- }
192
- }
193
- ),
194
- conditions: yup.array().of(yup.string()),
195
- })
196
- .noUnknown()
197
- )
188
+ .of(permission)
198
189
  .test(
199
190
  'duplicated-permissions',
200
191
  'Some permissions are duplicated (same action and subject)',
@@ -213,5 +204,6 @@ module.exports = {
213
204
  roles,
214
205
  isAPluginName,
215
206
  arrayOfConditionNames,
207
+ permission,
216
208
  updatePermissions,
217
209
  };
@@ -17,8 +17,6 @@ const checkPermissionsSchema = yup.object().shape({
17
17
  ),
18
18
  });
19
19
 
20
- // validatePermissionsExist
21
-
22
20
  const checkPermissionsExist = function (permissions) {
23
21
  const existingActions = getService('permission').actionProvider.values();
24
22
  const failIndex = permissions.findIndex(
@@ -48,7 +46,6 @@ const actionsExistSchema = yup
48
46
  .test('actions-exist', '', checkPermissionsExist);
49
47
 
50
48
  // exports
51
-
52
49
  module.exports = {
53
50
  validatedUpdatePermissionsInput: validateYupSchema(validators.updatePermissions),
54
51
  validatePermissionsExist: validateYupSchema(actionsExistSchema),
@@ -1,69 +1,13 @@
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 tsUtils = require('@strapi/typescript-utils');
7
6
  const getCustomAppConfigFile = require('./get-custom-app-config-file');
7
+ const { filterPluginsByAdminEntry, createPluginFile } = require('./plugins');
8
8
 
9
9
  const getPkgPath = (name) => path.dirname(require.resolve(`${name}/package.json`));
10
10
 
11
- async function createPluginsJs(plugins, dest) {
12
- const pluginsArray = plugins.map(({ pathToPlugin, name, info }) => {
13
- const shortName = _.camelCase(name);
14
-
15
- let realPath = '';
16
-
17
- /**
18
- * We're using a module here so we want to keep using the module resolution procedure.
19
- */
20
- if (info?.packageName || info?.required) {
21
- /**
22
- * path.join, on windows, it uses backslashes to resolve path.
23
- * The problem is that Webpack does not windows paths
24
- * With this tool, we need to rely on "/" and not "\".
25
- * This is the reason why '..\\..\\..\\node_modules\\@strapi\\plugin-content-type-builder/strapi-admin.js' was not working.
26
- * The regexp at line 105 aims to replace the windows backslashes by standard slash so that webpack can deal with them.
27
- * Backslash looks to work only for absolute paths with webpack => https://webpack.js.org/concepts/module-resolution/#absolute-paths
28
- */
29
- realPath = path.join(pathToPlugin, 'strapi-admin').replace(/\\/g, '/');
30
- } else {
31
- realPath = path
32
- .join(path.relative(path.resolve(dest, 'admin', 'src'), pathToPlugin), 'strapi-admin')
33
- .replace(/\\/g, '/');
34
- }
35
-
36
- return {
37
- name,
38
- pathToPlugin: realPath,
39
- shortName,
40
- };
41
- });
42
-
43
- const content = `
44
- ${pluginsArray
45
- .map(({ pathToPlugin, shortName }) => {
46
- const req = `'${pathToPlugin}'`;
47
-
48
- return `import ${shortName} from ${req};`;
49
- })
50
- .join('\n')}
51
-
52
-
53
- const plugins = {
54
- ${[...pluginsArray]
55
- .map(({ name, shortName }) => {
56
- return ` '${name}': ${shortName},`;
57
- })
58
- .join('\n')}
59
- };
60
-
61
- export default plugins;
62
- `;
63
-
64
- return fs.writeFile(path.resolve(dest, 'admin', 'src', 'plugins.js'), content);
65
- }
66
-
67
11
  async function copyAdmin(dest) {
68
12
  const adminPath = getPkgPath('@strapi/admin');
69
13
 
@@ -86,49 +30,8 @@ async function createCacheDir({ appDir, plugins }) {
86
30
  );
87
31
 
88
32
  const pluginsWithFront = Object.entries(plugins)
89
- .filter(([, plugin]) => {
90
- /**
91
- * There are two ways a plugin should be imported, either it's local to the strapi app,
92
- * or it's an actual npm module that's installed and resolved via node_modules.
93
- *
94
- * We first check if the plugin is local to the strapi app, using a regular `resolve` because
95
- * the pathToPlugin will be relative i.e. `/Users/my-name/strapi-app/src/plugins/my-plugin`.
96
- *
97
- * If the file doesn't exist well then it's probably a node_module, so instead we use `require.resolve`
98
- * which will resolve the path to the module in node_modules. If it fails with the specific code `MODULE_NOT_FOUND`
99
- * then it doesn't have an admin part to the package.
100
- *
101
- * NOTE: we should try to move to `./package.json[exports]` map with bundling of our own plugins,
102
- * because these entry files are written in commonjs restricting features e.g. tree-shaking.
103
- */
104
- try {
105
- const isLocalPluginWithLegacyAdminFile = fs.existsSync(
106
- path.resolve(`${plugin.pathToPlugin}/strapi-admin.js`)
107
- );
108
-
109
- if (!isLocalPluginWithLegacyAdminFile) {
110
- const isModulewithLegacyAdminFile = require.resolve(
111
- `${plugin.pathToPlugin}/strapi-admin.js`
112
- );
113
-
114
- return isModulewithLegacyAdminFile;
115
- }
116
-
117
- return isLocalPluginWithLegacyAdminFile;
118
- } catch (err) {
119
- if (err.code === 'MODULE_NOT_FOUND') {
120
- /**
121
- * the plugin does not contain FE code, so we
122
- * don't want to import it anyway
123
- */
124
- return false;
125
- }
126
-
127
- throw err;
128
- }
129
- })
130
- .map(([name, plugin]) => ({ name, ...plugin }));
131
-
33
+ .map(([name, plugin]) => ({ name, ...plugin }))
34
+ .filter(filterPluginsByAdminEntry);
132
35
  // create .cache dir
133
36
  await fs.emptyDir(cacheDir);
134
37
 
@@ -166,7 +69,7 @@ async function createCacheDir({ appDir, plugins }) {
166
69
  }
167
70
 
168
71
  // create plugins.js with plugins requires
169
- await createPluginsJs(pluginsWithFront, cacheDir);
72
+ await createPluginFile(pluginsWithFront, cacheDir);
170
73
 
171
74
  // create the tsconfig.json file so we can develop plugins in ts while being in a JS project
172
75
  if (!useTypeScript) {
@@ -174,4 +77,4 @@ async function createCacheDir({ appDir, plugins }) {
174
77
  }
175
78
  }
176
79
 
177
- module.exports = { createCacheDir, createPluginsJs };
80
+ module.exports = { createCacheDir };
@@ -0,0 +1,217 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const fs = require('fs');
5
+ const asyncFs = require('fs/promises');
6
+ const { camelCase } = require('lodash');
7
+ // eslint-disable-next-line import/no-extraneous-dependencies
8
+ const glob = require('glob');
9
+
10
+ /**
11
+ * @typedef {Object} PluginInfo
12
+ * @property {string} packageName
13
+ * @property {string} description
14
+ * @property {boolean=} required
15
+ */
16
+
17
+ /**
18
+ * @typedef {Object} Plugin
19
+ * @property {string} pathToPlugin
20
+ * @property {string} name
21
+ * @property {PluginInfo} info
22
+ * @property {string=} directory
23
+ */
24
+
25
+ /**
26
+ * @param {string[]} pluginsAllowlist
27
+ * @returns {Plugin[]}
28
+ */
29
+ const getPlugins = (pluginsAllowlist) => {
30
+ const rootPath = path.resolve(__dirname, '..', path.join('..', '..', '..', 'packages'));
31
+ /**
32
+ * So `glob` only supports '/' as a path separator, so we need to replace
33
+ * the path separator for the current OS with '/'. e.g. on windows it's `\`.
34
+ *
35
+ * see https://github.com/isaacs/node-glob/#windows for more information
36
+ *
37
+ * and see https://github.com/isaacs/node-glob/issues/467#issuecomment-1114240501 for the recommended fix.
38
+ */
39
+ let corePath = path.join(rootPath, 'core', '*');
40
+ let pluginsPath = path.join(rootPath, 'plugins', '*');
41
+
42
+ if (process.platform === 'win32') {
43
+ corePath = corePath.split(path.sep).join(path.posix.sep);
44
+ pluginsPath = pluginsPath.split(path.sep).join(path.posix.sep);
45
+ }
46
+
47
+ const corePackageDirs = glob.sync(corePath);
48
+ const pluginsPackageDirs = glob.sync(pluginsPath);
49
+
50
+ const plugins = [...corePackageDirs, ...pluginsPackageDirs]
51
+ .map((directory) => {
52
+ const isCoreAdmin = directory.includes('packages/core/admin');
53
+
54
+ if (isCoreAdmin) {
55
+ return null;
56
+ }
57
+
58
+ const { name, strapi } = require(path.join(directory, 'package.json'));
59
+
60
+ /**
61
+ * this will remove any of our packages that are
62
+ * not actually plugins for the application
63
+ */
64
+ if (!strapi || strapi.kind !== 'plugin') {
65
+ return null;
66
+ }
67
+
68
+ /**
69
+ * we want the name of the node_module
70
+ */
71
+ return {
72
+ pathToPlugin: name,
73
+ name: strapi.name,
74
+ info: { ...strapi, packageName: name },
75
+ directory,
76
+ };
77
+ })
78
+ .filter(filterPluginsByAdminEntry);
79
+
80
+ if (Array.isArray(pluginsAllowlist)) {
81
+ return plugins.filter((plugin) => pluginsAllowlist.includes(plugin.pathToPlugin));
82
+ }
83
+
84
+ return plugins;
85
+ };
86
+
87
+ /**
88
+ * @type {(plugin: Plugin) => boolean}
89
+ */
90
+ const filterPluginsByAdminEntry = (plugin) => {
91
+ if (!plugin) {
92
+ return false;
93
+ }
94
+
95
+ /**
96
+ * There are two ways a plugin should be imported, either it's local to the strapi app,
97
+ * or it's an actual npm module that's installed and resolved via node_modules.
98
+ *
99
+ * We first check if the plugin is local to the strapi app, using a regular `resolve` because
100
+ * the pathToPlugin will be relative i.e. `/Users/my-name/strapi-app/src/plugins/my-plugin`.
101
+ *
102
+ * If the file doesn't exist well then it's probably a node_module, so instead we use `require.resolve`
103
+ * which will resolve the path to the module in node_modules. If it fails with the specific code `MODULE_NOT_FOUND`
104
+ * then it doesn't have an admin part to the package.
105
+ *
106
+ * NOTE: we should try to move to `./package.json[exports]` map with bundling of our own plugins,
107
+ * because these entry files are written in commonjs restricting features e.g. tree-shaking.
108
+ */
109
+ try {
110
+ const isLocalPluginWithLegacyAdminFile = fs.existsSync(
111
+ path.resolve(`${plugin.pathToPlugin}/strapi-admin.js`)
112
+ );
113
+
114
+ if (!isLocalPluginWithLegacyAdminFile) {
115
+ const isModuleWithFE = require.resolve(`${plugin.pathToPlugin}/strapi-admin`);
116
+
117
+ return isModuleWithFE;
118
+ }
119
+
120
+ return isLocalPluginWithLegacyAdminFile;
121
+ } catch (err) {
122
+ if (err.code === 'MODULE_NOT_FOUND') {
123
+ /**
124
+ * the plugin does not contain FE code, so we
125
+ * don't want to import it anyway
126
+ */
127
+ return false;
128
+ }
129
+
130
+ throw err;
131
+ }
132
+ };
133
+
134
+ /**
135
+ *
136
+ * @param {Plugin[]} plugins
137
+ * @param {string} dest
138
+ * @returns {void}
139
+ */
140
+ async function createPluginFile(plugins, dest) {
141
+ const pluginsArray = plugins.map(({ pathToPlugin, name, info }) => {
142
+ const shortName = camelCase(name);
143
+
144
+ let realPath = '';
145
+
146
+ /**
147
+ * We're using a module here so we want to keep using the module resolution procedure.
148
+ */
149
+ if (info?.packageName || info?.required) {
150
+ /**
151
+ * path.join, on windows, it uses backslashes to resolve path.
152
+ * The problem is that Webpack does not windows paths
153
+ * With this tool, we need to rely on "/" and not "\".
154
+ * This is the reason why '..\\..\\..\\node_modules\\@strapi\\plugin-content-type-builder/strapi-admin.js' was not working.
155
+ * The regexp at line 105 aims to replace the windows backslashes by standard slash so that webpack can deal with them.
156
+ * Backslash looks to work only for absolute paths with webpack => https://webpack.js.org/concepts/module-resolution/#absolute-paths
157
+ */
158
+ realPath = path.join(pathToPlugin, 'strapi-admin').replace(/\\/g, '/');
159
+ } else {
160
+ realPath = path
161
+ .join(path.relative(path.resolve(dest, 'admin', 'src'), pathToPlugin), 'strapi-admin')
162
+ .replace(/\\/g, '/');
163
+ }
164
+
165
+ return {
166
+ name,
167
+ pathToPlugin: realPath,
168
+ shortName,
169
+ };
170
+ });
171
+
172
+ const content = `
173
+ ${pluginsArray
174
+ .map(({ pathToPlugin, shortName }) => {
175
+ const req = `'${pathToPlugin}'`;
176
+
177
+ return `import ${shortName} from ${req};`;
178
+ })
179
+ .join('\n')}
180
+
181
+
182
+ const plugins = {
183
+ ${[...pluginsArray]
184
+ .map(({ name, shortName }) => {
185
+ return ` '${name}': ${shortName},`;
186
+ })
187
+ .join('\n')}
188
+ };
189
+
190
+ export default plugins;
191
+ `;
192
+
193
+ return asyncFs.writeFile(path.resolve(dest, 'admin', 'src', 'plugins.js'), content);
194
+ }
195
+
196
+ /**
197
+ * @param {string[]} pluginsPath – an array of paths to the plugins from the user's directory
198
+ * @returns {RegExp} a regex that will exclude _all_ node_modules except for the plugins in the pluginsPath array.
199
+ */
200
+ const createPluginsExcludePath = (pluginsPath = []) => {
201
+ /**
202
+ * If there aren't any plugins in the node_modules array, just return the node_modules regex
203
+ * without complicating it.
204
+ */
205
+ if (pluginsPath.length === 0) {
206
+ return /node_modules/;
207
+ }
208
+
209
+ return new RegExp(`node_modules/(?!(${pluginsPath.join('|')}))`);
210
+ };
211
+
212
+ module.exports = {
213
+ getPlugins,
214
+ filterPluginsByAdminEntry,
215
+ createPluginFile,
216
+ createPluginsExcludePath,
217
+ };
package/webpack.config.js CHANGED
@@ -13,7 +13,7 @@ const browserslistToEsbuild = require('browserslist-to-esbuild');
13
13
 
14
14
  const alias = require('./webpack.alias');
15
15
  const getClientEnvironment = require('./env');
16
- const { createPluginsExcludePath } = require('./utils/create-plugins-exclude-path');
16
+ const { createPluginsExcludePath } = require('./utils/plugins');
17
17
 
18
18
  module.exports = ({
19
19
  dest,
@@ -85,7 +85,7 @@ module.exports = ({
85
85
  module: {
86
86
  rules: [
87
87
  {
88
- test: /\.tsx?$/,
88
+ test: /\.(ts|tsx)$/,
89
89
  loader: require.resolve('esbuild-loader'),
90
90
  exclude: excludeRegex,
91
91
  options: {
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunk_strapi_admin=self.webpackChunk_strapi_admin||[]).push([[1227],{21227:function(g,E,t){t.d(E,{ReviewWorkflowsAssigneeEE:function(){return O},ReviewWorkflowsStageEE:function(){return f}});var e=t(32735),s=t(87933),c=t(72850),i=t(49372),r=t(45509),l=t(60216),n=t.n(l),o=t(2121),u=t(68886);function f({color:a,name:A}){const{themeColorName:R}=(0,u.k)(a);return e.createElement(s.k,{alignItems:"center",gap:2,maxWidth:(0,r.Q1)(300)},e.createElement(c.x,{height:2,background:a,borderColor:R==="neutral0"?"neutral150":"transparent",hasRadius:!0,shrink:0,width:2}),e.createElement(i.Z,{fontWeight:"regular",textColor:"neutral700",ellipsis:!0},A))}f.defaultProps={color:o.FT},f.propTypes={color:n().string,name:n().string.isRequired};var T=t(67879),W=t(69997);function O({user:a}){const{formatMessage:A}=(0,T.Z)();return e.createElement(i.Z,{textColor:"neutral800"},(0,W.Gf)(a,A))}O.propTypes={user:n().shape({firstname:n().string,lastname:n().string,username:n().string}).isRequired}},2121:function(g,E,t){t.d(E,{$k:function(){return o},Ef:function(){return O},FT:function(){return T},Nj:function(){return n},Ot:function(){return l},VS:function(){return u},_X:function(){return a},gu:function(){return c},lv:function(){return f},qZ:function(){return i},sN:function(){return s},uL:function(){return W},x4:function(){return r}});var e=t(12301);const s="settings_review-workflows",c="Settings/Review_Workflows/RESET_WORKFLOW",i="Settings/Review_Workflows/SET_WORKFLOW",r="Settings/Review_Workflows/WORKFLOW_DELETE_STAGE",l="Settings/Review_Workflows/WORKFLOW_ADD_STAGE",n="Settings/Review_Workflows/WORKFLOW_UPDATE_STAGE",o="Settings/Review_Workflows/WORKFLOW_UPDATE_STAGE_POSITION",u="Settings/Review_Workflows/WORKFLOW_UPDATE",f={primary600:"Blue",primary200:"Lilac",alternative600:"Violet",alternative200:"Lavender",success600:"Green",success200:"Pale Green",danger500:"Cherry",danger200:"Pink",warning600:"Orange",warning200:"Yellow",secondary600:"Teal",secondary200:"Baby Blue",neutral400:"Gray",neutral0:"White"},T=e.W.colors.primary600,W={STAGE:"stage"},O="numberOfWorkflows",a="stagesPerWorkflow"},68886:function(g,E,t){t.d(E,{k:function(){return c},s:function(){return i}});var e=t(12301),s=t(2121);function c(r){if(!r)return null;const n=Object.entries(e.W.colors).filter(([,o])=>o.toUpperCase()===r.toUpperCase()).reduce((o,[u])=>(s.lv?.[u]&&(o=u),o),null);return n?{themeColorName:n,name:s.lv[n]}:null}function i(){return Object.entries(s.lv).map(([r,l])=>({hex:e.W.colors[r].toUpperCase(),name:l}))}}}]);