@robbeverhelst/do 1.390.0 → 1.391.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 +391 -354
- 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.391.0";
|
|
14424
14424
|
var API_PREFIX = "/api/v1";
|
|
14425
14425
|
var DEFAULT_API_URL = "http://localhost:3001";
|
|
14426
14426
|
|
|
@@ -18260,6 +18260,7 @@ var userSettings = pgTable("user_settings", {
|
|
|
18260
18260
|
themePack: settingsThemePack("theme_pack").notNull().default("do"),
|
|
18261
18261
|
themePackScope: settingsThemePackScope("theme_pack_scope").notNull().default("section"),
|
|
18262
18262
|
ui: settingsUi("ui").notNull().default("v1"),
|
|
18263
|
+
healthTodayHints: text("health_today_hints").array().notNull().default(sql`'{supplements,sleep}'::text[]`),
|
|
18263
18264
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18264
18265
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18265
18266
|
}, (t) => [unique("user_settings_tenant_user_uniq").on(t.tenantId, t.userId)]);
|
|
@@ -23945,7 +23946,8 @@ var collectionTypeValues = [
|
|
|
23945
23946
|
"wine",
|
|
23946
23947
|
"wardrobe",
|
|
23947
23948
|
"asset",
|
|
23948
|
-
"hobby"
|
|
23949
|
+
"hobby",
|
|
23950
|
+
"console"
|
|
23949
23951
|
];
|
|
23950
23952
|
var collectionTypeSchema = _enum2(collectionTypeValues);
|
|
23951
23953
|
var collectionViewValues = ["grid", "shelf", "map"];
|
|
@@ -29311,6 +29313,271 @@ var healthCycleShares = pgTable("health_cycle_shares", {
|
|
|
29311
29313
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
29312
29314
|
}, (t) => [primaryKey({ columns: [t.tenantId, t.userId] })]);
|
|
29313
29315
|
|
|
29316
|
+
// ../../packages/schema/src/contracts/modules.ts
|
|
29317
|
+
var MODULE_KEYS = [
|
|
29318
|
+
"tasks",
|
|
29319
|
+
"habits",
|
|
29320
|
+
"routines",
|
|
29321
|
+
"challenges",
|
|
29322
|
+
"projects",
|
|
29323
|
+
"areas",
|
|
29324
|
+
"notes",
|
|
29325
|
+
"shopping",
|
|
29326
|
+
"inventory",
|
|
29327
|
+
"meals",
|
|
29328
|
+
"animals",
|
|
29329
|
+
"contacts",
|
|
29330
|
+
"sharing",
|
|
29331
|
+
"automations"
|
|
29332
|
+
];
|
|
29333
|
+
var moduleKeySchema = _enum2(MODULE_KEYS);
|
|
29334
|
+
var FEATURE_MODULES = [
|
|
29335
|
+
{
|
|
29336
|
+
key: "today",
|
|
29337
|
+
label: "Today",
|
|
29338
|
+
description: "Your daily dashboard \u2014 always on.",
|
|
29339
|
+
group: "System",
|
|
29340
|
+
defaultEnabled: true,
|
|
29341
|
+
system: true
|
|
29342
|
+
},
|
|
29343
|
+
{
|
|
29344
|
+
key: "inbox",
|
|
29345
|
+
label: "Inbox",
|
|
29346
|
+
description: "Quick capture and triage \u2014 always on.",
|
|
29347
|
+
group: "System",
|
|
29348
|
+
defaultEnabled: true,
|
|
29349
|
+
system: true
|
|
29350
|
+
},
|
|
29351
|
+
{
|
|
29352
|
+
key: "settings",
|
|
29353
|
+
label: "Settings",
|
|
29354
|
+
description: "This screen \u2014 always on.",
|
|
29355
|
+
group: "System",
|
|
29356
|
+
defaultEnabled: true,
|
|
29357
|
+
system: true
|
|
29358
|
+
},
|
|
29359
|
+
{
|
|
29360
|
+
key: "tasks",
|
|
29361
|
+
label: "Tasks",
|
|
29362
|
+
description: "To-dos, due dates, and starred focus.",
|
|
29363
|
+
group: "Track",
|
|
29364
|
+
defaultEnabled: true
|
|
29365
|
+
},
|
|
29366
|
+
{
|
|
29367
|
+
key: "habits",
|
|
29368
|
+
label: "Habits",
|
|
29369
|
+
description: "Daily routines and streaks.",
|
|
29370
|
+
group: "Track",
|
|
29371
|
+
defaultEnabled: true
|
|
29372
|
+
},
|
|
29373
|
+
{
|
|
29374
|
+
key: "routines",
|
|
29375
|
+
label: "Routines",
|
|
29376
|
+
description: "Repeatable checklists you run.",
|
|
29377
|
+
group: "Track",
|
|
29378
|
+
defaultEnabled: true
|
|
29379
|
+
},
|
|
29380
|
+
{
|
|
29381
|
+
key: "challenges",
|
|
29382
|
+
label: "Challenges",
|
|
29383
|
+
description: "Time-boxed goals and competitions.",
|
|
29384
|
+
group: "Track",
|
|
29385
|
+
defaultEnabled: false
|
|
29386
|
+
},
|
|
29387
|
+
{
|
|
29388
|
+
key: "projects",
|
|
29389
|
+
label: "Projects",
|
|
29390
|
+
description: "Multi-step work with milestones.",
|
|
29391
|
+
group: "Organize",
|
|
29392
|
+
defaultEnabled: true
|
|
29393
|
+
},
|
|
29394
|
+
{
|
|
29395
|
+
key: "areas",
|
|
29396
|
+
label: "Areas",
|
|
29397
|
+
description: "Ongoing life domains (PARA areas).",
|
|
29398
|
+
group: "Organize",
|
|
29399
|
+
defaultEnabled: true
|
|
29400
|
+
},
|
|
29401
|
+
{
|
|
29402
|
+
key: "notes",
|
|
29403
|
+
label: "Notes",
|
|
29404
|
+
description: "Quick notes and documents.",
|
|
29405
|
+
group: "Organize",
|
|
29406
|
+
defaultEnabled: true
|
|
29407
|
+
},
|
|
29408
|
+
{
|
|
29409
|
+
key: "shopping",
|
|
29410
|
+
label: "Shopping",
|
|
29411
|
+
description: "Lists and groceries.",
|
|
29412
|
+
group: "Household",
|
|
29413
|
+
defaultEnabled: true
|
|
29414
|
+
},
|
|
29415
|
+
{
|
|
29416
|
+
key: "inventory",
|
|
29417
|
+
label: "Inventory",
|
|
29418
|
+
description: "Things you own and stock.",
|
|
29419
|
+
group: "Household",
|
|
29420
|
+
defaultEnabled: true
|
|
29421
|
+
},
|
|
29422
|
+
{
|
|
29423
|
+
key: "meals",
|
|
29424
|
+
label: "Meals",
|
|
29425
|
+
description: "Recipes and meal plans.",
|
|
29426
|
+
group: "Household",
|
|
29427
|
+
defaultEnabled: false
|
|
29428
|
+
},
|
|
29429
|
+
{
|
|
29430
|
+
key: "animals",
|
|
29431
|
+
label: "Animals",
|
|
29432
|
+
description: "Pets and flocks: eggs, weights, feed and care.",
|
|
29433
|
+
group: "Household",
|
|
29434
|
+
defaultEnabled: false
|
|
29435
|
+
},
|
|
29436
|
+
{
|
|
29437
|
+
key: "contacts",
|
|
29438
|
+
label: "Contacts",
|
|
29439
|
+
description: "People and relationships.",
|
|
29440
|
+
group: "People",
|
|
29441
|
+
defaultEnabled: false
|
|
29442
|
+
},
|
|
29443
|
+
{
|
|
29444
|
+
key: "sharing",
|
|
29445
|
+
label: "Members & sharing",
|
|
29446
|
+
description: "Members, roles, per-item sharing and comments.",
|
|
29447
|
+
group: "People",
|
|
29448
|
+
defaultEnabled: false
|
|
29449
|
+
},
|
|
29450
|
+
{
|
|
29451
|
+
key: "automations",
|
|
29452
|
+
label: "Automations",
|
|
29453
|
+
description: "Trigger \u2192 condition \u2192 action rules.",
|
|
29454
|
+
group: "Manage",
|
|
29455
|
+
defaultEnabled: false
|
|
29456
|
+
}
|
|
29457
|
+
];
|
|
29458
|
+
var TOGGLEABLE_MODULES = FEATURE_MODULES.filter((m) => !m.system);
|
|
29459
|
+
function isModuleKey(value) {
|
|
29460
|
+
return MODULE_KEYS.includes(value);
|
|
29461
|
+
}
|
|
29462
|
+
function defaultEnabledModules() {
|
|
29463
|
+
return TOGGLEABLE_MODULES.filter((m) => m.defaultEnabled).map((m) => m.key);
|
|
29464
|
+
}
|
|
29465
|
+
function normalizeEnabledModules(keys) {
|
|
29466
|
+
const present = new Set(keys.filter(isModuleKey));
|
|
29467
|
+
return MODULE_KEYS.filter((key) => present.has(key));
|
|
29468
|
+
}
|
|
29469
|
+
function effectiveEnabledModules(enabled) {
|
|
29470
|
+
const known = normalizeEnabledModules(enabled ?? []);
|
|
29471
|
+
return known.length > 0 ? known : defaultEnabledModules();
|
|
29472
|
+
}
|
|
29473
|
+
function setModuleEnabled(enabled, key, on) {
|
|
29474
|
+
const next = new Set(effectiveEnabledModules(enabled));
|
|
29475
|
+
if (on)
|
|
29476
|
+
next.add(key);
|
|
29477
|
+
else
|
|
29478
|
+
next.delete(key);
|
|
29479
|
+
return MODULE_KEYS.filter((candidate) => next.has(candidate));
|
|
29480
|
+
}
|
|
29481
|
+
|
|
29482
|
+
// ../../packages/schema/src/contracts/settings.ts
|
|
29483
|
+
var clockTimeSchema = string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "a time like 22:00");
|
|
29484
|
+
var quietHoursSchema = object({
|
|
29485
|
+
from: clockTimeSchema,
|
|
29486
|
+
until: clockTimeSchema,
|
|
29487
|
+
days: array(number2().int().min(0).max(6)).max(7)
|
|
29488
|
+
});
|
|
29489
|
+
var PINNED_AREAS_MAX = 5;
|
|
29490
|
+
var PILL_PAGES = [
|
|
29491
|
+
"now",
|
|
29492
|
+
"habits",
|
|
29493
|
+
"tasks",
|
|
29494
|
+
"calendar",
|
|
29495
|
+
"areas",
|
|
29496
|
+
"house",
|
|
29497
|
+
"collection",
|
|
29498
|
+
"animals",
|
|
29499
|
+
"notes",
|
|
29500
|
+
"progress",
|
|
29501
|
+
"landed",
|
|
29502
|
+
"review",
|
|
29503
|
+
"agents",
|
|
29504
|
+
"profile",
|
|
29505
|
+
"settings",
|
|
29506
|
+
"alerts",
|
|
29507
|
+
"trash"
|
|
29508
|
+
];
|
|
29509
|
+
var pillPageSchema = _enum2(PILL_PAGES);
|
|
29510
|
+
var PILL_PAGES_MAX = 4;
|
|
29511
|
+
var CALENDAR_ZOOM_MIN = 75;
|
|
29512
|
+
var CALENDAR_ZOOM_MAX = 300;
|
|
29513
|
+
var calendarZoomSchema = number2().int().min(CALENDAR_ZOOM_MIN).max(CALENDAR_ZOOM_MAX);
|
|
29514
|
+
var settingsGlassSchema = _enum2(settingsGlass.enumValues);
|
|
29515
|
+
var themePackSchema = _enum2(settingsThemePack.enumValues);
|
|
29516
|
+
var themePackScopeSchema = _enum2(settingsThemePackScope.enumValues);
|
|
29517
|
+
var settingsUiSchema = _enum2(settingsUi.enumValues);
|
|
29518
|
+
var HEALTH_TODAY_HINTS = ["supplements", "sleep", "appointment", "episode"];
|
|
29519
|
+
var healthTodayHintSchema = _enum2(HEALTH_TODAY_HINTS);
|
|
29520
|
+
var HEALTH_TODAY_HINTS_DEFAULT = ["supplements", "sleep"];
|
|
29521
|
+
var userSettingsSchema = createSelectSchema(userSettings, {
|
|
29522
|
+
pinnedAreaIds: array(string2()).default([]),
|
|
29523
|
+
focusAreaId: string2().nullable().default(null),
|
|
29524
|
+
focusUntil: exports_coerce.date().nullable().default(null),
|
|
29525
|
+
quietHours: quietHoursSchema.nullable().default(null),
|
|
29526
|
+
notifications: record(string2(), unknown()).nullable().default(null),
|
|
29527
|
+
lifeBlockSharing: lifeBlockSharingSchema.nullable().default(null),
|
|
29528
|
+
pillPages: array(string2()).default([]).transform((ids) => ids.filter((id) => pillPageSchema.safeParse(id).success)),
|
|
29529
|
+
foodDiaryMode: boolean2().default(false),
|
|
29530
|
+
calendarZoom: number2().int().nullable().default(null),
|
|
29531
|
+
glass: settingsGlassSchema.default("liquid"),
|
|
29532
|
+
followSky: boolean2().default(true),
|
|
29533
|
+
nightUntilWake: boolean2().default(false),
|
|
29534
|
+
largerText: boolean2().default(false),
|
|
29535
|
+
reduceMotion: boolean2().default(false),
|
|
29536
|
+
showStreakNumbers: boolean2().default(true),
|
|
29537
|
+
themePack: themePackSchema.default("do"),
|
|
29538
|
+
themePackScope: themePackScopeSchema.default("section"),
|
|
29539
|
+
ui: settingsUiSchema.default("v1"),
|
|
29540
|
+
healthTodayHints: array(string2()).default([...HEALTH_TODAY_HINTS_DEFAULT]).transform((ids) => ids.filter((id) => healthTodayHintSchema.safeParse(id).success)),
|
|
29541
|
+
createdAt: exports_coerce.date(),
|
|
29542
|
+
updatedAt: exports_coerce.date()
|
|
29543
|
+
}).omit({ autoRollOverdue: true });
|
|
29544
|
+
var updateUserSettingsInputSchema = createUpdateSchema(userSettings, {
|
|
29545
|
+
displayName: string2().trim().max(80).nullish(),
|
|
29546
|
+
avatarUrl: union([string2().url().max(2048), literal("")]).nullish(),
|
|
29547
|
+
timezone: string2().min(1).optional(),
|
|
29548
|
+
locale: string2().min(1).optional(),
|
|
29549
|
+
theme: settingsThemeSchema.optional(),
|
|
29550
|
+
density: settingsDensitySchema.optional(),
|
|
29551
|
+
accent: settingsAccentSchema.optional(),
|
|
29552
|
+
sunCity: string2().trim().max(80).transform((city) => city === "" ? null : city).nullish(),
|
|
29553
|
+
backdrop: backdropIdSchema.nullish(),
|
|
29554
|
+
enabledModules: array(string2().trim().min(1)).transform(normalizeEnabledModules).optional(),
|
|
29555
|
+
pinnedAreaIds: array(ulidSchema).transform((ids) => [...new Set(ids)]).pipe(array(ulidSchema).max(PINNED_AREAS_MAX)).optional(),
|
|
29556
|
+
focusAreaId: ulidSchema.nullish(),
|
|
29557
|
+
quietHours: quietHoursSchema.nullish(),
|
|
29558
|
+
lifeBlockSharing: lifeBlockSharingSchema.nullish(),
|
|
29559
|
+
calendarZoom: calendarZoomSchema.nullish(),
|
|
29560
|
+
pillPages: array(pillPageSchema).transform((ids) => [...new Set(ids)]).pipe(array(pillPageSchema).max(PILL_PAGES_MAX)).optional(),
|
|
29561
|
+
glass: settingsGlassSchema.optional(),
|
|
29562
|
+
followSky: boolean2().optional(),
|
|
29563
|
+
nightUntilWake: boolean2().optional(),
|
|
29564
|
+
largerText: boolean2().optional(),
|
|
29565
|
+
reduceMotion: boolean2().optional(),
|
|
29566
|
+
showStreakNumbers: boolean2().optional(),
|
|
29567
|
+
themePack: themePackSchema.optional(),
|
|
29568
|
+
themePackScope: themePackScopeSchema.optional(),
|
|
29569
|
+
ui: settingsUiSchema.optional(),
|
|
29570
|
+
healthTodayHints: array(healthTodayHintSchema).transform((ids) => HEALTH_TODAY_HINTS.filter((id) => ids.includes(id))).optional()
|
|
29571
|
+
}).omit({
|
|
29572
|
+
id: true,
|
|
29573
|
+
tenantId: true,
|
|
29574
|
+
userId: true,
|
|
29575
|
+
createdAt: true,
|
|
29576
|
+
updatedAt: true,
|
|
29577
|
+
autoRollOverdue: true,
|
|
29578
|
+
focusUntil: true
|
|
29579
|
+
}).strict();
|
|
29580
|
+
|
|
29314
29581
|
// ../../packages/schema/src/contracts/health-records.ts
|
|
29315
29582
|
var BODY_REGION_VALUES = [
|
|
29316
29583
|
"head",
|
|
@@ -29587,6 +29854,14 @@ var updateHealthProfileInputSchema = object({
|
|
|
29587
29854
|
emergencyContactId: ulidSchema.nullish(),
|
|
29588
29855
|
primaryGpContactId: ulidSchema.nullish()
|
|
29589
29856
|
}).strict();
|
|
29857
|
+
var healthTodaySchema = object({
|
|
29858
|
+
hints: array(healthTodayHintSchema),
|
|
29859
|
+
on: boolean2(),
|
|
29860
|
+
supplementHabitIds: array(string2()),
|
|
29861
|
+
sleep: object({ hours: number2() }).nullable(),
|
|
29862
|
+
appointment: object({ id: string2(), title: string2(), at: exports_coerce.date() }).nullable(),
|
|
29863
|
+
episode: object({ id: string2(), title: string2(), startedAt: exports_coerce.date() }).nullable()
|
|
29864
|
+
});
|
|
29590
29865
|
var grantHealthConsentInputSchema = object({ version: literal(HEALTH_CONSENT_VERSION) }).strict();
|
|
29591
29866
|
var HEALTH_ERASE_PHRASE = "delete my health data";
|
|
29592
29867
|
var eraseHealthDataInputSchema = object({ confirm: literal(HEALTH_ERASE_PHRASE) }).strict();
|
|
@@ -37987,7 +38262,7 @@ var planningRules = pgTable("planning_rules", {
|
|
|
37987
38262
|
var PLANNING_RULE_KINDS = planningRuleKind.enumValues;
|
|
37988
38263
|
var planningRuleKindSchema = _enum2(PLANNING_RULE_KINDS);
|
|
37989
38264
|
var PLANNING_RULE_SENTENCE_MAX = 280;
|
|
37990
|
-
var
|
|
38265
|
+
var clockTimeSchema2 = string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "expected HH:MM (24 h)");
|
|
37991
38266
|
var ruleWeekdaysSchema = array(number2().int().min(1).max(7)).min(1).max(7).transform((days) => [...new Set(days)].sort((a, b) => a - b));
|
|
37992
38267
|
var phraseSchema = string2().trim().min(1).max(80);
|
|
37993
38268
|
function clockMinutes(clock) {
|
|
@@ -37998,15 +38273,15 @@ var fixedTimeRuleSchema = object({
|
|
|
37998
38273
|
kind: literal("fixed_time"),
|
|
37999
38274
|
what: phraseSchema,
|
|
38000
38275
|
days: ruleWeekdaysSchema,
|
|
38001
|
-
at:
|
|
38276
|
+
at: clockTimeSchema2,
|
|
38002
38277
|
minutes: number2().int().min(5).max(24 * 60).default(60),
|
|
38003
38278
|
lifeKind: lifeBlockKindSchema.optional()
|
|
38004
38279
|
}).strict();
|
|
38005
38280
|
var keepFreeRuleSchema = object({
|
|
38006
38281
|
kind: literal("keep_free"),
|
|
38007
38282
|
days: ruleWeekdaysSchema,
|
|
38008
|
-
from:
|
|
38009
|
-
to:
|
|
38283
|
+
from: clockTimeSchema2,
|
|
38284
|
+
to: clockTimeSchema2,
|
|
38010
38285
|
what: phraseSchema.optional()
|
|
38011
38286
|
}).strict().refine((r) => clockMinutes(r.to) > clockMinutes(r.from), {
|
|
38012
38287
|
message: "`to` comes after `from`",
|
|
@@ -40769,364 +41044,104 @@ var sensorOperations = defineOperations({
|
|
|
40769
41044
|
path: "/sensors/home-assistant",
|
|
40770
41045
|
scopes: ["places:read"],
|
|
40771
41046
|
tag: "Sensors",
|
|
40772
|
-
summary: "Get the Home Assistant link",
|
|
40773
|
-
description: "Whether the Space has linked Home Assistant (in Settings in the app; the token is never returned), the `host` it was linked at, how many entities are mapped (`links`) and `lastReadingAt`, when the newest reading from it landed.",
|
|
40774
|
-
status: 200,
|
|
40775
|
-
response: { description: "The link's status." },
|
|
40776
|
-
errors: { 403: true }
|
|
40777
|
-
},
|
|
40778
|
-
entities: {
|
|
40779
|
-
method: "get",
|
|
40780
|
-
path: "/sensors/home-assistant/entities",
|
|
40781
|
-
scopes: ["places:read"],
|
|
40782
|
-
tag: "Sensors",
|
|
40783
|
-
summary: "List Home Assistant's entities",
|
|
40784
|
-
description: "Every entity Home Assistant has, by `entityId`: its name, domain, state, unit, device class, `lastUpdated`, the reading it most likely gives on a Place and on an asset (`suggested`) and the sensor link it's mapped by, or null. 409 before Home Assistant is linked; 503 when it doesn't answer.",
|
|
40785
|
-
status: 200,
|
|
40786
|
-
response: { description: "The entities, by id." },
|
|
40787
|
-
errors: { 403: true, 409: true, 503: "Home Assistant didn't answer, or refused the token." }
|
|
40788
|
-
},
|
|
40789
|
-
sync: {
|
|
40790
|
-
method: "post",
|
|
40791
|
-
path: "/sensors/home-assistant/sync",
|
|
40792
|
-
scopes: ["places:write"],
|
|
40793
|
-
tag: "Sensors",
|
|
40794
|
-
summary: "Sync Home Assistant now",
|
|
40795
|
-
description: "Read every mapped entity's state once and append it to the datapoints ledger: on a Place as `shed.temp`, `shed.humidity`, `shed.heater`, `shed.water_pct`, `shed.door`, `shed.feed_kg` or `shed.light` (what an animal's room card and the room alarm read), on an asset as `asset.state`, `asset.power` or `asset.energy`. A state already on the ledger, or one Home Assistant can't read, is skipped. The worker does the same every five minutes. Returns `{ syncedAt, entities, written, skipped, missing, error }` (`unauthorized`, `unavailable`, `bad_response`). 409 before Home Assistant is linked.",
|
|
40796
|
-
status: 200,
|
|
40797
|
-
response: { description: "What the sync did." },
|
|
40798
|
-
errors: { 403: true, 409: true }
|
|
40799
|
-
},
|
|
40800
|
-
unifiStatus: {
|
|
40801
|
-
method: "get",
|
|
40802
|
-
path: "/sensors/unifi",
|
|
40803
|
-
scopes: ["places:read"],
|
|
40804
|
-
tag: "Sensors",
|
|
40805
|
-
summary: "Whether UniFi is linked",
|
|
40806
|
-
description: "Whether the Space has linked its UniFi controller (in the app's Settings \u2192 Home), the host and site it was linked at, how many devices are mapped to an asset, and when the newest presence reading landed. Never the API key: a key can't link or unlink UniFi.",
|
|
40807
|
-
status: 200,
|
|
40808
|
-
response: { description: "The status." },
|
|
40809
|
-
errors: { 403: true }
|
|
40810
|
-
},
|
|
40811
|
-
unifiDevices: {
|
|
40812
|
-
method: "get",
|
|
40813
|
-
path: "/sensors/unifi/devices",
|
|
40814
|
-
scopes: ["places:read", "collections:read"],
|
|
40815
|
-
tag: "Sensors",
|
|
40816
|
-
summary: "The devices UniFi sees",
|
|
40817
|
-
description: "Every device the controller manages (gateway, switches, access points, cameras) and every client connected now: `mac`, `name`, `kind` (`device` | `client`), `model`, `online`, `firmware`, and the sensor `link` to the asset it's mapped to (behind the nodes wall). Network details. 409 before UniFi is linked; 503 when the controller can't be read.",
|
|
40818
|
-
status: 200,
|
|
40819
|
-
response: { description: "The devices." },
|
|
40820
|
-
errors: { 403: true, 409: true }
|
|
40821
|
-
},
|
|
40822
|
-
syncUnifi: {
|
|
40823
|
-
method: "post",
|
|
40824
|
-
path: "/sensors/unifi/sync",
|
|
40825
|
-
scopes: ["places:write"],
|
|
40826
|
-
tag: "Sensors",
|
|
40827
|
-
summary: "Sync UniFi now",
|
|
40828
|
-
description: "Map every asset whose facet names a UniFi MAC (`external.unifiMac`), ask the controller once, and put each mapped device's presence on its asset as `asset.presence` (1 online, 0 offline, with its firmware): what the asset page's Live card reads. A reading lands when the presence or firmware changes, else hourly; a device the controller doesn't list reads offline and is named in `missing`. The worker does the same every five minutes. 409 before UniFi is linked.",
|
|
40829
|
-
status: 200,
|
|
40830
|
-
response: { description: "What the sync did." },
|
|
40831
|
-
errors: { 403: true, 409: true }
|
|
40832
|
-
},
|
|
40833
|
-
links: {
|
|
40834
|
-
method: "get",
|
|
40835
|
-
path: "/sensors/links",
|
|
40836
|
-
scopes: ["places:read"],
|
|
40837
|
-
tag: "Sensors",
|
|
40838
|
-
summary: "List the mapped entities",
|
|
40839
|
-
description: "Every mapped entity, or only the ones on `nodeId`, with the name of what it lands on (`nodeTitle`). A mapping on an asset kept Not shared is its member's alone.",
|
|
40840
|
-
query: [{ name: "nodeId", description: "Only the mappings on this Place or asset." }],
|
|
40841
|
-
querySchema: sensorLinksQuerySchema,
|
|
40842
|
-
status: 200,
|
|
40843
|
-
response: { description: "The mappings, by entity id." },
|
|
40844
|
-
errors: { 400: true }
|
|
40845
|
-
},
|
|
40846
|
-
createLink: {
|
|
40847
|
-
method: "post",
|
|
40848
|
-
path: "/sensors/links",
|
|
40849
|
-
scopes: ["places:write"],
|
|
40850
|
-
tag: "Sensors",
|
|
40851
|
-
summary: "Map an entity",
|
|
40852
|
-
description: "Map a Home Assistant entity (`externalId`) to a Place, an asset, or an animal (its room: the Place it's housed in) as a `reading`: a Place takes `temp`, `humidity`, `heater`, `water`, `door`, `feeder` or `light`; an asset `state`, `power` or `energy`. Mapping an entity that's already mapped moves it. 400 when the reading doesn't fit; 404 for no such node; 409 for an animal with no room.",
|
|
40853
|
-
body: createSensorLinkInputSchema,
|
|
40854
|
-
status: 201,
|
|
40855
|
-
response: { description: "The mapping." },
|
|
40856
|
-
errors: { 400: true, 404: true, 409: true }
|
|
40857
|
-
},
|
|
40858
|
-
removeLink: {
|
|
40859
|
-
method: "delete",
|
|
40860
|
-
path: "/sensors/links/{id}",
|
|
40861
|
-
scopes: ["places:write"],
|
|
40862
|
-
tag: "Sensors",
|
|
40863
|
-
summary: "Unmap an entity",
|
|
40864
|
-
description: "Remove one mapping; the readings it gave stay on the ledger.",
|
|
40865
|
-
status: 204,
|
|
40866
|
-
response: { description: "Removed." },
|
|
40867
|
-
errors: { 404: true }
|
|
40868
|
-
}
|
|
40869
|
-
});
|
|
40870
|
-
|
|
40871
|
-
// ../../packages/schema/src/contracts/modules.ts
|
|
40872
|
-
var MODULE_KEYS = [
|
|
40873
|
-
"tasks",
|
|
40874
|
-
"habits",
|
|
40875
|
-
"routines",
|
|
40876
|
-
"challenges",
|
|
40877
|
-
"projects",
|
|
40878
|
-
"areas",
|
|
40879
|
-
"notes",
|
|
40880
|
-
"shopping",
|
|
40881
|
-
"inventory",
|
|
40882
|
-
"meals",
|
|
40883
|
-
"animals",
|
|
40884
|
-
"contacts",
|
|
40885
|
-
"sharing",
|
|
40886
|
-
"automations"
|
|
40887
|
-
];
|
|
40888
|
-
var moduleKeySchema = _enum2(MODULE_KEYS);
|
|
40889
|
-
var FEATURE_MODULES = [
|
|
40890
|
-
{
|
|
40891
|
-
key: "today",
|
|
40892
|
-
label: "Today",
|
|
40893
|
-
description: "Your daily dashboard \u2014 always on.",
|
|
40894
|
-
group: "System",
|
|
40895
|
-
defaultEnabled: true,
|
|
40896
|
-
system: true
|
|
40897
|
-
},
|
|
40898
|
-
{
|
|
40899
|
-
key: "inbox",
|
|
40900
|
-
label: "Inbox",
|
|
40901
|
-
description: "Quick capture and triage \u2014 always on.",
|
|
40902
|
-
group: "System",
|
|
40903
|
-
defaultEnabled: true,
|
|
40904
|
-
system: true
|
|
40905
|
-
},
|
|
40906
|
-
{
|
|
40907
|
-
key: "settings",
|
|
40908
|
-
label: "Settings",
|
|
40909
|
-
description: "This screen \u2014 always on.",
|
|
40910
|
-
group: "System",
|
|
40911
|
-
defaultEnabled: true,
|
|
40912
|
-
system: true
|
|
40913
|
-
},
|
|
40914
|
-
{
|
|
40915
|
-
key: "tasks",
|
|
40916
|
-
label: "Tasks",
|
|
40917
|
-
description: "To-dos, due dates, and starred focus.",
|
|
40918
|
-
group: "Track",
|
|
40919
|
-
defaultEnabled: true
|
|
40920
|
-
},
|
|
40921
|
-
{
|
|
40922
|
-
key: "habits",
|
|
40923
|
-
label: "Habits",
|
|
40924
|
-
description: "Daily routines and streaks.",
|
|
40925
|
-
group: "Track",
|
|
40926
|
-
defaultEnabled: true
|
|
40927
|
-
},
|
|
40928
|
-
{
|
|
40929
|
-
key: "routines",
|
|
40930
|
-
label: "Routines",
|
|
40931
|
-
description: "Repeatable checklists you run.",
|
|
40932
|
-
group: "Track",
|
|
40933
|
-
defaultEnabled: true
|
|
40934
|
-
},
|
|
40935
|
-
{
|
|
40936
|
-
key: "challenges",
|
|
40937
|
-
label: "Challenges",
|
|
40938
|
-
description: "Time-boxed goals and competitions.",
|
|
40939
|
-
group: "Track",
|
|
40940
|
-
defaultEnabled: false
|
|
40941
|
-
},
|
|
40942
|
-
{
|
|
40943
|
-
key: "projects",
|
|
40944
|
-
label: "Projects",
|
|
40945
|
-
description: "Multi-step work with milestones.",
|
|
40946
|
-
group: "Organize",
|
|
40947
|
-
defaultEnabled: true
|
|
40948
|
-
},
|
|
40949
|
-
{
|
|
40950
|
-
key: "areas",
|
|
40951
|
-
label: "Areas",
|
|
40952
|
-
description: "Ongoing life domains (PARA areas).",
|
|
40953
|
-
group: "Organize",
|
|
40954
|
-
defaultEnabled: true
|
|
41047
|
+
summary: "Get the Home Assistant link",
|
|
41048
|
+
description: "Whether the Space has linked Home Assistant (in Settings in the app; the token is never returned), the `host` it was linked at, how many entities are mapped (`links`) and `lastReadingAt`, when the newest reading from it landed.",
|
|
41049
|
+
status: 200,
|
|
41050
|
+
response: { description: "The link's status." },
|
|
41051
|
+
errors: { 403: true }
|
|
40955
41052
|
},
|
|
40956
|
-
{
|
|
40957
|
-
|
|
40958
|
-
|
|
40959
|
-
|
|
40960
|
-
|
|
40961
|
-
|
|
41053
|
+
entities: {
|
|
41054
|
+
method: "get",
|
|
41055
|
+
path: "/sensors/home-assistant/entities",
|
|
41056
|
+
scopes: ["places:read"],
|
|
41057
|
+
tag: "Sensors",
|
|
41058
|
+
summary: "List Home Assistant's entities",
|
|
41059
|
+
description: "Every entity Home Assistant has, by `entityId`: its name, domain, state, unit, device class, `lastUpdated`, the reading it most likely gives on a Place and on an asset (`suggested`) and the sensor link it's mapped by, or null. 409 before Home Assistant is linked; 503 when it doesn't answer.",
|
|
41060
|
+
status: 200,
|
|
41061
|
+
response: { description: "The entities, by id." },
|
|
41062
|
+
errors: { 403: true, 409: true, 503: "Home Assistant didn't answer, or refused the token." }
|
|
40962
41063
|
},
|
|
40963
|
-
{
|
|
40964
|
-
|
|
40965
|
-
|
|
40966
|
-
|
|
40967
|
-
|
|
40968
|
-
|
|
41064
|
+
sync: {
|
|
41065
|
+
method: "post",
|
|
41066
|
+
path: "/sensors/home-assistant/sync",
|
|
41067
|
+
scopes: ["places:write"],
|
|
41068
|
+
tag: "Sensors",
|
|
41069
|
+
summary: "Sync Home Assistant now",
|
|
41070
|
+
description: "Read every mapped entity's state once and append it to the datapoints ledger: on a Place as `shed.temp`, `shed.humidity`, `shed.heater`, `shed.water_pct`, `shed.door`, `shed.feed_kg` or `shed.light` (what an animal's room card and the room alarm read), on an asset as `asset.state`, `asset.power` or `asset.energy`. A state already on the ledger, or one Home Assistant can't read, is skipped. The worker does the same every five minutes. Returns `{ syncedAt, entities, written, skipped, missing, error }` (`unauthorized`, `unavailable`, `bad_response`). 409 before Home Assistant is linked.",
|
|
41071
|
+
status: 200,
|
|
41072
|
+
response: { description: "What the sync did." },
|
|
41073
|
+
errors: { 403: true, 409: true }
|
|
40969
41074
|
},
|
|
40970
|
-
{
|
|
40971
|
-
|
|
40972
|
-
|
|
40973
|
-
|
|
40974
|
-
|
|
40975
|
-
|
|
41075
|
+
unifiStatus: {
|
|
41076
|
+
method: "get",
|
|
41077
|
+
path: "/sensors/unifi",
|
|
41078
|
+
scopes: ["places:read"],
|
|
41079
|
+
tag: "Sensors",
|
|
41080
|
+
summary: "Whether UniFi is linked",
|
|
41081
|
+
description: "Whether the Space has linked its UniFi controller (in the app's Settings \u2192 Home), the host and site it was linked at, how many devices are mapped to an asset, and when the newest presence reading landed. Never the API key: a key can't link or unlink UniFi.",
|
|
41082
|
+
status: 200,
|
|
41083
|
+
response: { description: "The status." },
|
|
41084
|
+
errors: { 403: true }
|
|
40976
41085
|
},
|
|
40977
|
-
{
|
|
40978
|
-
|
|
40979
|
-
|
|
40980
|
-
|
|
40981
|
-
|
|
40982
|
-
|
|
41086
|
+
unifiDevices: {
|
|
41087
|
+
method: "get",
|
|
41088
|
+
path: "/sensors/unifi/devices",
|
|
41089
|
+
scopes: ["places:read", "collections:read"],
|
|
41090
|
+
tag: "Sensors",
|
|
41091
|
+
summary: "The devices UniFi sees",
|
|
41092
|
+
description: "Every device the controller manages (gateway, switches, access points, cameras) and every client connected now: `mac`, `name`, `kind` (`device` | `client`), `model`, `online`, `firmware`, and the sensor `link` to the asset it's mapped to (behind the nodes wall). Network details. 409 before UniFi is linked; 503 when the controller can't be read.",
|
|
41093
|
+
status: 200,
|
|
41094
|
+
response: { description: "The devices." },
|
|
41095
|
+
errors: { 403: true, 409: true }
|
|
40983
41096
|
},
|
|
40984
|
-
{
|
|
40985
|
-
|
|
40986
|
-
|
|
40987
|
-
|
|
40988
|
-
|
|
40989
|
-
|
|
41097
|
+
syncUnifi: {
|
|
41098
|
+
method: "post",
|
|
41099
|
+
path: "/sensors/unifi/sync",
|
|
41100
|
+
scopes: ["places:write"],
|
|
41101
|
+
tag: "Sensors",
|
|
41102
|
+
summary: "Sync UniFi now",
|
|
41103
|
+
description: "Map every asset whose facet names a UniFi MAC (`external.unifiMac`), ask the controller once, and put each mapped device's presence on its asset as `asset.presence` (1 online, 0 offline, with its firmware): what the asset page's Live card reads. A reading lands when the presence or firmware changes, else hourly; a device the controller doesn't list reads offline and is named in `missing`. The worker does the same every five minutes. 409 before UniFi is linked.",
|
|
41104
|
+
status: 200,
|
|
41105
|
+
response: { description: "What the sync did." },
|
|
41106
|
+
errors: { 403: true, 409: true }
|
|
40990
41107
|
},
|
|
40991
|
-
{
|
|
40992
|
-
|
|
40993
|
-
|
|
40994
|
-
|
|
40995
|
-
|
|
40996
|
-
|
|
41108
|
+
links: {
|
|
41109
|
+
method: "get",
|
|
41110
|
+
path: "/sensors/links",
|
|
41111
|
+
scopes: ["places:read"],
|
|
41112
|
+
tag: "Sensors",
|
|
41113
|
+
summary: "List the mapped entities",
|
|
41114
|
+
description: "Every mapped entity, or only the ones on `nodeId`, with the name of what it lands on (`nodeTitle`). A mapping on an asset kept Not shared is its member's alone.",
|
|
41115
|
+
query: [{ name: "nodeId", description: "Only the mappings on this Place or asset." }],
|
|
41116
|
+
querySchema: sensorLinksQuerySchema,
|
|
41117
|
+
status: 200,
|
|
41118
|
+
response: { description: "The mappings, by entity id." },
|
|
41119
|
+
errors: { 400: true }
|
|
40997
41120
|
},
|
|
40998
|
-
{
|
|
40999
|
-
|
|
41000
|
-
|
|
41001
|
-
|
|
41002
|
-
|
|
41003
|
-
|
|
41121
|
+
createLink: {
|
|
41122
|
+
method: "post",
|
|
41123
|
+
path: "/sensors/links",
|
|
41124
|
+
scopes: ["places:write"],
|
|
41125
|
+
tag: "Sensors",
|
|
41126
|
+
summary: "Map an entity",
|
|
41127
|
+
description: "Map a Home Assistant entity (`externalId`) to a Place, an asset, or an animal (its room: the Place it's housed in) as a `reading`: a Place takes `temp`, `humidity`, `heater`, `water`, `door`, `feeder` or `light`; an asset `state`, `power` or `energy`. Mapping an entity that's already mapped moves it. 400 when the reading doesn't fit; 404 for no such node; 409 for an animal with no room.",
|
|
41128
|
+
body: createSensorLinkInputSchema,
|
|
41129
|
+
status: 201,
|
|
41130
|
+
response: { description: "The mapping." },
|
|
41131
|
+
errors: { 400: true, 404: true, 409: true }
|
|
41004
41132
|
},
|
|
41005
|
-
{
|
|
41006
|
-
|
|
41007
|
-
|
|
41008
|
-
|
|
41009
|
-
|
|
41010
|
-
|
|
41133
|
+
removeLink: {
|
|
41134
|
+
method: "delete",
|
|
41135
|
+
path: "/sensors/links/{id}",
|
|
41136
|
+
scopes: ["places:write"],
|
|
41137
|
+
tag: "Sensors",
|
|
41138
|
+
summary: "Unmap an entity",
|
|
41139
|
+
description: "Remove one mapping; the readings it gave stay on the ledger.",
|
|
41140
|
+
status: 204,
|
|
41141
|
+
response: { description: "Removed." },
|
|
41142
|
+
errors: { 404: true }
|
|
41011
41143
|
}
|
|
41012
|
-
];
|
|
41013
|
-
var TOGGLEABLE_MODULES = FEATURE_MODULES.filter((m) => !m.system);
|
|
41014
|
-
function isModuleKey(value) {
|
|
41015
|
-
return MODULE_KEYS.includes(value);
|
|
41016
|
-
}
|
|
41017
|
-
function defaultEnabledModules() {
|
|
41018
|
-
return TOGGLEABLE_MODULES.filter((m) => m.defaultEnabled).map((m) => m.key);
|
|
41019
|
-
}
|
|
41020
|
-
function normalizeEnabledModules(keys) {
|
|
41021
|
-
const present = new Set(keys.filter(isModuleKey));
|
|
41022
|
-
return MODULE_KEYS.filter((key) => present.has(key));
|
|
41023
|
-
}
|
|
41024
|
-
function effectiveEnabledModules(enabled) {
|
|
41025
|
-
const known = normalizeEnabledModules(enabled ?? []);
|
|
41026
|
-
return known.length > 0 ? known : defaultEnabledModules();
|
|
41027
|
-
}
|
|
41028
|
-
function setModuleEnabled(enabled, key, on) {
|
|
41029
|
-
const next = new Set(effectiveEnabledModules(enabled));
|
|
41030
|
-
if (on)
|
|
41031
|
-
next.add(key);
|
|
41032
|
-
else
|
|
41033
|
-
next.delete(key);
|
|
41034
|
-
return MODULE_KEYS.filter((candidate) => next.has(candidate));
|
|
41035
|
-
}
|
|
41036
|
-
|
|
41037
|
-
// ../../packages/schema/src/contracts/settings.ts
|
|
41038
|
-
var clockTimeSchema2 = string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "a time like 22:00");
|
|
41039
|
-
var quietHoursSchema = object({
|
|
41040
|
-
from: clockTimeSchema2,
|
|
41041
|
-
until: clockTimeSchema2,
|
|
41042
|
-
days: array(number2().int().min(0).max(6)).max(7)
|
|
41043
41144
|
});
|
|
41044
|
-
var PINNED_AREAS_MAX = 5;
|
|
41045
|
-
var PILL_PAGES = [
|
|
41046
|
-
"now",
|
|
41047
|
-
"habits",
|
|
41048
|
-
"tasks",
|
|
41049
|
-
"calendar",
|
|
41050
|
-
"areas",
|
|
41051
|
-
"house",
|
|
41052
|
-
"collection",
|
|
41053
|
-
"animals",
|
|
41054
|
-
"notes",
|
|
41055
|
-
"progress",
|
|
41056
|
-
"landed",
|
|
41057
|
-
"review",
|
|
41058
|
-
"agents",
|
|
41059
|
-
"profile",
|
|
41060
|
-
"settings",
|
|
41061
|
-
"alerts",
|
|
41062
|
-
"trash"
|
|
41063
|
-
];
|
|
41064
|
-
var pillPageSchema = _enum2(PILL_PAGES);
|
|
41065
|
-
var PILL_PAGES_MAX = 4;
|
|
41066
|
-
var CALENDAR_ZOOM_MIN = 75;
|
|
41067
|
-
var CALENDAR_ZOOM_MAX = 300;
|
|
41068
|
-
var calendarZoomSchema = number2().int().min(CALENDAR_ZOOM_MIN).max(CALENDAR_ZOOM_MAX);
|
|
41069
|
-
var settingsGlassSchema = _enum2(settingsGlass.enumValues);
|
|
41070
|
-
var themePackSchema = _enum2(settingsThemePack.enumValues);
|
|
41071
|
-
var themePackScopeSchema = _enum2(settingsThemePackScope.enumValues);
|
|
41072
|
-
var settingsUiSchema = _enum2(settingsUi.enumValues);
|
|
41073
|
-
var userSettingsSchema = createSelectSchema(userSettings, {
|
|
41074
|
-
pinnedAreaIds: array(string2()).default([]),
|
|
41075
|
-
focusAreaId: string2().nullable().default(null),
|
|
41076
|
-
focusUntil: exports_coerce.date().nullable().default(null),
|
|
41077
|
-
quietHours: quietHoursSchema.nullable().default(null),
|
|
41078
|
-
notifications: record(string2(), unknown()).nullable().default(null),
|
|
41079
|
-
lifeBlockSharing: lifeBlockSharingSchema.nullable().default(null),
|
|
41080
|
-
pillPages: array(string2()).default([]).transform((ids) => ids.filter((id) => pillPageSchema.safeParse(id).success)),
|
|
41081
|
-
foodDiaryMode: boolean2().default(false),
|
|
41082
|
-
calendarZoom: number2().int().nullable().default(null),
|
|
41083
|
-
glass: settingsGlassSchema.default("liquid"),
|
|
41084
|
-
followSky: boolean2().default(true),
|
|
41085
|
-
nightUntilWake: boolean2().default(false),
|
|
41086
|
-
largerText: boolean2().default(false),
|
|
41087
|
-
reduceMotion: boolean2().default(false),
|
|
41088
|
-
showStreakNumbers: boolean2().default(true),
|
|
41089
|
-
themePack: themePackSchema.default("do"),
|
|
41090
|
-
themePackScope: themePackScopeSchema.default("section"),
|
|
41091
|
-
ui: settingsUiSchema.default("v1"),
|
|
41092
|
-
createdAt: exports_coerce.date(),
|
|
41093
|
-
updatedAt: exports_coerce.date()
|
|
41094
|
-
}).omit({ autoRollOverdue: true });
|
|
41095
|
-
var updateUserSettingsInputSchema = createUpdateSchema(userSettings, {
|
|
41096
|
-
displayName: string2().trim().max(80).nullish(),
|
|
41097
|
-
avatarUrl: union([string2().url().max(2048), literal("")]).nullish(),
|
|
41098
|
-
timezone: string2().min(1).optional(),
|
|
41099
|
-
locale: string2().min(1).optional(),
|
|
41100
|
-
theme: settingsThemeSchema.optional(),
|
|
41101
|
-
density: settingsDensitySchema.optional(),
|
|
41102
|
-
accent: settingsAccentSchema.optional(),
|
|
41103
|
-
sunCity: string2().trim().max(80).transform((city) => city === "" ? null : city).nullish(),
|
|
41104
|
-
backdrop: backdropIdSchema.nullish(),
|
|
41105
|
-
enabledModules: array(string2().trim().min(1)).transform(normalizeEnabledModules).optional(),
|
|
41106
|
-
pinnedAreaIds: array(ulidSchema).transform((ids) => [...new Set(ids)]).pipe(array(ulidSchema).max(PINNED_AREAS_MAX)).optional(),
|
|
41107
|
-
focusAreaId: ulidSchema.nullish(),
|
|
41108
|
-
quietHours: quietHoursSchema.nullish(),
|
|
41109
|
-
lifeBlockSharing: lifeBlockSharingSchema.nullish(),
|
|
41110
|
-
calendarZoom: calendarZoomSchema.nullish(),
|
|
41111
|
-
pillPages: array(pillPageSchema).transform((ids) => [...new Set(ids)]).pipe(array(pillPageSchema).max(PILL_PAGES_MAX)).optional(),
|
|
41112
|
-
glass: settingsGlassSchema.optional(),
|
|
41113
|
-
followSky: boolean2().optional(),
|
|
41114
|
-
nightUntilWake: boolean2().optional(),
|
|
41115
|
-
largerText: boolean2().optional(),
|
|
41116
|
-
reduceMotion: boolean2().optional(),
|
|
41117
|
-
showStreakNumbers: boolean2().optional(),
|
|
41118
|
-
themePack: themePackSchema.optional(),
|
|
41119
|
-
themePackScope: themePackScopeSchema.optional(),
|
|
41120
|
-
ui: settingsUiSchema.optional()
|
|
41121
|
-
}).omit({
|
|
41122
|
-
id: true,
|
|
41123
|
-
tenantId: true,
|
|
41124
|
-
userId: true,
|
|
41125
|
-
createdAt: true,
|
|
41126
|
-
updatedAt: true,
|
|
41127
|
-
autoRollOverdue: true,
|
|
41128
|
-
focusUntil: true
|
|
41129
|
-
}).strict();
|
|
41130
41145
|
|
|
41131
41146
|
// ../../packages/schema/src/operations/settings.ts
|
|
41132
41147
|
var settingsOperations = defineOperations({
|
|
@@ -43246,6 +43261,18 @@ var hobbyFacetSchema = object({
|
|
|
43246
43261
|
with: string2().min(1).max(80).nullish(),
|
|
43247
43262
|
coverUrl
|
|
43248
43263
|
}).strict();
|
|
43264
|
+
var consoleFacetSchema = object({
|
|
43265
|
+
model: string2().min(1).max(120).nullish(),
|
|
43266
|
+
region: string2().min(1).max(40).nullish(),
|
|
43267
|
+
condition: string2().min(1).max(80).nullish(),
|
|
43268
|
+
boxed: boolean2().nullish(),
|
|
43269
|
+
extras: string2().min(1).max(200).nullish(),
|
|
43270
|
+
year: number2().int().min(1950).max(2100).nullish(),
|
|
43271
|
+
works: boolean2().nullish(),
|
|
43272
|
+
fixNote: string2().min(1).max(200).nullish(),
|
|
43273
|
+
plays: array(string2().trim().min(1).max(40)).max(12).nullish(),
|
|
43274
|
+
coverUrl
|
|
43275
|
+
}).strict();
|
|
43249
43276
|
var placeFacetSchema = object({
|
|
43250
43277
|
address: string2().min(1).max(400).nullish(),
|
|
43251
43278
|
lat: number2().min(-90).max(90).nullish(),
|
|
@@ -43482,6 +43509,16 @@ var COLLECTION_TYPES = {
|
|
|
43482
43509
|
facetSchema: hobbyFacetSchema,
|
|
43483
43510
|
view: "grid",
|
|
43484
43511
|
subtitleKey: "kind"
|
|
43512
|
+
},
|
|
43513
|
+
console: {
|
|
43514
|
+
key: "console",
|
|
43515
|
+
label: "Consoles",
|
|
43516
|
+
itemNoun: "console",
|
|
43517
|
+
statuses: ["want", "doing", "have", "done"],
|
|
43518
|
+
statusLabels: { want: "Wanted", doing: "Hooked up", have: "In the cupboard", done: "Retired" },
|
|
43519
|
+
facetSchema: consoleFacetSchema,
|
|
43520
|
+
view: "grid",
|
|
43521
|
+
subtitleKey: "model"
|
|
43485
43522
|
}
|
|
43486
43523
|
};
|
|
43487
43524
|
var COLLECTION_TYPE_LIST = collectionTypeValues.map((k) => COLLECTION_TYPES[k]);
|
package/package.json
CHANGED