@cowliss/cli 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/README.md +16 -9
- package/dist/guest/{driver-M6LQVMr2.js → driver-14FnzM-h.js} +18 -15
- package/dist/guest/driver.d.ts +1 -1
- package/dist/guest/driver.js +1 -1
- package/dist/guest/emails.d.ts +18 -1
- package/dist/guest/{index-heC1gFE_.d.ts → index-BDj02EsQ.d.ts} +12 -15
- package/dist/guest/{journeys-BcbIxxI-.js → journeys-C8j8Sqvl.js} +216 -116
- package/dist/guest/journeys.d.ts +42 -16
- package/dist/guest/journeys.js +1 -1
- package/dist/guest/wasi.js +1 -1
- package/dist/index.js +2185 -1544
- package/examples/abandoned-checkout/journeys/abandoned-checkout.ts +2 -1
- package/examples/abandoned-checkout/scenarios/abandoned-checkout.timeout.json +2 -1
- package/examples/activity-decay/journeys/activity-decay.ts +1 -0
- package/examples/cross-app-pitch/journeys/cross-app-pitch.ts +5 -1
- package/examples/cross-app-pitch/scenarios/cross-app-pitch.json +2 -1
- package/examples/winback/journeys/winback.ts +2 -1
- package/examples/winback/scenarios/winback.json +4 -1
- package/package.json +3 -1
- package/dist/guest/constants-OZrYz4I2.d.ts +0 -42
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ cow whoami
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
`cow login` opens the dashboard and caches a session token. In CI, set
|
|
29
|
-
`
|
|
29
|
+
`COW_PIPELINE_KEY` to a pipeline key instead.
|
|
30
30
|
|
|
31
31
|
## Journeys and emails as code
|
|
32
32
|
|
|
@@ -45,6 +45,7 @@ import { defineJourney } from "@cowliss/cli/journeys";
|
|
|
45
45
|
export default defineJourney({
|
|
46
46
|
trigger: { event: "checkout_started" },
|
|
47
47
|
purpose: "emailMarketing",
|
|
48
|
+
senderIdentity: "cowliss-default",
|
|
48
49
|
run: async (event, api) => {
|
|
49
50
|
const purchased = await api.waitForEvent("purchase_completed", {
|
|
50
51
|
timeout: "24h",
|
|
@@ -52,7 +53,7 @@ export default defineJourney({
|
|
|
52
53
|
if (purchased) {
|
|
53
54
|
return;
|
|
54
55
|
}
|
|
55
|
-
await api.email
|
|
56
|
+
await api.send.email({
|
|
56
57
|
template: "abandoned-checkout",
|
|
57
58
|
props: { checkoutUrl: event.properties.checkoutUrl },
|
|
58
59
|
});
|
|
@@ -69,16 +70,22 @@ cow test abandoned-checkout --scenario scenarios/cart.json
|
|
|
69
70
|
# typecheck and bundle, no API call
|
|
70
71
|
cow build
|
|
71
72
|
|
|
72
|
-
#
|
|
73
|
-
cow
|
|
73
|
+
# upload the project; the server compiles it
|
|
74
|
+
cow push
|
|
74
75
|
|
|
75
|
-
#
|
|
76
|
-
cow
|
|
76
|
+
# what the server holds, and what is on where
|
|
77
|
+
cow status
|
|
78
|
+
|
|
79
|
+
# turn it on, per environment
|
|
80
|
+
cow enable abandoned-checkout --env development
|
|
77
81
|
```
|
|
78
82
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
A push creates a new version of every journey and template whose code
|
|
84
|
+
changed, and changes no flag: `cow enable` and `cow disable` are the only
|
|
85
|
+
things that put code in front of anyone. A journey runs its latest version
|
|
86
|
+
that finished compiling, so a push that fails to compile leaves the previous
|
|
87
|
+
one running, and a run that has already started stays on the version it
|
|
88
|
+
started on. To undo, `git revert` and push again.
|
|
82
89
|
|
|
83
90
|
## Admin, and everything else
|
|
84
91
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as manifestOutputSchema, i as journeyStepOutputSchema, o as templateRenderOutputSchema, r as guestInputSchema, t as CapabilityError } from "./journeys-
|
|
1
|
+
import { a as manifestOutputSchema, i as journeyStepOutputSchema, o as templateRenderOutputSchema, r as guestInputSchema, t as CapabilityError } from "./journeys-C8j8Sqvl.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { createElement } from "react";
|
|
4
4
|
import { renderToStaticMarkup } from "react-dom/server.browser";
|
|
@@ -78,7 +78,7 @@ function formatLogArg(value) {
|
|
|
78
78
|
* The returned state is the driver's window into the run: the pending
|
|
79
79
|
* call, the captured logs, and the clock the shims read.
|
|
80
80
|
*/
|
|
81
|
-
function createApi(input) {
|
|
81
|
+
function createApi(input, journey) {
|
|
82
82
|
let cursor = 0;
|
|
83
83
|
let markSuspended = () => {};
|
|
84
84
|
const state = {
|
|
@@ -118,17 +118,20 @@ function createApi(input) {
|
|
|
118
118
|
timeout: options.timeout
|
|
119
119
|
}
|
|
120
120
|
}),
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
args
|
|
131
|
-
|
|
121
|
+
send: {
|
|
122
|
+
email: (args) => call({
|
|
123
|
+
name: "send.email",
|
|
124
|
+
args: {
|
|
125
|
+
template: args.template,
|
|
126
|
+
props: args.props,
|
|
127
|
+
senderIdentity: args.senderIdentity ?? journey.senderIdentity
|
|
128
|
+
}
|
|
129
|
+
}),
|
|
130
|
+
webhook: (args) => call({
|
|
131
|
+
name: "send.webhook",
|
|
132
|
+
args
|
|
133
|
+
})
|
|
134
|
+
},
|
|
132
135
|
traits: {
|
|
133
136
|
set: (key, value) => call({
|
|
134
137
|
name: "traits.set",
|
|
@@ -5569,7 +5572,7 @@ function readManifest(module) {
|
|
|
5569
5572
|
kind: "journey",
|
|
5570
5573
|
trigger: journey.trigger,
|
|
5571
5574
|
purpose: journey.purpose,
|
|
5572
|
-
|
|
5575
|
+
senderIdentity: journey.senderIdentity,
|
|
5573
5576
|
tags: journey.tags
|
|
5574
5577
|
});
|
|
5575
5578
|
}
|
|
@@ -5584,7 +5587,7 @@ function readManifest(module) {
|
|
|
5584
5587
|
}
|
|
5585
5588
|
async function runJourneyStep(module, input) {
|
|
5586
5589
|
const journey = asJourney(module);
|
|
5587
|
-
const { api, state } = createApi(input);
|
|
5590
|
+
const { api, state } = createApi(input, journey);
|
|
5588
5591
|
const restore = installShims({
|
|
5589
5592
|
clock: state.clock,
|
|
5590
5593
|
seed: input.seed
|
package/dist/guest/driver.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ManifestOutput, i as JourneyStepOutput, o as TemplateRenderOutput } from "./index-
|
|
1
|
+
import { a as ManifestOutput, i as JourneyStepOutput, o as TemplateRenderOutput } from "./index-BDj02EsQ.js";
|
|
2
2
|
//#region src/guest/driver.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* The in-process driver: JSON in, JSON out (spec: Guest protocol). One
|
package/dist/guest/driver.js
CHANGED
package/dist/guest/emails.d.ts
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
|
-
import { r as SendClass } from "./constants-OZrYz4I2.js";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import { ReactElement } from "react";
|
|
3
|
+
//#region ../../packages/shared/src/constants.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The two classes of send, declared on the template rather than passed per
|
|
6
|
+
* call so the class cannot drift between two sends of the same message.
|
|
7
|
+
*
|
|
8
|
+
* Marketing is everything a journey sends on the org's behalf: it carries
|
|
9
|
+
* the RFC 8058 unsubscribe headers and runs the full gate list.
|
|
10
|
+
* Transactional is the developer's own operational mail (a receipt, an
|
|
11
|
+
* export-is-ready notice): it carries neither header and skips consent and
|
|
12
|
+
* the per-user frequency cap, because an unsubscribe link on an invoice is
|
|
13
|
+
* wrong and a receipt must not silently vanish for anyone who once left a
|
|
14
|
+
* newsletter. Suppression, the quota, the sending pause, and the from-domain
|
|
15
|
+
* check still apply to both: those bound cost and protect the shared SES
|
|
16
|
+
* account, and none of them are about what the recipient asked for.
|
|
17
|
+
*/
|
|
18
|
+
declare const SEND_CLASSES: readonly ["marketing", "transactional"];
|
|
19
|
+
type SendClass = (typeof SEND_CLASSES)[number];
|
|
20
|
+
//#endregion
|
|
4
21
|
//#region src/guest/emails.d.ts
|
|
5
22
|
/** A template's subject line, computed from the props it declares. */
|
|
6
23
|
type Subject<Schema extends z.ZodType> = (props: z.infer<Schema>) => string;
|
|
@@ -30,13 +30,14 @@ declare const journeyStepOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
30
30
|
timeout: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
31
31
|
}, z.core.$strict>;
|
|
32
32
|
}, z.core.$strip>, z.ZodObject<{
|
|
33
|
-
name: z.ZodLiteral<"email
|
|
33
|
+
name: z.ZodLiteral<"send.email">;
|
|
34
34
|
args: z.ZodObject<{
|
|
35
35
|
template: z.ZodString;
|
|
36
36
|
props: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
37
|
+
senderIdentity: z.ZodString;
|
|
37
38
|
}, z.core.$strict>;
|
|
38
39
|
}, z.core.$strip>, z.ZodObject<{
|
|
39
|
-
name: z.ZodLiteral<"webhook
|
|
40
|
+
name: z.ZodLiteral<"send.webhook">;
|
|
40
41
|
args: z.ZodObject<{
|
|
41
42
|
destination: z.ZodString;
|
|
42
43
|
payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
@@ -119,13 +120,14 @@ declare const journeyStepOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
119
120
|
timeout: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
120
121
|
}, z.core.$strict>;
|
|
121
122
|
}, z.core.$strip>, z.ZodObject<{
|
|
122
|
-
name: z.ZodLiteral<"email
|
|
123
|
+
name: z.ZodLiteral<"send.email">;
|
|
123
124
|
args: z.ZodObject<{
|
|
124
125
|
template: z.ZodString;
|
|
125
126
|
props: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
127
|
+
senderIdentity: z.ZodString;
|
|
126
128
|
}, z.core.$strict>;
|
|
127
129
|
}, z.core.$strip>, z.ZodObject<{
|
|
128
|
-
name: z.ZodLiteral<"webhook
|
|
130
|
+
name: z.ZodLiteral<"send.webhook">;
|
|
129
131
|
args: z.ZodObject<{
|
|
130
132
|
destination: z.ZodString;
|
|
131
133
|
payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
@@ -177,13 +179,14 @@ declare const journeyStepOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
177
179
|
timeout: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
178
180
|
}, z.core.$strict>;
|
|
179
181
|
}, z.core.$strip>, z.ZodObject<{
|
|
180
|
-
name: z.ZodLiteral<"email
|
|
182
|
+
name: z.ZodLiteral<"send.email">;
|
|
181
183
|
args: z.ZodObject<{
|
|
182
184
|
template: z.ZodString;
|
|
183
185
|
props: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
186
|
+
senderIdentity: z.ZodString;
|
|
184
187
|
}, z.core.$strict>;
|
|
185
188
|
}, z.core.$strip>, z.ZodObject<{
|
|
186
|
-
name: z.ZodLiteral<"webhook
|
|
189
|
+
name: z.ZodLiteral<"send.webhook">;
|
|
187
190
|
args: z.ZodObject<{
|
|
188
191
|
destination: z.ZodString;
|
|
189
192
|
payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
@@ -253,14 +256,8 @@ declare const manifestOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
253
256
|
}, z.core.$strict>, z.ZodObject<{
|
|
254
257
|
segment: z.ZodString;
|
|
255
258
|
}, z.core.$strict>]>;
|
|
256
|
-
purpose: z.
|
|
257
|
-
|
|
258
|
-
emailMarketing: "emailMarketing";
|
|
259
|
-
}>;
|
|
260
|
-
environments: z.ZodArray<z.ZodEnum<{
|
|
261
|
-
development: "development";
|
|
262
|
-
production: "production";
|
|
263
|
-
}>>;
|
|
259
|
+
purpose: z.ZodString;
|
|
260
|
+
senderIdentity: z.ZodOptional<z.ZodString>;
|
|
264
261
|
kind: z.ZodLiteral<"journey">;
|
|
265
262
|
}, z.core.$strip>, z.ZodObject<{
|
|
266
263
|
tags: z.ZodPipe<z.ZodDefault<z.ZodArray<z.ZodString>>, z.ZodTransform<string[], string[]>>;
|
|
@@ -281,7 +278,7 @@ type ManifestOutput = z.infer<typeof manifestOutputSchema>;
|
|
|
281
278
|
* reuses it.
|
|
282
279
|
*
|
|
283
280
|
* Both members are strict, so a journey holding the retired `source` key
|
|
284
|
-
* fails to compile
|
|
281
|
+
* fails to compile instead of silently triggering on every app.
|
|
285
282
|
* There is deliberately no pipe filter: a trigger narrows by the app the
|
|
286
283
|
* write is attributed to, the same token a segment definition names.
|
|
287
284
|
*/
|