@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 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
- `COW_DEPLOY_KEY` to a deploy key instead.
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.send({
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
- # publish it and make it the environment's live code
73
- cow deploy --env development
73
+ # upload the project; the server compiles it
74
+ cow push
74
75
 
75
- # rebuild and redeploy on every save
76
- cow dev
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
- Every push creates a numbered release. `cow deploy` makes one release an
80
- environment's current code, `cow rollback` puts the previous one back, and a
81
- run that has already started stays on the release it started on.
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-BcbIxxI-.js";
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
- email: { send: (args) => call({
122
- name: "email.send",
123
- args: {
124
- template: args.template,
125
- props: args.props
126
- }
127
- }) },
128
- webhook: { send: (args) => call({
129
- name: "webhook.send",
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
- environments: journey.environments,
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
@@ -1,4 +1,4 @@
1
- import { a as ManifestOutput, i as JourneyStepOutput, o as TemplateRenderOutput } from "./index-heC1gFE_.js";
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
@@ -1,3 +1,3 @@
1
- import { t as runGuest } from "./driver-M6LQVMr2.js";
1
+ import { t as runGuest } from "./driver-14FnzM-h.js";
2
2
 
3
3
  export { runGuest };
@@ -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.send">;
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.send">;
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.send">;
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.send">;
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.send">;
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.send">;
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.ZodEnum<{
257
- dataProcessing: "dataProcessing";
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 a release instead of silently triggering on every app.
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
  */