@robbeverhelst/do 1.388.0 → 1.390.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 +495 -230
- package/package.json +1 -1
package/dist/do.js
CHANGED
|
@@ -14420,7 +14420,7 @@ var configError = (message) => new CliError("config", message, EXIT.CONFIG);
|
|
|
14420
14420
|
|
|
14421
14421
|
// src/meta.ts
|
|
14422
14422
|
var CLI_NAME = "do";
|
|
14423
|
-
var VERSION = "1.
|
|
14423
|
+
var VERSION = "1.390.0";
|
|
14424
14424
|
var API_PREFIX = "/api/v1";
|
|
14425
14425
|
var DEFAULT_API_URL = "http://localhost:3001";
|
|
14426
14426
|
|
|
@@ -18515,6 +18515,7 @@ var keyDates = pgTable("key_dates", {
|
|
|
18515
18515
|
derivedFrom: text("derived_from"),
|
|
18516
18516
|
source: text("source").notNull().default("manual"),
|
|
18517
18517
|
confirmedAt: timestamp("confirmed_at", { withTimezone: true }),
|
|
18518
|
+
bookedAt: timestamp("booked_at", { withTimezone: true }),
|
|
18518
18519
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18519
18520
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18520
18521
|
}, (t) => [
|
|
@@ -20855,6 +20856,7 @@ var keyDateRepeatSchema = _enum2(["yearly"]);
|
|
|
20855
20856
|
var keyDateSchema = createSelectSchema(keyDates, {
|
|
20856
20857
|
date: keyDateDaySchema,
|
|
20857
20858
|
confirmedAt: exports_coerce.date().nullable(),
|
|
20859
|
+
bookedAt: exports_coerce.date().nullish(),
|
|
20858
20860
|
createdAt: exports_coerce.date(),
|
|
20859
20861
|
updatedAt: exports_coerce.date()
|
|
20860
20862
|
});
|
|
@@ -20884,7 +20886,8 @@ var createKeyDateInputSchema = object({
|
|
|
20884
20886
|
leadDays: leadDaysSchema.optional(),
|
|
20885
20887
|
derivedFrom: string2().trim().min(1).max(120).nullish(),
|
|
20886
20888
|
source: sourceSchema.optional(),
|
|
20887
|
-
confirmed: boolean2().optional()
|
|
20889
|
+
confirmed: boolean2().optional(),
|
|
20890
|
+
bookedAt: exports_coerce.date().nullish()
|
|
20888
20891
|
}).strict();
|
|
20889
20892
|
var updateKeyDateInputSchema = object({
|
|
20890
20893
|
kind: keyDateKindSchema.optional(),
|
|
@@ -20895,8 +20898,10 @@ var updateKeyDateInputSchema = object({
|
|
|
20895
20898
|
leadDays: leadDaysSchema.optional(),
|
|
20896
20899
|
derivedFrom: string2().trim().min(1).max(120).nullish(),
|
|
20897
20900
|
source: sourceSchema.optional(),
|
|
20898
|
-
confirmed: boolean2().optional()
|
|
20901
|
+
confirmed: boolean2().optional(),
|
|
20902
|
+
bookedAt: exports_coerce.date().nullish()
|
|
20899
20903
|
}).strict();
|
|
20904
|
+
var keyDateBookingInputSchema = object({ bookedAt: exports_coerce.date().nullable() }).strict();
|
|
20900
20905
|
var keyDatesQuerySchema = object({
|
|
20901
20906
|
nodeId: ulidSchema.optional(),
|
|
20902
20907
|
kind: keyDateKindSchema.optional(),
|
|
@@ -29275,6 +29280,36 @@ var healthDataKeys = pgTable("health_data_keys", {
|
|
|
29275
29280
|
sealedKey: text("sealed_key").notNull(),
|
|
29276
29281
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
29277
29282
|
}, (t) => [primaryKey({ columns: [t.tenantId, t.userId] })]);
|
|
29283
|
+
var healthCycleSettings = pgTable("health_cycle_settings", {
|
|
29284
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
29285
|
+
userId: text("user_id").notNull().references(() => users.id),
|
|
29286
|
+
on: boolean4("on").notNull().default(false),
|
|
29287
|
+
usualLength: integer2("usual_length"),
|
|
29288
|
+
shareNext: boolean4("share_next").notNull().default(false),
|
|
29289
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
29290
|
+
}, (t) => [
|
|
29291
|
+
primaryKey({ columns: [t.tenantId, t.userId] }),
|
|
29292
|
+
check2("health_cycle_settings_length_chk", sql`${t.usualLength} IS NULL OR ${t.usualLength} BETWEEN 15 AND 60`)
|
|
29293
|
+
]);
|
|
29294
|
+
var healthCycleDays = pgTable("health_cycle_days", {
|
|
29295
|
+
id: text("id").primaryKey(),
|
|
29296
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
29297
|
+
userId: text("user_id").notNull().references(() => users.id),
|
|
29298
|
+
day: date5("day", { mode: "string" }).notNull(),
|
|
29299
|
+
flow: text("flow"),
|
|
29300
|
+
symptoms: text("symptoms").array().notNull().default(sql`'{}'::text[]`),
|
|
29301
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
29302
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
29303
|
+
}, (t) => [
|
|
29304
|
+
uniqueIndex("health_cycle_days_member_day_uniq").on(t.tenantId, t.userId, t.day),
|
|
29305
|
+
check2("health_cycle_days_flow_chk", sql`${t.flow} IS NULL OR ${t.flow} IN ('none', 'light', 'medium', 'heavy')`)
|
|
29306
|
+
]);
|
|
29307
|
+
var healthCycleShares = pgTable("health_cycle_shares", {
|
|
29308
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
29309
|
+
userId: text("user_id").notNull().references(() => users.id),
|
|
29310
|
+
nextOn: date5("next_on", { mode: "string" }).notNull(),
|
|
29311
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
29312
|
+
}, (t) => [primaryKey({ columns: [t.tenantId, t.userId] })]);
|
|
29278
29313
|
|
|
29279
29314
|
// ../../packages/schema/src/contracts/health-records.ts
|
|
29280
29315
|
var BODY_REGION_VALUES = [
|
|
@@ -31645,6 +31680,283 @@ var habitOperations = defineOperations({
|
|
|
31645
31680
|
}
|
|
31646
31681
|
});
|
|
31647
31682
|
|
|
31683
|
+
// ../../packages/schema/src/contracts/plans.ts
|
|
31684
|
+
var PLAN_KINDS = ["week", "day"];
|
|
31685
|
+
var PLAN_ITEM_ACTIONS = ["plan", "someday", "let_go"];
|
|
31686
|
+
var PLAN_ITEM_STATES = ["proposed", "accepted", "dismissed"];
|
|
31687
|
+
var PLAN_STATUSES = ["open", "settled", "replaced"];
|
|
31688
|
+
var PLAN_DUPLICATE_MODES = ["merge", "reject"];
|
|
31689
|
+
var PLAN_MERGE_OUTCOMES = [
|
|
31690
|
+
"scheduled_task",
|
|
31691
|
+
"covered_by_item",
|
|
31692
|
+
"already_planned"
|
|
31693
|
+
];
|
|
31694
|
+
var PLAN_MATCH_KINDS = ["task", "time_block", "event"];
|
|
31695
|
+
var PLAN_MAX_ITEMS = 60;
|
|
31696
|
+
var PLAN_MAX_BLOCKS = 140;
|
|
31697
|
+
var PLAN_REASON_MAX = 280;
|
|
31698
|
+
var PLAN_NOTE_MAX = 2000;
|
|
31699
|
+
var planKindSchema = _enum2(PLAN_KINDS);
|
|
31700
|
+
var planItemActionSchema = _enum2(PLAN_ITEM_ACTIONS);
|
|
31701
|
+
var planItemStateSchema = _enum2(PLAN_ITEM_STATES);
|
|
31702
|
+
var planStatusSchema = _enum2(PLAN_STATUSES);
|
|
31703
|
+
var civilDaySchema = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "expected YYYY-MM-DD").refine((s) => new Date(`${s}T00:00:00Z`).toISOString().slice(0, 10) === s, "not a real day");
|
|
31704
|
+
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
31705
|
+
function addCivilDays(day, n) {
|
|
31706
|
+
return new Date(Date.parse(`${day}T00:00:00Z`) + n * DAY_MS).toISOString().slice(0, 10);
|
|
31707
|
+
}
|
|
31708
|
+
function planDays(kind, startsOn) {
|
|
31709
|
+
return kind === "week" ? Array.from({ length: 7 }, (_, i) => addCivilDays(startsOn, i)) : [startsOn];
|
|
31710
|
+
}
|
|
31711
|
+
function isMonday(day) {
|
|
31712
|
+
return new Date(`${day}T00:00:00Z`).getUTCDay() === 1;
|
|
31713
|
+
}
|
|
31714
|
+
var planItemInputSchema = object({
|
|
31715
|
+
taskId: ulidSchema,
|
|
31716
|
+
action: planItemActionSchema.default("plan"),
|
|
31717
|
+
day: civilDaySchema.optional(),
|
|
31718
|
+
at: exports_coerce.date().optional(),
|
|
31719
|
+
durationMinutes: number2().int().min(5).max(24 * 60).optional(),
|
|
31720
|
+
reason: string2().trim().min(1).max(PLAN_REASON_MAX).optional()
|
|
31721
|
+
}).strict().superRefine((v, ctx) => {
|
|
31722
|
+
if (v.action === "plan") {
|
|
31723
|
+
if (v.day === undefined === (v.at === undefined)) {
|
|
31724
|
+
ctx.addIssue({
|
|
31725
|
+
code: "custom",
|
|
31726
|
+
message: "a `plan` item takes exactly one of `day` or `at`",
|
|
31727
|
+
path: ["day"]
|
|
31728
|
+
});
|
|
31729
|
+
}
|
|
31730
|
+
if (v.durationMinutes !== undefined && v.at === undefined) {
|
|
31731
|
+
ctx.addIssue({
|
|
31732
|
+
code: "custom",
|
|
31733
|
+
message: "`durationMinutes` goes with `at` (a time)",
|
|
31734
|
+
path: ["durationMinutes"]
|
|
31735
|
+
});
|
|
31736
|
+
}
|
|
31737
|
+
} else if (v.day !== undefined || v.at !== undefined || v.durationMinutes !== undefined) {
|
|
31738
|
+
ctx.addIssue({
|
|
31739
|
+
code: "custom",
|
|
31740
|
+
message: `a \`${v.action}\` item takes no day, time or duration`,
|
|
31741
|
+
path: ["action"]
|
|
31742
|
+
});
|
|
31743
|
+
}
|
|
31744
|
+
});
|
|
31745
|
+
var planBlockInputSchema = object({
|
|
31746
|
+
templateId: ulidSchema.optional(),
|
|
31747
|
+
lifeKind: lifeBlockKindSchema,
|
|
31748
|
+
title: string2().trim().min(1).max(500).optional(),
|
|
31749
|
+
startAt: exports_coerce.date(),
|
|
31750
|
+
endAt: exports_coerce.date(),
|
|
31751
|
+
routineId: ulidSchema.optional(),
|
|
31752
|
+
reason: string2().trim().min(1).max(PLAN_REASON_MAX).optional()
|
|
31753
|
+
}).strict().refine((v) => {
|
|
31754
|
+
const minutes = (v.endAt.getTime() - v.startAt.getTime()) / 60000;
|
|
31755
|
+
return minutes > 0 && minutes <= TIME_BLOCK_MAX_MINUTES;
|
|
31756
|
+
}, { message: "endAt must be after startAt and at most a day later", path: ["endAt"] });
|
|
31757
|
+
var createPlanInputSchema = object({
|
|
31758
|
+
kind: planKindSchema,
|
|
31759
|
+
startsOn: civilDaySchema,
|
|
31760
|
+
forUserId: string2().min(1).optional(),
|
|
31761
|
+
note: string2().trim().min(1).max(PLAN_NOTE_MAX).optional(),
|
|
31762
|
+
items: array(planItemInputSchema).max(PLAN_MAX_ITEMS).default([]),
|
|
31763
|
+
blocks: array(planBlockInputSchema).max(PLAN_MAX_BLOCKS).default([]),
|
|
31764
|
+
onDuplicate: _enum2(PLAN_DUPLICATE_MODES).default("merge")
|
|
31765
|
+
}).strict().superRefine((v, ctx) => {
|
|
31766
|
+
if (v.items.length + v.blocks.length === 0) {
|
|
31767
|
+
ctx.addIssue({
|
|
31768
|
+
code: "custom",
|
|
31769
|
+
message: "a plan proposes at least one item or block",
|
|
31770
|
+
path: ["items"]
|
|
31771
|
+
});
|
|
31772
|
+
}
|
|
31773
|
+
if (v.kind === "week" && !isMonday(v.startsOn)) {
|
|
31774
|
+
ctx.addIssue({
|
|
31775
|
+
code: "custom",
|
|
31776
|
+
message: "a week plan starts on a Monday",
|
|
31777
|
+
path: ["startsOn"]
|
|
31778
|
+
});
|
|
31779
|
+
}
|
|
31780
|
+
const days = new Set(planDays(v.kind, v.startsOn));
|
|
31781
|
+
const seen = new Set;
|
|
31782
|
+
v.items.forEach((item, i) => {
|
|
31783
|
+
if (seen.has(item.taskId)) {
|
|
31784
|
+
ctx.addIssue({
|
|
31785
|
+
code: "custom",
|
|
31786
|
+
message: "one item per task",
|
|
31787
|
+
path: ["items", i, "taskId"]
|
|
31788
|
+
});
|
|
31789
|
+
}
|
|
31790
|
+
seen.add(item.taskId);
|
|
31791
|
+
if (item.day !== undefined && !days.has(item.day)) {
|
|
31792
|
+
ctx.addIssue({
|
|
31793
|
+
code: "custom",
|
|
31794
|
+
message: `the day falls outside the ${v.kind}`,
|
|
31795
|
+
path: ["items", i, "day"]
|
|
31796
|
+
});
|
|
31797
|
+
}
|
|
31798
|
+
});
|
|
31799
|
+
});
|
|
31800
|
+
var planDecisionInputSchema = object({
|
|
31801
|
+
itemIds: array(string2().min(1)).min(1).max(PLAN_MAX_ITEMS + PLAN_MAX_BLOCKS).optional()
|
|
31802
|
+
}).strict();
|
|
31803
|
+
var planAdjustInputSchema = object({
|
|
31804
|
+
itemId: string2().min(1),
|
|
31805
|
+
startAt: exports_coerce.date(),
|
|
31806
|
+
endAt: exports_coerce.date()
|
|
31807
|
+
}).strict().refine((v) => {
|
|
31808
|
+
const minutes = (v.endAt.getTime() - v.startAt.getTime()) / 60000;
|
|
31809
|
+
return minutes >= 5 && minutes <= TIME_BLOCK_MAX_MINUTES;
|
|
31810
|
+
}, { message: "endAt must be 5 minutes to a day after startAt", path: ["endAt"] });
|
|
31811
|
+
var PLAN_TEMPLATES = ["normal", "light", "away"];
|
|
31812
|
+
var planTemplateSchema = _enum2(PLAN_TEMPLATES);
|
|
31813
|
+
var planDraftInputSchema = object({
|
|
31814
|
+
startsOn: civilDaySchema.refine(isMonday, "a week starts on a Monday"),
|
|
31815
|
+
template: planTemplateSchema.default("normal")
|
|
31816
|
+
}).strict();
|
|
31817
|
+
var planPlaceInputSchema = object({
|
|
31818
|
+
taskId: ulidSchema,
|
|
31819
|
+
startAt: exports_coerce.date(),
|
|
31820
|
+
endAt: exports_coerce.date()
|
|
31821
|
+
}).strict().refine((v) => {
|
|
31822
|
+
const minutes = (v.endAt.getTime() - v.startAt.getTime()) / 60000;
|
|
31823
|
+
return minutes >= 5 && minutes <= TIME_BLOCK_MAX_MINUTES;
|
|
31824
|
+
}, { message: "endAt must be 5 minutes to a day after startAt", path: ["endAt"] });
|
|
31825
|
+
var planUnplaceInputSchema = object({ taskId: ulidSchema }).strict();
|
|
31826
|
+
var planListQuerySchema = object({
|
|
31827
|
+
kind: planKindSchema.optional(),
|
|
31828
|
+
status: planStatusSchema.optional(),
|
|
31829
|
+
startsOn: civilDaySchema.optional(),
|
|
31830
|
+
taskId: ulidSchema.optional()
|
|
31831
|
+
});
|
|
31832
|
+
var planTaskSchema = object({
|
|
31833
|
+
id: ulidSchema,
|
|
31834
|
+
title: string2(),
|
|
31835
|
+
status: taskStatusSchema,
|
|
31836
|
+
scheduledAt: exports_coerce.date().nullable(),
|
|
31837
|
+
allDay: boolean2(),
|
|
31838
|
+
dueAt: exports_coerce.date().nullable(),
|
|
31839
|
+
durationMinutes: number2().int().nullable(),
|
|
31840
|
+
areaId: string2().nullable(),
|
|
31841
|
+
projectId: string2().nullable(),
|
|
31842
|
+
moveCount: number2().int().nonnegative().default(0)
|
|
31843
|
+
});
|
|
31844
|
+
var planItemViewSchema = object({
|
|
31845
|
+
id: string2(),
|
|
31846
|
+
taskId: ulidSchema,
|
|
31847
|
+
action: planItemActionSchema,
|
|
31848
|
+
scheduledAt: exports_coerce.date().nullable(),
|
|
31849
|
+
allDay: boolean2(),
|
|
31850
|
+
durationMinutes: number2().int().nullable(),
|
|
31851
|
+
reason: string2().nullable(),
|
|
31852
|
+
state: planItemStateSchema,
|
|
31853
|
+
decidedAt: exports_coerce.date().nullable(),
|
|
31854
|
+
task: planTaskSchema
|
|
31855
|
+
});
|
|
31856
|
+
var planBlockViewSchema = object({
|
|
31857
|
+
id: string2(),
|
|
31858
|
+
templateId: string2().nullable(),
|
|
31859
|
+
lifeKind: lifeBlockKindSchema,
|
|
31860
|
+
title: string2(),
|
|
31861
|
+
startAt: exports_coerce.date(),
|
|
31862
|
+
endAt: exports_coerce.date(),
|
|
31863
|
+
routineId: string2().nullable(),
|
|
31864
|
+
reason: string2().nullable(),
|
|
31865
|
+
state: planItemStateSchema,
|
|
31866
|
+
decidedAt: exports_coerce.date().nullable(),
|
|
31867
|
+
blockId: string2().nullable()
|
|
31868
|
+
});
|
|
31869
|
+
var planViewSchema = object({
|
|
31870
|
+
id: string2(),
|
|
31871
|
+
kind: planKindSchema,
|
|
31872
|
+
startsOn: civilDaySchema,
|
|
31873
|
+
userId: string2(),
|
|
31874
|
+
agentId: string2().nullable(),
|
|
31875
|
+
note: string2().nullable(),
|
|
31876
|
+
template: planTemplateSchema.nullable().default(null),
|
|
31877
|
+
status: planStatusSchema,
|
|
31878
|
+
createdAt: exports_coerce.date(),
|
|
31879
|
+
updatedAt: exports_coerce.date(),
|
|
31880
|
+
items: array(planItemViewSchema),
|
|
31881
|
+
blocks: array(planBlockViewSchema).default([])
|
|
31882
|
+
});
|
|
31883
|
+
var planMergeSchema = object({
|
|
31884
|
+
blockIndex: number2().int().min(0),
|
|
31885
|
+
title: string2(),
|
|
31886
|
+
outcome: _enum2(PLAN_MERGE_OUTCOMES),
|
|
31887
|
+
match: object({ kind: _enum2(PLAN_MATCH_KINDS), id: string2(), title: string2() }),
|
|
31888
|
+
hint: string2()
|
|
31889
|
+
});
|
|
31890
|
+
var PLAN_RULE_OUTCOMES = [
|
|
31891
|
+
"anchored",
|
|
31892
|
+
"added",
|
|
31893
|
+
"kept_free",
|
|
31894
|
+
"over_limit",
|
|
31895
|
+
"below_min",
|
|
31896
|
+
"not_theirs"
|
|
31897
|
+
];
|
|
31898
|
+
var planShapingSchema = object({
|
|
31899
|
+
ruleId: string2(),
|
|
31900
|
+
sentence: string2(),
|
|
31901
|
+
outcome: _enum2(PLAN_RULE_OUTCOMES),
|
|
31902
|
+
title: string2(),
|
|
31903
|
+
hint: string2()
|
|
31904
|
+
});
|
|
31905
|
+
var planCreateResultSchema = planViewSchema.extend({
|
|
31906
|
+
merged: array(planMergeSchema).default([]),
|
|
31907
|
+
shaped: array(planShapingSchema).default([])
|
|
31908
|
+
});
|
|
31909
|
+
|
|
31910
|
+
// ../../packages/schema/src/contracts/health-cycle.ts
|
|
31911
|
+
var HEALTH_CYCLE_FLOWS = ["none", "light", "medium", "heavy"];
|
|
31912
|
+
var healthCycleFlowSchema = _enum2(HEALTH_CYCLE_FLOWS);
|
|
31913
|
+
var HEALTH_CYCLE_SYMPTOMS = ["cramps", "headache", "tired", "low_mood", "skin"];
|
|
31914
|
+
var healthCycleSymptomSchema = _enum2(HEALTH_CYCLE_SYMPTOMS);
|
|
31915
|
+
var HEALTH_CYCLE_LENGTH_MIN = 15;
|
|
31916
|
+
var HEALTH_CYCLE_LENGTH_MAX = 60;
|
|
31917
|
+
var healthCycleSettingsSchema = object({
|
|
31918
|
+
on: boolean2(),
|
|
31919
|
+
usualLength: number2().int().nullable(),
|
|
31920
|
+
shareNext: boolean2()
|
|
31921
|
+
});
|
|
31922
|
+
var healthCycleDaySchema = object({
|
|
31923
|
+
day: civilDaySchema,
|
|
31924
|
+
flow: healthCycleFlowSchema.nullable(),
|
|
31925
|
+
symptoms: array(healthCycleSymptomSchema)
|
|
31926
|
+
});
|
|
31927
|
+
var healthCycleSummarySchema = object({
|
|
31928
|
+
lastStart: civilDaySchema.nullable(),
|
|
31929
|
+
day: number2().int().nullable(),
|
|
31930
|
+
length: number2().int(),
|
|
31931
|
+
lengthFrom: _enum2(["set", "cycles", "default"]),
|
|
31932
|
+
periodDays: number2().int().nullable(),
|
|
31933
|
+
nextOn: civilDaySchema.nullable(),
|
|
31934
|
+
fertile: tuple([number2().int(), number2().int()]).nullable(),
|
|
31935
|
+
lengths: array(object({ start: civilDaySchema, days: number2().int() })),
|
|
31936
|
+
regular: string2().nullable()
|
|
31937
|
+
});
|
|
31938
|
+
var healthCycleViewSchema = object({
|
|
31939
|
+
settings: healthCycleSettingsSchema,
|
|
31940
|
+
days: array(healthCycleDaySchema),
|
|
31941
|
+
summary: healthCycleSummarySchema.nullable()
|
|
31942
|
+
});
|
|
31943
|
+
var updateHealthCycleSettingsInputSchema = object({
|
|
31944
|
+
on: boolean2().optional(),
|
|
31945
|
+
usualLength: number2().int().min(HEALTH_CYCLE_LENGTH_MIN).max(HEALTH_CYCLE_LENGTH_MAX).nullable().optional(),
|
|
31946
|
+
shareNext: boolean2().optional()
|
|
31947
|
+
}).strict().refine((v) => Object.keys(v).length > 0, { message: "set one setting at least" });
|
|
31948
|
+
var logHealthCycleDayInputSchema = object({
|
|
31949
|
+
flow: healthCycleFlowSchema.nullable().optional(),
|
|
31950
|
+
symptoms: array(healthCycleSymptomSchema).max(HEALTH_CYCLE_SYMPTOMS.length).refine((xs) => new Set(xs).size === xs.length, { message: "a symptom once" }).optional()
|
|
31951
|
+
}).strict().refine((v) => v.flow !== undefined || v.symptoms !== undefined, {
|
|
31952
|
+
message: "give a flow or symptoms"
|
|
31953
|
+
});
|
|
31954
|
+
var healthCycleSharedSchema = array(object({
|
|
31955
|
+
userId: string2(),
|
|
31956
|
+
name: string2(),
|
|
31957
|
+
nextOn: civilDaySchema
|
|
31958
|
+
}));
|
|
31959
|
+
|
|
31648
31960
|
// ../../packages/schema/src/contracts/health-export.ts
|
|
31649
31961
|
var HEALTH_EXPORT_RESOURCE_TYPES = [
|
|
31650
31962
|
"Patient",
|
|
@@ -31851,6 +32163,73 @@ var healthOperations = defineOperations({
|
|
|
31851
32163
|
response: { description: "The profile." },
|
|
31852
32164
|
errors: { 400: true, 403: "Health is off for the member, or the key acts for no member." }
|
|
31853
32165
|
},
|
|
32166
|
+
getCycle: {
|
|
32167
|
+
method: "get",
|
|
32168
|
+
path: "/health/cycle",
|
|
32169
|
+
scopes: ["health:read"],
|
|
32170
|
+
tag: "Health",
|
|
32171
|
+
summary: "Get the member's cycle",
|
|
32172
|
+
description: "Cycle, an optional part of Health each member turns on for themselves (off by default): `settings` (`on`, the `usualLength` they set or null, `shareNext`), the `days` logged in the last 400 days (oldest first: `day`, `flow` none/light/medium/heavy or null, `symptoms`) and the `summary` they make (the cycle's `day` today, `lastStart`, the usual `length` and where it comes from, `nextOn` and the `fertile` window as cycle days, both estimates, the last six `lengths`, and `regular`). While Cycle is off, `days` is empty and `summary` null.",
|
|
32173
|
+
status: 200,
|
|
32174
|
+
response: { description: "The member's cycle." },
|
|
32175
|
+
errors: { 403: "The key acts for no member." }
|
|
32176
|
+
},
|
|
32177
|
+
updateCycleSettings: {
|
|
32178
|
+
method: "patch",
|
|
32179
|
+
path: "/health/cycle/settings",
|
|
32180
|
+
scopes: ["health:write"],
|
|
32181
|
+
tag: "Health",
|
|
32182
|
+
summary: "Change the cycle settings",
|
|
32183
|
+
description: "Set `usualLength` (15\u201360 days, or null to work it out from the cycles) and `shareNext` (share only the next period's date with the Space). Only the member turns Cycle `on` or off, in do; a key that tries is refused (403). Returns the cycle.",
|
|
32184
|
+
body: updateHealthCycleSettingsInputSchema,
|
|
32185
|
+
status: 200,
|
|
32186
|
+
response: { description: "The member's cycle." },
|
|
32187
|
+
errors: {
|
|
32188
|
+
400: true,
|
|
32189
|
+
403: "Health or Cycle is off, a key tried to turn Cycle on or off, or the key acts for no member."
|
|
32190
|
+
}
|
|
32191
|
+
},
|
|
32192
|
+
logCycleDay: {
|
|
32193
|
+
method: "put",
|
|
32194
|
+
path: "/health/cycle/days/{day}",
|
|
32195
|
+
scopes: ["health:write"],
|
|
32196
|
+
tag: "Health",
|
|
32197
|
+
summary: "Log a cycle day",
|
|
32198
|
+
description: "Log the day (`YYYY-MM-DD`, today or before): the `flow` (none, light, medium, heavy, or null to clear it) and the `symptoms` (cramps, headache, tired, low_mood, skin). It replaces what the day had; an absent key keeps its part. Returns the cycle.",
|
|
32199
|
+
body: logHealthCycleDayInputSchema,
|
|
32200
|
+
status: 200,
|
|
32201
|
+
response: { description: "The member's cycle." },
|
|
32202
|
+
errors: {
|
|
32203
|
+
400: true,
|
|
32204
|
+
403: "Health or Cycle is off for the member, or the key acts for no member."
|
|
32205
|
+
}
|
|
32206
|
+
},
|
|
32207
|
+
deleteCycleDay: {
|
|
32208
|
+
method: "delete",
|
|
32209
|
+
path: "/health/cycle/days/{day}",
|
|
32210
|
+
scopes: ["health:write"],
|
|
32211
|
+
tag: "Health",
|
|
32212
|
+
summary: "Take back a cycle day",
|
|
32213
|
+
description: "Nothing logged on the day any more. Returns the cycle.",
|
|
32214
|
+
status: 200,
|
|
32215
|
+
response: { description: "The member's cycle." },
|
|
32216
|
+
errors: {
|
|
32217
|
+
400: true,
|
|
32218
|
+
403: "Health or Cycle is off for the member, or the key acts for no member.",
|
|
32219
|
+
404: true
|
|
32220
|
+
}
|
|
32221
|
+
},
|
|
32222
|
+
listSharedCycleDates: {
|
|
32223
|
+
method: "get",
|
|
32224
|
+
path: "/health/cycle/shared",
|
|
32225
|
+
scopes: ["health:read"],
|
|
32226
|
+
tag: "Health",
|
|
32227
|
+
summary: "List the shared next period dates",
|
|
32228
|
+
description: "The next period date each other member of the Space shares (`userId`, `name`, `nextOn`, an estimate), soonest first. Only the date: nothing they log is shared.",
|
|
32229
|
+
status: 200,
|
|
32230
|
+
response: { description: "The shared dates." },
|
|
32231
|
+
errors: { 403: "The key acts for no member." }
|
|
32232
|
+
},
|
|
31854
32233
|
log: {
|
|
31855
32234
|
method: "post",
|
|
31856
32235
|
path: "/health/log",
|
|
@@ -37786,233 +38165,6 @@ var planningRuleOperations = defineOperations({
|
|
|
37786
38165
|
})
|
|
37787
38166
|
});
|
|
37788
38167
|
|
|
37789
|
-
// ../../packages/schema/src/contracts/plans.ts
|
|
37790
|
-
var PLAN_KINDS = ["week", "day"];
|
|
37791
|
-
var PLAN_ITEM_ACTIONS = ["plan", "someday", "let_go"];
|
|
37792
|
-
var PLAN_ITEM_STATES = ["proposed", "accepted", "dismissed"];
|
|
37793
|
-
var PLAN_STATUSES = ["open", "settled", "replaced"];
|
|
37794
|
-
var PLAN_DUPLICATE_MODES = ["merge", "reject"];
|
|
37795
|
-
var PLAN_MERGE_OUTCOMES = [
|
|
37796
|
-
"scheduled_task",
|
|
37797
|
-
"covered_by_item",
|
|
37798
|
-
"already_planned"
|
|
37799
|
-
];
|
|
37800
|
-
var PLAN_MATCH_KINDS = ["task", "time_block", "event"];
|
|
37801
|
-
var PLAN_MAX_ITEMS = 60;
|
|
37802
|
-
var PLAN_MAX_BLOCKS = 140;
|
|
37803
|
-
var PLAN_REASON_MAX = 280;
|
|
37804
|
-
var PLAN_NOTE_MAX = 2000;
|
|
37805
|
-
var planKindSchema = _enum2(PLAN_KINDS);
|
|
37806
|
-
var planItemActionSchema = _enum2(PLAN_ITEM_ACTIONS);
|
|
37807
|
-
var planItemStateSchema = _enum2(PLAN_ITEM_STATES);
|
|
37808
|
-
var planStatusSchema = _enum2(PLAN_STATUSES);
|
|
37809
|
-
var civilDaySchema = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "expected YYYY-MM-DD").refine((s) => new Date(`${s}T00:00:00Z`).toISOString().slice(0, 10) === s, "not a real day");
|
|
37810
|
-
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
37811
|
-
function addCivilDays(day, n) {
|
|
37812
|
-
return new Date(Date.parse(`${day}T00:00:00Z`) + n * DAY_MS).toISOString().slice(0, 10);
|
|
37813
|
-
}
|
|
37814
|
-
function planDays(kind, startsOn) {
|
|
37815
|
-
return kind === "week" ? Array.from({ length: 7 }, (_, i) => addCivilDays(startsOn, i)) : [startsOn];
|
|
37816
|
-
}
|
|
37817
|
-
function isMonday(day) {
|
|
37818
|
-
return new Date(`${day}T00:00:00Z`).getUTCDay() === 1;
|
|
37819
|
-
}
|
|
37820
|
-
var planItemInputSchema = object({
|
|
37821
|
-
taskId: ulidSchema,
|
|
37822
|
-
action: planItemActionSchema.default("plan"),
|
|
37823
|
-
day: civilDaySchema.optional(),
|
|
37824
|
-
at: exports_coerce.date().optional(),
|
|
37825
|
-
durationMinutes: number2().int().min(5).max(24 * 60).optional(),
|
|
37826
|
-
reason: string2().trim().min(1).max(PLAN_REASON_MAX).optional()
|
|
37827
|
-
}).strict().superRefine((v, ctx) => {
|
|
37828
|
-
if (v.action === "plan") {
|
|
37829
|
-
if (v.day === undefined === (v.at === undefined)) {
|
|
37830
|
-
ctx.addIssue({
|
|
37831
|
-
code: "custom",
|
|
37832
|
-
message: "a `plan` item takes exactly one of `day` or `at`",
|
|
37833
|
-
path: ["day"]
|
|
37834
|
-
});
|
|
37835
|
-
}
|
|
37836
|
-
if (v.durationMinutes !== undefined && v.at === undefined) {
|
|
37837
|
-
ctx.addIssue({
|
|
37838
|
-
code: "custom",
|
|
37839
|
-
message: "`durationMinutes` goes with `at` (a time)",
|
|
37840
|
-
path: ["durationMinutes"]
|
|
37841
|
-
});
|
|
37842
|
-
}
|
|
37843
|
-
} else if (v.day !== undefined || v.at !== undefined || v.durationMinutes !== undefined) {
|
|
37844
|
-
ctx.addIssue({
|
|
37845
|
-
code: "custom",
|
|
37846
|
-
message: `a \`${v.action}\` item takes no day, time or duration`,
|
|
37847
|
-
path: ["action"]
|
|
37848
|
-
});
|
|
37849
|
-
}
|
|
37850
|
-
});
|
|
37851
|
-
var planBlockInputSchema = object({
|
|
37852
|
-
templateId: ulidSchema.optional(),
|
|
37853
|
-
lifeKind: lifeBlockKindSchema,
|
|
37854
|
-
title: string2().trim().min(1).max(500).optional(),
|
|
37855
|
-
startAt: exports_coerce.date(),
|
|
37856
|
-
endAt: exports_coerce.date(),
|
|
37857
|
-
routineId: ulidSchema.optional(),
|
|
37858
|
-
reason: string2().trim().min(1).max(PLAN_REASON_MAX).optional()
|
|
37859
|
-
}).strict().refine((v) => {
|
|
37860
|
-
const minutes = (v.endAt.getTime() - v.startAt.getTime()) / 60000;
|
|
37861
|
-
return minutes > 0 && minutes <= TIME_BLOCK_MAX_MINUTES;
|
|
37862
|
-
}, { message: "endAt must be after startAt and at most a day later", path: ["endAt"] });
|
|
37863
|
-
var createPlanInputSchema = object({
|
|
37864
|
-
kind: planKindSchema,
|
|
37865
|
-
startsOn: civilDaySchema,
|
|
37866
|
-
forUserId: string2().min(1).optional(),
|
|
37867
|
-
note: string2().trim().min(1).max(PLAN_NOTE_MAX).optional(),
|
|
37868
|
-
items: array(planItemInputSchema).max(PLAN_MAX_ITEMS).default([]),
|
|
37869
|
-
blocks: array(planBlockInputSchema).max(PLAN_MAX_BLOCKS).default([]),
|
|
37870
|
-
onDuplicate: _enum2(PLAN_DUPLICATE_MODES).default("merge")
|
|
37871
|
-
}).strict().superRefine((v, ctx) => {
|
|
37872
|
-
if (v.items.length + v.blocks.length === 0) {
|
|
37873
|
-
ctx.addIssue({
|
|
37874
|
-
code: "custom",
|
|
37875
|
-
message: "a plan proposes at least one item or block",
|
|
37876
|
-
path: ["items"]
|
|
37877
|
-
});
|
|
37878
|
-
}
|
|
37879
|
-
if (v.kind === "week" && !isMonday(v.startsOn)) {
|
|
37880
|
-
ctx.addIssue({
|
|
37881
|
-
code: "custom",
|
|
37882
|
-
message: "a week plan starts on a Monday",
|
|
37883
|
-
path: ["startsOn"]
|
|
37884
|
-
});
|
|
37885
|
-
}
|
|
37886
|
-
const days = new Set(planDays(v.kind, v.startsOn));
|
|
37887
|
-
const seen = new Set;
|
|
37888
|
-
v.items.forEach((item, i) => {
|
|
37889
|
-
if (seen.has(item.taskId)) {
|
|
37890
|
-
ctx.addIssue({
|
|
37891
|
-
code: "custom",
|
|
37892
|
-
message: "one item per task",
|
|
37893
|
-
path: ["items", i, "taskId"]
|
|
37894
|
-
});
|
|
37895
|
-
}
|
|
37896
|
-
seen.add(item.taskId);
|
|
37897
|
-
if (item.day !== undefined && !days.has(item.day)) {
|
|
37898
|
-
ctx.addIssue({
|
|
37899
|
-
code: "custom",
|
|
37900
|
-
message: `the day falls outside the ${v.kind}`,
|
|
37901
|
-
path: ["items", i, "day"]
|
|
37902
|
-
});
|
|
37903
|
-
}
|
|
37904
|
-
});
|
|
37905
|
-
});
|
|
37906
|
-
var planDecisionInputSchema = object({
|
|
37907
|
-
itemIds: array(string2().min(1)).min(1).max(PLAN_MAX_ITEMS + PLAN_MAX_BLOCKS).optional()
|
|
37908
|
-
}).strict();
|
|
37909
|
-
var planAdjustInputSchema = object({
|
|
37910
|
-
itemId: string2().min(1),
|
|
37911
|
-
startAt: exports_coerce.date(),
|
|
37912
|
-
endAt: exports_coerce.date()
|
|
37913
|
-
}).strict().refine((v) => {
|
|
37914
|
-
const minutes = (v.endAt.getTime() - v.startAt.getTime()) / 60000;
|
|
37915
|
-
return minutes >= 5 && minutes <= TIME_BLOCK_MAX_MINUTES;
|
|
37916
|
-
}, { message: "endAt must be 5 minutes to a day after startAt", path: ["endAt"] });
|
|
37917
|
-
var PLAN_TEMPLATES = ["normal", "light", "away"];
|
|
37918
|
-
var planTemplateSchema = _enum2(PLAN_TEMPLATES);
|
|
37919
|
-
var planDraftInputSchema = object({
|
|
37920
|
-
startsOn: civilDaySchema.refine(isMonday, "a week starts on a Monday"),
|
|
37921
|
-
template: planTemplateSchema.default("normal")
|
|
37922
|
-
}).strict();
|
|
37923
|
-
var planPlaceInputSchema = object({
|
|
37924
|
-
taskId: ulidSchema,
|
|
37925
|
-
startAt: exports_coerce.date(),
|
|
37926
|
-
endAt: exports_coerce.date()
|
|
37927
|
-
}).strict().refine((v) => {
|
|
37928
|
-
const minutes = (v.endAt.getTime() - v.startAt.getTime()) / 60000;
|
|
37929
|
-
return minutes >= 5 && minutes <= TIME_BLOCK_MAX_MINUTES;
|
|
37930
|
-
}, { message: "endAt must be 5 minutes to a day after startAt", path: ["endAt"] });
|
|
37931
|
-
var planUnplaceInputSchema = object({ taskId: ulidSchema }).strict();
|
|
37932
|
-
var planListQuerySchema = object({
|
|
37933
|
-
kind: planKindSchema.optional(),
|
|
37934
|
-
status: planStatusSchema.optional(),
|
|
37935
|
-
startsOn: civilDaySchema.optional(),
|
|
37936
|
-
taskId: ulidSchema.optional()
|
|
37937
|
-
});
|
|
37938
|
-
var planTaskSchema = object({
|
|
37939
|
-
id: ulidSchema,
|
|
37940
|
-
title: string2(),
|
|
37941
|
-
status: taskStatusSchema,
|
|
37942
|
-
scheduledAt: exports_coerce.date().nullable(),
|
|
37943
|
-
allDay: boolean2(),
|
|
37944
|
-
dueAt: exports_coerce.date().nullable(),
|
|
37945
|
-
durationMinutes: number2().int().nullable(),
|
|
37946
|
-
areaId: string2().nullable(),
|
|
37947
|
-
projectId: string2().nullable(),
|
|
37948
|
-
moveCount: number2().int().nonnegative().default(0)
|
|
37949
|
-
});
|
|
37950
|
-
var planItemViewSchema = object({
|
|
37951
|
-
id: string2(),
|
|
37952
|
-
taskId: ulidSchema,
|
|
37953
|
-
action: planItemActionSchema,
|
|
37954
|
-
scheduledAt: exports_coerce.date().nullable(),
|
|
37955
|
-
allDay: boolean2(),
|
|
37956
|
-
durationMinutes: number2().int().nullable(),
|
|
37957
|
-
reason: string2().nullable(),
|
|
37958
|
-
state: planItemStateSchema,
|
|
37959
|
-
decidedAt: exports_coerce.date().nullable(),
|
|
37960
|
-
task: planTaskSchema
|
|
37961
|
-
});
|
|
37962
|
-
var planBlockViewSchema = object({
|
|
37963
|
-
id: string2(),
|
|
37964
|
-
templateId: string2().nullable(),
|
|
37965
|
-
lifeKind: lifeBlockKindSchema,
|
|
37966
|
-
title: string2(),
|
|
37967
|
-
startAt: exports_coerce.date(),
|
|
37968
|
-
endAt: exports_coerce.date(),
|
|
37969
|
-
routineId: string2().nullable(),
|
|
37970
|
-
reason: string2().nullable(),
|
|
37971
|
-
state: planItemStateSchema,
|
|
37972
|
-
decidedAt: exports_coerce.date().nullable(),
|
|
37973
|
-
blockId: string2().nullable()
|
|
37974
|
-
});
|
|
37975
|
-
var planViewSchema = object({
|
|
37976
|
-
id: string2(),
|
|
37977
|
-
kind: planKindSchema,
|
|
37978
|
-
startsOn: civilDaySchema,
|
|
37979
|
-
userId: string2(),
|
|
37980
|
-
agentId: string2().nullable(),
|
|
37981
|
-
note: string2().nullable(),
|
|
37982
|
-
template: planTemplateSchema.nullable().default(null),
|
|
37983
|
-
status: planStatusSchema,
|
|
37984
|
-
createdAt: exports_coerce.date(),
|
|
37985
|
-
updatedAt: exports_coerce.date(),
|
|
37986
|
-
items: array(planItemViewSchema),
|
|
37987
|
-
blocks: array(planBlockViewSchema).default([])
|
|
37988
|
-
});
|
|
37989
|
-
var planMergeSchema = object({
|
|
37990
|
-
blockIndex: number2().int().min(0),
|
|
37991
|
-
title: string2(),
|
|
37992
|
-
outcome: _enum2(PLAN_MERGE_OUTCOMES),
|
|
37993
|
-
match: object({ kind: _enum2(PLAN_MATCH_KINDS), id: string2(), title: string2() }),
|
|
37994
|
-
hint: string2()
|
|
37995
|
-
});
|
|
37996
|
-
var PLAN_RULE_OUTCOMES = [
|
|
37997
|
-
"anchored",
|
|
37998
|
-
"added",
|
|
37999
|
-
"kept_free",
|
|
38000
|
-
"over_limit",
|
|
38001
|
-
"below_min",
|
|
38002
|
-
"not_theirs"
|
|
38003
|
-
];
|
|
38004
|
-
var planShapingSchema = object({
|
|
38005
|
-
ruleId: string2(),
|
|
38006
|
-
sentence: string2(),
|
|
38007
|
-
outcome: _enum2(PLAN_RULE_OUTCOMES),
|
|
38008
|
-
title: string2(),
|
|
38009
|
-
hint: string2()
|
|
38010
|
-
});
|
|
38011
|
-
var planCreateResultSchema = planViewSchema.extend({
|
|
38012
|
-
merged: array(planMergeSchema).default([]),
|
|
38013
|
-
shaped: array(planShapingSchema).default([])
|
|
38014
|
-
});
|
|
38015
|
-
|
|
38016
38168
|
// ../../packages/schema/src/operations/plans.ts
|
|
38017
38169
|
function decision(path, verb, what) {
|
|
38018
38170
|
return {
|
|
@@ -51502,6 +51654,74 @@ var HEALTH_COMMAND_SPECS = [
|
|
|
51502
51654
|
scopes: WRITE6,
|
|
51503
51655
|
returns: "HealthLabAnalyteView",
|
|
51504
51656
|
notes: "Body: SetHealthLabAnalyteInput. An absent key keeps a field; null clears it."
|
|
51657
|
+
},
|
|
51658
|
+
{
|
|
51659
|
+
path: ["health", "cycle"],
|
|
51660
|
+
summary: "Show your cycle: the settings, the days logged and what they say.",
|
|
51661
|
+
args: [],
|
|
51662
|
+
flags: [],
|
|
51663
|
+
scopes: READ6,
|
|
51664
|
+
returns: "HealthCycleView",
|
|
51665
|
+
notes: `${routeOf(healthOperations.getCycle)}. Off until you turn it on in do: then \`days\` is empty and \`summary\` null. \`summary.nextOn\` and \`fertile\` are estimates from the usual length.`
|
|
51666
|
+
},
|
|
51667
|
+
{
|
|
51668
|
+
path: ["health", "cycle", "log"],
|
|
51669
|
+
summary: "Log a cycle day (do health cycle log 2026-10-22 --flow light --symptoms cramps,tired).",
|
|
51670
|
+
args: [{ name: "day", required: true, description: "The day, YYYY-MM-DD: today or before." }],
|
|
51671
|
+
flags: [
|
|
51672
|
+
DATA_FLAG,
|
|
51673
|
+
{
|
|
51674
|
+
name: "flow",
|
|
51675
|
+
type: "string",
|
|
51676
|
+
description: 'none|light|medium|heavy; "" clears it.'
|
|
51677
|
+
},
|
|
51678
|
+
{
|
|
51679
|
+
name: "symptoms",
|
|
51680
|
+
type: "string",
|
|
51681
|
+
description: 'cramps,headache,tired,low_mood,skin, comma-separated; "" clears them.'
|
|
51682
|
+
}
|
|
51683
|
+
],
|
|
51684
|
+
scopes: WRITE6,
|
|
51685
|
+
returns: "HealthCycleView",
|
|
51686
|
+
notes: `${routeOf(healthOperations.logCycleDay)}. Body: LogHealthCycleDayInput. It replaces what the day had; a part not given stays.`
|
|
51687
|
+
},
|
|
51688
|
+
{
|
|
51689
|
+
path: ["health", "cycle", "unlog"],
|
|
51690
|
+
summary: "Take back a cycle day: nothing logged on it.",
|
|
51691
|
+
args: [{ name: "day", required: true, description: "The day, YYYY-MM-DD." }],
|
|
51692
|
+
flags: [],
|
|
51693
|
+
scopes: WRITE6,
|
|
51694
|
+
returns: "HealthCycleView"
|
|
51695
|
+
},
|
|
51696
|
+
{
|
|
51697
|
+
path: ["health", "cycle", "set"],
|
|
51698
|
+
summary: "Set your usual cycle length or share the next date (--length 30, --share on).",
|
|
51699
|
+
args: [],
|
|
51700
|
+
flags: [
|
|
51701
|
+
DATA_FLAG,
|
|
51702
|
+
{
|
|
51703
|
+
name: "length",
|
|
51704
|
+
type: "string",
|
|
51705
|
+
description: "Your usual length, 15\u201360 days; auto works it out from your cycles."
|
|
51706
|
+
},
|
|
51707
|
+
{
|
|
51708
|
+
name: "share",
|
|
51709
|
+
type: "string",
|
|
51710
|
+
description: "on|off: share only the next period's date with the Space."
|
|
51711
|
+
}
|
|
51712
|
+
],
|
|
51713
|
+
scopes: WRITE6,
|
|
51714
|
+
returns: "HealthCycleView",
|
|
51715
|
+
notes: `${routeOf(healthOperations.updateCycleSettings)}. Body: UpdateHealthCycleSettingsInput. Turning Cycle on or off is yours alone, in do: a key that tries gets 403.`
|
|
51716
|
+
},
|
|
51717
|
+
{
|
|
51718
|
+
path: ["health", "cycle", "shared"],
|
|
51719
|
+
summary: "List the next period dates the Space's other members share with it.",
|
|
51720
|
+
args: [],
|
|
51721
|
+
flags: [],
|
|
51722
|
+
scopes: READ6,
|
|
51723
|
+
returns: "HealthCycleShared",
|
|
51724
|
+
notes: "Only the date each one shares (an estimate); nothing they log."
|
|
51505
51725
|
}
|
|
51506
51726
|
];
|
|
51507
51727
|
var HEALTH_RECORD_OPERATIONS = {
|
|
@@ -51722,6 +51942,51 @@ var commands23 = pairCommands(HEALTH_COMMAND_SPECS, {
|
|
|
51722
51942
|
data: await requireClient().post(pathOf(googleHealthOperations.sync), {}),
|
|
51723
51943
|
render: renderRecord
|
|
51724
51944
|
}),
|
|
51945
|
+
"health cycle": async ({ requireClient }) => ({
|
|
51946
|
+
data: await requireClient().get(pathOf(healthOperations.getCycle)),
|
|
51947
|
+
render: renderRecord
|
|
51948
|
+
}),
|
|
51949
|
+
"health cycle log": async ({ args, flags, requireClient }) => {
|
|
51950
|
+
const day = requireArg(args, 0, "day");
|
|
51951
|
+
const fields = flagString(flags, "data") ? readDataFlag(flags) : {};
|
|
51952
|
+
const flow = flagString(flags, "flow");
|
|
51953
|
+
if (flow !== undefined)
|
|
51954
|
+
fields.flow = flow.trim() ? flow.trim() : null;
|
|
51955
|
+
const symptoms = flagString(flags, "symptoms");
|
|
51956
|
+
if (symptoms !== undefined) {
|
|
51957
|
+
fields.symptoms = symptoms.split(",").map((s) => s.trim()).filter(Boolean);
|
|
51958
|
+
}
|
|
51959
|
+
const body = parseInput(logHealthCycleDayInputSchema, fields);
|
|
51960
|
+
return {
|
|
51961
|
+
data: await requireClient().put(pathOf(healthOperations.logCycleDay, { day }), body),
|
|
51962
|
+
render: renderRecord
|
|
51963
|
+
};
|
|
51964
|
+
},
|
|
51965
|
+
"health cycle unlog": async ({ args, requireClient }) => ({
|
|
51966
|
+
data: await requireClient().delete(pathOf(healthOperations.deleteCycleDay, { day: requireArg(args, 0, "day") })),
|
|
51967
|
+
render: renderRecord
|
|
51968
|
+
}),
|
|
51969
|
+
"health cycle set": async ({ flags, requireClient }) => {
|
|
51970
|
+
const fields = flagString(flags, "data") ? readDataFlag(flags) : {};
|
|
51971
|
+
const length = flagString(flags, "length");
|
|
51972
|
+
if (length !== undefined)
|
|
51973
|
+
fields.usualLength = length === "auto" ? null : Number(length);
|
|
51974
|
+
const share = flagString(flags, "share");
|
|
51975
|
+
if (share !== undefined) {
|
|
51976
|
+
if (share !== "on" && share !== "off")
|
|
51977
|
+
throw usageError("--share is on or off");
|
|
51978
|
+
fields.shareNext = share === "on";
|
|
51979
|
+
}
|
|
51980
|
+
const body = parseInput(updateHealthCycleSettingsInputSchema, fields);
|
|
51981
|
+
return {
|
|
51982
|
+
data: await requireClient().patch(pathOf(healthOperations.updateCycleSettings), body),
|
|
51983
|
+
render: renderRecord
|
|
51984
|
+
};
|
|
51985
|
+
},
|
|
51986
|
+
"health cycle shared": async ({ requireClient }) => ({
|
|
51987
|
+
data: await requireClient().getPage(pathOf(healthOperations.listSharedCycleDates)),
|
|
51988
|
+
render: renderList
|
|
51989
|
+
}),
|
|
51725
51990
|
"health consent": async ({ requireClient }) => ({
|
|
51726
51991
|
data: await requireClient().get(pathOf(healthOperations.getConsent)),
|
|
51727
51992
|
render: renderRecord
|
package/package.json
CHANGED