Merge branch 'v5/main' into chore/refactor-env-to-config

This commit is contained in:
Ben Irvin 2024-01-18 11:49:34 +01:00 committed by GitHub
commit 00d88d8130
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
66 changed files with 2600 additions and 237 deletions

View File

@ -15,9 +15,95 @@ Here you can read about what content schemas the test instance has & the API cus
## Content Schemas
:::note
There's no content yet!
:::
### Article
```json
{
// ...
"attributes": {
"title": {
"type": "string"
},
"content": {
"type": "blocks"
},
"authors": {
"type": "relation",
"relation": "manyToMany",
"target": "api::author.author",
"inversedBy": "articles"
}
}
// ...
}
```
### Author
```json
{
// ...
"attributes": {
"name": {
"type": "string"
},
"profile": {
"allowedTypes": ["images", "files", "videos", "audios"],
"type": "media",
"multiple": false
},
"articles": {
"type": "relation",
"relation": "manyToMany",
"target": "api::article.article",
"mappedBy": "authors"
}
}
// ...
}
```
### Homepage (Single Type)
```json
{
// ...
"attributes": {
"title": {
"type": "string"
},
"content": {
"type": "blocks"
},
"admin_user": {
"type": "relation",
"relation": "oneToOne",
"target": "admin::user"
}
}
// ...
}
```
### Upcoming Match (Single Type)
```json
{
// ...
"attributes": {
"title": {
"type": "string"
},
"number_of_upcoming_matches": {
"type": "integer"
},
"next_match": {
"type": "date"
}
}
// ...
}
```
## API Customisations

View File

@ -0,0 +1,26 @@
{
"kind": "collectionType",
"collectionName": "articles",
"info": {
"singularName": "article",
"pluralName": "articles",
"displayName": "Article",
"description": ""
},
"options": {},
"pluginOptions": {},
"attributes": {
"title": {
"type": "string"
},
"content": {
"type": "blocks"
},
"authors": {
"type": "relation",
"relation": "manyToMany",
"target": "api::author.author",
"inversedBy": "articles"
}
}
}

View File

@ -1,9 +1,9 @@
'use strict';
/**
* testing controller
* article controller
*/
const { createCoreController } = require('@strapi/strapi').factories;
module.exports = createCoreController('api::testing.testing');
module.exports = createCoreController('api::article.article');

View File

@ -0,0 +1,587 @@
{
"/articles": {
"get": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ArticleListResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Article"],
"parameters": [
{
"name": "sort",
"in": "query",
"description": "Sort by attributes ascending (asc) or descending (desc)",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "pagination[withCount]",
"in": "query",
"description": "Return page/pageSize (default: true)",
"deprecated": false,
"required": false,
"schema": {
"type": "boolean"
}
},
{
"name": "pagination[page]",
"in": "query",
"description": "Page number (default: 0)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[pageSize]",
"in": "query",
"description": "Page size (default: 25)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[start]",
"in": "query",
"description": "Offset value (default: 0)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[limit]",
"in": "query",
"description": "Number of entities to return (default: 25)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "fields",
"in": "query",
"description": "Fields to return (ex: title,author)",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "populate",
"in": "query",
"description": "Relations to return",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "filters",
"in": "query",
"description": "Filters to apply",
"deprecated": false,
"required": false,
"schema": {
"type": "object"
},
"style": "deepObject"
},
{
"name": "locale",
"in": "query",
"description": "Locale to apply",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
}
],
"operationId": "get/articles"
},
"post": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ArticleResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Article"],
"parameters": [],
"operationId": "post/articles",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ArticleRequest"
}
}
}
}
}
},
"/articles/{id}": {
"get": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ArticleResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Article"],
"parameters": [
{
"name": "id",
"in": "path",
"description": "",
"deprecated": false,
"required": true,
"schema": {
"type": "number"
}
}
],
"operationId": "get/articles/{id}"
},
"put": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ArticleResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Article"],
"parameters": [
{
"name": "id",
"in": "path",
"description": "",
"deprecated": false,
"required": true,
"schema": {
"type": "number"
}
}
],
"operationId": "put/articles/{id}",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ArticleRequest"
}
}
}
}
},
"delete": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "integer",
"format": "int64"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Article"],
"parameters": [
{
"name": "id",
"in": "path",
"description": "",
"deprecated": false,
"required": true,
"schema": {
"type": "number"
}
}
],
"operationId": "delete/articles/{id}"
}
},
"/articles/{id}/localizations": {
"post": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ArticleLocalizationResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Article"],
"parameters": [
{
"name": "id",
"in": "path",
"description": "",
"deprecated": false,
"required": true,
"schema": {
"type": "number"
}
}
],
"operationId": "post/articles/{id}/localizations",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ArticleLocalizationRequest"
}
}
}
}
}
}
}

View File

@ -1,9 +1,9 @@
'use strict';
/**
* testing router
* article router
*/
const { createCoreRouter } = require('@strapi/strapi').factories;
module.exports = createCoreRouter('api::testing.testing');
module.exports = createCoreRouter('api::article.article');

View File

@ -1,9 +1,9 @@
'use strict';
/**
* testing service
* article service
*/
const { createCoreService } = require('@strapi/strapi').factories;
module.exports = createCoreService('api::testing.testing');
module.exports = createCoreService('api::article.article');

View File

@ -0,0 +1,27 @@
{
"kind": "collectionType",
"collectionName": "authors",
"info": {
"singularName": "author",
"pluralName": "authors",
"displayName": "Author"
},
"options": {},
"pluginOptions": {},
"attributes": {
"name": {
"type": "string"
},
"profile": {
"allowedTypes": ["images", "files", "videos", "audios"],
"type": "media",
"multiple": false
},
"articles": {
"type": "relation",
"relation": "manyToMany",
"target": "api::article.article",
"mappedBy": "authors"
}
}
}

View File

@ -0,0 +1,9 @@
'use strict';
/**
* author controller
*/
const { createCoreController } = require('@strapi/strapi').factories;
module.exports = createCoreController('api::author.author');

View File

@ -0,0 +1,587 @@
{
"/authors": {
"get": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthorListResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Author"],
"parameters": [
{
"name": "sort",
"in": "query",
"description": "Sort by attributes ascending (asc) or descending (desc)",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "pagination[withCount]",
"in": "query",
"description": "Return page/pageSize (default: true)",
"deprecated": false,
"required": false,
"schema": {
"type": "boolean"
}
},
{
"name": "pagination[page]",
"in": "query",
"description": "Page number (default: 0)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[pageSize]",
"in": "query",
"description": "Page size (default: 25)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[start]",
"in": "query",
"description": "Offset value (default: 0)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[limit]",
"in": "query",
"description": "Number of entities to return (default: 25)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "fields",
"in": "query",
"description": "Fields to return (ex: title,author)",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "populate",
"in": "query",
"description": "Relations to return",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "filters",
"in": "query",
"description": "Filters to apply",
"deprecated": false,
"required": false,
"schema": {
"type": "object"
},
"style": "deepObject"
},
{
"name": "locale",
"in": "query",
"description": "Locale to apply",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
}
],
"operationId": "get/authors"
},
"post": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthorResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Author"],
"parameters": [],
"operationId": "post/authors",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthorRequest"
}
}
}
}
}
},
"/authors/{id}": {
"get": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthorResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Author"],
"parameters": [
{
"name": "id",
"in": "path",
"description": "",
"deprecated": false,
"required": true,
"schema": {
"type": "number"
}
}
],
"operationId": "get/authors/{id}"
},
"put": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthorResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Author"],
"parameters": [
{
"name": "id",
"in": "path",
"description": "",
"deprecated": false,
"required": true,
"schema": {
"type": "number"
}
}
],
"operationId": "put/authors/{id}",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthorRequest"
}
}
}
}
},
"delete": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "integer",
"format": "int64"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Author"],
"parameters": [
{
"name": "id",
"in": "path",
"description": "",
"deprecated": false,
"required": true,
"schema": {
"type": "number"
}
}
],
"operationId": "delete/authors/{id}"
}
},
"/authors/{id}/localizations": {
"post": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthorLocalizationResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Author"],
"parameters": [
{
"name": "id",
"in": "path",
"description": "",
"deprecated": false,
"required": true,
"schema": {
"type": "number"
}
}
],
"operationId": "post/authors/{id}/localizations",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthorLocalizationRequest"
}
}
}
}
}
}
}

View File

@ -0,0 +1,9 @@
'use strict';
/**
* author router
*/
const { createCoreRouter } = require('@strapi/strapi').factories;
module.exports = createCoreRouter('api::author.author');

View File

@ -0,0 +1,9 @@
'use strict';
/**
* author service
*/
const { createCoreService } = require('@strapi/strapi').factories;
module.exports = createCoreService('api::author.author');

View File

@ -0,0 +1,25 @@
{
"kind": "singleType",
"collectionName": "homepages",
"info": {
"singularName": "homepage",
"pluralName": "homepages",
"displayName": "Homepage",
"description": ""
},
"options": {},
"pluginOptions": {},
"attributes": {
"title": {
"type": "string"
},
"content": {
"type": "blocks"
},
"admin_user": {
"type": "relation",
"relation": "oneToOne",
"target": "admin::user"
}
}
}

View File

@ -0,0 +1,9 @@
'use strict';
/**
* homepage controller
*/
const { createCoreController } = require('@strapi/strapi').factories;
module.exports = createCoreController('api::homepage.homepage');

View File

@ -0,0 +1,397 @@
{
"/homepage": {
"get": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HomepageResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Homepage"],
"parameters": [
{
"name": "sort",
"in": "query",
"description": "Sort by attributes ascending (asc) or descending (desc)",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "pagination[withCount]",
"in": "query",
"description": "Return page/pageSize (default: true)",
"deprecated": false,
"required": false,
"schema": {
"type": "boolean"
}
},
{
"name": "pagination[page]",
"in": "query",
"description": "Page number (default: 0)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[pageSize]",
"in": "query",
"description": "Page size (default: 25)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[start]",
"in": "query",
"description": "Offset value (default: 0)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[limit]",
"in": "query",
"description": "Number of entities to return (default: 25)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "fields",
"in": "query",
"description": "Fields to return (ex: title,author)",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "populate",
"in": "query",
"description": "Relations to return",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "filters",
"in": "query",
"description": "Filters to apply",
"deprecated": false,
"required": false,
"schema": {
"type": "object"
},
"style": "deepObject"
},
{
"name": "locale",
"in": "query",
"description": "Locale to apply",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
}
],
"operationId": "get/homepage"
},
"put": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HomepageResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Homepage"],
"parameters": [],
"operationId": "put/homepage",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HomepageRequest"
}
}
}
}
},
"delete": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "integer",
"format": "int64"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Homepage"],
"parameters": [],
"operationId": "delete/homepage"
}
},
"/homepage/localizations": {
"post": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HomepageLocalizationResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Homepage"],
"parameters": [],
"operationId": "post/homepage/localizations",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HomepageLocalizationRequest"
}
}
}
}
}
}
}

View File

@ -0,0 +1,9 @@
'use strict';
/**
* homepage router
*/
const { createCoreRouter } = require('@strapi/strapi').factories;
module.exports = createCoreRouter('api::homepage.homepage');

View File

@ -0,0 +1,9 @@
'use strict';
/**
* homepage service
*/
const { createCoreService } = require('@strapi/strapi').factories;
module.exports = createCoreService('api::homepage.homepage');

View File

@ -1,15 +0,0 @@
{
"kind": "collectionType",
"collectionName": "testings",
"info": {
"singularName": "testing",
"pluralName": "testings",
"displayName": "testing"
},
"options": {},
"attributes": {
"title": {
"type": "string"
}
}
}

View File

@ -0,0 +1,22 @@
{
"kind": "singleType",
"collectionName": "upcoming_matches",
"info": {
"singularName": "upcoming-match",
"pluralName": "upcoming-matches",
"displayName": "Upcoming Matches"
},
"options": {},
"pluginOptions": {},
"attributes": {
"title": {
"type": "string"
},
"number_of_upcoming_matches": {
"type": "integer"
},
"next_match": {
"type": "date"
}
}
}

View File

@ -0,0 +1,9 @@
'use strict';
/**
* upcoming-match controller
*/
const { createCoreController } = require('@strapi/strapi').factories;
module.exports = createCoreController('api::upcoming-match.upcoming-match');

View File

@ -0,0 +1,397 @@
{
"/upcoming-match": {
"get": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpcomingMatchResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Upcoming-match"],
"parameters": [
{
"name": "sort",
"in": "query",
"description": "Sort by attributes ascending (asc) or descending (desc)",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "pagination[withCount]",
"in": "query",
"description": "Return page/pageSize (default: true)",
"deprecated": false,
"required": false,
"schema": {
"type": "boolean"
}
},
{
"name": "pagination[page]",
"in": "query",
"description": "Page number (default: 0)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[pageSize]",
"in": "query",
"description": "Page size (default: 25)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[start]",
"in": "query",
"description": "Offset value (default: 0)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "pagination[limit]",
"in": "query",
"description": "Number of entities to return (default: 25)",
"deprecated": false,
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "fields",
"in": "query",
"description": "Fields to return (ex: title,author)",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "populate",
"in": "query",
"description": "Relations to return",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "filters",
"in": "query",
"description": "Filters to apply",
"deprecated": false,
"required": false,
"schema": {
"type": "object"
},
"style": "deepObject"
},
{
"name": "locale",
"in": "query",
"description": "Locale to apply",
"deprecated": false,
"required": false,
"schema": {
"type": "string"
}
}
],
"operationId": "get/upcoming-match"
},
"put": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpcomingMatchResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Upcoming-match"],
"parameters": [],
"operationId": "put/upcoming-match",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpcomingMatchRequest"
}
}
}
}
},
"delete": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "integer",
"format": "int64"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Upcoming-match"],
"parameters": [],
"operationId": "delete/upcoming-match"
}
},
"/upcoming-match/localizations": {
"post": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpcomingMatchLocalizationResponse"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"tags": ["Upcoming-match"],
"parameters": [],
"operationId": "post/upcoming-match/localizations",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpcomingMatchLocalizationRequest"
}
}
}
}
}
}
}

View File

@ -0,0 +1,9 @@
'use strict';
/**
* upcoming-match router
*/
const { createCoreRouter } = require('@strapi/strapi').factories;
module.exports = createCoreRouter('api::upcoming-match.upcoming-match');

View File

@ -0,0 +1,9 @@
'use strict';
/**
* upcoming-match service
*/
const { createCoreService } = require('@strapi/strapi').factories;
module.exports = createCoreService('api::upcoming-match.upcoming-match');

View File

@ -1,6 +1,18 @@
const { CUSTOM_TRANSFER_TOKEN_ACCESS_KEY } = require('./app-template/template/src/constants');
const ALLOWED_CONTENT_TYPES = ['admin::user', 'admin::role', 'admin::permission'];
const ALLOWED_CONTENT_TYPES = [
'admin::user',
'admin::role',
'admin::permission',
'api::article.article',
'api::author.author',
'api::homepage.homepage',
'api::upcoming-match.upcoming-match',
/**
* UPLOADS
*/
'plugin::upload.file',
];
// TODO: we should start using @strapi.io addresses to have the chance one day to
// actually receive and check the emails; also: it is not nice to spam other peoples

Binary file not shown.

View File

@ -32,7 +32,7 @@ const exportData = async () => {
const engine = createTransferEngine(source, destination, {
versionStrategy: 'ignore', // for an export to file, versionStrategy will always be skipped
schemaStrategy: 'ignore', // for an export to file, schemaStrategy will always be skipped
only: ['content'],
only: ['content', 'files'],
transforms: {
links: [
{

View File

@ -24,7 +24,7 @@ export const resetDatabaseAndImportDataFromPath = async (filePath) => {
const engine = createTransferEngine(source, destination, {
versionStrategy: 'ignore',
schemaStrategy: 'ignore',
only: ['content'],
only: ['content', 'files'],
transforms: {
links: [
{
@ -69,6 +69,7 @@ const createDestinationProvider = () => {
auth: { type: 'token', token: CUSTOM_TRANSFER_TOKEN_ACCESS_KEY },
strategy: 'restore',
restore: {
assets: true,
entities: {
include: ALLOWED_CONTENT_TYPES,
},

View File

@ -11,7 +11,7 @@ test.describe('Log Out', () => {
});
test('a user should be able to logout', async ({ page }) => {
await page.getByText('John Smith').click();
await page.getByText('test testing').click();
await page.getByText('Logout').click();
await expect(page.getByText('Log in to your Strapi account')).toBeVisible();

View File

@ -1,78 +0,0 @@
import { test, expect } from '@playwright/test';
import { login } from '../../utils/login';
import { resetDatabaseAndImportDataFromPath } from '../../scripts/dts-import';
test.describe('Edit View', () => {
test.beforeEach(async ({ page }) => {
await resetDatabaseAndImportDataFromPath('./e2e/data/with-admin.tar');
await page.goto('/admin');
await login({ page });
});
/**
* @note There is only one field in this content-type.
*/
test('A user should be able to navigate to the EditView of the content manager to create, save, publish, unpublish & delete a new entry', async ({
page,
}) => {
await page.getByRole('link', { name: 'Content Manager' }).click();
await page
.getByRole('link', { name: /Create new entry/ })
.nth(1)
.click();
/**
* Now we're in the edit view.
*/
await page.waitForURL('**/content-manager/collection-types/api::testing.testing/create');
await page.getByRole('textbox', { name: 'title' }).fill('my content');
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByText('Saved')).toBeVisible();
await expect(page.getByRole('button', { name: 'Save' })).toBeDisabled();
await page.getByRole('button', { name: 'Publish' }).click();
await expect(page.getByText('Published', { exact: true })).toBeVisible();
await expect(page.getByRole('button', { name: 'Unpublish' })).not.toBeDisabled();
await page.getByRole('textbox', { name: 'title' }).fill('my content revised');
await expect(page.getByRole('button', { name: 'Unpublish' })).toBeDisabled();
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByRole('button', { name: 'Unpublish' })).not.toBeDisabled();
await page.getByRole('button', { name: 'Unpublish' }).click();
await expect(page.getByRole('dialog', { name: 'Confirmation' })).toBeVisible();
await page.getByRole('button', { name: 'Yes, confirm' }).click();
await expect(page.getByText('Unpublished')).toBeVisible();
await expect(page.getByRole('button', { name: 'Publish' })).not.toBeDisabled();
await page.getByRole('button', { name: 'Delete this entry' }).click();
await expect(page.getByRole('dialog', { name: 'Confirmation' })).toBeVisible();
await page.getByRole('button', { name: 'Confirm' }).click();
await expect(page.getByText('Deleted')).toBeVisible();
/**
* We're back on the list view
*/
await page.waitForURL(
'**/content-manager/collection-types/api::testing.testing?page=1&pageSize=10&sort=title:ASC'
);
await expect(page.getByRole('link', { name: /Create new entry/ }).nth(1)).toBeVisible();
});
});

View File

@ -0,0 +1,177 @@
import { test, expect } from '@playwright/test';
import { login } from '../../utils/login';
import { resetDatabaseAndImportDataFromPath } from '../../scripts/dts-import';
test.describe('Edit View', () => {
test.beforeEach(async ({ page }) => {
await resetDatabaseAndImportDataFromPath('./e2e/data/with-admin.tar');
await page.goto('/admin');
await login({ page });
});
test.describe('Collection Type', () => {
test('A user should be able to navigate to the EditView of the content manager to create, save, publish, unpublish & delete a new entry', async ({
page,
}) => {
await page.getByRole('link', { name: 'Content Manager' }).click();
await page.getByRole('link', { name: /Create new entry/ }).click();
/**
* Now we're in the edit view.
*/
await page.waitForURL('**/content-manager/collection-types/api::article.article/create');
await page.getByRole('textbox', { name: 'title' }).fill('Being from Kansas City');
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByText('Saved')).toBeVisible();
await expect(page.getByRole('button', { name: 'Save' })).toBeDisabled();
await expect(page.getByText('Editing draft version')).toBeVisible();
await page.getByRole('link', { name: 'Content Manager' }).click();
await page.waitForURL(
'**/content-manager/collection-types/api::article.article?page=1&pageSize=10&sort=title:ASC'
);
await expect(page.getByRole('gridcell', { name: 'Being from Kansas City' })).toBeVisible();
await page.getByRole('gridcell', { name: 'Being from Kansas City' }).click();
await page.waitForURL('**/content-manager/collection-types/api::article.article/**');
await page.getByRole('textbox', { name: 'title' }).fill('');
await page.getByRole('textbox', { name: 'title' }).fill('Being an American');
await page
.getByRole('textbox')
.nth(1)
.fill('I miss the denver broncos, now I can only watch it on the evening.');
await page.getByRole('combobox', { name: 'authors' }).click();
await page.getByRole('option', { name: 'Ted Lasso' }).click();
await expect(page.getByRole('link', { name: 'Ted Lasso' })).toBeVisible();
await expect(page.getByRole('button', { name: 'Publish' })).toBeDisabled();
await expect(page.getByRole('button', { name: 'Save' })).not.toBeDisabled();
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByText('Saved')).toBeVisible();
await expect(page.getByRole('button', { name: 'Save' })).toBeDisabled();
await expect(page.getByRole('button', { name: 'Publish' })).not.toBeDisabled();
await page.getByRole('button', { name: 'Publish' }).click();
await expect(page.getByText('Published', { exact: true })).toBeVisible();
await expect(page.getByRole('button', { name: 'Unpublish' })).not.toBeDisabled();
await page.getByRole('textbox', { name: 'title' }).fill('Being an American in the UK');
await expect(page.getByRole('button', { name: 'Unpublish' })).toBeDisabled();
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByRole('button', { name: 'Unpublish' })).not.toBeDisabled();
await page.getByRole('button', { name: 'Unpublish' }).click();
await expect(page.getByRole('dialog', { name: 'Confirmation' })).toBeVisible();
await page.getByRole('button', { name: 'Yes, confirm' }).click();
await expect(page.getByText('Unpublished')).toBeVisible();
await expect(page.getByRole('button', { name: 'Publish' })).not.toBeDisabled();
await page.getByRole('button', { name: 'Delete this entry' }).click();
await expect(page.getByRole('dialog', { name: 'Confirmation' })).toBeVisible();
await page.getByRole('button', { name: 'Confirm' }).click();
await expect(page.getByText('Deleted')).toBeVisible();
/**
* We're back on the list view
*/
await page.waitForURL(
'**/content-manager/collection-types/api::article.article?page=1&pageSize=10&sort=title:ASC'
);
await expect(
page.getByRole('gridcell', { name: 'Being from Kansas City' })
).not.toBeVisible();
});
});
test.describe('Single Type', () => {
test('A user should be able to navigate to the EditView of the content manager to create, save, publish, unpublish & delete a new entry', async ({
page,
}) => {
await page.getByRole('link', { name: 'Content Manager' }).click();
await page.getByRole('link', { name: 'Homepage' }).click();
/**
* Now we're in the edit view.
*/
await page.waitForURL('**/content-manager/single-types/api::homepage.homepage');
await page.getByRole('textbox', { name: 'title' }).fill('Welcome to AFC Richmond');
await page
.getByRole('textbox')
.nth(1)
.fill(
"We're a premier league football club based in South West London with a vicious rivalry with Fulham. Because who doens't hate them?"
);
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByText('Saved')).toBeVisible();
await expect(page.getByRole('button', { name: 'Save' })).toBeDisabled();
await page.getByRole('button', { name: 'Publish' }).click();
await expect(page.getByText('Published', { exact: true })).toBeVisible();
await expect(page.getByRole('button', { name: 'Unpublish' })).not.toBeDisabled();
await page.getByRole('combobox', { name: 'admin_user' }).click();
await page.getByRole('option').nth(0).click();
await expect(page.getByRole('button', { name: 'Unpublish' })).toBeDisabled();
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByRole('button', { name: 'Unpublish' })).not.toBeDisabled();
await page.getByRole('button', { name: 'Unpublish' }).click();
await expect(page.getByRole('dialog', { name: 'Confirmation' })).toBeVisible();
await page.getByRole('button', { name: 'Yes, confirm' }).click();
await expect(page.getByText('Unpublished')).toBeVisible();
await expect(page.getByRole('button', { name: 'Publish' })).not.toBeDisabled();
await page.getByRole('button', { name: 'Delete this entry' }).click();
await expect(page.getByRole('dialog', { name: 'Confirmation' })).toBeVisible();
await page.getByRole('button', { name: 'Confirm' }).click();
await expect(page.getByText('Deleted')).toBeVisible();
await expect(page.getByRole('textbox', { name: 'title' })).toHaveText('');
});
});
});

View File

@ -18,7 +18,7 @@ test.describe('List View', () => {
await page.getByRole('link', { name: 'Content Manager' }).click();
await expect(page).toHaveTitle('Content Manager');
await expect(page.getByRole('heading', { name: 'testing' })).toBeVisible();
await expect(page.getByRole('heading', { name: 'Article' })).toBeVisible();
await expect(page.getByRole('link', { name: /Create new entry/ }).first()).toBeVisible();
});
});

View File

@ -101,7 +101,7 @@ const ContentTypeFormWrapper = ({
const { put, post, del } = fetchClient;
const isSingleType = collectionType === 'single-types';
const isCreatingEntry = !isSingleType && !id;
const isCreatingEntry = !isSingleType && id === 'create';
const requestURL =
isCreatingEntry && !origin

View File

@ -1,4 +1,4 @@
import 'koa-bodyparser';
import type {} from 'koa-body';
import authentication from './authentication';
import role from './role';

View File

@ -2,10 +2,7 @@
"extends": "tsconfig/base.json",
"include": ["src"],
"compilerOptions": {
"types": ["lodash", "jest"],
"rootDir": "../../",
"baseUrl": ".",
"esModuleInterop": true,
"allowJs": true
"baseUrl": "."
}
}

View File

@ -92,7 +92,6 @@
"js-cookie": "2.2.1",
"jsonwebtoken": "9.0.0",
"koa": "2.13.4",
"koa-bodyparser": "4.4.1",
"koa-compose": "4.1.0",
"koa-passport": "5.0.0",
"koa-static": "5.0.0",
@ -162,6 +161,7 @@
"@types/prettier": "2.7.3",
"@types/react-window": "1.8.8",
"@types/sanitize-html": "2.9.5",
"koa-body": "4.2.0",
"msw": "1.3.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View File

@ -26,16 +26,6 @@ import type {
const { isUsingTypeScript } = tsUtils;
/* TODO extend the request in this way once Replace is available
type FileRequest = Context['request'] & { file: unknown };
type FileContext = Replace<Context, { request: FileRequest }>;
*/
declare module 'koa' {
interface Request {
files: unknown;
}
}
/**
* A set of functions called "actions" for `Admin`
*/

View File

@ -1,4 +1,4 @@
import 'koa-bodyparser';
import type {} from 'koa-body';
import admin from './admin';
import apiToken from './api-token';

View File

@ -52,14 +52,14 @@
"@strapi/types": "4.17.1",
"@strapi/utils": "4.17.1",
"koa": "2.13.4",
"koa-bodyparser": "4.4.1",
"lodash": "4.17.21",
"qs": "6.11.1"
},
"devDependencies": {
"@strapi/pack-up": "workspace:*",
"@types/jest": "29.5.2",
"@types/lodash": "^4.14.191"
"@types/lodash": "^4.14.191",
"koa-body": "4.2.0"
},
"engines": {
"node": ">=18.0.0 <=20.x.x",

View File

@ -31,7 +31,10 @@ export default ({ strapi }: { strapi: Strapi }) => ({
return this.findUniqueUID({
contentTypeUID,
field,
value: slugify(defaultValue || contentType.modelName, options),
value: slugify(
_.isFunction(defaultValue) ? defaultValue() : defaultValue || contentType.modelName,
options
),
});
},

View File

@ -65,7 +65,6 @@
"@strapi/utils": "4.17.1",
"fs-extra": "10.1.0",
"immer": "9.0.19",
"koa-bodyparser": "4.4.1",
"lodash": "4.17.21",
"pluralize": "8.0.0",
"prop-types": "^15.8.1",
@ -80,9 +79,9 @@
"@strapi/types": "4.17.1",
"@testing-library/react": "14.0.0",
"@testing-library/user-event": "14.4.3",
"@types/koa-bodyparser": "4.3.12",
"@types/pluralize": "0.0.30",
"koa": "2.13.4",
"koa-body": "4.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "6.21.1",

View File

@ -1,6 +1,6 @@
import _ from 'lodash';
import type { Context } from 'koa';
import 'koa-bodyparser';
import type {} from 'koa-body';
import type { UID } from '@strapi/types';
import { getService } from '../utils';
import {

View File

@ -178,6 +178,9 @@ class Strapi extends Container implements StrapiI {
features: FeaturesService;
// @ts-expect-error - Assigned in constructor
ee: StrapiI['ee'];
constructor(opts: StrapiOptions = {}) {
super();

View File

@ -1,15 +0,0 @@
import glob, { IOptions } from 'glob';
/**
* Promise based glob
*/
function promiseGlob(...args: [string, IOptions]): Promise<string[]> {
return new Promise((resolve, reject) => {
glob(...args, (err, files) => {
if (err) return reject(err);
resolve(files);
});
});
}
export default promiseGlob;

View File

@ -2,6 +2,7 @@ import type { Fetch, Strapi } from '@strapi/types';
import { ProxyAgent } from 'undici';
// TODO: once core Node exposes a stable way to create a ProxyAgent we will use that instead of undici
export type { Fetch };
// Create a wrapper for Node's Fetch API that applies a global proxy
export function createStrapiFetch(strapi: Strapi): Fetch {

View File

@ -28,7 +28,6 @@ export const transformContentTypesToModels = (
): DatabaseConfig['models'] => {
return contentTypes.map((contentType) => {
// Add document id to content types
// @ts-expect-error - `default` function is not typed into `Attribute`
// as it is not documented
const documentIdAttribute: Record<string, Attribute.Any> =
contentType.modelType === 'contentType'

View File

@ -1,3 +1,4 @@
import type { IncomingMessage } from 'node:http';
import { randomUUID } from 'crypto';
import type { Context } from 'koa';
import type { RawData, ServerOptions } from 'ws';
@ -9,7 +10,7 @@ import { ProviderError, ProviderTransferError } from '../../../errors/providers'
import { VALID_TRANSFER_COMMANDS, ValidTransferCommand } from './constants';
import { TransferMethod } from '../constants';
type WSCallback = (client: WebSocket, request: Response) => void;
type WSCallback = (client: WebSocket, request: IncomingMessage) => void;
export interface HandlerOptions {
verify: (ctx: Context, scope?: TransferMethod) => Promise<void>;

View File

@ -70,6 +70,7 @@
"@types/koa": "2.13.4",
"@types/lodash": "^4.14.191",
"koa": "2.13.4",
"koa-body": "4.2.0",
"msw": "1.3.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View File

@ -2,6 +2,7 @@ import { pick } from 'lodash/fp';
import { errors } from '@strapi/utils';
import type Koa from 'koa';
import type {} from 'koa-body';
import type { EmailConfig, SendOptions } from '../types';
const { ApplicationError } = errors;
@ -13,7 +14,7 @@ const { ApplicationError } = errors;
*/
const emailController = {
async send(ctx: Koa.Context) {
const options: SendOptions = ctx.request.body;
const options = ctx.request.body as SendOptions;
try {
await strapi.plugin('email').service('email').send(options);
@ -32,7 +33,7 @@ const emailController = {
},
async test(ctx: Koa.Context) {
const { to } = ctx.request.body;
const { to } = ctx.request.body as Pick<SendOptions, 'to'>;
if (!to) {
throw new ApplicationError('No recipient(s) are given');

View File

@ -1,7 +1,7 @@
{
"extends": "./server/tsconfig.json",
"extends": "./tsconfig.json",
"include": ["./src", "../shared"],
"exclude": ["./server/src/**/*.test.ts"],
"exclude": ["node_modules", "**/*.test.ts"],
"compilerOptions": {
"rootDir": "../",
"baseUrl": ".",

View File

@ -3,6 +3,6 @@
"compilerOptions": {
"noEmit": true
},
"include": ["src"],
"include": ["src", "../shared"],
"exclude": ["node_modules"]
}

View File

@ -3,7 +3,6 @@
"include": ["./src", "../shared"],
"compilerOptions": {
"rootDir": "../",
"baseUrl": ".",
"esModuleInterop": true
"baseUrl": "."
}
}

View File

@ -73,6 +73,7 @@
"@strapi/icons": "1.14.1",
"@strapi/pack-up": "4.17.1",
"@strapi/types": "4.17.1",
"@strapi/utils": "4.17.1",
"@testing-library/react": "14.0.0",
"@testing-library/user-event": "14.4.3",
"cross-env": "^7.0.3",

View File

@ -173,9 +173,12 @@
},
"devDependencies": {
"@strapi/pack-up": "workspace:*",
"@types/find-root": "1.1.4",
"@types/jest": "29.5.2",
"@types/lodash": "^4.14.191",
"@types/node": "18.18.4",
"@types/webpack-bundle-analyzer": "4.6.3",
"@types/webpack-hot-middleware": "2.25.9",
"eslint-config-custom": "4.17.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View File

@ -17,6 +17,8 @@ interface BaseOptions {
stats?: boolean;
minify?: boolean;
sourcemaps?: boolean;
bundler?: 'webpack' | 'vite';
open?: boolean;
}
interface BuildContext<TOptions = unknown> extends BaseContext {
@ -51,7 +53,7 @@ const DEFAULT_BROWSERSLIST = [
'not dead',
];
const createBuildContext = async <TOptions>({
const createBuildContext = async <TOptions extends BaseOptions>({
cwd,
logger,
tsconfig,

View File

@ -23,7 +23,6 @@ const watch = async (ctx: BuildContext): Promise<WebpackWatcher> => {
const devMiddleware = webpackDevMiddleware(compiler);
// @ts-expect-error ignored
const hotMiddleware = webpackHotMiddleware(compiler, {
log: false,
path: '/__webpack_hmr',

View File

@ -56,7 +56,7 @@ type GetPopulatableKeysWithoutTarget<TSchemaUID extends Common.UID.Schema> = Exc
* Fragment populate notation for polymorphic attributes
*/
export type Fragment<TMaybeTargets extends Common.UID.Schema> = {
on?: { [TSchemaUID in TMaybeTargets]?: boolean | NestedParams<TSchemaUID> };
on?: { [key: string]: boolean | NestedParams<TMaybeTargets> };
};
type PopulateClause<
@ -108,9 +108,9 @@ export type ObjectNotation<TSchemaUID extends Common.UID.Schema> = [
}
>,
// Loose fallback when registries are not extended
| { [TKey in string]?: boolean | NestedParams<Common.UID.Schema> }
| { [key: string]: boolean | NestedParams<Common.UID.Schema> }
| {
[TKey in string]?:
[key: string]:
| boolean
| Fragment<Common.UID.Schema>
// TODO: V5: Remove root-level nested params for morph data structures and only allow fragments

View File

@ -61,7 +61,9 @@ export type StringNotation<TSchemaUID extends Common.UID.Schema> =
* type E = [42]; // ❌
* type F = 'title'; // ❌
*/
export type ArrayNotation<TSchemaUID extends Common.UID.Schema> = Any<TSchemaUID>[];
export type ArrayNotation<TSchemaUID extends Common.UID.Schema> =
| StringNotation<TSchemaUID>[]
| ObjectNotation<TSchemaUID>[];
/**
* Object notation for a sort
@ -74,15 +76,21 @@ export type ArrayNotation<TSchemaUID extends Common.UID.Schema> = Any<TSchemaUID
* type E = ['title']; // ❌
* type F = 'title'; // ❌
*/
export type ObjectNotation<TSchemaUID extends Common.UID.Schema> = {
[TKey in ObjectNotationKeys<TSchemaUID>]?: TKey extends SingleAttribute<TSchemaUID>
? // First level sort (scalar attributes, id, ...)
OrderKind.Any
: TKey extends Attribute.GetKeysWithTarget<TSchemaUID>
? // Deep sort (relations with a target, components, media, ...)
ObjectNotation<Attribute.GetTarget<TSchemaUID, TKey>>
: never;
};
export type ObjectNotation<TSchemaUID extends Common.UID.Schema> = Utils.Expression.If<
Common.AreSchemaRegistriesExtended,
{
[TKey in ObjectNotationKeys<TSchemaUID>]?: TKey extends SingleAttribute<TSchemaUID>
? // First level sort (scalar attributes, id, ...)
OrderKind.Any
: TKey extends Attribute.GetKeysWithTarget<TSchemaUID>
? // Deep sort (relations with a target, components, media, ...)
ObjectNotation<Attribute.GetTarget<TSchemaUID, TKey>>
: never;
},
{
[key: string]: OrderKind.Any | ObjectNotation<TSchemaUID>;
}
>;
/**
* Represents the keys of an object notation for a sort

View File

@ -61,7 +61,7 @@ export interface UniqueOption {
}
export interface DefaultOption<T> {
default?: T;
default?: T | (() => T);
}
export interface ConfigurableOption {

View File

@ -56,7 +56,6 @@
},
"devDependencies": {
"@strapi/pack-up": "4.17.1",
"@strapi/types": "4.17.1",
"@types/koa": "2.13.4",
"@types/node": "18.18.4",
"eslint-config-custom": "4.17.1",

View File

@ -1,5 +1,4 @@
import { traverseQueryPopulate } from '../traverse';
import { setGlobalStrapi, getStrapiFactory } from './test-utils';
describe('traverseQueryPopulate', () => {
test('should return an empty object incase no populatable field exists', async () => {
@ -18,7 +17,7 @@ describe('traverseQueryPopulate', () => {
});
test('should return all populatable fields', async () => {
const strapi = getStrapiFactory({
const strapi = {
getModel: jest.fn((uid) => {
return {
uid,
@ -39,9 +38,9 @@ describe('traverseQueryPopulate', () => {
})),
},
},
})();
} as any;
setGlobalStrapi(strapi);
global.strapi = strapi;
const query = await traverseQueryPopulate(jest.fn(), {
schema: {
@ -68,7 +67,7 @@ describe('traverseQueryPopulate', () => {
});
test('should return only selected populatable field', async () => {
const strapi = getStrapiFactory({
const strapi = {
getModel: jest.fn((uid) => {
return {
uid,
@ -88,9 +87,9 @@ describe('traverseQueryPopulate', () => {
})),
},
},
})();
} as any;
setGlobalStrapi(strapi);
global.strapi = strapi;
const query = await traverseQueryPopulate(jest.fn(), {
schema: {
@ -117,7 +116,7 @@ describe('traverseQueryPopulate', () => {
});
test('should populate dynamiczone', async () => {
const strapi = getStrapiFactory({
const strapi = {
getModel: jest.fn((uid) => {
return {
uid,
@ -137,9 +136,9 @@ describe('traverseQueryPopulate', () => {
})),
},
},
})();
} as any;
setGlobalStrapi(strapi);
global.strapi = strapi;
const query = await traverseQueryPopulate(jest.fn(), {
schema: {
@ -174,7 +173,7 @@ describe('traverseQueryPopulate', () => {
});
test('should deep populate dynamiczone components', async () => {
const strapi = getStrapiFactory({
const strapi = {
getModel: jest.fn((uid) => {
if (uid === 'blog.test-como') {
return {
@ -224,9 +223,9 @@ describe('traverseQueryPopulate', () => {
})),
},
},
})();
} as any;
setGlobalStrapi(strapi);
global.strapi = strapi;
const query = await traverseQueryPopulate(jest.fn(), {
schema: {

View File

@ -1,24 +0,0 @@
import type { LoadedStrapi } from '@strapi/types';
/**
* Update the global store with the given strapi value
*/
export const setGlobalStrapi = (strapi: LoadedStrapi): void => {
(global as unknown as Global).strapi = strapi;
};
/**
* Create a "Strapi" like object factory based on the
* given params and cast it to the correct type
*/
export const getStrapiFactory =
<
T extends {
[key in keyof Partial<LoadedStrapi>]: unknown;
}
>(
properties?: T
) =>
(additionalProperties?: Partial<T>) => {
return { ...properties, ...additionalProperties } as LoadedStrapi;
};

View File

@ -43,15 +43,22 @@ type FieldsParams = string | string[];
type FiltersParams = unknown;
export interface PopulateAttributesParams {
[key: string]: PopulateObjectParams;
[key: string]: boolean | PopulateObjectParams;
}
export interface PopulateObjectParams {
sort?: SortParams;
fields?: FieldsParams;
filters?: FiltersParams;
populate?: PopulateParams;
populate?: string | string[] | PopulateAttributesParams;
publicationState?: 'live' | 'preview';
on: PopulateAttributesParams;
on?: PopulateAttributesParams;
count?: boolean;
ordering?: unknown;
_q?: string;
limit?: number | string;
start?: number | string;
page?: number | string;
pageSize?: number | string;
}
type PopulateParams = string | string[] | PopulateAttributesParams;
@ -314,6 +321,12 @@ const convertPopulateQueryParams = (
throw new InvalidPopulateError();
};
const hasFragmentPopulateDefined = (
populate: PopulateObjectParams
): populate is PopulateObjectParams & Required<Pick<PopulateObjectParams, 'on'>> => {
return typeof populate === 'object' && 'on' in populate && !isNil(populate.on);
};
const convertPopulateObject = (populate: PopulateAttributesParams, schema?: Model) => {
if (!schema) {
return {};
@ -322,6 +335,10 @@ const convertPopulateObject = (populate: PopulateAttributesParams, schema?: Mode
const { attributes } = schema;
return Object.entries(populate).reduce((acc, [key, subPopulate]) => {
if (_.isBoolean(subPopulate)) {
return { ...acc, [key]: subPopulate };
}
const attribute = attributes[key];
if (!attribute) {
@ -332,10 +349,7 @@ const convertPopulateObject = (populate: PopulateAttributesParams, schema?: Mode
const isAllowedAttributeForFragmentPopulate =
isDynamicZoneAttribute(attribute) || isMorphToRelationalAttribute(attribute);
const hasFragmentPopulateDefined =
typeof subPopulate === 'object' && 'on' in subPopulate && !isNil(subPopulate.on);
if (isAllowedAttributeForFragmentPopulate && hasFragmentPopulateDefined) {
if (isAllowedAttributeForFragmentPopulate && hasFragmentPopulateDefined(subPopulate)) {
return {
...acc,
[key]: {
@ -408,7 +422,7 @@ const convertPopulateObject = (populate: PopulateAttributesParams, schema?: Mode
}, {});
};
const convertNestedPopulate = (subPopulate: PopulateObjectParams, schema?: Model) => {
const convertNestedPopulate = (subPopulate: boolean | PopulateObjectParams, schema?: Model) => {
if (_.isString(subPopulate)) {
return parseType({ type: 'boolean', value: subPopulate, forceCast: true });
}
@ -422,7 +436,7 @@ const convertNestedPopulate = (subPopulate: PopulateObjectParams, schema?: Model
}
const { sort, filters, fields, populate, count, ordering, page, pageSize, start, limit } =
subPopulate;
subPopulate as PopulateObjectParams;
const query: Query = {};

View File

@ -73,6 +73,7 @@
"@strapi/types": "4.17.1",
"@types/graphql-depth-limit": "1.1.5",
"@types/graphql-upload": "15.0.2",
"@types/koa-bodyparser": "4.3.12",
"@types/koa__cors": "5.0.0",
"cross-env": "^7.0.3",
"eslint-config-custom": "4.17.1",

View File

@ -76,7 +76,6 @@
"@strapi/types": "4.17.1",
"@testing-library/react": "14.0.0",
"@testing-library/user-event": "14.4.3",
"@types/koa-bodyparser": "4.3.12",
"koa": "2.13.4",
"msw": "1.3.0",
"react": "^18.2.0",

View File

@ -154,6 +154,8 @@ const build = async (opts: BuildOptions = {}) => {
},
error(err) {
handler.fail(ctx, task, err);
// exit as soon as one task fails
process.exit(1);
},
});
}

View File

@ -63,14 +63,12 @@ const dtsBuildTask: TaskHandler<DtsBuildTask> = {
printDiagnostic(diagnostic, { logger: ctx.logger, cwd: ctx.cwd });
}
if (emitResult.emitSkipped) {
const errors = allDiagnostics.filter(
(diag) => diag.category === ts.DiagnosticCategory.Error
);
const errors = allDiagnostics.filter(
(diag) => diag.category === ts.DiagnosticCategory.Error
);
if (errors.length) {
throw new Error('Failed to compile TypeScript definitions');
}
if (errors.length) {
throw new Error('Failed to compile TypeScript definitions');
}
})
)
@ -99,8 +97,6 @@ const dtsBuildTask: TaskHandler<DtsBuildTask> = {
if (isError(err)) {
ctx.logger.error(err.message);
}
process.exit(1);
},
};

View File

@ -9261,7 +9261,7 @@ __metadata:
js-cookie: "npm:2.2.1"
jsonwebtoken: "npm:9.0.0"
koa: "npm:2.13.4"
koa-bodyparser: "npm:4.4.1"
koa-body: "npm:4.2.0"
koa-compose: "npm:4.1.0"
koa-passport: "npm:5.0.0"
koa-static: "npm:5.0.0"
@ -9605,6 +9605,7 @@ __metadata:
"@strapi/icons": "npm:1.14.1"
"@strapi/pack-up": "npm:4.17.1"
"@strapi/types": "npm:4.17.1"
"@strapi/utils": "npm:4.17.1"
"@testing-library/react": "npm:14.0.0"
"@testing-library/user-event": "npm:14.4.3"
axios: "npm:1.6.0"
@ -9781,7 +9782,7 @@ __metadata:
"@types/jest": "npm:29.5.2"
"@types/lodash": "npm:^4.14.191"
koa: "npm:2.13.4"
koa-bodyparser: "npm:4.4.1"
koa-body: "npm:4.2.0"
lodash: "npm:4.17.21"
qs: "npm:6.11.1"
languageName: unknown
@ -9802,12 +9803,11 @@ __metadata:
"@strapi/utils": "npm:4.17.1"
"@testing-library/react": "npm:14.0.0"
"@testing-library/user-event": "npm:14.4.3"
"@types/koa-bodyparser": "npm:4.3.12"
"@types/pluralize": "npm:0.0.30"
fs-extra: "npm:10.1.0"
immer: "npm:9.0.19"
koa: "npm:2.13.4"
koa-bodyparser: "npm:4.4.1"
koa-body: "npm:4.2.0"
lodash: "npm:4.17.21"
pluralize: "npm:8.0.0"
prop-types: "npm:^15.8.1"
@ -9884,6 +9884,7 @@ __metadata:
"@types/koa": "npm:2.13.4"
"@types/lodash": "npm:^4.14.191"
koa: "npm:2.13.4"
koa-body: "npm:4.2.0"
lodash: "npm:4.17.21"
msw: "npm:1.3.0"
prop-types: "npm:^15.8.1"
@ -9920,6 +9921,7 @@ __metadata:
"@strapi/utils": "npm:4.17.1"
"@types/graphql-depth-limit": "npm:1.1.5"
"@types/graphql-upload": "npm:15.0.2"
"@types/koa-bodyparser": "npm:4.3.12"
"@types/koa__cors": "npm:5.0.0"
cross-env: "npm:^7.0.3"
eslint-config-custom: "npm:4.17.1"
@ -9964,7 +9966,6 @@ __metadata:
"@strapi/utils": "npm:4.17.1"
"@testing-library/react": "npm:14.0.0"
"@testing-library/user-event": "npm:14.4.3"
"@types/koa-bodyparser": "npm:4.3.12"
axios: "npm:1.6.0"
formik: "npm:2.4.0"
immer: "npm:9.0.19"
@ -10243,10 +10244,13 @@ __metadata:
"@strapi/types": "npm:4.17.1"
"@strapi/typescript-utils": "npm:4.17.1"
"@strapi/utils": "npm:4.17.1"
"@types/find-root": "npm:1.1.4"
"@types/jest": "npm:29.5.2"
"@types/lodash": "npm:^4.14.191"
"@types/node": "npm:18.18.4"
"@types/nodemon": "npm:1.19.6"
"@types/webpack-bundle-analyzer": "npm:4.6.3"
"@types/webpack-hot-middleware": "npm:2.25.9"
"@vitejs/plugin-react-swc": "npm:3.5.0"
boxen: "npm:5.1.2"
browserslist: "npm:^4.22.2"
@ -10422,7 +10426,6 @@ __metadata:
dependencies:
"@sindresorhus/slugify": "npm:1.1.0"
"@strapi/pack-up": "npm:4.17.1"
"@strapi/types": "npm:4.17.1"
"@types/koa": "npm:2.13.4"
"@types/node": "npm:18.18.4"
date-fns: "npm:2.30.0"
@ -11207,6 +11210,13 @@ __metadata:
languageName: node
linkType: hard
"@types/find-root@npm:1.1.4":
version: 1.1.4
resolution: "@types/find-root@npm:1.1.4"
checksum: e438c62b3ef3b706d058764797ec5227479ed4be98e9fec5456fb3b9a2096ccd3e35a84c94e2018278e22c651f12ae6ff4d6d7006b09fa5132da3612e2118076
languageName: node
linkType: hard
"@types/fined@npm:*":
version: 1.1.3
resolution: "@types/fined@npm:1.1.3"
@ -12197,6 +12207,28 @@ __metadata:
languageName: node
linkType: hard
"@types/webpack-bundle-analyzer@npm:4.6.3":
version: 4.6.3
resolution: "@types/webpack-bundle-analyzer@npm:4.6.3"
dependencies:
"@types/node": "npm:*"
tapable: "npm:^2.2.0"
webpack: "npm:^5"
checksum: 646b78aa5e06094b9558d49826fcecff6d7c67ab5e02120b9567a4cec904aaebb820ffac5f57963aada98a0603ae56c8aebfd9b54e8bb0597540e6687da063ac
languageName: node
linkType: hard
"@types/webpack-hot-middleware@npm:2.25.9":
version: 2.25.9
resolution: "@types/webpack-hot-middleware@npm:2.25.9"
dependencies:
"@types/connect": "npm:*"
tapable: "npm:^2.2.0"
webpack: "npm:^5"
checksum: bfa30ed24fcad7f4e4bce956ee7f2ddcc332428be38c2fa3613e8c53bd077d19806dc801de9c36cb77b966b38c9c9e27ef0367da25b684237f793955e406b657
languageName: node
linkType: hard
"@types/ws@npm:^8.5.4":
version: 8.5.4
resolution: "@types/ws@npm:8.5.4"
@ -28222,7 +28254,7 @@ __metadata:
languageName: node
linkType: hard
"qs@npm:6.11.1, qs@npm:^6.10.0, qs@npm:^6.10.2, qs@npm:^6.10.3, qs@npm:^6.11.0, qs@npm:^6.4.0, qs@npm:^6.5.2, qs@npm:^6.9.6":
"qs@npm:6.11.1, qs@npm:^6.10.0, qs@npm:^6.10.2, qs@npm:^6.10.3, qs@npm:^6.11.0, qs@npm:^6.4.0, qs@npm:^6.9.6":
version: 6.11.1
resolution: "qs@npm:6.11.1"
dependencies:
@ -28231,6 +28263,15 @@ __metadata:
languageName: node
linkType: hard
"qs@npm:^6.5.2":
version: 6.11.2
resolution: "qs@npm:6.11.2"
dependencies:
side-channel: "npm:^1.0.4"
checksum: f2321d0796664d0f94e92447ccd3bdfd6b6f3a50b6b762aa79d7f5b1ea3a7a9f94063ba896b82bc2a877ed6a7426d4081e4f16568fdb04f0ee188cca9d8505b4
languageName: node
linkType: hard
"qs@npm:~6.5.2":
version: 6.5.3
resolution: "qs@npm:6.5.3"
@ -28289,7 +28330,7 @@ __metadata:
languageName: node
linkType: hard
"raw-body@npm:2.5.1, raw-body@npm:^2.2.0, raw-body@npm:^2.3.3":
"raw-body@npm:2.5.1, raw-body@npm:^2.2.0":
version: 2.5.1
resolution: "raw-body@npm:2.5.1"
dependencies:
@ -28301,6 +28342,18 @@ __metadata:
languageName: node
linkType: hard
"raw-body@npm:^2.3.3":
version: 2.5.2
resolution: "raw-body@npm:2.5.2"
dependencies:
bytes: "npm:3.1.2"
http-errors: "npm:2.0.0"
iconv-lite: "npm:0.4.24"
unpipe: "npm:1.0.0"
checksum: 863b5171e140546a4d99f349b720abac4410338e23df5e409cfcc3752538c9caf947ce382c89129ba976f71894bd38b5806c774edac35ebf168d02aa1ac11a95
languageName: node
linkType: hard
"rc@npm:1.2.8, rc@npm:^1.2.7, rc@npm:^1.2.8":
version: 1.2.8
resolution: "rc@npm:1.2.8"
@ -33331,7 +33384,7 @@ __metadata:
languageName: node
linkType: hard
"webpack@npm:^5.89.0":
"webpack@npm:^5, webpack@npm:^5.89.0":
version: 5.89.0
resolution: "webpack@npm:5.89.0"
dependencies: