ghost 5.19.3 → 5.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/tryghost-adapter-manager-5.21.0.tgz +0 -0
- package/components/{tryghost-api-framework-5.19.3.tgz → tryghost-api-framework-5.21.0.tgz} +0 -0
- package/components/tryghost-api-version-compatibility-service-5.21.0.tgz +0 -0
- package/components/tryghost-audience-feedback-5.21.0.tgz +0 -0
- package/components/tryghost-bootstrap-socket-5.21.0.tgz +0 -0
- package/components/tryghost-constants-5.21.0.tgz +0 -0
- package/components/tryghost-custom-theme-settings-service-5.21.0.tgz +0 -0
- package/components/tryghost-data-generator-5.21.0.tgz +0 -0
- package/components/tryghost-domain-events-5.21.0.tgz +0 -0
- package/components/tryghost-email-analytics-provider-mailgun-5.21.0.tgz +0 -0
- package/components/tryghost-email-analytics-service-5.21.0.tgz +0 -0
- package/components/tryghost-email-content-generator-5.21.0.tgz +0 -0
- package/components/tryghost-express-dynamic-redirects-5.21.0.tgz +0 -0
- package/components/tryghost-extract-api-key-5.21.0.tgz +0 -0
- package/components/tryghost-html-to-plaintext-5.21.0.tgz +0 -0
- package/components/{tryghost-job-manager-5.19.3.tgz → tryghost-job-manager-5.21.0.tgz} +0 -0
- package/components/tryghost-link-redirects-5.21.0.tgz +0 -0
- package/components/tryghost-link-replacer-5.21.0.tgz +0 -0
- package/components/tryghost-link-tracking-5.21.0.tgz +0 -0
- package/components/tryghost-magic-link-5.21.0.tgz +0 -0
- package/components/tryghost-mailgun-client-5.21.0.tgz +0 -0
- package/components/tryghost-member-analytics-service-5.21.0.tgz +0 -0
- package/components/tryghost-member-attribution-5.21.0.tgz +0 -0
- package/components/tryghost-member-events-5.21.0.tgz +0 -0
- package/components/tryghost-members-analytics-ingress-5.21.0.tgz +0 -0
- package/components/tryghost-members-api-5.21.0.tgz +0 -0
- package/components/tryghost-members-csv-5.21.0.tgz +0 -0
- package/components/tryghost-members-events-service-5.21.0.tgz +0 -0
- package/components/tryghost-members-importer-5.21.0.tgz +0 -0
- package/components/tryghost-members-offers-5.21.0.tgz +0 -0
- package/components/tryghost-members-payments-5.21.0.tgz +0 -0
- package/components/{tryghost-members-ssr-5.19.3.tgz → tryghost-members-ssr-5.21.0.tgz} +0 -0
- package/components/tryghost-members-stripe-service-5.21.0.tgz +0 -0
- package/components/tryghost-minifier-5.21.0.tgz +0 -0
- package/components/tryghost-mw-api-version-mismatch-5.21.0.tgz +0 -0
- package/components/tryghost-mw-cache-control-5.21.0.tgz +0 -0
- package/components/tryghost-mw-error-handler-5.21.0.tgz +0 -0
- package/components/tryghost-mw-session-from-token-5.21.0.tgz +0 -0
- package/components/tryghost-mw-update-user-last-seen-5.21.0.tgz +0 -0
- package/components/tryghost-mw-vhost-5.21.0.tgz +0 -0
- package/components/tryghost-oembed-service-5.21.0.tgz +0 -0
- package/components/{tryghost-package-json-5.19.3.tgz → tryghost-package-json-5.21.0.tgz} +0 -0
- package/components/tryghost-referrers-5.21.0.tgz +0 -0
- package/components/tryghost-security-5.21.0.tgz +0 -0
- package/components/tryghost-session-service-5.21.0.tgz +0 -0
- package/components/tryghost-settings-path-manager-5.21.0.tgz +0 -0
- package/components/tryghost-staff-service-5.21.0.tgz +0 -0
- package/components/tryghost-stats-service-5.21.0.tgz +0 -0
- package/components/tryghost-tiers-5.21.0.tgz +0 -0
- package/components/{tryghost-update-check-service-5.19.3.tgz → tryghost-update-check-service-5.21.0.tgz} +0 -0
- package/components/tryghost-verification-trigger-5.21.0.tgz +0 -0
- package/components/tryghost-version-notifications-data-service-5.21.0.tgz +0 -0
- package/core/boot.js +2 -0
- package/core/built/admin/assets/{chunk.143.c035c61595ed02eee886.js → chunk.143.9cddfa7bd1a8b9cf3d4b.js} +7 -7
- package/core/built/admin/assets/{chunk.178.998dfbcebcec635146b1.js → chunk.178.6de14cfdb28df721b66e.js} +4 -4
- package/core/built/admin/assets/{chunk.613.f1d519ad47e7f9024263.js → chunk.613.695f31829550fb00d43c.js} +352 -421
- package/core/built/admin/assets/{chunk.613.f1d519ad47e7f9024263.js.LICENSE.txt → chunk.613.695f31829550fb00d43c.js.LICENSE.txt} +0 -0
- package/core/built/admin/assets/{ghost-5ce6f5a730c83c91fc258b12c537ea35.js → ghost-192fee3b46a193df1e65c49a67a7d694.js} +2866 -2707
- package/core/built/admin/assets/ghost-9873519a8ad69b5b23284f0a9e050bc6.css +1 -0
- package/core/built/admin/assets/ghost-dark-190bdce42b125c3d4be930bd7599b442.css +1 -0
- package/core/built/admin/assets/{vendor-5c7d7063620bec13668c4370145cd4b4.js → vendor-26cca1d4d56660dc6e915a12ccc3b330.js} +1079 -1032
- package/core/built/admin/index.html +7 -7
- package/core/cli/generate-data.js +51 -0
- package/core/frontend/helpers/ghost_head.js +1 -1
- package/core/server/api/endpoints/links.js +34 -1
- package/core/server/api/endpoints/members.js +1 -4
- package/core/server/api/endpoints/posts-public.js +1 -1
- package/core/server/api/endpoints/posts.js +2 -1
- package/core/server/api/endpoints/tiers-public.js +2 -14
- package/core/server/api/endpoints/tiers.js +5 -51
- package/core/server/api/endpoints/utils/serializers/input/posts.js +21 -1
- package/core/server/api/endpoints/utils/serializers/input/settings.js +1 -0
- package/core/server/api/endpoints/utils/serializers/input/tiers.js +18 -27
- package/core/server/api/endpoints/utils/serializers/output/index.js +4 -0
- package/core/server/api/endpoints/utils/serializers/output/links.js +5 -0
- package/core/server/api/endpoints/utils/serializers/output/mappers/activity-feed-events.js +89 -15
- package/core/server/api/endpoints/utils/serializers/output/mappers/posts.js +20 -6
- package/core/server/api/endpoints/utils/serializers/output/mappers/snippets.js +2 -2
- package/core/server/api/endpoints/utils/serializers/output/members.js +6 -5
- package/core/server/api/endpoints/utils/serializers/output/tiers.js +15 -55
- package/core/server/data/db/backup.js +17 -10
- package/core/server/data/importer/importers/data/custom-theme-settings.js +81 -0
- package/core/server/data/importer/importers/data/data-importer.js +2 -0
- package/core/server/data/migrations/utils/permissions.js +35 -24
- package/core/server/data/migrations/versions/5.20/2022-10-18-05-39-drop-nullable-tier-id.js +3 -0
- package/core/server/data/migrations/versions/5.20/2022-10-18-10-13-add-ghost-subscription-id-column-to-mscs.js +10 -0
- package/core/server/data/migrations/versions/5.20/2022-10-19-11-17-add-link-browse-permissions.js +10 -0
- package/core/server/data/migrations/versions/5.20/2022-10-20-02-52-add-link-edit-permissions.js +10 -0
- package/core/server/data/migrations/versions/5.21/2022-10-24-07-23-disable-feedback-enabled.js +20 -0
- package/core/server/data/migrations/versions/5.21/2022-10-25-12-05-backfill-missed-products-columns.js +35 -0
- package/core/server/data/migrations/versions/5.21/2022-10-26-04-49-add-batch-id-members-created-events.js +7 -0
- package/core/server/data/migrations/versions/5.21/2022-10-26-04-49-add-batch-id-subscription-created-events.js +7 -0
- package/core/server/data/migrations/versions/5.21/2022-10-26-04-50-member-subscription-created-batch-id.js +72 -0
- package/core/server/data/migrations/versions/5.21/2022-10-26-09-32-add-feedback-enabled-column-to-emails.js +7 -0
- package/core/server/data/migrations/versions/5.21/2022-10-27-09-50-add-member-track-source-setting.js +8 -0
- package/core/server/data/schema/commands.js +107 -48
- package/core/server/data/schema/default-settings/default-settings.json +8 -0
- package/core/server/data/schema/fixtures/fixture-manager.js +16 -14
- package/core/server/data/schema/fixtures/fixtures.json +14 -2
- package/core/server/data/schema/schema.js +7 -3
- package/core/server/models/base/plugins/actions.js +1 -1
- package/core/server/models/base/plugins/crud.js +12 -0
- package/core/server/models/email-recipient.js +14 -0
- package/core/server/models/email.js +2 -5
- package/core/server/models/member-click-event.js +37 -0
- package/core/server/models/member-created-event.js +23 -0
- package/core/server/models/member-paid-subscription-event.js +19 -0
- package/core/server/models/member.js +6 -0
- package/core/server/models/post.js +33 -2
- package/core/server/models/redirect.js +1 -0
- package/core/server/models/subscription-created-event.js +7 -0
- package/core/server/services/audience-feedback/index.js +2 -0
- package/core/server/services/link-redirection/LinkRedirectRepository.js +16 -5
- package/core/server/services/link-tracking/PostLinkRepository.js +26 -2
- package/core/server/services/link-tracking/index.js +3 -1
- package/core/server/services/mega/feedback-buttons.js +87 -16
- package/core/server/services/mega/mega.js +1 -0
- package/core/server/services/mega/template.js +3 -0
- package/core/server/services/member-attribution/index.js +3 -1
- package/core/server/services/members/api.js +4 -1
- package/core/server/services/members/service.js +8 -1
- package/core/server/services/newsletters/index.js +3 -1
- package/core/server/services/newsletters/service.js +11 -1
- package/core/server/services/tiers/TierRepository.js +116 -0
- package/core/server/services/tiers/index.js +1 -0
- package/core/server/services/tiers/service.js +32 -0
- package/core/server/services/url/UrlGenerator.js +4 -2
- package/core/server/web/api/endpoints/admin/routes.js +1 -0
- package/core/shared/config/defaults.json +1 -1
- package/core/shared/labs.js +7 -8
- package/ghost.js +1 -0
- package/package.json +117 -113
- package/yarn.lock +1187 -1129
- package/components/tryghost-adapter-manager-5.19.3.tgz +0 -0
- package/components/tryghost-api-version-compatibility-service-5.19.3.tgz +0 -0
- package/components/tryghost-audience-feedback-5.19.3.tgz +0 -0
- package/components/tryghost-bootstrap-socket-5.19.3.tgz +0 -0
- package/components/tryghost-constants-5.19.3.tgz +0 -0
- package/components/tryghost-custom-theme-settings-service-5.19.3.tgz +0 -0
- package/components/tryghost-domain-events-5.19.3.tgz +0 -0
- package/components/tryghost-email-analytics-provider-mailgun-5.19.3.tgz +0 -0
- package/components/tryghost-email-analytics-service-5.19.3.tgz +0 -0
- package/components/tryghost-email-content-generator-5.19.3.tgz +0 -0
- package/components/tryghost-express-dynamic-redirects-5.19.3.tgz +0 -0
- package/components/tryghost-extract-api-key-5.19.3.tgz +0 -0
- package/components/tryghost-html-to-plaintext-5.19.3.tgz +0 -0
- package/components/tryghost-link-redirects-5.19.3.tgz +0 -0
- package/components/tryghost-link-replacer-5.19.3.tgz +0 -0
- package/components/tryghost-link-tracking-5.19.3.tgz +0 -0
- package/components/tryghost-magic-link-5.19.3.tgz +0 -0
- package/components/tryghost-mailgun-client-5.19.3.tgz +0 -0
- package/components/tryghost-member-analytics-service-5.19.3.tgz +0 -0
- package/components/tryghost-member-attribution-5.19.3.tgz +0 -0
- package/components/tryghost-member-events-5.19.3.tgz +0 -0
- package/components/tryghost-members-analytics-ingress-5.19.3.tgz +0 -0
- package/components/tryghost-members-api-5.19.3.tgz +0 -0
- package/components/tryghost-members-csv-5.19.3.tgz +0 -0
- package/components/tryghost-members-events-service-5.19.3.tgz +0 -0
- package/components/tryghost-members-importer-5.19.3.tgz +0 -0
- package/components/tryghost-members-offers-5.19.3.tgz +0 -0
- package/components/tryghost-members-payments-5.19.3.tgz +0 -0
- package/components/tryghost-members-stripe-service-5.19.3.tgz +0 -0
- package/components/tryghost-minifier-5.19.3.tgz +0 -0
- package/components/tryghost-mw-api-version-mismatch-5.19.3.tgz +0 -0
- package/components/tryghost-mw-cache-control-5.19.3.tgz +0 -0
- package/components/tryghost-mw-error-handler-5.19.3.tgz +0 -0
- package/components/tryghost-mw-session-from-token-5.19.3.tgz +0 -0
- package/components/tryghost-mw-update-user-last-seen-5.19.3.tgz +0 -0
- package/components/tryghost-mw-vhost-5.19.3.tgz +0 -0
- package/components/tryghost-oembed-service-5.19.3.tgz +0 -0
- package/components/tryghost-referrers-5.19.3.tgz +0 -0
- package/components/tryghost-security-5.19.3.tgz +0 -0
- package/components/tryghost-session-service-5.19.3.tgz +0 -0
- package/components/tryghost-settings-path-manager-5.19.3.tgz +0 -0
- package/components/tryghost-staff-service-5.19.3.tgz +0 -0
- package/components/tryghost-stats-service-5.19.3.tgz +0 -0
- package/components/tryghost-verification-trigger-5.19.3.tgz +0 -0
- package/components/tryghost-version-notifications-data-service-5.19.3.tgz +0 -0
- package/core/built/admin/assets/ghost-982146a4ada3a5af1981d1919ae01d08.css +0 -1
- package/core/built/admin/assets/ghost-dark-41929e4857de411a23597a9de49a4e4f.css +0 -1
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<title>Ghost Admin</title>
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
<meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.
|
|
11
|
+
<meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.21%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%7D" />
|
|
12
12
|
|
|
13
13
|
<meta name="HandheldFriendly" content="True" />
|
|
14
14
|
<meta name="MobileOptimized" content="320" />
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
</style>
|
|
38
38
|
|
|
39
39
|
<link integrity="" rel="stylesheet" href="assets/vendor-3e6947aa681f0fb82b193090e520dc73.css">
|
|
40
|
-
<link integrity="" rel="stylesheet" href="assets/ghost-
|
|
40
|
+
<link integrity="" rel="stylesheet" href="assets/ghost-9873519a8ad69b5b23284f0a9e050bc6.css" title="light">
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
</head>
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
|
|
46
46
|
<div class="ember-load-indicator">
|
|
47
47
|
<div class="gh-loading-content">
|
|
48
|
-
<video width="100" height="100" loop
|
|
48
|
+
<video width="100" height="100" loop autoplay muted playsinline preload="metadata" style="width: 100px; height: 100px;">
|
|
49
49
|
<source src="assets/videos/logo-loader.mp4" type="video/mp4" />
|
|
50
50
|
<div class="gh-loading-spinner"></div>
|
|
51
51
|
</video>
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
|
|
57
57
|
<div id="ember-basic-dropdown-wormhole"></div>
|
|
58
58
|
|
|
59
|
-
<script src="assets/vendor-
|
|
60
|
-
<script src="assets/chunk.613.
|
|
61
|
-
<script src="assets/chunk.143.
|
|
62
|
-
<script src="assets/ghost-
|
|
59
|
+
<script src="assets/vendor-26cca1d4d56660dc6e915a12ccc3b330.js"></script>
|
|
60
|
+
<script src="assets/chunk.613.695f31829550fb00d43c.js"></script>
|
|
61
|
+
<script src="assets/chunk.143.9cddfa7bd1a8b9cf3d4b.js"></script>
|
|
62
|
+
<script src="assets/ghost-192fee3b46a193df1e65c49a67a7d694.js"></script>
|
|
63
63
|
</body>
|
|
64
64
|
</html>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const Command = require('./command');
|
|
2
|
+
const DataGenerator = require('@tryghost/data-generator');
|
|
3
|
+
|
|
4
|
+
module.exports = class REPL extends Command {
|
|
5
|
+
setup() {
|
|
6
|
+
this.help('Generates random data to populate the database for development & testing');
|
|
7
|
+
this.argument('--use-base-data', {type: 'boolean', defaultValue: false, desc: 'Only generate data outside of a defined base data set'});
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
initializeContext(context) {
|
|
11
|
+
const models = require('../server/models');
|
|
12
|
+
const knex = require('../server/data/db/connection');
|
|
13
|
+
|
|
14
|
+
models.init();
|
|
15
|
+
|
|
16
|
+
context.models = models;
|
|
17
|
+
context.m = models;
|
|
18
|
+
context.knex = knex;
|
|
19
|
+
context.k = knex;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
permittedEnvironments() {
|
|
23
|
+
return ['development', 'local', 'staging', 'production'];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async handle(argv = {}) {
|
|
27
|
+
const knex = require('../server/data/db/connection');
|
|
28
|
+
const {tables: schema} = require('../server/data/schema/index');
|
|
29
|
+
const dataGenerator = new DataGenerator({
|
|
30
|
+
useBaseData: argv['use-base-data'],
|
|
31
|
+
knex,
|
|
32
|
+
schema,
|
|
33
|
+
logger: {
|
|
34
|
+
log: this.log,
|
|
35
|
+
ok: this.ok,
|
|
36
|
+
info: this.info,
|
|
37
|
+
warn: this.warn,
|
|
38
|
+
error: this.error,
|
|
39
|
+
fatal: this.fatal,
|
|
40
|
+
debug: this.debug
|
|
41
|
+
},
|
|
42
|
+
modelQuantities: {}
|
|
43
|
+
});
|
|
44
|
+
try {
|
|
45
|
+
await dataGenerator.importData();
|
|
46
|
+
} catch (error) {
|
|
47
|
+
this.fatal('Failed while generating data: ', error);
|
|
48
|
+
}
|
|
49
|
+
knex.destroy();
|
|
50
|
+
}
|
|
51
|
+
};
|
|
@@ -234,7 +234,7 @@ module.exports = async function ghost_head(options) { // eslint-disable-line cam
|
|
|
234
234
|
head.push(`<script defer src="${getAssetUrl('public/comment-counts.min.js')}" data-ghost-comments-counts-api="${urlUtils.getSiteUrl(true)}members/api/comments/counts/"></script>`);
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
if (settingsCache.get('members_enabled')) {
|
|
237
|
+
if (settingsCache.get('members_enabled') && settingsCache.get('members_track_sources')) {
|
|
238
238
|
head.push(`<script defer src="${getAssetUrl('public/member-attribution.min.js')}"></script>`);
|
|
239
239
|
}
|
|
240
240
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const linkTrackingService = require('../../services/link-tracking');
|
|
2
|
+
const INVALIDATE_ALL_REDIRECTS = '/r/*';
|
|
2
3
|
|
|
3
4
|
module.exports = {
|
|
4
5
|
docName: 'links',
|
|
@@ -6,7 +7,7 @@ module.exports = {
|
|
|
6
7
|
options: [
|
|
7
8
|
'filter'
|
|
8
9
|
],
|
|
9
|
-
permissions:
|
|
10
|
+
permissions: true,
|
|
10
11
|
async query(frame) {
|
|
11
12
|
const links = await linkTrackingService.service.getLinks(frame.options);
|
|
12
13
|
|
|
@@ -21,5 +22,37 @@ module.exports = {
|
|
|
21
22
|
}
|
|
22
23
|
};
|
|
23
24
|
}
|
|
25
|
+
},
|
|
26
|
+
bulkEdit: {
|
|
27
|
+
statusCode: 200,
|
|
28
|
+
headers: {
|
|
29
|
+
cacheInvalidate: INVALIDATE_ALL_REDIRECTS
|
|
30
|
+
},
|
|
31
|
+
options: [
|
|
32
|
+
'filter'
|
|
33
|
+
],
|
|
34
|
+
data: [
|
|
35
|
+
'action',
|
|
36
|
+
'meta'
|
|
37
|
+
],
|
|
38
|
+
validation: {
|
|
39
|
+
data: {
|
|
40
|
+
action: {
|
|
41
|
+
required: true,
|
|
42
|
+
values: ['updateLink']
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
options: {
|
|
46
|
+
filter: {
|
|
47
|
+
required: true
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
permissions: {
|
|
52
|
+
method: 'edit'
|
|
53
|
+
},
|
|
54
|
+
async query(frame) {
|
|
55
|
+
return await linkTrackingService.service.bulkEdit(frame.data.bulk, frame.options);
|
|
56
|
+
}
|
|
24
57
|
}
|
|
25
58
|
};
|
|
@@ -435,10 +435,7 @@ module.exports = {
|
|
|
435
435
|
method: 'browse'
|
|
436
436
|
},
|
|
437
437
|
async query(frame) {
|
|
438
|
-
|
|
439
|
-
return {
|
|
440
|
-
events
|
|
441
|
-
};
|
|
438
|
+
return await membersService.api.events.getEventTimeline(frame.options);
|
|
442
439
|
}
|
|
443
440
|
}
|
|
444
441
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const models = require('../../models');
|
|
2
2
|
const tpl = require('@tryghost/tpl');
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
|
-
const allowedIncludes = ['tags', 'authors', 'tiers'];
|
|
4
|
+
const allowedIncludes = ['tags', 'authors', 'tiers', 'sentiment'];
|
|
5
5
|
|
|
6
6
|
const messages = {
|
|
7
7
|
postNotFound: 'Post not found.'
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// as it is a getter and may change during runtime.
|
|
3
|
-
const membersService = require('../../services/members');
|
|
4
|
-
|
|
5
|
-
const allowedIncludes = ['monthly_price', 'yearly_price', 'benefits'];
|
|
1
|
+
const tiersService = require('../../services/tiers');
|
|
6
2
|
|
|
7
3
|
module.exports = {
|
|
8
4
|
docName: 'tiers',
|
|
@@ -11,22 +7,14 @@ module.exports = {
|
|
|
11
7
|
options: [
|
|
12
8
|
'limit',
|
|
13
9
|
'fields',
|
|
14
|
-
'include',
|
|
15
10
|
'filter',
|
|
16
11
|
'order',
|
|
17
12
|
'debug',
|
|
18
13
|
'page'
|
|
19
14
|
],
|
|
20
15
|
permissions: true,
|
|
21
|
-
validation: {
|
|
22
|
-
options: {
|
|
23
|
-
include: {
|
|
24
|
-
values: allowedIncludes
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
16
|
async query(frame) {
|
|
29
|
-
const page = await
|
|
17
|
+
const page = await tiersService.api.browse(frame.options);
|
|
30
18
|
|
|
31
19
|
return page;
|
|
32
20
|
}
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
const membersService = require('../../services/members');
|
|
3
|
-
|
|
4
|
-
const tpl = require('@tryghost/tpl');
|
|
5
|
-
|
|
6
|
-
const allowedIncludes = ['monthly_price', 'yearly_price', 'benefits'];
|
|
7
|
-
|
|
8
|
-
const messages = {
|
|
9
|
-
productNotFound: 'Tier not found.'
|
|
10
|
-
};
|
|
1
|
+
const tiersService = require('../../services/tiers');
|
|
11
2
|
|
|
12
3
|
module.exports = {
|
|
13
4
|
docName: 'tiers',
|
|
@@ -16,7 +7,6 @@ module.exports = {
|
|
|
16
7
|
options: [
|
|
17
8
|
'limit',
|
|
18
9
|
'fields',
|
|
19
|
-
'include',
|
|
20
10
|
'filter',
|
|
21
11
|
'order',
|
|
22
12
|
'debug',
|
|
@@ -25,48 +15,21 @@ module.exports = {
|
|
|
25
15
|
permissions: {
|
|
26
16
|
docName: 'products'
|
|
27
17
|
},
|
|
28
|
-
validation: {
|
|
29
|
-
options: {
|
|
30
|
-
include: {
|
|
31
|
-
values: allowedIncludes
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
18
|
async query(frame) {
|
|
36
|
-
const page = await
|
|
37
|
-
|
|
19
|
+
const page = await tiersService.api.browse(frame.options);
|
|
38
20
|
return page;
|
|
39
21
|
}
|
|
40
22
|
},
|
|
41
23
|
|
|
42
24
|
read: {
|
|
43
|
-
options: [
|
|
44
|
-
'include'
|
|
45
|
-
],
|
|
46
|
-
headers: {},
|
|
47
25
|
data: [
|
|
48
26
|
'id'
|
|
49
27
|
],
|
|
50
|
-
validation: {
|
|
51
|
-
options: {
|
|
52
|
-
include: {
|
|
53
|
-
values: allowedIncludes
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
28
|
permissions: {
|
|
58
29
|
docName: 'products'
|
|
59
30
|
},
|
|
60
31
|
async query(frame) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (!model) {
|
|
64
|
-
throw new errors.NotFoundError({
|
|
65
|
-
message: tpl(messages.productNotFound)
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return model;
|
|
32
|
+
return await tiersService.api.read(frame.data.id);
|
|
70
33
|
}
|
|
71
34
|
},
|
|
72
35
|
|
|
@@ -84,11 +47,7 @@ module.exports = {
|
|
|
84
47
|
docName: 'products'
|
|
85
48
|
},
|
|
86
49
|
async query(frame) {
|
|
87
|
-
|
|
88
|
-
frame.data,
|
|
89
|
-
frame.options
|
|
90
|
-
);
|
|
91
|
-
return model;
|
|
50
|
+
return await tiersService.api.add(frame.data);
|
|
92
51
|
}
|
|
93
52
|
},
|
|
94
53
|
|
|
@@ -111,12 +70,7 @@ module.exports = {
|
|
|
111
70
|
docName: 'products'
|
|
112
71
|
},
|
|
113
72
|
async query(frame) {
|
|
114
|
-
|
|
115
|
-
frame.data,
|
|
116
|
-
frame.options
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
return model;
|
|
73
|
+
return await tiersService.api.edit(frame.options.id, frame.data);
|
|
120
74
|
}
|
|
121
75
|
}
|
|
122
76
|
};
|
|
@@ -16,7 +16,26 @@ function removeSourceFormats(frame) {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Map names of relations to the internal names
|
|
21
|
+
*/
|
|
22
|
+
function mapWithRelated(frame) {
|
|
23
|
+
if (frame.options.withRelated) {
|
|
24
|
+
// Map sentiment to count.sentiment
|
|
25
|
+
if (labs.isSet('audienceFeedback')) {
|
|
26
|
+
frame.options.withRelated = frame.options.withRelated.map((relation) => {
|
|
27
|
+
return relation === 'sentiment' ? 'count.sentiment' : relation;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
19
34
|
function defaultRelations(frame) {
|
|
35
|
+
// Apply same mapping as content API
|
|
36
|
+
mapWithRelated(frame);
|
|
37
|
+
|
|
38
|
+
// Addditional defaults for admin API
|
|
20
39
|
if (frame.options.withRelated) {
|
|
21
40
|
return;
|
|
22
41
|
}
|
|
@@ -26,7 +45,7 @@ function defaultRelations(frame) {
|
|
|
26
45
|
}
|
|
27
46
|
|
|
28
47
|
if (labs.isSet('audienceFeedback')) {
|
|
29
|
-
frame.options.withRelated = ['tags', 'authors', 'authors.roles', 'email', 'tiers', 'newsletter', 'count.
|
|
48
|
+
frame.options.withRelated = ['tags', 'authors', 'authors.roles', 'email', 'tiers', 'newsletter', 'count.conversions', 'count.clicks', 'count.sentiment', 'count.positive_feedback', 'count.negative_feedback'];
|
|
30
49
|
} else {
|
|
31
50
|
frame.options.withRelated = ['tags', 'authors', 'authors.roles', 'email', 'tiers', 'newsletter', 'count.signups', 'count.paid_conversions', 'count.clicks'];
|
|
32
51
|
}
|
|
@@ -111,6 +130,7 @@ module.exports = {
|
|
|
111
130
|
|
|
112
131
|
setDefaultOrder(frame);
|
|
113
132
|
forceVisibilityColumn(frame);
|
|
133
|
+
mapWithRelated(frame);
|
|
114
134
|
}
|
|
115
135
|
|
|
116
136
|
if (!localUtils.isContentAPI(frame)) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const localUtils = require('../../index');
|
|
2
|
-
const labs = require('../../../../../../shared/labs');
|
|
3
2
|
|
|
4
3
|
const forceActiveFilter = (frame) => {
|
|
5
4
|
if (frame.options.filter) {
|
|
@@ -10,39 +9,31 @@ const forceActiveFilter = (frame) => {
|
|
|
10
9
|
};
|
|
11
10
|
|
|
12
11
|
function convertTierInput(input) {
|
|
13
|
-
const converted = {
|
|
14
|
-
id: input.id,
|
|
15
|
-
name: input.name,
|
|
16
|
-
description: input.description,
|
|
17
|
-
slug: input.slug,
|
|
18
|
-
active: input.active,
|
|
19
|
-
type: input.type,
|
|
20
|
-
welcome_page_url: input.welcome_page_url,
|
|
21
|
-
created_at: input.created_at,
|
|
22
|
-
updated_at: input.updated_at,
|
|
23
|
-
visibility: input.visibility
|
|
24
|
-
};
|
|
12
|
+
const converted = Object.assign({}, input);
|
|
25
13
|
|
|
26
|
-
if (
|
|
27
|
-
converted.
|
|
14
|
+
if (Reflect.has(converted, 'active')) {
|
|
15
|
+
converted.status = converted.active ? 'active' : 'archived';
|
|
16
|
+
delete converted.active;
|
|
28
17
|
}
|
|
29
18
|
|
|
30
|
-
if (
|
|
31
|
-
converted.
|
|
32
|
-
|
|
33
|
-
currency: input.currency
|
|
34
|
-
};
|
|
19
|
+
if (Reflect.has(converted, 'welcome_page_url')) {
|
|
20
|
+
converted.welcomePageURL = converted.welcome_page_url;
|
|
21
|
+
delete converted.welcome_page_url;
|
|
35
22
|
}
|
|
36
23
|
|
|
37
|
-
if (
|
|
38
|
-
converted.
|
|
39
|
-
|
|
40
|
-
currency: input.currency
|
|
41
|
-
};
|
|
24
|
+
if (Reflect.has(converted, 'trial_days')) {
|
|
25
|
+
converted.trialDays = converted.trial_days;
|
|
26
|
+
delete converted.trial_days;
|
|
42
27
|
}
|
|
43
28
|
|
|
44
|
-
if (
|
|
45
|
-
converted.
|
|
29
|
+
if (Reflect.has(converted, 'monthly_price')) {
|
|
30
|
+
converted.monthlyPrice = converted.monthly_price;
|
|
31
|
+
delete converted.monthly_price;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (Reflect.has(converted, 'yearly_price')) {
|
|
35
|
+
converted.yearlyPrice = converted.yearly_price;
|
|
36
|
+
delete converted.yearly_price;
|
|
46
37
|
}
|
|
47
38
|
|
|
48
39
|
return converted;
|
|
@@ -2,6 +2,21 @@ const mapComment = require('./comments');
|
|
|
2
2
|
const url = require('../utils/url');
|
|
3
3
|
const _ = require('lodash');
|
|
4
4
|
|
|
5
|
+
const memberFields = [
|
|
6
|
+
'id',
|
|
7
|
+
'uuid',
|
|
8
|
+
'name',
|
|
9
|
+
'email',
|
|
10
|
+
'avatar_image'
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
const postFields = [
|
|
14
|
+
'id',
|
|
15
|
+
'uuid',
|
|
16
|
+
'title',
|
|
17
|
+
'url'
|
|
18
|
+
];
|
|
19
|
+
|
|
5
20
|
const commentEventMapper = (json, frame) => {
|
|
6
21
|
return {
|
|
7
22
|
...json,
|
|
@@ -10,26 +25,11 @@ const commentEventMapper = (json, frame) => {
|
|
|
10
25
|
};
|
|
11
26
|
|
|
12
27
|
const clickEventMapper = (json, frame) => {
|
|
13
|
-
const memberFields = [
|
|
14
|
-
'id',
|
|
15
|
-
'uuid',
|
|
16
|
-
'name',
|
|
17
|
-
'email',
|
|
18
|
-
'avatar_image'
|
|
19
|
-
];
|
|
20
|
-
|
|
21
28
|
const linkFields = [
|
|
22
29
|
'from',
|
|
23
30
|
'to'
|
|
24
31
|
];
|
|
25
32
|
|
|
26
|
-
const postFields = [
|
|
27
|
-
'id',
|
|
28
|
-
'uuid',
|
|
29
|
-
'title',
|
|
30
|
-
'url'
|
|
31
|
-
];
|
|
32
|
-
|
|
33
33
|
const data = json.data;
|
|
34
34
|
const response = {};
|
|
35
35
|
|
|
@@ -53,6 +53,67 @@ const clickEventMapper = (json, frame) => {
|
|
|
53
53
|
response.created_at = data.created_at;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
if (data.id) {
|
|
57
|
+
response.id = data.id;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
...json,
|
|
62
|
+
data: response
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const aggregatedClickEventMapper = (json) => {
|
|
67
|
+
const data = json.data;
|
|
68
|
+
const response = {};
|
|
69
|
+
|
|
70
|
+
if (data.member) {
|
|
71
|
+
response.member = _.pick(data.member, memberFields);
|
|
72
|
+
} else {
|
|
73
|
+
response.member = null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (data.created_at) {
|
|
77
|
+
response.created_at = data.created_at;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (data.id) {
|
|
81
|
+
response.id = data.id;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
response.count = {
|
|
85
|
+
clicks: data.count?.clicks ?? 0
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
...json,
|
|
90
|
+
data: response
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const feedbackEventMapper = (json, frame) => {
|
|
95
|
+
const feedbackFields = [
|
|
96
|
+
'id',
|
|
97
|
+
'score',
|
|
98
|
+
'created_at'
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
const data = json.data;
|
|
102
|
+
const response = _.pick(data, feedbackFields);
|
|
103
|
+
|
|
104
|
+
if (data.post) {
|
|
105
|
+
url.forPost(data.post.id, data.post, frame);
|
|
106
|
+
response.post = _.pick(data.post, postFields);
|
|
107
|
+
} else {
|
|
108
|
+
response.post = null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (data.member) {
|
|
112
|
+
response.member = _.pick(data.member, memberFields);
|
|
113
|
+
} else {
|
|
114
|
+
response.member = null;
|
|
115
|
+
}
|
|
116
|
+
|
|
56
117
|
return {
|
|
57
118
|
...json,
|
|
58
119
|
data: response
|
|
@@ -82,9 +143,22 @@ const activityFeedMapper = (event, frame) => {
|
|
|
82
143
|
if (event.type === 'click_event') {
|
|
83
144
|
return clickEventMapper(event, frame);
|
|
84
145
|
}
|
|
146
|
+
if (event.type === 'aggregated_click_event') {
|
|
147
|
+
return aggregatedClickEventMapper(event, frame);
|
|
148
|
+
}
|
|
149
|
+
if (event.type === 'feedback_event') {
|
|
150
|
+
return feedbackEventMapper(event, frame);
|
|
151
|
+
}
|
|
85
152
|
if (event.data?.attribution) {
|
|
86
153
|
event.data.attribution = serializeAttribution(event.data.attribution);
|
|
87
154
|
}
|
|
155
|
+
// TODO: add dedicated mappers for other event types
|
|
156
|
+
if (event.data?.batch_id) {
|
|
157
|
+
delete event.data.batch_id;
|
|
158
|
+
}
|
|
159
|
+
if (event.data?.subscriptionCreatedEvent) {
|
|
160
|
+
delete event.data.subscriptionCreatedEvent;
|
|
161
|
+
}
|
|
88
162
|
return event;
|
|
89
163
|
};
|
|
90
164
|
|
|
@@ -111,21 +111,35 @@ module.exports = async (model, frame, options = {}) => {
|
|
|
111
111
|
|
|
112
112
|
if (jsonModel.email && jsonModel.count) {
|
|
113
113
|
jsonModel.email.opened_count = Math.min(
|
|
114
|
-
|
|
115
|
-
jsonModel.email.opened_count || 0,
|
|
116
|
-
jsonModel.count.clicks || 0
|
|
117
|
-
),
|
|
114
|
+
jsonModel.email.opened_count || 0,
|
|
118
115
|
jsonModel.email.email_count
|
|
119
116
|
);
|
|
120
117
|
}
|
|
121
118
|
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
// The sentiment has been loaded as a count relation in count.sentiment. But externally in the API we use just 'sentiment' instead of count.sentiment
|
|
120
|
+
// This part moves count.sentiment to just 'sentiment' when it has been loaded
|
|
121
|
+
if (frame.options.withRelated && frame.options.withRelated.includes('count.sentiment')) {
|
|
122
|
+
if (!jsonModel.count) {
|
|
123
|
+
jsonModel.sentiment = 0;
|
|
124
|
+
} else {
|
|
125
|
+
jsonModel.sentiment = jsonModel.count.sentiment ?? 0;
|
|
126
|
+
|
|
127
|
+
// Delete it from the original location
|
|
128
|
+
delete jsonModel.count.sentiment;
|
|
129
|
+
|
|
130
|
+
if (Object.keys(jsonModel.count).length === 0) {
|
|
131
|
+
delete jsonModel.count;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
124
134
|
}
|
|
125
135
|
|
|
126
136
|
if (jsonModel.count && !jsonModel.count.positive_feedback) {
|
|
127
137
|
jsonModel.count.positive_feedback = 0;
|
|
128
138
|
}
|
|
129
139
|
|
|
140
|
+
if (jsonModel.count && !jsonModel.count.negative_feedback) {
|
|
141
|
+
jsonModel.count.negative_feedback = 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
130
144
|
return jsonModel;
|
|
131
145
|
};
|
|
@@ -22,8 +22,8 @@ module.exports = (snippet, frame) => {
|
|
|
22
22
|
/**
|
|
23
23
|
* @typedef {Object} SerializedSnippet
|
|
24
24
|
* @prop {string} id
|
|
25
|
-
* @prop {string
|
|
26
|
-
* @prop {string
|
|
25
|
+
* @prop {string} [name]
|
|
26
|
+
* @prop {string} [mobiledoc]
|
|
27
27
|
* @prop {string} created_at
|
|
28
28
|
* @prop {string} updated_at
|
|
29
29
|
* @prop {string} created_by
|