mirror of
https://github.com/sergeyyarkov/blog-example.git
synced 2026-10-11 02:08:57 +03:00
finally
This commit is contained in:
commit
804ebbc5a7
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules
|
||||
16
backend/.editorconfig
Normal file
16
backend/.editorconfig
Normal file
@ -0,0 +1,16 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[{package.json,*.yml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
3
backend/.eslintignore
Normal file
3
backend/.eslintignore
Normal file
@ -0,0 +1,3 @@
|
||||
.cache
|
||||
build
|
||||
**/node_modules/**
|
||||
27
backend/.eslintrc
Normal file
27
backend/.eslintrc
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"parser": "babel-eslint",
|
||||
"extends": "eslint:recommended",
|
||||
"env": {
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"browser": false
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"experimentalObjectRestSpread": true,
|
||||
"jsx": false
|
||||
},
|
||||
"sourceType": "module"
|
||||
},
|
||||
"globals": {
|
||||
"strapi": true
|
||||
},
|
||||
"rules": {
|
||||
"indent": ["error", 2, { "SwitchCase": 1 }],
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"no-console": 0,
|
||||
"quotes": ["error", "single"],
|
||||
"semi": ["error", "always"]
|
||||
}
|
||||
}
|
||||
112
backend/.gitignore
vendored
Normal file
112
backend/.gitignore
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
############################
|
||||
# OS X
|
||||
############################
|
||||
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
Icon
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
._*
|
||||
|
||||
|
||||
############################
|
||||
# Linux
|
||||
############################
|
||||
|
||||
*~
|
||||
|
||||
|
||||
############################
|
||||
# Windows
|
||||
############################
|
||||
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
$RECYCLE.BIN/
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
|
||||
############################
|
||||
# Packages
|
||||
############################
|
||||
|
||||
*.7z
|
||||
*.csv
|
||||
*.dat
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.seed
|
||||
*.so
|
||||
*.swo
|
||||
*.swp
|
||||
*.swn
|
||||
*.swm
|
||||
*.out
|
||||
*.pid
|
||||
|
||||
|
||||
############################
|
||||
# Logs and databases
|
||||
############################
|
||||
|
||||
.tmp
|
||||
*.log
|
||||
*.sql
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
|
||||
|
||||
############################
|
||||
# Misc.
|
||||
############################
|
||||
|
||||
*#
|
||||
ssl
|
||||
.idea
|
||||
nbproject
|
||||
public/uploads/*
|
||||
!public/uploads/.gitkeep
|
||||
|
||||
############################
|
||||
# Node.js
|
||||
############################
|
||||
|
||||
lib-cov
|
||||
lcov.info
|
||||
pids
|
||||
logs
|
||||
results
|
||||
node_modules
|
||||
.node_history
|
||||
|
||||
|
||||
############################
|
||||
# Tests
|
||||
############################
|
||||
|
||||
testApp
|
||||
coverage
|
||||
|
||||
############################
|
||||
# Strapi
|
||||
############################
|
||||
|
||||
exports
|
||||
.cache
|
||||
build
|
||||
3
backend/README.md
Normal file
3
backend/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Strapi application
|
||||
|
||||
A quick description of your strapi application
|
||||
0
backend/api/.gitkeep
Normal file
0
backend/api/.gitkeep
Normal file
52
backend/api/article/config/routes.json
Normal file
52
backend/api/article/config/routes.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"routes": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/articles",
|
||||
"handler": "article.find",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/articles/count",
|
||||
"handler": "article.count",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/articles/:id",
|
||||
"handler": "article.findOne",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/articles",
|
||||
"handler": "article.create",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/articles/:id",
|
||||
"handler": "article.update",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"path": "/articles/:id",
|
||||
"handler": "article.delete",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
8
backend/api/article/controllers/article.js
Normal file
8
backend/api/article/controllers/article.js
Normal file
@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Read the documentation (https://strapi.io/documentation/3.0.0-beta.x/concepts/controllers.html#core-controllers)
|
||||
* to customize this controller
|
||||
*/
|
||||
|
||||
module.exports = {};
|
||||
55
backend/api/article/models/article.js
Normal file
55
backend/api/article/models/article.js
Normal file
@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Lifecycle callbacks for the `article` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
35
backend/api/article/models/article.settings.json
Normal file
35
backend/api/article/models/article.settings.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"connection": "default",
|
||||
"collectionName": "articles",
|
||||
"info": {
|
||||
"name": "article"
|
||||
},
|
||||
"options": {
|
||||
"increments": true,
|
||||
"timestamps": true
|
||||
},
|
||||
"attributes": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"content": {
|
||||
"type": "richtext",
|
||||
"required": true
|
||||
},
|
||||
"image": {
|
||||
"model": "file",
|
||||
"via": "related",
|
||||
"plugin": "upload",
|
||||
"required": true
|
||||
},
|
||||
"published_at": {
|
||||
"type": "date",
|
||||
"required": true
|
||||
},
|
||||
"category": {
|
||||
"model": "category",
|
||||
"via": "articles"
|
||||
}
|
||||
}
|
||||
}
|
||||
8
backend/api/article/services/article.js
Normal file
8
backend/api/article/services/article.js
Normal file
@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Read the documentation (https://strapi.io/documentation/3.0.0-beta.x/concepts/services.html#core-services)
|
||||
* to customize this service
|
||||
*/
|
||||
|
||||
module.exports = {};
|
||||
52
backend/api/category/config/routes.json
Normal file
52
backend/api/category/config/routes.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"routes": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/categories",
|
||||
"handler": "category.find",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/categories/count",
|
||||
"handler": "category.count",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/categories/:id",
|
||||
"handler": "category.findOne",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/categories",
|
||||
"handler": "category.create",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/categories/:id",
|
||||
"handler": "category.update",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"path": "/categories/:id",
|
||||
"handler": "category.delete",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
8
backend/api/category/controllers/category.js
Normal file
8
backend/api/category/controllers/category.js
Normal file
@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Read the documentation (https://strapi.io/documentation/3.0.0-beta.x/concepts/controllers.html#core-controllers)
|
||||
* to customize this controller
|
||||
*/
|
||||
|
||||
module.exports = {};
|
||||
55
backend/api/category/models/category.js
Normal file
55
backend/api/category/models/category.js
Normal file
@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Lifecycle callbacks for the `category` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
20
backend/api/category/models/category.settings.json
Normal file
20
backend/api/category/models/category.settings.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"connection": "default",
|
||||
"collectionName": "categories",
|
||||
"info": {
|
||||
"name": "category"
|
||||
},
|
||||
"options": {
|
||||
"increments": true,
|
||||
"timestamps": true
|
||||
},
|
||||
"attributes": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"articles": {
|
||||
"via": "category",
|
||||
"collection": "article"
|
||||
}
|
||||
}
|
||||
}
|
||||
8
backend/api/category/services/category.js
Normal file
8
backend/api/category/services/category.js
Normal file
@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Read the documentation (https://strapi.io/documentation/3.0.0-beta.x/concepts/services.html#core-services)
|
||||
* to customize this service
|
||||
*/
|
||||
|
||||
module.exports = {};
|
||||
10
backend/config/application.json
Normal file
10
backend/config/application.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"favicon": {
|
||||
"path": "favicon.ico",
|
||||
"maxAge": 86400000
|
||||
},
|
||||
"public": {
|
||||
"path": "./public",
|
||||
"maxAge": 60000
|
||||
}
|
||||
}
|
||||
3
backend/config/custom.json
Normal file
3
backend/config/custom.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"myCustomConfiguration": "This configuration is accessible through strapi.config.myCustomConfiguration"
|
||||
}
|
||||
3
backend/config/environments/development/custom.json
Normal file
3
backend/config/environments/development/custom.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"myCustomConfiguration": "This configuration is accessible through strapi.config.environments.development.myCustomConfiguration"
|
||||
}
|
||||
15
backend/config/environments/development/database.json
Normal file
15
backend/config/environments/development/database.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "sqlite",
|
||||
"filename": ".tmp/data.db"
|
||||
},
|
||||
"options": {
|
||||
"useNullAsDefault": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
backend/config/environments/development/request.json
Normal file
23
backend/config/environments/development/request.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"session": {
|
||||
"enabled": true,
|
||||
"client": "cookie",
|
||||
"key": "strapi.sid",
|
||||
"prefix": "strapi:sess:",
|
||||
"secretKeys": ["mySecretKey1", "mySecretKey2"],
|
||||
"httpOnly": true,
|
||||
"maxAge": 86400000,
|
||||
"overwrite": true,
|
||||
"signed": false,
|
||||
"rolling": false
|
||||
},
|
||||
"logger": {
|
||||
"level": "debug",
|
||||
"exposeInContext": true,
|
||||
"requests": true
|
||||
},
|
||||
"parser": {
|
||||
"enabled": true,
|
||||
"multipart": true
|
||||
}
|
||||
}
|
||||
12
backend/config/environments/development/response.json
Normal file
12
backend/config/environments/development/response.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"gzip": {
|
||||
"enabled": false
|
||||
},
|
||||
"responseTime": {
|
||||
"enabled": false
|
||||
},
|
||||
"poweredBy": {
|
||||
"enabled": true,
|
||||
"value": "Strapi <strapi.io>"
|
||||
}
|
||||
}
|
||||
31
backend/config/environments/development/security.json
Normal file
31
backend/config/environments/development/security.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"csp": {
|
||||
"enabled": true,
|
||||
"policy": ["block-all-mixed-content"]
|
||||
},
|
||||
"p3p": {
|
||||
"enabled": false,
|
||||
"value": ""
|
||||
},
|
||||
"hsts": {
|
||||
"enabled": true,
|
||||
"maxAge": 31536000,
|
||||
"includeSubDomains": true
|
||||
},
|
||||
"xframe": {
|
||||
"enabled": true,
|
||||
"value": "SAMEORIGIN"
|
||||
},
|
||||
"xss": {
|
||||
"enabled": true,
|
||||
"mode": "block"
|
||||
},
|
||||
"cors": {
|
||||
"enabled": true
|
||||
},
|
||||
"ip": {
|
||||
"enabled": false,
|
||||
"whiteList": [],
|
||||
"blackList": []
|
||||
}
|
||||
}
|
||||
13
backend/config/environments/development/server.json
Normal file
13
backend/config/environments/development/server.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": 1337,
|
||||
"proxy": {
|
||||
"enabled": false
|
||||
},
|
||||
"cron": {
|
||||
"enabled": false
|
||||
},
|
||||
"admin": {
|
||||
"autoOpen": false
|
||||
}
|
||||
}
|
||||
3
backend/config/environments/production/custom.json
Normal file
3
backend/config/environments/production/custom.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"myCustomConfiguration": "This configuration is accessible through strapi.config.environments.production.myCustomConfiguration"
|
||||
}
|
||||
17
backend/config/environments/production/database.json
Normal file
17
backend/config/environments/production/database.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "sqlite",
|
||||
"host": "${process.env.DATABASE_HOST || '127.0.0.1'}",
|
||||
"port": "${process.env.DATABASE_PORT || 27017}",
|
||||
"database": "${process.env.DATABASE_NAME || 'strapi'}",
|
||||
"username": "${process.env.DATABASE_USERNAME || ''}",
|
||||
"password": "${process.env.DATABASE_PASSWORD || ''}"
|
||||
},
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
backend/config/environments/production/request.json
Normal file
23
backend/config/environments/production/request.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"session": {
|
||||
"enabled": true,
|
||||
"client": "cookie",
|
||||
"key": "strapi.sid",
|
||||
"prefix": "strapi:sess:",
|
||||
"secretKeys": ["mySecretKey1", "mySecretKey2"],
|
||||
"httpOnly": true,
|
||||
"maxAge": 86400000,
|
||||
"overwrite": true,
|
||||
"signed": false,
|
||||
"rolling": false
|
||||
},
|
||||
"logger": {
|
||||
"level": "info",
|
||||
"exposeInContext": true,
|
||||
"requests": false
|
||||
},
|
||||
"parser": {
|
||||
"enabled": true,
|
||||
"multipart": true
|
||||
}
|
||||
}
|
||||
12
backend/config/environments/production/response.json
Normal file
12
backend/config/environments/production/response.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"gzip": {
|
||||
"enabled": true
|
||||
},
|
||||
"responseTime": {
|
||||
"enabled": false
|
||||
},
|
||||
"poweredBy": {
|
||||
"enabled": true,
|
||||
"value": "Strapi <strapi.io>"
|
||||
}
|
||||
}
|
||||
31
backend/config/environments/production/security.json
Normal file
31
backend/config/environments/production/security.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"csp": {
|
||||
"enabled": true,
|
||||
"policy": ["block-all-mixed-content"]
|
||||
},
|
||||
"p3p": {
|
||||
"enabled": true,
|
||||
"value": ""
|
||||
},
|
||||
"hsts": {
|
||||
"enabled": true,
|
||||
"maxAge": 31536000,
|
||||
"includeSubDomains": true
|
||||
},
|
||||
"xframe": {
|
||||
"enabled": true,
|
||||
"value": "SAMEORIGIN"
|
||||
},
|
||||
"xss": {
|
||||
"enabled": true,
|
||||
"mode": "block"
|
||||
},
|
||||
"cors": {
|
||||
"enabled": true
|
||||
},
|
||||
"ip": {
|
||||
"enabled": false,
|
||||
"whiteList": [],
|
||||
"blackList": []
|
||||
}
|
||||
}
|
||||
14
backend/config/environments/production/server.json
Normal file
14
backend/config/environments/production/server.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": "${process.env.PORT || 1337}",
|
||||
"production": true,
|
||||
"proxy": {
|
||||
"enabled": false
|
||||
},
|
||||
"cron": {
|
||||
"enabled": false
|
||||
},
|
||||
"admin": {
|
||||
"autoOpen": false
|
||||
}
|
||||
}
|
||||
3
backend/config/environments/staging/custom.json
Normal file
3
backend/config/environments/staging/custom.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"myCustomConfiguration": "This configuration is accessible through strapi.config.environments.staging.myCustomConfiguration"
|
||||
}
|
||||
17
backend/config/environments/staging/database.json
Normal file
17
backend/config/environments/staging/database.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "sqlite",
|
||||
"host": "${process.env.DATABASE_HOST || '127.0.0.1'}",
|
||||
"port": "${process.env.DATABASE_PORT || 27017}",
|
||||
"database": "${process.env.DATABASE_NAME || 'strapi'}",
|
||||
"username": "${process.env.DATABASE_USERNAME || ''}",
|
||||
"password": "${process.env.DATABASE_PASSWORD || ''}"
|
||||
},
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
backend/config/environments/staging/request.json
Normal file
23
backend/config/environments/staging/request.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"session": {
|
||||
"enabled": true,
|
||||
"client": "cookie",
|
||||
"key": "strapi.sid",
|
||||
"prefix": "strapi:sess:",
|
||||
"secretKeys": ["mySecretKey1", "mySecretKey2"],
|
||||
"httpOnly": true,
|
||||
"maxAge": 86400000,
|
||||
"overwrite": true,
|
||||
"signed": false,
|
||||
"rolling": false
|
||||
},
|
||||
"logger": {
|
||||
"level": "info",
|
||||
"exposeInContext": true,
|
||||
"requests": false
|
||||
},
|
||||
"parser": {
|
||||
"enabled": true,
|
||||
"multipart": true
|
||||
}
|
||||
}
|
||||
12
backend/config/environments/staging/response.json
Normal file
12
backend/config/environments/staging/response.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"gzip": {
|
||||
"enabled": true
|
||||
},
|
||||
"responseTime": {
|
||||
"enabled": false
|
||||
},
|
||||
"poweredBy": {
|
||||
"enabled": true,
|
||||
"value": "Strapi <strapi.io>"
|
||||
}
|
||||
}
|
||||
31
backend/config/environments/staging/security.json
Normal file
31
backend/config/environments/staging/security.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"csp": {
|
||||
"enabled": true,
|
||||
"policy": ["block-all-mixed-content"]
|
||||
},
|
||||
"p3p": {
|
||||
"enabled": true,
|
||||
"value": ""
|
||||
},
|
||||
"hsts": {
|
||||
"enabled": true,
|
||||
"maxAge": 31536000,
|
||||
"includeSubDomains": true
|
||||
},
|
||||
"xframe": {
|
||||
"enabled": true,
|
||||
"value": "SAMEORIGIN"
|
||||
},
|
||||
"xss": {
|
||||
"enabled": true,
|
||||
"mode": "block"
|
||||
},
|
||||
"cors": {
|
||||
"enabled": true
|
||||
},
|
||||
"ip": {
|
||||
"enabled": false,
|
||||
"whiteList": [],
|
||||
"blackList": []
|
||||
}
|
||||
}
|
||||
14
backend/config/environments/staging/server.json
Normal file
14
backend/config/environments/staging/server.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": "${process.env.PORT || 1337}",
|
||||
"production": true,
|
||||
"proxy": {
|
||||
"enabled": false
|
||||
},
|
||||
"cron": {
|
||||
"enabled": false
|
||||
},
|
||||
"admin": {
|
||||
"autoOpen": false
|
||||
}
|
||||
}
|
||||
13
backend/config/functions/bootstrap.js
vendored
Normal file
13
backend/config/functions/bootstrap.js
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* An asynchronous bootstrap function that runs before
|
||||
* your application gets started.
|
||||
*
|
||||
* This gives you an opportunity to set up your data model,
|
||||
* run jobs, or perform some special logic.
|
||||
*
|
||||
* See more details here: https://strapi.io/documentation/3.0.0-beta.x/concepts/configurations.html#bootstrap
|
||||
*/
|
||||
|
||||
module.exports = () => {};
|
||||
21
backend/config/functions/cron.js
Normal file
21
backend/config/functions/cron.js
Normal file
@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Cron config that gives you an opportunity
|
||||
* to run scheduled jobs.
|
||||
*
|
||||
* The cron format consists of:
|
||||
* [SECOND (optional)] [MINUTE] [HOUR] [DAY OF MONTH] [MONTH OF YEAR] [DAY OF WEEK]
|
||||
*
|
||||
* See more details here: https://strapi.io/documentation/3.0.0-beta.x/concepts/configurations.html#cron-tasks
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Simple example.
|
||||
* Every monday at 1am.
|
||||
*/
|
||||
// '0 1 * * 1': () => {
|
||||
//
|
||||
// }
|
||||
};
|
||||
5
backend/config/functions/responses/404.js
Normal file
5
backend/config/functions/responses/404.js
Normal file
@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = async (/* ctx */) => {
|
||||
// return ctx.notFound('My custom message 404');
|
||||
};
|
||||
10
backend/config/hook.json
Normal file
10
backend/config/hook.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"timeout": 3000,
|
||||
"load": {
|
||||
"before": [],
|
||||
"order": [
|
||||
"Define the hooks' load order by putting their names in this array in the right order"
|
||||
],
|
||||
"after": []
|
||||
}
|
||||
}
|
||||
13
backend/config/language.json
Normal file
13
backend/config/language.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"defaultLocale": "en_us",
|
||||
"modes": [
|
||||
"query",
|
||||
"subdomain",
|
||||
"cookie",
|
||||
"header",
|
||||
"url",
|
||||
"tld"
|
||||
],
|
||||
"cookieName": "locale"
|
||||
}
|
||||
3
backend/config/locales/cs_cz.json
Normal file
3
backend/config/locales/cs_cz.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"welcome": "Vítejte"
|
||||
}
|
||||
3
backend/config/locales/de_de.json
Normal file
3
backend/config/locales/de_de.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"welcome": "Willkommen"
|
||||
}
|
||||
3
backend/config/locales/en_us.json
Normal file
3
backend/config/locales/en_us.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"welcome": "Welcome"
|
||||
}
|
||||
3
backend/config/locales/es_es.json
Normal file
3
backend/config/locales/es_es.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"welcome": "Bienvenido"
|
||||
}
|
||||
3
backend/config/locales/fr_fr.json
Normal file
3
backend/config/locales/fr_fr.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"welcome": "Bienvenue"
|
||||
}
|
||||
3
backend/config/locales/it_it.json
Normal file
3
backend/config/locales/it_it.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"welcome": "Benvenuto"
|
||||
}
|
||||
3
backend/config/locales/ja_jp.json
Normal file
3
backend/config/locales/ja_jp.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"welcome": "ようこそ"
|
||||
}
|
||||
4
backend/config/locales/ru_ru.json
Normal file
4
backend/config/locales/ru_ru.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"welcome": "Добро пожаловать"
|
||||
}
|
||||
|
||||
3
backend/config/locales/tr_tr.json
Normal file
3
backend/config/locales/tr_tr.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"welcome": "Hoşgeldin"
|
||||
}
|
||||
19
backend/config/middleware.json
Normal file
19
backend/config/middleware.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"timeout": 100,
|
||||
"load": {
|
||||
"before": [
|
||||
"responseTime",
|
||||
"logger",
|
||||
"cors",
|
||||
"responses",
|
||||
"gzip"
|
||||
],
|
||||
"order": [
|
||||
"Define the middlewares' load order by putting their name in this array is the right order"
|
||||
],
|
||||
"after": [
|
||||
"parser",
|
||||
"router"
|
||||
]
|
||||
}
|
||||
}
|
||||
0
backend/extensions/.gitkeep
Normal file
0
backend/extensions/.gitkeep
Normal file
3
backend/extensions/users-permissions/config/jwt.json
Normal file
3
backend/extensions/users-permissions/config/jwt.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"jwtSecret": "fc4be92f-25ac-4dfe-bac3-7b19917064c6"
|
||||
}
|
||||
BIN
backend/favicon.ico
Normal file
BIN
backend/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
38
backend/package.json
Normal file
38
backend/package.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "backend",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"description": "A Strapi application",
|
||||
"scripts": {
|
||||
"develop": "strapi develop",
|
||||
"start": "strapi start",
|
||||
"build": "strapi build",
|
||||
"strapi": "strapi"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"dependencies": {
|
||||
"knex": "<0.20.0",
|
||||
"sqlite3": "latest",
|
||||
"strapi": "3.0.0-beta.18.8",
|
||||
"strapi-admin": "3.0.0-beta.18.8",
|
||||
"strapi-connector-bookshelf": "3.0.0-beta.18.8",
|
||||
"strapi-plugin-content-manager": "3.0.0-beta.18.8",
|
||||
"strapi-plugin-content-type-builder": "3.0.0-beta.18.8",
|
||||
"strapi-plugin-email": "3.0.0-beta.18.8",
|
||||
"strapi-plugin-graphql": "3.0.0-beta.18.8",
|
||||
"strapi-plugin-upload": "3.0.0-beta.18.8",
|
||||
"strapi-plugin-users-permissions": "3.0.0-beta.18.8",
|
||||
"strapi-utils": "3.0.0-beta.18.8"
|
||||
},
|
||||
"author": {
|
||||
"name": "A Strapi developer"
|
||||
},
|
||||
"strapi": {
|
||||
"uuid": "6eb87738-282f-42e3-b657-0006839e0a75"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0",
|
||||
"npm": ">=6.0.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
56
backend/public/index.html
Normal file
56
backend/public/index.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<title>Welcome to your Strapi app</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="robots" content="noindex">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" />
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Lato:400,700&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
*{-webkit-box-sizing:border-box;text-decoration:none}body,html{margin:0;padding:0;font-size:62.5%;-webkit-font-smoothing:antialiased}body{font-size:1.3rem;font-family:Lato,Helvetica,Arial,Verdana,sans-serif;background:#fafafb;margin:0;padding:80px 0;color:#333740;line-height:1.8rem}strong{font-weight:700}.wrapper{width:684px;margin:auto}h1{text-align:center}h2{font-size:1.8rem;font-weight:700;margin-bottom:1px}.logo{height:40px;margin-bottom:74px}.informations{position:relative;overflow:hidden;display:flex;justify-content:space-between;width:100%;height:126px;margin-top:18px;padding:20px 30px;background:#fff;border-radius:2px;box-shadow:0 2px 4px 0 #e3e9f3}.informations:before{position:absolute;top:0;left:0;content:'';display:block;width:100%;height:2px;background:#007eff}.environment{display:inline-block;padding:0 10px;height:20px;margin-bottom:36px;background:#e6f0fb;border:1px solid #aed4fb;border-radius:2px;text-transform:uppercase;color:#007eff;font-size:1.2rem;font-weight:700;line-height:20px;letter-spacing:.05rem}.cta{display:inline-block;height:30px;padding:0 15px;margin-top:32px;border-radius:2px;color:#fff;font-weight:700;line-height:28px}.cta i{position:relative;display:inline-block;height:100%;vertical-align:middle;font-size:1rem;margin-right:20px}.cta i:before{position:absolute;top:8px}.cta-primary{background:#007eff}.cta-secondary{background:#6dbb1a}.text-align-right{text-align:right}.lets-started{position:relative;overflow:hidden;width:100%;height:144px;margin-top:18px;padding:20px 30px;background:#fff;border-radius:2px;box-shadow:0 2px 4px 0 #e3e9f3}.people-saying-hello{position:absolute;right:30px;bottom:-8px;width:113px;height:70px}.visible{opacity:1!important}.people-saying-hello img{position:absolute;max-width:100%;opacity:0;transition:opacity .2s ease-out}@media only screen and (max-width:768px){.wrapper{width:auto!important;margin:0 20px}.informations{flex-direction:column;height:auto}.environment{width:100%;text-align:center;margin-bottom:18px}.text-align-right{margin-top:18px;text-align:center}.cta{width:100%;text-align:center}.lets-started{height:auto}.people-saying-hello{display:none}}
|
||||
</style>
|
||||
</head>
|
||||
<body lang="en">
|
||||
<section class="wrapper">
|
||||
<h1><img class="logo" src="https://strapi.io/assets/images/logo_login.png" /></h1>
|
||||
<% if (isInitialised) { %>
|
||||
<div class="informations">
|
||||
|
||||
<div>
|
||||
<span class="environment"><%= strapi.config.environment %></span>
|
||||
<p>
|
||||
The server is running successfully (<strong>v<%= strapi.config.info.version %>)</strong>
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-align-right">
|
||||
<p><%= serverTime %></p>
|
||||
<a class="cta cta-primary" href="<%= strapi.config.admin.url %>" target="_blank" title="Click to open the administration" ><i class="fas fa-external-link-alt"></i>Open the administration</a>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (!isInitialised) { %>
|
||||
|
||||
<div class="lets-started">
|
||||
<h2>Let's get started!</h2>
|
||||
<p>To discover the power provided by Strapi, you need to create an administrator.</p>
|
||||
<a class="cta cta-secondary" href="<%= strapi.config.admin.url %>" target="_blank" title="Click to create the first administration" ><i class="fas fa-external-link-alt"></i>Create the first administrator</a>
|
||||
<div class="people-saying-hello">
|
||||
<img class="visible" src="https://strapi.io/assets/images/group_people_1.png" alt="People saying hello" />
|
||||
<img src="https://strapi.io/assets/images/group_people_2.png" alt="People saying hello" />
|
||||
<img src="https://strapi.io/assets/images/group_people_3.png" alt="People saying hello" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% } %>
|
||||
|
||||
</section>
|
||||
<script>
|
||||
var images=document.querySelectorAll('.people-saying-hello img');var nextIndex=0;setInterval(function(){var currentIndex=0;images.forEach(function(image,index){if(image.className==='visible'){currentIndex=index}});nextIndex=currentIndex+1;if(nextIndex===images.length){nextIndex=0}
|
||||
images.forEach(function(image){image.classList.remove('visible')})
|
||||
images[nextIndex].classList.add('visible')},1500)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
30
backend/public/production.html
Normal file
30
backend/public/production.html
Normal file
@ -0,0 +1,30 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<title>Welcome to your Strapi app</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="robots" content="noindex">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" />
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Lato:400,700&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
*{-webkit-box-sizing:border-box;text-decoration:none}body,html{margin:0;padding:0;font-size:62.5%;-webkit-font-smoothing:antialiased}body{font-size:1.3rem;font-family:Lato,Helvetica,Arial,Verdana,sans-serif;background:#fafafb;margin:0;padding:80px 0;color:#333740;line-height:1.8rem}strong{font-weight:700}.wrapper{width:684px;margin:auto}h1{text-align:center}h2{font-size:1.8rem;font-weight:700;margin-bottom:1px}.logo{height:40px}.informations{position:relative;overflow:hidden;display:flex;justify-content:space-between;width:100%;height:126px;margin-top:92px;padding:20px 30px;background:#fff;border-radius:2px;box-shadow:0 2px 4px 0 #e3e9f3}.informations:before{position:absolute;top:0;left:0;content:'';display:block;width:100%;height:2px;background:#6dbb1a}.environment{display:inline-block;padding:0 10px;height:20px;margin-bottom:36px;background:#e9f5dd;border:1px solid #6dbb1a;border-radius:2px;text-transform:uppercase;color:#6dbb1a;font-size:1.2rem;font-weight:700;line-height:20px;letter-spacing:.05rem}.cta{display:inline-block;height:30px;padding:0 15px;margin-top:32px;border-radius:2px;color:#fff;font-weight:700;line-height:28px}.cta i{position:relative;display:inline-block;height:100%;vertical-align:middle;font-size:1rem;margin-right:20px}.cta i:before{position:absolute;top:8px}.cta-primary{background:#007eff}.cta-secondary{background:#}.text-align-right{text-align:right}@media only screen and (max-width:768px){.wrapper{width:auto!important;margin:0 20px}.informations{flex-direction:column;height:auto}.informations p{text-align:center}.environment{width:100%;text-align:center;margin-bottom:18px}.text-align-right{margin-top:18px;text-align:center}}
|
||||
</style>
|
||||
</head>
|
||||
<body lang="en">
|
||||
<section class="wrapper">
|
||||
<h1><img class="logo" src="https://strapi.io/assets/images/logo_login.png" /></h1>
|
||||
<div class="informations">
|
||||
<div>
|
||||
<span class="environment"><%= strapi.config.environment %></span>
|
||||
<p>The server is running successfully.</p>
|
||||
</div>
|
||||
<div class="text-align-right">
|
||||
<p><%= serverTime %></p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
3
backend/public/robots.txt
Normal file
3
backend/public/robots.txt
Normal file
@ -0,0 +1,3 @@
|
||||
# To prevent search engines from seeing the site altogether, uncomment the next two lines:
|
||||
# User-Agent: *
|
||||
# Disallow: /
|
||||
0
backend/public/uploads/.gitkeep
Normal file
0
backend/public/uploads/.gitkeep
Normal file
10218
backend/yarn.lock
Normal file
10218
backend/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
25
frontend/.gitignore
vendored
Normal file
25
frontend/.gitignore
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env*
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
30
frontend/README.md
Normal file
30
frontend/README.md
Normal file
@ -0,0 +1,30 @@
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your brSowser to see the result.
|
||||
|
||||
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/zeit/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on ZEIT Now
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [ZEIT Now Platform](https://zeit.co/) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
23
frontend/apollo/queries/article/article.js
Normal file
23
frontend/apollo/queries/article/article.js
Normal file
@ -0,0 +1,23 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
const ARTICLE_QUERY = gql`
|
||||
|
||||
query Article($id: ID!) {
|
||||
article(id: $id) {
|
||||
id
|
||||
title
|
||||
content
|
||||
image {
|
||||
url
|
||||
}
|
||||
category {
|
||||
id
|
||||
name
|
||||
}
|
||||
published_at
|
||||
}
|
||||
}
|
||||
|
||||
`
|
||||
|
||||
export default ARTICLE_QUERY
|
||||
21
frontend/apollo/queries/article/articles.js
Normal file
21
frontend/apollo/queries/article/articles.js
Normal file
@ -0,0 +1,21 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
const ARTICLES_QUERY = gql`
|
||||
|
||||
query Articles {
|
||||
articles {
|
||||
id
|
||||
title
|
||||
category {
|
||||
id
|
||||
name
|
||||
}
|
||||
image {
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
`
|
||||
|
||||
export default ARTICLES_QUERY
|
||||
23
frontend/apollo/queries/category/articles.js
Normal file
23
frontend/apollo/queries/category/articles.js
Normal file
@ -0,0 +1,23 @@
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
const CATEGORY_ARTICLES_QUERY = gql`
|
||||
query Category($id: ID!){
|
||||
category(id: $id) {
|
||||
name
|
||||
articles {
|
||||
id
|
||||
title
|
||||
content
|
||||
image {
|
||||
url
|
||||
}
|
||||
category {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default CATEGORY_ARTICLES_QUERY;
|
||||
14
frontend/apollo/queries/category/categories.js
Normal file
14
frontend/apollo/queries/category/categories.js
Normal file
@ -0,0 +1,14 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
const CATEGORIES_QUERY = gql`
|
||||
|
||||
query Categories {
|
||||
categories {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
|
||||
`
|
||||
|
||||
export default CATEGORIES_QUERY
|
||||
47
frontend/assets/css/style.css
Normal file
47
frontend/assets/css/style.css
Normal file
@ -0,0 +1,47 @@
|
||||
@import "~nprogress/nprogress.css";
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: Staatliches;
|
||||
font-size: 120px;
|
||||
}
|
||||
|
||||
#category {
|
||||
font-family: Staatliches;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
#title {
|
||||
letter-spacing: 0.4px;
|
||||
font-size: 22px;
|
||||
font-size: 1.375rem;
|
||||
line-height: 1.13636;
|
||||
}
|
||||
|
||||
#banner {
|
||||
margin: 20px;
|
||||
height: 800px;
|
||||
}
|
||||
|
||||
#editor {
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.uk-navbar-container {
|
||||
background: #fff !important;
|
||||
font-family: Staatliches;
|
||||
}
|
||||
|
||||
.uk-card-body {
|
||||
padding: 15px 30px;
|
||||
}
|
||||
|
||||
img:hover {
|
||||
opacity: 1;
|
||||
transition: opacity 0.25s cubic-bezier(0.39, 0.575, 0.565, 1);
|
||||
}
|
||||
29
frontend/components/Articles.js
Normal file
29
frontend/components/Articles.js
Normal file
@ -0,0 +1,29 @@
|
||||
import Card from "./card";
|
||||
|
||||
const Articles = ({ articles }) => {
|
||||
console.log(articles)
|
||||
const leftArticlesCount = Math.ceil(articles.length / 5);
|
||||
const leftArticles = articles.slice(0, leftArticlesCount);
|
||||
const rightArticles = articles.slice(leftArticlesCount, articles.length);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="uk-child-width-1-2" data-uk-grid>
|
||||
<div>
|
||||
{leftArticles.map((article, i) => {
|
||||
return <Card article={article} key={`article__${article.id}`} />;
|
||||
})}
|
||||
</div>
|
||||
<div>
|
||||
<div className="uk-child-width-1-2@m uk-grid-match" data-uk-grid>
|
||||
{rightArticles.map((article, i) => {
|
||||
return <Card article={article} key={`article__${article.id}`} />;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Articles;
|
||||
29
frontend/components/card.js
Normal file
29
frontend/components/card.js
Normal file
@ -0,0 +1,29 @@
|
||||
import Link from "next/link";
|
||||
|
||||
const Card = ({ article }) => {
|
||||
return (
|
||||
<Link href='/articles/[id]' as={`/articles/${article.id}`}>
|
||||
<a className="uk-link-reset">
|
||||
<div className="uk-card uk-card-muted">
|
||||
<div className="uk-card-media-top">
|
||||
<img
|
||||
src={process.env.API_URL + article.image.url}
|
||||
alt={article.image.url}
|
||||
height="100"
|
||||
/>
|
||||
</div>
|
||||
<div className="uk-card-body">
|
||||
<p id="category" className="uk-text-uppercase">
|
||||
{article.category.name}
|
||||
</p>
|
||||
<p id="title" className="uk-text-large">
|
||||
{article.title}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default Card;
|
||||
45
frontend/components/nav.js
Normal file
45
frontend/components/nav.js
Normal file
@ -0,0 +1,45 @@
|
||||
import Link from "next/link"
|
||||
import Query from "../components/query";
|
||||
import CATEGORIES_QUERY from "../apollo/queries/category/categories.js";
|
||||
|
||||
const Nav = () => {
|
||||
return (
|
||||
<div>
|
||||
<Query query={CATEGORIES_QUERY} id={null}>
|
||||
{({ data: { categories } }) => {
|
||||
return (
|
||||
<div>
|
||||
<nav className="uk-container uk-container-large uk-navbar-container" data-uk-navbar>
|
||||
<div className="uk-navbar-left">
|
||||
<ul className="uk-navbar-nav">
|
||||
<li>
|
||||
<Link href="/">
|
||||
<a>Example Blog</a>
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="uk-navbar-right">
|
||||
<ul className="uk-navbar-nav">
|
||||
{categories.map((category, i) => {
|
||||
return (
|
||||
<li key={category.id}>
|
||||
<Link href='/categories/[id]' as={`/categories/${category.id}`}>
|
||||
<a className="uk-link-reset">{category.name}</a>
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Query>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Nav;
|
||||
13
frontend/components/query.js
Normal file
13
frontend/components/query.js
Normal file
@ -0,0 +1,13 @@
|
||||
import { useQuery } from '@apollo/react-hooks'
|
||||
|
||||
const Query = ({ children, query, id }) => {
|
||||
const { data, loading, error } = useQuery(query, {
|
||||
variables: {id}
|
||||
})
|
||||
|
||||
if (loading) return <p>loading...</p>
|
||||
if (error) return <p>Error: {JSON.stringify(error)}</p>
|
||||
return children({ data })
|
||||
}
|
||||
|
||||
export default Query
|
||||
9
frontend/next.config.js
Normal file
9
frontend/next.config.js
Normal file
@ -0,0 +1,9 @@
|
||||
require("dotenv").config();
|
||||
const withCSS = require('@zeit/next-css')
|
||||
const withFonts = require('next-fonts')
|
||||
|
||||
module.exports = withCSS({
|
||||
env: {
|
||||
API_URL: process.env.API_URL
|
||||
}
|
||||
})
|
||||
10351
frontend/package-lock.json
generated
Normal file
10351
frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
30
frontend/package.json
Normal file
30
frontend/package.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/react-hooks": "^3.1.3",
|
||||
"@zeit/next-css": "^1.0.1",
|
||||
"apollo-cache-inmemory": "^1.6.5",
|
||||
"apollo-client": "^2.6.8",
|
||||
"apollo-link-http": "^1.5.16",
|
||||
"dotenv": "^8.2.0",
|
||||
"graphql": "^14.6.0",
|
||||
"graphql-tag": "^2.10.3",
|
||||
"isomorphic-unfetch": "^3.0.0",
|
||||
"moment": "^2.24.0",
|
||||
"next": "9.2.2",
|
||||
"next-fonts": "^1.0.3",
|
||||
"next-with-apollo": "^5.0.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"react": "16.13.0",
|
||||
"react-dom": "16.13.0",
|
||||
"react-markdown": "^4.3.1",
|
||||
"react-moment": "^0.9.7"
|
||||
}
|
||||
}
|
||||
39
frontend/pages/_app.js
Normal file
39
frontend/pages/_app.js
Normal file
@ -0,0 +1,39 @@
|
||||
import Head from "next/head";
|
||||
import NProgress from 'nprogress'
|
||||
import Router from 'next/router'
|
||||
import "../assets/css/style.css";
|
||||
import { ApolloProvider } from "@apollo/react-hooks";
|
||||
import withData from "../utils/apollo";
|
||||
|
||||
import Nav from '../components/nav'
|
||||
|
||||
Router.events.on('routeChangeStart', url => NProgress.start())
|
||||
Router.events.on('routeChangeComplete', () => NProgress.done())
|
||||
Router.events.on('routeChangeError', () => NProgress.done())
|
||||
|
||||
const App = ({ Component, pageProps, apollo }) => {
|
||||
return (
|
||||
<ApolloProvider client={apollo}>
|
||||
<Head>
|
||||
<title>Strapi blog</title>
|
||||
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css?family=Staatliches"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/uikit@3.2.3/dist/css/uikit.min.css"
|
||||
/>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/js/uikit.min.js" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.2.3/dist/js/uikit-icons.min.js" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/js/uikit.js" />
|
||||
</Head>
|
||||
<Nav />
|
||||
<Component {...pageProps} />
|
||||
</ApolloProvider>
|
||||
)
|
||||
};
|
||||
|
||||
// Wraps all components in the tree with the data provider
|
||||
export default withData(App);
|
||||
39
frontend/pages/articles/[id].js
Normal file
39
frontend/pages/articles/[id].js
Normal file
@ -0,0 +1,39 @@
|
||||
import { useRouter } from "next/router";
|
||||
import Query from "../../components/query";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import Moment from "react-moment";
|
||||
import ARTICLE_QUERY from "../../apollo/queries/article/article";
|
||||
|
||||
const Article = () => {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<Query query={ARTICLE_QUERY} id={router.query.id}>
|
||||
{({ data: { article } }) => {
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
id="banner"
|
||||
className="uk-height-medium uk-flex uk-flex-center uk-flex-middle uk-background-cover uk-light uk-padding uk-margin"
|
||||
data-src={process.env.API_URL + article.image.url}
|
||||
data-srcset={process.env.API_URL + article.image.url}
|
||||
data-uk-img
|
||||
>
|
||||
<h1>{article.title}</h1>
|
||||
</div>
|
||||
|
||||
<div className="uk-section">
|
||||
<div className="uk-container uk-container-small">
|
||||
<ReactMarkdown source={article.content} />
|
||||
<p>
|
||||
<Moment format="MMM Do YYYY">{article.published_at}</Moment>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Query>
|
||||
);
|
||||
};
|
||||
|
||||
export default Article;
|
||||
27
frontend/pages/categories/[id].js
Normal file
27
frontend/pages/categories/[id].js
Normal file
@ -0,0 +1,27 @@
|
||||
import { useRouter } from "next/router";
|
||||
import Articles from "../../components/articles";
|
||||
import Query from "../../components/query";
|
||||
import CATEGORY_ARTICLES_QUERY from "../../apollo/queries/category/articles";
|
||||
|
||||
const Category = () => {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<Query query={CATEGORY_ARTICLES_QUERY} id={router.query.id}>
|
||||
{({ data: { category } }) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="uk-section">
|
||||
<div className="uk-container uk-container-large">
|
||||
<h1>{category.name}</h1>
|
||||
<Articles articles={category.articles} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Query>
|
||||
);
|
||||
};
|
||||
|
||||
export default Category
|
||||
22
frontend/pages/index.js
Normal file
22
frontend/pages/index.js
Normal file
@ -0,0 +1,22 @@
|
||||
import Articles from "../components/articles";
|
||||
import Query from "../components/query";
|
||||
import ARTICLES_QUERY from "../apollo/queries/article/articles";
|
||||
|
||||
const Home = () => {
|
||||
return (
|
||||
<div>
|
||||
<div className="uk-section">
|
||||
<div className="uk-container uk-container-large">
|
||||
<h1>Example Blog</h1>
|
||||
<Query query={ARTICLES_QUERY}>
|
||||
{({ data: { articles } }) => {
|
||||
return <Articles articles={articles} />;
|
||||
}}
|
||||
</Query>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home
|
||||
BIN
frontend/public/favicon.ico
Normal file
BIN
frontend/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
10
frontend/public/zeit.svg
Normal file
10
frontend/public/zeit.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="82" height="16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="url(#prefix__paint0_linear)" d="M9.018 0l9.019 16H0L9.018 0z"/>
|
||||
<path fill="#333" fill-rule="evenodd" d="M51.634 12.028h-6.492V2.052h6.492v1.256H46.61v3.007h4.37V7.57h-4.37v3.202h5.024v1.255zm-14.063 0h-7.235v-1.096l5.342-7.624h-5.253V2.052h7.058v1.097l-5.342 7.623h5.43v1.256zm21.88 0h6.333v-1.256h-2.423V3.308h2.423V2.052h-6.332v1.256h2.441v7.465h-2.441v1.255zm18.22 0h-1.468v-8.72h-3.36V2.052h8.225v1.256H77.67v8.72z" clip-rule="evenodd"/>
|
||||
<defs>
|
||||
<linearGradient id="prefix__paint0_linear" x1="28.022" x2="16.189" y1="22.991" y2="8.569" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#fff"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 794 B |
22
frontend/utils/apollo.js
Normal file
22
frontend/utils/apollo.js
Normal file
@ -0,0 +1,22 @@
|
||||
import { ApolloClient } from 'apollo-client'
|
||||
import { InMemoryCache } from 'apollo-cache-inmemory'
|
||||
import withApollo from 'next-with-apollo'
|
||||
import { createHttpLink } from 'apollo-link-http'
|
||||
import fetch from 'isomorphic-unfetch'
|
||||
|
||||
const GRAPHQL_URL = process.env.BACKEND_URL || 'http://localhost:1337/graphql'
|
||||
|
||||
const link = new createHttpLink({
|
||||
fetch,
|
||||
uri: GRAPHQL_URL
|
||||
})
|
||||
|
||||
export default withApollo(
|
||||
|
||||
({initialState}) =>
|
||||
new ApolloClient({
|
||||
link,
|
||||
cache: new InMemoryCache()
|
||||
.restore(initialState || {})
|
||||
})
|
||||
)
|
||||
6523
frontend/yarn.lock
Normal file
6523
frontend/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
391
package-lock.json
generated
Normal file
391
package-lock.json
generated
Normal file
@ -0,0 +1,391 @@
|
||||
{
|
||||
"name": "Example blog",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
|
||||
"requires": {
|
||||
"string-width": "^3.1.0",
|
||||
"strip-ansi": "^5.2.0",
|
||||
"wrap-ansi": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"concurrently": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.1.0.tgz",
|
||||
"integrity": "sha512-9ViZMu3OOCID3rBgU31mjBftro2chOop0G2u1olq1OuwRBVRw/GxHTg80TVJBUTJfoswMmEUeuOg1g1yu1X2dA==",
|
||||
"requires": {
|
||||
"chalk": "^2.4.2",
|
||||
"date-fns": "^2.0.1",
|
||||
"lodash": "^4.17.15",
|
||||
"read-pkg": "^4.0.1",
|
||||
"rxjs": "^6.5.2",
|
||||
"spawn-command": "^0.0.2-1",
|
||||
"supports-color": "^6.1.0",
|
||||
"tree-kill": "^1.2.2",
|
||||
"yargs": "^13.3.0"
|
||||
}
|
||||
},
|
||||
"date-fns": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.10.0.tgz",
|
||||
"integrity": "sha512-EhfEKevYGWhWlZbNeplfhIU/+N+x0iCIx7VzKlXma2EdQyznVlZhCptXUY+BegNpPW2kjdx15Rvq503YcXXrcA=="
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
|
||||
},
|
||||
"error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
|
||||
"requires": {
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
},
|
||||
"find-up": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
|
||||
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
||||
"requires": {
|
||||
"locate-path": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.7",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.7.tgz",
|
||||
"integrity": "sha512-ChkjQtKJ3GI6SsI4O5jwr8q8EPrWCnxuc4Tbx+vRI5x6mDOpjKKltNo1lRlszw3xwgTOSns1ZRBiMmmwpcvLxg=="
|
||||
},
|
||||
"is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
|
||||
},
|
||||
"json-parse-better-errors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
||||
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||
"requires": {
|
||||
"p-locate": "^3.0.0",
|
||||
"path-exists": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
},
|
||||
"normalize-package-data": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
|
||||
"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
|
||||
"requires": {
|
||||
"hosted-git-info": "^2.1.4",
|
||||
"resolve": "^1.10.0",
|
||||
"semver": "2 || 3 || 4 || 5",
|
||||
"validate-npm-package-license": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
|
||||
"integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
||||
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||
"requires": {
|
||||
"p-limit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
|
||||
},
|
||||
"parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
|
||||
"integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
|
||||
"requires": {
|
||||
"error-ex": "^1.3.1",
|
||||
"json-parse-better-errors": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
|
||||
},
|
||||
"pify": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
||||
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz",
|
||||
"integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=",
|
||||
"requires": {
|
||||
"normalize-package-data": "^2.3.2",
|
||||
"parse-json": "^4.0.0",
|
||||
"pify": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
|
||||
},
|
||||
"require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.15.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
|
||||
"integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "6.5.4",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
|
||||
"integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
|
||||
},
|
||||
"spawn-command": {
|
||||
"version": "0.0.2-1",
|
||||
"resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
|
||||
"integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A="
|
||||
},
|
||||
"spdx-correct": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
|
||||
"integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
|
||||
"requires": {
|
||||
"spdx-expression-parse": "^3.0.0",
|
||||
"spdx-license-ids": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"spdx-exceptions": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
|
||||
"integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA=="
|
||||
},
|
||||
"spdx-expression-parse": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
|
||||
"integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
|
||||
"requires": {
|
||||
"spdx-exceptions": "^2.1.0",
|
||||
"spdx-license-ids": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"spdx-license-ids": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
|
||||
"integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||
"requires": {
|
||||
"emoji-regex": "^7.0.1",
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
|
||||
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"tree-kill": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
|
||||
"integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz",
|
||||
"integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA=="
|
||||
},
|
||||
"validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
|
||||
"requires": {
|
||||
"spdx-correct": "^3.0.0",
|
||||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"which-module": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
|
||||
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
|
||||
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.0",
|
||||
"string-width": "^3.0.0",
|
||||
"strip-ansi": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "13.3.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
|
||||
"integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
|
||||
"requires": {
|
||||
"cliui": "^5.0.0",
|
||||
"find-up": "^3.0.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^3.0.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^13.1.1"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "13.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
|
||||
"integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
package.json
Normal file
14
package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "example-blog",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "concurrently \"yarn --cwd ./backend/ develop\" \"yarn --cwd ./frontend/ dev\""
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"concurrently": "^5.1.0"
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user