@robbeverhelst/do 1.341.0 → 1.342.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 +252 -74
- package/package.json +1 -1
package/dist/do.js
CHANGED
|
@@ -14418,7 +14418,7 @@ var configError = (message) => new CliError("config", message, EXIT.CONFIG);
|
|
|
14418
14418
|
|
|
14419
14419
|
// src/meta.ts
|
|
14420
14420
|
var CLI_NAME = "do";
|
|
14421
|
-
var VERSION = "1.
|
|
14421
|
+
var VERSION = "1.342.0";
|
|
14422
14422
|
var API_PREFIX = "/api/v1";
|
|
14423
14423
|
var DEFAULT_API_URL = "http://localhost:3001";
|
|
14424
14424
|
|
|
@@ -18020,7 +18020,10 @@ var habits = pgTable("habits", {
|
|
|
18020
18020
|
pausedFrom: date5("paused_from", { mode: "string" }),
|
|
18021
18021
|
pausedUntil: date5("paused_until", { mode: "string" }),
|
|
18022
18022
|
remind: boolean4("remind").notNull().default(false),
|
|
18023
|
-
retiredAt: timestamp("retired_at", { withTimezone: true })
|
|
18023
|
+
retiredAt: timestamp("retired_at", { withTimezone: true }),
|
|
18024
|
+
eventSourceId: text("event_source_id"),
|
|
18025
|
+
eventMatch: text("event_match"),
|
|
18026
|
+
eventOffset: text("event_offset")
|
|
18024
18027
|
}, (t) => [
|
|
18025
18028
|
index("habits_tenant_idx").on(t.tenantId),
|
|
18026
18029
|
index("habits_tenant_area_idx").on(t.tenantId, t.areaId),
|
|
@@ -18050,6 +18053,8 @@ var recurrenceRules = pgTable("recurrence_rules", {
|
|
|
18050
18053
|
interval: integer2("interval").notNull().default(1),
|
|
18051
18054
|
freq: recurrenceFreq("freq"),
|
|
18052
18055
|
byDay: text("by_day").array(),
|
|
18056
|
+
byMonthDay: integer2("by_month_day"),
|
|
18057
|
+
startsOn: date5("starts_on", { mode: "string" }),
|
|
18053
18058
|
timeOfDay: text("time_of_day"),
|
|
18054
18059
|
until: timestamp("until", { withTimezone: true }),
|
|
18055
18060
|
count: integer2("count"),
|
|
@@ -21269,6 +21274,75 @@ var animalOperations = defineOperations({
|
|
|
21269
21274
|
// ../../packages/schema/src/contracts/habit-sources.ts
|
|
21270
21275
|
var habitSourceSchema = _enum2(["manual", "google_fit", "strava", "github"]);
|
|
21271
21276
|
|
|
21277
|
+
// ../../packages/schema/src/contracts/recurrence.ts
|
|
21278
|
+
var recurrenceRuleSchema = createSelectSchema(recurrenceRules, {
|
|
21279
|
+
until: exports_coerce.date().nullable(),
|
|
21280
|
+
byMonthDay: number2().int().nullable().default(null),
|
|
21281
|
+
startsOn: exports_iso.date().nullable().default(null)
|
|
21282
|
+
});
|
|
21283
|
+
var occurrenceSchema = createSelectSchema(occurrences, {
|
|
21284
|
+
occurrenceDate: exports_coerce.date(),
|
|
21285
|
+
completedAt: exports_coerce.date().nullable()
|
|
21286
|
+
});
|
|
21287
|
+
var byDayCodeSchema = _enum2(["MO", "TU", "WE", "TH", "FR", "SA", "SU"]);
|
|
21288
|
+
var byDayOrdinalSchema = _enum2(["1", "2", "3", "4", "-1"]);
|
|
21289
|
+
var byDaySchema = union([
|
|
21290
|
+
byDayCodeSchema,
|
|
21291
|
+
templateLiteral([byDayOrdinalSchema, byDayCodeSchema])
|
|
21292
|
+
]);
|
|
21293
|
+
var BY_DAY_RE = /^(-1|[1-4])?(MO|TU|WE|TH|FR|SA|SU)$/;
|
|
21294
|
+
function parseByDay(code) {
|
|
21295
|
+
const m = BY_DAY_RE.exec(code);
|
|
21296
|
+
if (!m)
|
|
21297
|
+
return null;
|
|
21298
|
+
return { ordinal: m[1] ? Number(m[1]) : null, weekday: m[2] };
|
|
21299
|
+
}
|
|
21300
|
+
var recurrenceRuleParams = {
|
|
21301
|
+
timezone: string2().min(1).default("UTC"),
|
|
21302
|
+
interval: number2().int().positive().default(1),
|
|
21303
|
+
mode: recurrenceModeSchema,
|
|
21304
|
+
timeOfDay: string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "time-of-day must be HH:MM (24h)").nullish(),
|
|
21305
|
+
freq: recurrenceFreqSchema.optional(),
|
|
21306
|
+
byDay: array(byDaySchema).optional(),
|
|
21307
|
+
until: exports_coerce.date().optional(),
|
|
21308
|
+
count: number2().int().positive().optional(),
|
|
21309
|
+
unit: recurrenceUnitSchema.optional(),
|
|
21310
|
+
anchor: recurrenceAnchorSchema.optional()
|
|
21311
|
+
};
|
|
21312
|
+
function refineRecurrenceRule(v, ctx) {
|
|
21313
|
+
if (v.mode === "rigid" && !v.freq) {
|
|
21314
|
+
ctx.addIssue({ code: "custom", path: ["freq"], message: "rigid rules require a freq" });
|
|
21315
|
+
}
|
|
21316
|
+
const ordinal = v.byDay?.findIndex((code) => parseByDay(code)?.ordinal != null) ?? -1;
|
|
21317
|
+
if (ordinal >= 0 && v.freq !== "monthly" && v.freq !== "yearly") {
|
|
21318
|
+
ctx.addIssue({
|
|
21319
|
+
code: "custom",
|
|
21320
|
+
path: ["byDay", ordinal],
|
|
21321
|
+
message: "an ordinal weekday (1SU, -1FR) needs a monthly or yearly freq"
|
|
21322
|
+
});
|
|
21323
|
+
}
|
|
21324
|
+
if (v.mode === "flexible") {
|
|
21325
|
+
if (!v.unit) {
|
|
21326
|
+
ctx.addIssue({ code: "custom", path: ["unit"], message: "flexible rules require a unit" });
|
|
21327
|
+
}
|
|
21328
|
+
if (!v.anchor) {
|
|
21329
|
+
ctx.addIssue({
|
|
21330
|
+
code: "custom",
|
|
21331
|
+
path: ["anchor"],
|
|
21332
|
+
message: "flexible rules require an anchor"
|
|
21333
|
+
});
|
|
21334
|
+
}
|
|
21335
|
+
}
|
|
21336
|
+
}
|
|
21337
|
+
var createRecurrenceRuleInputSchema = object({
|
|
21338
|
+
templateId: ulidSchema,
|
|
21339
|
+
...recurrenceRuleParams
|
|
21340
|
+
}).superRefine(refineRecurrenceRule);
|
|
21341
|
+
var updateRecurrenceRuleInputSchema = object({ ...recurrenceRuleParams }).superRefine(refineRecurrenceRule);
|
|
21342
|
+
var updateOccurrenceInputSchema = createUpdateSchema(occurrences, {
|
|
21343
|
+
occurrenceDate: exports_coerce.date().optional()
|
|
21344
|
+
}).pick({ occurrenceDate: true, status: true }).strict();
|
|
21345
|
+
|
|
21272
21346
|
// ../../packages/schema/src/contracts/habits.ts
|
|
21273
21347
|
var habitSchema = createSelectSchema(habits, {
|
|
21274
21348
|
source: habitSourceSchema.default("manual"),
|
|
@@ -21278,7 +21352,10 @@ var habitSchema = createSelectSchema(habits, {
|
|
|
21278
21352
|
pausedFrom: exports_iso.date().nullable().default(null),
|
|
21279
21353
|
pausedUntil: exports_iso.date().nullable().default(null),
|
|
21280
21354
|
remind: boolean2().default(false),
|
|
21281
|
-
retiredAt: exports_coerce.date().nullable().default(null)
|
|
21355
|
+
retiredAt: exports_coerce.date().nullable().default(null),
|
|
21356
|
+
eventSourceId: string2().nullable().default(null),
|
|
21357
|
+
eventMatch: string2().nullable().default(null),
|
|
21358
|
+
eventOffset: string2().nullable().default(null)
|
|
21282
21359
|
});
|
|
21283
21360
|
var habitEntrySchema = createSelectSchema(habitEntries, {
|
|
21284
21361
|
occurredAt: exports_coerce.date(),
|
|
@@ -21297,6 +21374,30 @@ var habitTimeOfDaySchema = union([
|
|
|
21297
21374
|
]);
|
|
21298
21375
|
var habitAliasSchema = string2().trim().min(1).max(60);
|
|
21299
21376
|
var habitAliasesSchema = array(habitAliasSchema).max(12).transform((aliases) => aliases.filter((a, i) => aliases.findIndex((b) => b.toLowerCase() === a.toLowerCase()) === i));
|
|
21377
|
+
var habitScheduleSchema = discriminatedUnion("kind", [
|
|
21378
|
+
object({ kind: literal("daily") }),
|
|
21379
|
+
object({
|
|
21380
|
+
kind: literal("weekdays"),
|
|
21381
|
+
days: array(byDayCodeSchema).min(1).max(7).refine((days) => new Set(days).size === days.length, "each weekday once")
|
|
21382
|
+
}),
|
|
21383
|
+
object({
|
|
21384
|
+
kind: literal("every"),
|
|
21385
|
+
interval: number2().int().min(2),
|
|
21386
|
+
unit: _enum2(["day", "week"]),
|
|
21387
|
+
anchor: exports_iso.date()
|
|
21388
|
+
}),
|
|
21389
|
+
object({
|
|
21390
|
+
kind: literal("monthly"),
|
|
21391
|
+
dayOfMonth: union([number2().int().min(1).max(31), literal(-1)])
|
|
21392
|
+
}),
|
|
21393
|
+
object({
|
|
21394
|
+
kind: literal("event"),
|
|
21395
|
+
sourceId: ulidSchema,
|
|
21396
|
+
match: string2().trim().min(1).max(120),
|
|
21397
|
+
offset: _enum2(["day_before_evening", "same_day"])
|
|
21398
|
+
})
|
|
21399
|
+
]);
|
|
21400
|
+
var eventColumns = { eventSourceId: true, eventMatch: true, eventOffset: true };
|
|
21300
21401
|
var createHabitInputSchema = createInsertSchema(habits, {
|
|
21301
21402
|
id: ulidSchema,
|
|
21302
21403
|
source: habitSourceSchema.optional(),
|
|
@@ -21310,8 +21411,9 @@ var createHabitInputSchema = createInsertSchema(habits, {
|
|
|
21310
21411
|
aliases: habitAliasesSchema.optional(),
|
|
21311
21412
|
timeOfDay: habitTimeOfDaySchema.nullish(),
|
|
21312
21413
|
remind: boolean2().optional()
|
|
21313
|
-
}).omit({ tenantId: true, recurrenceRuleId: true, retiredAt: true }).extend({
|
|
21414
|
+
}).omit({ tenantId: true, recurrenceRuleId: true, retiredAt: true, ...eventColumns }).extend({
|
|
21314
21415
|
title: string2().min(1),
|
|
21416
|
+
schedule: habitScheduleSchema.optional(),
|
|
21315
21417
|
displayKind: string2().min(1).nullish()
|
|
21316
21418
|
});
|
|
21317
21419
|
var updateHabitInputSchema = createUpdateSchema(habits, {
|
|
@@ -21332,8 +21434,12 @@ var updateHabitInputSchema = createUpdateSchema(habits, {
|
|
|
21332
21434
|
recurrenceRuleId: true,
|
|
21333
21435
|
pausedFrom: true,
|
|
21334
21436
|
pausedUntil: true,
|
|
21335
|
-
retiredAt: true
|
|
21336
|
-
|
|
21437
|
+
retiredAt: true,
|
|
21438
|
+
...eventColumns
|
|
21439
|
+
}).extend({
|
|
21440
|
+
title: string2().min(1).optional(),
|
|
21441
|
+
schedule: habitScheduleSchema.optional()
|
|
21442
|
+
});
|
|
21337
21443
|
var HABIT_ENTRY_NOTE_MAX = 280;
|
|
21338
21444
|
var habitEntryNoteSchema = string2().trim().max(HABIT_ENTRY_NOTE_MAX).transform((note) => note === "" ? null : note);
|
|
21339
21445
|
var createHabitEntryInputSchema = createInsertSchema(habitEntries, {
|
|
@@ -21387,7 +21493,9 @@ var habitSummarySchema = habitSchema.extend({
|
|
|
21387
21493
|
inRoutines: array(habitRoutineRefSchema).default([]),
|
|
21388
21494
|
lastCheckIn: habitLastCheckInSchema.nullable().default(null),
|
|
21389
21495
|
pause: habitPauseSchema.nullable().default(null),
|
|
21390
|
-
today: habitTodaySchema.default({ due: true, done: false })
|
|
21496
|
+
today: habitTodaySchema.default({ due: true, done: false }),
|
|
21497
|
+
schedule: habitScheduleSchema.default({ kind: "daily" }),
|
|
21498
|
+
nextDue: array(exports_iso.date()).default([])
|
|
21391
21499
|
});
|
|
21392
21500
|
var habitHeatmapCellSchema = object({
|
|
21393
21501
|
date: string2(),
|
|
@@ -22194,73 +22302,6 @@ var projectDetailSchema = projectViewSchema.extend({
|
|
|
22194
22302
|
});
|
|
22195
22303
|
var attachTaskInputSchema = object({ taskId: ulidSchema });
|
|
22196
22304
|
|
|
22197
|
-
// ../../packages/schema/src/contracts/recurrence.ts
|
|
22198
|
-
var recurrenceRuleSchema = createSelectSchema(recurrenceRules, {
|
|
22199
|
-
until: exports_coerce.date().nullable()
|
|
22200
|
-
});
|
|
22201
|
-
var occurrenceSchema = createSelectSchema(occurrences, {
|
|
22202
|
-
occurrenceDate: exports_coerce.date(),
|
|
22203
|
-
completedAt: exports_coerce.date().nullable()
|
|
22204
|
-
});
|
|
22205
|
-
var byDayCodeSchema = _enum2(["MO", "TU", "WE", "TH", "FR", "SA", "SU"]);
|
|
22206
|
-
var byDayOrdinalSchema = _enum2(["1", "2", "3", "4", "-1"]);
|
|
22207
|
-
var byDaySchema = union([
|
|
22208
|
-
byDayCodeSchema,
|
|
22209
|
-
templateLiteral([byDayOrdinalSchema, byDayCodeSchema])
|
|
22210
|
-
]);
|
|
22211
|
-
var BY_DAY_RE = /^(-1|[1-4])?(MO|TU|WE|TH|FR|SA|SU)$/;
|
|
22212
|
-
function parseByDay(code) {
|
|
22213
|
-
const m = BY_DAY_RE.exec(code);
|
|
22214
|
-
if (!m)
|
|
22215
|
-
return null;
|
|
22216
|
-
return { ordinal: m[1] ? Number(m[1]) : null, weekday: m[2] };
|
|
22217
|
-
}
|
|
22218
|
-
var recurrenceRuleParams = {
|
|
22219
|
-
timezone: string2().min(1).default("UTC"),
|
|
22220
|
-
interval: number2().int().positive().default(1),
|
|
22221
|
-
mode: recurrenceModeSchema,
|
|
22222
|
-
timeOfDay: string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "time-of-day must be HH:MM (24h)").nullish(),
|
|
22223
|
-
freq: recurrenceFreqSchema.optional(),
|
|
22224
|
-
byDay: array(byDaySchema).optional(),
|
|
22225
|
-
until: exports_coerce.date().optional(),
|
|
22226
|
-
count: number2().int().positive().optional(),
|
|
22227
|
-
unit: recurrenceUnitSchema.optional(),
|
|
22228
|
-
anchor: recurrenceAnchorSchema.optional()
|
|
22229
|
-
};
|
|
22230
|
-
function refineRecurrenceRule(v, ctx) {
|
|
22231
|
-
if (v.mode === "rigid" && !v.freq) {
|
|
22232
|
-
ctx.addIssue({ code: "custom", path: ["freq"], message: "rigid rules require a freq" });
|
|
22233
|
-
}
|
|
22234
|
-
const ordinal = v.byDay?.findIndex((code) => parseByDay(code)?.ordinal != null) ?? -1;
|
|
22235
|
-
if (ordinal >= 0 && v.freq !== "monthly" && v.freq !== "yearly") {
|
|
22236
|
-
ctx.addIssue({
|
|
22237
|
-
code: "custom",
|
|
22238
|
-
path: ["byDay", ordinal],
|
|
22239
|
-
message: "an ordinal weekday (1SU, -1FR) needs a monthly or yearly freq"
|
|
22240
|
-
});
|
|
22241
|
-
}
|
|
22242
|
-
if (v.mode === "flexible") {
|
|
22243
|
-
if (!v.unit) {
|
|
22244
|
-
ctx.addIssue({ code: "custom", path: ["unit"], message: "flexible rules require a unit" });
|
|
22245
|
-
}
|
|
22246
|
-
if (!v.anchor) {
|
|
22247
|
-
ctx.addIssue({
|
|
22248
|
-
code: "custom",
|
|
22249
|
-
path: ["anchor"],
|
|
22250
|
-
message: "flexible rules require an anchor"
|
|
22251
|
-
});
|
|
22252
|
-
}
|
|
22253
|
-
}
|
|
22254
|
-
}
|
|
22255
|
-
var createRecurrenceRuleInputSchema = object({
|
|
22256
|
-
templateId: ulidSchema,
|
|
22257
|
-
...recurrenceRuleParams
|
|
22258
|
-
}).superRefine(refineRecurrenceRule);
|
|
22259
|
-
var updateRecurrenceRuleInputSchema = object({ ...recurrenceRuleParams }).superRefine(refineRecurrenceRule);
|
|
22260
|
-
var updateOccurrenceInputSchema = createUpdateSchema(occurrences, {
|
|
22261
|
-
occurrenceDate: exports_coerce.date().optional()
|
|
22262
|
-
}).pick({ occurrenceDate: true, status: true }).strict();
|
|
22263
|
-
|
|
22264
22305
|
// ../../packages/schema/src/contracts/routines.ts
|
|
22265
22306
|
var routineDayTimesSchema = partialRecord(_enum2(["MO", "TU", "WE", "TH", "FR", "SA", "SU"]), string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/));
|
|
22266
22307
|
var routineSchema = createSelectSchema(routines);
|
|
@@ -46989,7 +47030,144 @@ var commands19 = [
|
|
|
46989
47030
|
];
|
|
46990
47031
|
|
|
46991
47032
|
// src/commands/habits.ts
|
|
47033
|
+
var SCHEDULE_FLAGS = [
|
|
47034
|
+
{ name: "every-day", type: "boolean", description: "Due every day." },
|
|
47035
|
+
{
|
|
47036
|
+
name: "on",
|
|
47037
|
+
type: "string",
|
|
47038
|
+
description: "Due on these weekdays, comma-separated (mo,we,fr)."
|
|
47039
|
+
},
|
|
47040
|
+
{
|
|
47041
|
+
name: "every",
|
|
47042
|
+
type: "string",
|
|
47043
|
+
description: "Due every N days or weeks (3d, 2w), counted in calendar days from --from, never from the last check-in."
|
|
47044
|
+
},
|
|
47045
|
+
{
|
|
47046
|
+
name: "from",
|
|
47047
|
+
type: "string",
|
|
47048
|
+
description: "The day --every counts from, YYYY-MM-DD (default today)."
|
|
47049
|
+
},
|
|
47050
|
+
{
|
|
47051
|
+
name: "monthly",
|
|
47052
|
+
type: "string",
|
|
47053
|
+
description: "Due monthly on this day of the month: 1\u201331 (a 31 falls on a shorter month's last day), or last."
|
|
47054
|
+
},
|
|
47055
|
+
{ name: "data", type: "string", description: "JSON for any other field of the contract." }
|
|
47056
|
+
];
|
|
47057
|
+
var SCHEDULE_NOTES = "One of --every-day, --on mo,we,fr, --every 3d|2w [--from YYYY-MM-DD], --monthly 1|last sets its schedule; days it isn't due never break the streak. Without one, it keeps `period` + `frequencyCount` (3\xD7 a week). The reply's `nextDue` lists its next 4 due days.";
|
|
47058
|
+
function localToday() {
|
|
47059
|
+
const now = new Date;
|
|
47060
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
47061
|
+
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
|
|
47062
|
+
}
|
|
47063
|
+
function scheduleFromFlags(flags, today = localToday()) {
|
|
47064
|
+
const on = flagString(flags, "on");
|
|
47065
|
+
const every = flagString(flags, "every");
|
|
47066
|
+
const monthly = flagString(flags, "monthly");
|
|
47067
|
+
const given = [flagBool(flags, "every-day"), on, every, monthly].filter((v) => v !== undefined && v !== false);
|
|
47068
|
+
if (given.length > 1)
|
|
47069
|
+
throw usageError("pick one schedule: --every-day, --on, --every or --monthly");
|
|
47070
|
+
if (flagString(flags, "from") !== undefined && every === undefined)
|
|
47071
|
+
throw usageError("--from goes with --every");
|
|
47072
|
+
if (flagBool(flags, "every-day"))
|
|
47073
|
+
return { kind: "daily" };
|
|
47074
|
+
if (on !== undefined) {
|
|
47075
|
+
const days = on.split(",").map((d) => d.trim().toUpperCase()).filter((d) => d.length > 0);
|
|
47076
|
+
return { kind: "weekdays", days };
|
|
47077
|
+
}
|
|
47078
|
+
if (every !== undefined) {
|
|
47079
|
+
const m = /^(\d+)\s*([dw])$/i.exec(every.trim());
|
|
47080
|
+
if (!m)
|
|
47081
|
+
throw usageError("--every takes a number of days or weeks: 3d or 2w");
|
|
47082
|
+
return {
|
|
47083
|
+
kind: "every",
|
|
47084
|
+
interval: Number(m[1]),
|
|
47085
|
+
unit: m[2]?.toLowerCase() === "w" ? "week" : "day",
|
|
47086
|
+
anchor: flagString(flags, "from") ?? today
|
|
47087
|
+
};
|
|
47088
|
+
}
|
|
47089
|
+
if (monthly !== undefined) {
|
|
47090
|
+
const day = monthly.trim().toLowerCase() === "last" ? -1 : Number(monthly);
|
|
47091
|
+
if (!Number.isInteger(day))
|
|
47092
|
+
throw usageError("--monthly takes a day of the month (1\u201331) or last");
|
|
47093
|
+
return { kind: "monthly", dayOfMonth: day };
|
|
47094
|
+
}
|
|
47095
|
+
return;
|
|
47096
|
+
}
|
|
46992
47097
|
var commands20 = [
|
|
47098
|
+
{
|
|
47099
|
+
spec: {
|
|
47100
|
+
path: ["habits", "create"],
|
|
47101
|
+
summary: "Create a habit, with an optional schedule (every day, weekdays, every N, monthly).",
|
|
47102
|
+
args: [{ name: "title", required: false, description: "The habit's title." }],
|
|
47103
|
+
flags: SCHEDULE_FLAGS,
|
|
47104
|
+
scopes: [...habitOperations.create.scopes],
|
|
47105
|
+
returns: "HabitSummary",
|
|
47106
|
+
notes: `${routeOf(habitOperations.create)}. --data carries the rest of a CreateHabitInput; the id is minted and a yes/no measurement assumed when omitted. ${SCHEDULE_NOTES} e.g. \`do habits create "Water the plants" --every 3d\`.`
|
|
47107
|
+
},
|
|
47108
|
+
run: async ({ args, flags, requireClient }) => {
|
|
47109
|
+
const title = args.join(" ").trim();
|
|
47110
|
+
const schedule = scheduleFromFlags(flags);
|
|
47111
|
+
const body = parseInput(createHabitInputSchema, {
|
|
47112
|
+
id: ulid3(),
|
|
47113
|
+
measurementType: "binary",
|
|
47114
|
+
...title ? { title } : {},
|
|
47115
|
+
...readDataFlag(flags),
|
|
47116
|
+
...schedule ? { schedule } : {}
|
|
47117
|
+
});
|
|
47118
|
+
if (flagBool(flags, "dry-run")) {
|
|
47119
|
+
return {
|
|
47120
|
+
data: { dryRun: true, op: "create", entity: "habits", after: body },
|
|
47121
|
+
render: renderRecord
|
|
47122
|
+
};
|
|
47123
|
+
}
|
|
47124
|
+
return {
|
|
47125
|
+
data: await requireClient().post(pathOf(habitOperations.create), body),
|
|
47126
|
+
render: renderRecord
|
|
47127
|
+
};
|
|
47128
|
+
}
|
|
47129
|
+
},
|
|
47130
|
+
{
|
|
47131
|
+
spec: {
|
|
47132
|
+
path: ["habits", "update"],
|
|
47133
|
+
summary: "Change a habit: its schedule (--every-day, --on, --every, --monthly) or --data.",
|
|
47134
|
+
args: [{ name: "id", required: true, description: "Habit ULID." }],
|
|
47135
|
+
flags: SCHEDULE_FLAGS,
|
|
47136
|
+
scopes: [...habitOperations.update.scopes],
|
|
47137
|
+
returns: "HabitSummary",
|
|
47138
|
+
notes: `${routeOf(habitOperations.update)}. Only what you pass changes. ${SCHEDULE_NOTES}`
|
|
47139
|
+
},
|
|
47140
|
+
run: async ({ args, flags, requireClient }) => {
|
|
47141
|
+
const id = requireArg(args, 0, "habit id");
|
|
47142
|
+
const schedule = scheduleFromFlags(flags);
|
|
47143
|
+
const body = parseInput(updateHabitInputSchema, {
|
|
47144
|
+
...readDataFlag(flags),
|
|
47145
|
+
...schedule ? { schedule } : {}
|
|
47146
|
+
});
|
|
47147
|
+
if (Object.keys(body).length === 0)
|
|
47148
|
+
throw usageError("nothing to change \u2014 pass a schedule flag such as --on mo,we, or --data");
|
|
47149
|
+
const client = requireClient();
|
|
47150
|
+
if (flagBool(flags, "dry-run")) {
|
|
47151
|
+
const before = await client.get(pathOf(habitOperations.get, { id }));
|
|
47152
|
+
return {
|
|
47153
|
+
data: {
|
|
47154
|
+
dryRun: true,
|
|
47155
|
+
op: "update",
|
|
47156
|
+
entity: "habits",
|
|
47157
|
+
id,
|
|
47158
|
+
before,
|
|
47159
|
+
after: mergePreview(before, body),
|
|
47160
|
+
changes: body
|
|
47161
|
+
},
|
|
47162
|
+
render: renderRecord
|
|
47163
|
+
};
|
|
47164
|
+
}
|
|
47165
|
+
return {
|
|
47166
|
+
data: await client.patch(pathOf(habitOperations.update, { id }), body),
|
|
47167
|
+
render: renderRecord
|
|
47168
|
+
};
|
|
47169
|
+
}
|
|
47170
|
+
},
|
|
46993
47171
|
{
|
|
46994
47172
|
spec: {
|
|
46995
47173
|
path: ["habit", "log"],
|
package/package.json
CHANGED