vintasend-managed-templates 1.0.0-alpha2

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 (38) hide show
  1. package/README.md +529 -0
  2. package/dist/base-template-manager-backend.d.ts +202 -0
  3. package/dist/base-template-manager-backend.d.ts.map +1 -0
  4. package/dist/base-template-manager-backend.js +1 -0
  5. package/dist/composition.d.ts +238 -0
  6. package/dist/composition.d.ts.map +1 -0
  7. package/dist/composition.js +0 -0
  8. package/dist/constants.d.ts +32 -0
  9. package/dist/constants.d.ts.map +1 -0
  10. package/dist/constants.js +31 -0
  11. package/dist/errors.d.ts +80 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/errors.js +86 -0
  14. package/dist/filter-evaluation.d.ts +69 -0
  15. package/dist/filter-evaluation.d.ts.map +1 -0
  16. package/dist/filter-evaluation.js +252 -0
  17. package/dist/filters.d.ts +192 -0
  18. package/dist/filters.d.ts.map +1 -0
  19. package/dist/filters.js +252 -0
  20. package/dist/in-memory-template-manager-backend.d.ts +85 -0
  21. package/dist/in-memory-template-manager-backend.d.ts.map +1 -0
  22. package/dist/in-memory-template-manager-backend.js +323 -0
  23. package/dist/index.d.ts +19 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +18 -0
  26. package/dist/managed-template-renderer.d.ts +153 -0
  27. package/dist/managed-template-renderer.d.ts.map +1 -0
  28. package/dist/managed-template-renderer.js +152 -0
  29. package/dist/managed-template-service.d.ts +415 -0
  30. package/dist/managed-template-service.d.ts.map +1 -0
  31. package/dist/managed-template-service.js +712 -0
  32. package/dist/tags.d.ts +54 -0
  33. package/dist/tags.d.ts.map +1 -0
  34. package/dist/tags.js +108 -0
  35. package/dist/types.d.ts +100 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +1 -0
  38. package/package.json +41 -0
@@ -0,0 +1,415 @@
1
+ /**
2
+ * Backend-agnostic service for managing template versions and their statuses.
3
+ *
4
+ * `ManagedTemplateService` sits between a host application and the two seams this package
5
+ * defines: a `BaseTemplateManagerBackend` (where templates live) and a `ManagedTemplateRenderer`
6
+ * (how a template turns into something an adapter can send). Every storage call goes through the
7
+ * backend, so the service works unchanged against any implementation of that interface.
8
+ *
9
+ * What the service adds on top of the raw backend:
10
+ *
11
+ * * **Version resolution.** An absent `version` consistently means "the latest version of this
12
+ * key" across reads, status changes, and rendering, so callers never juggle version numbers
13
+ * unless they want a specific one.
14
+ * * **Status transitions.** Status changes are validated against `allowedStatusTransitions` and
15
+ * then written through the backend's audit trail, with named helpers (`activate` /
16
+ * `deactivate` / `archive`) for the common moves.
17
+ * * **Filter validation.** Filters are checked for shape and field names before they reach the
18
+ * backend, so a typo throws `ManagedTemplateInvalidFilterError` here instead of silently
19
+ * matching nothing (or blowing up) deep inside a backend's query translation.
20
+ * * **Tag hygiene.** Tag text is normalized and slugified here before it reaches the backend, so
21
+ * every implementation of the storage seam is handed the same slug for the same text, and text
22
+ * with nothing sluggable in it is rejected with `ManagedTemplateInvalidTagError` instead of
23
+ * becoming a tag no filter can ever name.
24
+ * * **Version-pinned rendering.** Rendering honours a notification's own
25
+ * `requestedTemplateVersion`, so a notification recorded against v3 renders v3 however many
26
+ * versions follow. The service adds an explicit `version` argument on top, overriding even
27
+ * that — which is what makes previewing an unpublished draft possible — and reports which
28
+ * version actually rendered, for the caller to record.
29
+ * * **Composition.** Templates are flattened before they render: a template that extends a base
30
+ * or includes a fragment reaches the engine as one string with no `managed_*` tag left in it
31
+ * (see `composition`). Reads are unaffected — `getTemplate` still hands back exactly what is
32
+ * stored, and `getComposedTemplate` is the explicit way to ask for the assembled form.
33
+ *
34
+ * Two deliberate non-policies, both chosen so the service stays a thin orchestration layer:
35
+ *
36
+ * * A key may have **any number of active versions at once**. Activating a version does not touch
37
+ * the ones already active; deciding which active version wins at render time is the host's call.
38
+ * * `changedBy` is **passed through untouched**, `null` included. The service never requires
39
+ * attribution on a status change.
40
+ */
41
+ import type { AnyNotification, BaseNotificationTypeConfig, JsonObject } from 'vintasend';
42
+ import type { BaseTemplateManagerBackend } from './base-template-manager-backend.js';
43
+ import { TemplateComposer, type TemplateReference } from './composition.js';
44
+ import type { ManagedTemplateStatus, ManagedTemplateTagStatus } from './constants.js';
45
+ import { type ManagedTemplateFilter, type ManagedTemplateFilterCapabilities, type ManagedTemplateOrderBy, type ManagedTemplateOrderByField } from './filters.js';
46
+ import type { ManagedTemplateRenderer, ManagedTemplateRenderResult } from './managed-template-renderer.js';
47
+ import type { ManagedTemplate, ManagedTemplateCreateInput, ManagedTemplateStatusHistory, ManagedTemplateTag, ManagedTemplateUpdateInput } from './types.js';
48
+ /**
49
+ * Which status a version may move to, keyed by the status it is in now.
50
+ *
51
+ * `archived` is terminal: an archived version is a historical record, and bringing one back would
52
+ * make its audit trail read as though it had never been retired. Publish a new version instead.
53
+ */
54
+ export declare const DEFAULT_STATUS_TRANSITIONS: Readonly<Record<ManagedTemplateStatus, readonly ManagedTemplateStatus[]>>;
55
+ export type ManagedTemplateServiceOptions = {
56
+ /**
57
+ * When true (the default), a status change must appear in `allowedStatusTransitions` for the
58
+ * version's current status. Set false to let any status move to any other and leave the
59
+ * ordering entirely to the host.
60
+ */
61
+ validateStatusTransitions?: boolean;
62
+ /**
63
+ * When true (the default), a template is flattened before it is rendered —
64
+ * `{% managed_extends %}` / `{% managed_include %}` and the rest are resolved against this
65
+ * service's backend. Set false to hand the engine what is stored, verbatim.
66
+ */
67
+ composeTemplates?: boolean;
68
+ /**
69
+ * The composer that does it. Defaults to one reading through the template manager backend, so
70
+ * composition resolves against the same store the service reads from rather than through
71
+ * whatever backend the renderer happens to hold.
72
+ */
73
+ composer?: TemplateComposer;
74
+ /** A lifecycle other than the default one. */
75
+ allowedStatusTransitions?: Readonly<Record<ManagedTemplateStatus, readonly ManagedTemplateStatus[]>>;
76
+ };
77
+ export declare class ManagedTemplateService<Config extends BaseNotificationTypeConfig, RenderedType = unknown, ContentType = unknown> {
78
+ readonly templateManagerBackend: BaseTemplateManagerBackend;
79
+ readonly templateRenderer: ManagedTemplateRenderer<Config, RenderedType, ContentType>;
80
+ readonly validateStatusTransitions: boolean;
81
+ readonly composeTemplates: boolean;
82
+ readonly composer: TemplateComposer;
83
+ readonly allowedStatusTransitions: Readonly<Record<ManagedTemplateStatus, readonly ManagedTemplateStatus[]>>;
84
+ private capabilitiesCache;
85
+ /**
86
+ * @param templateManagerBackend where templates are stored and versioned.
87
+ * @param templateRenderer turns a `ManagedTemplate` into something an adapter can send. The
88
+ * service drives its `createTemplateContent` / `renderFromTemplateContent` pair rather than
89
+ * its own backend read, so the renderer only needs to agree with this service on the shape of
90
+ * a template, not on where templates live.
91
+ */
92
+ constructor(templateManagerBackend: BaseTemplateManagerBackend, templateRenderer: ManagedTemplateRenderer<Config, RenderedType, ContentType>, options?: ManagedTemplateServiceOptions);
93
+ /**
94
+ * The backend's capability report, merged over the library default.
95
+ *
96
+ * Cached for the life of the service: a backend's capabilities are a static property of its
97
+ * implementation, so re-asking on every request would buy nothing.
98
+ */
99
+ getBackendSupportedFilterCapabilities(): ManagedTemplateFilterCapabilities;
100
+ /**
101
+ * Create the first version of a new template.
102
+ *
103
+ * Any tag text on the input that has no tag behind it yet becomes one, so a caller never has to
104
+ * create tags before using them.
105
+ *
106
+ * @throws ManagedTemplateInvalidTagError if a tag text has nothing that can be slugified.
107
+ */
108
+ createTemplate(input: ManagedTemplateCreateInput): Promise<ManagedTemplate>;
109
+ /**
110
+ * One version of a template. An absent `version` returns the latest version.
111
+ *
112
+ * @throws ManagedTemplateNotFoundError if the key (or that version of it) does not exist.
113
+ */
114
+ getTemplate(templateKey: string, version?: number | null): Promise<ManagedTemplate>;
115
+ /**
116
+ * Create a new version of an existing template from the latest one.
117
+ *
118
+ * Templates are versioned rather than edited in place, so this never mutates a version that has
119
+ * already been published — the backend copies the latest version forward, applies the set
120
+ * fields of `input`, and returns the new version.
121
+ *
122
+ * Tags follow the same rule as every other field on the input: absent carries the previous
123
+ * version's tags forward, and an empty array means a version with none.
124
+ */
125
+ updateTemplate(templateKey: string, input: ManagedTemplateUpdateInput): Promise<ManagedTemplate>;
126
+ /**
127
+ * Delete one version of a template, or its latest version when `version` is absent.
128
+ */
129
+ deleteTemplate(templateKey: string, version?: number | null): Promise<void>;
130
+ /** Every version of a template, newest version first. */
131
+ getTemplateVersions(templateKey: string): Promise<ManagedTemplate[]>;
132
+ private withCleanTags;
133
+ /**
134
+ * Move one version of a template to `status` and record it in the audit trail.
135
+ *
136
+ * Setting a version to the status it already holds is a no-op: the template is returned
137
+ * unchanged and no history entry is written, so repeating a call does not fill the audit trail
138
+ * with entries that record nothing.
139
+ *
140
+ * @throws ManagedTemplateNotFoundError if the key (or that version of it) does not exist.
141
+ * @throws ManagedTemplateStatusTransitionError if the move is not allowed from the version's
142
+ * current status and `validateStatusTransitions` is on.
143
+ */
144
+ setStatus(templateKey: string, status: ManagedTemplateStatus, version?: number | null, changedBy?: string | null): Promise<ManagedTemplate>;
145
+ /**
146
+ * Publish one version of a template.
147
+ *
148
+ * Other versions of the same key that are already active are left alone — a key may hold
149
+ * several active versions at once, and choosing between them is the host's call.
150
+ */
151
+ activate(templateKey: string, version?: number | null, changedBy?: string | null): Promise<ManagedTemplate>;
152
+ /** Retire one version without archiving it, so it can be activated again. */
153
+ deactivate(templateKey: string, version?: number | null, changedBy?: string | null): Promise<ManagedTemplate>;
154
+ /** Archive one version. Terminal under the default transition table. */
155
+ archive(templateKey: string, version?: number | null, changedBy?: string | null): Promise<ManagedTemplate>;
156
+ /**
157
+ * The status audit trail for a template, most recent change first.
158
+ *
159
+ * @param version every version's history when absent, if the backend supports it.
160
+ */
161
+ getStatusHistory(templateKey: string, version?: number | null): Promise<ManagedTemplateStatusHistory[]>;
162
+ /** Every template version in any of the given statuses. */
163
+ getTemplatesByStatus(status: ManagedTemplateStatus[]): Promise<ManagedTemplate[]>;
164
+ /**
165
+ * Whether `template` may move to `status`, without attempting the move.
166
+ *
167
+ * Lets a caller (a UI deciding which buttons to enable, say) ask the same question `setStatus`
168
+ * asks, instead of catching the exception to find out.
169
+ */
170
+ canTransitionTo(template: ManagedTemplate, status: ManagedTemplateStatus): boolean;
171
+ /**
172
+ * Which statuses `template` may move to right now, in a stable order.
173
+ *
174
+ * The version's current status is excluded even though `canTransitionTo` returns true for it:
175
+ * setting a version to the status it already holds is a documented no-op, not a transition, and
176
+ * offering it as an action would be offering to do nothing.
177
+ */
178
+ allowedTransitionsFor(template: ManagedTemplate): ManagedTemplateStatus[];
179
+ private checkStatusTransition;
180
+ /**
181
+ * Create a tag, failing if its text already slugs onto an existing one.
182
+ *
183
+ * Tagging a template creates missing tags on its own, so this is for the case where a tag is
184
+ * being defined ahead of any template using it — and where a collision with an existing tag is
185
+ * worth hearing about rather than silently resolving.
186
+ */
187
+ createTag(text: string, tenant?: string | null): Promise<ManagedTemplateTag>;
188
+ /** One tag by slug, or by the text it was created from. */
189
+ getTag(slug: string): Promise<ManagedTemplateTag>;
190
+ /** Tags, optionally narrowed by status, by a text search, or by tenant. */
191
+ getTags(status?: ManagedTemplateTagStatus[] | null, search?: string | null, tenant?: string | null): Promise<ManagedTemplateTag[]>;
192
+ /** The tags still on offer — what a tag picker should show. */
193
+ getActiveTags(tenant?: string | null): Promise<ManagedTemplateTag[]>;
194
+ /**
195
+ * Rename a tag, regenerating its slug from the new text.
196
+ *
197
+ * The templates carrying the tag keep it. The slug changes, though, so a saved filter naming
198
+ * the old slug stops matching — a rename is a change of identity, not a display change.
199
+ */
200
+ updateTag(slug: string, text: string): Promise<ManagedTemplateTag>;
201
+ /** Retire a tag from the pickers without touching the templates carrying it. */
202
+ archiveTag(slug: string): Promise<ManagedTemplateTag>;
203
+ /**
204
+ * Put an archived tag back on offer.
205
+ *
206
+ * Unlike an archived template version — terminal, because reviving one would rewrite what its
207
+ * audit trail says happened — a tag carries no history to contradict, so archiving one is
208
+ * reversible.
209
+ */
210
+ restoreTag(slug: string): Promise<ManagedTemplateTag>;
211
+ setTagStatus(slug: string, status: ManagedTemplateTagStatus): Promise<ManagedTemplateTag>;
212
+ /** Delete a tag, removing it from every template carrying it. */
213
+ deleteTag(slug: string): Promise<void>;
214
+ /** Resolve tag texts to tags, creating the ones that do not exist yet. */
215
+ getOrCreateTags(texts: string[], tenant?: string | null): Promise<ManagedTemplateTag[]>;
216
+ /** The tags on one version of a template, or on its latest version. */
217
+ getTemplateTags(templateKey: string, version?: number | null): Promise<ManagedTemplateTag[]>;
218
+ /**
219
+ * Replace the tags on one version of a template, creating any that do not exist.
220
+ *
221
+ * Retagging edits the version in place instead of creating a new one: tags are how a template
222
+ * is found, not part of what it renders, so relabelling should not spawn a version and drop it
223
+ * back to `draft`.
224
+ */
225
+ setTemplateTags(templateKey: string, tags: string[], version?: number | null): Promise<ManagedTemplate>;
226
+ /** Add tags to a version, leaving the ones already on it in place. */
227
+ addTemplateTags(templateKey: string, tags: string[], version?: number | null): Promise<ManagedTemplate>;
228
+ /**
229
+ * Remove tags from a version. Tags it does not carry are ignored.
230
+ *
231
+ * The tags themselves survive — this unlinks them from one version, it does not delete them.
232
+ */
233
+ removeTemplateTags(templateKey: string, tags: string[], version?: number | null): Promise<ManagedTemplate>;
234
+ /**
235
+ * The templates carrying these tags — all of them, or any of them.
236
+ *
237
+ * A shorthand for the `includesAllTags` / `includesAnyOfTags` filters, which is what it builds.
238
+ * Follows the same empty-collection rule they do: matching *all* of no tags returns everything,
239
+ * matching *any* of no tags returns nothing.
240
+ */
241
+ getTemplatesByTags(tags: string[], matchAll?: boolean): Promise<ManagedTemplate[]>;
242
+ /**
243
+ * Trim a tag's text, rejecting it when nothing sluggable is left.
244
+ *
245
+ * Checked here rather than left to the backend so every backend is handed text it can slugify,
246
+ * and so a caller hears about `' '` or `'!!!'` at the call site instead of ending up with a
247
+ * tag whose slug is empty and which no filter can name.
248
+ */
249
+ private cleanTagText;
250
+ /** Clean each text, dropping repeats that slug onto a tag already in the list. */
251
+ private cleanTagTexts;
252
+ /**
253
+ * Slugify a caller's tag texts, dropping the ones with nothing sluggable.
254
+ *
255
+ * Unlike `cleanTagTexts` this never throws: these slugs are used to *match*, and a tag no store
256
+ * could hold simply matches nothing — which is a correct answer, not an error worth
257
+ * interrupting a search for.
258
+ */
259
+ private static slugsFor;
260
+ /**
261
+ * The current version of every template — one row per key.
262
+ *
263
+ * "Current" is the `mostRecentActiveVersion` filter: the highest-numbered active or draft
264
+ * version of each key. It is the default because a listing is nearly always a list of
265
+ * *templates*, and the store holds a row per *version*, so the unfiltered read shows the same
266
+ * template once per version it has ever had and hides the current one among its own history.
267
+ *
268
+ * Pass `includeAllVersions: true` for the raw read.
269
+ */
270
+ getAllTemplates(includeAllVersions?: boolean): Promise<ManagedTemplate[]>;
271
+ /**
272
+ * The templates matching `filters`.
273
+ *
274
+ * @throws ManagedTemplateInvalidFilterError if the filter is malformed or names an unknown
275
+ * field.
276
+ */
277
+ getFilteredTemplates(filters: ManagedTemplateFilter): Promise<ManagedTemplate[]>;
278
+ /**
279
+ * The filter with everything the backend cannot answer removed.
280
+ *
281
+ * A capability report nothing acts on is decoration, and every caller left to walk the map
282
+ * itself would reach a slightly different conclusion. Dropping only ever widens the result, so
283
+ * the failure mode is extra rows a caller can see — `getAllTemplates()` against a backend that
284
+ * cannot answer `mostRecentActiveVersion` returns every version rather than throwing.
285
+ *
286
+ * Ordering is *not* negotiated here. It is refused instead, because dropping it leaves no
287
+ * trace in the rows for a caller to notice.
288
+ */
289
+ private negotiate;
290
+ /**
291
+ * One page of templates, one row per key by default.
292
+ *
293
+ * @param page 1-indexed.
294
+ */
295
+ getPaginatedTemplates(page: number, pageSize: number, includeAllVersions?: boolean, orderBy?: ManagedTemplateOrderBy): Promise<ManagedTemplate[]>;
296
+ /**
297
+ * One page of the templates matching `filters`.
298
+ *
299
+ * @param page 1-indexed.
300
+ */
301
+ getPaginatedFilteredTemplates(filters: ManagedTemplateFilter, page: number, pageSize: number, orderBy?: ManagedTemplateOrderBy): Promise<ManagedTemplate[]>;
302
+ /**
303
+ * Refuse an order the backend cannot apply, rather than passing it on to be ignored.
304
+ *
305
+ * Unlike an unsupported filter — which a caller drops, getting more rows than it asked for and
306
+ * being able to tell — an ignored order returns exactly the rows requested in an arbitrary
307
+ * sequence. Nothing downstream can detect that, so the only honest options are to apply it or
308
+ * to refuse, and the backend has already said which one this is.
309
+ */
310
+ validateOrderBy(orderBy: ManagedTemplateOrderBy | undefined): void;
311
+ /** Every field this backend can order a listing by, in vocabulary order. */
312
+ getSupportedOrderByFields(): ManagedTemplateOrderByField[];
313
+ /**
314
+ * Check a filter's shape and field names, throwing rather than passing a broken filter on.
315
+ *
316
+ * A backend translating an unknown field usually either matches nothing or throws something
317
+ * backend-specific, both of which are hard to debug from the call site. This catches the common
318
+ * mistakes — a typo'd field name, an `and`/`or` that is not an array, a logical group carrying
319
+ * sibling keys — while the caller's own frame is still on the stack. It does not validate
320
+ * lookup values; the backend remains the authority there.
321
+ *
322
+ * @throws ManagedTemplateInvalidFilterError if the filter is malformed or names an unknown
323
+ * field.
324
+ */
325
+ validateFilter(filters: ManagedTemplateFilter, path?: string): void;
326
+ /**
327
+ * Reject a tag filter that is not an array of strings.
328
+ *
329
+ * One of the two value checks `validateFilter` does make, because the failure it prevents is
330
+ * silent rather than loud: a bare `'welcome'` would have a backend ask for the tags `w`, `e`,
331
+ * `l`, `c` and return nothing, with no error anywhere.
332
+ */
333
+ private validateTagFields;
334
+ /**
335
+ * Reject a flag filter whose value is not a boolean.
336
+ *
337
+ * Checked for the same reason the tag fields are: the failure is silent otherwise. A backend
338
+ * reads a flag for its truthiness, so the string `'false'` — what a query parameter that
339
+ * skipped parsing arrives as — would ask for exactly what the caller meant to switch off.
340
+ */
341
+ private validateFlagFields;
342
+ private static validatePagination;
343
+ /**
344
+ * Flatten a template's inheritance and inclusion into a single self-contained one.
345
+ *
346
+ * Composition is what a store-backed template has instead of an engine loader: the engine is
347
+ * handed source rather than a name, so a `{% managed_extends %}` here is resolved against the
348
+ * backend before the engine ever sees the template. The result has no `managed_*` tag left in
349
+ * it, and the engine's own syntax is untouched.
350
+ *
351
+ * A no-op — returning the very template it was given — when the template composes to itself,
352
+ * and when the service was built with `composeTemplates: false`.
353
+ */
354
+ composeTemplate(template: ManagedTemplate): Promise<ManagedTemplate>;
355
+ /**
356
+ * One version of a template, assembled as the engine will receive it.
357
+ *
358
+ * The counterpart to `getTemplate`, which is deliberately literal about what is stored.
359
+ */
360
+ getComposedTemplate(templateKey: string, version?: number | null): Promise<ManagedTemplate>;
361
+ /**
362
+ * Assemble a template and throw the result away, to surface any problem now.
363
+ *
364
+ * What a form or a deploy check calls: it throws exactly what rendering would have thrown — a
365
+ * malformed tag, a base that does not exist, a loop — at a point where someone can still fix it
366
+ * rather than at send time.
367
+ */
368
+ validateComposition(template: ManagedTemplate): Promise<void>;
369
+ /**
370
+ * The templates one template directly extends or includes.
371
+ *
372
+ * Direct references only, and nothing is resolved, so this answers "what does this template
373
+ * name" without needing any of them to exist.
374
+ */
375
+ getTemplateReferences(template: ManagedTemplate): TemplateReference[];
376
+ /**
377
+ * Whether a template is a base to build on rather than one to send.
378
+ *
379
+ * Read off the source every time it is asked, which makes it the authority:
380
+ * `template.isAbstract` is a backend's stored copy of this answer, kept for the `isAbstract`
381
+ * filter to query, and this is what that copy is supposed to say.
382
+ *
383
+ * To *find* the bases rather than test one, filter on the stored flag — it is indexed and this
384
+ * is not:
385
+ *
386
+ * ```ts
387
+ * await service.getFilteredTemplates({ isAbstract: false }); // everything sendable
388
+ * ```
389
+ *
390
+ * Neither one refuses anything: the service renders an abstract template quite happily, and
391
+ * gives you the layout with an empty hole. Keeping bases out of a picker is the host's call.
392
+ */
393
+ isAbstract(template: ManagedTemplate): boolean;
394
+ /**
395
+ * Render a notification against a specific version of its template.
396
+ *
397
+ * The notification's `bodyTemplate` is the template key. Which version renders is decided in
398
+ * this order: the `version` argument, then the notification's own `requestedTemplateVersion`,
399
+ * then whatever the backend considers current.
400
+ *
401
+ * The argument is there to render a version the notification is *not* pinned to — previewing an
402
+ * unpublished draft, or reproducing what an old notification looked like. Leave it off and this
403
+ * renders what a real send would.
404
+ */
405
+ render(notification: AnyNotification<Config>, context: JsonObject, version?: number | null): Promise<ManagedTemplateRenderResult<RenderedType>>;
406
+ /**
407
+ * Render a notification against a template already in hand, with no backend read.
408
+ *
409
+ * The template is composed by this service — through *its* composer and *its*
410
+ * `composeTemplates` setting, not the renderer's — so one already fetched and edited in memory
411
+ * renders the same way a stored one does.
412
+ */
413
+ renderTemplate(notification: AnyNotification<Config>, template: ManagedTemplate, context: JsonObject): Promise<ManagedTemplateRenderResult<RenderedType>>;
414
+ }
415
+ //# sourceMappingURL=managed-template-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-template-service.d.ts","sourceRoot":"","sources":["../src/managed-template-service.ts"],"names":[],"mappings":"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"}