ghost 5.130.0 → 6.0.0-alpha.1

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.
Files changed (274) hide show
  1. package/components/tryghost-i18n-6.0.0-alpha.1.tgz +0 -0
  2. package/core/boot.js +0 -2
  3. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-bO8i1M7l.mjs → CodeEditorView-CA2VVtOE.mjs} +2 -2
  4. package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +1 -1
  5. package/core/built/admin/assets/admin-x-settings/{index-BeD9DTp3.mjs → index-Dl3F40x5.mjs} +2 -2
  6. package/core/built/admin/assets/admin-x-settings/{index-DIak5kz8.mjs → index-KA2tjCkS.mjs} +5 -5
  7. package/core/built/admin/assets/admin-x-settings/{modals-DLPpqlUq.mjs → modals-B0zezufO.mjs} +8130 -8122
  8. package/core/built/admin/assets/{chunk.524.2443bfd380e6da0cbabd.js → chunk.524.996c1c4d269fa6a50e90.js} +7 -7
  9. package/core/built/admin/assets/{chunk.582.434476dff5ddc79ed054.js → chunk.582.75cf44e5d1b925adf16d.js} +9 -9
  10. package/core/built/admin/assets/{chunk.728.214803966b81ffdb1acd.js → chunk.728.985c45ad584b4b91ca60.js} +124 -124
  11. package/core/built/admin/assets/{ghost-5d9c65b5c4ef960a664cd664b2616dea.js → ghost-5a5b2112df68dfaf6813ce38cad16847.js} +28 -29
  12. package/core/built/admin/assets/posts/posts.js +1 -1
  13. package/core/built/admin/assets/stats/stats.js +1 -1
  14. package/core/built/admin/index.html +4 -4
  15. package/core/frontend/helpers/get.js +4 -2
  16. package/core/frontend/helpers/ghost_head.js +71 -77
  17. package/core/frontend/meta/canonical-url.js +1 -7
  18. package/core/frontend/meta/context-object.js +1 -1
  19. package/core/frontend/meta/get-meta.js +1 -4
  20. package/core/frontend/meta/og-image.js +1 -1
  21. package/core/frontend/meta/og-type.js +0 -2
  22. package/core/frontend/meta/schema.js +1 -1
  23. package/core/frontend/meta/twitter-image.js +1 -1
  24. package/core/frontend/meta/url.js +1 -12
  25. package/core/frontend/services/rendering/context.js +0 -8
  26. package/core/server/api/endpoints/index.js +0 -4
  27. package/core/server/api/endpoints/session.js +0 -9
  28. package/core/server/api/endpoints/utils/serializers/input/settings.js +0 -2
  29. package/core/server/api/endpoints/utils/serializers/input/utils/settings-filter-type-group-mapper.js +0 -1
  30. package/core/server/api/endpoints/utils/serializers/input/utils/settings-key-group-mapper.js +0 -1
  31. package/core/server/api/endpoints/utils/serializers/input/utils/settings-key-type-mapper.js +0 -1
  32. package/core/server/api/endpoints/utils/serializers/output/all.js +1 -1
  33. package/core/server/api/endpoints/utils/serializers/output/index.js +0 -4
  34. package/core/server/api/endpoints/utils/serializers/output/mappers/snippets.js +1 -5
  35. package/core/server/api/endpoints/utils/serializers/output/members.js +0 -2
  36. package/core/server/api/endpoints/utils/validators/input/index.js +0 -4
  37. package/core/server/data/importer/importers/data/Base.js +1 -3
  38. package/core/server/data/importer/importers/data/SettingsImporter.js +1 -3
  39. package/core/server/data/migrations/utils/index.js +1 -4
  40. package/core/server/data/migrations/utils/permissions.js +14 -6
  41. package/core/server/data/migrations/utils/settings.js +39 -22
  42. package/core/server/data/migrations/versions/4.47/2022-05-03-15-30-final-v4.js +2 -0
  43. package/core/server/data/migrations/versions/4.47/2022-05-04-10-03-no-op.js +6 -0
  44. package/core/server/data/migrations/versions/5.100/2024-11-06-04-45-15-add-activitypub-integration.js +4 -2
  45. package/core/server/data/migrations/versions/5.113/2025-03-07-12-24-00-add-super-editor.js +4 -2
  46. package/core/server/data/migrations/versions/5.3/2022-07-06-07-58-add-ghost-explore-integration-role.js +4 -2
  47. package/core/server/data/migrations/versions/5.3/2022-07-06-09-17-add-ghost-explore-integration.js +4 -2
  48. package/core/server/data/migrations/versions/5.3/2022-07-06-09-26-add-ghost-explore-integration-api-key.js +4 -2
  49. package/core/server/data/migrations/versions/5.40/2023-03-21-18-42-add-self-serve-integration-role.js +4 -2
  50. package/core/server/data/migrations/versions/5.40/2023-03-21-18-52-add-self-serve-integration.js +4 -2
  51. package/core/server/data/migrations/versions/5.40/2023-03-21-19-02-add-self-serve-integration-api-key.js +4 -2
  52. package/core/server/data/migrations/versions/5.63/2023-09-13-13-03-10-add-ghost-core-content-integration.js +4 -2
  53. package/core/server/data/migrations/versions/5.63/2023-09-13-13-34-11-add-ghost-core-content-integration-key.js +4 -2
  54. package/core/server/data/migrations/versions/6.0/2025-06-20-01-41-54-remove-updated-by-column.js +46 -0
  55. package/core/server/data/migrations/versions/6.0/2025-06-20-13-41-55-remove-created-by-column.js +47 -0
  56. package/core/server/data/migrations/versions/6.0/2025-06-23-09-49-25-add-missing-member-uuids.js +22 -0
  57. package/core/server/data/migrations/versions/6.0/2025-06-23-10-03-26-members-nullable-uuid.js +5 -0
  58. package/core/server/data/migrations/versions/6.0/2025-06-24-09-19-42-use-object-id-for-hardcoded-user-id.js +95 -0
  59. package/core/server/data/migrations/versions/6.0/2025-06-25-15-03-29-remove-amp-from-settings.js +6 -0
  60. package/core/server/data/migrations/versions/6.0/2025-06-30-13-59-10-remove-mail-events-table.js +3 -0
  61. package/core/server/data/migrations/versions/6.0/2025-06-30-14-00-00-update-feature-image-alt-length.js +25 -0
  62. package/core/server/data/schema/default-settings/default-settings.json +0 -13
  63. package/core/server/data/schema/fixtures/FixtureManager.js +128 -5
  64. package/core/server/data/schema/fixtures/fixtures.json +4 -6
  65. package/core/server/data/schema/fixtures/index.js +3 -1
  66. package/core/server/data/schema/schema.js +20 -65
  67. package/core/server/data/seeders/DataGenerator.js +11 -2
  68. package/core/server/data/seeders/importers/EmailsImporter.js +1 -3
  69. package/core/server/data/seeders/importers/LabelsImporter.js +1 -3
  70. package/core/server/data/seeders/importers/MembersImporter.js +0 -1
  71. package/core/server/data/seeders/importers/MembersStripeCustomersImporter.js +1 -2
  72. package/core/server/data/seeders/importers/MembersStripeCustomersSubscriptionsImporter.js +0 -1
  73. package/core/server/data/seeders/importers/PostsImporter.js +0 -1
  74. package/core/server/data/seeders/importers/RolesUsersImporter.js +6 -1
  75. package/core/server/data/seeders/importers/TagsImporter.js +1 -2
  76. package/core/server/data/seeders/importers/UsersImporter.js +1 -2
  77. package/core/server/data/tinybird/README.md +9 -14
  78. package/core/server/models/base/bookshelf.js +8 -1
  79. package/core/server/models/base/plugins/events.js +0 -28
  80. package/core/server/models/base/plugins/user-type.js +10 -36
  81. package/core/server/models/post.js +25 -10
  82. package/core/server/models/relations/authors.js +2 -2
  83. package/core/server/models/settings.js +1 -14
  84. package/core/server/models/user.js +33 -6
  85. package/core/server/services/activitypub/ActivityPubService.js +1 -2
  86. package/core/server/services/activitypub/ActivityPubService.ts +1 -2
  87. package/core/server/services/link-redirection/README.md +1 -1
  88. package/core/server/services/mentions/MentionSendingService.js +1 -1
  89. package/core/server/services/update-check/UpdateCheckService.js +18 -2
  90. package/core/server/services/url/config.js +0 -2
  91. package/core/server/web/api/app.js +4 -0
  92. package/core/server/web/api/endpoints/admin/middleware.js +8 -9
  93. package/core/server/web/api/endpoints/admin/routes.js +0 -2
  94. package/core/server/web/comments/routes.js +3 -0
  95. package/core/server/web/shared/middleware/index.js +4 -0
  96. package/core/server/web/shared/middleware/max-limit-cap.js +27 -0
  97. package/core/server/web/shared/middleware/pretty-urls.js +3 -1
  98. package/core/server/web/shared/middleware/redirect-amp-urls.js +36 -0
  99. package/core/shared/config/defaults.json +2 -0
  100. package/core/shared/config/overrides.json +1 -4
  101. package/core/shared/labs.js +5 -6
  102. package/core/shared/max-limit-cap.js +61 -0
  103. package/package.json +4 -5
  104. package/tsconfig.tsbuildinfo +1 -1
  105. package/yarn.lock +18 -107
  106. package/components/tryghost-i18n-5.130.0.tgz +0 -0
  107. package/core/built/admin/assets/img/amp-d7b72aae3315fda95921fb575dfca100.svg +0 -4
  108. package/core/frontend/apps/amp/index.js +0 -30
  109. package/core/frontend/apps/amp/lib/helpers/amp_analytics.js +0 -32
  110. package/core/frontend/apps/amp/lib/helpers/amp_components.js +0 -48
  111. package/core/frontend/apps/amp/lib/helpers/amp_content.js +0 -214
  112. package/core/frontend/apps/amp/lib/helpers/amp_style.js +0 -8
  113. package/core/frontend/apps/amp/lib/router.js +0 -95
  114. package/core/frontend/apps/amp/lib/views/amp.hbs +0 -1046
  115. package/core/frontend/meta/amp-url.js +0 -14
  116. package/core/server/api/endpoints/mail-events.js +0 -17
  117. package/core/server/api/endpoints/utils/serializers/output/mail-events.js +0 -9
  118. package/core/server/api/endpoints/utils/validators/input/mail-events.js +0 -7
  119. package/core/server/data/migrations/utils/constants.js +0 -3
  120. package/core/server/data/migrations/versions/4.0/01-update-mobiledoc.js +0 -61
  121. package/core/server/data/migrations/versions/4.0/02-add-status-column-to-members.js +0 -11
  122. package/core/server/data/migrations/versions/4.0/03-populate-status-column-for-members.js +0 -81
  123. package/core/server/data/migrations/versions/4.0/04-drop-apps-related-tables.js +0 -10
  124. package/core/server/data/migrations/versions/4.0/05-add-members-subscribe-events-table.js +0 -9
  125. package/core/server/data/migrations/versions/4.0/06-populate-members-subscribe-events-table.js +0 -53
  126. package/core/server/data/migrations/versions/4.0/07-alter-unique-constraint-for-posts-slug.js +0 -7
  127. package/core/server/data/migrations/versions/4.0/08-add-members-login-events-table.js +0 -7
  128. package/core/server/data/migrations/versions/4.0/09-add-members-email-change-events-table.js +0 -9
  129. package/core/server/data/migrations/versions/4.0/10-add-members-status-events-table.js +0 -9
  130. package/core/server/data/migrations/versions/4.0/11-add-members-paid-subscription-events-table.js +0 -12
  131. package/core/server/data/migrations/versions/4.0/12-delete-apps-related-settings-keys.js +0 -16
  132. package/core/server/data/migrations/versions/4.0/13-add-members-payment-events-table.js +0 -10
  133. package/core/server/data/migrations/versions/4.0/14-remove-orphaned-stripe-records.js +0 -36
  134. package/core/server/data/migrations/versions/4.0/15-add-frontmatter-column-to-meta.js +0 -7
  135. package/core/server/data/migrations/versions/4.0/16-refactor-slack-setting.js +0 -96
  136. package/core/server/data/migrations/versions/4.0/17-populate-members-status-events-table.js +0 -41
  137. package/core/server/data/migrations/versions/4.0/18-transform-urls-absolute-to-transform-ready.js +0 -201
  138. package/core/server/data/migrations/versions/4.0/19-remove-labs-members-setting.js +0 -10
  139. package/core/server/data/migrations/versions/4.0/20-refactor-unsplash-setting.js +0 -41
  140. package/core/server/data/migrations/versions/4.0/21-sanitize-email-batches-provider-id.js +0 -8
  141. package/core/server/data/migrations/versions/4.0/22-solve-orphaned-webhooks.js +0 -87
  142. package/core/server/data/migrations/versions/4.0/23-regenerate-posts-html.js +0 -66
  143. package/core/server/data/migrations/versions/4.0/24-add-missing-email-permissions.js +0 -36
  144. package/core/server/data/migrations/versions/4.0/25-populate-members-paid-subscription-events-table.js +0 -129
  145. package/core/server/data/migrations/versions/4.0/26-add-cascade-on-delete.js +0 -76
  146. package/core/server/data/migrations/versions/4.0/27-add-primary-key-brute-migrations-lock.js +0 -9
  147. package/core/server/data/migrations/versions/4.0/28-add-webhook-intergrations-foreign-key.js +0 -16
  148. package/core/server/data/migrations/versions/4.0/29-fix-foreign-key-for-members-stripe-customers-subscriptions.js +0 -35
  149. package/core/server/data/migrations/versions/4.0/30-set-default-accent-color.js +0 -21
  150. package/core/server/data/migrations/versions/4.1/01-fix-backup-content-permission-typo.js +0 -15
  151. package/core/server/data/migrations/versions/4.1/02-add-unique-constraint-for-member-stripe-tables.js +0 -21
  152. package/core/server/data/migrations/versions/4.11/01-add-oauth-user-data.js +0 -12
  153. package/core/server/data/migrations/versions/4.11/02-add-email-verification-required-setting.js +0 -43
  154. package/core/server/data/migrations/versions/4.12/01-add-email-only-column-to-posts-meta-table.js +0 -7
  155. package/core/server/data/migrations/versions/4.12/02-fix-member-statuses.js +0 -39
  156. package/core/server/data/migrations/versions/4.13/01-add-members-stripe-connect-auth-permission-to-administrators.js +0 -6
  157. package/core/server/data/migrations/versions/4.13/02-add-members-products-events-table.js +0 -33
  158. package/core/server/data/migrations/versions/4.14/01-fix-comped-member-statuses.js +0 -73
  159. package/core/server/data/migrations/versions/4.14/02-fix-free-members-status-events.js +0 -61
  160. package/core/server/data/migrations/versions/4.15/01-add-temp-members-analytic-events-table.js +0 -12
  161. package/core/server/data/migrations/versions/4.16/01-add-custom-theme-settings-table.js +0 -9
  162. package/core/server/data/migrations/versions/4.17/01-add-custom-theme-settings-permissions.js +0 -21
  163. package/core/server/data/migrations/versions/4.17/02-add-offers-table.js +0 -19
  164. package/core/server/data/migrations/versions/4.17/03-add-offers-permissions.js +0 -35
  165. package/core/server/data/migrations/versions/4.19/01-add-active-column-to-offers.js +0 -7
  166. package/core/server/data/migrations/versions/4.19/02-add-offer-redemptions-table.js +0 -8
  167. package/core/server/data/migrations/versions/4.2/01-fix-incorrect-mrr-delta-events.js +0 -13
  168. package/core/server/data/migrations/versions/4.20/01-remove-offer-redemptions-table.js +0 -19
  169. package/core/server/data/migrations/versions/4.20/02-remove-offers-table.js +0 -30
  170. package/core/server/data/migrations/versions/4.20/03-add-offers-table.js +0 -21
  171. package/core/server/data/migrations/versions/4.20/04-add-offer-redemptions-table.js +0 -9
  172. package/core/server/data/migrations/versions/4.20/05-remove-not-null-constraint-from-portal-title.js +0 -44
  173. package/core/server/data/migrations/versions/4.22/01-add-is-launch-complete-setting.js +0 -8
  174. package/core/server/data/migrations/versions/4.22/02-update-launch-complete-setting-from-user-data.js +0 -39
  175. package/core/server/data/migrations/versions/4.23/01-truncate-offer-names.js +0 -59
  176. package/core/server/data/migrations/versions/4.3/01-add-products-table.js +0 -9
  177. package/core/server/data/migrations/versions/4.3/02-add-members-products-table.js +0 -8
  178. package/core/server/data/migrations/versions/4.3/03-add-default-product.js +0 -39
  179. package/core/server/data/migrations/versions/4.3/04-attach-members-to-product.js +0 -50
  180. package/core/server/data/migrations/versions/4.3/05-add-stripe-products-table.js +0 -9
  181. package/core/server/data/migrations/versions/4.3/06-add-stripe-prices-table.js +0 -15
  182. package/core/server/data/migrations/versions/4.3/07-add-products-permissions.js +0 -29
  183. package/core/server/data/migrations/versions/4.3/08-migrate-members-signup-setting.js +0 -109
  184. package/core/server/data/migrations/versions/4.3/09-add-price-id-column-to-subscriptions-table.js +0 -10
  185. package/core/server/data/migrations/versions/4.3/10-populate-stripe-price-id-in-subscriptions.js +0 -20
  186. package/core/server/data/migrations/versions/4.33/2022-01-14-11-50-add-type-column-to-products.js +0 -12
  187. package/core/server/data/migrations/versions/4.33/2022-01-14-11-51-add-default-free-tier.js +0 -40
  188. package/core/server/data/migrations/versions/4.33/2022-01-18-09-07-remove-duplicate-offer-redemptions.js +0 -46
  189. package/core/server/data/migrations/versions/4.33/2022-01-19-10-43-add-active-column-to-products-table.js +0 -7
  190. package/core/server/data/migrations/versions/4.34/2022-01-25-13-53-add-welcome-page-url-column-to-products.js +0 -7
  191. package/core/server/data/migrations/versions/4.35/2022-01-20-05-55-add-post-products-table.js +0 -8
  192. package/core/server/data/migrations/versions/4.35/2022-01-30-15-17-set-welcome-page-url-from-settings.js +0 -45
  193. package/core/server/data/migrations/versions/4.35/2022-02-01-11-48-update-email-recipient-filter-column-type.js +0 -19
  194. package/core/server/data/migrations/versions/4.35/2022-02-01-12-03-update-recipient-filter-column-type.js +0 -19
  195. package/core/server/data/migrations/versions/4.35/2022-02-02-10-38-add-default-content-visibility-tiers-setting.js +0 -8
  196. package/core/server/data/migrations/versions/4.35/2022-02-02-13-10-transform-specific-tiers-default-content-visibility.js +0 -147
  197. package/core/server/data/migrations/versions/4.35/2022-02-04-04-34-populate-empty-portal-products.js +0 -60
  198. package/core/server/data/migrations/versions/4.36/2022-02-07-14-34-add-last-seen-at-column-to-members.js +0 -10
  199. package/core/server/data/migrations/versions/4.37/2022-02-21-09-53-backfill-members-last-seen-at-column.js +0 -32
  200. package/core/server/data/migrations/versions/4.38/2022-03-01-08-46-add-visibility-to-tiers.js +0 -11
  201. package/core/server/data/migrations/versions/4.38/2022-03-03-16-12-add-visibility-to-tiers.js +0 -8
  202. package/core/server/data/migrations/versions/4.38/2022-03-03-16-17-drop-tiers-visible-column.js +0 -7
  203. package/core/server/data/migrations/versions/4.39/2022-03-07-10-57-update-free-products-visibility-column.js +0 -66
  204. package/core/server/data/migrations/versions/4.39/2022-03-07-10-57-update-products-visibility-column.js +0 -36
  205. package/core/server/data/migrations/versions/4.4/01-restore-free-members-signup-setting-from-backup.js +0 -99
  206. package/core/server/data/migrations/versions/4.4/02-migrate-members-signup-access.js +0 -126
  207. package/core/server/data/migrations/versions/4.40/2022-03-07-14-37-add-members-cancel-events-table.js +0 -8
  208. package/core/server/data/migrations/versions/4.40/2022-03-15-06-40-add-offers-admin-integration-permission-roles.js +0 -23
  209. package/core/server/data/migrations/versions/4.40/2022-03-15-06-40-add-tiers-admin-integration-permission-roles.js +0 -20
  210. package/core/server/data/migrations/versions/4.42/2022-03-21-17-17-add.js +0 -25
  211. package/core/server/data/migrations/versions/4.42/2022-03-30-15-44-add-newsletter-permissions.js +0 -28
  212. package/core/server/data/migrations/versions/4.43/2022-03-28-19-26-recreate-newsletter-table.js +0 -29
  213. package/core/server/data/migrations/versions/4.43/2022-03-29-14-45-add-members-newsletters-table.js +0 -7
  214. package/core/server/data/migrations/versions/4.43/2022-04-01-10-13-add-post-newsletter-relation.js +0 -108
  215. package/core/server/data/migrations/versions/4.43/2022-04-06-09-47-add-type-column-to-paid-subscription-events.js +0 -7
  216. package/core/server/data/migrations/versions/4.43/2022-04-06-14-56-add-email-newsletter-relation.js +0 -8
  217. package/core/server/data/migrations/versions/4.43/2022-04-08-10-45-add-subscription-id-to-mrr-events.js +0 -7
  218. package/core/server/data/migrations/versions/4.44/2022-04-06-15-22-populate-type-column-for-paid-subscription-events.js +0 -21
  219. package/core/server/data/migrations/versions/4.44/2022-04-08-11-54-add-cancelled-events.js +0 -51
  220. package/core/server/data/migrations/versions/4.44/2022-04-11-08-24-add-newsletter-permissions.js +0 -33
  221. package/core/server/data/migrations/versions/4.44/2022-04-11-10-54-add-mrr-to-subscriptions.js +0 -8
  222. package/core/server/data/migrations/versions/4.44/2022-04-12-07-33-fill-mrr.js +0 -29
  223. package/core/server/data/migrations/versions/4.44/2022-04-13-12-00-remove-newsletter-sender-name-not-null-constraint.js +0 -33
  224. package/core/server/data/migrations/versions/4.44/2022-04-15-07-53-add-offer-id-to-subscriptions.js +0 -9
  225. package/core/server/data/migrations/versions/4.45/2022-04-19-12-23-backfill-subscriptions-offers.js +0 -60
  226. package/core/server/data/migrations/versions/4.45/2022-04-20-11-25-add-newsletter-read-permission.js +0 -9
  227. package/core/server/data/migrations/versions/4.45/2022-04-21-02-55-add-notifications-key-entry-to-settings-table.js +0 -8
  228. package/core/server/data/migrations/versions/4.46/2022-04-13-12-00-add-created-at-newsletters.js +0 -6
  229. package/core/server/data/migrations/versions/4.46/2022-04-13-12-01-add-updated-at-newsletters.js +0 -6
  230. package/core/server/data/migrations/versions/4.46/2022-04-13-12-02-fill-created-at-newsletters.js +0 -19
  231. package/core/server/data/migrations/versions/4.46/2022-04-13-12-03-drop-nullable-created-at-newsletters.js +0 -3
  232. package/core/server/data/migrations/versions/4.46/2022-04-13-12-08-newsletters-show-header-name.js +0 -7
  233. package/core/server/data/migrations/versions/4.46/2022-04-13-12-57-add-uuid-column-to-newsletters.js +0 -8
  234. package/core/server/data/migrations/versions/4.46/2022-04-13-12-58-fill-uuid-for-newsletters.js +0 -19
  235. package/core/server/data/migrations/versions/4.46/2022-04-13-12-59-drop-nullable-uuid-newsletters.js +0 -3
  236. package/core/server/data/migrations/versions/4.46/2022-04-13-13-00-add-default-newsletter.js +0 -92
  237. package/core/server/data/migrations/versions/4.46/2022-04-20-08-39-map-subscribers-to-default-newsletter.js +0 -66
  238. package/core/server/data/migrations/versions/4.46/2022-04-22-07-43-add-newsletter-id-to-subscribe-events.js +0 -9
  239. package/core/server/data/migrations/versions/4.46/2022-04-27-07-59-set-newsletter-id-subscribe-events.js +0 -31
  240. package/core/server/data/migrations/versions/4.47/2022-05-03-15-30-update-newsletter-sending-options.js +0 -34
  241. package/core/server/data/migrations/versions/4.47/2022-05-04-10-03-transform-newsletter-header-image.js +0 -26
  242. package/core/server/data/migrations/versions/4.5/01-add-stripe-price-description-column.js +0 -7
  243. package/core/server/data/migrations/versions/4.5/02-add-product-description-column.js +0 -7
  244. package/core/server/data/migrations/versions/4.5/03-give-label-read-permissions-to-editors.js +0 -14
  245. package/core/server/data/migrations/versions/4.5/04-remove-unique-constraint-from-product-name.js +0 -13
  246. package/core/server/data/migrations/versions/4.5/05-rename-default-product-to-site-title.js +0 -38
  247. package/core/server/data/migrations/versions/4.6/01-remove-comped-status.js +0 -47
  248. package/core/server/data/migrations/versions/4.7/01-add-monthly-price-column-to-products.js +0 -7
  249. package/core/server/data/migrations/versions/4.7/02-add-yearly-price-column-to-products.js +0 -7
  250. package/core/server/data/migrations/versions/4.7/03-add-labs-setting.js +0 -42
  251. package/core/server/data/migrations/versions/4.8/01-add-feature-image-alt-column-to-posts-meta.js +0 -7
  252. package/core/server/data/migrations/versions/4.8/02-add-feature-image-caption-column-to-posts-meta.js +0 -7
  253. package/core/server/data/migrations/versions/4.8/03-add-default-product-portal-products.js +0 -69
  254. package/core/server/data/migrations/versions/4.8/04-migrate-show-newsletter-header-setting.js +0 -124
  255. package/core/server/data/migrations/versions/4.9/01-add-reset-all-passwords-permission.js +0 -11
  256. package/core/server/data/migrations/versions/4.9/02-add-benefits-table.js +0 -9
  257. package/core/server/data/migrations/versions/4.9/03-add-products-benefits-table.js +0 -8
  258. package/core/server/data/migrations/versions/4.9/04-add-member-segment-to-email-batches.js +0 -7
  259. package/core/server/data/migrations/versions/4.9/05-fix-missed-mobiledoc-url-transforms.js +0 -87
  260. package/core/server/data/migrations/versions/4.9/06-add-comped-status.js +0 -47
  261. package/core/server/data/migrations/versions/4.9/07-update-comped-members-status-events.js +0 -39
  262. package/core/server/models/mail-event.js +0 -12
  263. package/core/server/services/mail-events/BookshelfMailEventRepository.js +0 -40
  264. package/core/server/services/mail-events/InMemoryMailEventRepository.js +0 -10
  265. package/core/server/services/mail-events/InMemoryMailEventRepository.ts +0 -8
  266. package/core/server/services/mail-events/MailEvent.js +0 -20
  267. package/core/server/services/mail-events/MailEvent.ts +0 -10
  268. package/core/server/services/mail-events/MailEventRepository.js +0 -2
  269. package/core/server/services/mail-events/MailEventRepository.ts +0 -5
  270. package/core/server/services/mail-events/MailEventService.js +0 -124
  271. package/core/server/services/mail-events/MailEventService.ts +0 -169
  272. package/core/server/services/mail-events/index.js +0 -21
  273. package/core/server/services/mail-events/libraries.d.ts +0 -2
  274. /package/core/built/admin/assets/{chunk.728.214803966b81ffdb1acd.js.LICENSE.txt → chunk.728.985c45ad584b4b91ca60.js.LICENSE.txt} +0 -0
@@ -1,7 +1,9 @@
1
1
  const logging = require('@tryghost/logging');
2
- const {createTransactionalMigration, meta} = require('../../utils');
2
+ const {createTransactionalMigration} = require('../../utils');
3
3
  const ObjectID = require('bson-objectid').default;
4
4
 
5
+ const MIGRATION_USER = 1;
6
+
5
7
  module.exports = createTransactionalMigration(
6
8
  async function up(knex) {
7
9
  logging.info('Adding Ghost ActivityPub integration');
@@ -25,7 +27,7 @@ module.exports = createTransactionalMigration(
25
27
  name: 'Ghost ActivityPub',
26
28
  description: 'Internal Integration for ActivityPub',
27
29
  created_at: knex.raw('current_timestamp'),
28
- created_by: meta.MIGRATION_USER
30
+ created_by: MIGRATION_USER
29
31
  })
30
32
  .into('integrations');
31
33
  },
@@ -1,6 +1,8 @@
1
1
  const logging = require('@tryghost/logging');
2
2
  const {default: ObjectID} = require('bson-objectid');
3
- const {createTransactionalMigration, meta} = require('../../utils');
3
+ const {createTransactionalMigration} = require('../../utils');
4
+
5
+ const MIGRATION_USER = 1;
4
6
 
5
7
  module.exports = createTransactionalMigration(
6
8
  async function up(knex) {
@@ -18,7 +20,7 @@ module.exports = createTransactionalMigration(
18
20
  id: (new ObjectID()).toHexString(),
19
21
  name: 'Super Editor',
20
22
  description: 'Editor plus member management',
21
- created_by: meta.MIGRATION_USER,
23
+ created_by: MIGRATION_USER,
22
24
  created_at: knex.raw('current_timestamp')
23
25
  });
24
26
  },
@@ -1,6 +1,8 @@
1
1
  const logging = require('@tryghost/logging');
2
2
  const {default: ObjectID} = require('bson-objectid');
3
- const {createTransactionalMigration, meta} = require('../../utils');
3
+ const {createTransactionalMigration} = require('../../utils');
4
+
5
+ const MIGRATION_USER = 1;
4
6
 
5
7
  module.exports = createTransactionalMigration(
6
8
  async function up(knex) {
@@ -18,7 +20,7 @@ module.exports = createTransactionalMigration(
18
20
  id: (new ObjectID()).toHexString(),
19
21
  name: 'Ghost Explore Integration',
20
22
  description: 'Internal Integration for the Ghost Explore directory',
21
- created_by: meta.MIGRATION_USER,
23
+ created_by: MIGRATION_USER,
22
24
  created_at: knex.raw('current_timestamp')
23
25
  });
24
26
  },
@@ -1,6 +1,8 @@
1
1
  const logging = require('@tryghost/logging');
2
2
  const {default: ObjectID} = require('bson-objectid');
3
- const {createTransactionalMigration, meta} = require('../../utils');
3
+ const {createTransactionalMigration} = require('../../utils');
4
+
5
+ const MIGRATION_USER = 1;
4
6
 
5
7
  module.exports = createTransactionalMigration(
6
8
  async function up(knex) {
@@ -22,7 +24,7 @@ module.exports = createTransactionalMigration(
22
24
  description: 'Internal Integration for the Ghost Explore directory',
23
25
  slug: 'ghost-explore',
24
26
  created_at: knex.raw('current_timestamp'),
25
- created_by: meta.MIGRATION_USER
27
+ created_by: MIGRATION_USER
26
28
  });
27
29
  },
28
30
  async function down(knex) {
@@ -2,7 +2,9 @@ const {InternalServerError} = require('@tryghost/errors');
2
2
  const logging = require('@tryghost/logging');
3
3
  const security = require('@tryghost/security');
4
4
  const {default: ObjectID} = require('bson-objectid');
5
- const {createTransactionalMigration, meta} = require('../../utils');
5
+ const {createTransactionalMigration} = require('../../utils');
6
+
7
+ const MIGRATION_USER = 1;
6
8
 
7
9
  module.exports = createTransactionalMigration(
8
10
  async function up(knex) {
@@ -46,7 +48,7 @@ module.exports = createTransactionalMigration(
46
48
  role_id: role.id,
47
49
  integration_id: integration.id,
48
50
  created_at: knex.raw('current_timestamp'),
49
- created_by: meta.MIGRATION_USER
51
+ created_by: MIGRATION_USER
50
52
  });
51
53
  },
52
54
  async function down(knex) {
@@ -1,6 +1,8 @@
1
1
  const logging = require('@tryghost/logging');
2
2
  const {default: ObjectID} = require('bson-objectid');
3
- const {createTransactionalMigration, meta} = require('../../utils');
3
+ const {createTransactionalMigration} = require('../../utils');
4
+
5
+ const MIGRATION_USER = 1;
4
6
 
5
7
  module.exports = createTransactionalMigration(
6
8
  async function up(knex) {
@@ -18,7 +20,7 @@ module.exports = createTransactionalMigration(
18
20
  id: (new ObjectID()).toHexString(),
19
21
  name: 'Self-Serve Migration Integration',
20
22
  description: 'Core Integration for the Ghost Explore directory',
21
- created_by: meta.MIGRATION_USER,
23
+ created_by: MIGRATION_USER,
22
24
  created_at: knex.raw('current_timestamp')
23
25
  });
24
26
  },
@@ -1,6 +1,8 @@
1
1
  const logging = require('@tryghost/logging');
2
2
  const {default: ObjectID} = require('bson-objectid');
3
- const {createTransactionalMigration, meta} = require('../../utils');
3
+ const {createTransactionalMigration} = require('../../utils');
4
+
5
+ const MIGRATION_USER = 1;
4
6
 
5
7
  module.exports = createTransactionalMigration(
6
8
  async function up(knex) {
@@ -22,7 +24,7 @@ module.exports = createTransactionalMigration(
22
24
  description: 'Core Integration for the Self-Serve migration tool',
23
25
  slug: 'self-serve-migration',
24
26
  created_at: knex.raw('current_timestamp'),
25
- created_by: meta.MIGRATION_USER
27
+ created_by: MIGRATION_USER
26
28
  });
27
29
  },
28
30
  async function down(knex) {
@@ -2,7 +2,9 @@ const {InternalServerError} = require('@tryghost/errors');
2
2
  const logging = require('@tryghost/logging');
3
3
  const security = require('@tryghost/security');
4
4
  const {default: ObjectID} = require('bson-objectid');
5
- const {createTransactionalMigration, meta} = require('../../utils');
5
+ const {createTransactionalMigration} = require('../../utils');
6
+
7
+ const MIGRATION_USER = 1;
6
8
 
7
9
  module.exports = createTransactionalMigration(
8
10
  async function up(knex) {
@@ -46,7 +48,7 @@ module.exports = createTransactionalMigration(
46
48
  role_id: role.id,
47
49
  integration_id: integration.id,
48
50
  created_at: knex.raw('current_timestamp'),
49
- created_by: meta.MIGRATION_USER
51
+ created_by: MIGRATION_USER
50
52
  });
51
53
  },
52
54
  async function down(knex) {
@@ -2,7 +2,9 @@
2
2
 
3
3
  const logging = require('@tryghost/logging');
4
4
  const {default: ObjectID} = require('bson-objectid');
5
- const {createTransactionalMigration, meta} = require('../../utils');
5
+ const {createTransactionalMigration} = require('../../utils');
6
+
7
+ const MIGRATION_USER = 1;
6
8
 
7
9
  const coreContentIntegration = {
8
10
  slug: 'ghost-core-content',
@@ -26,7 +28,7 @@ const addIntegration = async (knex, integration) => {
26
28
  const now = knex.raw('CURRENT_TIMESTAMP');
27
29
  integration.id = (new ObjectID()).toHexString();
28
30
  integration.created_at = now;
29
- integration.created_by = meta.MIGRATION_USER;
31
+ integration.created_by = MIGRATION_USER;
30
32
 
31
33
  await knex('integrations').insert(integration);
32
34
  };
@@ -4,7 +4,9 @@ const {InternalServerError} = require('@tryghost/errors');
4
4
  const logging = require('@tryghost/logging');
5
5
  const security = require('@tryghost/security');
6
6
  const {default: ObjectID} = require('bson-objectid');
7
- const {createTransactionalMigration, meta} = require('../../utils');
7
+ const {createTransactionalMigration} = require('../../utils');
8
+
9
+ const MIGRATION_USER = 1;
8
10
 
9
11
  const coreContentIntegration = {
10
12
  slug: 'ghost-core-content',
@@ -45,7 +47,7 @@ const addIntegrationContentKey = async (knex, integration) => {
45
47
  role_id: null,
46
48
  integration_id: existingIntegration.id,
47
49
  created_at: knex.raw('current_timestamp'),
48
- created_by: meta.MIGRATION_USER
50
+ created_by: MIGRATION_USER
49
51
  });
50
52
  };
51
53
 
@@ -0,0 +1,46 @@
1
+ const logging = require('@tryghost/logging');
2
+ const {createNonTransactionalMigration} = require('../../utils');
3
+
4
+ async function dropUpdatedBy(knex, table) {
5
+ const hasUpdatedBy = await knex.schema.hasColumn(table, 'updated_by');
6
+
7
+ if (hasUpdatedBy) {
8
+ logging.info(`Dropping updated_by from ${table}`);
9
+
10
+ await knex.schema.alterTable(table, function (t) {
11
+ t.dropColumn('updated_by');
12
+ });
13
+ } else {
14
+ logging.info(`${table} does not have updated_by - skipping`);
15
+ }
16
+ }
17
+
18
+ module.exports = createNonTransactionalMigration(
19
+ async function up(knex) {
20
+ logging.info('Dropping updated_by from all tables');
21
+
22
+ await dropUpdatedBy(knex, 'posts');
23
+ await dropUpdatedBy(knex, 'users');
24
+ await dropUpdatedBy(knex, 'roles');
25
+ await dropUpdatedBy(knex, 'permissions');
26
+ await dropUpdatedBy(knex, 'settings');
27
+ await dropUpdatedBy(knex, 'tags');
28
+ await dropUpdatedBy(knex, 'invites');
29
+ await dropUpdatedBy(knex, 'integrations');
30
+ await dropUpdatedBy(knex, 'webhooks');
31
+ await dropUpdatedBy(knex, 'api_keys');
32
+ await dropUpdatedBy(knex, 'members');
33
+ await dropUpdatedBy(knex, 'labels');
34
+ await dropUpdatedBy(knex, 'members_stripe_customers');
35
+ await dropUpdatedBy(knex, 'members_stripe_customers_subscriptions');
36
+ await dropUpdatedBy(knex, 'emails');
37
+ await dropUpdatedBy(knex, 'snippets');
38
+
39
+ logging.info('updated_by dropped from all tables');
40
+ },
41
+
42
+ async function down() {
43
+ // Major version migrations are not reversible
44
+ logging.warn('Reverting removal of updated_by is not supported');
45
+ }
46
+ );
@@ -0,0 +1,47 @@
1
+ const logging = require('@tryghost/logging');
2
+ const {createNonTransactionalMigration} = require('../../utils');
3
+
4
+ async function dropCreatedBy(knex, table) {
5
+ const hasCreatedBy = await knex.schema.hasColumn(table, 'created_by');
6
+
7
+ if (hasCreatedBy) {
8
+ logging.info(`Dropping created_by from ${table}`);
9
+
10
+ await knex.schema.alterTable(table, function (t) {
11
+ t.dropColumn('created_by');
12
+ });
13
+ } else {
14
+ logging.info(`${table} does not have created_by - skipping`);
15
+ }
16
+ }
17
+
18
+ module.exports = createNonTransactionalMigration(
19
+ async function up(knex) {
20
+ logging.info('Dropping created_by from all tables');
21
+
22
+ await dropCreatedBy(knex, 'posts');
23
+ await dropCreatedBy(knex, 'users');
24
+ await dropCreatedBy(knex, 'roles');
25
+ await dropCreatedBy(knex, 'permissions');
26
+ await dropCreatedBy(knex, 'settings');
27
+ await dropCreatedBy(knex, 'tags');
28
+ await dropCreatedBy(knex, 'invites');
29
+ await dropCreatedBy(knex, 'integrations');
30
+ await dropCreatedBy(knex, 'webhooks');
31
+ await dropCreatedBy(knex, 'api_keys');
32
+ await dropCreatedBy(knex, 'members');
33
+ await dropCreatedBy(knex, 'labels');
34
+ await dropCreatedBy(knex, 'members_stripe_customers');
35
+ await dropCreatedBy(knex, 'members_stripe_customers_subscriptions');
36
+ await dropCreatedBy(knex, 'emails');
37
+ await dropCreatedBy(knex, 'tokens');
38
+ await dropCreatedBy(knex, 'snippets');
39
+
40
+ logging.info('created_by dropped from all tables');
41
+ },
42
+
43
+ async function down() {
44
+ // Major version migrations are not reversible
45
+ logging.warn('Reverting removal of created_by is not supported');
46
+ }
47
+ );
@@ -0,0 +1,22 @@
1
+ // For information on writing migrations, see https://www.notion.so/ghost/Database-migrations-eb5b78c435d741d2b34a582d57c24253
2
+
3
+ const logging = require('@tryghost/logging');
4
+ const crypto = require('crypto');
5
+
6
+ // For DML - data changes
7
+ const {createTransactionalMigration} = require('../../utils');
8
+
9
+ module.exports = createTransactionalMigration(
10
+ async function up(knex) {
11
+ const membersWithoutUUID = await knex.select('id').from('members').whereNull('uuid');
12
+
13
+ logging.info(`Adding uuid field value to ${membersWithoutUUID.length} members.`);
14
+
15
+ // eslint-disable-next-line no-restricted-syntax
16
+ for (const member of membersWithoutUUID) {
17
+ await knex('members').update('uuid', crypto.randomUUID()).where('id', member.id);
18
+ }
19
+ },
20
+ // down is a no-op
21
+ async function down() {}
22
+ );
@@ -0,0 +1,5 @@
1
+ const {createDropNullableMigration} = require('../../utils');
2
+
3
+ // Running drop nullable migration without foreign key checks disabled
4
+ // This is because uuid isn't used as a foreign key anywhere in the schema
5
+ module.exports = createDropNullableMigration('members', 'uuid');
@@ -0,0 +1,95 @@
1
+ const logging = require('@tryghost/logging');
2
+ const ObjectID = require('bson-objectid').default;
3
+
4
+ const {createTransactionalMigration} = require('../../utils');
5
+
6
+ const LEGACY_HARDCODED_USER_ID = '1';
7
+
8
+ module.exports = createTransactionalMigration(
9
+ async function up(knex) {
10
+ const newId = (new ObjectID()).toHexString();
11
+
12
+ logging.info(`Updating hardcoded user ID ${LEGACY_HARDCODED_USER_ID} to ${newId}`);
13
+
14
+ const currentUserWithHardcodedId = await knex('users').where('id', LEGACY_HARDCODED_USER_ID).first();
15
+
16
+ if (!currentUserWithHardcodedId) {
17
+ logging.warn(`User with ID ${LEGACY_HARDCODED_USER_ID} not found, skipping migration`);
18
+
19
+ return;
20
+ }
21
+
22
+ const now = Date.now();
23
+ const email = currentUserWithHardcodedId.email;
24
+ const slug = currentUserWithHardcodedId.slug;
25
+ const temporaryEmail = `migrating-${now}@migration.local`;
26
+ const temporarySlug = `migrating-${now}`;
27
+
28
+ // Step 1: Create a clone of the current user using the new ID.
29
+ // This is so we can assign existing references to the new user ID
30
+ // without violating foreign key constraints. We also need to use a
31
+ // temporary email and slug to avoid duplicate constraint errors
32
+ const clonedUser = {
33
+ ...currentUserWithHardcodedId,
34
+ id: newId,
35
+ slug: temporarySlug,
36
+ email: temporaryEmail
37
+ };
38
+
39
+ await knex('users').insert(clonedUser);
40
+
41
+ logging.info(`Cloned existing user with updated properties - ID: ${newId}, email: ${temporaryEmail}, slug: ${temporarySlug}`);
42
+
43
+ // Step 2: Update all references to the current user ID to point
44
+ // to the cloned user ID. The order matters to avoid foreign key
45
+ // constraint violations.
46
+
47
+ // 1. Tables with user_id column
48
+ await knex('roles_users').where('user_id', LEGACY_HARDCODED_USER_ID).update({user_id: newId});
49
+ await knex('permissions_users').where('user_id', LEGACY_HARDCODED_USER_ID).update({user_id: newId});
50
+ await knex('sessions').where('user_id', LEGACY_HARDCODED_USER_ID).update({user_id: newId});
51
+ await knex('api_keys').where('user_id', LEGACY_HARDCODED_USER_ID).update({user_id: newId});
52
+
53
+ // 2. Tables with author_id column
54
+ await knex('posts_authors').where('author_id', LEGACY_HARDCODED_USER_ID).update({author_id: newId});
55
+ await knex('post_revisions').where('author_id', LEGACY_HARDCODED_USER_ID).update({author_id: newId});
56
+
57
+ // 3. Tables with published_by column (nullable)
58
+ await knex('posts').where('published_by', LEGACY_HARDCODED_USER_ID).update({published_by: newId});
59
+
60
+ // 4. Actions table with actor_id
61
+ await knex('actions')
62
+ .where('actor_id', LEGACY_HARDCODED_USER_ID)
63
+ .where('actor_type', 'user')
64
+ .update({actor_id: newId});
65
+
66
+ // 5. Update user_id inside session_data JSON
67
+ await knex.raw(`
68
+ UPDATE sessions
69
+ SET session_data = JSON_SET(session_data, '$.user_id', ?)
70
+ WHERE JSON_VALID(session_data)
71
+ AND JSON_EXTRACT(session_data, '$.user_id') = ?
72
+ `, [newId, LEGACY_HARDCODED_USER_ID]);
73
+
74
+ // Step 3: Clean up the now redundant user record identified by the
75
+ // legacy user ID as there should be no references to it anymore
76
+ await knex('users').where('id', LEGACY_HARDCODED_USER_ID).del();
77
+
78
+ logging.info(`Removed user with ID ${LEGACY_HARDCODED_USER_ID}`);
79
+
80
+ // Step 4: Restore the original slug and email on the cloned user record
81
+ await knex('users').where('id', newId).update({
82
+ slug,
83
+ email
84
+ });
85
+
86
+ logging.info(`Restored user slug and email: ${slug}, ${email}`);
87
+
88
+ logging.info(`Successfully updated user ID from ${LEGACY_HARDCODED_USER_ID} to ${newId}`);
89
+ },
90
+
91
+ async function down() {
92
+ // Major version migrations are not reversible
93
+ logging.warn('Reverting migration of user ID to ObjectID is not supported');
94
+ }
95
+ );
@@ -0,0 +1,6 @@
1
+ const {combineTransactionalMigrations, removeSetting} = require('../../utils');
2
+
3
+ module.exports = combineTransactionalMigrations(
4
+ removeSetting('amp'),
5
+ removeSetting('amp_gtag_id')
6
+ );
@@ -0,0 +1,3 @@
1
+ const {dropTables} = require('../../utils');
2
+
3
+ module.exports = dropTables(['temp_mail_events']);
@@ -0,0 +1,25 @@
1
+ const logging = require('@tryghost/logging');
2
+ const {createNonTransactionalMigration} = require('../../utils');
3
+ const DatabaseInfo = require('@tryghost/database-info');
4
+
5
+ module.exports = createNonTransactionalMigration(
6
+ async function up(knex) {
7
+ if (DatabaseInfo.isSQLite(knex)) {
8
+ logging.warn('Skipping migration for SQLite3 (fixed-length VARCHAR columns are not enforced)');
9
+ return;
10
+ }
11
+
12
+ logging.info('Changing posts_meta.feature_image_alt column from VARCHAR(191) to VARCHAR(2000)');
13
+ await knex.schema.alterTable('posts_meta', function (table) {
14
+ table.string('feature_image_alt', 2000).alter();
15
+ });
16
+
17
+ logging.info('Changing post_revisions.feature_image_alt column from VARCHAR(191) to VARCHAR(2000)');
18
+ await knex.schema.alterTable('post_revisions', function (table) {
19
+ table.string('feature_image_alt', 2000).alter();
20
+ });
21
+ },
22
+ async function down() {
23
+ logging.warn('Reverting posts_meta.feature_image_alt and post_revisions.feature_image_alt column length increases is not supported (major version migrations are not reversible)');
24
+ }
25
+ );
@@ -427,19 +427,6 @@
427
427
  "flags": "RO"
428
428
  }
429
429
  },
430
- "amp": {
431
- "amp": {
432
- "defaultValue": "false",
433
- "validations": {
434
- "isIn": [["true", "false"]]
435
- },
436
- "type": "boolean"
437
- },
438
- "amp_gtag_id": {
439
- "defaultValue": null,
440
- "type": "string"
441
- }
442
- },
443
430
  "firstpromoter": {
444
431
  "firstpromoter": {
445
432
  "defaultValue": "false",
@@ -8,8 +8,39 @@ const baseUtils = require('../../../models/base/utils');
8
8
  const moment = require('moment');
9
9
 
10
10
  class FixtureManager {
11
- constructor(fixtures) {
12
- this.fixtures = fixtures;
11
+ /**
12
+ * Create a new FixtureManager instance
13
+ *
14
+ * @param {Object} fixtures - The fixture data
15
+ * @param {Object<string, Function>} placeholderMap - Map of placeholder
16
+ * strings to replacement functions that will be called with the models
17
+ * object. The replacement function will be called with the models object
18
+ * and should return the replacement value. The replacement function will
19
+ * only be called once and its value will be cached for subsequent calls.
20
+ * The placeholder string will be replaced with the replacement value in
21
+ * the fixtures.
22
+ * @example
23
+ * new FixtureManager(fixtures, {
24
+ * __OWNER_USER_ID__: (models) => models.User.generateId()
25
+ * })
26
+ */
27
+ constructor(fixtures, placeholderMap = {}) {
28
+ this._fixtures = fixtures;
29
+ this.placeholderMap = placeholderMap;
30
+ this.hasProcessedFixtures = false;
31
+ }
32
+
33
+ /**
34
+ * Lazily get the fixtures, processing placeholders on first access
35
+ * @returns {Object}
36
+ */
37
+ get fixtures() {
38
+ if (!this.hasProcessedFixtures) {
39
+ this._fixtures = this.processFixtures(this._fixtures, this.placeholderMap);
40
+ this.hasProcessedFixtures = true;
41
+ }
42
+
43
+ return this._fixtures;
13
44
  }
14
45
 
15
46
  /**
@@ -68,9 +99,17 @@ class FixtureManager {
68
99
  * @returns
69
100
  */
70
101
  async addAllFixtures(options) {
102
+ const ownerUserId = this.findOwnerUserId();
103
+
71
104
  const localOptions = _.merge({
72
105
  autoRefresh: false,
73
- context: {internal: true},
106
+ context: {
107
+ internal: true,
108
+ // Ensure the owner user is set in the context when creating
109
+ // the fixtures so that attribution gets correctly set (i.e
110
+ // the owner user is set as the `published_by` user on posts)
111
+ user: ownerUserId
112
+ },
74
113
  migrating: true
75
114
  }, options);
76
115
 
@@ -85,7 +124,6 @@ class FixtureManager {
85
124
 
86
125
  await sequence(this.fixtures.models.filter(m => !['User', 'Role'].includes(m.name)).map(model => () => {
87
126
  logging.info('Model: ' + model.name);
88
-
89
127
  return this.addFixturesForModel(model, localOptions);
90
128
  }));
91
129
 
@@ -175,9 +213,94 @@ class FixtureManager {
175
213
  return foundRelation;
176
214
  }
177
215
 
216
+ /**
217
+ * ### Find Owner User ID
218
+ * Find the owner user ID from the relation fixture
219
+ * @returns {string}
220
+ */
221
+ findOwnerUserId() {
222
+ const relation = this.findRelationFixture('User', 'Role');
223
+
224
+ return Object.keys(relation.entries).find(
225
+ key => relation.entries[key].includes('Owner')
226
+ );
227
+ }
228
+
178
229
  /******************************************************
179
230
  * From here down, the methods require access to models
180
- * But aren't dependent on this.fixtures
231
+ ******************************************************/
232
+
233
+ /**
234
+ * Process fixtures by replacing placeholder strings with dynamic values
235
+ *
236
+ * @param {Object} fixtures - The fixture data to process
237
+ * @param {Object<string, Function>} placeholderMap - Map of placeholder
238
+ * strings to replacement functions that will be called with the models
239
+ * object. The replacement function will be called with the models object
240
+ * and should return the replacement value. The replacement function will
241
+ * only be called once and its value will be cached for subsequent calls.
242
+ * The placeholder string will be replaced with the replacement value in
243
+ * the fixtures.
244
+ * @returns {Object}
245
+ */
246
+ processFixtures(fixtures, placeholderMap) {
247
+ const cache = new Map();
248
+
249
+ const processString = (str, replacements) => {
250
+ let result = str;
251
+
252
+ for (const placeholder in replacements) {
253
+ if (result.includes(placeholder)) {
254
+ if (!cache.has(placeholder)) {
255
+ cache.set(placeholder, replacements[placeholder](models));
256
+ }
257
+
258
+ const processedValue = cache.get(placeholder);
259
+
260
+ result = result.replaceAll(placeholder, processedValue);
261
+ }
262
+ }
263
+
264
+ return result;
265
+ };
266
+
267
+ const replacePlaceholders = (obj, replacements) => {
268
+ if (obj === null || obj === undefined) {
269
+ return obj;
270
+ }
271
+
272
+ if (typeof obj === 'string') {
273
+ return processString(obj, replacements);
274
+ }
275
+
276
+ if (Array.isArray(obj)) {
277
+ return obj.map(item => replacePlaceholders(item, replacements));
278
+ }
279
+
280
+ if (typeof obj === 'object') {
281
+ const result = {};
282
+
283
+ for (const key in obj) {
284
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
285
+ // Process the key itself for placeholders
286
+ const newKey = processString(key, replacements);
287
+
288
+ result[newKey] = replacePlaceholders(obj[key], replacements);
289
+ }
290
+ }
291
+
292
+ return result;
293
+ }
294
+
295
+ return obj;
296
+ };
297
+
298
+ return replacePlaceholders(fixtures, placeholderMap);
299
+ }
300
+
301
+ /******************************************************
302
+ * From here down, the methods aren't dependent on
303
+ * this.fixtures
181
304
  ******************************************************/
182
305
 
183
306
  /**