musora-content-services 2.189.0 → 2.190.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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/index.d.ts +2 -2
- package/src/index.js +2 -2
- package/src/services/marketing/promotions.ts +21 -11
- package/src/version-info.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [2.190.0](https://github.com/railroadmedia/musora-content-services/compare/v2.189.0...v2.190.0) (2026-10-20)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **MU2-2024:** resolve placement copy in fetchAvailablePromotionalCampaigns ([ac69d37](https://github.com/railroadmedia/musora-content-services/commit/ac69d379a264e031b1f5bd999b6bed8c78fbfb58))
|
|
11
|
+
|
|
5
12
|
## [2.189.0](https://github.com/railroadmedia/musora-content-services/compare/v2.188.0...v2.189.0) (2026-10-20)
|
|
6
13
|
|
|
7
14
|
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -222,7 +222,7 @@ import {
|
|
|
222
222
|
fetchAvailablePromotionalCampaigns,
|
|
223
223
|
fetchPromotionalCampaigns,
|
|
224
224
|
fetchUserCampaignStates,
|
|
225
|
-
|
|
225
|
+
resolveCampaignPlaceholders
|
|
226
226
|
} from './services/marketing/promotions.ts';
|
|
227
227
|
|
|
228
228
|
import {
|
|
@@ -902,7 +902,7 @@ declare module 'musora-content-services' {
|
|
|
902
902
|
resetAllAwards,
|
|
903
903
|
resetAllLearningPaths,
|
|
904
904
|
resetPassword,
|
|
905
|
-
|
|
905
|
+
resolveCampaignPlaceholders,
|
|
906
906
|
restoreComment,
|
|
907
907
|
restoreItemFromPlaylist,
|
|
908
908
|
restoreNotification,
|
package/src/index.js
CHANGED
|
@@ -226,7 +226,7 @@ import {
|
|
|
226
226
|
fetchAvailablePromotionalCampaigns,
|
|
227
227
|
fetchPromotionalCampaigns,
|
|
228
228
|
fetchUserCampaignStates,
|
|
229
|
-
|
|
229
|
+
resolveCampaignPlaceholders
|
|
230
230
|
} from './services/marketing/promotions.ts';
|
|
231
231
|
|
|
232
232
|
import {
|
|
@@ -901,7 +901,7 @@ export {
|
|
|
901
901
|
resetAllAwards,
|
|
902
902
|
resetAllLearningPaths,
|
|
903
903
|
resetPassword,
|
|
904
|
-
|
|
904
|
+
resolveCampaignPlaceholders,
|
|
905
905
|
restoreComment,
|
|
906
906
|
restoreItemFromPlaylist,
|
|
907
907
|
restoreNotification,
|
|
@@ -63,6 +63,11 @@ export interface CampaignQueryOptions {
|
|
|
63
63
|
active?: boolean
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
export interface AvailableCampaignOptions extends CampaignQueryOptions {
|
|
67
|
+
/** Values for the `{name}` placeholders in placement copy. See `resolveCampaignPlaceholders`. */
|
|
68
|
+
placeholderValues?: CampaignPlaceholderValues
|
|
69
|
+
}
|
|
70
|
+
|
|
66
71
|
const UNTOUCHED: UserCampaignState = { claimed: false, dismissed: false, eligible: true }
|
|
67
72
|
|
|
68
73
|
// ============================================
|
|
@@ -126,12 +131,17 @@ export async function fetchPromotionalCampaigns(
|
|
|
126
131
|
* Every running campaign the user has not already claimed or dismissed, and is eligible.
|
|
127
132
|
*/
|
|
128
133
|
export async function fetchAvailablePromotionalCampaigns(
|
|
129
|
-
options:
|
|
134
|
+
options: AvailableCampaignOptions = {}
|
|
130
135
|
): Promise<WithUserCampaignState<PromotionalCampaign>[]> {
|
|
131
|
-
|
|
136
|
+
const { placeholderValues = {}, ...queryOptions } = options
|
|
137
|
+
|
|
138
|
+
return campaignQuery(queryOptions)
|
|
132
139
|
.run()
|
|
133
140
|
.flatMap(decorateUserCampaignState)
|
|
134
141
|
.map(filterCampaignsForUser)
|
|
142
|
+
.map((campaigns) =>
|
|
143
|
+
campaigns.map((campaign) => resolveCampaignPlaceholders(campaign, placeholderValues))
|
|
144
|
+
)
|
|
135
145
|
.recover([])
|
|
136
146
|
}
|
|
137
147
|
|
|
@@ -184,23 +194,23 @@ export function decorateUserCampaignState<T extends PromotionalCampaign>(
|
|
|
184
194
|
}
|
|
185
195
|
|
|
186
196
|
// ============================================
|
|
187
|
-
//
|
|
197
|
+
// PLACEHOLDERS
|
|
188
198
|
// ============================================
|
|
189
199
|
|
|
190
|
-
export type
|
|
200
|
+
export type CampaignPlaceholderValues = Record<string, string>
|
|
191
201
|
|
|
192
202
|
const PLACEHOLDER = /\{(\w+)\}/g
|
|
193
203
|
|
|
194
204
|
const COPY_FIELDS = ['title', 'body', 'disclaimer', 'cta_label'] as const
|
|
195
205
|
|
|
196
|
-
const fillPlaceholders = (text: string, values:
|
|
206
|
+
const fillPlaceholders = (text: string, values: CampaignPlaceholderValues) =>
|
|
197
207
|
text.replace(PLACEHOLDER, (placeholder, name: string) => values[name] ?? placeholder)
|
|
198
208
|
|
|
199
209
|
const hasPlaceholder = (text: string | undefined) => !!text && new RegExp(PLACEHOLDER).test(text)
|
|
200
210
|
|
|
201
|
-
function
|
|
211
|
+
function resolvePlacementPlaceholders(
|
|
202
212
|
placement: PromotionalCampaignPlacement,
|
|
203
|
-
values:
|
|
213
|
+
values: CampaignPlaceholderValues
|
|
204
214
|
): PromotionalCampaignPlacement {
|
|
205
215
|
const resolved = { ...placement }
|
|
206
216
|
|
|
@@ -215,14 +225,14 @@ function resolvePlacementCopy(
|
|
|
215
225
|
* Replaces `{name}` placeholders in each placement's copy with the given values. A placement left
|
|
216
226
|
* with a placeholder that has no value is dropped, so raw `{name}` text never reaches the user.
|
|
217
227
|
*/
|
|
218
|
-
export function
|
|
228
|
+
export function resolveCampaignPlaceholders<T extends PromotionalCampaign>(
|
|
219
229
|
campaign: T,
|
|
220
|
-
values:
|
|
230
|
+
values: CampaignPlaceholderValues
|
|
221
231
|
): T {
|
|
222
232
|
return {
|
|
223
233
|
...campaign,
|
|
224
|
-
placements: campaign.placements
|
|
225
|
-
.map((placement) =>
|
|
234
|
+
placements: (campaign.placements ?? [])
|
|
235
|
+
.map((placement) => resolvePlacementPlaceholders(placement, values))
|
|
226
236
|
.filter((placement) => !COPY_FIELDS.some((field) => hasPlaceholder(placement[field]))),
|
|
227
237
|
}
|
|
228
238
|
}
|
package/src/version-info.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const MCS_VERSION = '2.
|
|
1
|
+
export const MCS_VERSION = '2.190.0'
|