diff --git a/.eslintignore b/.eslintignore index 5cdf069c80..e16b59bb01 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,7 @@ **/node_modules/** **/build/** **/dist/** +**/OLD/** testApp/** examples/** packages/strapi-generate-plugin/files/admin/src/** diff --git a/.eslintrc.front.js b/.eslintrc.front.js index ffa0c91cbb..ceb64d7a5c 100644 --- a/.eslintrc.front.js +++ b/.eslintrc.front.js @@ -47,7 +47,7 @@ module.exports = { 'no-console': 0, 'require-atomic-updates': 0, 'react-hooks/rules-of-hooks': 'error', - 'react-hooks/exhaustive-deps': 'warn', + 'react-hooks/exhaustive-deps': 'error', 'arrow-body-style': 0, 'arrow-parens': 0, camelcase: 0, @@ -64,10 +64,7 @@ module.exports = { { flatTernaryExpressions: false, SwitchCase: 1, - ignoredNodes: [ - 'ConditionalExpression', - "VariableDeclarator[kind='const']", - ], + ignoredNodes: ['ConditionalExpression', "VariableDeclarator[kind='const']"], }, ], 'func-names': ['error', 'never'], @@ -97,10 +94,7 @@ module.exports = { 'no-plusplus': 0, 'no-shadow': 0, 'no-underscore-dangle': 0, - 'no-use-before-define': [ - 'error', - { functions: false, classes: false, variables: false }, - ], + 'no-use-before-define': ['error', { functions: false, classes: false, variables: false }], 'object-curly-newline': [2, { multiline: true, consistent: true }], 'operator-linebreak': 0, 'padding-line-between-statements': [ diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md index b2637866a1..bc6da3ab2e 100644 --- a/.github/ISSUE_TEMPLATE/BUG_REPORT.md +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md @@ -16,6 +16,7 @@ https://guides.github.com/features/mastering-markdown/ A clear and concise description of what the bug is. **Steps to reproduce the behavior** + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -31,6 +32,7 @@ If applicable, add screenshots to help explain your problem. If applicable, add code samples to help explain your problem. **System** + - Node.js version: - NPM version: - Strapi version: diff --git a/.travis.yml b/.travis.yml index 85760cab6b..55e3be7390 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,17 +3,13 @@ services: - mysql addons: - postgresql: '10' - apt: - packages: - - postgresql-10 - - postgresql-client-10 + postgresql: '11.2' + env: global: - PGPORT=5433 -sudo: required -dist: trusty +dist: xenial language: node_js @@ -33,14 +29,6 @@ e2e_tests: &e2e_tests - yarn run -s test:start-app & wait-on http://localhost:1337 - yarn run -s test:e2e -install_mongo: &install_mongo - before_install: - - wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.6.tgz - - tar -zxvf mongodb-linux-x86_64-3.6.6.tgz - - mkdir -p ./data/db/27017 - - mkdir -p ./data/db/27000 - - ./mongodb-linux-x86_64-3.6.6/bin/mongod --fork --dbpath ./data/db/27017 --syslog --port 27017 - before_script: - yarn build - yarn global add -g wait-on @@ -50,11 +38,17 @@ jobs: include: - stage: test name: Snyk + before_install: + - curl -o- -L https://yarnpkg.com/install.sh | bash + - export PATH="$HOME/.yarn/bin:$PATH" script: yarn run -s test:snyk if: fork = false - stage: test name: 'Lint / Unit Tests ' + before_install: + - curl -o- -L https://yarnpkg.com/install.sh | bash + - export PATH="$HOME/.yarn/bin:$PATH" script: - yarn run -s lint - yarn run -s test:unit --coverage && codecov -C -F unit @@ -63,8 +57,13 @@ jobs: - <<: *e2e_tests name: 'E2E Postgresql' before_install: - - sudo cp /etc/postgresql/{9.6,10}/main/pg_hba.conf - - sudo /etc/init.d/postgresql restart + - curl -o- -L https://yarnpkg.com/install.sh | bash + - export PATH="$HOME/.yarn/bin:$PATH" + - sudo apt-get update + - sudo apt-get --yes remove postgresql-* + - sudo apt-get install -y postgresql-11 postgresql-client-11 + - sudo cp /etc/postgresql/{9.6,11}/main/pg_hba.conf + - sudo service postgresql restart 11 - psql -c 'create database strapi_test;' -U postgres env: - DB_STRING='--dbclient=postgres --dbhost=localhost --dbport=5433 --dbname=strapi_test --dbusername=postgres --dbpassword=' @@ -72,6 +71,8 @@ jobs: - <<: *e2e_tests name: 'E2E Mysql' before_install: + - curl -o- -L https://yarnpkg.com/install.sh | bash + - export PATH="$HOME/.yarn/bin:$PATH" - sudo cp $TRAVIS_BUILD_DIR/_travis/mysql.cnf /etc/mysql/conf.d/ - sudo service mysql restart - mysql -e 'CREATE DATABASE strapi_test;' @@ -80,21 +81,21 @@ jobs: - <<: *e2e_tests name: 'E2E Sqlite' + before_install: + - curl -o- -L https://yarnpkg.com/install.sh | bash + - export PATH="$HOME/.yarn/bin:$PATH" env: - DB_STRING='--dbclient=sqlite --dbfile=./tmp/data.db' - <<: *e2e_tests name: 'E2E MongoDB' - <<: *install_mongo + before_install: + - curl -o- -L https://yarnpkg.com/install.sh | bash + - export PATH="$HOME/.yarn/bin:$PATH" + - wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.6.tgz + - tar -zxvf mongodb-linux-x86_64-3.6.6.tgz + - mkdir -p ./data/db/27017 + - mkdir -p ./data/db/27000 + - ./mongodb-linux-x86_64-3.6.6/bin/mongod --fork --dbpath ./data/db/27017 --syslog --port 27017 env: - DB_STRING='--dbclient=mongo --dbhost=localhost --dbport=27017 --dbname=strapi_test --dbusername= --dbpassword=' - # - name: 'Cypress tests' - # <<: *install_mongo - # install: - # - yarn run -s bootstrap - # - yarn global add -g wait-on - # - cypress install - # script: - # - yarn run -s test:generate-app -- --dbclient=mongo --dbhost=localhost --dbport=27017 --dbname=strapi_test --dbusername= --dbpassword= - # - yarn run -s test:start-app & wait-on http://localhost:1337 - # - node test/cypress.js diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index e10ce3aaf0..7ef7ea0e03 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -213,6 +213,8 @@ module.exports = { '/3.0.0-beta.x/guides/scheduled-publication', '/3.0.0-beta.x/guides/secure-your-app', '/3.0.0-beta.x/guides/send-email', + '/3.0.0-beta.x/guides/registering-a-field-in-admin', + '/3.0.0-beta.x/guides/count-graphql', '/3.0.0-beta.x/guides/client', '/3.0.0-beta.x/guides/update-version', ], @@ -220,7 +222,11 @@ module.exports = { { collapsable: true, title: '⚙️️ Admin Panel', - children: ['/3.0.0-beta.x/admin-panel/customization', '/3.0.0-beta.x/admin-panel/deploy'], + children: [ + '/3.0.0-beta.x/admin-panel/customization', + '/3.0.0-beta.x/admin-panel/custom-webpack-config', + '/3.0.0-beta.x/admin-panel/deploy', + ], }, { collapsable: true, @@ -241,6 +247,7 @@ module.exports = { '/3.0.0-beta.x/plugin-development/plugin-architecture', '/3.0.0-beta.x/plugin-development/backend-development', '/3.0.0-beta.x/plugin-development/frontend-development', + '/3.0.0-beta.x/plugin-development/frontend-field-api', '/3.0.0-beta.x/plugin-development/frontend-settings-api', ], }, diff --git a/docs/3.0.0-beta.x/admin-panel/custom-webpack-config.md b/docs/3.0.0-beta.x/admin-panel/custom-webpack-config.md new file mode 100644 index 0000000000..f840ace0a9 --- /dev/null +++ b/docs/3.0.0-beta.x/admin-panel/custom-webpack-config.md @@ -0,0 +1,16 @@ +# Custom Webpack Config + +In order to extend the usage of webpack, you can define a function that extends its config inside `admin/admin.config.js`, like so: + +```js +module.exports = { + webpack: (config, webpack) => { + // Note: we provide webpack above so you should not `require` it + // Perform customizations to webpack config + // Important: return the modified config + config.plugins.push(new webpack.IgnorePlugin(/\/__tests__\//)); + + return config; + }, +}; +``` diff --git a/docs/3.0.0-beta.x/cli/CLI.md b/docs/3.0.0-beta.x/cli/CLI.md index 8812773a60..d44054627f 100644 --- a/docs/3.0.0-beta.x/cli/CLI.md +++ b/docs/3.0.0-beta.x/cli/CLI.md @@ -78,6 +78,8 @@ options: [--no-optimization] - **strapi build**
Builds the administration panel and minimizing the assets +- **strapi build --clean**
+ Builds the administration panel and delete the previous build and .cache folders - **strapi build --no-optimization**
Builds the administration panel without minimizing the assets. The build duration is faster. diff --git a/docs/3.0.0-beta.x/concepts/models.md b/docs/3.0.0-beta.x/concepts/models.md index 767c0073c3..61420edf26 100644 --- a/docs/3.0.0-beta.x/concepts/models.md +++ b/docs/3.0.0-beta.x/concepts/models.md @@ -132,6 +132,12 @@ Additional settings can be set on models: In this example, the model `Restaurant` will be accessible through the `Restaurants` global variable. The data will be stored in the `Restaurants_v1` collection or table and the model will use the `mongo` connection defined in `./config/environments/**/database.json` +::: warning +If not set manually in the JSON file, Strapi will adopt the filename as `globalId`. +The `globalId` serves as a reference to your model within relations and Strapi APIs. If you chose to rename it (either by renaming your file or by changing the value of the `globalId`), you'd have to migrate your tables manually and update the references. +Please note that you should not alter Strapi's models `globalId` (plugins and core ones) since it is used directly within Strapi APIs and other models' relations. +::: + ::: tip The `connection` value can be changed whenever you want, but you should be aware that there is no automatic data migration process. Also if the new connection doesn't use the same ORM you will have to rewrite your queries. ::: @@ -159,10 +165,7 @@ The info key on the model-json states information about the model. This informat The options key on the model-json states. -- `idAttribute`: This tells the model which attribute to expect as the unique identifier for each database row (typically an auto-incrementing primary key named 'id'). _Only valid for bookshelf._ -- `idAttributeType`: Data type of `idAttribute`, accepted list of value below. _Only valid for bookshelf._ - `timestamps`: This tells the model which attributes to use for timestamps. Accepts either `boolean` or `Array` of strings where first element is create date and second element is update date. Default value when set to `true` for Bookshelf is `["created_at", "updated_at"]` and for MongoDB is `["createdAt", "updatedAt"]`. -- `uuid` : Boolean to enable UUID support on MySQL, you will need to set the `idAttributeType` to `uuid` as well and install the `bookshelf-uuid` package. To load the package you can see [this example](./configurations.md#bookshelf-mongoose). **Path —** `User.settings.json`. diff --git a/docs/3.0.0-beta.x/concepts/services.md b/docs/3.0.0-beta.x/concepts/services.md index ee7d2da7c2..7d67016bde 100644 --- a/docs/3.0.0-beta.x/concepts/services.md +++ b/docs/3.0.0-beta.x/concepts/services.md @@ -137,12 +137,13 @@ module.exports = { */ async create(data, { files } = {}) { - const entry = await strapi.query(model).create(data); + const entry = await strapi.query('restaurant').create(data); if (files) { // automatically uploads the files based on the entry and the model await strapi.entityService.uploadFiles(entry, files, { - model: strapi.models.restaurant, + model: 'restaurant', + // if you are using a plugin's model you will have to add the `plugin` key (plugin: 'users-permissions') }); return this.findOne({ id: entry.id }); } @@ -167,12 +168,13 @@ module.exports = { */ async update(params, data, { files } = {}) { - const entry = await strapi.query(model).update(params, data); + const entry = await strapi.query('restaurant').update(params, data); if (files) { // automatically uploads the files based on the entry and the model await strapi.entityService.uploadFiles(entry, files, { - model: strapi.models.restaurant, + model: 'restaurant', + // if you are using a plugin's model you will have to add the `plugin` key (plugin: 'users-permissions') }); return this.findOne({ id: entry.id }); } diff --git a/docs/3.0.0-beta.x/deployment/google-app-engine.md b/docs/3.0.0-beta.x/deployment/google-app-engine.md new file mode 100644 index 0000000000..b4b5de3fdd --- /dev/null +++ b/docs/3.0.0-beta.x/deployment/google-app-engine.md @@ -0,0 +1,307 @@ +# Google App Engine + +In this guide we are going to: + +- Create a new Strapi project +- Configure PostgreSQL for the production enviroment +- Deploy the app to Google App Engine +- Add the [Google Cloud Storage file uploading plugin](https://github.com/Lith/strapi-provider-upload-google-cloud-storage) by [@Lith](https://github.com/Lith) + +### New Strapi project + +:::: tabs + +::: tab yarn + +Use **yarn** to install the Strapi project (**recommended**). [Install yarn with these docs](https://yarnpkg.com/lang/en/docs/install/) + +```bash +yarn create strapi-app my-project --quickstart +``` + +::: + +::: tab npx + +Use **npm/npx** to install the Strapi project + +```bash +npx create-strapi-app my-project --quickstart +``` + +::: + +:::: + +When the setup completes, register an admin user using the form which opens in the browser. This user will be only relevant in local development. + +The `sqlite` database is created at `.tmp/data.db`. + +Login, but don't add content types yet. Close the browser. Quit the running app. + +### Initial commit + +This may be a good point to commit the files in their initial state. + +```bash +cd my-project +git init +git add . +git commit -m first +``` + +### Install the Cloud SDK CLI tool + +[Cloud SDK: Command Line Interface](https://cloud.google.com/sdk/) + +### New App Engine project + +Create a new [App Engine](https://console.cloud.google.com/appengine/) project. + +Select the region, such as `europe-west`. + +- Language: Node JS +- Environment: Standard (or Flexible) + +(_A note on performance and cost_: the `Standard Environment` is sufficient for development, but it may not be for production. Review the resources your application will need to determine the cost. When you sign up for Google App Engine, it offers a certain amount of free credits which will not be billed.) + +Create the project. Take note of the instance identifier, which is in the form of `::`. + +Check if `gcloud` lists the project: + +```bash +gcloud projects list +``` + +Run `init` to authenticate the cli, and select current cloud project. + +```bash +gcloud init +``` + +### Create the database (PostgreSQL) + +Create the [Cloud SQL database](https://cloud.google.com/sql/docs/postgres/create-manage-databases) which the app is going to use. + +Take note of the user name (default is `postgres`) and password. + +The first database will be created with the name `postgres`. This cannot be deleted. + +Create another database, named `strapi` for example. It may be useful to delete and and re-create this while you are experimenting with the application setup. + +### Create app.yaml and .gcloudignore + +Create the `app.yaml` file in the project root. + +Add `app.yaml` to `.gitignore`. + +The instance identifier looks like `myapi-123456:europe-west1:myapi`. + +The `myapi-123456` part is the project identifier. (The number is automatically added to short project names). + +The following is an example config for `Standard Environment` or `Flexible Environment`. + +:::: tabs + +::: tab Standard Environment + +```yaml +runtime: nodejs10 + +instance_class: F2 + +env_variables: + HOST: '.appspot.com' + NODE_ENV: 'production' + DATABASE_NAME: 'strapi' + DATABASE_USERNAME: 'postgres' + DATABASE_PASSWORD: '' + INSTANCE_CONNECTION_NAME: '' + +beta_settings: + cloud_sql_instances: '' +``` + +::: + +::: tab Flexible Environment + +```yaml +runtime: nodejs10 + +env: flex + +env_variables: + HOST: '.appspot.com' + NODE_ENV: 'production' + DATABASE_NAME: 'strapi' + DATABASE_USERNAME: 'postgres' + DATABASE_PASSWORD: '' + INSTANCE_CONNECTION_NAME: '' + +beta_settings: + cloud_sql_instances: '' +``` + +::: + +:::: + +Create `.gcloudignore` in the project root, include `app.yaml` here as well. + +``` +app.yaml +.gcloudignore +.git +.gitignore +node_modules/ +#!include:.gitignore +``` + +In the case of Strapi, the admin UI will have to be re-built after every deploy, +and so we don't deploy local build artifacts, cache files and so on by including +the `.gitignore` entries. + +### Configure the database + +The `PostgreSQL` database will need the `pg` package. + +```bash +yarn add pg +``` + +[Google App Engine requires](https://cloud.google.com/sql/docs/postgres/connect-app-engine) to connect to the database using the unix socket path, not an IP and port. + +Edit `database.json`, and use the socket path as `host`. + +``` +config/environments/production/database.json +``` + +```json +{ + "defaultConnection": "default", + "connections": { + "default": { + "connector": "bookshelf", + "settings": { + "client": "postgres", + "host": "/cloudsql/${process.env.INSTANCE_CONNECTION_NAME}", + "database": "${process.env.DATABASE_NAME}", + "username": "${process.env.DATABASE_USERNAME}", + "password": "${process.env.DATABASE_PASSWORD}" + }, + "options": {} + } + } +} +``` + +Edit `server.json` to pick up the deployed hostname from the `HOST` variable in `app.yaml`. + +``` +config/environments/production/server.json +``` + +```json +{ + "host": "${process.env.HOST}", + "port": "${process.env.PORT || 1337}", + "production": true, + "proxy": { + "enabled": false + }, + "cron": { + "enabled": false + }, + "admin": { + "autoOpen": false + } +} +``` + +### Auto-build after deploy + +After deployment, the admin UI has to be re-built. This generates the contents of the `build` folder on the server. + +In `package.json`, add the `gcp-build` command to `scripts`: + +```json +{ + "scripts": { + "gcp-build": "strapi build" + } +} +``` + +### Deploy + +```bash +gcloud app deploy app.yaml --project myapi-123456 +``` + +Watch the logs: + +```bash +gcloud app logs tail --project=myapi-123456 -s default +``` + +Open the admin page and register and admin user. + +``` +https://myapp-123456.appspot.com/admin/ +``` + +### File uploading to Google Cloud Storage + +[Lith/strapi-provider-upload-google-cloud-storage](https://github.com/Lith/strapi-provider-upload-google-cloud-storage) + +```bash +yarn add strapi-provider-upload-google-cloud-storage +``` + +Deploy so that the server app includes the dependency from `package.json`. + +Create a Google service account key. + + + +Save the JSON credentials file. + +Plugins > File Upload > Settings > Production tab + +By default `localhost` is selected. Select the `Google Cloud Storage` plugin. + +Copy the JSON key and set the regions. + +Open the `Cloud Console > Storage > Browser` menu. + +Copy the bucket name to the plugin settings, the default is the app ID, such as `myapi-123456.appspot.com`. + +(Note that the `Access control` setting of the bucket has to be `Fine-grained`, which is the default.) + +Click `Save`, and it's ready to go! + +### Post-setup configuration + +**CORS** + +CORS is enabled by default, allowing `*` origin. You may want to limit the allowed origins. + +``` +config/environments/production/security.json +``` + +**Changing the admin url** + +``` +config/environments/production/server.json +``` + +```json +{ + "admin": { + "path": "/dashboard" + } +} +``` diff --git a/docs/3.0.0-beta.x/getting-started/deployment.md b/docs/3.0.0-beta.x/getting-started/deployment.md index 1bad0bd4e7..bb284520fd 100644 --- a/docs/3.0.0-beta.x/getting-started/deployment.md +++ b/docs/3.0.0-beta.x/getting-started/deployment.md @@ -46,6 +46,18 @@ Manual guides for deployment on various platforms, for One-click and docker plea +
+ + + + + +
+