@robbeverhelst/do 1.285.0 → 1.287.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 (2) hide show
  1. package/dist/do.js +360 -10
  2. package/package.json +1 -1
package/dist/do.js CHANGED
@@ -3974,7 +3974,8 @@ var notificationType = pgEnum("notification_type", [
3974
3974
  "echo",
3975
3975
  "card",
3976
3976
  "bank_link",
3977
- "import_failed"
3977
+ "import_failed",
3978
+ "animal_ask"
3978
3979
  ]);
3979
3980
  var notificationDomain = pgEnum("notification_domain", [
3980
3981
  "task",
@@ -5096,6 +5097,67 @@ var seatingProposals = pgTable("seating_proposals", {
5096
5097
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
5097
5098
  }, (t) => [index("seating_proposals_list_idx").on(t.guestListId)]);
5098
5099
 
5100
+ // ../../packages/schema/src/db/mail.ts
5101
+ var mailCampaignStatus = pgEnum("mail_campaign_status", [
5102
+ "draft",
5103
+ "sending",
5104
+ "sent",
5105
+ "cancelled"
5106
+ ]);
5107
+ var mailDeliveryStatus = pgEnum("mail_delivery_status", [
5108
+ "queued",
5109
+ "sending",
5110
+ "sent",
5111
+ "delivered",
5112
+ "bounced",
5113
+ "failed",
5114
+ "skipped"
5115
+ ]);
5116
+ var mailCampaigns = pgTable("mail_campaigns", {
5117
+ id: text("id").primaryKey(),
5118
+ tenantId: text("tenant_id").notNull().references(() => tenants.id),
5119
+ guestListId: text("guest_list_id").references(() => guestLists.id, { onDelete: "cascade" }),
5120
+ kind: text("kind").notNull().default("message"),
5121
+ template: text("template").notNull(),
5122
+ data: jsonb("data").$type().notNull().default({}),
5123
+ replyTo: text("reply_to"),
5124
+ status: mailCampaignStatus("status").notNull().default("draft"),
5125
+ createdByUserId: text("created_by_user_id").references(() => users.id),
5126
+ testSentAt: timestamp("test_sent_at", { withTimezone: true }),
5127
+ startedAt: timestamp("started_at", { withTimezone: true }),
5128
+ finishedAt: timestamp("finished_at", { withTimezone: true }),
5129
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5130
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5131
+ }, (t) => [
5132
+ index("mail_campaigns_tenant_idx").on(t.tenantId),
5133
+ index("mail_campaigns_status_idx").on(t.status)
5134
+ ]);
5135
+ var mailDeliveries = pgTable("mail_deliveries", {
5136
+ id: text("id").primaryKey(),
5137
+ tenantId: text("tenant_id").notNull().references(() => tenants.id),
5138
+ campaignId: text("campaign_id").notNull().references(() => mailCampaigns.id, { onDelete: "cascade" }),
5139
+ contactId: text("contact_id").references(() => contacts.id),
5140
+ householdId: text("household_id").references(() => households.id),
5141
+ toEmail: text("to_email").notNull(),
5142
+ language: text("language").notNull().default("nl"),
5143
+ data: jsonb("data").$type().notNull().default({}),
5144
+ status: mailDeliveryStatus("status").notNull().default("queued"),
5145
+ transport: text("transport"),
5146
+ providerMessageId: text("provider_message_id"),
5147
+ attempts: integer("attempts").notNull().default(0),
5148
+ error: text("error"),
5149
+ sentAt: timestamp("sent_at", { withTimezone: true }),
5150
+ deliveredAt: timestamp("delivered_at", { withTimezone: true }),
5151
+ bouncedAt: timestamp("bounced_at", { withTimezone: true }),
5152
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
5153
+ }, (t) => [
5154
+ index("mail_deliveries_campaign_status_idx").on(t.campaignId, t.status),
5155
+ index("mail_deliveries_sent_at_idx").on(t.sentAt),
5156
+ index("mail_deliveries_household_idx").on(t.householdId),
5157
+ uniqueIndex("mail_deliveries_provider_message_uniq").on(t.providerMessageId),
5158
+ uniqueIndex("mail_deliveries_campaign_email_uniq").on(t.campaignId, t.toEmail)
5159
+ ]);
5160
+
5099
5161
  // ../../packages/schema/src/db/calendar.ts
5100
5162
  var calendarLinkPurpose = pgEnum("calendar_link_purpose", ["block", "deadline"]);
5101
5163
  var calendarEventLinks = pgTable("calendar_event_links", {
@@ -21227,8 +21289,10 @@ var houseAssetSchema = object({
21227
21289
  trail: array(houseTrailStepSchema),
21228
21290
  parts: array(houseAssetPartSchema),
21229
21291
  linked: array(houseAssetLinkSchema),
21230
- warrantyUntil: day.nullable()
21292
+ warrantyUntil: day.nullable(),
21293
+ visibility: _enum2(NODE_VISIBILITY_VALUES).default("space")
21231
21294
  });
21295
+ var setAssetVisibilityInputSchema = object({ visibility: _enum2(NODE_VISIBILITY_VALUES) }).strict();
21232
21296
  var linkAssetPartInputSchema = object({ inventoryItemId: ulidSchema }).strict();
21233
21297
  var lendAssetInputSchema = object({
21234
21298
  direction: _enum2(["lent", "borrowed"]),
@@ -21533,10 +21597,12 @@ var postRunSchema = object({
21533
21597
  steps: array(runStepSchema).max(12).optional()
21534
21598
  });
21535
21599
  var POST_RECEIPT_ABOUT_VALUES = ["red_flags", "saved"];
21600
+ var POST_RECEIPT_SOURCE_MAX = 80;
21536
21601
  var postReceiptInputSchema = object({
21537
21602
  nodeId: ulidSchema,
21538
21603
  parts: array(ulidSchema).min(1).max(10).optional(),
21539
- about: _enum2(POST_RECEIPT_ABOUT_VALUES).optional()
21604
+ about: _enum2(POST_RECEIPT_ABOUT_VALUES).optional(),
21605
+ source: string2().trim().min(1).max(POST_RECEIPT_SOURCE_MAX).optional()
21540
21606
  }).strict();
21541
21607
  var postReceiptPartSchema = object({
21542
21608
  id: string2(),
@@ -21548,7 +21614,8 @@ var postReceiptSchema = object({
21548
21614
  nodeType: string2(),
21549
21615
  parts: array(string2()).optional(),
21550
21616
  partNodes: array(postReceiptPartSchema).optional(),
21551
- about: _enum2(POST_RECEIPT_ABOUT_VALUES).optional()
21617
+ about: _enum2(POST_RECEIPT_ABOUT_VALUES).optional(),
21618
+ source: string2().optional()
21552
21619
  });
21553
21620
  var POST_TITLE_MAX = 200;
21554
21621
  var postTitleSchema = string2().trim().min(1).max(POST_TITLE_MAX);
@@ -23749,15 +23816,30 @@ var recipeUsedInSchema = object({
23749
23816
  eatenAt: exports_coerce.date(),
23750
23817
  mealType: mealLogTypeSchema,
23751
23818
  servings: number2().nullable(),
23752
- alongside: array(string2())
23819
+ alongside: array(string2()),
23820
+ sides: array(object({
23821
+ label: string2(),
23822
+ grams: number2(),
23823
+ kcal: number2(),
23824
+ source: mealItemSourceSchema
23825
+ })).default([]),
23826
+ after: array(object({ kind: _enum2(["tired", "symptom"]), label: string2() })).default([])
23753
23827
  })),
23828
+ eatenCount: number2().int().nonnegative().default(0),
23754
23829
  plans: array(object({
23755
23830
  id: ulidSchema,
23756
23831
  plannedFor: exports_coerce.date(),
23757
23832
  mealType: mealTypeSchema,
23758
23833
  servings: number2().int().nullable()
23759
- }))
23834
+ })),
23835
+ shopping: array(object({
23836
+ listId: ulidSchema,
23837
+ title: string2(),
23838
+ items: number2().int().positive(),
23839
+ addedAt: exports_coerce.date()
23840
+ })).default([])
23760
23841
  });
23842
+ var recipeIngredientMatchInputSchema = object({ foodId: string2().min(1) }).strict();
23761
23843
 
23762
23844
  // ../../packages/schema/src/contracts/meal-plans.ts
23763
23845
  var mealPlanSchema = createSelectSchema(mealPlans, {
@@ -24765,6 +24847,9 @@ var insuranceFieldsSchema = object({
24765
24847
  deductible: amount4,
24766
24848
  extras: array(text4).max(30),
24767
24849
  claimPhone: phone,
24850
+ claimHours: text4,
24851
+ reportWithinDays: number2().int().min(1).max(365),
24852
+ leakSearchLimit: amount4,
24768
24853
  brokerContactId: ulidSchema,
24769
24854
  renewalDate: keyDateDaySchema,
24770
24855
  exclusionsSummary: longText
@@ -25009,14 +25094,20 @@ var incidentPolicySchema = refSchema.extend({
25009
25094
  broker: refSchema.nullable(),
25010
25095
  claimPhone: string2().nullable(),
25011
25096
  policyNo: string2().nullable(),
25012
- deductible: number2().nullable()
25097
+ deductible: number2().nullable(),
25098
+ claimHours: string2().nullable().default(null),
25099
+ reportWithinDays: number2().nullable().default(null),
25100
+ leakSearchLimit: number2().nullable().default(null),
25101
+ covers: boolean3().default(false),
25102
+ readByAgent: boolean3().default(false)
25013
25103
  });
25014
25104
  var incidentViewSchema = incidentSchema.extend({
25015
25105
  title: string2(),
25016
25106
  visibility: _enum2(NODE_VISIBILITY_VALUES),
25017
25107
  policy: incidentPolicySchema.nullable(),
25018
25108
  place: refSchema.nullable(),
25019
- fileCount: number2().int().nonnegative()
25109
+ fileCount: number2().int().nonnegative(),
25110
+ stepNotes: record(string2(), string2()).default({})
25020
25111
  });
25021
25112
  var createIncidentInputSchema = object({
25022
25113
  id: ulidSchema,
@@ -25629,7 +25720,8 @@ var animalIdsSchema = object({
25629
25720
  passportNoMasked: string2().trim().min(1).max(40).optional(),
25630
25721
  ringNo: string2().trim().min(1).max(40).optional(),
25631
25722
  ringYear: number2().int().min(1900).max(2200).optional(),
25632
- ringIssuer: string2().trim().min(1).max(80).optional()
25723
+ ringIssuer: string2().trim().min(1).max(80).optional(),
25724
+ ringType: _enum2(["open", "closed"]).optional()
25633
25725
  }).strict();
25634
25726
  function isMaskedNumber(value) {
25635
25727
  const shown = value.replace(/[\s*\u2022xX.-]/g, "");
@@ -25919,6 +26011,7 @@ var animalRoomReadingSchema = object({
25919
26011
  unit: string2().nullable(),
25920
26012
  text: string2().nullable(),
25921
26013
  detail: string2().nullish(),
26014
+ device: string2().nullish(),
25922
26015
  at: exports_coerce.date()
25923
26016
  });
25924
26017
  var animalRoomAlertSchema = object({
@@ -26739,6 +26832,148 @@ var thankYouViewSchema = object({
26739
26832
  thanked: array(thankYouGiftSchema)
26740
26833
  });
26741
26834
 
26835
+ // ../../packages/schema/src/contracts/mail.ts
26836
+ var MAIL_LANGUAGES = ["nl", "pt"];
26837
+ var mailLanguageSchema = _enum2(MAIL_LANGUAGES);
26838
+ var MAIL_CAMPAIGN_STATUSES = ["draft", "sending", "sent", "cancelled"];
26839
+ var mailCampaignStatusSchema = _enum2(MAIL_CAMPAIGN_STATUSES);
26840
+ var MAIL_DELIVERY_STATUSES = [
26841
+ "queued",
26842
+ "sending",
26843
+ "sent",
26844
+ "delivered",
26845
+ "bounced",
26846
+ "failed",
26847
+ "skipped"
26848
+ ];
26849
+ var mailDeliveryStatusSchema = _enum2(MAIL_DELIVERY_STATUSES);
26850
+ var mailCampaignSchema = createSelectSchema(mailCampaigns, {
26851
+ data: record(string2(), unknown()),
26852
+ testSentAt: exports_coerce.date().nullable().default(null),
26853
+ startedAt: exports_coerce.date().nullable(),
26854
+ finishedAt: exports_coerce.date().nullable(),
26855
+ createdAt: exports_coerce.date(),
26856
+ updatedAt: exports_coerce.date()
26857
+ });
26858
+ var mailDeliverySchema = createSelectSchema(mailDeliveries, {
26859
+ data: record(string2(), unknown()),
26860
+ sentAt: exports_coerce.date().nullable(),
26861
+ deliveredAt: exports_coerce.date().nullable(),
26862
+ bouncedAt: exports_coerce.date().nullable(),
26863
+ createdAt: exports_coerce.date()
26864
+ });
26865
+ var mailFooterSchema = object({
26866
+ deleteBy: keyDateDaySchema.optional(),
26867
+ contact: email2().max(320).optional()
26868
+ }).strict();
26869
+ var lineSchema = string2().trim().min(1).max(2000);
26870
+ var mailMessageCopySchema = object({
26871
+ subject: string2().trim().min(1).max(200),
26872
+ heading: string2().trim().min(1).max(200),
26873
+ paragraphs: array(lineSchema).max(20).default([]),
26874
+ button: object({ label: string2().trim().min(1).max(80), url: url() }).strict().nullish()
26875
+ }).strict();
26876
+ var mailMessageDataSchema = object({
26877
+ nl: mailMessageCopySchema,
26878
+ pt: mailMessageCopySchema.optional(),
26879
+ footer: mailFooterSchema.optional()
26880
+ }).strict();
26881
+ var mailDaySchema = object({
26882
+ date: keyDateDaySchema,
26883
+ label: object({
26884
+ nl: string2().trim().min(1).max(120),
26885
+ pt: string2().trim().min(1).max(120).optional()
26886
+ }).strict(),
26887
+ place: string2().trim().min(1).max(200).optional()
26888
+ }).strict();
26889
+ var mailSaveTheDateCopySchema = object({
26890
+ subject: string2().trim().min(1).max(200),
26891
+ heading: string2().trim().min(1).max(200),
26892
+ paragraphs: array(lineSchema).max(20).default([]),
26893
+ button: string2().trim().min(1).max(80)
26894
+ }).strict();
26895
+ var mailSaveTheDateDataSchema = object({
26896
+ nl: mailSaveTheDateCopySchema,
26897
+ pt: mailSaveTheDateCopySchema.optional(),
26898
+ days: array(mailDaySchema).min(1).max(5),
26899
+ calendarTitle: string2().trim().min(1).max(120).optional(),
26900
+ footer: mailFooterSchema.optional()
26901
+ }).strict();
26902
+ var mailSaveTheDateDeliverySchema = object({ link: url().optional() }).strict();
26903
+ var mailProviderEventSchema = looseObject({
26904
+ type: string2().min(1),
26905
+ created_at: string2().optional(),
26906
+ data: looseObject({
26907
+ email_id: string2().min(1),
26908
+ to: array(string2()).optional(),
26909
+ bounce: looseObject({
26910
+ type: string2().optional(),
26911
+ message: string2().optional()
26912
+ }).optional()
26913
+ })
26914
+ });
26915
+ var MAIL_CAMPAIGN_KINDS = ["message", "save_the_date", "invitation"];
26916
+ var mailCampaignKindSchema = _enum2(MAIL_CAMPAIGN_KINDS);
26917
+ var MAIL_TEMPLATES = ["message", "save_the_date"];
26918
+ var mailTemplateSchema = _enum2(MAIL_TEMPLATES);
26919
+ var mailTemplateDataSchemas = {
26920
+ message: mailMessageDataSchema,
26921
+ save_the_date: mailSaveTheDateDataSchema
26922
+ };
26923
+ function mailTemplateDataError(template, data) {
26924
+ const parsed = mailTemplateDataSchemas[template].safeParse(data);
26925
+ return parsed.success ? null : parsed.error.issues[0]?.message ?? "invalid data";
26926
+ }
26927
+ var replyToSchema = email2().max(320);
26928
+ var createMailCampaignInputSchema = object({
26929
+ id: ulidSchema,
26930
+ guestListId: ulidSchema,
26931
+ kind: mailCampaignKindSchema.default("message"),
26932
+ template: mailTemplateSchema.default("message"),
26933
+ data: record(string2(), unknown()),
26934
+ replyTo: replyToSchema.nullish()
26935
+ }).strict().superRefine((input, ctx) => {
26936
+ const error = mailTemplateDataError(input.template, input.data);
26937
+ if (error)
26938
+ ctx.addIssue({ code: "custom", path: ["data"], message: error });
26939
+ });
26940
+ var updateMailCampaignInputSchema = object({
26941
+ kind: mailCampaignKindSchema.optional(),
26942
+ data: record(string2(), unknown()).optional(),
26943
+ replyTo: replyToSchema.nullish()
26944
+ }).strict();
26945
+ var mailCampaignsQuerySchema = object({ guestListId: ulidSchema }).strict();
26946
+ var mailPreviewQuerySchema = object({ language: mailLanguageSchema.default("nl") }).strict();
26947
+ var mailPreviewSchema = object({
26948
+ language: mailLanguageSchema,
26949
+ subject: string2(),
26950
+ html: string2(),
26951
+ text: string2(),
26952
+ attachments: array(string2()).default([])
26953
+ });
26954
+ var mailTestResultSchema = object({ to: array(string2()) });
26955
+ var sendMailCampaignInputSchema = object({ households: number2().int().positive() }).strict();
26956
+ var householdMailStatusSchema = _enum2([
26957
+ "queued",
26958
+ "sent",
26959
+ "delivered",
26960
+ "bounced",
26961
+ "failed",
26962
+ "skipped"
26963
+ ]);
26964
+ var mailRecipientHouseholdSchema = object({
26965
+ householdId: string2().nullable(),
26966
+ name: string2(),
26967
+ language: mailLanguageSchema,
26968
+ addresses: number2().int().nonnegative(),
26969
+ status: householdMailStatusSchema.nullable()
26970
+ });
26971
+ var mailCampaignViewSchema = mailCampaignSchema.extend({
26972
+ households: array(mailRecipientHouseholdSchema),
26973
+ counts: partialRecord(mailDeliveryStatusSchema, number2().int().nonnegative()),
26974
+ readyToSend: boolean3()
26975
+ });
26976
+
26742
26977
  // ../../packages/schema/src/contracts/calendar.ts
26743
26978
  var calendarEventLinkSchema = createSelectSchema(calendarEventLinks, {
26744
26979
  createdAt: exports_coerce.date(),
@@ -28439,7 +28674,7 @@ function parseCapture2(input, now) {
28439
28674
 
28440
28675
  // src/meta.ts
28441
28676
  var CLI_NAME = "do";
28442
- var VERSION = "1.285.0";
28677
+ var VERSION = "1.287.0";
28443
28678
  var API_PREFIX = "/api/v1";
28444
28679
  var DEFAULT_API_URL = "http://localhost:3001";
28445
28680
 
@@ -31897,6 +32132,19 @@ var COMMAND_SPECS = [
31897
32132
  returns: "RecipeUsedIn",
31898
32133
  notes: "GET /api/v1/recipes/{id}/used-in. At most five of each; meals need health:read too (without it, plans only)."
31899
32134
  },
32135
+ {
32136
+ path: ["recipes", "match"],
32137
+ summary: "Confirm or swap what a recipe ingredient matched: the reference food it is.",
32138
+ args: [
32139
+ { name: "id", required: true, description: "Recipe ULID." },
32140
+ { name: "ingredient", required: true, description: "The ingredient's id." },
32141
+ { name: "food", required: true, description: "A food id from `do foods search`." }
32142
+ ],
32143
+ flags: [],
32144
+ scopes: ["meals:write"],
32145
+ returns: "RecipeDetail",
32146
+ notes: "PUT /api/v1/recipes/{id}/ingredients/{ingredientId}/match. The ingredient's product becomes that food and the nutrition is worked out again."
32147
+ },
31900
32148
  {
31901
32149
  path: ["agents", "list"],
31902
32150
  summary: "List the Space's Agents (id + name).",
@@ -33828,6 +34076,61 @@ var COMMAND_SPECS = [
33828
34076
  scopes: ["contacts:write"],
33829
34077
  returns: "SeatingProposal"
33830
34078
  },
34079
+ {
34080
+ path: ["mail-campaigns", "list"],
34081
+ summary: "A guest list's mail campaigns (save-the-dates, invitations), newest first.",
34082
+ args: [],
34083
+ flags: [{ name: "list", type: "string", description: "The guest list's id (required)." }],
34084
+ scopes: ["contacts:read"],
34085
+ returns: "MailCampaignView",
34086
+ notes: "Each campaign carries the households it reaches (a draft: who it would go to) with their status, its mails by status, and readyToSend."
34087
+ },
34088
+ {
34089
+ path: ["mail-campaigns", "get"],
34090
+ summary: "One mail campaign, with its households and how far it got.",
34091
+ args: [{ name: "id", required: true, description: "The campaign's id." }],
34092
+ flags: [],
34093
+ scopes: ["contacts:read"],
34094
+ returns: "MailCampaignView"
34095
+ },
34096
+ {
34097
+ path: ["mail-campaigns", "create"],
34098
+ summary: "Draft a mail campaign for a guest list; nothing is sent.",
34099
+ args: [],
34100
+ flags: [
34101
+ {
34102
+ name: "data",
34103
+ type: "string",
34104
+ description: 'JSON CreateMailCampaignInput, e.g. {"guestListId":"01\u2026","kind":"save_the_date","template":"message","data":{"nl":{"subject":"\u2026","heading":"\u2026","paragraphs":["\u2026"]},"pt":{\u2026},"footer":{"deleteBy":"2027-12-31"}},"replyTo":"hallo@example.com"}'
34105
+ }
34106
+ ],
34107
+ scopes: ["contacts:write"],
34108
+ returns: "MailCampaignView",
34109
+ notes: "Drafting only: a member previews it, sends a test to the Space's members and sends it from the Mail tab. An agent can never test or send."
34110
+ },
34111
+ {
34112
+ path: ["mail-campaigns", "update"],
34113
+ summary: "Edit a draft campaign (its copy, kind or reply address).",
34114
+ args: [{ name: "id", required: true, description: "The campaign's id." }],
34115
+ flags: [
34116
+ {
34117
+ name: "data",
34118
+ type: "string",
34119
+ description: 'JSON UpdateMailCampaignInput, e.g. {"data":{"nl":{\u2026}}}'
34120
+ }
34121
+ ],
34122
+ scopes: ["contacts:write"],
34123
+ returns: "MailCampaignView",
34124
+ notes: "Only a draft changes (409 otherwise); an edit makes the last test stale."
34125
+ },
34126
+ {
34127
+ path: ["mail-campaigns", "preview"],
34128
+ summary: "Draw a campaign's mail as its first household would get it.",
34129
+ args: [{ name: "id", required: true, description: "The campaign's id." }],
34130
+ flags: [{ name: "language", type: "string", description: "nl (default) or pt." }],
34131
+ scopes: ["contacts:read"],
34132
+ returns: "MailPreview"
34133
+ },
33831
34134
  {
33832
34135
  path: ["guest-lists", "thank-you"],
33833
34136
  summary: "The gifts for the event: the cards still to send, then the ones sent.",
@@ -37120,6 +37423,17 @@ var HANDLERS = {
37120
37423
  const id = requireArg(args, 0, "recipe id");
37121
37424
  return { data: await requireClient().get(`/recipes/${id}/used-in`), render: renderRecord };
37122
37425
  },
37426
+ "recipes match": async ({ args, requireClient }) => {
37427
+ const id = requireArg(args, 0, "recipe id");
37428
+ const ingredient = requireArg(args, 1, "ingredient id");
37429
+ const foodId = requireArg(args, 2, "food id");
37430
+ return {
37431
+ data: await requireClient().put(`/recipes/${id}/ingredients/${ingredient}/match`, {
37432
+ foodId
37433
+ }),
37434
+ render: renderRecord
37435
+ };
37436
+ },
37123
37437
  "notes backlinks": async ({ args, requireClient }) => {
37124
37438
  const id = requireArg(args, 0, "note id");
37125
37439
  return {
@@ -39006,6 +39320,42 @@ var HANDLERS = {
39006
39320
  render: renderRecord
39007
39321
  };
39008
39322
  },
39323
+ "mail-campaigns list": async ({ flags, requireClient }) => {
39324
+ const list = flagString(flags, "list");
39325
+ if (!list)
39326
+ throw usageError("mail-campaigns list needs --list <guest list id>");
39327
+ parseInput(mailCampaignsQuerySchema, { guestListId: list });
39328
+ return {
39329
+ data: await requireClient().get("/mail-campaigns", { query: { guestListId: list } }),
39330
+ render: renderRecord
39331
+ };
39332
+ },
39333
+ "mail-campaigns get": async ({ args, requireClient }) => {
39334
+ const id = requireArg(args, 0, "campaign id");
39335
+ return { data: await requireClient().get(`/mail-campaigns/${id}`), render: renderRecord };
39336
+ },
39337
+ "mail-campaigns create": async ({ flags, requireClient }) => {
39338
+ const body = parseInput(createMailCampaignInputSchema, { id: ulid3(), ...readDataFlag(flags) });
39339
+ return { data: await requireClient().post("/mail-campaigns", body), render: renderRecord };
39340
+ },
39341
+ "mail-campaigns update": async ({ args, flags, requireClient }) => {
39342
+ const id = requireArg(args, 0, "campaign id");
39343
+ const body = parseInput(updateMailCampaignInputSchema, readDataFlag(flags));
39344
+ return {
39345
+ data: await requireClient().patch(`/mail-campaigns/${id}`, body),
39346
+ render: renderRecord
39347
+ };
39348
+ },
39349
+ "mail-campaigns preview": async ({ args, flags, requireClient }) => {
39350
+ const id = requireArg(args, 0, "campaign id");
39351
+ const query = parseInput(mailPreviewQuerySchema, {
39352
+ language: flagString(flags, "language") ?? "nl"
39353
+ });
39354
+ return {
39355
+ data: await requireClient().get(`/mail-campaigns/${id}/preview`, { query }),
39356
+ render: renderRecord
39357
+ };
39358
+ },
39009
39359
  "guest-lists thank-you": async ({ args, requireClient }) => {
39010
39360
  const id = requireArg(args, 0, "guest list id");
39011
39361
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbeverhelst/do",
3
- "version": "1.285.0",
3
+ "version": "1.287.0",
4
4
  "private": false,
5
5
  "description": "do — the agent-drivable CLI over the public /api/v1 surface",
6
6
  "homepage": "https://github.com/robbeverhelst/do/tree/main/apps/cli",