@marlinjai/mail-contract 0.3.0 → 0.5.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/dist/index.d.mts +9117 -2230
- package/dist/index.d.ts +9117 -2230
- package/dist/index.js +449 -19
- package/dist/index.mjs +413 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -150,6 +150,7 @@ __export(index_exports, {
|
|
|
150
150
|
EXPORT_WARNING_COUNT_HEADER: () => EXPORT_WARNING_COUNT_HEADER,
|
|
151
151
|
Email: () => Email,
|
|
152
152
|
EmailStep: () => EmailStep,
|
|
153
|
+
EmailStepLanguage: () => EmailStepLanguage,
|
|
153
154
|
ErrorBody: () => ErrorBody,
|
|
154
155
|
ErrorCodeSchema: () => ErrorCodeSchema,
|
|
155
156
|
Event: () => Event,
|
|
@@ -199,7 +200,10 @@ __export(index_exports, {
|
|
|
199
200
|
InviteListQuery: () => InviteListQuery,
|
|
200
201
|
InviteStatus: () => InviteStatus,
|
|
201
202
|
JsonValue: () => JsonValue,
|
|
203
|
+
LETTER_RECIPIENT_REFUSAL: () => LETTER_RECIPIENT_REFUSAL,
|
|
202
204
|
LIST_UNSUBSCRIBE_POST_VALUE: () => LIST_UNSUBSCRIBE_POST_VALUE,
|
|
205
|
+
LOCALE_TAG_PATTERN: () => LOCALE_TAG_PATTERN,
|
|
206
|
+
LocaleTag: () => LocaleTag,
|
|
203
207
|
MAILING_ACTIONS: () => MAILING_ACTIONS,
|
|
204
208
|
MAILING_KINDS: () => MAILING_KINDS,
|
|
205
209
|
MAILING_STATUSES: () => MAILING_STATUSES,
|
|
@@ -217,18 +221,22 @@ __export(index_exports, {
|
|
|
217
221
|
MAX_IMPORT_URL_LENGTH: () => MAX_IMPORT_URL_LENGTH,
|
|
218
222
|
MAX_INVITE_TTL_DAYS: () => MAX_INVITE_TTL_DAYS,
|
|
219
223
|
MAX_IN_LIST: () => MAX_IN_LIST,
|
|
224
|
+
MAX_LETTER_RECIPIENTS: () => MAX_LETTER_RECIPIENTS,
|
|
220
225
|
MAX_MERGE_DEFAULTS: () => MAX_MERGE_DEFAULTS,
|
|
221
226
|
MAX_MERGE_DEFAULT_LENGTH: () => MAX_MERGE_DEFAULT_LENGTH,
|
|
222
227
|
MAX_MJML_DEPTH: () => MAX_MJML_DEPTH,
|
|
223
228
|
MAX_MJML_ELEMENTS: () => MAX_MJML_ELEMENTS,
|
|
224
229
|
MAX_MJML_IMPORT_BYTES: () => MAX_MJML_IMPORT_BYTES,
|
|
225
230
|
MAX_PAGE_LIMIT: () => MAX_PAGE_LIMIT,
|
|
231
|
+
MAX_PREHEADER_LENGTH: () => MAX_PREHEADER_LENGTH,
|
|
226
232
|
MAX_RECIPIENTS_PER_BATCH: () => MAX_RECIPIENTS_PER_BATCH,
|
|
227
233
|
MAX_RE_ENTRY_COOLDOWN_SECONDS: () => MAX_RE_ENTRY_COOLDOWN_SECONDS,
|
|
228
234
|
MAX_SAVED_SECTIONS: () => MAX_SAVED_SECTIONS,
|
|
229
235
|
MAX_SPLIT_BRANCHES: () => MAX_SPLIT_BRANCHES,
|
|
230
236
|
MAX_STEPS: () => MAX_STEPS,
|
|
231
237
|
MAX_STEP_VISITS: () => MAX_STEP_VISITS,
|
|
238
|
+
MAX_SUBJECT_LENGTH: () => MAX_SUBJECT_LENGTH,
|
|
239
|
+
MAX_TEMPLATE_TRANSLATIONS: () => MAX_TEMPLATE_TRANSLATIONS,
|
|
232
240
|
MAX_TRIGGERS: () => MAX_TRIGGERS,
|
|
233
241
|
MEMBER_ROLES: () => MEMBER_ROLES,
|
|
234
242
|
MERGE_FIELD_PATTERN: () => MERGE_FIELD_PATTERN,
|
|
@@ -246,6 +254,9 @@ __export(index_exports, {
|
|
|
246
254
|
MailingExportQuery: () => MailingExportQuery,
|
|
247
255
|
MailingFinishedData: () => MailingFinishedData,
|
|
248
256
|
MailingKind: () => MailingKind,
|
|
257
|
+
MailingLanguage: () => MailingLanguage,
|
|
258
|
+
MailingLanguageReport: () => MailingLanguageReport,
|
|
259
|
+
MailingLanguageStatus: () => MailingLanguageStatus,
|
|
249
260
|
MailingListQuery: () => MailingListQuery,
|
|
250
261
|
MailingMetadata: () => MailingMetadata,
|
|
251
262
|
MailingRetryFailedRequest: () => MailingRetryFailedRequest,
|
|
@@ -346,6 +357,7 @@ __export(index_exports, {
|
|
|
346
357
|
SuppressionCreate: () => SuppressionCreate,
|
|
347
358
|
SuppressionListQuery: () => SuppressionListQuery,
|
|
348
359
|
SuppressionReason: () => SuppressionReason,
|
|
360
|
+
TEMPLATE_LANGUAGE_STATUSES: () => TEMPLATE_LANGUAGE_STATUSES,
|
|
349
361
|
TERMINAL_MAILING_STATUSES: () => TERMINAL_MAILING_STATUSES,
|
|
350
362
|
Tag: () => Tag,
|
|
351
363
|
TagAssignment: () => TagAssignment,
|
|
@@ -361,8 +373,13 @@ __export(index_exports, {
|
|
|
361
373
|
TemplateImportPreview: () => TemplateImportPreview,
|
|
362
374
|
TemplateImportPreviewRequest: () => TemplateImportPreviewRequest,
|
|
363
375
|
TemplateImportResult: () => TemplateImportResult,
|
|
376
|
+
TemplateLanguageStatus: () => TemplateLanguageStatus,
|
|
364
377
|
TemplateListQuery: () => TemplateListQuery,
|
|
378
|
+
TemplatePreheader: () => TemplatePreheader,
|
|
379
|
+
TemplateSubject: () => TemplateSubject,
|
|
365
380
|
TemplateSummary: () => TemplateSummary,
|
|
381
|
+
TemplateTranslation: () => TemplateTranslation,
|
|
382
|
+
TemplateTranslations: () => TemplateTranslations,
|
|
366
383
|
TemplateUpdate: () => TemplateUpdate,
|
|
367
384
|
TemplateUpdatedData: () => TemplateUpdatedData,
|
|
368
385
|
TemplateVersion: () => TemplateVersion,
|
|
@@ -415,14 +432,22 @@ __export(index_exports, {
|
|
|
415
432
|
WorkspaceSettings: () => WorkspaceSettings,
|
|
416
433
|
WorkspaceUpdate: () => WorkspaceUpdate,
|
|
417
434
|
acceptsIdempotencyKey: () => acceptsIdempotencyKey,
|
|
435
|
+
addLanguageDraft: () => addLanguageDraft,
|
|
418
436
|
alwaysWaits: () => alwaysWaits,
|
|
419
437
|
automationFilterFamily: () => automationFilterFamily,
|
|
420
438
|
automationRoutes: () => automationRoutes,
|
|
421
439
|
billingRoutes: () => billingRoutes,
|
|
422
440
|
buildPath: () => buildPath,
|
|
441
|
+
buildTemplatePatch: () => buildTemplatePatch,
|
|
423
442
|
canTransition: () => canTransition,
|
|
443
|
+
canonicalLocale: () => canonicalLocale,
|
|
424
444
|
cycles: () => cycles,
|
|
425
445
|
defaultSettings: () => defaultSettings,
|
|
446
|
+
draftDocument: () => draftDocument,
|
|
447
|
+
draftsDirty: () => draftsDirty,
|
|
448
|
+
draftsFromTemplate: () => draftsFromTemplate,
|
|
449
|
+
draftsPatch: () => draftsPatch,
|
|
450
|
+
editLanguageDraft: () => editLanguageDraft,
|
|
426
451
|
emptyFlow: () => emptyFlow,
|
|
427
452
|
errorBody: () => errorBody,
|
|
428
453
|
exportFilename: () => exportFilename,
|
|
@@ -438,6 +463,10 @@ __export(index_exports, {
|
|
|
438
463
|
isDayEntirelyPast: () => isDayEntirelyPast,
|
|
439
464
|
isPublishable: () => isPublishable,
|
|
440
465
|
isRetryableError: () => isRetryableError,
|
|
466
|
+
keepLanguageDocument: () => keepLanguageDocument,
|
|
467
|
+
languageName: () => languageName,
|
|
468
|
+
languageTabs: () => languageTabs,
|
|
469
|
+
matchLocale: () => matchLocale,
|
|
441
470
|
matchRoute: () => matchRoute,
|
|
442
471
|
missingRequiredMergeFields: () => missingRequiredMergeFields,
|
|
443
472
|
nowSeconds: () => nowSeconds,
|
|
@@ -446,12 +475,19 @@ __export(index_exports, {
|
|
|
446
475
|
parseExportWarningsHeader: () => parseExportWarningsHeader,
|
|
447
476
|
parseUsageWarningHeader: () => parseUsageWarningHeader,
|
|
448
477
|
platformRoutes: () => platformRoutes,
|
|
478
|
+
primaryLanguage: () => primaryLanguage,
|
|
449
479
|
reachable: () => reachable,
|
|
480
|
+
readyWithoutSubject: () => readyWithoutSubject,
|
|
481
|
+
rebaseDrafts: () => rebaseDrafts,
|
|
482
|
+
removeLanguageDraft: () => removeLanguageDraft,
|
|
483
|
+
restorePatch: () => restorePatch,
|
|
450
484
|
routes: () => routes,
|
|
451
485
|
sendingRoutes: () => sendingRoutes,
|
|
486
|
+
setLanguageStatus: () => setLanguageStatus,
|
|
452
487
|
signWebhook: () => signWebhook,
|
|
453
488
|
statusForError: () => statusForError,
|
|
454
489
|
stepTargets: () => stepTargets,
|
|
490
|
+
storedTemplateLine: () => storedTemplateLine,
|
|
455
491
|
stronglyConnected: () => stronglyConnected,
|
|
456
492
|
templateRoutes: () => templateRoutes,
|
|
457
493
|
testGroupSize: () => testGroupSize,
|
|
@@ -487,6 +523,29 @@ function page(item) {
|
|
|
487
523
|
}
|
|
488
524
|
var IdParams = import_zod.z.object({ id: Id });
|
|
489
525
|
var Ok = import_zod.z.object({ ok: import_zod.z.literal(true) });
|
|
526
|
+
var LOCALE_TAG_PATTERN = /^[A-Za-z]{2,3}(?:-[A-Za-z]{4})?(?:-(?:[A-Za-z]{2}|[0-9]{3}))?$/;
|
|
527
|
+
var LocaleTag = import_zod.z.string().min(2).max(35).regex(LOCALE_TAG_PATTERN, "a language tag such as en, fr or pt-BR");
|
|
528
|
+
function canonicalLocale(tag) {
|
|
529
|
+
if (typeof tag !== "string") return null;
|
|
530
|
+
const trimmed = tag.trim().replace(/_/g, "-");
|
|
531
|
+
if (!LOCALE_TAG_PATTERN.test(trimmed)) return null;
|
|
532
|
+
return trimmed.split("-").map((part, i) => {
|
|
533
|
+
if (i === 0) return part.toLowerCase();
|
|
534
|
+
if (part.length === 4) return part[0].toUpperCase() + part.slice(1).toLowerCase();
|
|
535
|
+
return part.toUpperCase();
|
|
536
|
+
}).join("-");
|
|
537
|
+
}
|
|
538
|
+
function primaryLanguage(tag) {
|
|
539
|
+
return canonicalLocale(tag)?.split("-")[0] ?? null;
|
|
540
|
+
}
|
|
541
|
+
function matchLocale(wanted, available) {
|
|
542
|
+
const canonical = canonicalLocale(wanted);
|
|
543
|
+
if (!canonical) return null;
|
|
544
|
+
const exact = available.find((a) => canonicalLocale(a) === canonical);
|
|
545
|
+
if (exact !== void 0) return exact;
|
|
546
|
+
const primary = canonical.split("-")[0];
|
|
547
|
+
return available.find((a) => primaryLanguage(a) === primary) ?? null;
|
|
548
|
+
}
|
|
490
549
|
|
|
491
550
|
// src/errors.ts
|
|
492
551
|
var import_zod2 = require("zod");
|
|
@@ -602,32 +661,71 @@ var TemplateDocument = import_zod3.z.object({
|
|
|
602
661
|
sections: import_zod3.z.array(import_zod3.z.record(import_zod3.z.unknown()))
|
|
603
662
|
}).passthrough();
|
|
604
663
|
var MAX_DOCUMENT_BYTES = 1e6;
|
|
664
|
+
var MAX_SUBJECT_LENGTH = 998;
|
|
665
|
+
var MAX_PREHEADER_LENGTH = 500;
|
|
666
|
+
var TemplateSubject = import_zod3.z.string().max(MAX_SUBJECT_LENGTH).regex(/^[^\x00-\x1f\x7f]*$/, "one line, without control characters");
|
|
667
|
+
var TemplatePreheader = import_zod3.z.string().max(MAX_PREHEADER_LENGTH).regex(/^[^\x00-\x1f\x7f]*$/, "one line, without control characters");
|
|
668
|
+
var TEMPLATE_LANGUAGE_STATUSES = ["draft", "ready"];
|
|
669
|
+
var TemplateLanguageStatus = import_zod3.z.enum(TEMPLATE_LANGUAGE_STATUSES);
|
|
670
|
+
var TemplateTranslation = import_zod3.z.object({
|
|
671
|
+
subject: TemplateSubject.nullable(),
|
|
672
|
+
preheader: TemplatePreheader.nullable(),
|
|
673
|
+
document: TemplateDocument,
|
|
674
|
+
status: TemplateLanguageStatus
|
|
675
|
+
});
|
|
676
|
+
var MAX_TEMPLATE_TRANSLATIONS = 19;
|
|
677
|
+
var TemplateTranslations = import_zod3.z.record(LocaleTag, TemplateTranslation).refine((t) => Object.keys(t).length <= MAX_TEMPLATE_TRANSLATIONS, `at most ${MAX_TEMPLATE_TRANSLATIONS} language versions`);
|
|
605
678
|
var Template = import_zod3.z.object({
|
|
606
679
|
id: Id,
|
|
607
680
|
name: import_zod3.z.string().min(1).max(200),
|
|
608
681
|
description: import_zod3.z.string().max(2e3).nullable(),
|
|
682
|
+
/**
|
|
683
|
+
* The main language: what `subject`, `preheader` and `document` are written
|
|
684
|
+
* in, and what every recipient without a ready version of their own gets.
|
|
685
|
+
* Set from the workspace's `default_locale` when the template is created
|
|
686
|
+
* unless given, and never changed by a later change of that setting.
|
|
687
|
+
*/
|
|
688
|
+
locale: LocaleTag,
|
|
689
|
+
/** The main language's subject line; null when the mailing that uses the template gives one. */
|
|
690
|
+
subject: TemplateSubject.nullable(),
|
|
691
|
+
preheader: TemplatePreheader.nullable(),
|
|
609
692
|
document: TemplateDocument,
|
|
610
|
-
/**
|
|
693
|
+
/**
|
|
694
|
+
* The other languages. A version whose language the workspace no longer
|
|
695
|
+
* lists is kept, but no send uses it until the language is listed again.
|
|
696
|
+
*/
|
|
697
|
+
translations: TemplateTranslations,
|
|
698
|
+
/** Increments on every saved change, of any language. */
|
|
611
699
|
version: import_zod3.z.number().int().min(1),
|
|
612
700
|
thumbnail_url: import_zod3.z.string().url().nullable(),
|
|
613
701
|
archived_at: Timestamp.nullable(),
|
|
614
702
|
created_at: Timestamp,
|
|
615
703
|
updated_at: Timestamp
|
|
616
704
|
});
|
|
617
|
-
var TemplateSummary = Template.omit({ document: true })
|
|
705
|
+
var TemplateSummary = Template.omit({ document: true, translations: true }).extend({
|
|
706
|
+
languages: import_zod3.z.record(LocaleTag, TemplateLanguageStatus)
|
|
707
|
+
});
|
|
618
708
|
var TemplateCreate = import_zod3.z.object({
|
|
619
709
|
name: import_zod3.z.string().min(1).max(200),
|
|
620
710
|
description: import_zod3.z.string().max(2e3).optional(),
|
|
621
|
-
|
|
711
|
+
locale: LocaleTag.optional(),
|
|
712
|
+
subject: TemplateSubject.nullable().optional(),
|
|
713
|
+
preheader: TemplatePreheader.nullable().optional(),
|
|
714
|
+
document: TemplateDocument,
|
|
715
|
+
translations: TemplateTranslations.optional()
|
|
622
716
|
});
|
|
623
717
|
var TemplateUpdate = import_zod3.z.object({
|
|
624
718
|
base_version: import_zod3.z.number().int().min(1),
|
|
625
719
|
name: import_zod3.z.string().min(1).max(200).optional(),
|
|
626
720
|
description: import_zod3.z.string().max(2e3).nullable().optional(),
|
|
721
|
+
locale: LocaleTag.optional(),
|
|
722
|
+
subject: TemplateSubject.nullable().optional(),
|
|
723
|
+
preheader: TemplatePreheader.nullable().optional(),
|
|
627
724
|
document: TemplateDocument.optional(),
|
|
725
|
+
translations: import_zod3.z.record(LocaleTag, TemplateTranslation.nullable()).optional(),
|
|
628
726
|
archived: import_zod3.z.boolean().optional()
|
|
629
727
|
}).refine(
|
|
630
|
-
(v) => v.name !== void 0 || v.description !== void 0 || v.document !== void 0 || v.archived !== void 0,
|
|
728
|
+
(v) => v.name !== void 0 || v.description !== void 0 || v.locale !== void 0 || v.subject !== void 0 || v.preheader !== void 0 || v.document !== void 0 || v.translations !== void 0 || v.archived !== void 0,
|
|
631
729
|
"at least one field besides base_version"
|
|
632
730
|
);
|
|
633
731
|
var SavedSectionBody = import_zod3.z.record(import_zod3.z.unknown());
|
|
@@ -657,7 +755,11 @@ var TemplateListQuery = PageQuery.extend({
|
|
|
657
755
|
var TemplateVersion = import_zod3.z.object({
|
|
658
756
|
template_id: Id,
|
|
659
757
|
version: import_zod3.z.number().int().min(1),
|
|
758
|
+
locale: LocaleTag,
|
|
759
|
+
subject: TemplateSubject.nullable(),
|
|
760
|
+
preheader: TemplatePreheader.nullable(),
|
|
660
761
|
document: TemplateDocument,
|
|
762
|
+
translations: TemplateTranslations,
|
|
661
763
|
created_by: import_zod3.z.string().nullable(),
|
|
662
764
|
created_at: Timestamp
|
|
663
765
|
});
|
|
@@ -678,7 +780,8 @@ var CompileResult = import_zod3.z.object({
|
|
|
678
780
|
errors: import_zod3.z.array(CompileMessage)
|
|
679
781
|
});
|
|
680
782
|
var TemplateCompileRequest = import_zod3.z.object({
|
|
681
|
-
version: import_zod3.z.number().int().min(1).optional()
|
|
783
|
+
version: import_zod3.z.number().int().min(1).optional(),
|
|
784
|
+
locale: LocaleTag.optional()
|
|
682
785
|
});
|
|
683
786
|
var CompileRequest = import_zod3.z.object({
|
|
684
787
|
document: TemplateDocument
|
|
@@ -770,7 +873,8 @@ var EXPORT_FORMATS = ["mjml", "html"];
|
|
|
770
873
|
var ExportFormat = import_zod3.z.enum(EXPORT_FORMATS);
|
|
771
874
|
var TemplateExportQuery = import_zod3.z.object({
|
|
772
875
|
format: ExportFormat,
|
|
773
|
-
version: import_zod3.z.coerce.number().int().min(1).optional()
|
|
876
|
+
version: import_zod3.z.coerce.number().int().min(1).optional(),
|
|
877
|
+
locale: LocaleTag.optional()
|
|
774
878
|
});
|
|
775
879
|
var MailingExportQuery = import_zod3.z.object({ format: ExportFormat });
|
|
776
880
|
var EXPORT_CONTENT_TYPES = {
|
|
@@ -901,10 +1005,35 @@ var Mailing = import_zod5.z.object({
|
|
|
901
1005
|
name: import_zod5.z.string().max(200).nullable(),
|
|
902
1006
|
subject: import_zod5.z.string().min(1).max(998),
|
|
903
1007
|
preheader: import_zod5.z.string().max(500).nullable(),
|
|
904
|
-
/**
|
|
1008
|
+
/**
|
|
1009
|
+
* The template the document was taken from, if any. The snapshot is what is
|
|
1010
|
+
* sent in the main language; the template's other language versions are
|
|
1011
|
+
* taken, the ready ones, when the mailing starts (see "Languages" in the
|
|
1012
|
+
* contract's documentation).
|
|
1013
|
+
*/
|
|
905
1014
|
template_id: Id.nullable(),
|
|
906
1015
|
document: TemplateDocument,
|
|
907
|
-
|
|
1016
|
+
/**
|
|
1017
|
+
* The main language: what `subject`, `preheader` and `document` are written
|
|
1018
|
+
* in, and what every recipient without a ready version in their own language
|
|
1019
|
+
* gets. The template's main language, or the workspace's default for a
|
|
1020
|
+
* mailing made from a document.
|
|
1021
|
+
*/
|
|
1022
|
+
locale: LocaleTag,
|
|
1023
|
+
/**
|
|
1024
|
+
* The language every recipient is treated as reading, or null to read each
|
|
1025
|
+
* recipient's own (their `merge.locale`, else their contact's language). A
|
|
1026
|
+
* letter sets it to the language its one reader wrote in; a broadcast can use
|
|
1027
|
+
* it to send one language version to everyone. It is matched like anyone's
|
|
1028
|
+
* language: without a ready version in it, the main language goes out.
|
|
1029
|
+
*/
|
|
1030
|
+
send_locale: LocaleTag.nullable(),
|
|
1031
|
+
/**
|
|
1032
|
+
* The topic the mailing is sent under. Null for a letter (a one-to-one
|
|
1033
|
+
* mailing with at most one recipient, which belongs to no topic and whose
|
|
1034
|
+
* unsubscribe link offers every topic) and for an automation's notification.
|
|
1035
|
+
*/
|
|
1036
|
+
topic: Slug.nullable(),
|
|
908
1037
|
provider_id: Id,
|
|
909
1038
|
status: MailingStatus,
|
|
910
1039
|
counts: MailingCounts,
|
|
@@ -929,23 +1058,37 @@ var MailingContent = {
|
|
|
929
1058
|
name: import_zod5.z.string().max(200).optional(),
|
|
930
1059
|
subject: import_zod5.z.string().min(1).max(998),
|
|
931
1060
|
preheader: import_zod5.z.string().max(500).optional(),
|
|
932
|
-
|
|
1061
|
+
/** See `Mailing.send_locale`. */
|
|
1062
|
+
send_locale: LocaleTag.nullable().optional(),
|
|
1063
|
+
/**
|
|
1064
|
+
* Omitted or null makes the mailing a letter: one recipient at most, sent to
|
|
1065
|
+
* anybody not blocked on every topic, with an unsubscribe link that offers
|
|
1066
|
+
* every topic and no List-Unsubscribe headers. See "Letters" in the
|
|
1067
|
+
* contract's documentation.
|
|
1068
|
+
*/
|
|
1069
|
+
topic: Slug.nullable().optional(),
|
|
933
1070
|
provider_id: Id,
|
|
934
1071
|
metadata: MailingMetadata.optional()
|
|
935
1072
|
};
|
|
936
1073
|
var MailingCreate = import_zod5.z.object({
|
|
937
1074
|
...MailingContent,
|
|
1075
|
+
subject: MailingContent.subject.optional(),
|
|
938
1076
|
document: TemplateDocument.optional(),
|
|
939
1077
|
template_id: Id.optional()
|
|
940
1078
|
}).refine((v) => v.document === void 0 !== (v.template_id === void 0), {
|
|
941
1079
|
message: "exactly one of document or template_id",
|
|
942
1080
|
path: ["document"]
|
|
1081
|
+
}).refine((v) => v.template_id !== void 0 || v.subject !== void 0, {
|
|
1082
|
+
message: "a mailing made from a document needs a subject",
|
|
1083
|
+
path: ["subject"]
|
|
943
1084
|
});
|
|
944
1085
|
var MailingUpdate = import_zod5.z.object({
|
|
945
1086
|
name: import_zod5.z.string().max(200).nullable().optional(),
|
|
946
1087
|
subject: MailingContent.subject.optional(),
|
|
947
1088
|
preheader: import_zod5.z.string().max(500).nullable().optional(),
|
|
948
|
-
|
|
1089
|
+
/** Null turns a draft into a letter, which it can only be with at most one recipient. */
|
|
1090
|
+
topic: Slug.nullable().optional(),
|
|
1091
|
+
send_locale: LocaleTag.nullable().optional(),
|
|
949
1092
|
provider_id: Id.optional(),
|
|
950
1093
|
metadata: MailingMetadata.optional(),
|
|
951
1094
|
document: TemplateDocument.optional()
|
|
@@ -968,7 +1111,8 @@ var MailingRetryFailedRequest = import_zod5.z.object({
|
|
|
968
1111
|
var MailingActionRequest = import_zod5.z.object({}).strict();
|
|
969
1112
|
var MailingTestRequest = import_zod5.z.object({
|
|
970
1113
|
to: Email,
|
|
971
|
-
merge: Properties.optional()
|
|
1114
|
+
merge: Properties.optional(),
|
|
1115
|
+
locale: LocaleTag.optional()
|
|
972
1116
|
});
|
|
973
1117
|
var MailingTestResult = import_zod5.z.object({
|
|
974
1118
|
message_id: Id,
|
|
@@ -993,6 +1137,8 @@ var Recipient = import_zod5.z.object({
|
|
|
993
1137
|
updated_at: Timestamp
|
|
994
1138
|
});
|
|
995
1139
|
var MAX_RECIPIENTS_PER_BATCH = 1e3;
|
|
1140
|
+
var MAX_LETTER_RECIPIENTS = 1;
|
|
1141
|
+
var LETTER_RECIPIENT_REFUSAL = "letter_has_one_recipient";
|
|
996
1142
|
var RecipientInput = import_zod5.z.object({
|
|
997
1143
|
contact_id: Id.optional(),
|
|
998
1144
|
external_id: import_zod5.z.string().min(1).max(255).optional(),
|
|
@@ -1033,9 +1179,27 @@ var MessageSummary = import_zod5.z.object({
|
|
|
1033
1179
|
error: import_zod5.z.string().nullable(),
|
|
1034
1180
|
is_test: import_zod5.z.boolean(),
|
|
1035
1181
|
recipient_count: import_zod5.z.number().int().min(1),
|
|
1182
|
+
/** The language version the message was sent in; null for messages archived before languages existed. */
|
|
1183
|
+
locale: LocaleTag.nullable(),
|
|
1036
1184
|
created_at: Timestamp
|
|
1037
1185
|
});
|
|
1038
1186
|
var Message = MessageSummary.extend({ html: import_zod5.z.string() });
|
|
1187
|
+
var MailingLanguageStatus = import_zod5.z.enum(["main", "ready", "draft", "not_a_workspace_language"]);
|
|
1188
|
+
var MailingLanguage = import_zod5.z.object({
|
|
1189
|
+
locale: LocaleTag,
|
|
1190
|
+
status: MailingLanguageStatus,
|
|
1191
|
+
/** Queued recipients who will get this version. */
|
|
1192
|
+
planned: import_zod5.z.number().int().min(0),
|
|
1193
|
+
/** Messages already sent in this language (tests excluded). */
|
|
1194
|
+
sent: import_zod5.z.number().int().min(0)
|
|
1195
|
+
});
|
|
1196
|
+
var MailingLanguageReport = import_zod5.z.object({
|
|
1197
|
+
main_locale: LocaleTag,
|
|
1198
|
+
send_locale: LocaleTag.nullable(),
|
|
1199
|
+
languages: import_zod5.z.array(MailingLanguage),
|
|
1200
|
+
fallback: import_zod5.z.array(import_zod5.z.object({ wanted: import_zod5.z.string(), planned: import_zod5.z.number().int().min(1) })),
|
|
1201
|
+
no_language: import_zod5.z.number().int().min(0)
|
|
1202
|
+
});
|
|
1039
1203
|
var MessageListQuery = PageQuery.extend({
|
|
1040
1204
|
mailing_id: Id.optional(),
|
|
1041
1205
|
outcome: MessageOutcome.optional()
|
|
@@ -1545,15 +1709,22 @@ var Unchosen = import_zod7.z.literal("");
|
|
|
1545
1709
|
var DraftSlug = import_zod7.z.union([Slug, Unchosen]);
|
|
1546
1710
|
var DraftPropertyKey = import_zod7.z.union([ContactPropertyKey, Unchosen]);
|
|
1547
1711
|
var label = { label: import_zod7.z.string().max(120).nullish() };
|
|
1712
|
+
var EmailStepLanguage = import_zod7.z.object({
|
|
1713
|
+
subject: import_zod7.z.string().min(1).max(998),
|
|
1714
|
+
preheader: import_zod7.z.string().max(500).nullable(),
|
|
1715
|
+
document: TemplateDocument
|
|
1716
|
+
}).strict();
|
|
1548
1717
|
var EmailStep = import_zod7.z.object({
|
|
1549
1718
|
kind: import_zod7.z.literal("email"),
|
|
1550
1719
|
...label,
|
|
1551
1720
|
...next,
|
|
1552
1721
|
template_id: Id.nullish(),
|
|
1553
1722
|
document: TemplateDocument.nullish(),
|
|
1554
|
-
/** Empty while the step is being written; `not_chosen` refuses to publish it. */
|
|
1723
|
+
/** Empty while the step is being written, or when its template has a subject; else `not_chosen` refuses to publish it. */
|
|
1555
1724
|
subject: import_zod7.z.string().max(998),
|
|
1556
|
-
preheader: import_zod7.z.string().max(500).nullish()
|
|
1725
|
+
preheader: import_zod7.z.string().max(500).nullish(),
|
|
1726
|
+
locale: LocaleTag.nullish(),
|
|
1727
|
+
languages: import_zod7.z.record(LocaleTag, EmailStepLanguage).nullish()
|
|
1557
1728
|
}).strict();
|
|
1558
1729
|
var DelayStep = import_zod7.z.object({
|
|
1559
1730
|
kind: import_zod7.z.literal("delay"),
|
|
@@ -1859,7 +2030,7 @@ function validateAutomation(flow, settings, ctx) {
|
|
|
1859
2030
|
if (!step.template_id && !step.document) {
|
|
1860
2031
|
add({ code: "empty_email", step_id: id, path: [...path, "template_id"], message: "This email has neither a template nor content." });
|
|
1861
2032
|
}
|
|
1862
|
-
if (step.subject.trim() === "") {
|
|
2033
|
+
if (step.subject.trim() === "" && !(step.template_id && known.templates_with_subject?.has(step.template_id))) {
|
|
1863
2034
|
add({ code: "not_chosen", step_id: id, path: [...path, "subject"], message: "This email has no subject line." });
|
|
1864
2035
|
}
|
|
1865
2036
|
if (step.template_id) checkRef(known.templates, step.template_id, "template", [...path, "template_id"], add, id);
|
|
@@ -2344,7 +2515,7 @@ var AutomationReport = import_zod7.z.object({
|
|
|
2344
2515
|
var AutomationExitRunRequest = import_zod7.z.object({ reason: import_zod7.z.string().max(200).optional() }).strict();
|
|
2345
2516
|
var AutomationRunParams = import_zod7.z.object({ id: Id, run_id: Id });
|
|
2346
2517
|
var AutomationStepParams = import_zod7.z.object({ id: Id, step_id: StepId });
|
|
2347
|
-
var AutomationTestEmailRequest = import_zod7.z.object({ to: Email, merge: Properties.optional() }).strict();
|
|
2518
|
+
var AutomationTestEmailRequest = import_zod7.z.object({ to: Email, merge: Properties.optional(), locale: LocaleTag.optional() }).strict();
|
|
2348
2519
|
var AutomationValidateRequest = import_zod7.z.object({ flow: AutomationFlow.optional(), settings: AutomationSettings.partial().optional() }).strict();
|
|
2349
2520
|
var EventCreate = import_zod7.z.object({
|
|
2350
2521
|
name: EventName,
|
|
@@ -2413,10 +2584,19 @@ var MergeDefaults = import_zod8.z.record(MergeFieldName, MergeDefaultValue).refi
|
|
|
2413
2584
|
message: `a reserved merge field (${Object.keys(RESERVED_MERGE_FIELDS).join(", ")}) cannot have a workspace default`
|
|
2414
2585
|
});
|
|
2415
2586
|
var WorkspaceSettings = import_zod8.z.object({
|
|
2416
|
-
/**
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2587
|
+
/**
|
|
2588
|
+
* The workspace's main language (a {@link LocaleTag}, e.g. "de"): the main
|
|
2589
|
+
* language of a new template, and of the hosted pages when nothing else
|
|
2590
|
+
* decides.
|
|
2591
|
+
*/
|
|
2592
|
+
default_locale: LocaleTag,
|
|
2593
|
+
/**
|
|
2594
|
+
* The languages the workspace writes in, including `default_locale`, none
|
|
2595
|
+
* twice (compared without regard to casing). A template can have a version in
|
|
2596
|
+
* each; the hosted pages are offered in those of them they support (English,
|
|
2597
|
+
* German, French, Italian, Spanish). The service stores canonical casing.
|
|
2598
|
+
*/
|
|
2599
|
+
locales: import_zod8.z.array(LocaleTag).min(1).max(20).refine((l) => new Set(l.map((t) => t.toLowerCase())).size === l.length, "a language appears twice"),
|
|
2420
2600
|
/** Open and click tracking. Off by default, opt-in per workspace. */
|
|
2421
2601
|
tracking_enabled: import_zod8.z.boolean(),
|
|
2422
2602
|
/** Where images, stylesheets and fonts in a mail may load from. `any` by default. */
|
|
@@ -2530,6 +2710,7 @@ var AUDIT_ACTIONS = [
|
|
|
2530
2710
|
"provider.anomaly_cleared",
|
|
2531
2711
|
"topic.created",
|
|
2532
2712
|
"topic.updated",
|
|
2713
|
+
"topic.deleted",
|
|
2533
2714
|
"template.created",
|
|
2534
2715
|
"template.updated",
|
|
2535
2716
|
"template.deleted",
|
|
@@ -2667,6 +2848,200 @@ var InviteAccepted = import_zod9.z.object({
|
|
|
2667
2848
|
});
|
|
2668
2849
|
var INVITE_REFUSAL_REASONS = ["email_mismatch", "inviter_lacks_role", "expired", "revoked", "accepted"];
|
|
2669
2850
|
|
|
2851
|
+
// src/template-languages.ts
|
|
2852
|
+
function languageTabs(mainLocale, versions, workspaceLocales) {
|
|
2853
|
+
const main = canonicalLocale(mainLocale) ?? mainLocale;
|
|
2854
|
+
const statuses = /* @__PURE__ */ new Map();
|
|
2855
|
+
for (const [tag, status] of Object.entries(versions)) {
|
|
2856
|
+
const canonical = canonicalLocale(tag) ?? tag;
|
|
2857
|
+
if (canonical !== main) statuses.set(canonical, status);
|
|
2858
|
+
}
|
|
2859
|
+
const tabs = [{ locale: main, kind: "main", status: "ready" }];
|
|
2860
|
+
const seen = /* @__PURE__ */ new Set([main]);
|
|
2861
|
+
for (const tag of workspaceLocales) {
|
|
2862
|
+
const canonical = canonicalLocale(tag) ?? tag;
|
|
2863
|
+
if (seen.has(canonical)) continue;
|
|
2864
|
+
seen.add(canonical);
|
|
2865
|
+
tabs.push({ locale: canonical, kind: "translation", status: statuses.get(canonical) ?? "missing" });
|
|
2866
|
+
}
|
|
2867
|
+
const kept = [...statuses.keys()].filter((tag) => !seen.has(tag)).sort();
|
|
2868
|
+
for (const tag of kept) tabs.push({ locale: tag, kind: "kept", status: statuses.get(tag) });
|
|
2869
|
+
return tabs;
|
|
2870
|
+
}
|
|
2871
|
+
function languageName(tag) {
|
|
2872
|
+
const canonical = canonicalLocale(tag) ?? tag;
|
|
2873
|
+
try {
|
|
2874
|
+
const names = new Intl.DisplayNames(["en"], { type: "language", fallback: "none" });
|
|
2875
|
+
const name = names.of(canonical);
|
|
2876
|
+
return name && name !== canonical ? name : canonical;
|
|
2877
|
+
} catch {
|
|
2878
|
+
return canonical;
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
function storedTemplateLine(value) {
|
|
2882
|
+
if (value === null || value === void 0) return null;
|
|
2883
|
+
const trimmed = value.trim();
|
|
2884
|
+
return trimmed === "" ? null : trimmed;
|
|
2885
|
+
}
|
|
2886
|
+
function buildTemplatePatch(args) {
|
|
2887
|
+
const { loaded, main, documentChanged, translations, changed, removed } = args;
|
|
2888
|
+
const out = {};
|
|
2889
|
+
const subject = storedTemplateLine(main.subject);
|
|
2890
|
+
if (subject !== storedTemplateLine(loaded.subject)) out.subject = subject;
|
|
2891
|
+
const preheader = storedTemplateLine(main.preheader);
|
|
2892
|
+
if (preheader !== storedTemplateLine(loaded.preheader)) out.preheader = preheader;
|
|
2893
|
+
if (documentChanged) out.document = main.document;
|
|
2894
|
+
const patch = {};
|
|
2895
|
+
for (const tag of changed) {
|
|
2896
|
+
const version = translations[tag];
|
|
2897
|
+
if (version && !removed.has(tag)) {
|
|
2898
|
+
patch[tag] = { subject: storedTemplateLine(version.subject), preheader: storedTemplateLine(version.preheader), document: version.document, status: version.status };
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
for (const tag of removed) {
|
|
2902
|
+
if (Object.prototype.hasOwnProperty.call(loaded.translations, tag)) patch[tag] = null;
|
|
2903
|
+
}
|
|
2904
|
+
if (Object.keys(patch).length > 0) out.translations = patch;
|
|
2905
|
+
return out;
|
|
2906
|
+
}
|
|
2907
|
+
function restorePatch(old, current, workspaceLocales) {
|
|
2908
|
+
const oldMain = canonicalLocale(old.locale) ?? old.locale;
|
|
2909
|
+
const listed = workspaceLocales ? new Set(workspaceLocales.map((t) => canonicalLocale(t) ?? t)) : null;
|
|
2910
|
+
const patch = {};
|
|
2911
|
+
const skipped = [];
|
|
2912
|
+
const untouched = /* @__PURE__ */ new Set();
|
|
2913
|
+
for (const [tag, version] of Object.entries(old.translations)) {
|
|
2914
|
+
const canonical = canonicalLocale(tag) ?? tag;
|
|
2915
|
+
if (canonical === oldMain) continue;
|
|
2916
|
+
if (listed && !listed.has(canonical)) {
|
|
2917
|
+
skipped.push(canonical);
|
|
2918
|
+
untouched.add(canonical);
|
|
2919
|
+
continue;
|
|
2920
|
+
}
|
|
2921
|
+
patch[canonical] = version;
|
|
2922
|
+
}
|
|
2923
|
+
for (const tag of Object.keys(current.translations)) {
|
|
2924
|
+
const canonical = canonicalLocale(tag) ?? tag;
|
|
2925
|
+
if (!(canonical in patch) && !untouched.has(canonical)) patch[canonical] = null;
|
|
2926
|
+
if (canonical === oldMain) patch[canonical] = null;
|
|
2927
|
+
}
|
|
2928
|
+
const update = {
|
|
2929
|
+
...oldMain !== (canonicalLocale(current.locale) ?? current.locale) ? { locale: oldMain } : {},
|
|
2930
|
+
subject: old.subject,
|
|
2931
|
+
preheader: old.preheader,
|
|
2932
|
+
document: old.document,
|
|
2933
|
+
...Object.keys(patch).length > 0 ? { translations: patch } : {}
|
|
2934
|
+
};
|
|
2935
|
+
return { update, skipped: skipped.sort() };
|
|
2936
|
+
}
|
|
2937
|
+
function draftsFromTemplate(template) {
|
|
2938
|
+
const translations = {};
|
|
2939
|
+
for (const [tag, version] of Object.entries(template.translations)) translations[canonicalLocale(tag) ?? tag] = version;
|
|
2940
|
+
return {
|
|
2941
|
+
main: { subject: template.subject ?? "", preheader: template.preheader ?? "", document: template.document },
|
|
2942
|
+
translations,
|
|
2943
|
+
mainDocumentChanged: false,
|
|
2944
|
+
changed: [],
|
|
2945
|
+
removed: []
|
|
2946
|
+
};
|
|
2947
|
+
}
|
|
2948
|
+
var withChanged = (list2, tag) => list2.includes(tag) ? [...list2] : [...list2, tag];
|
|
2949
|
+
var without = (list2, tag) => list2.filter((t) => t !== tag);
|
|
2950
|
+
function draftDocument(drafts, locale) {
|
|
2951
|
+
if (locale === null) return drafts.main.document;
|
|
2952
|
+
return drafts.translations[locale]?.document;
|
|
2953
|
+
}
|
|
2954
|
+
function addLanguageDraft(drafts, locale) {
|
|
2955
|
+
const tag = canonicalLocale(locale) ?? locale;
|
|
2956
|
+
if (drafts.translations[tag]) return drafts;
|
|
2957
|
+
return {
|
|
2958
|
+
...drafts,
|
|
2959
|
+
translations: {
|
|
2960
|
+
...drafts.translations,
|
|
2961
|
+
[tag]: {
|
|
2962
|
+
subject: drafts.main.subject,
|
|
2963
|
+
preheader: drafts.main.preheader,
|
|
2964
|
+
document: structuredClone(drafts.main.document),
|
|
2965
|
+
status: "draft"
|
|
2966
|
+
}
|
|
2967
|
+
},
|
|
2968
|
+
changed: withChanged(drafts.changed, tag),
|
|
2969
|
+
removed: without(drafts.removed, tag)
|
|
2970
|
+
};
|
|
2971
|
+
}
|
|
2972
|
+
function removeLanguageDraft(drafts, locale) {
|
|
2973
|
+
const tag = canonicalLocale(locale) ?? locale;
|
|
2974
|
+
const { [tag]: _gone, ...rest } = drafts.translations;
|
|
2975
|
+
return { ...drafts, translations: rest, changed: without(drafts.changed, tag), removed: withChanged(drafts.removed, tag) };
|
|
2976
|
+
}
|
|
2977
|
+
function editLanguageDraft(drafts, locale, edit) {
|
|
2978
|
+
if (locale === null) {
|
|
2979
|
+
return {
|
|
2980
|
+
...drafts,
|
|
2981
|
+
main: { ...drafts.main, ...edit },
|
|
2982
|
+
mainDocumentChanged: drafts.mainDocumentChanged || edit.document !== void 0
|
|
2983
|
+
};
|
|
2984
|
+
}
|
|
2985
|
+
const version = drafts.translations[locale];
|
|
2986
|
+
if (!version) return drafts;
|
|
2987
|
+
const next2 = { ...version, ...edit };
|
|
2988
|
+
return { ...drafts, translations: { ...drafts.translations, [locale]: next2 }, changed: withChanged(drafts.changed, locale) };
|
|
2989
|
+
}
|
|
2990
|
+
function keepLanguageDocument(drafts, locale, document) {
|
|
2991
|
+
if (locale === null) return { ...drafts, main: { ...drafts.main, document } };
|
|
2992
|
+
const version = drafts.translations[locale];
|
|
2993
|
+
if (!version) return drafts;
|
|
2994
|
+
return { ...drafts, translations: { ...drafts.translations, [locale]: { ...version, document } } };
|
|
2995
|
+
}
|
|
2996
|
+
function setLanguageStatus(drafts, locale, status) {
|
|
2997
|
+
const version = drafts.translations[locale];
|
|
2998
|
+
if (!version || version.status === status) return drafts;
|
|
2999
|
+
return { ...drafts, translations: { ...drafts.translations, [locale]: { ...version, status } }, changed: withChanged(drafts.changed, locale) };
|
|
3000
|
+
}
|
|
3001
|
+
function draftsPatch(drafts, loaded) {
|
|
3002
|
+
return buildTemplatePatch({
|
|
3003
|
+
loaded,
|
|
3004
|
+
main: drafts.main,
|
|
3005
|
+
documentChanged: drafts.mainDocumentChanged,
|
|
3006
|
+
translations: drafts.translations,
|
|
3007
|
+
changed: new Set(drafts.changed),
|
|
3008
|
+
removed: new Set(drafts.removed)
|
|
3009
|
+
});
|
|
3010
|
+
}
|
|
3011
|
+
function draftsDirty(drafts, loaded) {
|
|
3012
|
+
return Object.keys(draftsPatch(drafts, loaded)).length > 0;
|
|
3013
|
+
}
|
|
3014
|
+
function readyWithoutSubject(drafts) {
|
|
3015
|
+
return Object.entries(drafts.translations).filter(([tag, v]) => drafts.changed.includes(tag) && v.status === "ready" && storedTemplateLine(v.subject) === null).map(([tag]) => tag);
|
|
3016
|
+
}
|
|
3017
|
+
function rebaseDrafts(sent, now, saved) {
|
|
3018
|
+
const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
3019
|
+
let out = draftsFromTemplate(saved);
|
|
3020
|
+
if (now.main.subject !== sent.main.subject) out = editLanguageDraft(out, null, { subject: now.main.subject });
|
|
3021
|
+
if (now.main.preheader !== sent.main.preheader) out = editLanguageDraft(out, null, { preheader: now.main.preheader });
|
|
3022
|
+
out = same(now.main.document, sent.main.document) ? keepLanguageDocument(out, null, now.main.document) : editLanguageDraft(out, null, { document: now.main.document });
|
|
3023
|
+
const tags = /* @__PURE__ */ new Set([...Object.keys(sent.translations), ...Object.keys(now.translations)]);
|
|
3024
|
+
for (const tag of tags) {
|
|
3025
|
+
const before = sent.translations[tag];
|
|
3026
|
+
const after = now.translations[tag];
|
|
3027
|
+
if (same(before, after)) {
|
|
3028
|
+
if (after) out = keepLanguageDocument(out, tag, after.document);
|
|
3029
|
+
continue;
|
|
3030
|
+
}
|
|
3031
|
+
if (!after) {
|
|
3032
|
+
out = removeLanguageDraft(out, tag);
|
|
3033
|
+
continue;
|
|
3034
|
+
}
|
|
3035
|
+
out = {
|
|
3036
|
+
...out,
|
|
3037
|
+
translations: { ...out.translations, [tag]: after },
|
|
3038
|
+
changed: withChanged(out.changed, tag),
|
|
3039
|
+
removed: without(out.removed, tag)
|
|
3040
|
+
};
|
|
3041
|
+
}
|
|
3042
|
+
return out;
|
|
3043
|
+
}
|
|
3044
|
+
|
|
2670
3045
|
// src/providers.ts
|
|
2671
3046
|
var import_zod10 = require("zod");
|
|
2672
3047
|
var PROVIDER_KINDS = ["smtp", "resend"];
|
|
@@ -3777,6 +4152,16 @@ var sendingRoutes = {
|
|
|
3777
4152
|
access: "admin",
|
|
3778
4153
|
phase: "S2"
|
|
3779
4154
|
},
|
|
4155
|
+
/** Refused with `conflict` while a mailing or an automation step still uses the topic; subscriptions and suppressions on it go with it. */
|
|
4156
|
+
"topics.delete": {
|
|
4157
|
+
method: "DELETE",
|
|
4158
|
+
path: "/v1/topics/:id",
|
|
4159
|
+
params: IdParams,
|
|
4160
|
+
response: Ok,
|
|
4161
|
+
status: 200,
|
|
4162
|
+
access: "admin",
|
|
4163
|
+
phase: "S2"
|
|
4164
|
+
},
|
|
3780
4165
|
"contacts.upsert": {
|
|
3781
4166
|
method: "POST",
|
|
3782
4167
|
path: "/v1/contacts",
|
|
@@ -4251,6 +4636,15 @@ var platformRoutes = {
|
|
|
4251
4636
|
access: "read",
|
|
4252
4637
|
phase: "S4"
|
|
4253
4638
|
},
|
|
4639
|
+
"mailings.languages": {
|
|
4640
|
+
method: "GET",
|
|
4641
|
+
path: "/v1/mailings/:id/languages",
|
|
4642
|
+
params: IdParams,
|
|
4643
|
+
response: MailingLanguageReport,
|
|
4644
|
+
status: 200,
|
|
4645
|
+
access: "read",
|
|
4646
|
+
phase: "S4"
|
|
4647
|
+
},
|
|
4254
4648
|
"signupForms.list": {
|
|
4255
4649
|
method: "GET",
|
|
4256
4650
|
path: "/v1/signup-forms",
|
|
@@ -4849,6 +5243,7 @@ function matchRoute(method, pathname) {
|
|
|
4849
5243
|
EXPORT_WARNING_COUNT_HEADER,
|
|
4850
5244
|
Email,
|
|
4851
5245
|
EmailStep,
|
|
5246
|
+
EmailStepLanguage,
|
|
4852
5247
|
ErrorBody,
|
|
4853
5248
|
ErrorCodeSchema,
|
|
4854
5249
|
Event,
|
|
@@ -4898,7 +5293,10 @@ function matchRoute(method, pathname) {
|
|
|
4898
5293
|
InviteListQuery,
|
|
4899
5294
|
InviteStatus,
|
|
4900
5295
|
JsonValue,
|
|
5296
|
+
LETTER_RECIPIENT_REFUSAL,
|
|
4901
5297
|
LIST_UNSUBSCRIBE_POST_VALUE,
|
|
5298
|
+
LOCALE_TAG_PATTERN,
|
|
5299
|
+
LocaleTag,
|
|
4902
5300
|
MAILING_ACTIONS,
|
|
4903
5301
|
MAILING_KINDS,
|
|
4904
5302
|
MAILING_STATUSES,
|
|
@@ -4916,18 +5314,22 @@ function matchRoute(method, pathname) {
|
|
|
4916
5314
|
MAX_IMPORT_URL_LENGTH,
|
|
4917
5315
|
MAX_INVITE_TTL_DAYS,
|
|
4918
5316
|
MAX_IN_LIST,
|
|
5317
|
+
MAX_LETTER_RECIPIENTS,
|
|
4919
5318
|
MAX_MERGE_DEFAULTS,
|
|
4920
5319
|
MAX_MERGE_DEFAULT_LENGTH,
|
|
4921
5320
|
MAX_MJML_DEPTH,
|
|
4922
5321
|
MAX_MJML_ELEMENTS,
|
|
4923
5322
|
MAX_MJML_IMPORT_BYTES,
|
|
4924
5323
|
MAX_PAGE_LIMIT,
|
|
5324
|
+
MAX_PREHEADER_LENGTH,
|
|
4925
5325
|
MAX_RECIPIENTS_PER_BATCH,
|
|
4926
5326
|
MAX_RE_ENTRY_COOLDOWN_SECONDS,
|
|
4927
5327
|
MAX_SAVED_SECTIONS,
|
|
4928
5328
|
MAX_SPLIT_BRANCHES,
|
|
4929
5329
|
MAX_STEPS,
|
|
4930
5330
|
MAX_STEP_VISITS,
|
|
5331
|
+
MAX_SUBJECT_LENGTH,
|
|
5332
|
+
MAX_TEMPLATE_TRANSLATIONS,
|
|
4931
5333
|
MAX_TRIGGERS,
|
|
4932
5334
|
MEMBER_ROLES,
|
|
4933
5335
|
MERGE_FIELD_PATTERN,
|
|
@@ -4945,6 +5347,9 @@ function matchRoute(method, pathname) {
|
|
|
4945
5347
|
MailingExportQuery,
|
|
4946
5348
|
MailingFinishedData,
|
|
4947
5349
|
MailingKind,
|
|
5350
|
+
MailingLanguage,
|
|
5351
|
+
MailingLanguageReport,
|
|
5352
|
+
MailingLanguageStatus,
|
|
4948
5353
|
MailingListQuery,
|
|
4949
5354
|
MailingMetadata,
|
|
4950
5355
|
MailingRetryFailedRequest,
|
|
@@ -5045,6 +5450,7 @@ function matchRoute(method, pathname) {
|
|
|
5045
5450
|
SuppressionCreate,
|
|
5046
5451
|
SuppressionListQuery,
|
|
5047
5452
|
SuppressionReason,
|
|
5453
|
+
TEMPLATE_LANGUAGE_STATUSES,
|
|
5048
5454
|
TERMINAL_MAILING_STATUSES,
|
|
5049
5455
|
Tag,
|
|
5050
5456
|
TagAssignment,
|
|
@@ -5060,8 +5466,13 @@ function matchRoute(method, pathname) {
|
|
|
5060
5466
|
TemplateImportPreview,
|
|
5061
5467
|
TemplateImportPreviewRequest,
|
|
5062
5468
|
TemplateImportResult,
|
|
5469
|
+
TemplateLanguageStatus,
|
|
5063
5470
|
TemplateListQuery,
|
|
5471
|
+
TemplatePreheader,
|
|
5472
|
+
TemplateSubject,
|
|
5064
5473
|
TemplateSummary,
|
|
5474
|
+
TemplateTranslation,
|
|
5475
|
+
TemplateTranslations,
|
|
5065
5476
|
TemplateUpdate,
|
|
5066
5477
|
TemplateUpdatedData,
|
|
5067
5478
|
TemplateVersion,
|
|
@@ -5114,14 +5525,22 @@ function matchRoute(method, pathname) {
|
|
|
5114
5525
|
WorkspaceSettings,
|
|
5115
5526
|
WorkspaceUpdate,
|
|
5116
5527
|
acceptsIdempotencyKey,
|
|
5528
|
+
addLanguageDraft,
|
|
5117
5529
|
alwaysWaits,
|
|
5118
5530
|
automationFilterFamily,
|
|
5119
5531
|
automationRoutes,
|
|
5120
5532
|
billingRoutes,
|
|
5121
5533
|
buildPath,
|
|
5534
|
+
buildTemplatePatch,
|
|
5122
5535
|
canTransition,
|
|
5536
|
+
canonicalLocale,
|
|
5123
5537
|
cycles,
|
|
5124
5538
|
defaultSettings,
|
|
5539
|
+
draftDocument,
|
|
5540
|
+
draftsDirty,
|
|
5541
|
+
draftsFromTemplate,
|
|
5542
|
+
draftsPatch,
|
|
5543
|
+
editLanguageDraft,
|
|
5125
5544
|
emptyFlow,
|
|
5126
5545
|
errorBody,
|
|
5127
5546
|
exportFilename,
|
|
@@ -5137,6 +5556,10 @@ function matchRoute(method, pathname) {
|
|
|
5137
5556
|
isDayEntirelyPast,
|
|
5138
5557
|
isPublishable,
|
|
5139
5558
|
isRetryableError,
|
|
5559
|
+
keepLanguageDocument,
|
|
5560
|
+
languageName,
|
|
5561
|
+
languageTabs,
|
|
5562
|
+
matchLocale,
|
|
5140
5563
|
matchRoute,
|
|
5141
5564
|
missingRequiredMergeFields,
|
|
5142
5565
|
nowSeconds,
|
|
@@ -5145,12 +5568,19 @@ function matchRoute(method, pathname) {
|
|
|
5145
5568
|
parseExportWarningsHeader,
|
|
5146
5569
|
parseUsageWarningHeader,
|
|
5147
5570
|
platformRoutes,
|
|
5571
|
+
primaryLanguage,
|
|
5148
5572
|
reachable,
|
|
5573
|
+
readyWithoutSubject,
|
|
5574
|
+
rebaseDrafts,
|
|
5575
|
+
removeLanguageDraft,
|
|
5576
|
+
restorePatch,
|
|
5149
5577
|
routes,
|
|
5150
5578
|
sendingRoutes,
|
|
5579
|
+
setLanguageStatus,
|
|
5151
5580
|
signWebhook,
|
|
5152
5581
|
statusForError,
|
|
5153
5582
|
stepTargets,
|
|
5583
|
+
storedTemplateLine,
|
|
5154
5584
|
stronglyConnected,
|
|
5155
5585
|
templateRoutes,
|
|
5156
5586
|
testGroupSize,
|