@strapi/generators 4.2.0-alpha.O → 4.2.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 (89) hide show
  1. package/lib/files/{plugin → js/plugin}/admin/src/components/Initializer/index.js +0 -0
  2. package/lib/files/{plugin → js/plugin}/admin/src/components/PluginIcon/index.js +0 -0
  3. package/lib/files/{plugin → js/plugin}/admin/src/index.js +0 -0
  4. package/lib/files/{plugin → js/plugin}/admin/src/pages/App/index.js +0 -0
  5. package/lib/files/{plugin → js/plugin}/admin/src/pages/HomePage/index.js +2 -2
  6. package/lib/files/js/plugin/admin/src/pluginId.js +5 -0
  7. package/lib/files/{plugin → js/plugin}/admin/src/translations/en.json +0 -0
  8. package/lib/files/{plugin → js/plugin}/admin/src/translations/fr.json +0 -0
  9. package/lib/files/{plugin → js/plugin}/admin/src/utils/axiosInstance.js +0 -0
  10. package/lib/files/{plugin → js/plugin}/admin/src/utils/getTrad.js +0 -0
  11. package/lib/files/{plugin → js/plugin}/server/bootstrap.js +0 -0
  12. package/lib/files/{plugin → js/plugin}/server/config/index.js +0 -0
  13. package/lib/files/{plugin → js/plugin}/server/content-types/index.js +0 -0
  14. package/lib/files/{plugin → js/plugin}/server/controllers/index.js +0 -0
  15. package/lib/files/{plugin → js/plugin}/server/controllers/my-controller.js.hbs +2 -2
  16. package/lib/files/{plugin → js/plugin}/server/destroy.js +0 -0
  17. package/lib/files/{plugin → js/plugin}/server/index.js +0 -0
  18. package/lib/files/{plugin → js/plugin}/server/middlewares/index.js +0 -0
  19. package/lib/files/{plugin → js/plugin}/server/policies/index.js +0 -0
  20. package/lib/files/{plugin → js/plugin}/server/register.js +0 -0
  21. package/lib/files/{plugin → js/plugin}/server/routes/index.js +0 -0
  22. package/lib/files/{plugin → js/plugin}/server/services/index.js +0 -0
  23. package/lib/files/{plugin → js/plugin}/server/services/my-service.js +0 -0
  24. package/lib/files/{plugin → js/plugin}/strapi-admin.js +0 -0
  25. package/lib/files/{plugin → js/plugin}/strapi-server.js +0 -0
  26. package/lib/files/ts/plugin/admin/src/components/Initializer/index.tsx +25 -0
  27. package/lib/files/ts/plugin/admin/src/components/PluginIcon/index.tsx +12 -0
  28. package/lib/files/ts/plugin/admin/src/index.tsx +66 -0
  29. package/lib/files/ts/plugin/admin/src/pages/App/index.tsx +25 -0
  30. package/lib/files/ts/plugin/admin/src/pages/HomePage/index.tsx +19 -0
  31. package/lib/files/ts/plugin/admin/src/pluginId.ts +5 -0
  32. package/lib/files/ts/plugin/admin/src/translations/en.json +1 -0
  33. package/lib/files/ts/plugin/admin/src/translations/fr.json +1 -0
  34. package/lib/files/ts/plugin/admin/src/utils/axiosInstance.ts +40 -0
  35. package/lib/files/ts/plugin/admin/src/utils/getTrad.ts +5 -0
  36. package/lib/files/ts/plugin/server/bootstrap.ts +3 -0
  37. package/lib/files/ts/plugin/server/config/index.ts +4 -0
  38. package/lib/files/ts/plugin/server/content-types/index.ts +1 -0
  39. package/lib/files/ts/plugin/server/controllers/index.ts +5 -0
  40. package/lib/files/ts/plugin/server/controllers/my-controller.ts.hbs +8 -0
  41. package/lib/files/ts/plugin/server/destroy.ts +3 -0
  42. package/lib/files/ts/plugin/server/index.ts +23 -0
  43. package/lib/files/ts/plugin/server/middlewares/index.ts +1 -0
  44. package/lib/files/ts/plugin/server/policies/index.ts +1 -0
  45. package/lib/files/ts/plugin/server/register.ts +3 -0
  46. package/lib/files/ts/plugin/server/routes/index.ts +10 -0
  47. package/lib/files/ts/plugin/server/services/index.ts +5 -0
  48. package/lib/files/ts/plugin/server/services/my-service.ts +5 -0
  49. package/lib/files/ts/plugin/strapi-admin.js +3 -0
  50. package/lib/files/ts/plugin/strapi-server.js +3 -0
  51. package/lib/files/ts/plugin/tsconfig.json +25 -0
  52. package/lib/index.js +1 -1
  53. package/lib/plops/api.js +10 -6
  54. package/lib/plops/content-type.js +10 -7
  55. package/lib/plops/controller.js +6 -2
  56. package/lib/plops/middleware.js +7 -2
  57. package/lib/plops/plugin.js +26 -8
  58. package/lib/plops/policy.js +6 -2
  59. package/lib/plops/prompts/get-attributes-prompts.js +6 -3
  60. package/lib/plops/service.js +6 -2
  61. package/lib/plops/utils/validate-attribute-input.js +11 -0
  62. package/lib/templates/{README.md.hbs → js/README.md.hbs} +0 -0
  63. package/lib/templates/{collection-type-routes.js.hbs → js/collection-type-routes.js.hbs} +0 -0
  64. package/lib/templates/{content-type.schema.json.hbs → js/content-type.schema.json.hbs} +0 -0
  65. package/lib/templates/{controller.js.hbs → js/controller.js.hbs} +0 -0
  66. package/lib/templates/{core-controller.js.hbs → js/core-controller.js.hbs} +0 -0
  67. package/lib/templates/{core-router.js.hbs → js/core-router.js.hbs} +0 -0
  68. package/lib/templates/{core-service.js.hbs → js/core-service.js.hbs} +0 -0
  69. package/lib/templates/{middleware.js.hbs → js/middleware.js.hbs} +0 -0
  70. package/lib/templates/{plugin-package.json.hbs → js/plugin-package.json.hbs} +0 -0
  71. package/lib/templates/{policy.js.hbs → js/policy.js.hbs} +0 -0
  72. package/lib/templates/{service.js.hbs → js/service.js.hbs} +0 -0
  73. package/lib/templates/{single-route.js.hbs → js/single-route.js.hbs} +0 -0
  74. package/lib/templates/{single-type-routes.js.hbs → js/single-type-routes.js.hbs} +1 -1
  75. package/lib/templates/ts/README.md.hbs +3 -0
  76. package/lib/templates/ts/collection-type-routes.ts.hbs +49 -0
  77. package/lib/templates/ts/content-type.schema.json.hbs +15 -0
  78. package/lib/templates/ts/controller.ts.hbs +13 -0
  79. package/lib/templates/ts/core-controller.ts.hbs +7 -0
  80. package/lib/templates/ts/core-router.ts.hbs +7 -0
  81. package/lib/templates/ts/core-service.ts.hbs +7 -0
  82. package/lib/templates/ts/middleware.js.hbs +12 -0
  83. package/lib/templates/ts/plugin-package.json.hbs +32 -0
  84. package/lib/templates/ts/policy.ts.hbs +16 -0
  85. package/lib/templates/ts/service.ts.hbs +5 -0
  86. package/lib/templates/ts/single-route.ts.hbs +13 -0
  87. package/lib/templates/ts/single-type-routes.ts.hbs +31 -0
  88. package/package.json +4 -3
  89. package/lib/files/plugin/admin/src/pluginId.js +0 -5
@@ -4,7 +4,7 @@
4
4
  *
5
5
  */
6
6
 
7
- import React, { memo } from 'react';
7
+ import React from 'react';
8
8
  // import PropTypes from 'prop-types';
9
9
  import pluginId from '../../pluginId';
10
10
 
@@ -17,4 +17,4 @@ const HomePage = () => {
17
17
  );
18
18
  };
19
19
 
20
- export default memo(HomePage);
20
+ export default HomePage;
@@ -0,0 +1,5 @@
1
+ import pluginPkg from '../../package.json';
2
+
3
+ const pluginId = pluginPkg.name.replace(/^(@[^-,.][\w,-]+\/|strapi-)plugin-/i, '');
4
+
5
+ export default pluginId;
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- module.exports = {
3
+ module.exports = ({ strapi }) => ({
4
4
  index(ctx) {
5
5
  ctx.body = strapi
6
6
  .plugin('{{ pluginName }}')
7
7
  .service('myService')
8
8
  .getWelcomeMessage();
9
9
  },
10
- };
10
+ });
File without changes
File without changes
File without changes
@@ -0,0 +1,25 @@
1
+ /**
2
+ *
3
+ * Initializer
4
+ *
5
+ */
6
+
7
+ import React, { useEffect, useRef } from 'react';
8
+ import pluginId from '../../pluginId';
9
+
10
+ type InitializerProps = {
11
+ setPlugin: (id: string) => void;
12
+ };
13
+
14
+ const Initializer: React.FC<InitializerProps> = ({ setPlugin }) => {
15
+ const ref = useRef<(id: string) => void | null>(null);
16
+ ref.current = setPlugin;
17
+
18
+ useEffect(() => {
19
+ ref.current(pluginId);
20
+ }, []);
21
+
22
+ return null;
23
+ };
24
+
25
+ export default Initializer;
@@ -0,0 +1,12 @@
1
+ /**
2
+ *
3
+ * PluginIcon
4
+ *
5
+ */
6
+
7
+ import React from 'react';
8
+ import Puzzle from '@strapi/icons/Puzzle';
9
+
10
+ const PluginIcon: React.VoidFunctionComponent = () => <Puzzle />;
11
+
12
+ export default PluginIcon;
@@ -0,0 +1,66 @@
1
+ import React from 'react';
2
+ import { prefixPluginTranslations } from '@strapi/helper-plugin';
3
+ import pluginPkg from '../../package.json';
4
+ import pluginId from './pluginId';
5
+ import Initializer from './components/Initializer';
6
+ import PluginIcon from './components/PluginIcon';
7
+
8
+ const name = pluginPkg.strapi.name;
9
+
10
+ export default {
11
+ register(app) {
12
+ app.addMenuLink({
13
+ to: `/plugins/${pluginId}`,
14
+ icon: PluginIcon,
15
+ intlLabel: {
16
+ id: `${pluginId}.plugin.name`,
17
+ defaultMessage: name,
18
+ },
19
+ Component: async () => {
20
+ const component = await import(/* webpackChunkName: "[request]" */ './pages/App');
21
+
22
+ return component;
23
+ },
24
+ permissions: [
25
+ // Uncomment to set the permissions of the plugin here
26
+ // {
27
+ // action: '', // the action name should be plugin::plugin-name.actionType
28
+ // subject: null,
29
+ // },
30
+ ],
31
+ });
32
+ const plugin = {
33
+ id: pluginId,
34
+ initializer: Initializer,
35
+ isReady: false,
36
+ name,
37
+ };
38
+
39
+ app.registerPlugin(plugin);
40
+ },
41
+
42
+ bootstrap(app) {},
43
+ async registerTrads(app) {
44
+ const { locales } = app;
45
+
46
+ const importedTrads = await Promise.all(
47
+ locales.map(locale => {
48
+ return import(`./translations/${locale}.json`)
49
+ .then(({ default: data }) => {
50
+ return {
51
+ data: prefixPluginTranslations(data, pluginId),
52
+ locale,
53
+ };
54
+ })
55
+ .catch(() => {
56
+ return {
57
+ data: {},
58
+ locale,
59
+ };
60
+ });
61
+ })
62
+ );
63
+
64
+ return Promise.resolve(importedTrads);
65
+ },
66
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ *
3
+ * This component is the skeleton around the actual pages, and should only
4
+ * contain code that should be seen on all pages. (e.g. navigation bar)
5
+ *
6
+ */
7
+
8
+ import React from 'react';
9
+ import { Switch, Route } from 'react-router-dom';
10
+ import { NotFound } from '@strapi/helper-plugin';
11
+ import pluginId from '../../pluginId';
12
+ import HomePage from '../HomePage';
13
+
14
+ const App: React.VoidFunctionComponent = () => {
15
+ return (
16
+ <div>
17
+ <Switch>
18
+ <Route path={`/plugins/${pluginId}`} component={HomePage} exact />
19
+ <Route component={NotFound} />
20
+ </Switch>
21
+ </div>
22
+ );
23
+ };
24
+
25
+ export default App;
@@ -0,0 +1,19 @@
1
+ /*
2
+ *
3
+ * HomePage
4
+ *
5
+ */
6
+
7
+ import React from 'react';
8
+ import pluginId from '../../pluginId';
9
+
10
+ const HomePage: React.VoidFunctionComponent = () => {
11
+ return (
12
+ <div>
13
+ <h1>{pluginId}&apos;s HomePage</h1>
14
+ <p>Happy coding</p>
15
+ </div>
16
+ );
17
+ };
18
+
19
+ export default HomePage;
@@ -0,0 +1,5 @@
1
+ import pluginPkg from '../../package.json';
2
+
3
+ const pluginId = pluginPkg.name.replace(/^(@[^-,.][\w,-]+\/|strapi-)plugin-/i, '');
4
+
5
+ export default pluginId;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * axios with a custom config.
3
+ */
4
+
5
+ import axios from 'axios';
6
+ import { auth } from '@strapi/helper-plugin';
7
+
8
+ const instance = axios.create({
9
+ baseURL: process.env.STRAPI_ADMIN_BACKEND_URL,
10
+ });
11
+
12
+ instance.interceptors.request.use(
13
+ async (config) => {
14
+ config.headers = {
15
+ Authorization: `Bearer ${auth.getToken()}`,
16
+ Accept: 'application/json',
17
+ 'Content-Type': 'application/json',
18
+ };
19
+
20
+ return config;
21
+ },
22
+ (error) => {
23
+ Promise.reject(error);
24
+ }
25
+ );
26
+
27
+ instance.interceptors.response.use(
28
+ (response) => response,
29
+ (error) => {
30
+ // whatever you want to do with the error
31
+ if (error.response?.status === 401) {
32
+ auth.clearAppStorage();
33
+ window.location.reload();
34
+ }
35
+
36
+ throw error;
37
+ }
38
+ );
39
+
40
+ export default instance;
@@ -0,0 +1,5 @@
1
+ import pluginId from '../pluginId';
2
+
3
+ const getTrad = (id: string) => `${pluginId}.${id}`;
4
+
5
+ export default getTrad;
@@ -0,0 +1,3 @@
1
+ export default ({ strapi }) => {
2
+ // bootstrap phase
3
+ };
@@ -0,0 +1,4 @@
1
+ export default {
2
+ default: {},
3
+ validator() {},
4
+ };
@@ -0,0 +1 @@
1
+ export default {};
@@ -0,0 +1,5 @@
1
+ import myController from './my-controller';
2
+
3
+ export default {
4
+ myController,
5
+ };
@@ -0,0 +1,8 @@
1
+ export default ({ strapi }) => ({
2
+ index(ctx) {
3
+ ctx.body = strapi
4
+ .plugin('{{ pluginName }}')
5
+ .service('myService')
6
+ .getWelcomeMessage();
7
+ },
8
+ });
@@ -0,0 +1,3 @@
1
+ export default ({ strapi }) => {
2
+ // destroy phase
3
+ };
@@ -0,0 +1,23 @@
1
+ import register from './register';
2
+ import bootstrap from './bootstrap';
3
+ import destroy from './destroy';
4
+ import config from './config';
5
+ import contentTypes from './content-types';
6
+ import controllers from './controllers';
7
+ import routes from './routes';
8
+ import middlewares from './middlewares';
9
+ import policies from './policies';
10
+ import services from './services';
11
+
12
+ export default {
13
+ register,
14
+ bootstrap,
15
+ destroy,
16
+ config,
17
+ controllers,
18
+ routes,
19
+ services,
20
+ contentTypes,
21
+ policies,
22
+ middlewares,
23
+ };
@@ -0,0 +1 @@
1
+ export default {};
@@ -0,0 +1 @@
1
+ export default {};
@@ -0,0 +1,3 @@
1
+ export default ({ strapi }) => {
2
+ // registeration phase
3
+ };
@@ -0,0 +1,10 @@
1
+ export default [
2
+ {
3
+ method: 'GET',
4
+ path: '/',
5
+ handler: 'myController.index',
6
+ config: {
7
+ policies: [],
8
+ },
9
+ },
10
+ ];
@@ -0,0 +1,5 @@
1
+ import myService from './my-service';
2
+
3
+ export default {
4
+ myService,
5
+ };
@@ -0,0 +1,5 @@
1
+ export default ({ strapi }) => ({
2
+ getWelcomeMessage() {
3
+ return 'Welcome to Strapi 🚀';
4
+ },
5
+ });
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ module.exports = require('./admin/src').default;
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ module.exports = require('./dist/server');
@@ -0,0 +1,25 @@
1
+ {
2
+ "extends": "@strapi/typescript-utils/lib/configs/server",
3
+
4
+ "compilerOptions": {
5
+ "outDir": "dist",
6
+ "rootDir": "."
7
+ },
8
+
9
+ "include": [
10
+ // Include the root directory
11
+ "server",
12
+ // Force the JSON files in the src folder to be included
13
+ "server/**/*.json"
14
+ ],
15
+
16
+ "exclude": [
17
+ "node_modules/",
18
+ "dist/",
19
+
20
+ // Do not include admin files in the server compilation
21
+ "admin/",
22
+ // Do not include test files
23
+ "**/*.test.ts"
24
+ ]
25
+ }
package/lib/index.js CHANGED
@@ -7,7 +7,7 @@ const nodePlop = require('node-plop');
7
7
  /**
8
8
  * Starts the Plop CLI programmatically
9
9
  */
10
- const runCLI = () => {
10
+ const runCLI = async () => {
11
11
  Plop.launch({ configPath: join(__dirname, 'plopfile.js') }, env =>
12
12
  run({ ...env, dest: join(process.cwd(), 'src') }, undefined, true)
13
13
  );
package/lib/plops/api.js CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  const { join } = require('path');
4
4
  const fs = require('fs-extra');
5
+ const tsUtils = require('@strapi/typescript-utils');
6
+
5
7
  const validateInput = require('./utils/validate-input');
6
8
 
7
9
  module.exports = plop => {
@@ -46,17 +48,19 @@ module.exports = plop => {
46
48
  ],
47
49
  actions(answers) {
48
50
  const filePath = answers.isPluginApi && answers.plugin ? 'plugins/{{plugin}}' : 'api/{{id}}';
51
+ const currentDir = process.cwd();
52
+ const language = tsUtils.isUsingTypeScriptSync(currentDir) ? 'ts' : 'js';
49
53
 
50
54
  const baseActions = [
51
55
  {
52
56
  type: 'add',
53
- path: `${filePath}/controllers/{{id}}.js`,
54
- templateFile: 'templates/controller.js.hbs',
57
+ path: `${filePath}/controllers/{{id}}.${language}`,
58
+ templateFile: `templates/${language}/controller.${language}.hbs`,
55
59
  },
56
60
  {
57
61
  type: 'add',
58
- path: `${filePath}/services/{{id}}.js`,
59
- templateFile: 'templates/service.js.hbs',
62
+ path: `${filePath}/services/{{id}}.${language}`,
63
+ templateFile: `templates/${language}/service.${language}.hbs`,
60
64
  },
61
65
  ];
62
66
 
@@ -67,8 +71,8 @@ module.exports = plop => {
67
71
  return [
68
72
  {
69
73
  type: 'add',
70
- path: `${filePath}/routes/{{id}}.js`,
71
- templateFile: `templates/single-route.js.hbs`,
74
+ path: `${filePath}/routes/{{id}}.${language}`,
75
+ templateFile: `templates/${language}/single-route.${language}.hbs`,
72
76
  },
73
77
  ...baseActions,
74
78
  ];
@@ -4,6 +4,7 @@ const { join } = require('path');
4
4
  const slugify = require('@sindresorhus/slugify');
5
5
  const fs = require('fs-extra');
6
6
  const { isKebabCase } = require('@strapi/utils');
7
+ const tsUtils = require('@strapi/typescript-utils');
7
8
 
8
9
  const getDestinationPrompts = require('./prompts/get-destination-prompts');
9
10
  const getFilePath = require('./utils/get-file-path');
@@ -81,12 +82,14 @@ module.exports = plop => {
81
82
  }, {});
82
83
 
83
84
  const filePath = getFilePath(answers.destination);
85
+ const currentDir = process.cwd();
86
+ const language = tsUtils.isUsingTypeScriptSync(currentDir) ? 'ts' : 'js';
84
87
 
85
88
  const baseActions = [
86
89
  {
87
90
  type: 'add',
88
91
  path: `${filePath}/content-types/{{ singularName }}/schema.json`,
89
- templateFile: 'templates/content-type.schema.json.hbs',
92
+ templateFile: `templates/${language}/content-type.schema.json.hbs`,
90
93
  data: {
91
94
  collectionName: slugify(answers.pluralName, { separator: '_' }),
92
95
  },
@@ -120,20 +123,20 @@ module.exports = plop => {
120
123
  baseActions.push(
121
124
  {
122
125
  type: 'add',
123
- path: `${filePath}/controllers/{{singularName}}.js`,
124
- templateFile: 'templates/core-controller.js.hbs',
126
+ path: `${filePath}/controllers/{{singularName}}.${language}`,
127
+ templateFile: `templates/${language}/core-controller.${language}.hbs`,
125
128
  data: { uid },
126
129
  },
127
130
  {
128
131
  type: 'add',
129
- path: `${filePath}/services/{{singularName}}.js`,
130
- templateFile: 'templates/core-service.js.hbs',
132
+ path: `${filePath}/services/{{singularName}}.${language}`,
133
+ templateFile: `templates/${language}/core-service.${language}.hbs`,
131
134
  data: { uid },
132
135
  },
133
136
  {
134
137
  type: 'add',
135
- path: `${filePath}/routes/{{singularName}}.js`,
136
- templateFile: `templates/core-router.js.hbs`,
138
+ path: `${filePath}/routes/{{singularName}}.${language}`,
139
+ templateFile: `templates/${language}/core-router.${language}.hbs`,
137
140
  data: { uid },
138
141
  }
139
142
  );
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ const tsUtils = require('@strapi/typescript-utils');
4
+
3
5
  const getDestinationPrompts = require('./prompts/get-destination-prompts');
4
6
  const getFilePath = require('./utils/get-file-path');
5
7
  const validateInput = require('./utils/validate-input');
@@ -19,12 +21,14 @@ module.exports = plop => {
19
21
  ],
20
22
  actions(answers) {
21
23
  const filePath = getFilePath(answers.destination);
24
+ const currentDir = process.cwd();
25
+ const language = tsUtils.isUsingTypeScriptSync(currentDir) ? 'ts' : 'js';
22
26
 
23
27
  return [
24
28
  {
25
29
  type: 'add',
26
- path: `${filePath}/controllers/{{ id }}.js`,
27
- templateFile: 'templates/controller.js.hbs',
30
+ path: `${filePath}/controllers/{{ id }}.${language}`,
31
+ templateFile: `templates/${language}/controller.${language}.hbs`,
28
32
  },
29
33
  ];
30
34
  },
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ const tsUtils = require('@strapi/typescript-utils');
4
+
3
5
  const getDestinationPrompts = require('./prompts/get-destination-prompts');
4
6
  const getFilePath = require('./utils/get-file-path');
5
7
 
@@ -17,11 +19,14 @@ module.exports = plop => {
17
19
  ],
18
20
  actions(answers) {
19
21
  const filePath = getFilePath(answers.destination);
22
+ const currentDir = process.cwd();
23
+ const language = tsUtils.isUsingTypeScriptSync(currentDir) ? 'ts' : 'js';
24
+
20
25
  return [
21
26
  {
22
27
  type: 'add',
23
- path: `${filePath}/middlewares/{{ name }}.js`,
24
- templateFile: 'templates/middleware.js.hbs',
28
+ path: `${filePath}/middlewares/{{ name }}.${language}`,
29
+ templateFile: `templates/${language}/middleware.${language}.hbs`,
25
30
  },
26
31
  ];
27
32
  },
@@ -1,17 +1,22 @@
1
1
  'use strict';
2
2
 
3
3
  const chalk = require('chalk');
4
+ const { isUsingTypeScriptSync } = require('@strapi/typescript-utils');
4
5
 
5
- const logInstructions = pluginName => {
6
+ const logInstructions = (pluginName, { language }) => {
6
7
  const maxLength = ` resolve: './src/plugins/${pluginName}'`.length;
7
8
  const separator = Array(maxLength)
8
9
  .fill('─')
9
10
  .join('');
10
11
 
12
+ const exportInstruction = language === 'js' ? 'module.exports =' : 'export default';
13
+
11
14
  return `
12
- You can now enable your plugin by adding the following in ${chalk.yellow('./config/plugins.js')}.
15
+ You can now enable your plugin by adding the following in ${chalk.yellow(
16
+ `./config/plugins.${language}`
17
+ )}
13
18
  ${separator}
14
- module.exports = {
19
+ ${exportInstruction} {
15
20
  ${chalk.gray('// ...')}
16
21
  ${chalk.green(`'${pluginName}'`)}: {
17
22
  enabled: ${chalk.yellow(true)},
@@ -33,26 +38,39 @@ module.exports = plop => {
33
38
  name: 'pluginName',
34
39
  message: 'Plugin name',
35
40
  },
41
+ {
42
+ type: 'list',
43
+ name: 'language',
44
+ message: 'Choose your preferred language',
45
+ choices: ['Javascript', 'Typescript'],
46
+ default: 'Javascript',
47
+ },
36
48
  ],
37
49
  actions(answers) {
50
+ const isTypescript = answers.language === 'Typescript';
51
+ const language = isTypescript ? 'ts' : 'js';
52
+ const projectLanguage = isUsingTypeScriptSync(process.cwd()) ? 'ts' : 'js';
53
+
54
+ // TODO: Adds tsconfig & build command for TS plugins?
55
+
38
56
  return [
39
57
  {
40
58
  type: 'addMany',
41
59
  destination: 'plugins/{{ pluginName }}',
42
- base: 'files/plugin',
43
- templateFiles: 'files/plugin/**',
60
+ base: `files/${language}/plugin`,
61
+ templateFiles: `files/${language}/plugin/**`,
44
62
  },
45
63
  {
46
64
  type: 'add',
47
65
  path: 'plugins/{{ pluginName }}/README.md',
48
- templateFile: 'templates/README.md.hbs',
66
+ templateFile: `templates/${language}/README.md.hbs`,
49
67
  },
50
68
  {
51
69
  type: 'add',
52
70
  path: 'plugins/{{ pluginName }}/package.json',
53
- templateFile: 'templates/plugin-package.json.hbs',
71
+ templateFile: `templates/${language}/plugin-package.json.hbs`,
54
72
  },
55
- () => plop.renderString(logInstructions(answers.pluginName)),
73
+ () => plop.renderString(logInstructions(answers.pluginName, { language: projectLanguage })),
56
74
  ];
57
75
  },
58
76
  });
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ const tsUtils = require('@strapi/typescript-utils');
4
+
3
5
  const getDestinationPrompts = require('./prompts/get-destination-prompts');
4
6
  const getFilePath = require('./utils/get-file-path');
5
7
 
@@ -17,12 +19,14 @@ module.exports = plop => {
17
19
  ],
18
20
  actions(answers) {
19
21
  const filePath = getFilePath(answers.destination);
22
+ const currentDir = process.cwd();
23
+ const language = tsUtils.isUsingTypeScriptSync(currentDir) ? 'ts' : 'js';
20
24
 
21
25
  return [
22
26
  {
23
27
  type: 'add',
24
- path: `${filePath}/policies/{{id}}.js`,
25
- templateFile: 'templates/policy.js.hbs',
28
+ path: `${filePath}/policies/{{id}}.${language}`,
29
+ templateFile: `templates/${language}/policy.${language}.hbs`,
26
30
  },
27
31
  ];
28
32
  },
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const validateInput = require('../utils/validate-input');
3
+ const validateAttributeInput = require('../utils/validate-attribute-input');
4
4
 
5
5
  const DEFAULT_TYPES = [
6
6
  // advanced types
@@ -50,7 +50,7 @@ module.exports = async inquirer => {
50
50
  type: 'input',
51
51
  name: 'attributeName',
52
52
  message: 'Name of attribute',
53
- validate: input => validateInput(input),
53
+ validate: input => validateAttributeInput(input),
54
54
  },
55
55
  {
56
56
  type: 'list',
@@ -72,7 +72,10 @@ module.exports = async inquirer => {
72
72
  type: 'list',
73
73
  name: 'multiple',
74
74
  message: 'Choose media type',
75
- choices: [{ name: 'Multiple', value: true }, { name: 'Single', value: false }],
75
+ choices: [
76
+ { name: 'Multiple', value: true },
77
+ { name: 'Single', value: false },
78
+ ],
76
79
  },
77
80
  {
78
81
  type: 'confirm',
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ const tsUtils = require('@strapi/typescript-utils');
4
+
3
5
  const getDestinationPrompts = require('./prompts/get-destination-prompts');
4
6
  const getFilePath = require('./utils/get-file-path');
5
7
 
@@ -17,12 +19,14 @@ module.exports = plop => {
17
19
  ],
18
20
  actions(answers) {
19
21
  const filePath = getFilePath(answers.destination);
22
+ const currentDir = process.cwd();
23
+ const language = tsUtils.isUsingTypeScriptSync(currentDir) ? 'ts' : 'js';
20
24
 
21
25
  return [
22
26
  {
23
27
  type: 'add',
24
- path: `${filePath}/services/{{ id }}.js`,
25
- templateFile: 'templates/service.js.hbs',
28
+ path: `${filePath}/services/{{ id }}.${language}`,
29
+ templateFile: `templates/${language}/service.${language}.hbs`,
26
30
  },
27
31
  ];
28
32
  },
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ module.exports = input => {
4
+ const regex = /^[A-Za-z-|_]+$/g;
5
+
6
+ if (!input) {
7
+ return 'You must provide an input';
8
+ }
9
+
10
+ return regex.test(input) || "Please use only letters, '-', '_', and no spaces";
11
+ };
@@ -1,4 +1,4 @@
1
- module.exports = {
1
+ export default {
2
2
  routes: [
3
3
  {
4
4
  method: 'GET',
@@ -0,0 +1,3 @@
1
+ # Strapi plugin {{ pluginName }}
2
+
3
+ A quick description of {{ pluginName }}.
@@ -0,0 +1,49 @@
1
+ module.exports = {
2
+ routes: [
3
+ {
4
+ method: 'GET',
5
+ path: '/{{pluralize id}}',
6
+ handler: '{{id}}.find',
7
+ config: {
8
+ policies: [],
9
+ middlewares: [],
10
+ },
11
+ },
12
+ {
13
+ method: 'GET',
14
+ path: '/{{pluralize id}}/:id',
15
+ handler: '{{id}}.findOne',
16
+ config: {
17
+ policies: [],
18
+ middlewares: [],
19
+ },
20
+ },
21
+ {
22
+ method: 'POST',
23
+ path: '/{{pluralize id}}',
24
+ handler: '{{id}}.create',
25
+ config: {
26
+ policies: [],
27
+ middlewares: [],
28
+ },
29
+ },
30
+ {
31
+ method: 'PUT',
32
+ path: '/{{pluralize id}}/:id',
33
+ handler: '{{id}}.update',
34
+ config: {
35
+ policies: [],
36
+ middlewares: [],
37
+ },
38
+ },
39
+ {
40
+ method: 'DELETE',
41
+ path: '/{{pluralize id}}/:id',
42
+ handler: '{{id}}.delete',
43
+ config: {
44
+ policies: [],
45
+ middlewares: [],
46
+ },
47
+ },
48
+ ],
49
+ };
@@ -0,0 +1,15 @@
1
+
2
+ {
3
+ "kind": "{{kind}}",
4
+ "collectionName": "{{ collectionName }}",
5
+ "info": {
6
+ "singularName": "{{ singularName }}",
7
+ "pluralName": "{{ pluralName }}",
8
+ "displayName": "{{ displayName }}"
9
+ },
10
+ "options": {
11
+ "draftAndPublish": {{ useDraftAndPublish }},
12
+ "comment": ""
13
+ },
14
+ "attributes": {}
15
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * A set of functions called "actions" for `{{id}}`
3
+ */
4
+
5
+ export default {
6
+ // exampleAction: async (ctx, next) => {
7
+ // try {
8
+ // ctx.body = 'ok';
9
+ // } catch (err) {
10
+ // ctx.body = err;
11
+ // }
12
+ // }
13
+ };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * {{ id }} controller
3
+ */
4
+
5
+ import { factories } from '@strapi/strapi'
6
+
7
+ export default factories.createCoreController('{{ uid }}');
@@ -0,0 +1,7 @@
1
+ /**
2
+ * {{ id }} router.
3
+ */
4
+
5
+ import { factories } from '@strapi/strapi';
6
+
7
+ export default factories.createCoreRouter('{{ uid }}');
@@ -0,0 +1,7 @@
1
+ /**
2
+ * {{ id }} service.
3
+ */
4
+
5
+ import { factories } from '@strapi/strapi';
6
+
7
+ export default factories.createCoreService('{{ uid }}');
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `{{ name }}` middleware.
3
+ */
4
+
5
+ export default (config, { strapi }) => {
6
+ // Add your own logic here.
7
+ return async (ctx, next) => {
8
+ strapi.log.info('In {{ name }} middleware.');
9
+
10
+ await next();
11
+ };
12
+ };
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "{{ pluginName }}",
3
+ "version": "0.0.0",
4
+ "description": "This is the description of the plugin.",
5
+ "strapi": {
6
+ "name": "{{ pluginName }}",
7
+ "description": "Description of {{ pluginName }} plugin",
8
+ "kind": "plugin"
9
+ },
10
+ "dependencies": {},
11
+ "devDependencies": {
12
+ "typescript": "4.6.3",
13
+ "@strapi/strapi": "4.1.8"
14
+ },
15
+ "author": {
16
+ "name": "A Strapi developer"
17
+ },
18
+ "maintainers": [
19
+ {
20
+ "name": "A Strapi developer"
21
+ }
22
+ ],
23
+ "engines": {
24
+ "node": ">=12.x.x <=16.x.x",
25
+ "npm": ">=6.0.0"
26
+ },
27
+ "scripts": {
28
+ "develop": "tsc -w",
29
+ "build": "tsc"
30
+ },
31
+ "license": "MIT"
32
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `{{id}}` policy.
3
+ */
4
+
5
+ export default (policyContext, config, { strapi }) => {
6
+ // Add your own logic here.
7
+ strapi.log.info('In {{id}} policy.');
8
+
9
+ const canDoSomething = true;
10
+
11
+ if (canDoSomething) {
12
+ return true;
13
+ }
14
+
15
+ return false;
16
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * {{id}} service.
3
+ */
4
+
5
+ export default () => ({});
@@ -0,0 +1,13 @@
1
+ export default {
2
+ routes: [
3
+ // {
4
+ // method: 'GET',
5
+ // path: '/{{id}}',
6
+ // handler: '{{id}}.exampleAction',
7
+ // config: {
8
+ // policies: [],
9
+ // middlewares: [],
10
+ // },
11
+ // },
12
+ ],
13
+ };
@@ -0,0 +1,31 @@
1
+ export default {
2
+ routes: [
3
+ {
4
+ method: 'GET',
5
+ path: '/{{id}}',
6
+ handler: '{{id}}.find',
7
+ config: {
8
+ policies: [],
9
+ middlewares: [],
10
+ },
11
+ },
12
+ {
13
+ method: 'PUT',
14
+ path: '/{{id}}',
15
+ handler: '{{id}}.update',
16
+ config: {
17
+ policies: [],
18
+ middlewares: [],
19
+ },
20
+ },
21
+ {
22
+ method: 'DELETE',
23
+ path: '/{{id}}',
24
+ handler: '{{id}}.delete',
25
+ config: {
26
+ policies: [],
27
+ middlewares: [],
28
+ },
29
+ },
30
+ ],
31
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/generators",
3
- "version": "4.2.0-alpha.O",
3
+ "version": "4.2.0-beta.2",
4
4
  "description": "Interactive API generator.",
5
5
  "keywords": [
6
6
  "strapi",
@@ -30,7 +30,8 @@
30
30
  "main": "lib/index.js",
31
31
  "dependencies": {
32
32
  "@sindresorhus/slugify": "1.1.0",
33
- "@strapi/utils": "4.2.0-alpha.O",
33
+ "@strapi/typescript-utils": "4.2.0-beta.2",
34
+ "@strapi/utils": "4.2.0-beta.2",
34
35
  "chalk": "4.1.2",
35
36
  "fs-extra": "10.0.0",
36
37
  "node-plop": "0.26.3",
@@ -41,5 +42,5 @@
41
42
  "node": ">=12.22.0 <=16.x.x",
42
43
  "npm": ">=6.0.0"
43
44
  },
44
- "gitHead": "0e1f1ae08565a5f2427753582f37645a43c00cb2"
45
+ "gitHead": "bff73257e7695d6f361c91dda8cc810a2bb70b6e"
45
46
  }
@@ -1,5 +0,0 @@
1
- const pluginPkg = require('../../package.json');
2
-
3
- const pluginId = pluginPkg.name.replace(/^@strapi\/plugin-/i, '');
4
-
5
- module.exports = pluginId;