Fixed max-complexity-warnings for members API

no-issue

This removes logic from the Members API controller, and into the Members
BREAD service, this allows our controllers to be simpler and easier to
maintain, as well as keeping the important logic all together.
This commit is contained in:
Fabien O'Carroll 2021-10-25 13:53:13 +02:00
parent cfb5323017
commit a68b96001c
3 changed files with 11 additions and 108 deletions

View File

@ -59,8 +59,7 @@ module.exports = {
permissions: true, permissions: true,
validation: {}, validation: {},
async query(frame) { async query(frame) {
frame.options.withRelated = ['labels', 'stripeSubscriptions', 'stripeSubscriptions.customer', 'stripeSubscriptions.stripePrice', 'stripeSubscriptions.stripePrice.stripeProduct']; const page = await membersService.api.memberBREADService.browse(frame.options);
const page = await membersService.api.members.list(frame.options);
return page; return page;
} }
@ -84,7 +83,7 @@ module.exports = {
}, },
permissions: true, permissions: true,
async query(frame) { async query(frame) {
let member = await membersService.api.memberBREADService.read(frame.data, frame.options); const member = await membersService.api.memberBREADService.read(frame.data, frame.options);
if (!member) { if (!member) {
throw new errors.NotFoundError({ throw new errors.NotFoundError({
@ -115,72 +114,9 @@ module.exports = {
}, },
permissions: true, permissions: true,
async query(frame) { async query(frame) {
let member; const member = await membersService.api.memberBREADService.add(frame.data.members[0], frame.options);
frame.options.withRelated = ['stripeSubscriptions', 'products', 'labels', 'stripeSubscriptions.stripePrice', 'stripeSubscriptions.stripePrice.stripeProduct'];
if (!labsService.isSet('multipleProducts')) {
delete frame.data.products;
}
try {
if (!membersService.config.isStripeConnected()
&& (frame.data.members[0].stripe_customer_id || frame.data.members[0].comped)) {
const property = frame.data.members[0].comped ? 'comped' : 'stripe_customer_id';
throw new errors.ValidationError({ return member;
message: tpl(messages.stripeNotConnected.message),
context: tpl(messages.stripeNotConnected.context),
help: tpl(messages.stripeNotConnected.help),
property
});
}
member = await membersService.api.members.create(frame.data.members[0], frame.options);
if (frame.data.members[0].stripe_customer_id) {
await membersService.api.members.linkStripeCustomer({
customer_id: frame.data.members[0].stripe_customer_id,
member_id: member.id
}, frame.options);
}
if (!labsService.isSet('multipleProducts')) {
if (frame.data.members[0].comped) {
await membersService.api.members.setComplimentarySubscription(member);
}
}
if (frame.options.send_email) {
await membersService.api.sendEmailWithMagicLink({email: member.get('email'), requestedType: frame.options.email_type});
}
return member;
} catch (error) {
if (error.code && error.message.toLowerCase().indexOf('unique') !== -1) {
throw new errors.ValidationError({
message: tpl(messages.memberAlreadyExists.message),
context: tpl(messages.memberAlreadyExists.context, {
action: 'add'
})
});
}
// NOTE: failed to link Stripe customer/plan/subscription or have thrown custom Stripe connection error.
// It's a bit ugly doing regex matching to detect errors, but it's the easiest way that works without
// introducing additional logic/data format into current error handling
const isStripeLinkingError = error.message && (error.message.match(/customer|plan|subscription/g));
if (member && isStripeLinkingError) {
if (error.message.indexOf('customer') && error.code === 'resource_missing') {
error.message = `Member not imported. ${error.message}`;
error.context = tpl(messages.stripeCustomerNotFound.context);
error.help = tpl(messages.stripeCustomerNotFound.help);
}
await membersService.api.members.destroy({
id: member.get('id')
}, frame.options);
}
throw error;
}
} }
}, },
@ -199,42 +135,9 @@ module.exports = {
}, },
permissions: true, permissions: true,
async query(frame) { async query(frame) {
if (!labsService.isSet('multipleProducts')) { const member = await membersService.api.memberBREADService.edit(frame.data.members[0], frame.options);
delete frame.data.products;
}
try {
frame.options.withRelated = ['stripeSubscriptions', 'products', 'labels', 'stripeSubscriptions.stripePrice', 'stripeSubscriptions.stripePrice.stripeProduct'];
const member = await membersService.api.members.update(frame.data.members[0], frame.options);
const hasCompedSubscription = !!member.related('stripeSubscriptions').find(sub => sub.get('plan_nickname') === 'Complimentary' && sub.get('status') === 'active'); return member;
if (!labsService.isSet('multipleProducts')) {
if (typeof frame.data.members[0].comped === 'boolean') {
if (frame.data.members[0].comped && !hasCompedSubscription) {
await membersService.api.members.setComplimentarySubscription(member);
} else if (!(frame.data.members[0].comped) && hasCompedSubscription) {
await membersService.api.members.cancelComplimentarySubscription(member);
}
await member.load(['stripeSubscriptions', 'products', 'stripeSubscriptions.stripePrice', 'stripeSubscriptions.stripePrice.stripeProduct']);
}
}
await member.load(['stripeSubscriptions.customer', 'stripeSubscriptions.stripePrice', 'stripeSubscriptions.stripePrice.stripeProduct']);
return member;
} catch (error) {
if (error.code && error.message.toLowerCase().indexOf('unique') !== -1) {
throw new errors.ValidationError({
message: tpl(messages.memberAlreadyExists.message),
context: tpl(messages.memberAlreadyExists.context, {
action: 'edit'
})
});
}
throw error;
}
} }
}, },

View File

@ -79,7 +79,7 @@
"@tryghost/limit-service": "0.6.5", "@tryghost/limit-service": "0.6.5",
"@tryghost/logging": "0.2.2", "@tryghost/logging": "0.2.2",
"@tryghost/magic-link": "1.0.14", "@tryghost/magic-link": "1.0.14",
"@tryghost/members-api": "2.4.4", "@tryghost/members-api": "2.5.0",
"@tryghost/members-csv": "1.1.8", "@tryghost/members-csv": "1.1.8",
"@tryghost/members-importer": "0.3.4", "@tryghost/members-importer": "0.3.4",
"@tryghost/members-offers": "0.10.1", "@tryghost/members-offers": "0.10.1",

View File

@ -1529,10 +1529,10 @@
"@tryghost/domain-events" "^0.1.3" "@tryghost/domain-events" "^0.1.3"
"@tryghost/member-events" "^0.3.1" "@tryghost/member-events" "^0.3.1"
"@tryghost/members-api@2.4.4": "@tryghost/members-api@2.5.0":
version "2.4.4" version "2.5.0"
resolved "https://registry.yarnpkg.com/@tryghost/members-api/-/members-api-2.4.4.tgz#d47e35ff1f1f47712086d90679441ef468673898" resolved "https://registry.yarnpkg.com/@tryghost/members-api/-/members-api-2.5.0.tgz#6d3378c69f3134a328f9f154e4102c87f8ad5bb1"
integrity sha512-KQMqyrRAOufjq5TfxfST4Yb6VzHPC0ojYQPBcxpBO7wXJEG0TIFsCbV/e94OCy/YR01cckovHnNJy1XJlx+Eyw== integrity sha512-VKVc9N5/ikBz5HIqwSa1oOVOEJp+1PVrw/DDZGurGNwIGuMIiA64ynBxutICzQ3LgH8E3AxDWdqZhd/cOkNlNg==
dependencies: dependencies:
"@tryghost/debug" "^0.1.2" "@tryghost/debug" "^0.1.2"
"@tryghost/domain-events" "^0.1.3" "@tryghost/domain-events" "^0.1.3"