Added resource data to Mentions Admin API

refs https://github.com/TryGhost/Team/issues/2503

This is in the MentionController atm as it's considered a presentation
concern. We might want to consider moving this into the MentionsAPI in
future so that we can simplify the controller and even remove it
completely in favour of putting the data-mapping in the endpoint definition.
This commit is contained in:
Fabien "egg" O'Carroll 2023-02-02 13:34:39 +07:00
parent bef3516f72
commit e5d31e2900
5 changed files with 68 additions and 7 deletions

View File

@ -5,7 +5,7 @@ export default Model.extend({
source: attr('string'),
target: attr('string'),
timestamp: attr('date'),
resourceId: attr('string', {allowNull: true}),
resource: attr(),
sourceTitle: attr('string'),
sourceSiteTitle: attr('string'),
sourceAuthor: attr('string'),

View File

@ -7,7 +7,7 @@ module.exports = (model) => {
target: json.target,
timestamp: json.timestamp,
payload: json.payload,
resource_id: json.resourceId,
resource: json.resource,
source_title: json.sourceTitle,
source_site_title: json.sourceSiteTitle,
source_excerpt: json.sourceExcerpt,

View File

@ -10,11 +10,28 @@ const logging = require('@tryghost/logging');
* @typedef {import('@tryghost/webmentions/lib/MentionsAPI').Page} Page<Model>
*/
/**
* @typedef {object} MentionResource
* @prop {ObjectID} id
* @prop {string} type
* @prop {string} name
*/
/**
* @typedef {Mention} MentionDTO
* @prop {Resource} resource
*/
/**
* @typedef {object} IJobService
* @prop {(name: string, fn: Function) => void} addJob
*/
/**
* @typedef {object} IMentionResourceService
* @prop {(id: ObjectID) => Promise<MentionResource>} getByID
*/
module.exports = class MentionController {
/** @type {import('@tryghost/webmentions/lib/MentionsAPI')} */
#api;
@ -22,19 +39,24 @@ module.exports = class MentionController {
/** @type {IJobService} */
#jobService;
/** @type {IMentionResourceService} */
#mentionResourceService;
/**
* @param {object} deps
* @param {import('@tryghost/webmentions/lib/MentionsAPI')} deps.api
* @param {IJobService} deps.jobService
* @param {IMentionResourceService} deps.mentionResourceService
*/
async init(deps) {
this.#api = deps.api;
this.#jobService = deps.jobService;
this.#mentionResourceService = deps.mentionResourceService;
}
/**
* @param {import('@tryghost/api-framework').Frame} frame
* @returns {Promise<Page<Mention>>}
* @returns {Promise<Page<MentionDTO>>}
*/
async browse(frame) {
let limit;
@ -58,14 +80,34 @@ module.exports = class MentionController {
order = 'created_at asc';
}
const results = await this.#api.listMentions({
const mentions = await this.#api.listMentions({
filter: frame.options.filter,
order,
limit,
page
});
return results;
const resources = await Promise.all(mentions.data.map((mention) => {
return this.#mentionResourceService.getByID(mention.resourceId);
}));
/** @type {Page<MentionDTO>} */
const result = {
data: mentions.data.map((mention, index) => {
const mentionDTO = {
...mention.toJSON(),
resource: resources[index],
toJSON() {
return mentionDTO;
}
};
delete mentionDTO.resourceId;
return mentionDTO;
}),
meta: mentions.meta
};
return result;
}
/**

View File

@ -62,6 +62,25 @@ module.exports = {
offloaded: false
});
}
},
mentionResourceService: {
async getByID(id) {
if (!id) {
return null;
}
const post = await models.Post.findOne({id: id.toHexString()});
if (!post) {
return null;
}
return {
id: id,
name: post.get('title'),
type: 'post'
};
}
}
});

View File

@ -6,7 +6,7 @@ Object {
Object {
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"payload": null,
"resource_id": null,
"resource": null,
"source": Any<String>,
"source_author": null,
"source_excerpt": null,
@ -20,7 +20,7 @@ Object {
Object {
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"payload": null,
"resource_id": null,
"resource": null,
"source": Any<String>,
"source_author": null,
"source_excerpt": null,