@shware/workflow 0.4.0 → 2.0.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/README.md +90 -49
- package/dist/client.d.cts +1 -1
- package/dist/client.d.mts +1 -1
- package/dist/cloudflare/bindings.cjs.map +1 -1
- package/dist/cloudflare/bindings.d.cts +1 -1
- package/dist/cloudflare/bindings.d.mts +1 -1
- package/dist/cloudflare/bindings.mjs.map +1 -1
- package/dist/cloudflare/channels.cjs +13 -18
- package/dist/cloudflare/channels.cjs.map +1 -1
- package/dist/cloudflare/channels.d.cts +3 -3
- package/dist/cloudflare/channels.d.cts.map +1 -1
- package/dist/cloudflare/channels.d.mts +3 -3
- package/dist/cloudflare/channels.d.mts.map +1 -1
- package/dist/cloudflare/channels.mjs +14 -19
- package/dist/cloudflare/channels.mjs.map +1 -1
- package/dist/cloudflare/index.d.cts +4 -4
- package/dist/cloudflare/index.d.mts +4 -4
- package/dist/cloudflare/router.d.cts +1 -1
- package/dist/cloudflare/router.d.mts +1 -1
- package/dist/cloudflare/runner.d.cts +2 -2
- package/dist/cloudflare/runner.d.mts +2 -2
- package/dist/cloudflare/senders.cjs +15 -8
- package/dist/cloudflare/senders.cjs.map +1 -1
- package/dist/cloudflare/senders.d.cts +15 -11
- package/dist/cloudflare/senders.d.cts.map +1 -1
- package/dist/cloudflare/senders.d.mts +15 -11
- package/dist/cloudflare/senders.d.mts.map +1 -1
- package/dist/cloudflare/senders.mjs +15 -8
- package/dist/cloudflare/senders.mjs.map +1 -1
- package/dist/cloudflare/worker.cjs +7 -4
- package/dist/cloudflare/worker.cjs.map +1 -1
- package/dist/cloudflare/worker.d.cts +2 -2
- package/dist/cloudflare/worker.d.cts.map +1 -1
- package/dist/cloudflare/worker.d.mts +2 -2
- package/dist/cloudflare/worker.d.mts.map +1 -1
- package/dist/cloudflare/worker.mjs +8 -5
- package/dist/cloudflare/worker.mjs.map +1 -1
- package/dist/config.cjs +66 -42
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +26 -45
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +26 -45
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +67 -42
- package/dist/config.mjs.map +1 -1
- package/dist/dsl/action.cjs +1 -1
- package/dist/dsl/action.cjs.map +1 -1
- package/dist/dsl/action.d.cts +1 -1
- package/dist/dsl/action.d.mts +1 -1
- package/dist/dsl/action.mjs +1 -1
- package/dist/dsl/action.mjs.map +1 -1
- package/dist/dsl/bundle.cjs +3 -2
- package/dist/dsl/bundle.cjs.map +1 -1
- package/dist/dsl/bundle.d.cts +3 -2
- package/dist/dsl/bundle.d.cts.map +1 -1
- package/dist/dsl/bundle.d.mts +3 -2
- package/dist/dsl/bundle.d.mts.map +1 -1
- package/dist/dsl/bundle.mjs +3 -2
- package/dist/dsl/bundle.mjs.map +1 -1
- package/dist/dsl/condition.cjs +1 -1
- package/dist/dsl/condition.cjs.map +1 -1
- package/dist/dsl/condition.d.cts +1 -1
- package/dist/dsl/condition.d.mts +1 -1
- package/dist/dsl/condition.mjs +1 -1
- package/dist/dsl/condition.mjs.map +1 -1
- package/dist/dsl/flow.cjs +45 -17
- package/dist/dsl/flow.cjs.map +1 -1
- package/dist/dsl/flow.d.cts +30 -17
- package/dist/dsl/flow.d.cts.map +1 -1
- package/dist/dsl/flow.d.mts +30 -17
- package/dist/dsl/flow.d.mts.map +1 -1
- package/dist/dsl/flow.mjs +45 -18
- package/dist/dsl/flow.mjs.map +1 -1
- package/dist/dsl/index.cjs +0 -1
- package/dist/dsl/index.d.cts +2 -2
- package/dist/dsl/index.d.mts +2 -2
- package/dist/dsl/index.mjs +2 -2
- package/dist/dsl/template.cjs +2 -47
- package/dist/dsl/template.cjs.map +1 -1
- package/dist/dsl/template.d.cts +4 -54
- package/dist/dsl/template.d.cts.map +1 -1
- package/dist/dsl/template.d.mts +4 -54
- package/dist/dsl/template.d.mts.map +1 -1
- package/dist/dsl/template.mjs +3 -47
- package/dist/dsl/template.mjs.map +1 -1
- package/dist/dsl/workflow.cjs +1 -1
- package/dist/dsl/workflow.cjs.map +1 -1
- package/dist/dsl/workflow.d.cts +1 -1
- package/dist/dsl/workflow.d.mts +1 -1
- package/dist/dsl/workflow.mjs +1 -1
- package/dist/dsl/workflow.mjs.map +1 -1
- package/dist/email-context.cjs +29 -0
- package/dist/email-context.cjs.map +1 -0
- package/dist/email-context.d.cts +11 -0
- package/dist/email-context.d.cts.map +1 -0
- package/dist/email-context.d.mts +11 -0
- package/dist/email-context.d.mts.map +1 -0
- package/dist/email-context.mjs +27 -0
- package/dist/email-context.mjs.map +1 -0
- package/dist/email.cjs +72 -0
- package/dist/email.cjs.map +1 -0
- package/dist/email.d.cts +63 -0
- package/dist/email.d.cts.map +1 -0
- package/dist/email.d.mts +63 -0
- package/dist/email.d.mts.map +1 -0
- package/dist/email.mjs +65 -0
- package/dist/email.mjs.map +1 -0
- package/dist/engine/index.d.cts +2 -2
- package/dist/engine/index.d.mts +2 -2
- package/dist/engine/ports.d.cts +7 -2
- package/dist/engine/ports.d.cts.map +1 -1
- package/dist/engine/ports.d.mts +7 -2
- package/dist/engine/ports.d.mts.map +1 -1
- package/dist/index.cjs +13 -3
- package/dist/index.d.cts +5 -4
- package/dist/index.d.mts +5 -4
- package/dist/index.mjs +5 -4
- package/dist/push.cjs +3 -5
- package/dist/push.cjs.map +1 -1
- package/dist/push.d.cts +2 -2
- package/dist/push.d.cts.map +1 -1
- package/dist/push.d.mts +2 -2
- package/dist/push.d.mts.map +1 -1
- package/dist/push.mjs +4 -6
- package/dist/push.mjs.map +1 -1
- package/dist/react-email.cjs +16 -8
- package/dist/react-email.cjs.map +1 -1
- package/dist/react-email.d.cts +2 -1
- package/dist/react-email.d.cts.map +1 -1
- package/dist/react-email.d.mts +2 -1
- package/dist/react-email.d.mts.map +1 -1
- package/dist/react-email.mjs +17 -9
- package/dist/react-email.mjs.map +1 -1
- package/dist/reporting/classify.cjs.map +1 -1
- package/dist/reporting/classify.d.cts +1 -1
- package/dist/reporting/classify.d.mts +1 -1
- package/dist/reporting/classify.mjs.map +1 -1
- package/dist/reporting/observer.cjs +5 -4
- package/dist/reporting/observer.cjs.map +1 -1
- package/dist/reporting/observer.d.cts +3 -2
- package/dist/reporting/observer.d.cts.map +1 -1
- package/dist/reporting/observer.d.mts +3 -2
- package/dist/reporting/observer.d.mts.map +1 -1
- package/dist/reporting/observer.mjs +5 -4
- package/dist/reporting/observer.mjs.map +1 -1
- package/dist/reporting/tracking.cjs +3 -12
- package/dist/reporting/tracking.cjs.map +1 -1
- package/dist/reporting/tracking.d.cts +18 -7
- package/dist/reporting/tracking.d.cts.map +1 -1
- package/dist/reporting/tracking.d.mts +18 -7
- package/dist/reporting/tracking.d.mts.map +1 -1
- package/dist/reporting/tracking.mjs +3 -12
- package/dist/reporting/tracking.mjs.map +1 -1
- package/dist/templates.cjs +90 -30
- package/dist/templates.cjs.map +1 -1
- package/dist/templates.d.cts +70 -13
- package/dist/templates.d.cts.map +1 -1
- package/dist/templates.d.mts +70 -13
- package/dist/templates.d.mts.map +1 -1
- package/dist/templates.mjs +87 -31
- package/dist/templates.mjs.map +1 -1
- package/package.json +11 -1
package/dist/email.d.mts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { EmailTemplate } from "./templates.mjs";
|
|
2
|
+
//#region src/email.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Email metadata: who a template's email comes from, where replies go, and the unsubscribe link
|
|
5
|
+
* its layout carries. Each `emailTemplate` declares its own `from` (and `replyTo`, if replies should
|
|
6
|
+
* go elsewhere); the unsubscribe link is the template's `unsubscribeUrl`, else the config's
|
|
7
|
+
* `email.unsubscribeUrl`, else none. `resolveEmail` is that rule, and the sender, the renderer,
|
|
8
|
+
* the Worker's preview and the studio all go through it. No React and no I/O here, so a browser
|
|
9
|
+
* can import it.
|
|
10
|
+
*/
|
|
11
|
+
/** An address as the transports take it: bare, or with a display name. */
|
|
12
|
+
export type EmailAddress = string | {
|
|
13
|
+
email: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
};
|
|
16
|
+
/** `Name <email>`, or the bare address. */
|
|
17
|
+
export declare function formatEmailAddress(address: EmailAddress): string;
|
|
18
|
+
/** The config's `email`: what every email template shares. */
|
|
19
|
+
export interface EmailConfig {
|
|
20
|
+
/**
|
|
21
|
+
* The unsubscribe link of every email template that names none of its own. The layout reads it
|
|
22
|
+
* with `useEmailContext()`; sent, it is tracked like every link, but following it shows a
|
|
23
|
+
* confirmation page, and only the confirmation (a POST no link scanner sends) unsubscribes.
|
|
24
|
+
*/
|
|
25
|
+
unsubscribeUrl?: string;
|
|
26
|
+
/** How the Worker tells a person's opens and clicks from a machine's (see the reporting classifier). */
|
|
27
|
+
tracking?: {
|
|
28
|
+
/**
|
|
29
|
+
* An open or click this many milliseconds after delivery is a weak machine signal — machine
|
|
30
|
+
* only together with another (a second link within seconds); 1000 by default. A person
|
|
31
|
+
* tapping a mail notification can click within a few seconds, so keep it short.
|
|
32
|
+
*/
|
|
33
|
+
quickClickMs?: number;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** One template's email metadata, resolved against the config. */
|
|
37
|
+
export interface ResolvedEmail {
|
|
38
|
+
from: EmailAddress;
|
|
39
|
+
/** Absent when the template names none: the email goes out without a Reply-To. */
|
|
40
|
+
replyTo?: EmailAddress;
|
|
41
|
+
/** Absent when neither the template nor the config names one: the email has no unsubscribe link. */
|
|
42
|
+
unsubscribeUrl?: string;
|
|
43
|
+
}
|
|
44
|
+
/** The template's metadata, its `unsubscribeUrl` falling back to the config's. Leaves both untouched. */
|
|
45
|
+
export declare function resolveEmail(template: Pick<EmailTemplate, 'from' | 'replyTo' | 'unsubscribeUrl'>, config?: EmailConfig): ResolvedEmail;
|
|
46
|
+
/** Throws naming `where` when `address` is neither `user@host` nor `{ email: 'user@host', name? }`. */
|
|
47
|
+
export declare function assertEmailAddress(address: unknown, where: string): void;
|
|
48
|
+
/** Throws naming `where` unless `url` is an absolute http(s) URL; '' and null are not a way to leave it out. */
|
|
49
|
+
export declare function assertUnsubscribeUrl(url: unknown, where: string): void;
|
|
50
|
+
/** The config's `email` and every registered template's metadata; throws on the first invalid value. */
|
|
51
|
+
export declare function assertEmailConfig(config: {
|
|
52
|
+
email?: EmailConfig;
|
|
53
|
+
}, templates: Iterable<EmailTemplate>): void;
|
|
54
|
+
/** A template's own `from` / `replyTo` / `unsubscribeUrl`, as `emailTemplate` checks them. */
|
|
55
|
+
export declare function assertEmailMetadata(template: {
|
|
56
|
+
from?: unknown;
|
|
57
|
+
replyTo?: unknown;
|
|
58
|
+
unsubscribeUrl?: unknown;
|
|
59
|
+
}, where: string): void;
|
|
60
|
+
/** The unsubscribe link may carry its own query (a token, a list): the path names it. */
|
|
61
|
+
export declare function isUnsubscribeLink(url: string, unsubscribeUrl: string | undefined): boolean;
|
|
62
|
+
//#endregion
|
|
63
|
+
//# sourceMappingURL=email.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.d.mts","names":[],"sources":["../src/email.ts"],"mappings":";;;;;;;;;;;YAYY;EAA0B;EAAe;;;wBAGrC,mBAAmB,SAAS;;iBAM3B;;;;;;EAMf;;EAEA;;;;;;IAME;;;;iBAKa;EACf,MAAM;;EAEN,UAAU;;EAEV;;;wBAIc,aACd,UAAU,KAAK,uDACf,SAAS,cACR;;wBAYa,mBAAmB,kBAAkB;;wBAkBrC,qBAAqB,cAAc;;wBAanC,kBACd;EAAU,QAAQ;GAClB,WAAW,SAAS;;wBA0BN,oBACd;EAAY;EAAgB;EAAmB;GAC/C;;wBAUc,kBAAkB,aAAa"}
|
package/dist/email.mjs
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
//#region src/email.ts
|
|
2
|
+
/** `Name <email>`, or the bare address. */
|
|
3
|
+
function formatEmailAddress(address) {
|
|
4
|
+
if (typeof address === "string") return address;
|
|
5
|
+
return address.name === void 0 ? address.email : `${address.name} <${address.email}>`;
|
|
6
|
+
}
|
|
7
|
+
/** The template's metadata, its `unsubscribeUrl` falling back to the config's. Leaves both untouched. */
|
|
8
|
+
function resolveEmail(template, config) {
|
|
9
|
+
const unsubscribeUrl = template.unsubscribeUrl ?? config?.unsubscribeUrl;
|
|
10
|
+
return {
|
|
11
|
+
from: template.from,
|
|
12
|
+
...template.replyTo === void 0 ? {} : { replyTo: template.replyTo },
|
|
13
|
+
...unsubscribeUrl === void 0 ? {} : { unsubscribeUrl }
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const ADDRESS = /^[^\s@<>]+@[^\s@<>]+$/;
|
|
17
|
+
/** Throws naming `where` when `address` is neither `user@host` nor `{ email: 'user@host', name? }`. */
|
|
18
|
+
function assertEmailAddress(address, where) {
|
|
19
|
+
const email = typeof address === "object" && address !== null ? address.email : address;
|
|
20
|
+
const name = typeof address === "object" && address !== null ? address.name : void 0;
|
|
21
|
+
if (typeof email !== "string" || !ADDRESS.test(email)) throw new TypeError(`${where} must be an email address or { email, name? }`);
|
|
22
|
+
if (name !== void 0 && typeof name !== "string") throw new TypeError(`${where}.name must be a string`);
|
|
23
|
+
}
|
|
24
|
+
/** Throws naming `where` unless `url` is an absolute http(s) URL; '' and null are not a way to leave it out. */
|
|
25
|
+
function assertUnsubscribeUrl(url, where) {
|
|
26
|
+
let parsed;
|
|
27
|
+
try {
|
|
28
|
+
parsed = typeof url === "string" ? new URL(url) : void 0;
|
|
29
|
+
} catch {
|
|
30
|
+
parsed = void 0;
|
|
31
|
+
}
|
|
32
|
+
if (parsed === void 0 || parsed.protocol !== "https:" && parsed.protocol !== "http:") throw new TypeError(`${where} must be an http(s) URL (leave it out for none)`);
|
|
33
|
+
}
|
|
34
|
+
/** The config's `email` and every registered template's metadata; throws on the first invalid value. */
|
|
35
|
+
function assertEmailConfig(config, templates) {
|
|
36
|
+
if (Object.hasOwn(config, "emails")) throw new TypeError("the config's `emails` is gone: `from` and `replyTo` are declared on each emailTemplate, and the rest moved to `email: { unsubscribeUrl, tracking }`");
|
|
37
|
+
const email = config.email;
|
|
38
|
+
if (email !== void 0) {
|
|
39
|
+
if (email.unsubscribeUrl !== void 0) assertUnsubscribeUrl(email.unsubscribeUrl, "email.unsubscribeUrl");
|
|
40
|
+
const quick = email.tracking?.quickClickMs;
|
|
41
|
+
if (quick !== void 0 && !(typeof quick === "number" && Number.isFinite(quick) && quick >= 0)) throw new TypeError("email.tracking.quickClickMs must be a non-negative number");
|
|
42
|
+
}
|
|
43
|
+
for (const template of templates) assertEmailMetadata(template, `email template '${template.id}'`);
|
|
44
|
+
}
|
|
45
|
+
/** A template's own `from` / `replyTo` / `unsubscribeUrl`, as `emailTemplate` checks them. */
|
|
46
|
+
function assertEmailMetadata(template, where) {
|
|
47
|
+
assertEmailAddress(template.from, `${where}: from`);
|
|
48
|
+
if (template.replyTo !== void 0) assertEmailAddress(template.replyTo, `${where}: replyTo`);
|
|
49
|
+
if (template.unsubscribeUrl !== void 0) assertUnsubscribeUrl(template.unsubscribeUrl, `${where}: unsubscribeUrl`);
|
|
50
|
+
}
|
|
51
|
+
/** The unsubscribe link may carry its own query (a token, a list): the path names it. */
|
|
52
|
+
function isUnsubscribeLink(url, unsubscribeUrl) {
|
|
53
|
+
if (unsubscribeUrl === void 0) return false;
|
|
54
|
+
try {
|
|
55
|
+
const a = new URL(url);
|
|
56
|
+
const b = new URL(unsubscribeUrl);
|
|
57
|
+
return a.origin === b.origin && a.pathname === b.pathname;
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { assertEmailAddress, assertEmailConfig, assertEmailMetadata, assertUnsubscribeUrl, formatEmailAddress, isUnsubscribeLink, resolveEmail };
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=email.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.mjs","names":[],"sources":["../src/email.ts"],"sourcesContent":["import type { EmailTemplate } from './templates';\n\n/**\n * Email metadata: who a template's email comes from, where replies go, and the unsubscribe link\n * its layout carries. Each `emailTemplate` declares its own `from` (and `replyTo`, if replies should\n * go elsewhere); the unsubscribe link is the template's `unsubscribeUrl`, else the config's\n * `email.unsubscribeUrl`, else none. `resolveEmail` is that rule, and the sender, the renderer,\n * the Worker's preview and the studio all go through it. No React and no I/O here, so a browser\n * can import it.\n */\n\n/** An address as the transports take it: bare, or with a display name. */\nexport type EmailAddress = string | { email: string; name?: string };\n\n/** `Name <email>`, or the bare address. */\nexport function formatEmailAddress(address: EmailAddress): string {\n if (typeof address === 'string') return address;\n return address.name === undefined ? address.email : `${address.name} <${address.email}>`;\n}\n\n/** The config's `email`: what every email template shares. */\nexport interface EmailConfig {\n /**\n * The unsubscribe link of every email template that names none of its own. The layout reads it\n * with `useEmailContext()`; sent, it is tracked like every link, but following it shows a\n * confirmation page, and only the confirmation (a POST no link scanner sends) unsubscribes.\n */\n unsubscribeUrl?: string;\n /** How the Worker tells a person's opens and clicks from a machine's (see the reporting classifier). */\n tracking?: {\n /**\n * An open or click this many milliseconds after delivery is a weak machine signal — machine\n * only together with another (a second link within seconds); 1000 by default. A person\n * tapping a mail notification can click within a few seconds, so keep it short.\n */\n quickClickMs?: number;\n };\n}\n\n/** One template's email metadata, resolved against the config. */\nexport interface ResolvedEmail {\n from: EmailAddress;\n /** Absent when the template names none: the email goes out without a Reply-To. */\n replyTo?: EmailAddress;\n /** Absent when neither the template nor the config names one: the email has no unsubscribe link. */\n unsubscribeUrl?: string;\n}\n\n/** The template's metadata, its `unsubscribeUrl` falling back to the config's. Leaves both untouched. */\nexport function resolveEmail(\n template: Pick<EmailTemplate, 'from' | 'replyTo' | 'unsubscribeUrl'>,\n config?: EmailConfig\n): ResolvedEmail {\n const unsubscribeUrl = template.unsubscribeUrl ?? config?.unsubscribeUrl;\n return {\n from: template.from,\n ...(template.replyTo === undefined ? {} : { replyTo: template.replyTo }),\n ...(unsubscribeUrl === undefined ? {} : { unsubscribeUrl }),\n };\n}\n\nconst ADDRESS = /^[^\\s@<>]+@[^\\s@<>]+$/;\n\n/** Throws naming `where` when `address` is neither `user@host` nor `{ email: 'user@host', name? }`. */\nexport function assertEmailAddress(address: unknown, where: string): void {\n const email =\n typeof address === 'object' && address !== null\n ? (address as { email?: unknown }).email\n : address;\n const name =\n typeof address === 'object' && address !== null\n ? (address as { name?: unknown }).name\n : undefined;\n if (typeof email !== 'string' || !ADDRESS.test(email)) {\n throw new TypeError(`${where} must be an email address or { email, name? }`);\n }\n if (name !== undefined && typeof name !== 'string') {\n throw new TypeError(`${where}.name must be a string`);\n }\n}\n\n/** Throws naming `where` unless `url` is an absolute http(s) URL; '' and null are not a way to leave it out. */\nexport function assertUnsubscribeUrl(url: unknown, where: string): void {\n let parsed: URL | undefined;\n try {\n parsed = typeof url === 'string' ? new URL(url) : undefined;\n } catch {\n parsed = undefined;\n }\n if (parsed === undefined || (parsed.protocol !== 'https:' && parsed.protocol !== 'http:')) {\n throw new TypeError(`${where} must be an http(s) URL (leave it out for none)`);\n }\n}\n\n/** The config's `email` and every registered template's metadata; throws on the first invalid value. */\nexport function assertEmailConfig(\n config: { email?: EmailConfig },\n templates: Iterable<EmailTemplate>\n): void {\n if (Object.hasOwn(config, 'emails')) {\n throw new TypeError(\n \"the config's `emails` is gone: `from` and `replyTo` are declared on each emailTemplate, \" +\n 'and the rest moved to `email: { unsubscribeUrl, tracking }`'\n );\n }\n const email = config.email;\n if (email !== undefined) {\n if (email.unsubscribeUrl !== undefined) {\n assertUnsubscribeUrl(email.unsubscribeUrl, 'email.unsubscribeUrl');\n }\n const quick = email.tracking?.quickClickMs;\n if (\n quick !== undefined &&\n !(typeof quick === 'number' && Number.isFinite(quick) && quick >= 0)\n ) {\n throw new TypeError('email.tracking.quickClickMs must be a non-negative number');\n }\n }\n for (const template of templates)\n assertEmailMetadata(template, `email template '${template.id}'`);\n}\n\n/** A template's own `from` / `replyTo` / `unsubscribeUrl`, as `emailTemplate` checks them. */\nexport function assertEmailMetadata(\n template: { from?: unknown; replyTo?: unknown; unsubscribeUrl?: unknown },\n where: string\n): void {\n assertEmailAddress(template.from, `${where}: from`);\n if (template.replyTo !== undefined) assertEmailAddress(template.replyTo, `${where}: replyTo`);\n if (template.unsubscribeUrl !== undefined) {\n assertUnsubscribeUrl(template.unsubscribeUrl, `${where}: unsubscribeUrl`);\n }\n}\n\n/** The unsubscribe link may carry its own query (a token, a list): the path names it. */\nexport function isUnsubscribeLink(url: string, unsubscribeUrl: string | undefined): boolean {\n if (unsubscribeUrl === undefined) return false;\n try {\n const a = new URL(url);\n const b = new URL(unsubscribeUrl);\n return a.origin === b.origin && a.pathname === b.pathname;\n } catch {\n return false;\n }\n}\n"],"mappings":";;AAeA,SAAgB,mBAAmB,SAA+B;CAChE,IAAI,OAAO,YAAY,UAAU,OAAO;CACxC,OAAO,QAAQ,SAAS,KAAA,IAAY,QAAQ,QAAQ,GAAG,QAAQ,KAAK,IAAI,QAAQ,MAAM;AACxF;;AA+BA,SAAgB,aACd,UACA,QACe;CACf,MAAM,iBAAiB,SAAS,kBAAkB,QAAQ;CAC1D,OAAO;EACL,MAAM,SAAS;EACf,GAAI,SAAS,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,SAAS,QAAQ;EACtE,GAAI,mBAAmB,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe;CAC3D;AACF;AAEA,MAAM,UAAU;;AAGhB,SAAgB,mBAAmB,SAAkB,OAAqB;CACxE,MAAM,QACJ,OAAO,YAAY,YAAY,YAAY,OACtC,QAAgC,QACjC;CACN,MAAM,OACJ,OAAO,YAAY,YAAY,YAAY,OACtC,QAA+B,OAChC,KAAA;CACN,IAAI,OAAO,UAAU,YAAY,CAAC,QAAQ,KAAK,KAAK,GAClD,MAAM,IAAI,UAAU,GAAG,MAAM,8CAA8C;CAE7E,IAAI,SAAS,KAAA,KAAa,OAAO,SAAS,UACxC,MAAM,IAAI,UAAU,GAAG,MAAM,uBAAuB;AAExD;;AAGA,SAAgB,qBAAqB,KAAc,OAAqB;CACtE,IAAI;CACJ,IAAI;EACF,SAAS,OAAO,QAAQ,WAAW,IAAI,IAAI,GAAG,IAAI,KAAA;CACpD,QAAQ;EACN,SAAS,KAAA;CACX;CACA,IAAI,WAAW,KAAA,KAAc,OAAO,aAAa,YAAY,OAAO,aAAa,SAC/E,MAAM,IAAI,UAAU,GAAG,MAAM,gDAAgD;AAEjF;;AAGA,SAAgB,kBACd,QACA,WACM;CACN,IAAI,OAAO,OAAO,QAAQ,QAAQ,GAChC,MAAM,IAAI,UACR,qJAEF;CAEF,MAAM,QAAQ,OAAO;CACrB,IAAI,UAAU,KAAA,GAAW;EACvB,IAAI,MAAM,mBAAmB,KAAA,GAC3B,qBAAqB,MAAM,gBAAgB,sBAAsB;EAEnE,MAAM,QAAQ,MAAM,UAAU;EAC9B,IACE,UAAU,KAAA,KACV,EAAE,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,SAAS,IAElE,MAAM,IAAI,UAAU,2DAA2D;CAEnF;CACA,KAAK,MAAM,YAAY,WACrB,oBAAoB,UAAU,mBAAmB,SAAS,GAAG,EAAE;AACnE;;AAGA,SAAgB,oBACd,UACA,OACM;CACN,mBAAmB,SAAS,MAAM,GAAG,MAAM,OAAO;CAClD,IAAI,SAAS,YAAY,KAAA,GAAW,mBAAmB,SAAS,SAAS,GAAG,MAAM,UAAU;CAC5F,IAAI,SAAS,mBAAmB,KAAA,GAC9B,qBAAqB,SAAS,gBAAgB,GAAG,MAAM,iBAAiB;AAE5E;;AAGA,SAAgB,kBAAkB,KAAa,gBAA6C;CAC1F,IAAI,mBAAmB,KAAA,GAAW,OAAO;CACzC,IAAI;EACF,MAAM,IAAI,IAAI,IAAI,GAAG;EACrB,MAAM,IAAI,IAAI,IAAI,cAAc;EAChC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE;CACnD,QAAQ;EACN,OAAO;CACT;AACF"}
|
package/dist/engine/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ActionInvocation, ActionInvoker, EngineStep, EventSink, FactSource, JourneyContext, JourneyObserver, JourneyOutcome, MessageSender, MessageTracking, OutboundMessage, PushDevice, SendResult } from "./ports.cjs";
|
|
1
|
+
import { ActionInvocation, ActionInvoker, EngineStep, EventSink, FactSource, JourneyContext, JourneyObserver, JourneyOutcome, LinkPurpose, MessageSender, MessageTracking, OutboundMessage, PushDevice, SendResult } from "./ports.cjs";
|
|
2
2
|
import { ActionVersionPolicy, RegisteredAction, RegistryActionInvoker } from "./actions.cjs";
|
|
3
3
|
import { hashToBucket, murmur3 } from "./bucket.cjs";
|
|
4
4
|
import { DEVICES_UPDATED_EVENT, EvaluateOptions, PROFILE_UPDATED_EVENT, evaluateCondition, matchesWhere, relevantEvents } from "./condition.cjs";
|
|
5
5
|
import { runJourney } from "./interpreter.cjs";
|
|
6
6
|
import { scaleDurations, scaleSegmentWindows } from "./time-scale.cjs";
|
|
7
7
|
import { nextWindowStart, resolveTimeZone } from "./time-window.cjs";
|
|
8
|
-
export { type ActionInvocation, type ActionInvoker, type ActionVersionPolicy, DEVICES_UPDATED_EVENT, type EngineStep, type EvaluateOptions, type EventSink, type FactSource, type JourneyContext, type JourneyObserver, type JourneyOutcome, type MessageSender, type MessageTracking, type OutboundMessage, PROFILE_UPDATED_EVENT, type PushDevice, type RegisteredAction, RegistryActionInvoker, type SendResult, evaluateCondition, hashToBucket, matchesWhere, murmur3, nextWindowStart, relevantEvents, resolveTimeZone, runJourney, scaleDurations, scaleSegmentWindows };
|
|
8
|
+
export { type ActionInvocation, type ActionInvoker, type ActionVersionPolicy, DEVICES_UPDATED_EVENT, type EngineStep, type EvaluateOptions, type EventSink, type FactSource, type JourneyContext, type JourneyObserver, type JourneyOutcome, type LinkPurpose, type MessageSender, type MessageTracking, type OutboundMessage, PROFILE_UPDATED_EVENT, type PushDevice, type RegisteredAction, RegistryActionInvoker, type SendResult, evaluateCondition, hashToBucket, matchesWhere, murmur3, nextWindowStart, relevantEvents, resolveTimeZone, runJourney, scaleDurations, scaleSegmentWindows };
|
package/dist/engine/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ActionInvocation, ActionInvoker, EngineStep, EventSink, FactSource, JourneyContext, JourneyObserver, JourneyOutcome, MessageSender, MessageTracking, OutboundMessage, PushDevice, SendResult } from "./ports.mjs";
|
|
1
|
+
import { ActionInvocation, ActionInvoker, EngineStep, EventSink, FactSource, JourneyContext, JourneyObserver, JourneyOutcome, LinkPurpose, MessageSender, MessageTracking, OutboundMessage, PushDevice, SendResult } from "./ports.mjs";
|
|
2
2
|
import { ActionVersionPolicy, RegisteredAction, RegistryActionInvoker } from "./actions.mjs";
|
|
3
3
|
import { hashToBucket, murmur3 } from "./bucket.mjs";
|
|
4
4
|
import { DEVICES_UPDATED_EVENT, EvaluateOptions, PROFILE_UPDATED_EVENT, evaluateCondition, matchesWhere, relevantEvents } from "./condition.mjs";
|
|
5
5
|
import { runJourney } from "./interpreter.mjs";
|
|
6
6
|
import { scaleDurations, scaleSegmentWindows } from "./time-scale.mjs";
|
|
7
7
|
import { nextWindowStart, resolveTimeZone } from "./time-window.mjs";
|
|
8
|
-
export { type ActionInvocation, type ActionInvoker, type ActionVersionPolicy, DEVICES_UPDATED_EVENT, type EngineStep, type EvaluateOptions, type EventSink, type FactSource, type JourneyContext, type JourneyObserver, type JourneyOutcome, type MessageSender, type MessageTracking, type OutboundMessage, PROFILE_UPDATED_EVENT, type PushDevice, type RegisteredAction, RegistryActionInvoker, type SendResult, evaluateCondition, hashToBucket, matchesWhere, murmur3, nextWindowStart, relevantEvents, resolveTimeZone, runJourney, scaleDurations, scaleSegmentWindows };
|
|
8
|
+
export { type ActionInvocation, type ActionInvoker, type ActionVersionPolicy, DEVICES_UPDATED_EVENT, type EngineStep, type EvaluateOptions, type EventSink, type FactSource, type JourneyContext, type JourneyObserver, type JourneyOutcome, type LinkPurpose, type MessageSender, type MessageTracking, type OutboundMessage, PROFILE_UPDATED_EVENT, type PushDevice, type RegisteredAction, RegistryActionInvoker, type SendResult, evaluateCondition, hashToBucket, matchesWhere, murmur3, nextWindowStart, relevantEvents, resolveTimeZone, runJourney, scaleDurations, scaleSegmentWindows };
|
package/dist/engine/ports.d.cts
CHANGED
|
@@ -93,14 +93,19 @@ export interface OutboundMessage {
|
|
|
93
93
|
/** What the host's observer asked the sender to add for measuring this copy (see `MessageTracking`). */
|
|
94
94
|
tracking?: MessageTracking | undefined;
|
|
95
95
|
}
|
|
96
|
+
/** What following a tracked email link does: redirect to it, or confirm an unsubscribe. */
|
|
97
|
+
export type LinkPurpose = 'link' | 'unsubscribe';
|
|
96
98
|
/**
|
|
97
99
|
* Measuring a copy, as the built-in senders apply it: an email's links are routed through
|
|
98
100
|
* `link` and `pixel` is appended as a 1×1 image; a push carries `data` in its payload.
|
|
99
101
|
* Each is optional, and a sender ignores what its channel has no use for.
|
|
100
102
|
*/
|
|
101
103
|
export interface MessageTracking {
|
|
102
|
-
/**
|
|
103
|
-
|
|
104
|
+
/**
|
|
105
|
+
* The original `http(s)` URL in, the URL that records the click and redirects out — or, for the
|
|
106
|
+
* email's unsubscribe link, asks the recipient to confirm.
|
|
107
|
+
*/
|
|
108
|
+
link?: (url: string, purpose: LinkPurpose) => string;
|
|
104
109
|
/** Loaded when the email is opened. */
|
|
105
110
|
pixel?: string;
|
|
106
111
|
/** Extra string keys in the push payload. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ports.d.cts","names":[],"sources":["../../src/engine/ports.ts"],"mappings":";;;;;;;;;;;;;;;;iBAiBiB;;EAEf,GAAG,GAAG,cAAc,UAAU,QAAQ,KAAK,QAAQ;;EAGnD,MAAM,cAAc,aAAa;;EAGjC,WAAW,cAAc,sBAAsB;;;;;;;;;;;;EAa/C,UAAU,cAAc,4BAA4B;;EAGpD,YAAY,eAAe;;;;;EAM3B,YAAY,cAAc,oBAAoB;;;iBAI/B;EACf;EACA;;;iBAIe;;;;;;EAMf,YACE,eACA;IAAS;IAAkB;IAAkB,QAAQ;MACpD;EACH,YAAY,eAAe,QAAQ;;EAEnC,oBAAoB,eAAe,QAAQ;;EAE3C,eAAe,QAAQ;;EAEvB,cAAc,SAAS,YAAY;;iBAGpB;;EAEf;EACA;EACA;EACA,SAAS;EACT;;EAEA,OAAO,eAAe;EACtB;;;;;;EAMA;;EAEA,SAAS;;;;;;EAMT;;EAEA,WAAW
|
|
1
|
+
{"version":3,"file":"ports.d.cts","names":[],"sources":["../../src/engine/ports.ts"],"mappings":";;;;;;;;;;;;;;;;iBAiBiB;;EAEf,GAAG,GAAG,cAAc,UAAU,QAAQ,KAAK,QAAQ;;EAGnD,MAAM,cAAc,aAAa;;EAGjC,WAAW,cAAc,sBAAsB;;;;;;;;;;;;EAa/C,UAAU,cAAc,4BAA4B;;EAGpD,YAAY,eAAe;;;;;EAM3B,YAAY,cAAc,oBAAoB;;;iBAI/B;EACf;EACA;;;iBAIe;;;;;;EAMf,YACE,eACA;IAAS;IAAkB;IAAkB,QAAQ;MACpD;EACH,YAAY,eAAe,QAAQ;;EAEnC,oBAAoB,eAAe,QAAQ;;EAE3C,eAAe,QAAQ;;EAEvB,cAAc,SAAS,YAAY;;iBAGpB;;EAEf;EACA;EACA;EACA,SAAS;EACT;;EAEA,OAAO,eAAe;EACtB;;;;;;EAMA;;EAEA,SAAS;;;;;;EAMT;;EAEA,WAAW;;;YAID;;;;;;iBAOK;;;;;EAKf,QAAQ,aAAa,SAAS;;EAE9B;;EAEA,OAAO;;;;;;EAMP,eAAe;;;;;;;iBAQA;EACf;EACA;;iBAGe;EACf,KAAK,SAAS,kBAAkB,eAAe;;;;;;;;;iBAUhC;;EAEf,SAAS;IACP;IACA;IACA;IACA;MACE;;EAEJ,aAAa;IACX;IACA;IACA;IACA;IACA;MACE;;EAEJ,iBAAiB,SAAS,kBAAkB,QAAQ;;EAEpD,aAAa,SAAS,iBAAiB;IAAU;MAAoB,aAAa;;EAElF,UAAU;IACR;IACA;IACA;IACA,QAAQ;IACR;;IAEA;MACE;;;;;;;;;iBAUW;EACf,SAAS;IACP,SAAS;IACT;IACA,OAAO,eAAe;MACpB,eAAe;;;iBAIJ;;;;;;;;EAQf,KAAK,eAAe,SAAS,eAAe,uBAAuB,aAAa;;;iBAIjE;;EAEf;;EAEA;;EAEA,MAAM,eAAe;EACrB;;EAEA;;;;;;;iBAQe;EACf,OAAO,YAAY,mBAAmB;;iBAGvB;EACf;;EAEA;;;;;;;EAOA;EACA,MAAM;EACN,OAAO;EACP,UAAU;EACV,QAAQ;;EAER,UAAU;;EAEV,YAAY;;EAEZ,WAAW;;;;;;;YAQD;EACN;;EACA;EAAkB;;EAClB;;EACA;;EACA"}
|
package/dist/engine/ports.d.mts
CHANGED
|
@@ -93,14 +93,19 @@ export interface OutboundMessage {
|
|
|
93
93
|
/** What the host's observer asked the sender to add for measuring this copy (see `MessageTracking`). */
|
|
94
94
|
tracking?: MessageTracking | undefined;
|
|
95
95
|
}
|
|
96
|
+
/** What following a tracked email link does: redirect to it, or confirm an unsubscribe. */
|
|
97
|
+
export type LinkPurpose = 'link' | 'unsubscribe';
|
|
96
98
|
/**
|
|
97
99
|
* Measuring a copy, as the built-in senders apply it: an email's links are routed through
|
|
98
100
|
* `link` and `pixel` is appended as a 1×1 image; a push carries `data` in its payload.
|
|
99
101
|
* Each is optional, and a sender ignores what its channel has no use for.
|
|
100
102
|
*/
|
|
101
103
|
export interface MessageTracking {
|
|
102
|
-
/**
|
|
103
|
-
|
|
104
|
+
/**
|
|
105
|
+
* The original `http(s)` URL in, the URL that records the click and redirects out — or, for the
|
|
106
|
+
* email's unsubscribe link, asks the recipient to confirm.
|
|
107
|
+
*/
|
|
108
|
+
link?: (url: string, purpose: LinkPurpose) => string;
|
|
104
109
|
/** Loaded when the email is opened. */
|
|
105
110
|
pixel?: string;
|
|
106
111
|
/** Extra string keys in the push payload. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ports.d.mts","names":[],"sources":["../../src/engine/ports.ts"],"mappings":";;;;;;;;;;;;;;;;iBAiBiB;;EAEf,GAAG,GAAG,cAAc,UAAU,QAAQ,KAAK,QAAQ;;EAGnD,MAAM,cAAc,aAAa;;EAGjC,WAAW,cAAc,sBAAsB;;;;;;;;;;;;EAa/C,UAAU,cAAc,4BAA4B;;EAGpD,YAAY,eAAe;;;;;EAM3B,YAAY,cAAc,oBAAoB;;;iBAI/B;EACf;EACA;;;iBAIe;;;;;;EAMf,YACE,eACA;IAAS;IAAkB;IAAkB,QAAQ;MACpD;EACH,YAAY,eAAe,QAAQ;;EAEnC,oBAAoB,eAAe,QAAQ;;EAE3C,eAAe,QAAQ;;EAEvB,cAAc,SAAS,YAAY;;iBAGpB;;EAEf;EACA;EACA;EACA,SAAS;EACT;;EAEA,OAAO,eAAe;EACtB;;;;;;EAMA;;EAEA,SAAS;;;;;;EAMT;;EAEA,WAAW
|
|
1
|
+
{"version":3,"file":"ports.d.mts","names":[],"sources":["../../src/engine/ports.ts"],"mappings":";;;;;;;;;;;;;;;;iBAiBiB;;EAEf,GAAG,GAAG,cAAc,UAAU,QAAQ,KAAK,QAAQ;;EAGnD,MAAM,cAAc,aAAa;;EAGjC,WAAW,cAAc,sBAAsB;;;;;;;;;;;;EAa/C,UAAU,cAAc,4BAA4B;;EAGpD,YAAY,eAAe;;;;;EAM3B,YAAY,cAAc,oBAAoB;;;iBAI/B;EACf;EACA;;;iBAIe;;;;;;EAMf,YACE,eACA;IAAS;IAAkB;IAAkB,QAAQ;MACpD;EACH,YAAY,eAAe,QAAQ;;EAEnC,oBAAoB,eAAe,QAAQ;;EAE3C,eAAe,QAAQ;;EAEvB,cAAc,SAAS,YAAY;;iBAGpB;;EAEf;EACA;EACA;EACA,SAAS;EACT;;EAEA,OAAO,eAAe;EACtB;;;;;;EAMA;;EAEA,SAAS;;;;;;EAMT;;EAEA,WAAW;;;YAID;;;;;;iBAOK;;;;;EAKf,QAAQ,aAAa,SAAS;;EAE9B;;EAEA,OAAO;;;;;;EAMP,eAAe;;;;;;;iBAQA;EACf;EACA;;iBAGe;EACf,KAAK,SAAS,kBAAkB,eAAe;;;;;;;;;iBAUhC;;EAEf,SAAS;IACP;IACA;IACA;IACA;MACE;;EAEJ,aAAa;IACX;IACA;IACA;IACA;IACA;MACE;;EAEJ,iBAAiB,SAAS,kBAAkB,QAAQ;;EAEpD,aAAa,SAAS,iBAAiB;IAAU;MAAoB,aAAa;;EAElF,UAAU;IACR;IACA;IACA;IACA,QAAQ;IACR;;IAEA;MACE;;;;;;;;;iBAUW;EACf,SAAS;IACP,SAAS;IACT;IACA,OAAO,eAAe;MACpB,eAAe;;;iBAIJ;;;;;;;;EAQf,KAAK,eAAe,SAAS,eAAe,uBAAuB,aAAa;;;iBAIjE;;EAEf;;EAEA;;EAEA,MAAM,eAAe;EACrB;;EAEA;;;;;;;iBAQe;EACf,OAAO,YAAY,mBAAmB;;iBAGvB;EACf;;EAEA;;;;;;;EAOA;EACA,MAAM;EACN,OAAO;EACP,UAAU;EACV,QAAQ;;EAER,UAAU;;EAEV,YAAY;;EAEZ,WAAW;;;;;;;YAQD;EACN;;EACA;EAAkB;;EAClB;;EACA;;EACA"}
|
package/dist/index.cjs
CHANGED
|
@@ -2,9 +2,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
const require_hash = require("./hash.cjs");
|
|
3
3
|
const require_dsl_action = require("./dsl/action.cjs");
|
|
4
4
|
const require_dsl_refs = require("./dsl/refs.cjs");
|
|
5
|
-
const require_templates = require("./templates.cjs");
|
|
6
5
|
const require_dsl_template = require("./dsl/template.cjs");
|
|
7
6
|
const require_dsl_condition = require("./dsl/condition.cjs");
|
|
7
|
+
const require_email = require("./email.cjs");
|
|
8
|
+
const require_templates = require("./templates.cjs");
|
|
8
9
|
const require_dsl_flow = require("./dsl/flow.cjs");
|
|
9
10
|
const require_dsl_trigger = require("./dsl/trigger.cjs");
|
|
10
11
|
const require_ir = require("./ir.cjs");
|
|
@@ -17,6 +18,7 @@ const require_plan = require("./plan.cjs");
|
|
|
17
18
|
const require_runtime = require("./runtime.cjs");
|
|
18
19
|
exports.ActionIR = require_ir.ActionIR;
|
|
19
20
|
exports.BundleIR = require_ir.BundleIR;
|
|
21
|
+
exports.CHANNEL_OF = require_templates.CHANNEL_OF;
|
|
20
22
|
exports.ChannelIR = require_ir.ChannelIR;
|
|
21
23
|
exports.ConditionIR = require_ir.ConditionIR;
|
|
22
24
|
exports.ConfigCompileError = require_config.ConfigCompileError;
|
|
@@ -41,7 +43,11 @@ exports.WorkflowIR = require_ir.WorkflowIR;
|
|
|
41
43
|
exports.action = require_dsl_action.action;
|
|
42
44
|
exports.and = require_dsl_condition.and;
|
|
43
45
|
exports.apnsEnvironment = require_config.apnsEnvironment;
|
|
46
|
+
exports.assertEmailAddress = require_email.assertEmailAddress;
|
|
47
|
+
exports.assertEmailConfig = require_email.assertEmailConfig;
|
|
48
|
+
exports.assertEmailMetadata = require_email.assertEmailMetadata;
|
|
44
49
|
exports.assertSupportedSchema = require_templates.assertSupportedSchema;
|
|
50
|
+
exports.assertUnsubscribeUrl = require_email.assertUnsubscribeUrl;
|
|
45
51
|
exports.between = require_dsl_condition.between;
|
|
46
52
|
exports.canonicalJSON = require_hash.canonicalJSON;
|
|
47
53
|
exports.checkEvent = require_contract.checkEvent;
|
|
@@ -56,11 +62,12 @@ exports.eq = require_dsl_condition.eq;
|
|
|
56
62
|
exports.event = require_dsl_refs.event;
|
|
57
63
|
exports.exists = require_dsl_condition.exists;
|
|
58
64
|
exports.flow = require_dsl_flow.flow;
|
|
59
|
-
exports.formatEmailAddress =
|
|
65
|
+
exports.formatEmailAddress = require_email.formatEmailAddress;
|
|
60
66
|
exports.fullHash = require_hash.fullHash;
|
|
61
67
|
exports.gt = require_dsl_condition.gt;
|
|
62
68
|
exports.gte = require_dsl_condition.gte;
|
|
63
69
|
exports.inArray = require_dsl_condition.inArray;
|
|
70
|
+
exports.indexTemplates = require_templates.indexTemplates;
|
|
64
71
|
exports.isConfig = require_config.isConfig;
|
|
65
72
|
exports.isContract = require_contract.isContract;
|
|
66
73
|
exports.isDiscordTemplate = require_templates.isDiscordTemplate;
|
|
@@ -68,6 +75,9 @@ exports.isEmailTemplate = require_templates.isEmailTemplate;
|
|
|
68
75
|
exports.isPushTemplate = require_templates.isPushTemplate;
|
|
69
76
|
exports.isSemanticChange = require_plan.isSemanticChange;
|
|
70
77
|
exports.isSlackTemplate = require_templates.isSlackTemplate;
|
|
78
|
+
exports.isTemplate = require_templates.isTemplate;
|
|
79
|
+
exports.isUnsubscribeLink = require_email.isUnsubscribeLink;
|
|
80
|
+
exports.lookupTemplate = require_templates.lookupTemplate;
|
|
71
81
|
exports.lt = require_dsl_condition.lt;
|
|
72
82
|
exports.lte = require_dsl_condition.lte;
|
|
73
83
|
exports.ne = require_dsl_condition.ne;
|
|
@@ -86,6 +96,7 @@ exports.registryValidator = require_templates.registryValidator;
|
|
|
86
96
|
exports.renderDiscordContent = require_templates.renderDiscordContent;
|
|
87
97
|
exports.renderPushContent = require_templates.renderPushContent;
|
|
88
98
|
exports.renderSlackContent = require_templates.renderSlackContent;
|
|
99
|
+
exports.resolveEmail = require_email.resolveEmail;
|
|
89
100
|
exports.resolveRuntime = require_runtime.resolveRuntime;
|
|
90
101
|
exports.segment = require_dsl_condition.segment;
|
|
91
102
|
exports.semanticHash = require_hash.semanticHash;
|
|
@@ -94,7 +105,6 @@ exports.slackTemplate = require_templates.slackTemplate;
|
|
|
94
105
|
exports.stripMeta = require_hash.stripMeta;
|
|
95
106
|
exports.stripProvenance = require_hash.stripProvenance;
|
|
96
107
|
exports.template = require_dsl_template.template;
|
|
97
|
-
exports.templates = require_dsl_template.templates;
|
|
98
108
|
exports.trigger = require_dsl_trigger.trigger;
|
|
99
109
|
exports.user = require_dsl_refs.user;
|
|
100
110
|
exports.workflow = require_dsl_workflow.workflow;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ActionIR, BundleIR, ChannelIR, ConditionIR, DurationIR, GoalIR, IR_VERSION, MetaIR, NodeIR, NodeMetaIR, PropValueIR, PropertyOperatorIR, ScalarIR, SegmentIR, SourceLocIR, TemplateIR, TriggerIR, UserPropertyRefIR, WeekdayIR, WorkflowIR } from "./ir.cjs";
|
|
2
|
-
import {
|
|
2
|
+
import { EmailAddress, EmailConfig, ResolvedEmail, assertEmailAddress, assertEmailConfig, assertEmailMetadata, assertUnsubscribeUrl, formatEmailAddress, isUnsubscribeLink, resolveEmail } from "./email.cjs";
|
|
3
|
+
import { AnyTemplate, CHANNEL_OF, ChannelTemplate, DiscordContent, DiscordTemplate, EmailMetadata, EmailTemplate, EmailTemplateDefinition, PropsSchema, PushContent, PushTemplate, PushTemplateDefinition, ResolvedProps, SlackContent, SlackTemplate, TemplateChannel, TemplateIssue, TemplateRegistry, TemplateValidationError, WebhookTemplateDefinition, assertSupportedSchema, discordTemplate, emailTemplate, indexTemplates, isDiscordTemplate, isEmailTemplate, isPushTemplate, isSlackTemplate, isTemplate, lookupTemplate, parseTemplateProps, pushTemplate, registryValidator, renderDiscordContent, renderPushContent, renderSlackContent, slackTemplate } from "./templates.cjs";
|
|
3
4
|
import { ActionContext, ActionHandler, ActionRef, action } from "./dsl/action.cjs";
|
|
4
5
|
import { Duration, EventMap, TimeOfDay, UserPropertyBase, Weekday } from "./dsl/base.cjs";
|
|
5
6
|
import { EventRef, EventRefs, MessageArgs, PayloadRef, PayloadRefNode, PayloadRefs, PropInput, PropsInput, UserPropertyRef, UserRefs, event, user } from "./dsl/refs.cjs";
|
|
6
|
-
import { Channel, EmptyProps, PropsOf, TemplateFactory, TemplateRef,
|
|
7
|
+
import { Channel, EmptyProps, PropsOf, TemplateFactory, TemplateRef, template } from "./dsl/template.cjs";
|
|
7
8
|
import { Condition, PayloadWhere, PerformedOptions, SegmentDefinition, SegmentRef, and, between, contains, eq, exists, gt, gte, inArray, lt, lte, ne, not, notBetween, notContains, notExists, notInArray, or, performed, reachable, segment } from "./dsl/condition.cjs";
|
|
8
9
|
import { BranchArm, BranchCase, EmitArgs, EmitPayload, Flow, FlowBuilder, PreferOptions, PushOptions, SubFlow, flow } from "./dsl/flow.cjs";
|
|
9
10
|
import { DateTime, EventTriggerOptions, TriggerFactory, TriggerRef, trigger } from "./dsl/trigger.cjs";
|
|
@@ -12,7 +13,7 @@ import { compileBundle } from "./dsl/bundle.cjs";
|
|
|
12
13
|
import "./dsl/index.cjs";
|
|
13
14
|
import { Contract, ContractDefinition, ContractIssue, ContractResult, ContractValidationError, DeclaredOutput, EventPayload, ProfilePatch, checkEvent, defineContract, isContract } from "./contract.cjs";
|
|
14
15
|
import { JourneyMode, JourneyRuntimeConfig, JourneyRuntimeOptions, resolveRuntime } from "./runtime.cjs";
|
|
15
|
-
import { ApnsConfig, ConfigCompileError, DatabaseConfig,
|
|
16
|
+
import { ApnsConfig, ConfigCompileError, DatabaseConfig, FcmConfig, JourneyConfig, JourneyConfigDefinition, WebPushConfig, apnsEnvironment, compileConfig, defineConfig, isConfig } from "./config.cjs";
|
|
16
17
|
import { canonicalJSON, fullHash, semanticHash, sha256Hex, stripMeta, stripProvenance } from "./hash.cjs";
|
|
17
18
|
import { BundlePlan, ChangeStatus, NodeChange, ResourceChange, WorkflowChange, isSemanticChange, plan } from "./plan.cjs";
|
|
18
|
-
export { type ActionContext, type ActionHandler, ActionIR, type ActionRef, AnyTemplate, ApnsConfig, type BranchArm, type BranchCase, BundleIR, BundlePlan, ChangeStatus, type Channel, ChannelIR, type Condition, ConditionIR, ConfigCompileError, Contract, ContractDefinition, ContractIssue, ContractResult, ContractValidationError, DatabaseConfig, type DateTime, DeclaredOutput, DiscordContent, DiscordTemplate, type Duration, DurationIR, EmailAddress, EmailConfig, EmailTemplate, EmailTemplateDefinition, type EmitArgs, type EmitPayload, type EmptyProps, type EventMap, EventPayload, type EventRef, type EventRefs, type EventTriggerOptions, FcmConfig, type Flow, type FlowBuilder, GoalIR, type GoalOptions, IR_VERSION, JourneyConfig, JourneyConfigDefinition, JourneyMode, JourneyRuntimeConfig, JourneyRuntimeOptions, type MessageArgs, MetaIR, NodeChange, NodeIR, NodeMetaIR, type PayloadRef, type PayloadRefNode, type PayloadRefs, type PayloadWhere, type PerformedOptions, type PreferOptions, ProfilePatch, type PropInput, PropValueIR, PropertyOperatorIR, type PropsInput, type PropsOf, PropsSchema, PushContent, type PushOptions, PushTemplate, PushTemplateDefinition, ResolvedProps, ResourceChange, ScalarIR, type SegmentDefinition, SegmentIR, type SegmentRef, SlackContent, SlackTemplate, SourceLocIR, type SubFlow, TemplateChannel, type TemplateFactory, TemplateIR, TemplateIssue, type TemplateRef,
|
|
19
|
+
export { type ActionContext, type ActionHandler, ActionIR, type ActionRef, AnyTemplate, ApnsConfig, type BranchArm, type BranchCase, BundleIR, BundlePlan, CHANNEL_OF, ChangeStatus, type Channel, ChannelIR, ChannelTemplate, type Condition, ConditionIR, ConfigCompileError, Contract, ContractDefinition, ContractIssue, ContractResult, ContractValidationError, DatabaseConfig, type DateTime, DeclaredOutput, DiscordContent, DiscordTemplate, type Duration, DurationIR, EmailAddress, EmailConfig, EmailMetadata, EmailTemplate, EmailTemplateDefinition, type EmitArgs, type EmitPayload, type EmptyProps, type EventMap, EventPayload, type EventRef, type EventRefs, type EventTriggerOptions, FcmConfig, type Flow, type FlowBuilder, GoalIR, type GoalOptions, IR_VERSION, JourneyConfig, JourneyConfigDefinition, JourneyMode, JourneyRuntimeConfig, JourneyRuntimeOptions, type MessageArgs, MetaIR, NodeChange, NodeIR, NodeMetaIR, type PayloadRef, type PayloadRefNode, type PayloadRefs, type PayloadWhere, type PerformedOptions, type PreferOptions, ProfilePatch, type PropInput, PropValueIR, PropertyOperatorIR, type PropsInput, type PropsOf, PropsSchema, PushContent, type PushOptions, PushTemplate, PushTemplateDefinition, ResolvedEmail, ResolvedProps, ResourceChange, ScalarIR, type SegmentDefinition, SegmentIR, type SegmentRef, SlackContent, SlackTemplate, SourceLocIR, type SubFlow, TemplateChannel, type TemplateFactory, TemplateIR, TemplateIssue, type TemplateRef, TemplateRegistry, TemplateValidationError, type TimeOfDay, type TriggerFactory, TriggerIR, type TriggerRef, type UserPropertyBase, type UserPropertyRef, UserPropertyRefIR, type UserRefs, WebPushConfig, WebhookTemplateDefinition, type Weekday, WeekdayIR, type WorkflowBuilder, WorkflowChange, type WorkflowDefinition, WorkflowIR, action, and, apnsEnvironment, assertEmailAddress, assertEmailConfig, assertEmailMetadata, assertSupportedSchema, assertUnsubscribeUrl, between, canonicalJSON, checkEvent, compileBundle, compileConfig, contains, defineConfig, defineContract, discordTemplate, emailTemplate, eq, event, exists, flow, formatEmailAddress, fullHash, gt, gte, inArray, indexTemplates, isConfig, isContract, isDiscordTemplate, isEmailTemplate, isPushTemplate, isSemanticChange, isSlackTemplate, isTemplate, isUnsubscribeLink, lookupTemplate, lt, lte, ne, not, notBetween, notContains, notExists, notInArray, or, parseTemplateProps, performed, plan, pushTemplate, reachable, registryValidator, renderDiscordContent, renderPushContent, renderSlackContent, resolveEmail, resolveRuntime, segment, semanticHash, sha256Hex, slackTemplate, stripMeta, stripProvenance, template, trigger, user, workflow };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ActionIR, BundleIR, ChannelIR, ConditionIR, DurationIR, GoalIR, IR_VERSION, MetaIR, NodeIR, NodeMetaIR, PropValueIR, PropertyOperatorIR, ScalarIR, SegmentIR, SourceLocIR, TemplateIR, TriggerIR, UserPropertyRefIR, WeekdayIR, WorkflowIR } from "./ir.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { EmailAddress, EmailConfig, ResolvedEmail, assertEmailAddress, assertEmailConfig, assertEmailMetadata, assertUnsubscribeUrl, formatEmailAddress, isUnsubscribeLink, resolveEmail } from "./email.mjs";
|
|
3
|
+
import { AnyTemplate, CHANNEL_OF, ChannelTemplate, DiscordContent, DiscordTemplate, EmailMetadata, EmailTemplate, EmailTemplateDefinition, PropsSchema, PushContent, PushTemplate, PushTemplateDefinition, ResolvedProps, SlackContent, SlackTemplate, TemplateChannel, TemplateIssue, TemplateRegistry, TemplateValidationError, WebhookTemplateDefinition, assertSupportedSchema, discordTemplate, emailTemplate, indexTemplates, isDiscordTemplate, isEmailTemplate, isPushTemplate, isSlackTemplate, isTemplate, lookupTemplate, parseTemplateProps, pushTemplate, registryValidator, renderDiscordContent, renderPushContent, renderSlackContent, slackTemplate } from "./templates.mjs";
|
|
3
4
|
import { ActionContext, ActionHandler, ActionRef, action } from "./dsl/action.mjs";
|
|
4
5
|
import { Duration, EventMap, TimeOfDay, UserPropertyBase, Weekday } from "./dsl/base.mjs";
|
|
5
6
|
import { EventRef, EventRefs, MessageArgs, PayloadRef, PayloadRefNode, PayloadRefs, PropInput, PropsInput, UserPropertyRef, UserRefs, event, user } from "./dsl/refs.mjs";
|
|
6
|
-
import { Channel, EmptyProps, PropsOf, TemplateFactory, TemplateRef,
|
|
7
|
+
import { Channel, EmptyProps, PropsOf, TemplateFactory, TemplateRef, template } from "./dsl/template.mjs";
|
|
7
8
|
import { Condition, PayloadWhere, PerformedOptions, SegmentDefinition, SegmentRef, and, between, contains, eq, exists, gt, gte, inArray, lt, lte, ne, not, notBetween, notContains, notExists, notInArray, or, performed, reachable, segment } from "./dsl/condition.mjs";
|
|
8
9
|
import { BranchArm, BranchCase, EmitArgs, EmitPayload, Flow, FlowBuilder, PreferOptions, PushOptions, SubFlow, flow } from "./dsl/flow.mjs";
|
|
9
10
|
import { DateTime, EventTriggerOptions, TriggerFactory, TriggerRef, trigger } from "./dsl/trigger.mjs";
|
|
@@ -12,7 +13,7 @@ import { compileBundle } from "./dsl/bundle.mjs";
|
|
|
12
13
|
import "./dsl/index.mjs";
|
|
13
14
|
import { Contract, ContractDefinition, ContractIssue, ContractResult, ContractValidationError, DeclaredOutput, EventPayload, ProfilePatch, checkEvent, defineContract, isContract } from "./contract.mjs";
|
|
14
15
|
import { JourneyMode, JourneyRuntimeConfig, JourneyRuntimeOptions, resolveRuntime } from "./runtime.mjs";
|
|
15
|
-
import { ApnsConfig, ConfigCompileError, DatabaseConfig,
|
|
16
|
+
import { ApnsConfig, ConfigCompileError, DatabaseConfig, FcmConfig, JourneyConfig, JourneyConfigDefinition, WebPushConfig, apnsEnvironment, compileConfig, defineConfig, isConfig } from "./config.mjs";
|
|
16
17
|
import { canonicalJSON, fullHash, semanticHash, sha256Hex, stripMeta, stripProvenance } from "./hash.mjs";
|
|
17
18
|
import { BundlePlan, ChangeStatus, NodeChange, ResourceChange, WorkflowChange, isSemanticChange, plan } from "./plan.mjs";
|
|
18
|
-
export { type ActionContext, type ActionHandler, ActionIR, type ActionRef, AnyTemplate, ApnsConfig, type BranchArm, type BranchCase, BundleIR, BundlePlan, ChangeStatus, type Channel, ChannelIR, type Condition, ConditionIR, ConfigCompileError, Contract, ContractDefinition, ContractIssue, ContractResult, ContractValidationError, DatabaseConfig, type DateTime, DeclaredOutput, DiscordContent, DiscordTemplate, type Duration, DurationIR, EmailAddress, EmailConfig, EmailTemplate, EmailTemplateDefinition, type EmitArgs, type EmitPayload, type EmptyProps, type EventMap, EventPayload, type EventRef, type EventRefs, type EventTriggerOptions, FcmConfig, type Flow, type FlowBuilder, GoalIR, type GoalOptions, IR_VERSION, JourneyConfig, JourneyConfigDefinition, JourneyMode, JourneyRuntimeConfig, JourneyRuntimeOptions, type MessageArgs, MetaIR, NodeChange, NodeIR, NodeMetaIR, type PayloadRef, type PayloadRefNode, type PayloadRefs, type PayloadWhere, type PerformedOptions, type PreferOptions, ProfilePatch, type PropInput, PropValueIR, PropertyOperatorIR, type PropsInput, type PropsOf, PropsSchema, PushContent, type PushOptions, PushTemplate, PushTemplateDefinition, ResolvedProps, ResourceChange, ScalarIR, type SegmentDefinition, SegmentIR, type SegmentRef, SlackContent, SlackTemplate, SourceLocIR, type SubFlow, TemplateChannel, type TemplateFactory, TemplateIR, TemplateIssue, type TemplateRef,
|
|
19
|
+
export { type ActionContext, type ActionHandler, ActionIR, type ActionRef, AnyTemplate, ApnsConfig, type BranchArm, type BranchCase, BundleIR, BundlePlan, CHANNEL_OF, ChangeStatus, type Channel, ChannelIR, ChannelTemplate, type Condition, ConditionIR, ConfigCompileError, Contract, ContractDefinition, ContractIssue, ContractResult, ContractValidationError, DatabaseConfig, type DateTime, DeclaredOutput, DiscordContent, DiscordTemplate, type Duration, DurationIR, EmailAddress, EmailConfig, EmailMetadata, EmailTemplate, EmailTemplateDefinition, type EmitArgs, type EmitPayload, type EmptyProps, type EventMap, EventPayload, type EventRef, type EventRefs, type EventTriggerOptions, FcmConfig, type Flow, type FlowBuilder, GoalIR, type GoalOptions, IR_VERSION, JourneyConfig, JourneyConfigDefinition, JourneyMode, JourneyRuntimeConfig, JourneyRuntimeOptions, type MessageArgs, MetaIR, NodeChange, NodeIR, NodeMetaIR, type PayloadRef, type PayloadRefNode, type PayloadRefs, type PayloadWhere, type PerformedOptions, type PreferOptions, ProfilePatch, type PropInput, PropValueIR, PropertyOperatorIR, type PropsInput, type PropsOf, PropsSchema, PushContent, type PushOptions, PushTemplate, PushTemplateDefinition, ResolvedEmail, ResolvedProps, ResourceChange, ScalarIR, type SegmentDefinition, SegmentIR, type SegmentRef, SlackContent, SlackTemplate, SourceLocIR, type SubFlow, TemplateChannel, type TemplateFactory, TemplateIR, TemplateIssue, type TemplateRef, TemplateRegistry, TemplateValidationError, type TimeOfDay, type TriggerFactory, TriggerIR, type TriggerRef, type UserPropertyBase, type UserPropertyRef, UserPropertyRefIR, type UserRefs, WebPushConfig, WebhookTemplateDefinition, type Weekday, WeekdayIR, type WorkflowBuilder, WorkflowChange, type WorkflowDefinition, WorkflowIR, action, and, apnsEnvironment, assertEmailAddress, assertEmailConfig, assertEmailMetadata, assertSupportedSchema, assertUnsubscribeUrl, between, canonicalJSON, checkEvent, compileBundle, compileConfig, contains, defineConfig, defineContract, discordTemplate, emailTemplate, eq, event, exists, flow, formatEmailAddress, fullHash, gt, gte, inArray, indexTemplates, isConfig, isContract, isDiscordTemplate, isEmailTemplate, isPushTemplate, isSemanticChange, isSlackTemplate, isTemplate, isUnsubscribeLink, lookupTemplate, lt, lte, ne, not, notBetween, notContains, notExists, notInArray, or, parseTemplateProps, performed, plan, pushTemplate, reachable, registryValidator, renderDiscordContent, renderPushContent, renderSlackContent, resolveEmail, resolveRuntime, segment, semanticHash, sha256Hex, slackTemplate, stripMeta, stripProvenance, template, trigger, user, workflow };
|
package/dist/index.mjs
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { canonicalJSON, fullHash, semanticHash, sha256Hex, stripMeta, stripProvenance } from "./hash.mjs";
|
|
2
2
|
import { action } from "./dsl/action.mjs";
|
|
3
3
|
import { event, user } from "./dsl/refs.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { template, templates } from "./dsl/template.mjs";
|
|
4
|
+
import { template } from "./dsl/template.mjs";
|
|
6
5
|
import { and, between, contains, eq, exists, gt, gte, inArray, lt, lte, ne, not, notBetween, notContains, notExists, notInArray, or, performed, reachable, segment } from "./dsl/condition.mjs";
|
|
6
|
+
import { assertEmailAddress, assertEmailConfig, assertEmailMetadata, assertUnsubscribeUrl, formatEmailAddress, isUnsubscribeLink, resolveEmail } from "./email.mjs";
|
|
7
|
+
import { CHANNEL_OF, TemplateValidationError, assertSupportedSchema, discordTemplate, emailTemplate, indexTemplates, isDiscordTemplate, isEmailTemplate, isPushTemplate, isSlackTemplate, isTemplate, lookupTemplate, parseTemplateProps, pushTemplate, registryValidator, renderDiscordContent, renderPushContent, renderSlackContent, slackTemplate } from "./templates.mjs";
|
|
7
8
|
import { flow } from "./dsl/flow.mjs";
|
|
8
9
|
import { trigger } from "./dsl/trigger.mjs";
|
|
9
10
|
import { ActionIR, BundleIR, ChannelIR, ConditionIR, DurationIR, GoalIR, IR_VERSION, MetaIR, NodeIR, NodeMetaIR, PropValueIR, PropertyOperatorIR, ScalarIR, SegmentIR, SourceLocIR, TemplateIR, TriggerIR, UserPropertyRefIR, WeekdayIR, WorkflowIR } from "./ir.mjs";
|
|
10
11
|
import { workflow } from "./dsl/workflow.mjs";
|
|
11
12
|
import { compileBundle } from "./dsl/bundle.mjs";
|
|
12
13
|
import "./dsl/index.mjs";
|
|
13
|
-
import { ConfigCompileError, apnsEnvironment, compileConfig, defineConfig,
|
|
14
|
+
import { ConfigCompileError, apnsEnvironment, compileConfig, defineConfig, isConfig } from "./config.mjs";
|
|
14
15
|
import { ContractValidationError, checkEvent, defineContract, isContract } from "./contract.mjs";
|
|
15
16
|
import { isSemanticChange, plan } from "./plan.mjs";
|
|
16
17
|
import { resolveRuntime } from "./runtime.mjs";
|
|
17
|
-
export { ActionIR, BundleIR, ChannelIR, ConditionIR, ConfigCompileError, ContractValidationError, DurationIR, GoalIR, IR_VERSION, MetaIR, NodeIR, NodeMetaIR, PropValueIR, PropertyOperatorIR, ScalarIR, SegmentIR, SourceLocIR, TemplateIR, TemplateValidationError, TriggerIR, UserPropertyRefIR, WeekdayIR, WorkflowIR, action, and, apnsEnvironment, assertSupportedSchema, between, canonicalJSON, checkEvent, compileBundle, compileConfig, contains, defineConfig, defineContract, discordTemplate, emailTemplate, eq, event, exists, flow, formatEmailAddress, fullHash, gt, gte, inArray, isConfig, isContract, isDiscordTemplate, isEmailTemplate, isPushTemplate, isSemanticChange, isSlackTemplate, lt, lte, ne, not, notBetween, notContains, notExists, notInArray, or, parseTemplateProps, performed, plan, pushTemplate, reachable, registryValidator, renderDiscordContent, renderPushContent, renderSlackContent, resolveRuntime, segment, semanticHash, sha256Hex, slackTemplate, stripMeta, stripProvenance, template,
|
|
18
|
+
export { ActionIR, BundleIR, CHANNEL_OF, ChannelIR, ConditionIR, ConfigCompileError, ContractValidationError, DurationIR, GoalIR, IR_VERSION, MetaIR, NodeIR, NodeMetaIR, PropValueIR, PropertyOperatorIR, ScalarIR, SegmentIR, SourceLocIR, TemplateIR, TemplateValidationError, TriggerIR, UserPropertyRefIR, WeekdayIR, WorkflowIR, action, and, apnsEnvironment, assertEmailAddress, assertEmailConfig, assertEmailMetadata, assertSupportedSchema, assertUnsubscribeUrl, between, canonicalJSON, checkEvent, compileBundle, compileConfig, contains, defineConfig, defineContract, discordTemplate, emailTemplate, eq, event, exists, flow, formatEmailAddress, fullHash, gt, gte, inArray, indexTemplates, isConfig, isContract, isDiscordTemplate, isEmailTemplate, isPushTemplate, isSemanticChange, isSlackTemplate, isTemplate, isUnsubscribeLink, lookupTemplate, lt, lte, ne, not, notBetween, notContains, notExists, notInArray, or, parseTemplateProps, performed, plan, pushTemplate, reachable, registryValidator, renderDiscordContent, renderPushContent, renderSlackContent, resolveEmail, resolveRuntime, segment, semanticHash, sha256Hex, slackTemplate, stripMeta, stripProvenance, template, trigger, user, workflow };
|
package/dist/push.cjs
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_templates = require("./templates.cjs");
|
|
3
3
|
//#region src/push.ts
|
|
4
|
-
/** A renderer over the registry; a TemplateValidationError means nothing may be sent. */
|
|
4
|
+
/** A renderer over the registry, by template id; a TemplateValidationError means nothing may be sent. */
|
|
5
5
|
function registryPushRenderer(pushes) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return require_templates.renderPushContent(pushes[key], key, props);
|
|
9
|
-
};
|
|
6
|
+
const index = require_templates.indexTemplates("push", pushes);
|
|
7
|
+
return async (id, props) => require_templates.renderPushContent(require_templates.lookupTemplate(index, "push", id), props);
|
|
10
8
|
}
|
|
11
9
|
//#endregion
|
|
12
10
|
exports.registryPushRenderer = registryPushRenderer;
|
package/dist/push.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.cjs","names":["renderPushContent"],"sources":["../src/push.ts"],"sourcesContent":["import type { ScalarIR } from './ir';\nimport {
|
|
1
|
+
{"version":3,"file":"push.cjs","names":["indexTemplates","renderPushContent","lookupTemplate"],"sources":["../src/push.ts"],"sourcesContent":["import type { ScalarIR } from './ir';\nimport {\n type PushContent,\n type PushTemplate,\n indexTemplates,\n lookupTemplate,\n renderPushContent,\n} from './templates';\n\n/**\n * `@shware/workflow/push` — push-notification content. A push is data, not a\n * component: a title and a body the OS renders in its own chrome, built by a\n * `pushTemplate`'s `content(parsedProps)` — final text, never placeholder-\n * expanded, so braces in user data survive. Transport is a separate concern\n * (`@shware/workflow/apns`, `@shware/workflow/fcm`).\n */\n\nexport type RenderedPush = PushContent;\n\nexport type PushRenderer = (\n template: string,\n props: Record<string, ScalarIR | undefined>\n) => Promise<RenderedPush>;\n\n/** A renderer over the registry, by template id; a TemplateValidationError means nothing may be sent. */\nexport function registryPushRenderer(pushes: Readonly<Record<string, PushTemplate>>): PushRenderer {\n const index = indexTemplates('push', pushes);\n return async (id, props) => renderPushContent(lookupTemplate(index, 'push', id), props);\n}\n"],"mappings":";;;;AAyBA,SAAgB,qBAAqB,QAA8D;CACjG,MAAM,QAAQA,kBAAAA,eAAe,QAAQ,MAAM;CAC3C,OAAO,OAAO,IAAI,UAAUC,kBAAAA,kBAAkBC,kBAAAA,eAAe,OAAO,QAAQ,EAAE,GAAG,KAAK;AACxF"}
|
package/dist/push.d.cts
CHANGED
|
@@ -10,7 +10,7 @@ import { PushContent, PushTemplate } from "./templates.cjs";
|
|
|
10
10
|
*/
|
|
11
11
|
export type RenderedPush = PushContent;
|
|
12
12
|
export type PushRenderer = (template: string, props: Record<string, ScalarIR | undefined>) => Promise<RenderedPush>;
|
|
13
|
-
/** A renderer over the registry; a TemplateValidationError means nothing may be sent. */
|
|
14
|
-
export declare function registryPushRenderer(pushes: Record<string, PushTemplate
|
|
13
|
+
/** A renderer over the registry, by template id; a TemplateValidationError means nothing may be sent. */
|
|
14
|
+
export declare function registryPushRenderer(pushes: Readonly<Record<string, PushTemplate>>): PushRenderer;
|
|
15
15
|
//#endregion
|
|
16
16
|
//# sourceMappingURL=push.d.cts.map
|
package/dist/push.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.d.cts","names":[],"sources":["../src/push.ts"],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"push.d.cts","names":[],"sources":["../src/push.ts"],"mappings":";;;;;;;;;;YAiBY,eAAe;YAEf,gBACV,kBACA,OAAO,eAAe,0BACnB,QAAQ;;wBAGG,qBAAqB,QAAQ,SAAS,eAAe,iBAAiB"}
|
package/dist/push.d.mts
CHANGED
|
@@ -10,7 +10,7 @@ import { PushContent, PushTemplate } from "./templates.mjs";
|
|
|
10
10
|
*/
|
|
11
11
|
export type RenderedPush = PushContent;
|
|
12
12
|
export type PushRenderer = (template: string, props: Record<string, ScalarIR | undefined>) => Promise<RenderedPush>;
|
|
13
|
-
/** A renderer over the registry; a TemplateValidationError means nothing may be sent. */
|
|
14
|
-
export declare function registryPushRenderer(pushes: Record<string, PushTemplate
|
|
13
|
+
/** A renderer over the registry, by template id; a TemplateValidationError means nothing may be sent. */
|
|
14
|
+
export declare function registryPushRenderer(pushes: Readonly<Record<string, PushTemplate>>): PushRenderer;
|
|
15
15
|
//#endregion
|
|
16
16
|
//# sourceMappingURL=push.d.mts.map
|
package/dist/push.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.d.mts","names":[],"sources":["../src/push.ts"],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"push.d.mts","names":[],"sources":["../src/push.ts"],"mappings":";;;;;;;;;;YAiBY,eAAe;YAEf,gBACV,kBACA,OAAO,eAAe,0BACnB,QAAQ;;wBAGG,qBAAqB,QAAQ,SAAS,eAAe,iBAAiB"}
|
package/dist/push.mjs
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { renderPushContent } from "./templates.mjs";
|
|
1
|
+
import { indexTemplates, lookupTemplate, renderPushContent } from "./templates.mjs";
|
|
2
2
|
//#region src/push.ts
|
|
3
|
-
/** A renderer over the registry; a TemplateValidationError means nothing may be sent. */
|
|
3
|
+
/** A renderer over the registry, by template id; a TemplateValidationError means nothing may be sent. */
|
|
4
4
|
function registryPushRenderer(pushes) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return renderPushContent(pushes[key], key, props);
|
|
8
|
-
};
|
|
5
|
+
const index = indexTemplates("push", pushes);
|
|
6
|
+
return async (id, props) => renderPushContent(lookupTemplate(index, "push", id), props);
|
|
9
7
|
}
|
|
10
8
|
//#endregion
|
|
11
9
|
export { registryPushRenderer };
|
package/dist/push.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.mjs","names":[],"sources":["../src/push.ts"],"sourcesContent":["import type { ScalarIR } from './ir';\nimport {
|
|
1
|
+
{"version":3,"file":"push.mjs","names":[],"sources":["../src/push.ts"],"sourcesContent":["import type { ScalarIR } from './ir';\nimport {\n type PushContent,\n type PushTemplate,\n indexTemplates,\n lookupTemplate,\n renderPushContent,\n} from './templates';\n\n/**\n * `@shware/workflow/push` — push-notification content. A push is data, not a\n * component: a title and a body the OS renders in its own chrome, built by a\n * `pushTemplate`'s `content(parsedProps)` — final text, never placeholder-\n * expanded, so braces in user data survive. Transport is a separate concern\n * (`@shware/workflow/apns`, `@shware/workflow/fcm`).\n */\n\nexport type RenderedPush = PushContent;\n\nexport type PushRenderer = (\n template: string,\n props: Record<string, ScalarIR | undefined>\n) => Promise<RenderedPush>;\n\n/** A renderer over the registry, by template id; a TemplateValidationError means nothing may be sent. */\nexport function registryPushRenderer(pushes: Readonly<Record<string, PushTemplate>>): PushRenderer {\n const index = indexTemplates('push', pushes);\n return async (id, props) => renderPushContent(lookupTemplate(index, 'push', id), props);\n}\n"],"mappings":";;;AAyBA,SAAgB,qBAAqB,QAA8D;CACjG,MAAM,QAAQ,eAAe,QAAQ,MAAM;CAC3C,OAAO,OAAO,IAAI,UAAU,kBAAkB,eAAe,OAAO,QAAQ,EAAE,GAAG,KAAK;AACxF"}
|
package/dist/react-email.cjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_email = require("./email.cjs");
|
|
2
3
|
const require_templates = require("./templates.cjs");
|
|
4
|
+
const require_email_context = require("./email-context.cjs");
|
|
3
5
|
let react = require("react");
|
|
4
6
|
let react_dom_server = require("react-dom/server");
|
|
5
7
|
//#region src/react-email.ts
|
|
@@ -8,10 +10,14 @@ let react_dom_server = require("react-dom/server");
|
|
|
8
10
|
* registry (`react-dom` is an optional peer dependency; import this subpath
|
|
9
11
|
* only when you use it).
|
|
10
12
|
*
|
|
11
|
-
* The registry
|
|
13
|
+
* The registry holds `emailTemplate({...})` definitions, looked up by their `id`. Props are
|
|
12
14
|
* parsed against the template's schema before the component renders — a
|
|
13
15
|
* failure throws TemplateValidationError and nothing renders — and the
|
|
14
|
-
* component renders as an element
|
|
16
|
+
* component renders as an element inside an `EmailProvider` carrying the
|
|
17
|
+
* template's resolved metadata (`resolveEmail` against the config's `email`),
|
|
18
|
+
* so hooks and context work and a layout's `useEmailContext()` reads the
|
|
19
|
+
* unsubscribe link the email is sent with; the render returns that metadata
|
|
20
|
+
* with the subject and HTML, for the sender. Rendering
|
|
15
21
|
* streams and waits for every Suspense boundary (`allReady`) — react-email's
|
|
16
22
|
* `<Tailwind>` suspends while it compiles the classes, which synchronous
|
|
17
23
|
* static markup cannot wait for — then prepends the XHTML doctype react-email
|
|
@@ -19,13 +25,15 @@ let react_dom_server = require("react-dom/server");
|
|
|
19
25
|
* statically imports prettier and html-to-text for options never used here.
|
|
20
26
|
*/
|
|
21
27
|
const DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
|
|
22
|
-
function registryRenderer(emails) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const template =
|
|
26
|
-
const parsed = require_templates.parseTemplateProps(template,
|
|
27
|
-
const
|
|
28
|
+
function registryRenderer(emails, config) {
|
|
29
|
+
const index = require_templates.indexTemplates("email", emails);
|
|
30
|
+
return async (id, props) => {
|
|
31
|
+
const template = require_templates.lookupTemplate(index, "email", id);
|
|
32
|
+
const parsed = require_templates.parseTemplateProps(template, props);
|
|
33
|
+
const email = require_email.resolveEmail(template, config);
|
|
34
|
+
const element = (0, react.createElement)(require_email_context.EmailProvider, { email }, (0, react.createElement)(template.component, parsed));
|
|
28
35
|
return {
|
|
36
|
+
...email,
|
|
29
37
|
subject: template.subject,
|
|
30
38
|
html: DOCTYPE + await renderToHtml(element)
|
|
31
39
|
};
|
package/dist/react-email.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-email.cjs","names":["parseTemplateProps","createElement","renderToReadableStream"],"sources":["../src/react-email.ts"],"sourcesContent":["import { type ComponentType, type ReactElement, createElement } from 'react';\nimport { renderToReadableStream } from 'react-dom/server';\nimport type { EmailRenderer } from './cloudflare';\nimport { type
|
|
1
|
+
{"version":3,"file":"react-email.cjs","names":["indexTemplates","lookupTemplate","parseTemplateProps","resolveEmail","createElement","EmailProvider","renderToReadableStream"],"sources":["../src/react-email.ts"],"sourcesContent":["import { type ComponentType, type ReactElement, createElement } from 'react';\nimport { renderToReadableStream } from 'react-dom/server';\nimport type { EmailRenderer } from './cloudflare';\nimport { type EmailConfig, resolveEmail } from './email';\nimport { EmailProvider } from './email-context';\nimport {\n type EmailTemplate,\n indexTemplates,\n lookupTemplate,\n parseTemplateProps,\n} from './templates';\n\n/**\n * `@shware/workflow/react-email` — an EmailRenderer over the project's email\n * registry (`react-dom` is an optional peer dependency; import this subpath\n * only when you use it).\n *\n * The registry holds `emailTemplate({...})` definitions, looked up by their `id`. Props are\n * parsed against the template's schema before the component renders — a\n * failure throws TemplateValidationError and nothing renders — and the\n * component renders as an element inside an `EmailProvider` carrying the\n * template's resolved metadata (`resolveEmail` against the config's `email`),\n * so hooks and context work and a layout's `useEmailContext()` reads the\n * unsubscribe link the email is sent with; the render returns that metadata\n * with the subject and HTML, for the sender. Rendering\n * streams and waits for every Suspense boundary (`allReady`) — react-email's\n * `<Tailwind>` suspends while it compiles the classes, which synchronous\n * static markup cannot wait for — then prepends the XHTML doctype react-email\n * uses. @react-email/render itself is avoided because its Workers build\n * statically imports prettier and html-to-text for options never used here.\n */\n\nconst DOCTYPE =\n '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">';\n\nexport function registryRenderer(\n emails: Readonly<Record<string, EmailTemplate>>,\n config?: EmailConfig\n): EmailRenderer {\n const index = indexTemplates('email', emails);\n return async (id, props) => {\n const template = lookupTemplate(index, 'email', id);\n const parsed = parseTemplateProps(template, props);\n const email = resolveEmail(template, config);\n const element = createElement(\n EmailProvider,\n { email },\n createElement(template.component as ComponentType<object>, parsed)\n );\n return { ...email, subject: template.subject, html: DOCTYPE + (await renderToHtml(element)) };\n };\n}\n\n/** Render to a string once every Suspense boundary has resolved; a rendering error rejects. */\nasync function renderToHtml(element: ReactElement): Promise<string> {\n let failure: unknown;\n const stream = await renderToReadableStream(element, {\n onError: (error) => {\n failure = error;\n },\n });\n await stream.allReady;\n const html = await new Response(stream).text();\n if (failure !== undefined) {\n throw failure instanceof Error ? failure : new Error('email render failed', { cause: failure });\n }\n // Streaming a document adds what static markup did not: an HTML5 doctype (the caller prepends\n // the XHTML one email clients expect) and React 19's image preload hints, which mean nothing in\n // an email. Both are dropped, as @react-email/render does.\n return html\n .replace(/^<!DOCTYPE html>/i, '')\n .replace(/<link rel=\"preload\" as=\"image\"[^>]*\\/>/g, '');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,MAAM,UACJ;AAEF,SAAgB,iBACd,QACA,QACe;CACf,MAAM,QAAQA,kBAAAA,eAAe,SAAS,MAAM;CAC5C,OAAO,OAAO,IAAI,UAAU;EAC1B,MAAM,WAAWC,kBAAAA,eAAe,OAAO,SAAS,EAAE;EAClD,MAAM,SAASC,kBAAAA,mBAAmB,UAAU,KAAK;EACjD,MAAM,QAAQC,cAAAA,aAAa,UAAU,MAAM;EAC3C,MAAM,WAAA,GAAUC,MAAAA,cAAAA,CACdC,sBAAAA,eACA,EAAE,MAAM,IAAA,GACRD,MAAAA,cAAAA,CAAc,SAAS,WAAoC,MAAM,CACnE;EACA,OAAO;GAAE,GAAG;GAAO,SAAS,SAAS;GAAS,MAAM,UAAW,MAAM,aAAa,OAAO;EAAG;CAC9F;AACF;;AAGA,eAAe,aAAa,SAAwC;CAClE,IAAI;CACJ,MAAM,SAAS,OAAA,GAAME,iBAAAA,uBAAAA,CAAuB,SAAS,EACnD,UAAU,UAAU;EAClB,UAAU;CACZ,EACF,CAAC;CACD,MAAM,OAAO;CACb,MAAM,OAAO,MAAM,IAAI,SAAS,MAAM,CAAC,CAAC,KAAK;CAC7C,IAAI,YAAY,KAAA,GACd,MAAM,mBAAmB,QAAQ,UAAU,IAAI,MAAM,uBAAuB,EAAE,OAAO,QAAQ,CAAC;CAKhG,OAAO,KACJ,QAAQ,qBAAqB,EAAE,CAAC,CAChC,QAAQ,2CAA2C,EAAE;AAC1D"}
|
package/dist/react-email.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { EmailConfig } from "./email.cjs";
|
|
1
2
|
import { EmailTemplate } from "./templates.cjs";
|
|
2
3
|
import { EmailRenderer } from "./cloudflare/senders.cjs";
|
|
3
4
|
import "./cloudflare/index.cjs";
|
|
4
5
|
//#region src/react-email.d.ts
|
|
5
|
-
export declare function registryRenderer(emails: Record<string, EmailTemplate
|
|
6
|
+
export declare function registryRenderer(emails: Readonly<Record<string, EmailTemplate>>, config?: EmailConfig): EmailRenderer;
|
|
6
7
|
//#endregion
|
|
7
8
|
//# sourceMappingURL=react-email.d.cts.map
|