mirror of
https://github.com/strapi/strapi.git
synced 2025-08-15 12:18:38 +00:00
Refactored uid utils
Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
parent
cdefc1d2de
commit
b37a92c60f
@ -53,7 +53,7 @@
|
|||||||
{
|
{
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
"path": "/uid/generate",
|
"path": "/uid/generate",
|
||||||
"handler": "ContentManager.generateUID",
|
"handler": "uid.generateUID",
|
||||||
"config": {
|
"config": {
|
||||||
"policies": []
|
"policies": []
|
||||||
}
|
}
|
||||||
@ -61,11 +61,13 @@
|
|||||||
{
|
{
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
"path": "/uid/check-availability",
|
"path": "/uid/check-availability",
|
||||||
"handler": "ContentManager.checkUIDAvailability",
|
"handler": "uid.checkUIDAvailability",
|
||||||
"config": {
|
"config": {
|
||||||
"policies": []
|
"policies": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"path": "/explorer/:model",
|
"path": "/explorer/:model",
|
||||||
|
@ -4,11 +4,6 @@ const _ = require('lodash');
|
|||||||
const { contentTypes: contentTypesUtils } = require('strapi-utils');
|
const { contentTypes: contentTypesUtils } = require('strapi-utils');
|
||||||
|
|
||||||
const parseMultipartBody = require('../utils/parse-multipart');
|
const parseMultipartBody = require('../utils/parse-multipart');
|
||||||
const {
|
|
||||||
validateGenerateUIDInput,
|
|
||||||
validateCheckUIDAvailabilityInput,
|
|
||||||
validateUIDField,
|
|
||||||
} = require('./validation');
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
PUBLISHED_AT_ATTRIBUTE,
|
PUBLISHED_AT_ATTRIBUTE,
|
||||||
@ -47,37 +42,6 @@ const findEntityAndCheckPermissions = async (ability, action, model, id) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
async generateUID(ctx) {
|
|
||||||
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
|
||||||
|
|
||||||
await validateUIDField(contentTypeUID, field);
|
|
||||||
|
|
||||||
const uidService = strapi.plugins['content-manager'].services.uid;
|
|
||||||
|
|
||||||
ctx.body = {
|
|
||||||
data: await uidService.generateUIDField({ contentTypeUID, field, data }),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
async checkUIDAvailability(ctx) {
|
|
||||||
const { contentTypeUID, field, value } = await validateCheckUIDAvailabilityInput(
|
|
||||||
ctx.request.body
|
|
||||||
);
|
|
||||||
|
|
||||||
await validateUIDField(contentTypeUID, field);
|
|
||||||
|
|
||||||
const uidService = strapi.plugins['content-manager'].services.uid;
|
|
||||||
|
|
||||||
const isAvailable = await uidService.checkUIDAvailability({ contentTypeUID, field, value });
|
|
||||||
|
|
||||||
ctx.body = {
|
|
||||||
isAvailable,
|
|
||||||
suggestion: !isAvailable
|
|
||||||
? await uidService.findUniqueUID({ contentTypeUID, field, value })
|
|
||||||
: null,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of entities of a content-type matching the query parameters
|
* Returns a list of entities of a content-type matching the query parameters
|
||||||
*/
|
*/
|
||||||
|
41
packages/strapi-plugin-content-manager/controllers/uid.js
Normal file
41
packages/strapi-plugin-content-manager/controllers/uid.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { getService } = require('../utils');
|
||||||
|
const {
|
||||||
|
validateGenerateUIDInput,
|
||||||
|
validateCheckUIDAvailabilityInput,
|
||||||
|
validateUIDField,
|
||||||
|
} = require('./validation');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async generateUID(ctx) {
|
||||||
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
||||||
|
|
||||||
|
await validateUIDField(contentTypeUID, field);
|
||||||
|
|
||||||
|
const uidService = getService('uid');
|
||||||
|
|
||||||
|
ctx.body = {
|
||||||
|
data: await uidService.generateUIDField({ contentTypeUID, field, data }),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
async checkUIDAvailability(ctx) {
|
||||||
|
const { contentTypeUID, field, value } = await validateCheckUIDAvailabilityInput(
|
||||||
|
ctx.request.body
|
||||||
|
);
|
||||||
|
|
||||||
|
await validateUIDField(contentTypeUID, field);
|
||||||
|
|
||||||
|
const uidService = getService('uid');
|
||||||
|
|
||||||
|
const isAvailable = await uidService.checkUIDAvailability({ contentTypeUID, field, value });
|
||||||
|
|
||||||
|
ctx.body = {
|
||||||
|
isAvailable,
|
||||||
|
suggestion: !isAvailable
|
||||||
|
? await uidService.findUniqueUID({ contentTypeUID, field, value })
|
||||||
|
: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
@ -2,7 +2,16 @@ openapi: 3.0.2
|
|||||||
info:
|
info:
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
title: Strapi Content Manager API
|
title: Strapi Content Manager API
|
||||||
description: This is nice
|
description: |
|
||||||
|
## REST API Reference
|
||||||
|
|
||||||
|
This doc contains all the available routes in the content manager REST API.
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
- An authenticated admin token that you can get using the login route
|
||||||
|
---
|
||||||
|
|
||||||
servers:
|
servers:
|
||||||
- url: http://localhost:1337
|
- url: http://localhost:1337
|
||||||
description: Local server
|
description: Local server
|
||||||
@ -191,23 +200,89 @@ paths:
|
|||||||
data:
|
data:
|
||||||
$ref: '#/components/schemas/component-configuration'
|
$ref: '#/components/schemas/component-configuration'
|
||||||
|
|
||||||
|
# UID
|
||||||
/content-manager/uid/generate:
|
/content-manager/uid/generate:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- UID attribute utils
|
- UID attribute utils
|
||||||
description: Generate a uid
|
description: Generate a uid
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- contentTypeUID
|
||||||
|
- field
|
||||||
|
- data
|
||||||
|
properties:
|
||||||
|
contentTypeUID:
|
||||||
|
type: string
|
||||||
|
field:
|
||||||
|
type: string
|
||||||
|
data:
|
||||||
|
type: object
|
||||||
|
description: Current value of the entry being created or edited
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: A generated uid value
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- data
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: string
|
||||||
|
|
||||||
/content-manager/uid/check-availability:
|
/content-manager/uid/check-availability:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- UID attribute utils
|
- UID attribute utils
|
||||||
description: Check availability of a uid
|
description: Check availability of a uid
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- contentTypeUID
|
||||||
|
- field
|
||||||
|
- data
|
||||||
|
properties:
|
||||||
|
contentTypeUID:
|
||||||
|
type: string
|
||||||
|
field:
|
||||||
|
type: string
|
||||||
|
value:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: A generated uid value
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- isAvailable
|
||||||
|
properties:
|
||||||
|
isAvailable:
|
||||||
|
type: boolean
|
||||||
|
suggestion:
|
||||||
|
type: string
|
||||||
|
description: Suggestion if request value is not available
|
||||||
|
|
||||||
|
# Relationships
|
||||||
/content-manager/relationships/{modelUid}/{targetField}:
|
/content-manager/relationships/{modelUid}/{targetField}:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- Relational fields
|
- Relational fields
|
||||||
description: Fetch list of possible related content
|
description: Fetch list of possible related content
|
||||||
|
|
||||||
|
# Collection type
|
||||||
/content-manager/collection-type/{modelUid}:
|
/content-manager/collection-type/{modelUid}:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -246,6 +321,7 @@ paths:
|
|||||||
- Collection Types content management
|
- Collection Types content management
|
||||||
description: Unpublish one entry
|
description: Unpublish one entry
|
||||||
|
|
||||||
|
# Single type
|
||||||
/content-manager/single-type/{modelUid}:
|
/content-manager/single-type/{modelUid}:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { isNil, propEq, mapValues } = require('lodash/fp');
|
const { isNil, mapValues } = require('lodash/fp');
|
||||||
const { contentTypes: contentTypesUtils } = require('strapi-utils');
|
const { contentTypes: contentTypesUtils } = require('strapi-utils');
|
||||||
|
|
||||||
const { getService } = require('../utils');
|
const { getService } = require('../utils');
|
||||||
@ -33,7 +33,7 @@ const service = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
findDisplayedContentTypes() {
|
findDisplayedContentTypes() {
|
||||||
return this.findAllContentTypes().filter(propEq(true, 'isDisplayed'));
|
return this.findAllContentTypes().filter(({ isDisplayed }) => isDisplayed === true);
|
||||||
},
|
},
|
||||||
|
|
||||||
findContentTypesByKind(kind = contentTypesUtils.constants.COLLECTION_TYPE) {
|
findContentTypesByKind(kind = contentTypesUtils.constants.COLLECTION_TYPE) {
|
||||||
|
@ -39,7 +39,7 @@ describe('Content Manager single types', () => {
|
|||||||
describe('Generate UID', () => {
|
describe('Generate UID', () => {
|
||||||
test('Throws if input is not provided', async () => {
|
test('Throws if input is not provided', async () => {
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/generate`,
|
url: `/content-manager/uid/generate`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {},
|
body: {},
|
||||||
});
|
});
|
||||||
@ -59,7 +59,7 @@ describe('Content Manager single types', () => {
|
|||||||
|
|
||||||
test('Throws when contentType is not found', async () => {
|
test('Throws when contentType is not found', async () => {
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/generate`,
|
url: `/content-manager/uid/generate`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: 'non-existent',
|
contentTypeUID: 'non-existent',
|
||||||
@ -79,7 +79,7 @@ describe('Content Manager single types', () => {
|
|||||||
|
|
||||||
test('Throws when field is not a uid field', async () => {
|
test('Throws when field is not a uid field', async () => {
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/generate`,
|
url: `/content-manager/uid/generate`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
@ -99,9 +99,9 @@ describe('Content Manager single types', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Generates a unique field when not targetField', async () => {
|
test('Generates a unique field when targetField is empty', async () => {
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/generate`,
|
url: `/content-manager/uid/generate`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
@ -122,7 +122,7 @@ describe('Content Manager single types', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const secondRes = await rq({
|
const secondRes = await rq({
|
||||||
url: `/content-manager/explorer/uid/generate`,
|
url: `/content-manager/uid/generate`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
@ -137,7 +137,7 @@ describe('Content Manager single types', () => {
|
|||||||
|
|
||||||
test('Generates a unique field based on targetField', async () => {
|
test('Generates a unique field based on targetField', async () => {
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/generate`,
|
url: `/content-manager/uid/generate`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
@ -160,7 +160,7 @@ describe('Content Manager single types', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const secondRes = await rq({
|
const secondRes = await rq({
|
||||||
url: `/content-manager/explorer/uid/generate`,
|
url: `/content-manager/uid/generate`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
@ -177,7 +177,7 @@ describe('Content Manager single types', () => {
|
|||||||
|
|
||||||
test('Avoids collisions with already generated uids', async () => {
|
test('Avoids collisions with already generated uids', async () => {
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/generate`,
|
url: `/content-manager/uid/generate`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
@ -200,7 +200,7 @@ describe('Content Manager single types', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const secondRes = await rq({
|
const secondRes = await rq({
|
||||||
url: `/content-manager/explorer/uid/generate`,
|
url: `/content-manager/uid/generate`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
@ -223,7 +223,7 @@ describe('Content Manager single types', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const thridRes = await rq({
|
const thridRes = await rq({
|
||||||
url: `/content-manager/explorer/uid/generate`,
|
url: `/content-manager/uid/generate`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
@ -242,7 +242,7 @@ describe('Content Manager single types', () => {
|
|||||||
describe('Check UID availability', () => {
|
describe('Check UID availability', () => {
|
||||||
test('Throws if input is not provided', async () => {
|
test('Throws if input is not provided', async () => {
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/check-availability`,
|
url: `/content-manager/uid/check-availability`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {},
|
body: {},
|
||||||
});
|
});
|
||||||
@ -262,7 +262,7 @@ describe('Content Manager single types', () => {
|
|||||||
|
|
||||||
test('Throws on invalid uid value', async () => {
|
test('Throws on invalid uid value', async () => {
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/check-availability`,
|
url: `/content-manager/uid/check-availability`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
@ -281,7 +281,7 @@ describe('Content Manager single types', () => {
|
|||||||
|
|
||||||
test('Throws when contentType is not found', async () => {
|
test('Throws when contentType is not found', async () => {
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/check-availability`,
|
url: `/content-manager/uid/check-availability`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: 'non-existent',
|
contentTypeUID: 'non-existent',
|
||||||
@ -301,7 +301,7 @@ describe('Content Manager single types', () => {
|
|||||||
|
|
||||||
test('Throws when field is not a uid field', async () => {
|
test('Throws when field is not a uid field', async () => {
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/check-availability`,
|
url: `/content-manager/uid/check-availability`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
@ -323,7 +323,7 @@ describe('Content Manager single types', () => {
|
|||||||
|
|
||||||
test('Checks availability', async () => {
|
test('Checks availability', async () => {
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/check-availability`,
|
url: `/content-manager/uid/check-availability`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
@ -350,7 +350,7 @@ describe('Content Manager single types', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const res = await rq({
|
const res = await rq({
|
||||||
url: `/content-manager/explorer/uid/check-availability`,
|
url: `/content-manager/uid/check-availability`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
contentTypeUID: uid,
|
contentTypeUID: uid,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user