mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-01 13:54:35 +03:00
Refactored member controller to use model layer
refs https://github.com/TryGhost/Members/pull/105 - As members module has become a core part it makes sense to follow the same principles as in all other controllers and use the model directly instead of calling external services. - Bumped @tryghost/members-api to 0.11.1 . New stripe-specific methods used in controllers are available starting with this version - Exposing these new methods is a little hacky because there are no relationships setup on members_* tables. Left notes for future improvements once relations are introduced. - We don't allow for chaging member's emails at the moment. For this reason had to modify JSON schema a little. It doesn't support OO inheritence: "This shortcoming is perhaps one of the biggest surprises of the combining operations in JSON schema: it does not behave like inheritance in an object-oriented language. " (ref. https://json-schema.org/understanding-json-schema/reference/combining.html#allof)
This commit is contained in:
parent
f31a338797
commit
e9e3f58792
@ -6,6 +6,28 @@ const membersService = require('../../services/members');
|
||||
const common = require('../../lib/common');
|
||||
const fsLib = require('../../lib/fs');
|
||||
|
||||
const listMembers = async function (options) {
|
||||
const res = (await models.Member.findPage(options));
|
||||
const members = res.data.map(model => model.toJSON(options));
|
||||
|
||||
// NOTE: this logic is here until relations between Members/MemberStripeCustomer/StripeCustomerSubscription
|
||||
// are in place
|
||||
const membersWithSubscriptions = await Promise.all(members.map(async function (member) {
|
||||
const subscriptions = await membersService.api.members.getStripeSubscriptions(member);
|
||||
|
||||
return Object.assign(member, {
|
||||
stripe: {
|
||||
subscriptions
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
return {
|
||||
members: membersWithSubscriptions,
|
||||
meta: res.meta
|
||||
};
|
||||
};
|
||||
|
||||
const members = {
|
||||
docName: 'members',
|
||||
browse: {
|
||||
@ -19,8 +41,8 @@ const members = {
|
||||
],
|
||||
permissions: true,
|
||||
validation: {},
|
||||
query(frame) {
|
||||
return membersService.api.members.list(frame.options);
|
||||
async query(frame) {
|
||||
return listMembers(frame.options);
|
||||
}
|
||||
},
|
||||
|
||||
@ -33,12 +55,24 @@ const members = {
|
||||
validation: {},
|
||||
permissions: true,
|
||||
async query(frame) {
|
||||
const member = await membersService.api.members.get(frame.data, frame.options);
|
||||
let member = await models.Member.findOne(frame.data, frame.options);
|
||||
|
||||
if (!member) {
|
||||
throw new common.errors.NotFoundError({
|
||||
message: common.i18n.t('errors.api.members.memberNotFound')
|
||||
});
|
||||
}
|
||||
|
||||
// NOTE: this logic is here until relations between Members/MemberStripeCustomer/StripeCustomerSubscription
|
||||
// are in place
|
||||
const subscriptions = await membersService.api.members.getStripeSubscriptions(member);
|
||||
member = member.toJSON(frame.options);
|
||||
Object.assign(member, {
|
||||
stripe: {
|
||||
subscriptions
|
||||
}
|
||||
});
|
||||
|
||||
return member;
|
||||
}
|
||||
},
|
||||
@ -63,10 +97,12 @@ const members = {
|
||||
permissions: true,
|
||||
async query(frame) {
|
||||
try {
|
||||
const member = await membersService.api.members.create(frame.data.members[0], {
|
||||
sendEmail: frame.options.send_email,
|
||||
emailType: frame.options.email_type
|
||||
});
|
||||
const member = await models.Member.add(frame.data.members[0], frame.options);
|
||||
|
||||
if (frame.options.send_email) {
|
||||
await membersService.api.sendEmailWithMagicLink(member.get('email'), frame.options.email_type);
|
||||
}
|
||||
|
||||
return member;
|
||||
} catch (error) {
|
||||
if (error.code && error.message.toLowerCase().indexOf('unique') !== -1) {
|
||||
@ -93,7 +129,8 @@ const members = {
|
||||
},
|
||||
permissions: true,
|
||||
async query(frame) {
|
||||
const member = await membersService.api.members.update(frame.data.members[0], frame.options);
|
||||
const member = await models.Member.edit(frame.data.members[0], frame.options);
|
||||
|
||||
return member;
|
||||
}
|
||||
},
|
||||
@ -114,7 +151,21 @@ const members = {
|
||||
permissions: true,
|
||||
async query(frame) {
|
||||
frame.options.require = true;
|
||||
await membersService.api.members.destroy(frame.options)
|
||||
|
||||
let member = await models.Member.findOne(frame.data, frame.options);
|
||||
|
||||
if (!member) {
|
||||
throw new common.errors.NotFoundError({
|
||||
message: common.i18n.t('errors.api.resource.resourceNotFound', {
|
||||
resource: 'Member'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// NOTE: move to a model layer once Members/MemberStripeCustomer relations are in place
|
||||
await membersService.api.members.destroyStripeSubscriptions(member);
|
||||
|
||||
await models.Member.destroy(frame.options)
|
||||
.catch(models.Member.NotFoundError, () => {
|
||||
throw new common.errors.NotFoundError({
|
||||
message: common.i18n.t('errors.api.resource.resourceNotFound', {
|
||||
@ -147,8 +198,8 @@ const members = {
|
||||
method: 'browse'
|
||||
},
|
||||
validation: {},
|
||||
query(frame) {
|
||||
return membersService.api.members.list(frame.options);
|
||||
async query(frame) {
|
||||
return listMembers(frame.options);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -13,7 +13,40 @@
|
||||
"maxItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"allOf": [{"$ref": "members#/definitions/member"}]
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"maxLength": 191,
|
||||
"pattern": "^([^,]|$)"
|
||||
},
|
||||
"note": {
|
||||
"type": "string",
|
||||
"minLength": 0,
|
||||
"maxLength": 2000
|
||||
},
|
||||
"subscribed": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"id": {
|
||||
"strip": true
|
||||
},
|
||||
"email": {
|
||||
"strip": true
|
||||
},
|
||||
"created_at": {
|
||||
"strip": true
|
||||
},
|
||||
"created_by": {
|
||||
"strip": true
|
||||
},
|
||||
"updated_at": {
|
||||
"strip": true
|
||||
},
|
||||
"updated_by": {
|
||||
"strip": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -41,7 +41,7 @@
|
||||
"dependencies": {
|
||||
"@nexes/nql": "0.3.0",
|
||||
"@tryghost/helpers": "1.1.20",
|
||||
"@tryghost/members-api": "0.11.0",
|
||||
"@tryghost/members-api": "0.11.1",
|
||||
"@tryghost/members-ssr": "0.7.3",
|
||||
"@tryghost/social-urls": "0.1.5",
|
||||
"@tryghost/string": "^0.1.3",
|
||||
|
@ -237,10 +237,10 @@
|
||||
jsonwebtoken "^8.5.1"
|
||||
lodash "^4.17.15"
|
||||
|
||||
"@tryghost/members-api@0.11.0":
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/members-api/-/members-api-0.11.0.tgz#94a6ca7b11bf5132b7c8102dc92501965bf2e766"
|
||||
integrity sha512-WV+8y1TzYnvoZGnw9kXH8hMuJhgebHbOskeJiy8X8yn45UD/hlMMuF+y015W1lrMYblEhBS5E4eGfAX+laKqOw==
|
||||
"@tryghost/members-api@0.11.1":
|
||||
version "0.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/members-api/-/members-api-0.11.1.tgz#c878ea23b46eeede101715d2ecc72df8f31f307a"
|
||||
integrity sha512-SeT66Ddkfq2PQIt9XGn+/qcgc2tRMShgFIuGcE01Df/b27WfkELQu8IP+CK/1giuXg/cooEdpoWmbLQ5qm/+3w==
|
||||
dependencies:
|
||||
"@tryghost/magic-link" "^0.3.3"
|
||||
bluebird "^3.5.4"
|
||||
|
Loading…
Reference in New Issue
Block a user