@robbeverhelst/do 1.393.0 → 1.394.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 +286 -182
- 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.394.0";
|
|
14424
14424
|
var API_PREFIX = "/api/v1";
|
|
14425
14425
|
var DEFAULT_API_URL = "http://localhost:3001";
|
|
14426
14426
|
|
|
@@ -20637,6 +20637,25 @@ var files = pgTable("files", {
|
|
|
20637
20637
|
index("files_owner_idx").on(t.ownerNodeId, t.createdAt)
|
|
20638
20638
|
]);
|
|
20639
20639
|
|
|
20640
|
+
// ../../packages/schema/src/db/inventory.ts
|
|
20641
|
+
var inventoryItems = pgTable("inventory_items", {
|
|
20642
|
+
...leafColumns(),
|
|
20643
|
+
productId: text("product_id").references(() => products.id),
|
|
20644
|
+
quantity: doublePrecision("quantity").notNull().default(0),
|
|
20645
|
+
unit: text("unit"),
|
|
20646
|
+
category: text("category"),
|
|
20647
|
+
location: text("location"),
|
|
20648
|
+
lowStockThreshold: doublePrecision("low_stock_threshold"),
|
|
20649
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
20650
|
+
notes: text("notes"),
|
|
20651
|
+
facet: jsonb("facet").$type(),
|
|
20652
|
+
placeId: text("place_id").references(() => places.id, { onDelete: "set null" })
|
|
20653
|
+
}, (t) => [
|
|
20654
|
+
index("inventory_items_tenant_place_idx").on(t.tenantId, t.placeId),
|
|
20655
|
+
index("inventory_items_tenant_idx").on(t.tenantId),
|
|
20656
|
+
index("inventory_items_product_idx").on(t.productId)
|
|
20657
|
+
]);
|
|
20658
|
+
|
|
20640
20659
|
// ../../packages/schema/src/db/periods.ts
|
|
20641
20660
|
var periodKind = pgEnum("period_kind", [
|
|
20642
20661
|
"hibernation",
|
|
@@ -20801,6 +20820,21 @@ var animalHandoverNotes = pgTable("animal_handover_notes", {
|
|
|
20801
20820
|
photoFileId: text("photo_file_id").references(() => files.id, { onDelete: "set null" }),
|
|
20802
20821
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
20803
20822
|
}, (t) => [index("animal_handover_notes_period_idx").on(t.tenantId, t.periodId)]);
|
|
20823
|
+
var animalFeedings = pgTable("animal_feedings", {
|
|
20824
|
+
id: text("id").primaryKey(),
|
|
20825
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
20826
|
+
animalId: text("animal_id").notNull().references(() => animals.id, { onDelete: "cascade" }),
|
|
20827
|
+
supplyId: text("supply_id").notNull().references(() => inventoryItems.id, { onDelete: "cascade" }),
|
|
20828
|
+
what: text("what"),
|
|
20829
|
+
amount: text("amount"),
|
|
20830
|
+
times: text("times"),
|
|
20831
|
+
note: text("note"),
|
|
20832
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
20833
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
20834
|
+
}, (t) => [
|
|
20835
|
+
unique("animal_feedings_animal_supply_uniq").on(t.tenantId, t.animalId, t.supplyId),
|
|
20836
|
+
index("animal_feedings_supply_idx").on(t.tenantId, t.supplyId)
|
|
20837
|
+
]);
|
|
20804
20838
|
var animalMedicineEveryUnit = pgEnum("animal_medicine_every_unit", [
|
|
20805
20839
|
"day",
|
|
20806
20840
|
"week",
|
|
@@ -21253,6 +21287,21 @@ var animalHabitSchema = nodeRefSchema.extend({
|
|
|
21253
21287
|
routine: string2().nullable().optional(),
|
|
21254
21288
|
animalIds: array(ulidSchema).default([])
|
|
21255
21289
|
});
|
|
21290
|
+
var animalFeedingSchema = object({
|
|
21291
|
+
animalId: ulidSchema,
|
|
21292
|
+
supplyId: ulidSchema,
|
|
21293
|
+
what: string2().nullable(),
|
|
21294
|
+
amount: string2().nullable(),
|
|
21295
|
+
times: string2().nullable(),
|
|
21296
|
+
note: string2().nullable()
|
|
21297
|
+
});
|
|
21298
|
+
var feedingText = (max) => string2().trim().min(1).max(max).nullish();
|
|
21299
|
+
var animalFeedingInputSchema = object({
|
|
21300
|
+
what: feedingText(120),
|
|
21301
|
+
amount: feedingText(60),
|
|
21302
|
+
times: feedingText(80),
|
|
21303
|
+
note: feedingText(200)
|
|
21304
|
+
}).strict();
|
|
21256
21305
|
var animalSupplySchema = nodeRefSchema.extend({
|
|
21257
21306
|
quantity: number2(),
|
|
21258
21307
|
unit: string2().nullable(),
|
|
@@ -21262,7 +21311,8 @@ var animalSupplySchema = nodeRefSchema.extend({
|
|
|
21262
21311
|
daysLeft: number2().int().nullable(),
|
|
21263
21312
|
full: number2().nullable(),
|
|
21264
21313
|
onList: string2().nullable(),
|
|
21265
|
-
animalIds: array(ulidSchema).optional()
|
|
21314
|
+
animalIds: array(ulidSchema).optional(),
|
|
21315
|
+
feedings: array(animalFeedingSchema).optional()
|
|
21266
21316
|
});
|
|
21267
21317
|
var animalDayCountSchema = object({ day: string2(), count: number2().int() });
|
|
21268
21318
|
var animalWeightPointSchema = object({
|
|
@@ -22124,6 +22174,29 @@ var animalOperations = defineOperations({
|
|
|
22124
22174
|
response: { description: "The timeline entries." },
|
|
22125
22175
|
errors: { 404: true }
|
|
22126
22176
|
},
|
|
22177
|
+
setFeeding: {
|
|
22178
|
+
method: "put",
|
|
22179
|
+
path: "/animals/{id}/feeding/{supplyId}",
|
|
22180
|
+
scopes: WRITE,
|
|
22181
|
+
tag: "Animals",
|
|
22182
|
+
summary: "Say how an animal is fed from a supply",
|
|
22183
|
+
description: "What it gets (`what`, when it's more than the supply's name), how much (`amount`, \"2 \xD7 110 g\"), when (`times`, \"07:30 and 18:00\") and a line for whoever feeds it (`note`), each as written. A field left out stays; `null` clears it. Links the supply (a Household item) to the animal when it doesn't feed it yet. Read back on the animal's and the overview's supplies, as `feedings`.",
|
|
22184
|
+
body: animalFeedingInputSchema,
|
|
22185
|
+
status: 200,
|
|
22186
|
+
response: { description: "The feeding." },
|
|
22187
|
+
errors: { 400: true, 404: true }
|
|
22188
|
+
},
|
|
22189
|
+
removeFeeding: {
|
|
22190
|
+
method: "delete",
|
|
22191
|
+
path: "/animals/{id}/feeding/{supplyId}",
|
|
22192
|
+
scopes: WRITE,
|
|
22193
|
+
tag: "Animals",
|
|
22194
|
+
summary: "Take an animal's feeding off a supply",
|
|
22195
|
+
description: "The supply still feeds it; only what was said about how is gone.",
|
|
22196
|
+
status: 204,
|
|
22197
|
+
response: { description: "Gone." },
|
|
22198
|
+
errors: { 404: true }
|
|
22199
|
+
},
|
|
22127
22200
|
lostCard: {
|
|
22128
22201
|
method: "get",
|
|
22129
22202
|
path: "/animals/{id}/lost-card",
|
|
@@ -24174,6 +24247,163 @@ var collectionEntryKindValues = [
|
|
|
24174
24247
|
];
|
|
24175
24248
|
var collectionEntryKindSchema = _enum2(collectionEntryKindValues);
|
|
24176
24249
|
|
|
24250
|
+
// ../../packages/schema/src/contracts/collection-kinds.ts
|
|
24251
|
+
var collectionKindFieldTypeValues = [
|
|
24252
|
+
"text",
|
|
24253
|
+
"number",
|
|
24254
|
+
"choice",
|
|
24255
|
+
"year",
|
|
24256
|
+
"date",
|
|
24257
|
+
"yesno"
|
|
24258
|
+
];
|
|
24259
|
+
var collectionKindFieldTypeSchema = _enum2(collectionKindFieldTypeValues);
|
|
24260
|
+
var collectionKindIconValues = [
|
|
24261
|
+
"disc",
|
|
24262
|
+
"dice",
|
|
24263
|
+
"brick",
|
|
24264
|
+
"book",
|
|
24265
|
+
"pad",
|
|
24266
|
+
"sprout",
|
|
24267
|
+
"paw",
|
|
24268
|
+
"tag"
|
|
24269
|
+
];
|
|
24270
|
+
var collectionKindIconSchema = _enum2(collectionKindIconValues);
|
|
24271
|
+
var collectionKindPresetValues = ["lego", "vinyl", "board", "custom"];
|
|
24272
|
+
var collectionKindPresetSchema = _enum2(collectionKindPresetValues);
|
|
24273
|
+
var slug = string2().min(1).max(40).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "lowercase letters and digits, dashes between");
|
|
24274
|
+
var collectionKindKeySchema = slug.refine((k) => !collectionTypeValues.includes(k), "that's a built-in kind");
|
|
24275
|
+
var collectionKindFieldSchema = object({
|
|
24276
|
+
key: slug,
|
|
24277
|
+
label: string2().trim().min(1).max(40),
|
|
24278
|
+
type: collectionKindFieldTypeSchema,
|
|
24279
|
+
choices: array(string2().trim().min(1).max(40)).max(30).optional()
|
|
24280
|
+
}).strict().refine((f) => f.type === "choice" || f.choices === undefined, {
|
|
24281
|
+
message: "only a choice field has choices",
|
|
24282
|
+
path: ["choices"]
|
|
24283
|
+
});
|
|
24284
|
+
var collectionKindFieldsSchema = array(collectionKindFieldSchema).max(12).refine((fs) => new Set(fs.map((f) => f.key)).size === fs.length, "each field key once");
|
|
24285
|
+
var word = string2().trim().min(1).max(30);
|
|
24286
|
+
var collectionKindStatusWordsSchema = object({ want: word, have: word, doing: word, done: word, dropped: word }).strict();
|
|
24287
|
+
var collectionKindSchema = object({
|
|
24288
|
+
id: ulidSchema,
|
|
24289
|
+
key: string2(),
|
|
24290
|
+
name: string2(),
|
|
24291
|
+
one: string2(),
|
|
24292
|
+
many: string2(),
|
|
24293
|
+
icon: string2(),
|
|
24294
|
+
preset: string2().nullable(),
|
|
24295
|
+
fields: array(object({
|
|
24296
|
+
key: string2(),
|
|
24297
|
+
label: string2(),
|
|
24298
|
+
type: string2(),
|
|
24299
|
+
choices: array(string2()).optional()
|
|
24300
|
+
})),
|
|
24301
|
+
statusWords: collectionKindStatusWordsSchema,
|
|
24302
|
+
view: string2(),
|
|
24303
|
+
itemCount: number2().int(),
|
|
24304
|
+
createdAt: exports_coerce.date(),
|
|
24305
|
+
updatedAt: exports_coerce.date()
|
|
24306
|
+
});
|
|
24307
|
+
var name2 = string2().trim().min(1).max(40);
|
|
24308
|
+
var createCollectionKindInputSchema = object({
|
|
24309
|
+
id: ulidSchema,
|
|
24310
|
+
name: name2,
|
|
24311
|
+
key: collectionKindKeySchema.optional(),
|
|
24312
|
+
one: name2.optional(),
|
|
24313
|
+
many: name2.optional(),
|
|
24314
|
+
icon: collectionKindIconSchema.optional(),
|
|
24315
|
+
preset: collectionKindPresetSchema.optional(),
|
|
24316
|
+
fields: collectionKindFieldsSchema.optional(),
|
|
24317
|
+
statusWords: collectionKindStatusWordsSchema.optional()
|
|
24318
|
+
}).strict();
|
|
24319
|
+
var updateCollectionKindInputSchema = object({
|
|
24320
|
+
name: name2.optional(),
|
|
24321
|
+
one: name2.optional(),
|
|
24322
|
+
many: name2.optional(),
|
|
24323
|
+
icon: collectionKindIconSchema.optional(),
|
|
24324
|
+
fields: collectionKindFieldsSchema.optional(),
|
|
24325
|
+
statusWords: collectionKindStatusWordsSchema.optional()
|
|
24326
|
+
}).strict();
|
|
24327
|
+
var f = (label, type) => ({
|
|
24328
|
+
key: kindSlug(label),
|
|
24329
|
+
label,
|
|
24330
|
+
type
|
|
24331
|
+
});
|
|
24332
|
+
var COLLECTION_KIND_PRESETS = {
|
|
24333
|
+
lego: {
|
|
24334
|
+
name: "LEGO",
|
|
24335
|
+
one: "set",
|
|
24336
|
+
icon: "brick",
|
|
24337
|
+
fields: [
|
|
24338
|
+
f("Set number", "text"),
|
|
24339
|
+
f("Pieces", "number"),
|
|
24340
|
+
f("Theme", "choice"),
|
|
24341
|
+
f("Bags", "number"),
|
|
24342
|
+
f("Minifigures", "number"),
|
|
24343
|
+
f("Released", "year")
|
|
24344
|
+
],
|
|
24345
|
+
statusWords: {
|
|
24346
|
+
want: "Want",
|
|
24347
|
+
have: "In the box",
|
|
24348
|
+
doing: "Building",
|
|
24349
|
+
done: "Built",
|
|
24350
|
+
dropped: "Parted out"
|
|
24351
|
+
}
|
|
24352
|
+
},
|
|
24353
|
+
vinyl: {
|
|
24354
|
+
name: "Vinyl",
|
|
24355
|
+
one: "record",
|
|
24356
|
+
icon: "disc",
|
|
24357
|
+
fields: [
|
|
24358
|
+
f("Artist", "text"),
|
|
24359
|
+
f("Label", "choice"),
|
|
24360
|
+
f("Pressing", "text"),
|
|
24361
|
+
f("Speed", "number"),
|
|
24362
|
+
f("Condition", "choice"),
|
|
24363
|
+
f("Released", "year")
|
|
24364
|
+
],
|
|
24365
|
+
statusWords: {
|
|
24366
|
+
want: "Want",
|
|
24367
|
+
have: "Have",
|
|
24368
|
+
doing: "On rotation",
|
|
24369
|
+
done: "Played out",
|
|
24370
|
+
dropped: "Sold"
|
|
24371
|
+
}
|
|
24372
|
+
},
|
|
24373
|
+
board: {
|
|
24374
|
+
name: "Board games",
|
|
24375
|
+
one: "board game",
|
|
24376
|
+
icon: "dice",
|
|
24377
|
+
fields: [
|
|
24378
|
+
f("Players", "number"),
|
|
24379
|
+
f("Play time", "text"),
|
|
24380
|
+
f("Designer", "text"),
|
|
24381
|
+
f("Expansions", "text"),
|
|
24382
|
+
f("Plays", "number"),
|
|
24383
|
+
f("Released", "year")
|
|
24384
|
+
],
|
|
24385
|
+
statusWords: {
|
|
24386
|
+
want: "Want",
|
|
24387
|
+
have: "Have",
|
|
24388
|
+
doing: "Learning",
|
|
24389
|
+
done: "Played",
|
|
24390
|
+
dropped: "Gave away"
|
|
24391
|
+
}
|
|
24392
|
+
},
|
|
24393
|
+
custom: {
|
|
24394
|
+
name: "",
|
|
24395
|
+
one: "",
|
|
24396
|
+
icon: "tag",
|
|
24397
|
+
fields: [f("Maker", "text"), f("Year", "year"), f("Condition", "choice")],
|
|
24398
|
+
statusWords: { want: "Want", have: "Have", doing: "Using", done: "Done", dropped: "Gone" }
|
|
24399
|
+
}
|
|
24400
|
+
};
|
|
24401
|
+
function kindSlug(name) {
|
|
24402
|
+
const s = name.toLowerCase().normalize("NFKD").replace(/[\u0300-\u036F]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40).replace(/-+$/, "");
|
|
24403
|
+
return s || "kind";
|
|
24404
|
+
}
|
|
24405
|
+
var kindCoverUrl = string2().url().max(2048);
|
|
24406
|
+
|
|
24177
24407
|
// ../../packages/schema/src/contracts/collection.ts
|
|
24178
24408
|
var collectionRatingSchema = number2().min(0.5).max(5).step(0.5, "must be a whole or half star (0.5 steps)");
|
|
24179
24409
|
var collectionFacetSchema = record(string2(), unknown());
|
|
@@ -24197,7 +24427,7 @@ var collectionItemSchema = createSelectSchema(collectionItems, {
|
|
|
24197
24427
|
});
|
|
24198
24428
|
var createCollectionItemInputSchema = createInsertSchema(collectionItems, {
|
|
24199
24429
|
id: ulidSchema,
|
|
24200
|
-
type: collectionTypeSchema,
|
|
24430
|
+
type: union([collectionTypeSchema, collectionKindKeySchema]),
|
|
24201
24431
|
status: collectionStatusSchema.optional(),
|
|
24202
24432
|
quantity: number2().min(0).nullish(),
|
|
24203
24433
|
areaId: ulidSchema.nullish(),
|
|
@@ -26346,162 +26576,6 @@ var circleOperations = defineOperations({
|
|
|
26346
26576
|
})
|
|
26347
26577
|
});
|
|
26348
26578
|
|
|
26349
|
-
// ../../packages/schema/src/contracts/collection-kinds.ts
|
|
26350
|
-
var collectionKindFieldTypeValues = [
|
|
26351
|
-
"text",
|
|
26352
|
-
"number",
|
|
26353
|
-
"choice",
|
|
26354
|
-
"year",
|
|
26355
|
-
"date",
|
|
26356
|
-
"yesno"
|
|
26357
|
-
];
|
|
26358
|
-
var collectionKindFieldTypeSchema = _enum2(collectionKindFieldTypeValues);
|
|
26359
|
-
var collectionKindIconValues = [
|
|
26360
|
-
"disc",
|
|
26361
|
-
"dice",
|
|
26362
|
-
"brick",
|
|
26363
|
-
"book",
|
|
26364
|
-
"pad",
|
|
26365
|
-
"sprout",
|
|
26366
|
-
"paw",
|
|
26367
|
-
"tag"
|
|
26368
|
-
];
|
|
26369
|
-
var collectionKindIconSchema = _enum2(collectionKindIconValues);
|
|
26370
|
-
var collectionKindPresetValues = ["lego", "vinyl", "board", "custom"];
|
|
26371
|
-
var collectionKindPresetSchema = _enum2(collectionKindPresetValues);
|
|
26372
|
-
var slug = string2().min(1).max(40).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "lowercase letters and digits, dashes between");
|
|
26373
|
-
var collectionKindKeySchema = slug.refine((k) => !collectionTypeValues.includes(k), "that's a built-in kind");
|
|
26374
|
-
var collectionKindFieldSchema = object({
|
|
26375
|
-
key: slug,
|
|
26376
|
-
label: string2().trim().min(1).max(40),
|
|
26377
|
-
type: collectionKindFieldTypeSchema,
|
|
26378
|
-
choices: array(string2().trim().min(1).max(40)).max(30).optional()
|
|
26379
|
-
}).strict().refine((f) => f.type === "choice" || f.choices === undefined, {
|
|
26380
|
-
message: "only a choice field has choices",
|
|
26381
|
-
path: ["choices"]
|
|
26382
|
-
});
|
|
26383
|
-
var collectionKindFieldsSchema = array(collectionKindFieldSchema).max(12).refine((fs) => new Set(fs.map((f) => f.key)).size === fs.length, "each field key once");
|
|
26384
|
-
var word = string2().trim().min(1).max(30);
|
|
26385
|
-
var collectionKindStatusWordsSchema = object({ want: word, have: word, doing: word, done: word, dropped: word }).strict();
|
|
26386
|
-
var collectionKindSchema = object({
|
|
26387
|
-
id: ulidSchema,
|
|
26388
|
-
key: string2(),
|
|
26389
|
-
name: string2(),
|
|
26390
|
-
one: string2(),
|
|
26391
|
-
many: string2(),
|
|
26392
|
-
icon: string2(),
|
|
26393
|
-
preset: string2().nullable(),
|
|
26394
|
-
fields: array(object({
|
|
26395
|
-
key: string2(),
|
|
26396
|
-
label: string2(),
|
|
26397
|
-
type: string2(),
|
|
26398
|
-
choices: array(string2()).optional()
|
|
26399
|
-
})),
|
|
26400
|
-
statusWords: collectionKindStatusWordsSchema,
|
|
26401
|
-
view: string2(),
|
|
26402
|
-
itemCount: number2().int(),
|
|
26403
|
-
createdAt: exports_coerce.date(),
|
|
26404
|
-
updatedAt: exports_coerce.date()
|
|
26405
|
-
});
|
|
26406
|
-
var name2 = string2().trim().min(1).max(40);
|
|
26407
|
-
var createCollectionKindInputSchema = object({
|
|
26408
|
-
id: ulidSchema,
|
|
26409
|
-
name: name2,
|
|
26410
|
-
key: collectionKindKeySchema.optional(),
|
|
26411
|
-
one: name2.optional(),
|
|
26412
|
-
many: name2.optional(),
|
|
26413
|
-
icon: collectionKindIconSchema.optional(),
|
|
26414
|
-
preset: collectionKindPresetSchema.optional(),
|
|
26415
|
-
fields: collectionKindFieldsSchema.optional(),
|
|
26416
|
-
statusWords: collectionKindStatusWordsSchema.optional()
|
|
26417
|
-
}).strict();
|
|
26418
|
-
var updateCollectionKindInputSchema = object({
|
|
26419
|
-
name: name2.optional(),
|
|
26420
|
-
one: name2.optional(),
|
|
26421
|
-
many: name2.optional(),
|
|
26422
|
-
icon: collectionKindIconSchema.optional(),
|
|
26423
|
-
fields: collectionKindFieldsSchema.optional(),
|
|
26424
|
-
statusWords: collectionKindStatusWordsSchema.optional()
|
|
26425
|
-
}).strict();
|
|
26426
|
-
var f = (label, type) => ({
|
|
26427
|
-
key: kindSlug(label),
|
|
26428
|
-
label,
|
|
26429
|
-
type
|
|
26430
|
-
});
|
|
26431
|
-
var COLLECTION_KIND_PRESETS = {
|
|
26432
|
-
lego: {
|
|
26433
|
-
name: "LEGO",
|
|
26434
|
-
one: "set",
|
|
26435
|
-
icon: "brick",
|
|
26436
|
-
fields: [
|
|
26437
|
-
f("Set number", "text"),
|
|
26438
|
-
f("Pieces", "number"),
|
|
26439
|
-
f("Theme", "choice"),
|
|
26440
|
-
f("Bags", "number"),
|
|
26441
|
-
f("Minifigures", "number"),
|
|
26442
|
-
f("Released", "year")
|
|
26443
|
-
],
|
|
26444
|
-
statusWords: {
|
|
26445
|
-
want: "Want",
|
|
26446
|
-
have: "In the box",
|
|
26447
|
-
doing: "Building",
|
|
26448
|
-
done: "Built",
|
|
26449
|
-
dropped: "Parted out"
|
|
26450
|
-
}
|
|
26451
|
-
},
|
|
26452
|
-
vinyl: {
|
|
26453
|
-
name: "Vinyl",
|
|
26454
|
-
one: "record",
|
|
26455
|
-
icon: "disc",
|
|
26456
|
-
fields: [
|
|
26457
|
-
f("Artist", "text"),
|
|
26458
|
-
f("Label", "choice"),
|
|
26459
|
-
f("Pressing", "text"),
|
|
26460
|
-
f("Speed", "number"),
|
|
26461
|
-
f("Condition", "choice"),
|
|
26462
|
-
f("Released", "year")
|
|
26463
|
-
],
|
|
26464
|
-
statusWords: {
|
|
26465
|
-
want: "Want",
|
|
26466
|
-
have: "Have",
|
|
26467
|
-
doing: "On rotation",
|
|
26468
|
-
done: "Played out",
|
|
26469
|
-
dropped: "Sold"
|
|
26470
|
-
}
|
|
26471
|
-
},
|
|
26472
|
-
board: {
|
|
26473
|
-
name: "Board games",
|
|
26474
|
-
one: "board game",
|
|
26475
|
-
icon: "dice",
|
|
26476
|
-
fields: [
|
|
26477
|
-
f("Players", "number"),
|
|
26478
|
-
f("Play time", "text"),
|
|
26479
|
-
f("Designer", "text"),
|
|
26480
|
-
f("Expansions", "text"),
|
|
26481
|
-
f("Plays", "number"),
|
|
26482
|
-
f("Released", "year")
|
|
26483
|
-
],
|
|
26484
|
-
statusWords: {
|
|
26485
|
-
want: "Want",
|
|
26486
|
-
have: "Have",
|
|
26487
|
-
doing: "Learning",
|
|
26488
|
-
done: "Played",
|
|
26489
|
-
dropped: "Gave away"
|
|
26490
|
-
}
|
|
26491
|
-
},
|
|
26492
|
-
custom: {
|
|
26493
|
-
name: "",
|
|
26494
|
-
one: "",
|
|
26495
|
-
icon: "tag",
|
|
26496
|
-
fields: [f("Maker", "text"), f("Year", "year"), f("Condition", "choice")],
|
|
26497
|
-
statusWords: { want: "Want", have: "Have", doing: "Using", done: "Done", dropped: "Gone" }
|
|
26498
|
-
}
|
|
26499
|
-
};
|
|
26500
|
-
function kindSlug(name) {
|
|
26501
|
-
const s = name.toLowerCase().normalize("NFKD").replace(/[\u0300-\u036F]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40).replace(/-+$/, "");
|
|
26502
|
-
return s || "kind";
|
|
26503
|
-
}
|
|
26504
|
-
|
|
26505
26579
|
// ../../packages/schema/src/contracts/pagination.ts
|
|
26506
26580
|
var paginationQuerySchema = object({
|
|
26507
26581
|
limit: exports_coerce.number().int().positive().optional(),
|
|
@@ -34368,25 +34442,6 @@ var incidentOperations = defineOperations({
|
|
|
34368
34442
|
})
|
|
34369
34443
|
});
|
|
34370
34444
|
|
|
34371
|
-
// ../../packages/schema/src/db/inventory.ts
|
|
34372
|
-
var inventoryItems = pgTable("inventory_items", {
|
|
34373
|
-
...leafColumns(),
|
|
34374
|
-
productId: text("product_id").references(() => products.id),
|
|
34375
|
-
quantity: doublePrecision("quantity").notNull().default(0),
|
|
34376
|
-
unit: text("unit"),
|
|
34377
|
-
category: text("category"),
|
|
34378
|
-
location: text("location"),
|
|
34379
|
-
lowStockThreshold: doublePrecision("low_stock_threshold"),
|
|
34380
|
-
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
34381
|
-
notes: text("notes"),
|
|
34382
|
-
facet: jsonb("facet").$type(),
|
|
34383
|
-
placeId: text("place_id").references(() => places.id, { onDelete: "set null" })
|
|
34384
|
-
}, (t) => [
|
|
34385
|
-
index("inventory_items_tenant_place_idx").on(t.tenantId, t.placeId),
|
|
34386
|
-
index("inventory_items_tenant_idx").on(t.tenantId),
|
|
34387
|
-
index("inventory_items_product_idx").on(t.productId)
|
|
34388
|
-
]);
|
|
34389
|
-
|
|
34390
34445
|
// ../../packages/schema/src/presets/facets.ts
|
|
34391
34446
|
var PANTRY_DISPLAY_KIND = "pantry";
|
|
34392
34447
|
var MEDS_DISPLAY_KIND = "meds";
|
|
@@ -46653,6 +46708,55 @@ var commands2 = [
|
|
|
46653
46708
|
};
|
|
46654
46709
|
}
|
|
46655
46710
|
},
|
|
46711
|
+
{
|
|
46712
|
+
spec: {
|
|
46713
|
+
path: ["animals", "feeding-set"],
|
|
46714
|
+
summary: "Say how an animal is fed from a supply: what, how much, when, a note.",
|
|
46715
|
+
args: [
|
|
46716
|
+
{ name: "id", required: true, description: "Animal ULID." },
|
|
46717
|
+
{ name: "supplyId", required: true, description: "Supply (Household item) ULID." }
|
|
46718
|
+
],
|
|
46719
|
+
flags: [
|
|
46720
|
+
{
|
|
46721
|
+
name: "data",
|
|
46722
|
+
type: "string",
|
|
46723
|
+
description: 'JSON: `{ "amount": "2 \xD7 110 g", "times": "07:30 and 18:00", "what": "\u2026", "note": "\u2026" }`; null clears a field.'
|
|
46724
|
+
}
|
|
46725
|
+
],
|
|
46726
|
+
scopes: [...animalOperations.setFeeding.scopes],
|
|
46727
|
+
returns: "AnimalFeeding",
|
|
46728
|
+
notes: `${routeOf(animalOperations.setFeeding)}. Each field as written; one left out stays. Links the supply to the animal when it doesn't feed it yet. Read back as \`feedings\` on the animal's supplies.`
|
|
46729
|
+
},
|
|
46730
|
+
run: async ({ args, flags, requireClient }) => {
|
|
46731
|
+
const id = requireArg(args, 0, "animal id");
|
|
46732
|
+
const supplyId = requireArg(args, 1, "supply id");
|
|
46733
|
+
const body = parseInput(animalFeedingInputSchema, readDataFlag(flags));
|
|
46734
|
+
return {
|
|
46735
|
+
data: await requireClient().put(pathOf(animalOperations.setFeeding, { id, supplyId }), body),
|
|
46736
|
+
render: renderRecord
|
|
46737
|
+
};
|
|
46738
|
+
}
|
|
46739
|
+
},
|
|
46740
|
+
{
|
|
46741
|
+
spec: {
|
|
46742
|
+
path: ["animals", "feeding-off"],
|
|
46743
|
+
summary: "Take an animal's feeding off a supply (the supply still feeds it).",
|
|
46744
|
+
args: [
|
|
46745
|
+
{ name: "id", required: true, description: "Animal ULID." },
|
|
46746
|
+
{ name: "supplyId", required: true, description: "Supply (Household item) ULID." }
|
|
46747
|
+
],
|
|
46748
|
+
flags: [],
|
|
46749
|
+
scopes: [...animalOperations.removeFeeding.scopes],
|
|
46750
|
+
returns: "void",
|
|
46751
|
+
notes: `${routeOf(animalOperations.removeFeeding)}. Only what was said about how it's fed goes; the link stays.`
|
|
46752
|
+
},
|
|
46753
|
+
run: async ({ args, requireClient }) => {
|
|
46754
|
+
const id = requireArg(args, 0, "animal id");
|
|
46755
|
+
const supplyId = requireArg(args, 1, "supply id");
|
|
46756
|
+
await requireClient().delete(pathOf(animalOperations.removeFeeding, { id, supplyId }));
|
|
46757
|
+
return { data: { ok: true, animalId: id, supplyId }, render: renderRecord };
|
|
46758
|
+
}
|
|
46759
|
+
},
|
|
46656
46760
|
{
|
|
46657
46761
|
spec: {
|
|
46658
46762
|
path: ["animals", "acquisition"],
|
|
@@ -47877,12 +47981,12 @@ var commands9 = [
|
|
|
47877
47981
|
{
|
|
47878
47982
|
name: "type",
|
|
47879
47983
|
type: "string",
|
|
47880
|
-
description: "Type (book|film|game|music|place|wine|wardrobe|hobby)."
|
|
47984
|
+
description: "Type (book|film|game|music|place|wine|wardrobe|hobby), or a kind's key (`do collection kinds`)."
|
|
47881
47985
|
},
|
|
47882
47986
|
{
|
|
47883
47987
|
name: "status",
|
|
47884
47988
|
type: "string",
|
|
47885
|
-
description: "Initial status; defaults to the Type's first."
|
|
47989
|
+
description: "Initial status; defaults to the Type's first (a kind's: want)."
|
|
47886
47990
|
}
|
|
47887
47991
|
],
|
|
47888
47992
|
scopes: [...collectionOperations.create.scopes],
|
|
@@ -47890,13 +47994,13 @@ var commands9 = [
|
|
|
47890
47994
|
grammar: {
|
|
47891
47995
|
"#tag": "Adds a tag. Repeatable: '#scifi #2024'."
|
|
47892
47996
|
},
|
|
47893
|
-
notes:
|
|
47997
|
+
notes: `--type is required; the per-Type facet rides --data (validated server-side against the Type), e.g. \`do collection add "Castle" --type hobby --status doing --data '{"facet":{"kind":"LEGO","progress":{"done":7,"total":12,"unit":"bag"}}}'\`. An Item of one of the Space's own kinds takes its key as --type and answers its fields in the facet: \`do collection add "Harbour" --type vinyl --data '{"facet":{"artist":"Juniper"}}'\`.`
|
|
47894
47998
|
},
|
|
47895
47999
|
run: async ({ args, flags, requireClient }) => {
|
|
47896
48000
|
const { title, tags } = parseTitleTags(args);
|
|
47897
48001
|
if (title.length === 0)
|
|
47898
48002
|
throw usageError('collection add needs a title, e.g. `do collection add "Dune" --type book`');
|
|
47899
|
-
const type = requireFlag(flags, "type", "collection add needs --type <book|film|game|music|place|wine|wardrobe|hobby>");
|
|
48003
|
+
const type = requireFlag(flags, "type", "collection add needs --type <book|film|game|music|place|wine|wardrobe|hobby|a kind's key>");
|
|
47900
48004
|
const body = parseInput(createCollectionItemInputSchema, {
|
|
47901
48005
|
id: ulid3(),
|
|
47902
48006
|
...readDataFlag(flags),
|
package/package.json
CHANGED