Added @tryghost/email-suppression-list package

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

This package contains definitions for the public interface of the
email suppression list as well as an abstract implementation.
This commit is contained in:
Fabien "egg" O'Carroll 2022-11-18 14:00:26 +07:00
parent 426c515f83
commit 22fe3ec88b
6 changed files with 150 additions and 0 deletions

View File

@ -0,0 +1,6 @@
module.exports = {
plugins: ['ghost'],
extends: [
'plugin:ghost/node'
]
};

View File

@ -0,0 +1,21 @@
# Email Suppression List
## Usage
## Develop
This is a monorepo package.
Follow the instructions for the top-level repo.
1. `git clone` this repo & `cd` into it as usual
2. Run `yarn` to install top-level dependencies.
## Test
- `yarn lint` run just eslint
- `yarn test` run lint and tests

View File

@ -0,0 +1 @@
module.exports = require('./lib/email-suppression-list');

View File

@ -0,0 +1,90 @@
const assert = require('assert');
/**
* @typedef {object} EmailSuppressionInfo
* @prop {'spam' | 'failed'} reason
* @prop {Date} timestamp
*/
/**
* @typedef {object} EmailSuppressedData
* @prop {true} suppressed
* @prop {EmailSuppressionInfo} info
*/
/**
* @typedef {object} EmailNotSuppressedData
* @prop {false} suppressed
* @prop {null} info
*/
/**
* @typedef {EmailSuppressedData | EmailNotSuppressedData} IEmailSuppressionData
*/
/**
* @typedef {object} IEmailSuppressionList
* @prop {(email: string) => Promise<EmailSuppressionData>} getSuppressionData
* @prop {(emails: string[]) => Promise<EmailSuppressionData[]>} getBulkSuppressionData
* @prop {(email: string) => Promise<boolean>} removeEmail
*/
/**
* @implements {IEmailSuppressionData}
*/
class EmailSuppressionData {
/** @type {boolean} */
suppressed;
/** @type {EmailSuppressionInfo | null} */
info;
constructor(suppressed, info) {
if (!suppressed) {
this.suppressed = false;
this.info = null;
} else {
this.suppressed = true;
assert(info.reason === 'spam' || info.reason === 'fail');
assert(info.timestamp instanceof Date);
this.info = {
reason: info.reason,
timestamp: info.timestamp
};
}
}
}
/**
* @abstract
* @implements {IEmailSuppressionList}
*/
class AbstractEmailSuppressionList {
/**
* @param {string} email
* @returns {Promise<boolean>}
*/
async removeEmail(email) {
return Promise.reject();
}
/**
* @param {string} email
* @returns {Promise<EmailSuppressionData>}
*/
async getSuppressionData(email) {
return Promise.reject();
}
/**
* @param {string[]} emails
* @returns {Promise<EmailSuppressionData[]>}
*/
async getBulkSuppressionData(emails) {
return Promise.all(emails.map(email => this.getSuppressionData(email)));
}
}
module.exports = {
AbstractEmailSuppressionList,
EmailSuppressionData
};

View File

@ -0,0 +1,26 @@
{
"name": "@tryghost/email-suppression-list",
"version": "0.0.0",
"repository": "https://github.com/TryGhost/Ghost/tree/main/packages/email-suppression-list",
"author": "Ghost Foundation",
"private": true,
"main": "index.js",
"scripts": {
"dev": "echo \"Implement me!\"",
"test": "NODE_ENV=testing c8 --all --check-coverage --reporter text --reporter cobertura mocha './test/**/*.test.js'",
"lint:code": "eslint *.js lib/ --ext .js --cache",
"lint": "yarn lint:code && yarn lint:test",
"lint:test": "eslint -c test/.eslintrc.js test/ --ext .js --cache"
},
"files": [
"index.js",
"lib"
],
"devDependencies": {
"c8": "7.12.0",
"mocha": "10.1.0",
"should": "13.2.3",
"sinon": "14.0.2"
},
"dependencies": {}
}

View File

@ -0,0 +1,6 @@
module.exports = {
plugins: ['ghost'],
extends: [
'plugin:ghost/test'
]
};