diff --git a/packages/generators/generate-plop/files/admin/src/containers/App/index.js b/packages/generators/generate-plop/files/admin/src/containers/App/index.js new file mode 100644 index 0000000000..b2d80ef744 --- /dev/null +++ b/packages/generators/generate-plop/files/admin/src/containers/App/index.js @@ -0,0 +1,25 @@ +/** + * + * This component is the skeleton around the actual pages, and should only + * contain code that should be seen on all pages. (e.g. navigation bar) + * + */ + +import React from 'react'; +import { Switch, Route } from 'react-router-dom'; +import { NotFound } from '@strapi/helper-plugin'; +import pluginId from '../../pluginId'; +import HomePage from '../HomePage'; + +const App = () => { + return ( +
+ + + + +
+ ); +}; + +export default App; diff --git a/packages/generators/generate-plop/files/admin/src/containers/HomePage/index.js b/packages/generators/generate-plop/files/admin/src/containers/HomePage/index.js new file mode 100644 index 0000000000..05c5a6a377 --- /dev/null +++ b/packages/generators/generate-plop/files/admin/src/containers/HomePage/index.js @@ -0,0 +1,20 @@ +/* + * + * HomePage + * + */ + +import React, { memo } from 'react'; +// import PropTypes from 'prop-types'; +import pluginId from '../../pluginId'; + +const HomePage = () => { + return ( +
+

{pluginId}'s HomePage

+

Happy coding

+
+ ); +}; + +export default memo(HomePage); diff --git a/packages/generators/generate-plop/files/admin/src/containers/Initializer/index.js b/packages/generators/generate-plop/files/admin/src/containers/Initializer/index.js new file mode 100644 index 0000000000..71dc50e94c --- /dev/null +++ b/packages/generators/generate-plop/files/admin/src/containers/Initializer/index.js @@ -0,0 +1,26 @@ +/** + * + * Initializer + * + */ + +import { useEffect, useRef } from 'react'; +import PropTypes from 'prop-types'; +import pluginId from '../../pluginId'; + +const Initializer = ({ setPlugin }) => { + const ref = useRef(); + ref.current = setPlugin; + + useEffect(() => { + ref.current(pluginId); + }, []); + + return null; +}; + +Initializer.propTypes = { + setPlugin: PropTypes.func.isRequired, +}; + +export default Initializer; diff --git a/packages/generators/generate-plop/files/admin/src/index.js b/packages/generators/generate-plop/files/admin/src/index.js new file mode 100644 index 0000000000..704e4277d8 --- /dev/null +++ b/packages/generators/generate-plop/files/admin/src/index.js @@ -0,0 +1,62 @@ +import { prefixPluginTranslations } from '@strapi/helper-plugin'; +import pluginPkg from '../../package.json'; +import pluginId from './pluginId'; +import App from './containers/App'; +import Initializer from './containers/Initializer'; + +const pluginDescription = pluginPkg.strapi.description || pluginPkg.description; +const icon = pluginPkg.strapi.icon; +const name = pluginPkg.strapi.name; + +export default { + register(app) { + app.addMenuLink({ + to: `/plugins/${pluginId}`, + icon, + intlLabel: { + id: `${pluginId}.plugin.name`, + defaultMessage: name, + }, + Component: App, + permissions: [ + // Uncomment to set the permissions of the plugin here + // { + // action: '', // the action name should be plugins::plugin-name.actionType + // subject: null, + // }, + ], + }); + app.registerPlugin({ + description: pluginDescription, + icon, + id: pluginId, + initializer: Initializer, + isReady: false, + isRequired: pluginPkg.strapi.required || false, + name, + }); + }, + // eslint-disable-next-line + bootstrap(app) {}, + async registerTrads({ locales }) { + const importedTrads = await Promise.all( + locales.map(locale => { + return import(`./translations/${locale}.json`) + .then(({ default: data }) => { + return { + data: prefixPluginTranslations(data, pluginId), + locale, + }; + }) + .catch(() => { + return { + data: {}, + locale, + }; + }); + }) + ); + + return Promise.resolve(importedTrads); + }, +}; diff --git a/packages/generators/generate-plop/files/admin/src/pluginId.js b/packages/generators/generate-plop/files/admin/src/pluginId.js new file mode 100644 index 0000000000..f604a009da --- /dev/null +++ b/packages/generators/generate-plop/files/admin/src/pluginId.js @@ -0,0 +1,5 @@ +const pluginPkg = require('../../package.json'); + +const pluginId = pluginPkg.name.replace(/^@strapi\/plugin-/i, ''); + +module.exports = pluginId; diff --git a/packages/generators/generate-plop/files/admin/src/translations/en.json b/packages/generators/generate-plop/files/admin/src/translations/en.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/generators/generate-plop/files/admin/src/translations/en.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/generators/generate-plop/files/admin/src/translations/fr.json b/packages/generators/generate-plop/files/admin/src/translations/fr.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/generators/generate-plop/files/admin/src/translations/fr.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/generators/generate-plop/files/admin/src/utils/getTrad.js b/packages/generators/generate-plop/files/admin/src/utils/getTrad.js new file mode 100644 index 0000000000..a2b8632a8d --- /dev/null +++ b/packages/generators/generate-plop/files/admin/src/utils/getTrad.js @@ -0,0 +1,5 @@ +import pluginId from '../pluginId'; + +const getTrad = id => `${pluginId}.${id}`; + +export default getTrad; diff --git a/packages/generators/generate-plop/package.json b/packages/generators/generate-plop/package.json index 900c86e010..d241f5842d 100644 --- a/packages/generators/generate-plop/package.json +++ b/packages/generators/generate-plop/package.json @@ -5,6 +5,7 @@ "main": "index.js", "license": "MIT", "dependencies": { + "fs-extra": "10.0.0", "plop": "2.7.4" } } diff --git a/packages/generators/generate-plop/plopfile.js b/packages/generators/generate-plop/plopfile.js index d3d469b8ff..2640a23c7f 100644 --- a/packages/generators/generate-plop/plopfile.js +++ b/packages/generators/generate-plop/plopfile.js @@ -1,8 +1,12 @@ 'use strict'; const { join } = require('path'); +const fs = require('fs-extra'); module.exports = function(plop) { + const rootDir = process.cwd(); + plop.setWelcomeMessage('Strapi Generators'); + // Service generator plop.setGenerator('service', { description: 'Generate a service for an API', @@ -16,7 +20,7 @@ module.exports = function(plop) { actions: [ { type: 'add', - path: join(process.cwd(), 'api/{{id}}/services/{{id}}.js'), + path: join(rootDir, 'api/{{id}}/services/{{id}}.js'), templateFile: 'templates/service.js.hbs', }, ], @@ -24,7 +28,7 @@ module.exports = function(plop) { // Model generator plop.setGenerator('model', { - description: 'application model logic', + description: 'Generate a model for an API', prompts: [ { type: 'input', @@ -40,12 +44,12 @@ module.exports = function(plop) { actions: [ { type: 'add', - path: join(process.cwd(), 'api/{{id}}/models/{{id}}.js'), + path: join(rootDir, 'api/{{id}}/models/{{id}}.js'), templateFile: 'templates/model.js.hbs', }, { type: 'add', - path: join(process.cwd(), 'api/{{id}}/models/{{id}}.settings.json'), + path: join(rootDir, 'api/{{id}}/models/{{id}}.settings.json'), templateFile: 'templates/model.settings.json.hbs', }, ], @@ -64,7 +68,7 @@ module.exports = function(plop) { actions: [ { type: 'add', - path: join(process.cwd(), 'api/{{id}}/controllers/{{id}}.js'), + path: join(rootDir, 'api/{{id}}/controllers/{{id}}.js'), templateFile: 'templates/controller.js.hbs', }, ], @@ -72,7 +76,7 @@ module.exports = function(plop) { // Policy generator plop.setGenerator('policy', { - description: 'Generate a policy', + description: 'Generate a policy for an API', prompts: [ { type: 'input', @@ -83,9 +87,60 @@ module.exports = function(plop) { actions: [ { type: 'add', - path: join(process.cwd(), 'config/policies/{{id}}.js'), + path: join(rootDir, 'config/policies/{{id}}.js'), templateFile: 'templates/policy.js.hbs', }, ], }); + + // Plugin generator + plop.setGenerator('plugin', { + description: 'Generate a basic plugin', + prompts: [ + { + type: 'input', + name: 'id', + message: 'Plugin name', + }, + ], + actions: data => { + fs.copySync(join(__dirname, 'files', 'admin'), join(rootDir, 'plugins', data.id, 'admin')); + + return [ + { + type: 'add', + path: join(rootDir, 'plugins/{{id}}/services/{{id}}.js'), + templateFile: 'templates/service.js.hbs', + }, + { + type: 'add', + path: join(rootDir, 'plugins/{{id}}/controllers/{{id}}.js'), + templateFile: 'templates/controller.js.hbs', + }, + { + type: 'add', + path: join(rootDir, 'plugins/{{id}}/config/routes.json'), + templateFile: 'templates/routes.json.hbs', + }, + { + type: 'add', + path: join(rootDir, 'plugins/{{id}}/README.md'), + templateFile: 'templates/README.md.hbs', + }, + { + type: 'add', + path: join(rootDir, 'plugins/{{id}}/package.json'), + templateFile: 'templates/plugin-package.json.hbs', + }, + { + destination: join(rootDir, 'plugins/{{id}}'), + type: 'addMany', + templateFiles: 'templates/.*', + globOptions: { + dot: true, + }, + }, + ]; + }, + }); }; diff --git a/packages/generators/generate-plop/templates/.editorconfig b/packages/generators/generate-plop/templates/.editorconfig new file mode 100644 index 0000000000..d4eed8406b --- /dev/null +++ b/packages/generators/generate-plop/templates/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = false +indent_style = space +indent_size = 2 diff --git a/packages/generators/generate-plop/templates/.gitattributes b/packages/generators/generate-plop/templates/.gitattributes new file mode 100644 index 0000000000..065a11c71d --- /dev/null +++ b/packages/generators/generate-plop/templates/.gitattributes @@ -0,0 +1,103 @@ +# From https://github.com/Danimoth/gitattributes/blob/master/Web.gitattributes + +# Handle line endings automatically for files detected as text +# and leave all files detected as binary untouched. +* text=auto + +# +# The above will handle all files NOT found below +# + +# +## These files are text and should be normalized (Convert crlf => lf) +# + +# source code +*.php text +*.css text +*.sass text +*.scss text +*.less text +*.styl text +*.js text eol=lf +*.coffee text +*.json text +*.htm text +*.html text +*.xml text +*.svg text +*.txt text +*.ini text +*.inc text +*.pl text +*.rb text +*.py text +*.scm text +*.sql text +*.sh text +*.bat text + +# templates +*.ejs text +*.hbt text +*.jade text +*.haml text +*.hbs text +*.dot text +*.tmpl text +*.phtml text + +# git config +.gitattributes text +.gitignore text +.gitconfig text + +# code analysis config +.jshintrc text +.jscsrc text +.jshintignore text +.csslintrc text + +# misc config +*.yaml text +*.yml text +.editorconfig text + +# build config +*.npmignore text +*.bowerrc text + +# Heroku +Procfile text +.slugignore text + +# Documentation +*.md text +LICENSE text +AUTHORS text + + +# +## These files are binary and should be left untouched +# + +# (binary is a macro for -text -diff) +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.mov binary +*.mp4 binary +*.mp3 binary +*.flv binary +*.fla binary +*.swf binary +*.gz binary +*.zip binary +*.7z binary +*.ttf binary +*.eot binary +*.woff binary +*.pyc binary +*.pdf binary diff --git a/packages/generators/generate-plop/templates/.gitignore b/packages/generators/generate-plop/templates/.gitignore new file mode 100644 index 0000000000..afe256bf30 --- /dev/null +++ b/packages/generators/generate-plop/templates/.gitignore @@ -0,0 +1,10 @@ +# Don't check auto-generated stuff into git +coverage +node_modules +stats.json +package-lock.json + +# Cruft +.DS_Store +npm-debug.log +.idea diff --git a/packages/generators/generate-plop/templates/README.md.hbs b/packages/generators/generate-plop/templates/README.md.hbs new file mode 100644 index 0000000000..c0073e2006 --- /dev/null +++ b/packages/generators/generate-plop/templates/README.md.hbs @@ -0,0 +1,3 @@ +# Strapi plugin {{id}} + +A quick description of {{id}}. diff --git a/packages/generators/generate-plop/templates/plugin-package.json.hbs b/packages/generators/generate-plop/templates/plugin-package.json.hbs new file mode 100644 index 0000000000..75bec5a029 --- /dev/null +++ b/packages/generators/generate-plop/templates/plugin-package.json.hbs @@ -0,0 +1,28 @@ +{ + "name": "strapi-plugin-{{id}}", + "version": "0.0.0", + "description": "This is the description of the plugin.", + "strapi": { + "name": "{{id}}", + "icon": "plug", + "description": "Description of {{id}} plugin." + }, + "dependencies": {}, + "author": { + "name": "A Strapi developer", + "email": "", + "url": "" + }, + "maintainers": [ + { + "name": "A Strapi developer", + "email": "", + "url": "" + } + ], + "engines": { + "node": ">=12.x. <=14.x.x", + "npm": ">=6.0.0" + }, + "license": "MIT" +} \ No newline at end of file diff --git a/packages/generators/generate-plop/templates/routes.json.hbs b/packages/generators/generate-plop/templates/routes.json.hbs new file mode 100644 index 0000000000..1de66cd215 --- /dev/null +++ b/packages/generators/generate-plop/templates/routes.json.hbs @@ -0,0 +1,12 @@ +{ + "routes": [ + { + "method": "GET", + "path": "/", + "handler": "{{id}}.index", + "config": { + "policies": [] + } + } + ] +} \ No newline at end of file