@robbeverhelst/do 1.295.0 → 1.296.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/dist/do.js +405 -5
- package/package.json +1 -1
package/dist/do.js
CHANGED
|
@@ -5221,6 +5221,46 @@ var mailDeliveries = pgTable("mail_deliveries", {
|
|
|
5221
5221
|
uniqueIndex("mail_deliveries_campaign_email_uniq").on(t.campaignId, t.toEmail)
|
|
5222
5222
|
]);
|
|
5223
5223
|
|
|
5224
|
+
// ../../packages/schema/src/db/rsvp-questions.ts
|
|
5225
|
+
var rsvpQuestionKind = pgEnum("rsvp_question_kind", [
|
|
5226
|
+
"choice",
|
|
5227
|
+
"multi",
|
|
5228
|
+
"text",
|
|
5229
|
+
"number",
|
|
5230
|
+
"yes_no"
|
|
5231
|
+
]);
|
|
5232
|
+
var rsvpQuestionScope = pgEnum("rsvp_question_scope", ["household", "guest"]);
|
|
5233
|
+
var rsvpQuestions = pgTable("rsvp_questions", {
|
|
5234
|
+
id: text("id").primaryKey(),
|
|
5235
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
5236
|
+
guestListId: text("guest_list_id").notNull().references(() => guestLists.id, { onDelete: "cascade" }),
|
|
5237
|
+
kind: rsvpQuestionKind("kind").notNull(),
|
|
5238
|
+
label: jsonb("label").$type().notNull(),
|
|
5239
|
+
options: jsonb("options").$type().notNull().default([]),
|
|
5240
|
+
scope: rsvpQuestionScope("scope").notNull().default("household"),
|
|
5241
|
+
eventKey: text("event_key"),
|
|
5242
|
+
required: boolean("required").notNull().default(false),
|
|
5243
|
+
sort: integer("sort").notNull().default(0),
|
|
5244
|
+
showIf: jsonb("show_if").$type().notNull().default([]),
|
|
5245
|
+
preset: text("preset"),
|
|
5246
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
5247
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
5248
|
+
}, (t) => [index("rsvp_questions_list_idx").on(t.guestListId)]);
|
|
5249
|
+
var rsvpAnswers = pgTable("rsvp_answers", {
|
|
5250
|
+
id: text("id").primaryKey(),
|
|
5251
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
5252
|
+
guestListId: text("guest_list_id").notNull().references(() => guestLists.id, { onDelete: "cascade" }),
|
|
5253
|
+
questionId: text("question_id").notNull().references(() => rsvpQuestions.id, { onDelete: "cascade" }),
|
|
5254
|
+
householdId: text("household_id").notNull().references(() => households.id, { onDelete: "cascade" }),
|
|
5255
|
+
guestId: text("guest_id").references(() => guests.id, { onDelete: "cascade" }),
|
|
5256
|
+
value: jsonb("value").$type().notNull(),
|
|
5257
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
5258
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
5259
|
+
}, (t) => [
|
|
5260
|
+
unique("rsvp_answers_uniq").on(t.questionId, t.householdId, t.guestId).nullsNotDistinct(),
|
|
5261
|
+
index("rsvp_answers_list_idx").on(t.guestListId)
|
|
5262
|
+
]);
|
|
5263
|
+
|
|
5224
5264
|
// ../../packages/schema/src/db/calendar.ts
|
|
5225
5265
|
var calendarLinkPurpose = pgEnum("calendar_link_purpose", ["block", "deadline"]);
|
|
5226
5266
|
var calendarEventLinks = pgTable("calendar_event_links", {
|
|
@@ -20590,7 +20630,13 @@ var METRICS = {
|
|
|
20590
20630
|
bedtime: { label: "Bedtime", unit: "clock", min: 0, max: 720, step: 5 }
|
|
20591
20631
|
};
|
|
20592
20632
|
var metricKeySchema = _enum2(["weight", "sleep", "mood", "rating", "energy", "bedtime"]);
|
|
20593
|
-
var metricSourceSchema = _enum2([
|
|
20633
|
+
var metricSourceSchema = _enum2([
|
|
20634
|
+
"manual",
|
|
20635
|
+
"device",
|
|
20636
|
+
"agent",
|
|
20637
|
+
"google_fit",
|
|
20638
|
+
"google_health"
|
|
20639
|
+
]);
|
|
20594
20640
|
var loggedMetricSourceSchema = _enum2(["manual", "device", "agent"]);
|
|
20595
20641
|
var metricPointSchema = object({
|
|
20596
20642
|
day: string2(),
|
|
@@ -20614,7 +20660,7 @@ var sessionSchema = object({
|
|
|
20614
20660
|
sport: string2(),
|
|
20615
20661
|
name: string2().nullable(),
|
|
20616
20662
|
minutes: number2().nullable(),
|
|
20617
|
-
source: _enum2(["google_fit", "strava"])
|
|
20663
|
+
source: _enum2(["google_fit", "google_health", "strava"])
|
|
20618
20664
|
});
|
|
20619
20665
|
var sessionsQuerySchema = object({
|
|
20620
20666
|
days: exports_coerce.number().int().min(1).max(365).default(14)
|
|
@@ -22801,6 +22847,65 @@ var journalMilestoneListSchema = object({
|
|
|
22801
22847
|
milestones: array(journalMilestoneSchema)
|
|
22802
22848
|
});
|
|
22803
22849
|
|
|
22850
|
+
// ../../packages/schema/src/contracts/journal-recall.ts
|
|
22851
|
+
var JOURNAL_RECALL_LIMIT = 30;
|
|
22852
|
+
var JOURNAL_RECALL_MAX_DAYS = 366;
|
|
22853
|
+
var daysBetween = (from, to) => (Date.parse(`${to}T00:00:00Z`) - Date.parse(`${from}T00:00:00Z`)) / 86400000;
|
|
22854
|
+
var journalRecallQuerySchema = object({
|
|
22855
|
+
q: string2().trim().min(2, "search for at least 2 characters").max(100).optional(),
|
|
22856
|
+
around: journalDateSchema.optional(),
|
|
22857
|
+
from: journalDateSchema.optional(),
|
|
22858
|
+
to: journalDateSchema.optional(),
|
|
22859
|
+
limit: exports_coerce.number().int().min(1).max(JOURNAL_RECALL_LIMIT).optional()
|
|
22860
|
+
}).strict().refine((q) => !(q.around && (q.from || q.to)), {
|
|
22861
|
+
message: "give around, or from and to, not both",
|
|
22862
|
+
path: ["around"]
|
|
22863
|
+
}).refine((q) => !q.from || !q.to || q.from <= q.to, {
|
|
22864
|
+
message: "from must be on or before to",
|
|
22865
|
+
path: ["to"]
|
|
22866
|
+
}).refine((q) => !q.from || !q.to || daysBetween(q.from, q.to) < JOURNAL_RECALL_MAX_DAYS, {
|
|
22867
|
+
message: `a recall covers at most ${JOURNAL_RECALL_MAX_DAYS} days`,
|
|
22868
|
+
path: ["to"]
|
|
22869
|
+
});
|
|
22870
|
+
var journalRecallMilestoneSchema = object({
|
|
22871
|
+
id: string2(),
|
|
22872
|
+
title: string2(),
|
|
22873
|
+
kind: journalMilestoneKindSchema,
|
|
22874
|
+
happenedOn: journalDateSchema,
|
|
22875
|
+
precision: journalMilestonePrecisionSchema,
|
|
22876
|
+
planned: boolean3()
|
|
22877
|
+
});
|
|
22878
|
+
var journalRecallEarlierSchema = object({
|
|
22879
|
+
date: journalDateSchema,
|
|
22880
|
+
yearsAgo: number2().int().positive(),
|
|
22881
|
+
title: string2().nullable(),
|
|
22882
|
+
rating: number2().nullable()
|
|
22883
|
+
});
|
|
22884
|
+
var journalRecallSchema = object({
|
|
22885
|
+
q: string2().nullable(),
|
|
22886
|
+
from: journalDateSchema.nullable(),
|
|
22887
|
+
to: journalDateSchema.nullable(),
|
|
22888
|
+
timezone: string2().min(1),
|
|
22889
|
+
days: array(journalDayListItemSchema).max(JOURNAL_RECALL_LIMIT),
|
|
22890
|
+
rated: number2().int().nonnegative(),
|
|
22891
|
+
average: number2().nullable(),
|
|
22892
|
+
milestones: array(journalRecallMilestoneSchema),
|
|
22893
|
+
earlier: array(journalRecallEarlierSchema)
|
|
22894
|
+
});
|
|
22895
|
+
var journalDigestDaySchema = object({
|
|
22896
|
+
date: journalDateSchema,
|
|
22897
|
+
title: string2().nullable(),
|
|
22898
|
+
rating: number2().nullable()
|
|
22899
|
+
});
|
|
22900
|
+
var journalDigestSchema = object({
|
|
22901
|
+
from: journalDateSchema,
|
|
22902
|
+
to: journalDateSchema,
|
|
22903
|
+
timezone: string2().min(1),
|
|
22904
|
+
days: array(journalDigestDaySchema),
|
|
22905
|
+
milestones: array(journalRecallMilestoneSchema),
|
|
22906
|
+
text: string2()
|
|
22907
|
+
});
|
|
22908
|
+
|
|
22804
22909
|
// ../../packages/schema/src/contracts/journal-recap.ts
|
|
22805
22910
|
var journalWeekKeySchema = string2().regex(/^\d{4}-W(0[1-9]|[1-4]\d|5[0-3])$/, "must be an ISO week (YYYY-Www)");
|
|
22806
22911
|
var JOURNAL_MOMENTS_MAX = 3;
|
|
@@ -27235,6 +27340,10 @@ var mailFooterSchema = object({
|
|
|
27235
27340
|
deleteBy: keyDateDaySchema.optional(),
|
|
27236
27341
|
contact: email2().max(320).optional()
|
|
27237
27342
|
}).strict();
|
|
27343
|
+
var mailLookShape = {
|
|
27344
|
+
couple: string2().trim().min(1).max(120).optional(),
|
|
27345
|
+
imagesUrl: url({ protocol: /^https$/ }).max(500).optional()
|
|
27346
|
+
};
|
|
27238
27347
|
var lineSchema = string2().trim().min(1).max(2000);
|
|
27239
27348
|
var mailMessageCopySchema = object({
|
|
27240
27349
|
subject: string2().trim().min(1).max(200),
|
|
@@ -27245,6 +27354,7 @@ var mailMessageCopySchema = object({
|
|
|
27245
27354
|
var mailMessageDataSchema = object({
|
|
27246
27355
|
nl: mailMessageCopySchema,
|
|
27247
27356
|
pt: mailMessageCopySchema.optional(),
|
|
27357
|
+
...mailLookShape,
|
|
27248
27358
|
footer: mailFooterSchema.optional()
|
|
27249
27359
|
}).strict();
|
|
27250
27360
|
var mailDaySchema = object({
|
|
@@ -27266,9 +27376,37 @@ var mailSaveTheDateDataSchema = object({
|
|
|
27266
27376
|
pt: mailSaveTheDateCopySchema.optional(),
|
|
27267
27377
|
days: array(mailDaySchema).min(1).max(5),
|
|
27268
27378
|
calendarTitle: string2().trim().min(1).max(120).optional(),
|
|
27379
|
+
...mailLookShape,
|
|
27269
27380
|
footer: mailFooterSchema.optional()
|
|
27270
27381
|
}).strict();
|
|
27271
27382
|
var mailSaveTheDateDeliverySchema = object({ link: url().optional() }).strict();
|
|
27383
|
+
var mailProgrammeItemSchema = object({
|
|
27384
|
+
date: keyDateDaySchema.optional(),
|
|
27385
|
+
time: string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "time is HH:MM"),
|
|
27386
|
+
label: mailDaySchema.shape.label,
|
|
27387
|
+
place: string2().trim().min(1).max(200).optional()
|
|
27388
|
+
}).strict();
|
|
27389
|
+
var laterMailShape = {
|
|
27390
|
+
nl: mailSaveTheDateCopySchema,
|
|
27391
|
+
pt: mailSaveTheDateCopySchema.optional(),
|
|
27392
|
+
days: array(mailDaySchema).min(1).max(5),
|
|
27393
|
+
...mailLookShape,
|
|
27394
|
+
footer: mailFooterSchema.optional()
|
|
27395
|
+
};
|
|
27396
|
+
var mailInvitationDataSchema = object({
|
|
27397
|
+
...laterMailShape,
|
|
27398
|
+
programme: array(mailProgrammeItemSchema).max(12).optional(),
|
|
27399
|
+
rsvpBy: keyDateDaySchema.optional(),
|
|
27400
|
+
calendarTitle: string2().trim().min(1).max(120).optional()
|
|
27401
|
+
}).strict();
|
|
27402
|
+
var mailReminderDataSchema = object({ ...laterMailShape, rsvpBy: keyDateDaySchema }).strict();
|
|
27403
|
+
var mailFinalInfoDataSchema = object({ ...laterMailShape, programme: array(mailProgrammeItemSchema).max(12).optional() }).strict();
|
|
27404
|
+
var mailHouseholdDeliverySchema = object({
|
|
27405
|
+
link: url().optional(),
|
|
27406
|
+
household: string2().trim().min(1).max(200).optional(),
|
|
27407
|
+
programme: array(mailProgrammeItemSchema).max(12).optional(),
|
|
27408
|
+
table: string2().trim().min(1).max(120).optional()
|
|
27409
|
+
}).strict();
|
|
27272
27410
|
var mailProviderEventSchema = looseObject({
|
|
27273
27411
|
type: string2().min(1),
|
|
27274
27412
|
created_at: string2().optional(),
|
|
@@ -27283,11 +27421,20 @@ var mailProviderEventSchema = looseObject({
|
|
|
27283
27421
|
});
|
|
27284
27422
|
var MAIL_CAMPAIGN_KINDS = ["message", "save_the_date", "invitation"];
|
|
27285
27423
|
var mailCampaignKindSchema = _enum2(MAIL_CAMPAIGN_KINDS);
|
|
27286
|
-
var MAIL_TEMPLATES = [
|
|
27424
|
+
var MAIL_TEMPLATES = [
|
|
27425
|
+
"message",
|
|
27426
|
+
"save_the_date",
|
|
27427
|
+
"invitation",
|
|
27428
|
+
"reminder",
|
|
27429
|
+
"final_info"
|
|
27430
|
+
];
|
|
27287
27431
|
var mailTemplateSchema = _enum2(MAIL_TEMPLATES);
|
|
27288
27432
|
var mailTemplateDataSchemas = {
|
|
27289
27433
|
message: mailMessageDataSchema,
|
|
27290
|
-
save_the_date: mailSaveTheDateDataSchema
|
|
27434
|
+
save_the_date: mailSaveTheDateDataSchema,
|
|
27435
|
+
invitation: mailInvitationDataSchema,
|
|
27436
|
+
reminder: mailReminderDataSchema,
|
|
27437
|
+
final_info: mailFinalInfoDataSchema
|
|
27291
27438
|
};
|
|
27292
27439
|
function mailTemplateDataError(template, data) {
|
|
27293
27440
|
const parsed = mailTemplateDataSchemas[template].safeParse(data);
|
|
@@ -27343,6 +27490,100 @@ var mailCampaignViewSchema = mailCampaignSchema.extend({
|
|
|
27343
27490
|
readyToSend: boolean3()
|
|
27344
27491
|
});
|
|
27345
27492
|
|
|
27493
|
+
// ../../packages/schema/src/contracts/rsvp-questions.ts
|
|
27494
|
+
var RSVP_QUESTION_KINDS = ["choice", "multi", "text", "number", "yes_no"];
|
|
27495
|
+
var rsvpQuestionKindSchema = _enum2(RSVP_QUESTION_KINDS);
|
|
27496
|
+
var rsvpQuestionScopeSchema = _enum2(["household", "guest"]);
|
|
27497
|
+
var RSVP_QUESTION_PRESETS = ["diet", "message"];
|
|
27498
|
+
var rsvpQuestionPresetSchema = _enum2(RSVP_QUESTION_PRESETS);
|
|
27499
|
+
var RSVP_SHOW_IF_MAX = 5;
|
|
27500
|
+
var rsvpTextSchema = (max) => object({
|
|
27501
|
+
nl: string2().trim().min(1).max(max).optional(),
|
|
27502
|
+
pt: string2().trim().min(1).max(max).optional()
|
|
27503
|
+
}).strict().refine((t) => t.nl !== undefined || t.pt !== undefined, "give it in NL or PT");
|
|
27504
|
+
var keySchema = string2().regex(/^[a-z][a-z0-9_]{0,31}$/, "expected a short lower-case word (vegan, civil)");
|
|
27505
|
+
var rsvpQuestionOptionSchema = object({ key: keySchema, label: rsvpTextSchema(120) }).strict();
|
|
27506
|
+
var rsvpShowIfConditionSchema = union([
|
|
27507
|
+
object({
|
|
27508
|
+
questionId: ulidSchema,
|
|
27509
|
+
equals: union([string2().max(200), number2(), boolean3()])
|
|
27510
|
+
}).strict(),
|
|
27511
|
+
object({ eventKey: keySchema.optional(), rsvp: literal("yes") }).strict()
|
|
27512
|
+
]);
|
|
27513
|
+
var rsvpAnswerValueSchema = union([
|
|
27514
|
+
string2().max(2000),
|
|
27515
|
+
array(string2().max(32)).max(20),
|
|
27516
|
+
number2(),
|
|
27517
|
+
boolean3()
|
|
27518
|
+
]);
|
|
27519
|
+
var rsvpQuestionSchema = createSelectSchema(rsvpQuestions, {
|
|
27520
|
+
label: object({ nl: string2().optional(), pt: string2().optional() }),
|
|
27521
|
+
options: array(object({
|
|
27522
|
+
key: string2(),
|
|
27523
|
+
label: object({ nl: string2().optional(), pt: string2().optional() })
|
|
27524
|
+
})),
|
|
27525
|
+
showIf: array(rsvpShowIfConditionSchema),
|
|
27526
|
+
preset: rsvpQuestionPresetSchema.nullable(),
|
|
27527
|
+
createdAt: exports_coerce.date(),
|
|
27528
|
+
updatedAt: exports_coerce.date()
|
|
27529
|
+
});
|
|
27530
|
+
var rsvpAnswerSchema = createSelectSchema(rsvpAnswers, {
|
|
27531
|
+
value: rsvpAnswerValueSchema,
|
|
27532
|
+
createdAt: exports_coerce.date(),
|
|
27533
|
+
updatedAt: exports_coerce.date()
|
|
27534
|
+
});
|
|
27535
|
+
function rsvpOptionsProblem(kind, options) {
|
|
27536
|
+
if (kind === "choice" || kind === "multi") {
|
|
27537
|
+
if (options.length < 2)
|
|
27538
|
+
return `a ${kind} question needs two options or more`;
|
|
27539
|
+
if (new Set(options.map((o) => o.key)).size !== options.length)
|
|
27540
|
+
return "each option needs its own key";
|
|
27541
|
+
return null;
|
|
27542
|
+
}
|
|
27543
|
+
return options.length > 0 ? `a ${kind} question has no options` : null;
|
|
27544
|
+
}
|
|
27545
|
+
var questionFields = {
|
|
27546
|
+
label: rsvpTextSchema(300),
|
|
27547
|
+
options: array(rsvpQuestionOptionSchema).max(30).optional(),
|
|
27548
|
+
scope: rsvpQuestionScopeSchema.optional(),
|
|
27549
|
+
eventKey: keySchema.nullish(),
|
|
27550
|
+
required: boolean3().optional(),
|
|
27551
|
+
sort: number2().int().min(0).max(1e4).optional(),
|
|
27552
|
+
showIf: array(rsvpShowIfConditionSchema).max(RSVP_SHOW_IF_MAX).optional()
|
|
27553
|
+
};
|
|
27554
|
+
var createRsvpQuestionInputSchema = object({
|
|
27555
|
+
id: ulidSchema,
|
|
27556
|
+
guestListId: ulidSchema,
|
|
27557
|
+
kind: rsvpQuestionKindSchema,
|
|
27558
|
+
...questionFields
|
|
27559
|
+
}).strict().superRefine((q, ctx) => {
|
|
27560
|
+
const problem = rsvpOptionsProblem(q.kind, q.options ?? []);
|
|
27561
|
+
if (problem)
|
|
27562
|
+
ctx.addIssue({ code: "custom", message: problem, path: ["options"] });
|
|
27563
|
+
if (q.showIf?.some((c) => ("questionId" in c) && c.questionId === q.id))
|
|
27564
|
+
ctx.addIssue({
|
|
27565
|
+
code: "custom",
|
|
27566
|
+
message: "a question can't depend on itself",
|
|
27567
|
+
path: ["showIf"]
|
|
27568
|
+
});
|
|
27569
|
+
});
|
|
27570
|
+
var updateRsvpQuestionInputSchema = object(questionFields).partial().strict();
|
|
27571
|
+
var rsvpQuestionsQuerySchema = object({ guestListId: ulidSchema });
|
|
27572
|
+
var rsvpAnswerInputSchema = object({
|
|
27573
|
+
questionId: ulidSchema,
|
|
27574
|
+
guestId: ulidSchema.nullish(),
|
|
27575
|
+
value: rsvpAnswerValueSchema.nullable()
|
|
27576
|
+
}).strict();
|
|
27577
|
+
var setRsvpAnswersInputSchema = object({
|
|
27578
|
+
guestListId: ulidSchema,
|
|
27579
|
+
householdId: ulidSchema,
|
|
27580
|
+
answers: array(rsvpAnswerInputSchema).min(1).max(200)
|
|
27581
|
+
}).strict();
|
|
27582
|
+
var rsvpAnswersQuerySchema = object({
|
|
27583
|
+
guestListId: ulidSchema,
|
|
27584
|
+
householdId: ulidSchema.optional()
|
|
27585
|
+
});
|
|
27586
|
+
|
|
27346
27587
|
// ../../packages/schema/src/contracts/calendar.ts
|
|
27347
27588
|
var calendarEventLinkSchema = createSelectSchema(calendarEventLinks, {
|
|
27348
27589
|
createdAt: exports_coerce.date(),
|
|
@@ -28935,7 +29176,7 @@ function parseCapture2(input, now) {
|
|
|
28935
29176
|
|
|
28936
29177
|
// src/meta.ts
|
|
28937
29178
|
var CLI_NAME = "do";
|
|
28938
|
-
var VERSION = "1.
|
|
29179
|
+
var VERSION = "1.296.0";
|
|
28939
29180
|
var API_PREFIX = "/api/v1";
|
|
28940
29181
|
var DEFAULT_API_URL = "http://localhost:3001";
|
|
28941
29182
|
|
|
@@ -29686,6 +29927,24 @@ var ENTITIES = [
|
|
|
29686
29927
|
canDelete: true
|
|
29687
29928
|
}
|
|
29688
29929
|
},
|
|
29930
|
+
{
|
|
29931
|
+
name: "rsvp-questions",
|
|
29932
|
+
path: "/rsvp-questions",
|
|
29933
|
+
readScope: "contacts:read",
|
|
29934
|
+
returns: "RsvpQuestion",
|
|
29935
|
+
canGet: true,
|
|
29936
|
+
listFlags: [
|
|
29937
|
+
{ name: "list", description: "the guest list's id (required)", query: "guestListId" }
|
|
29938
|
+
],
|
|
29939
|
+
write: {
|
|
29940
|
+
scope: "contacts:write",
|
|
29941
|
+
createSchema: createRsvpQuestionInputSchema,
|
|
29942
|
+
createInput: "CreateRsvpQuestionInput",
|
|
29943
|
+
updateSchema: updateRsvpQuestionInputSchema,
|
|
29944
|
+
updateInput: "UpdateRsvpQuestionInput",
|
|
29945
|
+
canDelete: true
|
|
29946
|
+
}
|
|
29947
|
+
},
|
|
29689
29948
|
{
|
|
29690
29949
|
name: "guests",
|
|
29691
29950
|
path: "/guests",
|
|
@@ -30401,6 +30660,24 @@ var HEALTH_COMMAND_SPECS = [
|
|
|
30401
30660
|
scopes: READ,
|
|
30402
30661
|
returns: "HealthLabOverview"
|
|
30403
30662
|
},
|
|
30663
|
+
{
|
|
30664
|
+
path: ["health", "google", "status"],
|
|
30665
|
+
summary: "Whether your Google Health is connected, the last sync, and what stops it.",
|
|
30666
|
+
args: [],
|
|
30667
|
+
flags: [],
|
|
30668
|
+
scopes: READ,
|
|
30669
|
+
returns: "GoogleHealthStatus",
|
|
30670
|
+
notes: "GET /api/v1/health/google-health. Connecting needs Google's consent in a browser: Settings \u2192 Health in do. `failure` (reauth, not_linked, unavailable, other) says what stops the sync, with a title and a hint."
|
|
30671
|
+
},
|
|
30672
|
+
{
|
|
30673
|
+
path: ["health", "google", "sync"],
|
|
30674
|
+
summary: "Sync your Google Health now (sleep, resting heart rate, HRV, steps, workouts), as the morning sync does.",
|
|
30675
|
+
args: [],
|
|
30676
|
+
flags: [],
|
|
30677
|
+
scopes: WRITE2,
|
|
30678
|
+
returns: "GoogleHealthSyncResult",
|
|
30679
|
+
notes: "POST /api/v1/health/google-health/sync. Written and skipped per resource, and the status after it; a sync that stops answers 200 with `status.failure`. 409 before Google Health is connected, 403 while the server has it switched off."
|
|
30680
|
+
},
|
|
30404
30681
|
{
|
|
30405
30682
|
path: ["health", "analyte"],
|
|
30406
30683
|
summary: "One analyte's trend across draws (do health analyte vitamin_d).",
|
|
@@ -30787,6 +31064,33 @@ var COMMAND_SPECS = [
|
|
|
30787
31064
|
returns: "JournalSearch",
|
|
30788
31065
|
notes: "GET /api/v1/journal/search?q= \u2014 matches the one-liner, highlights, the summary and entries of your own days (at most 30). journal:read is a sensitive scope."
|
|
30789
31066
|
},
|
|
31067
|
+
{
|
|
31068
|
+
path: ["journal", "recall"],
|
|
31069
|
+
summary: "Recall your Journal: the days that answer some words or a window (or the last 7 days), the milestones near them and the same date in earlier years.",
|
|
31070
|
+
args: [{ name: "words", required: false, description: "A topic to look for (2+ characters)." }],
|
|
31071
|
+
flags: [
|
|
31072
|
+
{
|
|
31073
|
+
name: "around",
|
|
31074
|
+
type: "string",
|
|
31075
|
+
description: "A day, YYYY-MM-DD: reads 3 days either side."
|
|
31076
|
+
},
|
|
31077
|
+
{ name: "from", type: "string", description: "The window's first day, YYYY-MM-DD." },
|
|
31078
|
+
{ name: "to", type: "string", description: "The window's last day, YYYY-MM-DD." },
|
|
31079
|
+
{ name: "limit", type: "string", description: "At most this many days (1\u201330)." }
|
|
31080
|
+
],
|
|
31081
|
+
scopes: ["journal:read"],
|
|
31082
|
+
returns: "JournalRecall",
|
|
31083
|
+
notes: "GET /api/v1/journal/recall (journal_recall) \u2014 your own days only, dated so an answer can cite them; another member's days never answer. --around can't be combined with --from/--to. journal:read is a sensitive scope."
|
|
31084
|
+
},
|
|
31085
|
+
{
|
|
31086
|
+
path: ["journal", "digest"],
|
|
31087
|
+
summary: "The last 7 days of your Journal as a short digest: each day's line and rating, and the milestones a week either side.",
|
|
31088
|
+
args: [],
|
|
31089
|
+
flags: [],
|
|
31090
|
+
scopes: ["journal:read"],
|
|
31091
|
+
returns: "JournalDigest",
|
|
31092
|
+
notes: "GET /api/v1/journal/digest \u2014 `text` is the few plain lines an agent keeps in its private session. journal:read is a sensitive scope."
|
|
31093
|
+
},
|
|
30790
31094
|
{
|
|
30791
31095
|
path: ["journal", "week"],
|
|
30792
31096
|
summary: "One week of the Journal: its recap (prose, best moments, a pattern), its days, the usual rating and the numbers from Progress.",
|
|
@@ -34420,6 +34724,31 @@ var COMMAND_SPECS = [
|
|
|
34420
34724
|
scopes: ["contacts:write"],
|
|
34421
34725
|
returns: "GuestView"
|
|
34422
34726
|
},
|
|
34727
|
+
{
|
|
34728
|
+
path: ["rsvp-answers", "list"],
|
|
34729
|
+
summary: "A guest list's answers to its RSVP questions, or one household's.",
|
|
34730
|
+
args: [],
|
|
34731
|
+
flags: [
|
|
34732
|
+
{ name: "list", type: "string", description: "The guest list's id (required)." },
|
|
34733
|
+
{ name: "household", type: "string", description: "Only this household's answers." }
|
|
34734
|
+
],
|
|
34735
|
+
scopes: ["contacts:read"],
|
|
34736
|
+
returns: "RsvpAnswer"
|
|
34737
|
+
},
|
|
34738
|
+
{
|
|
34739
|
+
path: ["rsvp-answers", "set"],
|
|
34740
|
+
summary: "Set a household's RSVP answers (null clears one); an answer to a hidden question is dropped.",
|
|
34741
|
+
args: [],
|
|
34742
|
+
flags: [
|
|
34743
|
+
{
|
|
34744
|
+
name: "data",
|
|
34745
|
+
type: "string",
|
|
34746
|
+
description: 'JSON SetRsvpAnswersInput, e.g. {"guestListId":"01\u2026","householdId":"01\u2026","answers":[{"questionId":"01\u2026","value":true},{"questionId":"01\u2026","guestId":"01\u2026","value":["vegan"]}]}'
|
|
34747
|
+
}
|
|
34748
|
+
],
|
|
34749
|
+
scopes: ["contacts:write"],
|
|
34750
|
+
returns: "RsvpAnswer"
|
|
34751
|
+
},
|
|
34423
34752
|
{
|
|
34424
34753
|
path: ["seating-proposals", "list"],
|
|
34425
34754
|
summary: "A guest list's proposed seating plans, newest first.",
|
|
@@ -36042,6 +36371,33 @@ function renderJournalSearch(data, mode) {
|
|
|
36042
36371
|
return paint(mode, "dim", "(no journal days mention that)");
|
|
36043
36372
|
return renderJournalDays({ days: d.days }, mode);
|
|
36044
36373
|
}
|
|
36374
|
+
function renderJournalRecall(data, mode) {
|
|
36375
|
+
const d = data;
|
|
36376
|
+
const head = [
|
|
36377
|
+
d.q ? `\u201C${d.q}\u201D` : null,
|
|
36378
|
+
d.from && d.to ? `${d.from} \u2013 ${d.to}` : null,
|
|
36379
|
+
d.average != null ? `avg ${d.average} over ${d.rated} rated` : null
|
|
36380
|
+
].filter(Boolean).join(" \xB7 ");
|
|
36381
|
+
const out = head ? [paint(mode, "dim", head)] : [];
|
|
36382
|
+
out.push((d.days ?? []).length === 0 ? paint(mode, "dim", "(no journal day answers that)") : renderJournalDays({ days: d.days }, mode));
|
|
36383
|
+
if ((d.milestones ?? []).length > 0) {
|
|
36384
|
+
out.push("", paint(mode, "dim", "Milestones near"));
|
|
36385
|
+
for (const m of d.milestones ?? [])
|
|
36386
|
+
out.push(` \u25C6 ${m.title}${paint(mode, "dim", ` \xB7 ${m.happenedOn}${m.planned ? " (planned)" : ""}`)}`);
|
|
36387
|
+
}
|
|
36388
|
+
if ((d.earlier ?? []).length > 0) {
|
|
36389
|
+
out.push("", paint(mode, "dim", "On this day"));
|
|
36390
|
+
for (const e of d.earlier ?? []) {
|
|
36391
|
+
const rating = e.rating == null ? "" : paint(mode, "dim", ` ${e.rating}/10`);
|
|
36392
|
+
out.push(` ${e.date} ${e.title ?? paint(mode, "dim", "(no entry)")}${rating}`);
|
|
36393
|
+
}
|
|
36394
|
+
}
|
|
36395
|
+
return out.join(`
|
|
36396
|
+
`);
|
|
36397
|
+
}
|
|
36398
|
+
function renderJournalDigest(data) {
|
|
36399
|
+
return data.text ?? "";
|
|
36400
|
+
}
|
|
36045
36401
|
function renderJournalImportScan(data, mode) {
|
|
36046
36402
|
const d = data;
|
|
36047
36403
|
const items = d.items;
|
|
@@ -37170,6 +37526,27 @@ var HANDLERS = {
|
|
|
37170
37526
|
render: renderJournalSearch
|
|
37171
37527
|
};
|
|
37172
37528
|
},
|
|
37529
|
+
"journal recall": async ({ args, flags, requireClient }) => {
|
|
37530
|
+
const q = args.join(" ").trim() || undefined;
|
|
37531
|
+
if (q !== undefined && q.length < 2)
|
|
37532
|
+
throw usageError("journal recall needs 2+ characters");
|
|
37533
|
+
const query = {
|
|
37534
|
+
q,
|
|
37535
|
+
around: flagString(flags, "around"),
|
|
37536
|
+
from: flagString(flags, "from"),
|
|
37537
|
+
to: flagString(flags, "to"),
|
|
37538
|
+
limit: flagString(flags, "limit")
|
|
37539
|
+
};
|
|
37540
|
+
parseInput(journalRecallQuerySchema, Object.fromEntries(Object.entries(query).filter(([, v]) => v !== undefined)));
|
|
37541
|
+
return {
|
|
37542
|
+
data: await requireClient().get("/journal/recall", { query }),
|
|
37543
|
+
render: renderJournalRecall
|
|
37544
|
+
};
|
|
37545
|
+
},
|
|
37546
|
+
"journal digest": async ({ requireClient }) => ({
|
|
37547
|
+
data: await requireClient().get("/journal/digest"),
|
|
37548
|
+
render: renderJournalDigest
|
|
37549
|
+
}),
|
|
37173
37550
|
"journal week": async ({ args, requireClient }) => {
|
|
37174
37551
|
const week = journalWeekArg(args, "week");
|
|
37175
37552
|
return {
|
|
@@ -39407,6 +39784,14 @@ var HANDLERS = {
|
|
|
39407
39784
|
data: await requireClient().delete(`/health/shares/${requireArg(args, 0, "id")}`),
|
|
39408
39785
|
render: renderRecord
|
|
39409
39786
|
}),
|
|
39787
|
+
"health google status": async ({ requireClient }) => ({
|
|
39788
|
+
data: await requireClient().get("/health/google-health"),
|
|
39789
|
+
render: renderRecord
|
|
39790
|
+
}),
|
|
39791
|
+
"health google sync": async ({ requireClient }) => ({
|
|
39792
|
+
data: await requireClient().post("/health/google-health/sync", {}),
|
|
39793
|
+
render: renderRecord
|
|
39794
|
+
}),
|
|
39410
39795
|
"health consent": async ({ requireClient }) => ({
|
|
39411
39796
|
data: await requireClient().get("/health/consent"),
|
|
39412
39797
|
render: renderRecord
|
|
@@ -39746,6 +40131,21 @@ var HANDLERS = {
|
|
|
39746
40131
|
const body = parseInput(markGuestsSentInputSchema, readDataFlag(flags));
|
|
39747
40132
|
return { data: await requireClient().post("/guests/sent", body), render: renderRecord };
|
|
39748
40133
|
},
|
|
40134
|
+
"rsvp-answers list": async ({ flags, requireClient }) => {
|
|
40135
|
+
const list = flagString(flags, "list");
|
|
40136
|
+
if (!list)
|
|
40137
|
+
throw usageError("rsvp-answers list needs --list <guest list id>");
|
|
40138
|
+
const household = flagString(flags, "household");
|
|
40139
|
+
const query = parseInput(rsvpAnswersQuerySchema, {
|
|
40140
|
+
guestListId: list,
|
|
40141
|
+
...household ? { householdId: household } : {}
|
|
40142
|
+
});
|
|
40143
|
+
return { data: await requireClient().get("/rsvp-answers", { query }), render: renderRecord };
|
|
40144
|
+
},
|
|
40145
|
+
"rsvp-answers set": async ({ flags, requireClient }) => {
|
|
40146
|
+
const body = parseInput(setRsvpAnswersInputSchema, readDataFlag(flags));
|
|
40147
|
+
return { data: await requireClient().put("/rsvp-answers", body), render: renderRecord };
|
|
40148
|
+
},
|
|
39749
40149
|
"seating-proposals list": async ({ flags, requireClient }) => {
|
|
39750
40150
|
const list = flagString(flags, "list");
|
|
39751
40151
|
if (!list)
|
package/package.json
CHANGED