@cowliss/cli 0.10.0 → 0.12.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.
Files changed (117) hide show
  1. package/{examples → blueprints}/abandoned-checkout/journeys/abandoned-checkout.ts +1 -1
  2. package/{examples → blueprints}/activity-decay/journeys/activity-decay.ts +1 -1
  3. package/blueprints/ecommerce/emails/_shell.tsx +133 -0
  4. package/blueprints/ecommerce/emails/abandoned-checkout-last-call.tsx +46 -0
  5. package/blueprints/ecommerce/emails/abandoned-checkout.tsx +46 -0
  6. package/blueprints/ecommerce/emails/order-thanks.tsx +44 -0
  7. package/blueprints/ecommerce/emails/replenishment.tsx +40 -0
  8. package/blueprints/ecommerce/emails/review-request.tsx +44 -0
  9. package/blueprints/ecommerce/emails/vip-thanks.tsx +51 -0
  10. package/blueprints/ecommerce/emails/welcome.tsx +48 -0
  11. package/blueprints/ecommerce/emails/winback-offer.tsx +41 -0
  12. package/blueprints/ecommerce/emails/winback-reminder.tsx +45 -0
  13. package/blueprints/ecommerce/journeys/_helpers.ts +14 -0
  14. package/blueprints/ecommerce/journeys/abandoned-checkout.ts +44 -0
  15. package/blueprints/ecommerce/journeys/first-order-thanks.ts +40 -0
  16. package/blueprints/ecommerce/journeys/replenishment.ts +39 -0
  17. package/blueprints/ecommerce/journeys/vip.ts +29 -0
  18. package/blueprints/ecommerce/journeys/welcome.ts +42 -0
  19. package/blueprints/ecommerce/journeys/winback.ts +35 -0
  20. package/blueprints/ecommerce/scenarios/abandoned-checkout.last-call.json +30 -0
  21. package/blueprints/ecommerce/scenarios/abandoned-checkout.recovered.json +24 -0
  22. package/blueprints/ecommerce/scenarios/abandoned-checkout.reminded.json +33 -0
  23. package/blueprints/ecommerce/scenarios/first-order-thanks.delivered.json +35 -0
  24. package/blueprints/ecommerce/scenarios/first-order-thanks.never-delivered.json +21 -0
  25. package/blueprints/ecommerce/scenarios/replenishment.due.json +21 -0
  26. package/blueprints/ecommerce/scenarios/replenishment.reordered.json +20 -0
  27. package/blueprints/ecommerce/scenarios/vip.crossed.json +22 -0
  28. package/blueprints/ecommerce/scenarios/welcome.new-shopper.json +21 -0
  29. package/blueprints/ecommerce/scenarios/winback.returned.json +26 -0
  30. package/blueprints/ecommerce/scenarios/winback.still-gone.json +30 -0
  31. package/blueprints/ecommerce/segments/first-time-buyers.ts +24 -0
  32. package/blueprints/ecommerce/segments/lapsed.ts +27 -0
  33. package/blueprints/ecommerce/segments/repeat-buyers.ts +18 -0
  34. package/blueprints/ecommerce/segments/vip-customers.ts +20 -0
  35. package/blueprints/mobile-game/emails/_shell.tsx +138 -0
  36. package/blueprints/mobile-game/emails/day-two-return.tsx +41 -0
  37. package/blueprints/mobile-game/emails/lapsed-offer.tsx +41 -0
  38. package/blueprints/mobile-game/emails/lapsed-reminder.tsx +48 -0
  39. package/blueprints/mobile-game/emails/purchase-receipt.tsx +47 -0
  40. package/blueprints/mobile-game/emails/spender-thanks.tsx +53 -0
  41. package/blueprints/mobile-game/emails/stuck-hint.tsx +48 -0
  42. package/blueprints/mobile-game/emails/tutorial-nudge.tsx +48 -0
  43. package/blueprints/mobile-game/journeys/_helpers.ts +14 -0
  44. package/blueprints/mobile-game/journeys/day-two-return.ts +40 -0
  45. package/blueprints/mobile-game/journeys/first-purchase.ts +34 -0
  46. package/blueprints/mobile-game/journeys/lapsed-player.ts +39 -0
  47. package/blueprints/mobile-game/journeys/onboarding.ts +35 -0
  48. package/blueprints/mobile-game/journeys/spender-care.ts +41 -0
  49. package/blueprints/mobile-game/journeys/stuck.ts +58 -0
  50. package/blueprints/mobile-game/scenarios/day-two-return.came-back.json +16 -0
  51. package/blueprints/mobile-game/scenarios/day-two-return.no-show.json +21 -0
  52. package/blueprints/mobile-game/scenarios/first-purchase.paid.json +21 -0
  53. package/blueprints/mobile-game/scenarios/lapsed-player.returned.json +26 -0
  54. package/blueprints/mobile-game/scenarios/lapsed-player.still-gone.json +30 -0
  55. package/blueprints/mobile-game/scenarios/onboarding.finished.json +16 -0
  56. package/blueprints/mobile-game/scenarios/onboarding.stalled.json +21 -0
  57. package/blueprints/mobile-game/scenarios/spender-care.crossed.json +22 -0
  58. package/blueprints/mobile-game/scenarios/stuck.cleared.json +16 -0
  59. package/blueprints/mobile-game/scenarios/stuck.three-fails.json +30 -0
  60. package/blueprints/mobile-game/segments/active-players.ts +30 -0
  61. package/blueprints/mobile-game/segments/lapsed-players.ts +29 -0
  62. package/blueprints/mobile-game/segments/new-players.ts +31 -0
  63. package/blueprints/mobile-game/segments/paying-players.ts +21 -0
  64. package/blueprints/saas-trial/emails/_shell.tsx +151 -0
  65. package/blueprints/saas-trial/emails/activated.tsx +61 -0
  66. package/blueprints/saas-trial/emails/activation-help.tsx +49 -0
  67. package/blueprints/saas-trial/emails/activation-nudge.tsx +48 -0
  68. package/blueprints/saas-trial/emails/invite-your-team.tsx +58 -0
  69. package/blueprints/saas-trial/emails/trial-converted.tsx +57 -0
  70. package/blueprints/saas-trial/emails/trial-ended.tsx +52 -0
  71. package/blueprints/saas-trial/emails/trial-ending-activated.tsx +53 -0
  72. package/blueprints/saas-trial/emails/trial-ending-unactivated.tsx +54 -0
  73. package/blueprints/saas-trial/emails/trial-welcome.tsx +57 -0
  74. package/blueprints/saas-trial/journeys/_helpers.ts +14 -0
  75. package/blueprints/saas-trial/journeys/activated.ts +42 -0
  76. package/blueprints/saas-trial/journeys/activation-nudge.ts +44 -0
  77. package/blueprints/saas-trial/journeys/invite-your-team.ts +42 -0
  78. package/blueprints/saas-trial/journeys/trial-ended.ts +39 -0
  79. package/blueprints/saas-trial/journeys/trial-ending.ts +58 -0
  80. package/blueprints/saas-trial/journeys/trial-welcome.ts +35 -0
  81. package/blueprints/saas-trial/scenarios/activated.first-project.json +14 -0
  82. package/blueprints/saas-trial/scenarios/activated.second-project.json +12 -0
  83. package/blueprints/saas-trial/scenarios/activation-nudge.activated-late.json +16 -0
  84. package/blueprints/saas-trial/scenarios/activation-nudge.activated.json +8 -0
  85. package/blueprints/saas-trial/scenarios/activation-nudge.stalled.json +23 -0
  86. package/blueprints/saas-trial/scenarios/invite-your-team.alone.json +16 -0
  87. package/blueprints/saas-trial/scenarios/invite-your-team.invited.json +8 -0
  88. package/blueprints/saas-trial/scenarios/trial-ended.converted.json +16 -0
  89. package/blueprints/saas-trial/scenarios/trial-ended.expired.json +13 -0
  90. package/blueprints/saas-trial/scenarios/trial-ending.activated.json +20 -0
  91. package/blueprints/saas-trial/scenarios/trial-ending.converted.json +12 -0
  92. package/blueprints/saas-trial/scenarios/trial-ending.unactivated.json +16 -0
  93. package/blueprints/saas-trial/scenarios/trial-welcome.started.json +13 -0
  94. package/blueprints/saas-trial/segments/activated-users.ts +25 -0
  95. package/blueprints/saas-trial/segments/converted.ts +28 -0
  96. package/blueprints/saas-trial/segments/trialing.ts +26 -0
  97. package/blueprints/saas-trial/segments/unactivated.ts +27 -0
  98. package/{examples → blueprints}/winback/journeys/winback.ts +18 -7
  99. package/blueprints/winback/scenarios/winback.bought-again.json +14 -0
  100. package/{examples/winback/scenarios/winback.json → blueprints/winback/scenarios/winback.lapsed.json} +2 -5
  101. package/dist/guest/{driver-poSdZIj8.js → driver-B_pjmy5g.js} +2 -1
  102. package/dist/guest/driver-emails.js +3 -2
  103. package/dist/guest/driver.d.ts +1 -1
  104. package/dist/guest/driver.js +1 -1
  105. package/dist/guest/{index-EqBCZnpq.d.ts → index-DADBwPaG.d.ts} +63 -12
  106. package/dist/guest/{journeys-F8Yk8s1P.js → journeys-v2-Djgs8U91.js} +87 -71
  107. package/dist/guest/journeys.d.ts +1 -1
  108. package/dist/guest/journeys.js +58 -1
  109. package/dist/guest/segments.d.ts +81 -0
  110. package/dist/guest/segments.js +35 -0
  111. package/dist/index.js +1476 -638
  112. package/package.json +6 -2
  113. /package/{examples → blueprints}/abandoned-checkout/emails/abandoned-checkout.tsx +0 -0
  114. /package/{examples → blueprints}/abandoned-checkout/scenarios/abandoned-checkout.recovered.json +0 -0
  115. /package/{examples → blueprints}/abandoned-checkout/scenarios/abandoned-checkout.timeout.json +0 -0
  116. /package/{examples → blueprints}/activity-decay/scenarios/activity-decay.json +0 -0
  117. /package/{examples → blueprints}/winback/emails/winback.tsx +0 -0
@@ -1,3 +1,60 @@
1
- import { n as defineJourney, t as CapabilityError } from "./journeys-F8Yk8s1P.js";
1
+ import { a as manifestJourneySchema } from "./journeys-v2-Djgs8U91.js";
2
2
 
3
+ //#region src/guest/journeys.ts
4
+ /**
5
+ * A capability that failed host-side (an unknown webhook, invalid
6
+ * props, a profile that is not there). The failure is journaled, so a
7
+ * journey that catches it takes the same branch on every replay.
8
+ */
9
+ var CapabilityError = class extends Error {
10
+ code;
11
+ constructor(code, message) {
12
+ super(message);
13
+ this.name = "CapabilityError";
14
+ this.code = code;
15
+ }
16
+ };
17
+ /**
18
+ * The config half of a journey, validated with the same schema the release
19
+ * manifest is validated with, so a bad trigger, a malformed purpose key, or
20
+ * a `from` that is not an address fails at build time rather than at the
21
+ * first execution. Whether the org declares that purpose, and whether it may
22
+ * send from that domain, are questions only the push can answer.
23
+ */
24
+ const journeyConfigSchema = manifestJourneySchema.pick({
25
+ trigger: true,
26
+ purpose: true,
27
+ enrollment: true,
28
+ description: true,
29
+ from: true,
30
+ tags: true
31
+ });
32
+ /**
33
+ * Author a journey. Throws at definition time on an invalid config.
34
+ *
35
+ * There is no environment gate here: an organization has one data space, and
36
+ * a journey runs wherever it is on and nowhere else (ADR 0011, ADR 0013).
37
+ *
38
+ * There is no app gate either. A journey belongs to the one app `cow.json`
39
+ * names, so it only ever sees that app's events, profiles and segments
40
+ * (ADR 0022); a trigger naming an app is refused rather than honoured.
41
+ */
42
+ function defineJourney(input) {
43
+ const config = journeyConfigSchema.parse({
44
+ trigger: input.trigger,
45
+ purpose: input.purpose,
46
+ enrollment: input.enrollment,
47
+ description: input.description,
48
+ from: input.from,
49
+ tags: input.tags
50
+ });
51
+ if (config.from === void 0) throw new Error("defineJourney needs a \"from\": the address this journey sends as, on a domain your organization verified. Add and verify it on the Domains page (Settings, Domains). For example from: \"Billing <billing@your-domain.com>\".");
52
+ return {
53
+ ...config,
54
+ from: config.from,
55
+ run: input.run
56
+ };
57
+ }
58
+
59
+ //#endregion
3
60
  export { CapabilityError, defineJourney };
@@ -0,0 +1,81 @@
1
+ import { i as manifestSegmentSchema } from "./index-DADBwPaG.js";
2
+ import { z } from "zod";
3
+ //#region src/guest/segments.d.ts
4
+ /**
5
+ * The authoring surface tenant segments import (`@cowliss/cli/segments`):
6
+ * one `segments/<key>.ts` file is one audience, named by its filename and
7
+ * enrolled from by any journey in the same repository (ADR 0023).
8
+ *
9
+ * A segment compiles to nothing. The definition is a predicate list the
10
+ * evaluator folds host-side, so this file is read once by `cow build` and
11
+ * never bundled into the sandbox — but it is authored beside journeys and
12
+ * imported the same way, so like `./journeys` it reaches for nothing but
13
+ * `@cowliss/shared/journeys-v2`.
14
+ */
15
+ /** A predicate list as an author writes it, before zod fills its defaults. */
16
+ type DefinitionInput = z.input<typeof manifestSegmentSchema>["definition"];
17
+ /** One predicate over a trait or over the recipient's event history. */
18
+ type Predicate = DefinitionInput["predicates"][number];
19
+ declare const segmentConfigSchema: z.ZodObject<{
20
+ tags: z.ZodPipe<z.ZodDefault<z.ZodArray<z.ZodString>>, z.ZodTransform<string[], string[]>>;
21
+ description: z.ZodOptional<z.ZodString>;
22
+ definition: z.ZodObject<{
23
+ match: z.ZodDefault<z.ZodEnum<{
24
+ all: "all";
25
+ any: "any";
26
+ }>>;
27
+ predicates: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
28
+ kind: z.ZodLiteral<"trait">;
29
+ name: z.ZodString;
30
+ op: z.ZodEnum<{
31
+ contains: "contains";
32
+ eq: "eq";
33
+ exists: "exists";
34
+ gt: "gt";
35
+ gte: "gte";
36
+ lt: "lt";
37
+ lte: "lte";
38
+ neq: "neq";
39
+ notExists: "notExists";
40
+ }>;
41
+ value: z.ZodOptional<z.ZodUnknown>;
42
+ }, z.core.$strip>, z.ZodObject<{
43
+ kind: z.ZodLiteral<"event">;
44
+ name: z.ZodString;
45
+ op: z.ZodEnum<{
46
+ notPerformed: "notPerformed";
47
+ performed: "performed";
48
+ }>;
49
+ atLeast: z.ZodDefault<z.ZodNumber>;
50
+ withinDays: z.ZodOptional<z.ZodNumber>;
51
+ }, z.core.$strip>], "kind">>;
52
+ }, z.core.$strict>;
53
+ }, z.core.$strip>;
54
+ /**
55
+ * A segment as `defineSegment` returns it. `cow build` reads it off the
56
+ * module's default export and copies it into the manifest under the file's
57
+ * key; the push writes one row from it.
58
+ */
59
+ type Segment = z.infer<typeof segmentConfigSchema>;
60
+ /**
61
+ * Author a segment. Throws at definition time on an invalid predicate list,
62
+ * so a typo is a build error with the file in hand rather than an audience
63
+ * that quietly matches nobody.
64
+ *
65
+ * Reach for this when two journeys enroll from the same audience: they then
66
+ * name one file instead of repeating a predicate list that can drift. A
67
+ * segment only one journey uses belongs in that journey's trigger, where the
68
+ * code and the audience cannot disagree (ADR 0016).
69
+ *
70
+ * There is no app here, and no consent purpose: a segment belongs to the one
71
+ * app its repository pushes to, and evaluates that app's profiles and events
72
+ * and no others (ADR 0022).
73
+ */
74
+ declare function defineSegment(input: DefinitionInput & {
75
+ /** One plain sentence about who is in it. Shown wherever it is read. */
76
+ description?: string;
77
+ /** The author's labels; the dashboard's only grouping. */
78
+ tags?: string[];
79
+ }): Segment;
80
+ //#endregion
81
+ export { Predicate, Segment, defineSegment };
@@ -0,0 +1,35 @@
1
+ import { o as manifestSegmentSchema } from "./journeys-v2-Djgs8U91.js";
2
+
3
+ //#region src/guest/segments.ts
4
+ const segmentConfigSchema = manifestSegmentSchema.pick({
5
+ tags: true,
6
+ description: true,
7
+ definition: true
8
+ });
9
+ /**
10
+ * Author a segment. Throws at definition time on an invalid predicate list,
11
+ * so a typo is a build error with the file in hand rather than an audience
12
+ * that quietly matches nobody.
13
+ *
14
+ * Reach for this when two journeys enroll from the same audience: they then
15
+ * name one file instead of repeating a predicate list that can drift. A
16
+ * segment only one journey uses belongs in that journey's trigger, where the
17
+ * code and the audience cannot disagree (ADR 0016).
18
+ *
19
+ * There is no app here, and no consent purpose: a segment belongs to the one
20
+ * app its repository pushes to, and evaluates that app's profiles and events
21
+ * and no others (ADR 0022).
22
+ */
23
+ function defineSegment(input) {
24
+ return segmentConfigSchema.parse({
25
+ description: input.description,
26
+ tags: input.tags,
27
+ definition: {
28
+ match: input.match,
29
+ predicates: input.predicates
30
+ }
31
+ });
32
+ }
33
+
34
+ //#endregion
35
+ export { defineSegment };