@robbeverhelst/do 1.390.0 → 1.392.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 +716 -345
- 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.392.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)]);
|
|
@@ -23932,6 +23933,24 @@ var collectionSavedViews = pgTable("collection_saved_views", {
|
|
|
23932
23933
|
}, (t) => [
|
|
23933
23934
|
index("collection_saved_views_tenant_idx").on(t.tenantId)
|
|
23934
23935
|
]);
|
|
23936
|
+
var collectionKinds = pgTable("collection_kinds", {
|
|
23937
|
+
id: text("id").primaryKey(),
|
|
23938
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
23939
|
+
key: text("key").notNull(),
|
|
23940
|
+
name: text("name").notNull(),
|
|
23941
|
+
one: text("one").notNull(),
|
|
23942
|
+
many: text("many").notNull(),
|
|
23943
|
+
icon: text("icon").notNull().default("tag"),
|
|
23944
|
+
preset: text("preset"),
|
|
23945
|
+
fields: jsonb("fields").$type().notNull().default([]),
|
|
23946
|
+
statusWords: jsonb("status_words").$type().notNull(),
|
|
23947
|
+
view: text("view").notNull().default("grid"),
|
|
23948
|
+
createdByUserId: text("created_by_user_id").references(() => users.id, {
|
|
23949
|
+
onDelete: "set null"
|
|
23950
|
+
}),
|
|
23951
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
23952
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
23953
|
+
}, (t) => [unique("collection_kinds_tenant_key_uniq").on(t.tenantId, t.key)]);
|
|
23935
23954
|
|
|
23936
23955
|
// ../../packages/schema/src/contracts/collection-values.ts
|
|
23937
23956
|
var collectionStatusValues = ["want", "have", "doing", "done", "dropped", "gone"];
|
|
@@ -23945,7 +23964,8 @@ var collectionTypeValues = [
|
|
|
23945
23964
|
"wine",
|
|
23946
23965
|
"wardrobe",
|
|
23947
23966
|
"asset",
|
|
23948
|
-
"hobby"
|
|
23967
|
+
"hobby",
|
|
23968
|
+
"console"
|
|
23949
23969
|
];
|
|
23950
23970
|
var collectionTypeSchema = _enum2(collectionTypeValues);
|
|
23951
23971
|
var collectionViewValues = ["grid", "shelf", "map"];
|
|
@@ -26137,6 +26157,162 @@ var circleOperations = defineOperations({
|
|
|
26137
26157
|
})
|
|
26138
26158
|
});
|
|
26139
26159
|
|
|
26160
|
+
// ../../packages/schema/src/contracts/collection-kinds.ts
|
|
26161
|
+
var collectionKindFieldTypeValues = [
|
|
26162
|
+
"text",
|
|
26163
|
+
"number",
|
|
26164
|
+
"choice",
|
|
26165
|
+
"year",
|
|
26166
|
+
"date",
|
|
26167
|
+
"yesno"
|
|
26168
|
+
];
|
|
26169
|
+
var collectionKindFieldTypeSchema = _enum2(collectionKindFieldTypeValues);
|
|
26170
|
+
var collectionKindIconValues = [
|
|
26171
|
+
"disc",
|
|
26172
|
+
"dice",
|
|
26173
|
+
"brick",
|
|
26174
|
+
"book",
|
|
26175
|
+
"pad",
|
|
26176
|
+
"sprout",
|
|
26177
|
+
"paw",
|
|
26178
|
+
"tag"
|
|
26179
|
+
];
|
|
26180
|
+
var collectionKindIconSchema = _enum2(collectionKindIconValues);
|
|
26181
|
+
var collectionKindPresetValues = ["lego", "vinyl", "board", "custom"];
|
|
26182
|
+
var collectionKindPresetSchema = _enum2(collectionKindPresetValues);
|
|
26183
|
+
var slug = string2().min(1).max(40).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "lowercase letters and digits, dashes between");
|
|
26184
|
+
var collectionKindKeySchema = slug.refine((k) => !collectionTypeValues.includes(k), "that's a built-in kind");
|
|
26185
|
+
var collectionKindFieldSchema = object({
|
|
26186
|
+
key: slug,
|
|
26187
|
+
label: string2().trim().min(1).max(40),
|
|
26188
|
+
type: collectionKindFieldTypeSchema,
|
|
26189
|
+
choices: array(string2().trim().min(1).max(40)).max(30).optional()
|
|
26190
|
+
}).strict().refine((f) => f.type === "choice" || f.choices === undefined, {
|
|
26191
|
+
message: "only a choice field has choices",
|
|
26192
|
+
path: ["choices"]
|
|
26193
|
+
});
|
|
26194
|
+
var collectionKindFieldsSchema = array(collectionKindFieldSchema).max(12).refine((fs) => new Set(fs.map((f) => f.key)).size === fs.length, "each field key once");
|
|
26195
|
+
var word = string2().trim().min(1).max(30);
|
|
26196
|
+
var collectionKindStatusWordsSchema = object({ want: word, have: word, doing: word, done: word, dropped: word }).strict();
|
|
26197
|
+
var collectionKindSchema = object({
|
|
26198
|
+
id: ulidSchema,
|
|
26199
|
+
key: string2(),
|
|
26200
|
+
name: string2(),
|
|
26201
|
+
one: string2(),
|
|
26202
|
+
many: string2(),
|
|
26203
|
+
icon: string2(),
|
|
26204
|
+
preset: string2().nullable(),
|
|
26205
|
+
fields: array(object({
|
|
26206
|
+
key: string2(),
|
|
26207
|
+
label: string2(),
|
|
26208
|
+
type: string2(),
|
|
26209
|
+
choices: array(string2()).optional()
|
|
26210
|
+
})),
|
|
26211
|
+
statusWords: collectionKindStatusWordsSchema,
|
|
26212
|
+
view: string2(),
|
|
26213
|
+
itemCount: number2().int(),
|
|
26214
|
+
createdAt: exports_coerce.date(),
|
|
26215
|
+
updatedAt: exports_coerce.date()
|
|
26216
|
+
});
|
|
26217
|
+
var name2 = string2().trim().min(1).max(40);
|
|
26218
|
+
var createCollectionKindInputSchema = object({
|
|
26219
|
+
id: ulidSchema,
|
|
26220
|
+
name: name2,
|
|
26221
|
+
key: collectionKindKeySchema.optional(),
|
|
26222
|
+
one: name2.optional(),
|
|
26223
|
+
many: name2.optional(),
|
|
26224
|
+
icon: collectionKindIconSchema.optional(),
|
|
26225
|
+
preset: collectionKindPresetSchema.optional(),
|
|
26226
|
+
fields: collectionKindFieldsSchema.optional(),
|
|
26227
|
+
statusWords: collectionKindStatusWordsSchema.optional()
|
|
26228
|
+
}).strict();
|
|
26229
|
+
var updateCollectionKindInputSchema = object({
|
|
26230
|
+
name: name2.optional(),
|
|
26231
|
+
one: name2.optional(),
|
|
26232
|
+
many: name2.optional(),
|
|
26233
|
+
icon: collectionKindIconSchema.optional(),
|
|
26234
|
+
fields: collectionKindFieldsSchema.optional(),
|
|
26235
|
+
statusWords: collectionKindStatusWordsSchema.optional()
|
|
26236
|
+
}).strict();
|
|
26237
|
+
var f = (label, type) => ({
|
|
26238
|
+
key: kindSlug(label),
|
|
26239
|
+
label,
|
|
26240
|
+
type
|
|
26241
|
+
});
|
|
26242
|
+
var COLLECTION_KIND_PRESETS = {
|
|
26243
|
+
lego: {
|
|
26244
|
+
name: "LEGO",
|
|
26245
|
+
one: "set",
|
|
26246
|
+
icon: "brick",
|
|
26247
|
+
fields: [
|
|
26248
|
+
f("Set number", "text"),
|
|
26249
|
+
f("Pieces", "number"),
|
|
26250
|
+
f("Theme", "choice"),
|
|
26251
|
+
f("Bags", "number"),
|
|
26252
|
+
f("Minifigures", "number"),
|
|
26253
|
+
f("Released", "year")
|
|
26254
|
+
],
|
|
26255
|
+
statusWords: {
|
|
26256
|
+
want: "Want",
|
|
26257
|
+
have: "In the box",
|
|
26258
|
+
doing: "Building",
|
|
26259
|
+
done: "Built",
|
|
26260
|
+
dropped: "Parted out"
|
|
26261
|
+
}
|
|
26262
|
+
},
|
|
26263
|
+
vinyl: {
|
|
26264
|
+
name: "Vinyl",
|
|
26265
|
+
one: "record",
|
|
26266
|
+
icon: "disc",
|
|
26267
|
+
fields: [
|
|
26268
|
+
f("Artist", "text"),
|
|
26269
|
+
f("Label", "choice"),
|
|
26270
|
+
f("Pressing", "text"),
|
|
26271
|
+
f("Speed", "number"),
|
|
26272
|
+
f("Condition", "choice"),
|
|
26273
|
+
f("Released", "year")
|
|
26274
|
+
],
|
|
26275
|
+
statusWords: {
|
|
26276
|
+
want: "Want",
|
|
26277
|
+
have: "Have",
|
|
26278
|
+
doing: "On rotation",
|
|
26279
|
+
done: "Played out",
|
|
26280
|
+
dropped: "Sold"
|
|
26281
|
+
}
|
|
26282
|
+
},
|
|
26283
|
+
board: {
|
|
26284
|
+
name: "Board games",
|
|
26285
|
+
one: "board game",
|
|
26286
|
+
icon: "dice",
|
|
26287
|
+
fields: [
|
|
26288
|
+
f("Players", "number"),
|
|
26289
|
+
f("Play time", "text"),
|
|
26290
|
+
f("Designer", "text"),
|
|
26291
|
+
f("Expansions", "text"),
|
|
26292
|
+
f("Plays", "number"),
|
|
26293
|
+
f("Released", "year")
|
|
26294
|
+
],
|
|
26295
|
+
statusWords: {
|
|
26296
|
+
want: "Want",
|
|
26297
|
+
have: "Have",
|
|
26298
|
+
doing: "Learning",
|
|
26299
|
+
done: "Played",
|
|
26300
|
+
dropped: "Gave away"
|
|
26301
|
+
}
|
|
26302
|
+
},
|
|
26303
|
+
custom: {
|
|
26304
|
+
name: "",
|
|
26305
|
+
one: "",
|
|
26306
|
+
icon: "tag",
|
|
26307
|
+
fields: [f("Maker", "text"), f("Year", "year"), f("Condition", "choice")],
|
|
26308
|
+
statusWords: { want: "Want", have: "Have", doing: "Using", done: "Done", dropped: "Gone" }
|
|
26309
|
+
}
|
|
26310
|
+
};
|
|
26311
|
+
function kindSlug(name) {
|
|
26312
|
+
const s = name.toLowerCase().normalize("NFKD").replace(/[\u0300-\u036F]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40).replace(/-+$/, "");
|
|
26313
|
+
return s || "kind";
|
|
26314
|
+
}
|
|
26315
|
+
|
|
26140
26316
|
// ../../packages/schema/src/contracts/pagination.ts
|
|
26141
26317
|
var paginationQuerySchema = object({
|
|
26142
26318
|
limit: exports_coerce.number().int().positive().optional(),
|
|
@@ -26147,6 +26323,7 @@ var paginationQuerySchema = object({
|
|
|
26147
26323
|
var READ2 = ["collections:read"];
|
|
26148
26324
|
var WRITE2 = ["collections:write"];
|
|
26149
26325
|
var entryParams = { entryId: "The entry's ULID." };
|
|
26326
|
+
var kindParams = { kindId: "The kind's ULID." };
|
|
26150
26327
|
var collectionOperations = defineOperations({
|
|
26151
26328
|
...crudOperations({
|
|
26152
26329
|
segment: "collection",
|
|
@@ -26202,6 +26379,65 @@ var collectionOperations = defineOperations({
|
|
|
26202
26379
|
status: 200,
|
|
26203
26380
|
response: { description: "The Type registry." }
|
|
26204
26381
|
},
|
|
26382
|
+
listKinds: {
|
|
26383
|
+
method: "get",
|
|
26384
|
+
path: "/collection/kinds",
|
|
26385
|
+
scopes: READ2,
|
|
26386
|
+
tag: "Collection",
|
|
26387
|
+
summary: "List the Space's own kinds",
|
|
26388
|
+
description: "The kinds the Space added (vinyl, board games, \u2026) beside the built-in Types, by name: each with its `key` (what an Item of it carries as its `type`), `name`, `one`/`many`, `icon`, the `preset` it started from, its `fields` (key, label, type: `text`, `number`, `choice`, `year`, `date` or `yesno`, and a choice field's `choices`; the first three show on its tile), its `statusWords` for want, have, doing, done and dropped, its `view` (`grid`) and `itemCount`.",
|
|
26389
|
+
status: 200,
|
|
26390
|
+
response: { description: "The kinds." }
|
|
26391
|
+
},
|
|
26392
|
+
createKind: {
|
|
26393
|
+
method: "post",
|
|
26394
|
+
path: "/collection/kinds",
|
|
26395
|
+
scopes: WRITE2,
|
|
26396
|
+
tag: "Collection",
|
|
26397
|
+
summary: "Add a kind",
|
|
26398
|
+
description: "Start from a `preset` (`lego`, `vinyl`, `board` or `custom`, \"Something else\") and a `name`; what's left out comes from the preset (the icon, the fields, the status words), the `key` is the name's slug (never a built-in Type; 409 when the Space has it) and `one`/`many` come from the name. It starts on the clean grid.",
|
|
26399
|
+
body: createCollectionKindInputSchema,
|
|
26400
|
+
status: 201,
|
|
26401
|
+
response: { description: "The kind." },
|
|
26402
|
+
errors: { 400: true, 409: "The Space already has a kind with this key." }
|
|
26403
|
+
},
|
|
26404
|
+
getKind: {
|
|
26405
|
+
method: "get",
|
|
26406
|
+
path: "/collection/kinds/{kindId}",
|
|
26407
|
+
pathParams: kindParams,
|
|
26408
|
+
scopes: READ2,
|
|
26409
|
+
tag: "Collection",
|
|
26410
|
+
summary: "A kind of the Space's own",
|
|
26411
|
+
description: "The same shape as a row of the list.",
|
|
26412
|
+
status: 200,
|
|
26413
|
+
response: { description: "The kind." },
|
|
26414
|
+
errors: { 404: true }
|
|
26415
|
+
},
|
|
26416
|
+
updateKind: {
|
|
26417
|
+
method: "patch",
|
|
26418
|
+
path: "/collection/kinds/{kindId}",
|
|
26419
|
+
pathParams: kindParams,
|
|
26420
|
+
scopes: WRITE2,
|
|
26421
|
+
tag: "Collection",
|
|
26422
|
+
summary: "Change a kind",
|
|
26423
|
+
description: "Its name, one/many, icon, `fields` (replaces the list) or `statusWords`; a field left out stays. The key never changes.",
|
|
26424
|
+
body: updateCollectionKindInputSchema,
|
|
26425
|
+
status: 200,
|
|
26426
|
+
response: { description: "The kind." },
|
|
26427
|
+
errors: { 400: true, 404: true }
|
|
26428
|
+
},
|
|
26429
|
+
removeKind: {
|
|
26430
|
+
method: "delete",
|
|
26431
|
+
path: "/collection/kinds/{kindId}",
|
|
26432
|
+
pathParams: kindParams,
|
|
26433
|
+
scopes: WRITE2,
|
|
26434
|
+
tag: "Collection",
|
|
26435
|
+
summary: "Remove a kind",
|
|
26436
|
+
description: "Only a kind with no Items (409 otherwise: move or remove them first).",
|
|
26437
|
+
status: 204,
|
|
26438
|
+
response: { description: "Removed." },
|
|
26439
|
+
errors: { 404: true, 409: "The kind still has Items." }
|
|
26440
|
+
},
|
|
26205
26441
|
backfillCovers: {
|
|
26206
26442
|
method: "post",
|
|
26207
26443
|
path: "/collection/covers",
|
|
@@ -29311,6 +29547,271 @@ var healthCycleShares = pgTable("health_cycle_shares", {
|
|
|
29311
29547
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
29312
29548
|
}, (t) => [primaryKey({ columns: [t.tenantId, t.userId] })]);
|
|
29313
29549
|
|
|
29550
|
+
// ../../packages/schema/src/contracts/modules.ts
|
|
29551
|
+
var MODULE_KEYS = [
|
|
29552
|
+
"tasks",
|
|
29553
|
+
"habits",
|
|
29554
|
+
"routines",
|
|
29555
|
+
"challenges",
|
|
29556
|
+
"projects",
|
|
29557
|
+
"areas",
|
|
29558
|
+
"notes",
|
|
29559
|
+
"shopping",
|
|
29560
|
+
"inventory",
|
|
29561
|
+
"meals",
|
|
29562
|
+
"animals",
|
|
29563
|
+
"contacts",
|
|
29564
|
+
"sharing",
|
|
29565
|
+
"automations"
|
|
29566
|
+
];
|
|
29567
|
+
var moduleKeySchema = _enum2(MODULE_KEYS);
|
|
29568
|
+
var FEATURE_MODULES = [
|
|
29569
|
+
{
|
|
29570
|
+
key: "today",
|
|
29571
|
+
label: "Today",
|
|
29572
|
+
description: "Your daily dashboard \u2014 always on.",
|
|
29573
|
+
group: "System",
|
|
29574
|
+
defaultEnabled: true,
|
|
29575
|
+
system: true
|
|
29576
|
+
},
|
|
29577
|
+
{
|
|
29578
|
+
key: "inbox",
|
|
29579
|
+
label: "Inbox",
|
|
29580
|
+
description: "Quick capture and triage \u2014 always on.",
|
|
29581
|
+
group: "System",
|
|
29582
|
+
defaultEnabled: true,
|
|
29583
|
+
system: true
|
|
29584
|
+
},
|
|
29585
|
+
{
|
|
29586
|
+
key: "settings",
|
|
29587
|
+
label: "Settings",
|
|
29588
|
+
description: "This screen \u2014 always on.",
|
|
29589
|
+
group: "System",
|
|
29590
|
+
defaultEnabled: true,
|
|
29591
|
+
system: true
|
|
29592
|
+
},
|
|
29593
|
+
{
|
|
29594
|
+
key: "tasks",
|
|
29595
|
+
label: "Tasks",
|
|
29596
|
+
description: "To-dos, due dates, and starred focus.",
|
|
29597
|
+
group: "Track",
|
|
29598
|
+
defaultEnabled: true
|
|
29599
|
+
},
|
|
29600
|
+
{
|
|
29601
|
+
key: "habits",
|
|
29602
|
+
label: "Habits",
|
|
29603
|
+
description: "Daily routines and streaks.",
|
|
29604
|
+
group: "Track",
|
|
29605
|
+
defaultEnabled: true
|
|
29606
|
+
},
|
|
29607
|
+
{
|
|
29608
|
+
key: "routines",
|
|
29609
|
+
label: "Routines",
|
|
29610
|
+
description: "Repeatable checklists you run.",
|
|
29611
|
+
group: "Track",
|
|
29612
|
+
defaultEnabled: true
|
|
29613
|
+
},
|
|
29614
|
+
{
|
|
29615
|
+
key: "challenges",
|
|
29616
|
+
label: "Challenges",
|
|
29617
|
+
description: "Time-boxed goals and competitions.",
|
|
29618
|
+
group: "Track",
|
|
29619
|
+
defaultEnabled: false
|
|
29620
|
+
},
|
|
29621
|
+
{
|
|
29622
|
+
key: "projects",
|
|
29623
|
+
label: "Projects",
|
|
29624
|
+
description: "Multi-step work with milestones.",
|
|
29625
|
+
group: "Organize",
|
|
29626
|
+
defaultEnabled: true
|
|
29627
|
+
},
|
|
29628
|
+
{
|
|
29629
|
+
key: "areas",
|
|
29630
|
+
label: "Areas",
|
|
29631
|
+
description: "Ongoing life domains (PARA areas).",
|
|
29632
|
+
group: "Organize",
|
|
29633
|
+
defaultEnabled: true
|
|
29634
|
+
},
|
|
29635
|
+
{
|
|
29636
|
+
key: "notes",
|
|
29637
|
+
label: "Notes",
|
|
29638
|
+
description: "Quick notes and documents.",
|
|
29639
|
+
group: "Organize",
|
|
29640
|
+
defaultEnabled: true
|
|
29641
|
+
},
|
|
29642
|
+
{
|
|
29643
|
+
key: "shopping",
|
|
29644
|
+
label: "Shopping",
|
|
29645
|
+
description: "Lists and groceries.",
|
|
29646
|
+
group: "Household",
|
|
29647
|
+
defaultEnabled: true
|
|
29648
|
+
},
|
|
29649
|
+
{
|
|
29650
|
+
key: "inventory",
|
|
29651
|
+
label: "Inventory",
|
|
29652
|
+
description: "Things you own and stock.",
|
|
29653
|
+
group: "Household",
|
|
29654
|
+
defaultEnabled: true
|
|
29655
|
+
},
|
|
29656
|
+
{
|
|
29657
|
+
key: "meals",
|
|
29658
|
+
label: "Meals",
|
|
29659
|
+
description: "Recipes and meal plans.",
|
|
29660
|
+
group: "Household",
|
|
29661
|
+
defaultEnabled: false
|
|
29662
|
+
},
|
|
29663
|
+
{
|
|
29664
|
+
key: "animals",
|
|
29665
|
+
label: "Animals",
|
|
29666
|
+
description: "Pets and flocks: eggs, weights, feed and care.",
|
|
29667
|
+
group: "Household",
|
|
29668
|
+
defaultEnabled: false
|
|
29669
|
+
},
|
|
29670
|
+
{
|
|
29671
|
+
key: "contacts",
|
|
29672
|
+
label: "Contacts",
|
|
29673
|
+
description: "People and relationships.",
|
|
29674
|
+
group: "People",
|
|
29675
|
+
defaultEnabled: false
|
|
29676
|
+
},
|
|
29677
|
+
{
|
|
29678
|
+
key: "sharing",
|
|
29679
|
+
label: "Members & sharing",
|
|
29680
|
+
description: "Members, roles, per-item sharing and comments.",
|
|
29681
|
+
group: "People",
|
|
29682
|
+
defaultEnabled: false
|
|
29683
|
+
},
|
|
29684
|
+
{
|
|
29685
|
+
key: "automations",
|
|
29686
|
+
label: "Automations",
|
|
29687
|
+
description: "Trigger \u2192 condition \u2192 action rules.",
|
|
29688
|
+
group: "Manage",
|
|
29689
|
+
defaultEnabled: false
|
|
29690
|
+
}
|
|
29691
|
+
];
|
|
29692
|
+
var TOGGLEABLE_MODULES = FEATURE_MODULES.filter((m) => !m.system);
|
|
29693
|
+
function isModuleKey(value) {
|
|
29694
|
+
return MODULE_KEYS.includes(value);
|
|
29695
|
+
}
|
|
29696
|
+
function defaultEnabledModules() {
|
|
29697
|
+
return TOGGLEABLE_MODULES.filter((m) => m.defaultEnabled).map((m) => m.key);
|
|
29698
|
+
}
|
|
29699
|
+
function normalizeEnabledModules(keys) {
|
|
29700
|
+
const present = new Set(keys.filter(isModuleKey));
|
|
29701
|
+
return MODULE_KEYS.filter((key) => present.has(key));
|
|
29702
|
+
}
|
|
29703
|
+
function effectiveEnabledModules(enabled) {
|
|
29704
|
+
const known = normalizeEnabledModules(enabled ?? []);
|
|
29705
|
+
return known.length > 0 ? known : defaultEnabledModules();
|
|
29706
|
+
}
|
|
29707
|
+
function setModuleEnabled(enabled, key, on) {
|
|
29708
|
+
const next = new Set(effectiveEnabledModules(enabled));
|
|
29709
|
+
if (on)
|
|
29710
|
+
next.add(key);
|
|
29711
|
+
else
|
|
29712
|
+
next.delete(key);
|
|
29713
|
+
return MODULE_KEYS.filter((candidate) => next.has(candidate));
|
|
29714
|
+
}
|
|
29715
|
+
|
|
29716
|
+
// ../../packages/schema/src/contracts/settings.ts
|
|
29717
|
+
var clockTimeSchema = string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "a time like 22:00");
|
|
29718
|
+
var quietHoursSchema = object({
|
|
29719
|
+
from: clockTimeSchema,
|
|
29720
|
+
until: clockTimeSchema,
|
|
29721
|
+
days: array(number2().int().min(0).max(6)).max(7)
|
|
29722
|
+
});
|
|
29723
|
+
var PINNED_AREAS_MAX = 5;
|
|
29724
|
+
var PILL_PAGES = [
|
|
29725
|
+
"now",
|
|
29726
|
+
"habits",
|
|
29727
|
+
"tasks",
|
|
29728
|
+
"calendar",
|
|
29729
|
+
"areas",
|
|
29730
|
+
"house",
|
|
29731
|
+
"collection",
|
|
29732
|
+
"animals",
|
|
29733
|
+
"notes",
|
|
29734
|
+
"progress",
|
|
29735
|
+
"landed",
|
|
29736
|
+
"review",
|
|
29737
|
+
"agents",
|
|
29738
|
+
"profile",
|
|
29739
|
+
"settings",
|
|
29740
|
+
"alerts",
|
|
29741
|
+
"trash"
|
|
29742
|
+
];
|
|
29743
|
+
var pillPageSchema = _enum2(PILL_PAGES);
|
|
29744
|
+
var PILL_PAGES_MAX = 4;
|
|
29745
|
+
var CALENDAR_ZOOM_MIN = 75;
|
|
29746
|
+
var CALENDAR_ZOOM_MAX = 300;
|
|
29747
|
+
var calendarZoomSchema = number2().int().min(CALENDAR_ZOOM_MIN).max(CALENDAR_ZOOM_MAX);
|
|
29748
|
+
var settingsGlassSchema = _enum2(settingsGlass.enumValues);
|
|
29749
|
+
var themePackSchema = _enum2(settingsThemePack.enumValues);
|
|
29750
|
+
var themePackScopeSchema = _enum2(settingsThemePackScope.enumValues);
|
|
29751
|
+
var settingsUiSchema = _enum2(settingsUi.enumValues);
|
|
29752
|
+
var HEALTH_TODAY_HINTS = ["supplements", "sleep", "appointment", "episode"];
|
|
29753
|
+
var healthTodayHintSchema = _enum2(HEALTH_TODAY_HINTS);
|
|
29754
|
+
var HEALTH_TODAY_HINTS_DEFAULT = ["supplements", "sleep"];
|
|
29755
|
+
var userSettingsSchema = createSelectSchema(userSettings, {
|
|
29756
|
+
pinnedAreaIds: array(string2()).default([]),
|
|
29757
|
+
focusAreaId: string2().nullable().default(null),
|
|
29758
|
+
focusUntil: exports_coerce.date().nullable().default(null),
|
|
29759
|
+
quietHours: quietHoursSchema.nullable().default(null),
|
|
29760
|
+
notifications: record(string2(), unknown()).nullable().default(null),
|
|
29761
|
+
lifeBlockSharing: lifeBlockSharingSchema.nullable().default(null),
|
|
29762
|
+
pillPages: array(string2()).default([]).transform((ids) => ids.filter((id) => pillPageSchema.safeParse(id).success)),
|
|
29763
|
+
foodDiaryMode: boolean2().default(false),
|
|
29764
|
+
calendarZoom: number2().int().nullable().default(null),
|
|
29765
|
+
glass: settingsGlassSchema.default("liquid"),
|
|
29766
|
+
followSky: boolean2().default(true),
|
|
29767
|
+
nightUntilWake: boolean2().default(false),
|
|
29768
|
+
largerText: boolean2().default(false),
|
|
29769
|
+
reduceMotion: boolean2().default(false),
|
|
29770
|
+
showStreakNumbers: boolean2().default(true),
|
|
29771
|
+
themePack: themePackSchema.default("do"),
|
|
29772
|
+
themePackScope: themePackScopeSchema.default("section"),
|
|
29773
|
+
ui: settingsUiSchema.default("v1"),
|
|
29774
|
+
healthTodayHints: array(string2()).default([...HEALTH_TODAY_HINTS_DEFAULT]).transform((ids) => ids.filter((id) => healthTodayHintSchema.safeParse(id).success)),
|
|
29775
|
+
createdAt: exports_coerce.date(),
|
|
29776
|
+
updatedAt: exports_coerce.date()
|
|
29777
|
+
}).omit({ autoRollOverdue: true });
|
|
29778
|
+
var updateUserSettingsInputSchema = createUpdateSchema(userSettings, {
|
|
29779
|
+
displayName: string2().trim().max(80).nullish(),
|
|
29780
|
+
avatarUrl: union([string2().url().max(2048), literal("")]).nullish(),
|
|
29781
|
+
timezone: string2().min(1).optional(),
|
|
29782
|
+
locale: string2().min(1).optional(),
|
|
29783
|
+
theme: settingsThemeSchema.optional(),
|
|
29784
|
+
density: settingsDensitySchema.optional(),
|
|
29785
|
+
accent: settingsAccentSchema.optional(),
|
|
29786
|
+
sunCity: string2().trim().max(80).transform((city) => city === "" ? null : city).nullish(),
|
|
29787
|
+
backdrop: backdropIdSchema.nullish(),
|
|
29788
|
+
enabledModules: array(string2().trim().min(1)).transform(normalizeEnabledModules).optional(),
|
|
29789
|
+
pinnedAreaIds: array(ulidSchema).transform((ids) => [...new Set(ids)]).pipe(array(ulidSchema).max(PINNED_AREAS_MAX)).optional(),
|
|
29790
|
+
focusAreaId: ulidSchema.nullish(),
|
|
29791
|
+
quietHours: quietHoursSchema.nullish(),
|
|
29792
|
+
lifeBlockSharing: lifeBlockSharingSchema.nullish(),
|
|
29793
|
+
calendarZoom: calendarZoomSchema.nullish(),
|
|
29794
|
+
pillPages: array(pillPageSchema).transform((ids) => [...new Set(ids)]).pipe(array(pillPageSchema).max(PILL_PAGES_MAX)).optional(),
|
|
29795
|
+
glass: settingsGlassSchema.optional(),
|
|
29796
|
+
followSky: boolean2().optional(),
|
|
29797
|
+
nightUntilWake: boolean2().optional(),
|
|
29798
|
+
largerText: boolean2().optional(),
|
|
29799
|
+
reduceMotion: boolean2().optional(),
|
|
29800
|
+
showStreakNumbers: boolean2().optional(),
|
|
29801
|
+
themePack: themePackSchema.optional(),
|
|
29802
|
+
themePackScope: themePackScopeSchema.optional(),
|
|
29803
|
+
ui: settingsUiSchema.optional(),
|
|
29804
|
+
healthTodayHints: array(healthTodayHintSchema).transform((ids) => HEALTH_TODAY_HINTS.filter((id) => ids.includes(id))).optional()
|
|
29805
|
+
}).omit({
|
|
29806
|
+
id: true,
|
|
29807
|
+
tenantId: true,
|
|
29808
|
+
userId: true,
|
|
29809
|
+
createdAt: true,
|
|
29810
|
+
updatedAt: true,
|
|
29811
|
+
autoRollOverdue: true,
|
|
29812
|
+
focusUntil: true
|
|
29813
|
+
}).strict();
|
|
29814
|
+
|
|
29314
29815
|
// ../../packages/schema/src/contracts/health-records.ts
|
|
29315
29816
|
var BODY_REGION_VALUES = [
|
|
29316
29817
|
"head",
|
|
@@ -29587,6 +30088,14 @@ var updateHealthProfileInputSchema = object({
|
|
|
29587
30088
|
emergencyContactId: ulidSchema.nullish(),
|
|
29588
30089
|
primaryGpContactId: ulidSchema.nullish()
|
|
29589
30090
|
}).strict();
|
|
30091
|
+
var healthTodaySchema = object({
|
|
30092
|
+
hints: array(healthTodayHintSchema),
|
|
30093
|
+
on: boolean2(),
|
|
30094
|
+
supplementHabitIds: array(string2()),
|
|
30095
|
+
sleep: object({ hours: number2() }).nullable(),
|
|
30096
|
+
appointment: object({ id: string2(), title: string2(), at: exports_coerce.date() }).nullable(),
|
|
30097
|
+
episode: object({ id: string2(), title: string2(), startedAt: exports_coerce.date() }).nullable()
|
|
30098
|
+
});
|
|
29590
30099
|
var grantHealthConsentInputSchema = object({ version: literal(HEALTH_CONSENT_VERSION) }).strict();
|
|
29591
30100
|
var HEALTH_ERASE_PHRASE = "delete my health data";
|
|
29592
30101
|
var eraseHealthDataInputSchema = object({ confirm: literal(HEALTH_ERASE_PHRASE) }).strict();
|
|
@@ -37987,7 +38496,7 @@ var planningRules = pgTable("planning_rules", {
|
|
|
37987
38496
|
var PLANNING_RULE_KINDS = planningRuleKind.enumValues;
|
|
37988
38497
|
var planningRuleKindSchema = _enum2(PLANNING_RULE_KINDS);
|
|
37989
38498
|
var PLANNING_RULE_SENTENCE_MAX = 280;
|
|
37990
|
-
var
|
|
38499
|
+
var clockTimeSchema2 = string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "expected HH:MM (24 h)");
|
|
37991
38500
|
var ruleWeekdaysSchema = array(number2().int().min(1).max(7)).min(1).max(7).transform((days) => [...new Set(days)].sort((a, b) => a - b));
|
|
37992
38501
|
var phraseSchema = string2().trim().min(1).max(80);
|
|
37993
38502
|
function clockMinutes(clock) {
|
|
@@ -37998,15 +38507,15 @@ var fixedTimeRuleSchema = object({
|
|
|
37998
38507
|
kind: literal("fixed_time"),
|
|
37999
38508
|
what: phraseSchema,
|
|
38000
38509
|
days: ruleWeekdaysSchema,
|
|
38001
|
-
at:
|
|
38510
|
+
at: clockTimeSchema2,
|
|
38002
38511
|
minutes: number2().int().min(5).max(24 * 60).default(60),
|
|
38003
38512
|
lifeKind: lifeBlockKindSchema.optional()
|
|
38004
38513
|
}).strict();
|
|
38005
38514
|
var keepFreeRuleSchema = object({
|
|
38006
38515
|
kind: literal("keep_free"),
|
|
38007
38516
|
days: ruleWeekdaysSchema,
|
|
38008
|
-
from:
|
|
38009
|
-
to:
|
|
38517
|
+
from: clockTimeSchema2,
|
|
38518
|
+
to: clockTimeSchema2,
|
|
38010
38519
|
what: phraseSchema.optional()
|
|
38011
38520
|
}).strict().refine((r) => clockMinutes(r.to) > clockMinutes(r.from), {
|
|
38012
38521
|
message: "`to` comes after `from`",
|
|
@@ -40065,18 +40574,18 @@ var runPlayStatusValues = [
|
|
|
40065
40574
|
"dropped"
|
|
40066
40575
|
];
|
|
40067
40576
|
var runPlayStatusSchema = _enum2(runPlayStatusValues);
|
|
40068
|
-
var
|
|
40577
|
+
var name3 = string2().trim().min(1).max(200);
|
|
40069
40578
|
var text5 = string2().trim().max(2000);
|
|
40070
40579
|
var shortText2 = string2().trim().max(300);
|
|
40071
40580
|
var isoDate = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "must be an ISO date (YYYY-MM-DD)");
|
|
40072
40581
|
var ref = string2().trim().min(1).max(200);
|
|
40073
40582
|
var runCharacterSchema = object({
|
|
40074
|
-
name:
|
|
40583
|
+
name: name3,
|
|
40075
40584
|
pronoun: _enum2(["he", "she", "they"]).nullish(),
|
|
40076
40585
|
subtitle: shortText2.nullish(),
|
|
40077
40586
|
level: number2().int().min(0).max(1e4).nullish(),
|
|
40078
40587
|
build: shortText2.nullish(),
|
|
40079
|
-
stats: array(object({ k:
|
|
40588
|
+
stats: array(object({ k: name3, v: union([number2(), shortText2]) }).strict()).max(40).optional(),
|
|
40080
40589
|
traits: array(shortText2).max(20).optional(),
|
|
40081
40590
|
backstory: text5.nullish(),
|
|
40082
40591
|
rules: array(shortText2).max(30).optional(),
|
|
@@ -40085,12 +40594,12 @@ var runCharacterSchema = object({
|
|
|
40085
40594
|
var runArcSchema = object({
|
|
40086
40595
|
title: shortText2.nullish(),
|
|
40087
40596
|
chapters: array(object({
|
|
40088
|
-
key:
|
|
40089
|
-
name:
|
|
40597
|
+
key: name3,
|
|
40598
|
+
name: name3,
|
|
40090
40599
|
range: shortText2.nullish(),
|
|
40091
40600
|
moral: text5.nullish()
|
|
40092
40601
|
}).strict()).max(40),
|
|
40093
|
-
current:
|
|
40602
|
+
current: name3.nullish()
|
|
40094
40603
|
}).strict();
|
|
40095
40604
|
var runStepStatusValues = ["done", "now", "todo", "skipped"];
|
|
40096
40605
|
var runStepStatusSchema = _enum2(runStepStatusValues);
|
|
@@ -40103,7 +40612,7 @@ var runQuestStatusValues = ["active", "paused", "planned", "done", "failed"];
|
|
|
40103
40612
|
var runQuestStatusSchema = _enum2(runQuestStatusValues);
|
|
40104
40613
|
var runQuestSchema = object({
|
|
40105
40614
|
ref: ref.nullish(),
|
|
40106
|
-
name:
|
|
40615
|
+
name: name3,
|
|
40107
40616
|
line: shortText2.nullish(),
|
|
40108
40617
|
status: runQuestStatusSchema.default("active"),
|
|
40109
40618
|
objective: text5.nullish(),
|
|
@@ -40118,7 +40627,7 @@ var runQuestSchema = object({
|
|
|
40118
40627
|
}).strict()).max(40).optional(),
|
|
40119
40628
|
pausedAt: shortText2.nullish(),
|
|
40120
40629
|
why: text5.nullish(),
|
|
40121
|
-
revisitAt:
|
|
40630
|
+
revisitAt: name3.nullish()
|
|
40122
40631
|
}).strict();
|
|
40123
40632
|
var runNextStepsSchema = object({
|
|
40124
40633
|
items: array(shortText2.pipe(string2().min(1))).max(3),
|
|
@@ -40127,50 +40636,50 @@ var runNextStepsSchema = object({
|
|
|
40127
40636
|
}).strict();
|
|
40128
40637
|
var runChoiceSchema = object({
|
|
40129
40638
|
ref: ref.nullish(),
|
|
40130
|
-
title:
|
|
40639
|
+
title: name3,
|
|
40131
40640
|
place: shortText2.nullish(),
|
|
40132
40641
|
status: _enum2(["made", "planned"]).default("made"),
|
|
40133
40642
|
options: array(shortText2).max(6).optional(),
|
|
40134
40643
|
why: text5.nullish(),
|
|
40135
40644
|
consequence: text5.nullish(),
|
|
40136
|
-
revisitAt:
|
|
40137
|
-
chapter:
|
|
40645
|
+
revisitAt: name3.nullish(),
|
|
40646
|
+
chapter: name3.nullish(),
|
|
40138
40647
|
tone: _enum2(["good", "grey", "dark"]).nullish(),
|
|
40139
40648
|
on: isoDate.nullish()
|
|
40140
40649
|
}).strict();
|
|
40141
40650
|
var runHomeSchema = object({
|
|
40142
40651
|
ref: ref.nullish(),
|
|
40143
|
-
name:
|
|
40652
|
+
name: name3,
|
|
40144
40653
|
role: _enum2(["home", "collector", "storage", "planned", "later"]).default("home"),
|
|
40145
40654
|
place: shortText2.nullish(),
|
|
40146
|
-
upgrades: array(object({ name:
|
|
40655
|
+
upgrades: array(object({ name: name3, done: boolean2().default(false) }).strict()).max(40).optional(),
|
|
40147
40656
|
steward: shortText2.nullish(),
|
|
40148
40657
|
note: text5.nullish()
|
|
40149
40658
|
}).strict();
|
|
40150
40659
|
var runPersonSchema = object({
|
|
40151
40660
|
ref: ref.nullish(),
|
|
40152
|
-
name:
|
|
40661
|
+
name: name3,
|
|
40153
40662
|
role: _enum2(["child", "spouse", "steward", "follower", "pet", "rival", "other"]),
|
|
40154
40663
|
status: _enum2(["with", "planned", "lost"]).default("with"),
|
|
40155
40664
|
home: shortText2.nullish(),
|
|
40156
40665
|
note: text5.nullish()
|
|
40157
40666
|
}).strict();
|
|
40158
40667
|
var runMountSchema = object({
|
|
40159
|
-
name:
|
|
40668
|
+
name: name3,
|
|
40160
40669
|
status: _enum2(["with", "planned", "lost"]).default("with"),
|
|
40161
40670
|
note: text5.nullish()
|
|
40162
40671
|
}).strict();
|
|
40163
40672
|
var runUniqueSchema = object({
|
|
40164
40673
|
ref: ref.nullish(),
|
|
40165
|
-
name:
|
|
40674
|
+
name: name3,
|
|
40166
40675
|
status: _enum2(["have", "now", "want"]).default("have"),
|
|
40167
40676
|
source: shortText2.nullish(),
|
|
40168
40677
|
displayAt: shortText2.nullish(),
|
|
40169
|
-
set:
|
|
40678
|
+
set: name3.nullish()
|
|
40170
40679
|
}).strict();
|
|
40171
40680
|
var runChecklistSchema = object({
|
|
40172
40681
|
key: string2().trim().min(1).max(60).regex(/^[a-z0-9][a-z0-9_-]*$/, "must be a lowercase slug"),
|
|
40173
|
-
label:
|
|
40682
|
+
label: name3,
|
|
40174
40683
|
total: number2().int().min(0).max(5000).nullish(),
|
|
40175
40684
|
items: array(object({ id: ref, label: shortText2.nullish() }).strict()).max(5000).optional(),
|
|
40176
40685
|
done: array(ref).max(5000),
|
|
@@ -40179,7 +40688,7 @@ var runChecklistSchema = object({
|
|
|
40179
40688
|
legend: shortText2.nullish()
|
|
40180
40689
|
}).strict();
|
|
40181
40690
|
var runTeamMemberSchema = object({
|
|
40182
|
-
species:
|
|
40691
|
+
species: name3,
|
|
40183
40692
|
nick: shortText2.nullish(),
|
|
40184
40693
|
level: number2().int().min(1).max(100).nullish(),
|
|
40185
40694
|
nature: shortText2.nullish(),
|
|
@@ -40193,8 +40702,8 @@ var runAchievementsSchema = object({
|
|
|
40193
40702
|
source: _enum2(["steam", "xbox", "psn", "manual"]).default("manual"),
|
|
40194
40703
|
total: number2().int().min(0).max(5000).nullish(),
|
|
40195
40704
|
enabled: boolean2().default(true),
|
|
40196
|
-
unlocked: array(object({ name:
|
|
40197
|
-
locked: array(object({ name:
|
|
40705
|
+
unlocked: array(object({ name: name3, on: isoDate.nullish(), hint: shortText2.nullish(), key: ref.nullish() }).strict()).max(5000),
|
|
40706
|
+
locked: array(object({ name: name3, hint: shortText2.nullish(), key: ref.nullish() }).strict()).max(5000).optional(),
|
|
40198
40707
|
syncedAt: string2().datetime({ offset: true }).nullish()
|
|
40199
40708
|
}).strict();
|
|
40200
40709
|
var runRareFindsSchema = object({
|
|
@@ -40204,7 +40713,7 @@ var runRareFindsSchema = object({
|
|
|
40204
40713
|
}).strict();
|
|
40205
40714
|
var runInstallSchema = object({
|
|
40206
40715
|
edition: shortText2.nullish(),
|
|
40207
|
-
mods: array(object({ name:
|
|
40716
|
+
mods: array(object({ name: name3, url: string2().url().max(2000).nullish() }).strict()).max(200).default([]),
|
|
40208
40717
|
savePath: string2().trim().max(500).nullish(),
|
|
40209
40718
|
lastBackup: isoDate.nullish(),
|
|
40210
40719
|
notes: text5.nullish()
|
|
@@ -40214,7 +40723,7 @@ var runSaveFields = {
|
|
|
40214
40723
|
game: _enum2(["skyrim"]).default("skyrim"),
|
|
40215
40724
|
fileName: shortText2.nullish(),
|
|
40216
40725
|
saveNumber: number2().int().min(0).max(1e9),
|
|
40217
|
-
playerName:
|
|
40726
|
+
playerName: name3,
|
|
40218
40727
|
level: number2().int().min(0).max(1e4),
|
|
40219
40728
|
location: shortText2,
|
|
40220
40729
|
race: shortText2.nullish(),
|
|
@@ -40260,7 +40769,7 @@ var runFacetSchema = object({
|
|
|
40260
40769
|
install: runInstallSchema.nullish(),
|
|
40261
40770
|
save: runSaveSchema.nullish(),
|
|
40262
40771
|
money: object({ goal: shortText2.nullish(), purpose: shortText2.nullish() }).strict().nullish(),
|
|
40263
|
-
links: array(object({ label:
|
|
40772
|
+
links: array(object({ label: name3, url: string2().url().max(2000) }).strict()).max(50).optional()
|
|
40264
40773
|
}).strict();
|
|
40265
40774
|
var runListSectionValues = [
|
|
40266
40775
|
"orderOfPlay",
|
|
@@ -40414,12 +40923,12 @@ var runSaveHeaderResultSchema = object({
|
|
|
40414
40923
|
var createRunInputSchema = object({
|
|
40415
40924
|
id: ulidSchema,
|
|
40416
40925
|
gameId: ulidSchema,
|
|
40417
|
-
title:
|
|
40926
|
+
title: name3,
|
|
40418
40927
|
status: runPlayStatusSchema.optional(),
|
|
40419
40928
|
facet: runFacetSchema.optional()
|
|
40420
40929
|
}).strict();
|
|
40421
40930
|
var updateRunInputSchema = object({
|
|
40422
|
-
title:
|
|
40931
|
+
title: name3.optional(),
|
|
40423
40932
|
status: runPlayStatusSchema.optional(),
|
|
40424
40933
|
facet: runFacetSchema.optional()
|
|
40425
40934
|
}).strict();
|
|
@@ -40808,325 +41317,65 @@ var sensorOperations = defineOperations({
|
|
|
40808
41317
|
response: { description: "The status." },
|
|
40809
41318
|
errors: { 403: true }
|
|
40810
41319
|
},
|
|
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
|
|
40955
|
-
},
|
|
40956
|
-
{
|
|
40957
|
-
key: "notes",
|
|
40958
|
-
label: "Notes",
|
|
40959
|
-
description: "Quick notes and documents.",
|
|
40960
|
-
group: "Organize",
|
|
40961
|
-
defaultEnabled: true
|
|
40962
|
-
},
|
|
40963
|
-
{
|
|
40964
|
-
key: "shopping",
|
|
40965
|
-
label: "Shopping",
|
|
40966
|
-
description: "Lists and groceries.",
|
|
40967
|
-
group: "Household",
|
|
40968
|
-
defaultEnabled: true
|
|
40969
|
-
},
|
|
40970
|
-
{
|
|
40971
|
-
key: "inventory",
|
|
40972
|
-
label: "Inventory",
|
|
40973
|
-
description: "Things you own and stock.",
|
|
40974
|
-
group: "Household",
|
|
40975
|
-
defaultEnabled: true
|
|
40976
|
-
},
|
|
40977
|
-
{
|
|
40978
|
-
key: "meals",
|
|
40979
|
-
label: "Meals",
|
|
40980
|
-
description: "Recipes and meal plans.",
|
|
40981
|
-
group: "Household",
|
|
40982
|
-
defaultEnabled: false
|
|
41320
|
+
unifiDevices: {
|
|
41321
|
+
method: "get",
|
|
41322
|
+
path: "/sensors/unifi/devices",
|
|
41323
|
+
scopes: ["places:read", "collections:read"],
|
|
41324
|
+
tag: "Sensors",
|
|
41325
|
+
summary: "The devices UniFi sees",
|
|
41326
|
+
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.",
|
|
41327
|
+
status: 200,
|
|
41328
|
+
response: { description: "The devices." },
|
|
41329
|
+
errors: { 403: true, 409: true }
|
|
40983
41330
|
},
|
|
40984
|
-
{
|
|
40985
|
-
|
|
40986
|
-
|
|
40987
|
-
|
|
40988
|
-
|
|
40989
|
-
|
|
41331
|
+
syncUnifi: {
|
|
41332
|
+
method: "post",
|
|
41333
|
+
path: "/sensors/unifi/sync",
|
|
41334
|
+
scopes: ["places:write"],
|
|
41335
|
+
tag: "Sensors",
|
|
41336
|
+
summary: "Sync UniFi now",
|
|
41337
|
+
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.",
|
|
41338
|
+
status: 200,
|
|
41339
|
+
response: { description: "What the sync did." },
|
|
41340
|
+
errors: { 403: true, 409: true }
|
|
40990
41341
|
},
|
|
40991
|
-
{
|
|
40992
|
-
|
|
40993
|
-
|
|
40994
|
-
|
|
40995
|
-
|
|
40996
|
-
|
|
41342
|
+
links: {
|
|
41343
|
+
method: "get",
|
|
41344
|
+
path: "/sensors/links",
|
|
41345
|
+
scopes: ["places:read"],
|
|
41346
|
+
tag: "Sensors",
|
|
41347
|
+
summary: "List the mapped entities",
|
|
41348
|
+
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.",
|
|
41349
|
+
query: [{ name: "nodeId", description: "Only the mappings on this Place or asset." }],
|
|
41350
|
+
querySchema: sensorLinksQuerySchema,
|
|
41351
|
+
status: 200,
|
|
41352
|
+
response: { description: "The mappings, by entity id." },
|
|
41353
|
+
errors: { 400: true }
|
|
40997
41354
|
},
|
|
40998
|
-
{
|
|
40999
|
-
|
|
41000
|
-
|
|
41001
|
-
|
|
41002
|
-
|
|
41003
|
-
|
|
41355
|
+
createLink: {
|
|
41356
|
+
method: "post",
|
|
41357
|
+
path: "/sensors/links",
|
|
41358
|
+
scopes: ["places:write"],
|
|
41359
|
+
tag: "Sensors",
|
|
41360
|
+
summary: "Map an entity",
|
|
41361
|
+
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.",
|
|
41362
|
+
body: createSensorLinkInputSchema,
|
|
41363
|
+
status: 201,
|
|
41364
|
+
response: { description: "The mapping." },
|
|
41365
|
+
errors: { 400: true, 404: true, 409: true }
|
|
41004
41366
|
},
|
|
41005
|
-
{
|
|
41006
|
-
|
|
41007
|
-
|
|
41008
|
-
|
|
41009
|
-
|
|
41010
|
-
|
|
41367
|
+
removeLink: {
|
|
41368
|
+
method: "delete",
|
|
41369
|
+
path: "/sensors/links/{id}",
|
|
41370
|
+
scopes: ["places:write"],
|
|
41371
|
+
tag: "Sensors",
|
|
41372
|
+
summary: "Unmap an entity",
|
|
41373
|
+
description: "Remove one mapping; the readings it gave stay on the ledger.",
|
|
41374
|
+
status: 204,
|
|
41375
|
+
response: { description: "Removed." },
|
|
41376
|
+
errors: { 404: true }
|
|
41011
41377
|
}
|
|
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
41378
|
});
|
|
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
41379
|
|
|
41131
41380
|
// ../../packages/schema/src/operations/settings.ts
|
|
41132
41381
|
var settingsOperations = defineOperations({
|
|
@@ -43246,6 +43495,18 @@ var hobbyFacetSchema = object({
|
|
|
43246
43495
|
with: string2().min(1).max(80).nullish(),
|
|
43247
43496
|
coverUrl
|
|
43248
43497
|
}).strict();
|
|
43498
|
+
var consoleFacetSchema = object({
|
|
43499
|
+
model: string2().min(1).max(120).nullish(),
|
|
43500
|
+
region: string2().min(1).max(40).nullish(),
|
|
43501
|
+
condition: string2().min(1).max(80).nullish(),
|
|
43502
|
+
boxed: boolean2().nullish(),
|
|
43503
|
+
extras: string2().min(1).max(200).nullish(),
|
|
43504
|
+
year: number2().int().min(1950).max(2100).nullish(),
|
|
43505
|
+
works: boolean2().nullish(),
|
|
43506
|
+
fixNote: string2().min(1).max(200).nullish(),
|
|
43507
|
+
plays: array(string2().trim().min(1).max(40)).max(12).nullish(),
|
|
43508
|
+
coverUrl
|
|
43509
|
+
}).strict();
|
|
43249
43510
|
var placeFacetSchema = object({
|
|
43250
43511
|
address: string2().min(1).max(400).nullish(),
|
|
43251
43512
|
lat: number2().min(-90).max(90).nullish(),
|
|
@@ -43482,6 +43743,16 @@ var COLLECTION_TYPES = {
|
|
|
43482
43743
|
facetSchema: hobbyFacetSchema,
|
|
43483
43744
|
view: "grid",
|
|
43484
43745
|
subtitleKey: "kind"
|
|
43746
|
+
},
|
|
43747
|
+
console: {
|
|
43748
|
+
key: "console",
|
|
43749
|
+
label: "Consoles",
|
|
43750
|
+
itemNoun: "console",
|
|
43751
|
+
statuses: ["want", "doing", "have", "done"],
|
|
43752
|
+
statusLabels: { want: "Wanted", doing: "Hooked up", have: "In the cupboard", done: "Retired" },
|
|
43753
|
+
facetSchema: consoleFacetSchema,
|
|
43754
|
+
view: "grid",
|
|
43755
|
+
subtitleKey: "model"
|
|
43485
43756
|
}
|
|
43486
43757
|
};
|
|
43487
43758
|
var COLLECTION_TYPE_LIST = collectionTypeValues.map((k) => COLLECTION_TYPES[k]);
|
|
@@ -47095,6 +47366,106 @@ var commands9 = [
|
|
|
47095
47366
|
return { data: types, render: renderList };
|
|
47096
47367
|
}
|
|
47097
47368
|
},
|
|
47369
|
+
{
|
|
47370
|
+
spec: {
|
|
47371
|
+
path: ["collection", "kinds"],
|
|
47372
|
+
summary: "List the Space's own kinds (vinyl, board games, \u2026) with their fields and words.",
|
|
47373
|
+
args: [],
|
|
47374
|
+
flags: [],
|
|
47375
|
+
scopes: [...collectionOperations.listKinds.scopes],
|
|
47376
|
+
returns: "CollectionKind[]",
|
|
47377
|
+
notes: `${routeOf(collectionOperations.listKinds)}. Each kind's \`key\` is what an Item of it carries as its \`type\`.`
|
|
47378
|
+
},
|
|
47379
|
+
run: async ({ requireClient }) => ({
|
|
47380
|
+
data: await requireClient().getPage(pathOf(collectionOperations.listKinds)),
|
|
47381
|
+
render: renderList
|
|
47382
|
+
})
|
|
47383
|
+
},
|
|
47384
|
+
{
|
|
47385
|
+
spec: {
|
|
47386
|
+
path: ["collection", "kind"],
|
|
47387
|
+
summary: "One of the Space's own kinds.",
|
|
47388
|
+
args: [{ name: "id", required: true, description: "Kind ULID." }],
|
|
47389
|
+
flags: [],
|
|
47390
|
+
scopes: [...collectionOperations.getKind.scopes],
|
|
47391
|
+
returns: "CollectionKind",
|
|
47392
|
+
notes: `${routeOf(collectionOperations.getKind)}.`
|
|
47393
|
+
},
|
|
47394
|
+
run: readOperation(collectionOperations.getKind, renderRecord, { kindId: "kind id" })
|
|
47395
|
+
},
|
|
47396
|
+
{
|
|
47397
|
+
spec: {
|
|
47398
|
+
path: ["collection", "kind-add"],
|
|
47399
|
+
summary: "Add a kind: from a preset (lego, vinyl, board, custom) or from scratch.",
|
|
47400
|
+
args: [{ name: "name", required: true, description: 'Its name ("Vinyl").' }],
|
|
47401
|
+
flags: [
|
|
47402
|
+
{
|
|
47403
|
+
name: "preset",
|
|
47404
|
+
type: "string",
|
|
47405
|
+
description: `Start from ${Object.keys(COLLECTION_KIND_PRESETS).join(", ")}; what's left out comes from it.`
|
|
47406
|
+
},
|
|
47407
|
+
{
|
|
47408
|
+
name: "data",
|
|
47409
|
+
type: "string",
|
|
47410
|
+
description: 'More JSON: `{ "key": "\u2026", "one": "record", "many": "records", "icon": "disc", "fields": [{ "key": "artist", "label": "Artist", "type": "text" }], "statusWords": { \u2026 } }`. The id is minted.'
|
|
47411
|
+
}
|
|
47412
|
+
],
|
|
47413
|
+
scopes: [...collectionOperations.createKind.scopes],
|
|
47414
|
+
returns: "CollectionKind",
|
|
47415
|
+
notes: `${routeOf(collectionOperations.createKind)}. The key is the name's slug unless given; a key the Space has is a 409. \`do collection kind-add Vinyl --preset vinyl\`.`
|
|
47416
|
+
},
|
|
47417
|
+
run: async ({ args, flags, requireClient }) => {
|
|
47418
|
+
const name = requireArg(args, 0, "name");
|
|
47419
|
+
const preset = flagString(flags, "preset");
|
|
47420
|
+
if (preset)
|
|
47421
|
+
parseInput(collectionKindPresetSchema, preset);
|
|
47422
|
+
const body = parseInput(createCollectionKindInputSchema, {
|
|
47423
|
+
id: ulid3(),
|
|
47424
|
+
name,
|
|
47425
|
+
...preset ? { preset } : {},
|
|
47426
|
+
...readDataFlag(flags)
|
|
47427
|
+
});
|
|
47428
|
+
return {
|
|
47429
|
+
data: await requireClient().post(pathOf(collectionOperations.createKind), body),
|
|
47430
|
+
render: renderRecord
|
|
47431
|
+
};
|
|
47432
|
+
}
|
|
47433
|
+
},
|
|
47434
|
+
{
|
|
47435
|
+
spec: {
|
|
47436
|
+
path: ["collection", "kind-update"],
|
|
47437
|
+
summary: "Change a kind: its name, one/many, icon, fields or status words (the key stays).",
|
|
47438
|
+
args: [{ name: "id", required: true, description: "Kind ULID." }],
|
|
47439
|
+
flags: [{ name: "data", type: "string", description: "UpdateCollectionKindInput JSON." }],
|
|
47440
|
+
scopes: [...collectionOperations.updateKind.scopes],
|
|
47441
|
+
returns: "CollectionKind",
|
|
47442
|
+
notes: `${routeOf(collectionOperations.updateKind)}. \`fields\` replaces the list.`
|
|
47443
|
+
},
|
|
47444
|
+
run: async ({ args, flags, requireClient }) => {
|
|
47445
|
+
const kindId = requireArg(args, 0, "kind id");
|
|
47446
|
+
const body = parseInput(updateCollectionKindInputSchema, readDataFlag(flags));
|
|
47447
|
+
return {
|
|
47448
|
+
data: await requireClient().patch(pathOf(collectionOperations.updateKind, { kindId }), body),
|
|
47449
|
+
render: renderRecord
|
|
47450
|
+
};
|
|
47451
|
+
}
|
|
47452
|
+
},
|
|
47453
|
+
{
|
|
47454
|
+
spec: {
|
|
47455
|
+
path: ["collection", "kind-remove"],
|
|
47456
|
+
summary: "Remove a kind that has no Items.",
|
|
47457
|
+
args: [{ name: "id", required: true, description: "Kind ULID." }],
|
|
47458
|
+
flags: [],
|
|
47459
|
+
scopes: [...collectionOperations.removeKind.scopes],
|
|
47460
|
+
returns: "void",
|
|
47461
|
+
notes: `${routeOf(collectionOperations.removeKind)}. A 409 while it still has Items.`
|
|
47462
|
+
},
|
|
47463
|
+
run: async ({ args, requireClient }) => {
|
|
47464
|
+
const kindId = requireArg(args, 0, "kind id");
|
|
47465
|
+
await requireClient().delete(pathOf(collectionOperations.removeKind, { kindId }));
|
|
47466
|
+
return { data: { ok: true, kindId }, render: renderRecord };
|
|
47467
|
+
}
|
|
47468
|
+
},
|
|
47098
47469
|
{
|
|
47099
47470
|
spec: {
|
|
47100
47471
|
path: ["collection", "list"],
|
package/package.json
CHANGED