@robbeverhelst/do 1.391.0 → 1.393.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 +719 -30
- 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.393.0";
|
|
14424
14424
|
var API_PREFIX = "/api/v1";
|
|
14425
14425
|
var DEFAULT_API_URL = "http://localhost:3001";
|
|
14426
14426
|
|
|
@@ -20801,6 +20801,49 @@ var animalHandoverNotes = pgTable("animal_handover_notes", {
|
|
|
20801
20801
|
photoFileId: text("photo_file_id").references(() => files.id, { onDelete: "set null" }),
|
|
20802
20802
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
20803
20803
|
}, (t) => [index("animal_handover_notes_period_idx").on(t.tenantId, t.periodId)]);
|
|
20804
|
+
var animalMedicineEveryUnit = pgEnum("animal_medicine_every_unit", [
|
|
20805
|
+
"day",
|
|
20806
|
+
"week",
|
|
20807
|
+
"month"
|
|
20808
|
+
]);
|
|
20809
|
+
var animalMedicines = pgTable("animal_medicines", {
|
|
20810
|
+
id: text("id").primaryKey(),
|
|
20811
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
20812
|
+
title: text("title").notNull(),
|
|
20813
|
+
dose: text("dose"),
|
|
20814
|
+
everyCount: integer2("every_count").notNull().default(1),
|
|
20815
|
+
everyUnit: animalMedicineEveryUnit("every_unit").notNull().default("day"),
|
|
20816
|
+
timeOfDay: text("time_of_day"),
|
|
20817
|
+
startsOn: date5("starts_on", { mode: "string" }),
|
|
20818
|
+
endsOn: date5("ends_on", { mode: "string" }),
|
|
20819
|
+
nextOn: date5("next_on", { mode: "string" }),
|
|
20820
|
+
stock: doublePrecision("stock"),
|
|
20821
|
+
unit: text("unit"),
|
|
20822
|
+
perDose: doublePrecision("per_dose").notNull().default(1),
|
|
20823
|
+
lowAt: doublePrecision("low_at"),
|
|
20824
|
+
note: text("note"),
|
|
20825
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
20826
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
20827
|
+
}, (t) => [index("animal_medicines_tenant_idx").on(t.tenantId)]);
|
|
20828
|
+
var animalMedicineAnimals = pgTable("animal_medicine_animals", {
|
|
20829
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
20830
|
+
medicineId: text("medicine_id").notNull().references(() => animalMedicines.id, { onDelete: "cascade" }),
|
|
20831
|
+
animalId: text("animal_id").notNull().references(() => animals.id, { onDelete: "cascade" })
|
|
20832
|
+
}, (t) => [
|
|
20833
|
+
primaryKey({ columns: [t.medicineId, t.animalId] }),
|
|
20834
|
+
index("animal_medicine_animals_animal_idx").on(t.tenantId, t.animalId)
|
|
20835
|
+
]);
|
|
20836
|
+
var animalMedicineDoses = pgTable("animal_medicine_doses", {
|
|
20837
|
+
id: text("id").primaryKey(),
|
|
20838
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
20839
|
+
medicineId: text("medicine_id").notNull().references(() => animalMedicines.id, { onDelete: "cascade" }),
|
|
20840
|
+
day: date5("day", { mode: "string" }).notNull(),
|
|
20841
|
+
givenAt: timestamp("given_at", { withTimezone: true }).notNull().defaultNow(),
|
|
20842
|
+
givenByUserId: text("given_by_user_id").references(() => users.id, { onDelete: "set null" }),
|
|
20843
|
+
took: doublePrecision("took").notNull().default(0),
|
|
20844
|
+
nextWas: date5("next_was", { mode: "string" }),
|
|
20845
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
20846
|
+
}, (t) => [unique("animal_medicine_doses_day_uniq").on(t.medicineId, t.day)]);
|
|
20804
20847
|
|
|
20805
20848
|
// ../../packages/schema/src/db/documents.ts
|
|
20806
20849
|
var documentKind = pgEnum("document_kind", [
|
|
@@ -21712,6 +21755,61 @@ var animalArrivedInputSchema = object({
|
|
|
21712
21755
|
on: keyDateDaySchema.optional(),
|
|
21713
21756
|
quarantineMonths: number2().int().min(0).max(12).optional()
|
|
21714
21757
|
}).strict();
|
|
21758
|
+
var animalMedicineEveryUnitSchema = _enum2(animalMedicineEveryUnit.enumValues);
|
|
21759
|
+
var animalMedicineViewSchema = object({
|
|
21760
|
+
id: ulidSchema,
|
|
21761
|
+
title: string2(),
|
|
21762
|
+
dose: string2().nullable(),
|
|
21763
|
+
everyCount: number2().int(),
|
|
21764
|
+
everyUnit: animalMedicineEveryUnitSchema,
|
|
21765
|
+
timeOfDay: string2().nullable(),
|
|
21766
|
+
startsOn: string2().nullable(),
|
|
21767
|
+
endsOn: string2().nullable(),
|
|
21768
|
+
nextOn: string2().nullable(),
|
|
21769
|
+
stock: number2().nullable(),
|
|
21770
|
+
unit: string2().nullable(),
|
|
21771
|
+
perDose: number2(),
|
|
21772
|
+
lowAt: number2().nullable(),
|
|
21773
|
+
note: string2().nullable(),
|
|
21774
|
+
animals: array(nodeRefSchema),
|
|
21775
|
+
daily: boolean2(),
|
|
21776
|
+
low: boolean2(),
|
|
21777
|
+
ended: boolean2(),
|
|
21778
|
+
course: object({ day: number2().int(), of: number2().int() }).nullable(),
|
|
21779
|
+
dueToday: boolean2(),
|
|
21780
|
+
doneToday: boolean2(),
|
|
21781
|
+
lastGivenOn: string2().nullable(),
|
|
21782
|
+
createdAt: exports_coerce.date(),
|
|
21783
|
+
updatedAt: exports_coerce.date()
|
|
21784
|
+
});
|
|
21785
|
+
var medicineText = (max) => string2().trim().min(1).max(max);
|
|
21786
|
+
var animalMedicineFields = object({
|
|
21787
|
+
id: ulidSchema,
|
|
21788
|
+
title: medicineText(120),
|
|
21789
|
+
animalIds: array(ulidSchema).min(1).max(20),
|
|
21790
|
+
dose: medicineText(120).nullish(),
|
|
21791
|
+
everyCount: number2().int().min(1).max(366).optional(),
|
|
21792
|
+
everyUnit: animalMedicineEveryUnitSchema.optional(),
|
|
21793
|
+
timeOfDay: string2().regex(/^(morning|midday|afternoon|evening|night|([01][0-9]|2[0-3]):[0-5][0-9])$/).nullish(),
|
|
21794
|
+
startsOn: keyDateDaySchema.nullish(),
|
|
21795
|
+
endsOn: keyDateDaySchema.nullish(),
|
|
21796
|
+
nextOn: keyDateDaySchema.nullish(),
|
|
21797
|
+
stock: number2().min(0).max(1e5).nullish(),
|
|
21798
|
+
unit: medicineText(30).nullish(),
|
|
21799
|
+
perDose: number2().positive().max(1e4).optional(),
|
|
21800
|
+
lowAt: number2().min(0).max(1e5).nullish(),
|
|
21801
|
+
note: medicineText(300).nullish()
|
|
21802
|
+
}).strict();
|
|
21803
|
+
var endsAfterStart2 = (v) => !v.startsOn || !v.endsOn || v.endsOn >= v.startsOn;
|
|
21804
|
+
var endsMessage = { message: "endsOn is before startsOn", path: ["endsOn"] };
|
|
21805
|
+
var createAnimalMedicineInputSchema = animalMedicineFields.refine(endsAfterStart2, endsMessage);
|
|
21806
|
+
var updateAnimalMedicineInputSchema = animalMedicineFields.omit({ id: true }).partial().strict().refine(endsAfterStart2, endsMessage);
|
|
21807
|
+
var animalMedicinesQuerySchema = object({
|
|
21808
|
+
animalId: ulidSchema.optional(),
|
|
21809
|
+
day: keyDateDaySchema.optional(),
|
|
21810
|
+
includeEnded: _enum2(["true", "false"]).transform((v) => v === "true").optional()
|
|
21811
|
+
});
|
|
21812
|
+
var animalMedicineDoseInputSchema = object({ day: keyDateDaySchema.optional() }).strict();
|
|
21715
21813
|
|
|
21716
21814
|
// ../../packages/schema/src/operations/crud.ts
|
|
21717
21815
|
var DELETE_REASON_QUERY = [
|
|
@@ -21795,6 +21893,7 @@ function crudOperations(r) {
|
|
|
21795
21893
|
var READ = ["animals:read"];
|
|
21796
21894
|
var WRITE = ["animals:write"];
|
|
21797
21895
|
var visit = { visitId: "The vet visit's ULID." };
|
|
21896
|
+
var medicine = { medicineId: "The medicine's ULID." };
|
|
21798
21897
|
var animalOperations = defineOperations({
|
|
21799
21898
|
...crudOperations({
|
|
21800
21899
|
segment: "animals",
|
|
@@ -21883,6 +21982,96 @@ var animalOperations = defineOperations({
|
|
|
21883
21982
|
response: { description: "The species profile." },
|
|
21884
21983
|
errors: { 400: true }
|
|
21885
21984
|
},
|
|
21985
|
+
listMedicines: {
|
|
21986
|
+
method: "get",
|
|
21987
|
+
path: "/animals/medicines",
|
|
21988
|
+
scopes: READ,
|
|
21989
|
+
tag: "Animals",
|
|
21990
|
+
summary: "List the animals' medicines",
|
|
21991
|
+
description: "By title: each medicine with the `animals` it's for, its `dose`, how often (`everyCount` `everyUnit`; `daily` when every 1 day), `timeOfDay`, a course's `startsOn`/`endsOn` and its `course` day N of M, the `nextOn` day of one that isn't daily, the counted `stock` (`unit`, `perDose`, `low` at `lowAt`), the `note`, and on `day` (UTC today by default) whether it's `dueToday` and `doneToday`, with `lastGivenOn`. Ended courses only with `includeEnded`.",
|
|
21992
|
+
query: [
|
|
21993
|
+
{ name: "animalId", description: "Only this animal's (an animal's ULID)." },
|
|
21994
|
+
{ name: "day", description: "The reader's day, `YYYY-MM-DD`; UTC today when left out." },
|
|
21995
|
+
{ name: "includeEnded", description: "`true`: ended courses too." }
|
|
21996
|
+
],
|
|
21997
|
+
querySchema: animalMedicinesQuerySchema,
|
|
21998
|
+
status: 200,
|
|
21999
|
+
response: { description: "The medicines." }
|
|
22000
|
+
},
|
|
22001
|
+
createMedicine: {
|
|
22002
|
+
method: "post",
|
|
22003
|
+
path: "/animals/medicines",
|
|
22004
|
+
scopes: WRITE,
|
|
22005
|
+
tag: "Animals",
|
|
22006
|
+
summary: "Add a medicine for one animal or a few",
|
|
22007
|
+
description: "A daily one (the default, every 1 day), a course (`startsOn` to `endsOn`) or one that comes round (`everyCount` `everyUnit`, with its `nextOn`). Count the `stock` to have each dose take `perDose` (default 1) from it and say low at `lowAt`. Every animal must be one in this Space (400).",
|
|
22008
|
+
body: createAnimalMedicineInputSchema,
|
|
22009
|
+
status: 201,
|
|
22010
|
+
response: { description: "The medicine." },
|
|
22011
|
+
errors: { 400: true }
|
|
22012
|
+
},
|
|
22013
|
+
getMedicine: {
|
|
22014
|
+
method: "get",
|
|
22015
|
+
path: "/animals/medicines/{medicineId}",
|
|
22016
|
+
pathParams: medicine,
|
|
22017
|
+
scopes: READ,
|
|
22018
|
+
tag: "Animals",
|
|
22019
|
+
summary: "A medicine, as it stands today",
|
|
22020
|
+
description: "The same shape as a row of the list, on UTC today.",
|
|
22021
|
+
status: 200,
|
|
22022
|
+
response: { description: "The medicine." },
|
|
22023
|
+
errors: { 404: true }
|
|
22024
|
+
},
|
|
22025
|
+
updateMedicine: {
|
|
22026
|
+
method: "patch",
|
|
22027
|
+
path: "/animals/medicines/{medicineId}",
|
|
22028
|
+
pathParams: medicine,
|
|
22029
|
+
scopes: WRITE,
|
|
22030
|
+
tag: "Animals",
|
|
22031
|
+
summary: "Change a medicine",
|
|
22032
|
+
description: "A field left out stays; `null` clears it; `animalIds` replaces who it's for. Set `stock` when a new box comes in.",
|
|
22033
|
+
body: updateAnimalMedicineInputSchema,
|
|
22034
|
+
status: 200,
|
|
22035
|
+
response: { description: "The medicine." },
|
|
22036
|
+
errors: { 400: true, 404: true }
|
|
22037
|
+
},
|
|
22038
|
+
removeMedicine: {
|
|
22039
|
+
method: "delete",
|
|
22040
|
+
path: "/animals/medicines/{medicineId}",
|
|
22041
|
+
pathParams: medicine,
|
|
22042
|
+
scopes: WRITE,
|
|
22043
|
+
tag: "Animals",
|
|
22044
|
+
summary: "Remove a medicine",
|
|
22045
|
+
description: "With the doses given; to stop a course and keep it, set its `endsOn` instead.",
|
|
22046
|
+
status: 204,
|
|
22047
|
+
response: { description: "Removed." },
|
|
22048
|
+
errors: { 404: true }
|
|
22049
|
+
},
|
|
22050
|
+
giveMedicineDose: {
|
|
22051
|
+
method: "post",
|
|
22052
|
+
path: "/animals/medicines/{medicineId}/doses",
|
|
22053
|
+
pathParams: medicine,
|
|
22054
|
+
scopes: WRITE,
|
|
22055
|
+
tag: "Animals",
|
|
22056
|
+
summary: "Give a medicine's dose",
|
|
22057
|
+
description: "The dose for `day` (UTC today by default): it takes `perDose` from a counted stock (never below 0) and moves the next day of one that isn't daily on from that day. Again that day changes nothing.",
|
|
22058
|
+
body: animalMedicineDoseInputSchema,
|
|
22059
|
+
status: 200,
|
|
22060
|
+
response: { description: "The medicine, on that day." },
|
|
22061
|
+
errors: { 400: true, 404: true }
|
|
22062
|
+
},
|
|
22063
|
+
undoMedicineDose: {
|
|
22064
|
+
method: "delete",
|
|
22065
|
+
path: "/animals/medicines/{medicineId}/doses/{day}",
|
|
22066
|
+
pathParams: { ...medicine, day: "The day it was given for, `YYYY-MM-DD`." },
|
|
22067
|
+
scopes: WRITE,
|
|
22068
|
+
tag: "Animals",
|
|
22069
|
+
summary: "Take a medicine's dose back",
|
|
22070
|
+
description: "The stock and the next day go back to before it; 404 when none was given that day.",
|
|
22071
|
+
status: 200,
|
|
22072
|
+
response: { description: "The medicine, on that day." },
|
|
22073
|
+
errors: { 400: "`day` isn't a `YYYY-MM-DD` day.", 404: true }
|
|
22074
|
+
},
|
|
21886
22075
|
vetVisit: {
|
|
21887
22076
|
method: "get",
|
|
21888
22077
|
path: "/animals/vet-visits/{visitId}",
|
|
@@ -23933,6 +24122,24 @@ var collectionSavedViews = pgTable("collection_saved_views", {
|
|
|
23933
24122
|
}, (t) => [
|
|
23934
24123
|
index("collection_saved_views_tenant_idx").on(t.tenantId)
|
|
23935
24124
|
]);
|
|
24125
|
+
var collectionKinds = pgTable("collection_kinds", {
|
|
24126
|
+
id: text("id").primaryKey(),
|
|
24127
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
24128
|
+
key: text("key").notNull(),
|
|
24129
|
+
name: text("name").notNull(),
|
|
24130
|
+
one: text("one").notNull(),
|
|
24131
|
+
many: text("many").notNull(),
|
|
24132
|
+
icon: text("icon").notNull().default("tag"),
|
|
24133
|
+
preset: text("preset"),
|
|
24134
|
+
fields: jsonb("fields").$type().notNull().default([]),
|
|
24135
|
+
statusWords: jsonb("status_words").$type().notNull(),
|
|
24136
|
+
view: text("view").notNull().default("grid"),
|
|
24137
|
+
createdByUserId: text("created_by_user_id").references(() => users.id, {
|
|
24138
|
+
onDelete: "set null"
|
|
24139
|
+
}),
|
|
24140
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
24141
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
24142
|
+
}, (t) => [unique("collection_kinds_tenant_key_uniq").on(t.tenantId, t.key)]);
|
|
23936
24143
|
|
|
23937
24144
|
// ../../packages/schema/src/contracts/collection-values.ts
|
|
23938
24145
|
var collectionStatusValues = ["want", "have", "doing", "done", "dropped", "gone"];
|
|
@@ -26139,6 +26346,162 @@ var circleOperations = defineOperations({
|
|
|
26139
26346
|
})
|
|
26140
26347
|
});
|
|
26141
26348
|
|
|
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
|
+
|
|
26142
26505
|
// ../../packages/schema/src/contracts/pagination.ts
|
|
26143
26506
|
var paginationQuerySchema = object({
|
|
26144
26507
|
limit: exports_coerce.number().int().positive().optional(),
|
|
@@ -26149,6 +26512,7 @@ var paginationQuerySchema = object({
|
|
|
26149
26512
|
var READ2 = ["collections:read"];
|
|
26150
26513
|
var WRITE2 = ["collections:write"];
|
|
26151
26514
|
var entryParams = { entryId: "The entry's ULID." };
|
|
26515
|
+
var kindParams = { kindId: "The kind's ULID." };
|
|
26152
26516
|
var collectionOperations = defineOperations({
|
|
26153
26517
|
...crudOperations({
|
|
26154
26518
|
segment: "collection",
|
|
@@ -26204,6 +26568,65 @@ var collectionOperations = defineOperations({
|
|
|
26204
26568
|
status: 200,
|
|
26205
26569
|
response: { description: "The Type registry." }
|
|
26206
26570
|
},
|
|
26571
|
+
listKinds: {
|
|
26572
|
+
method: "get",
|
|
26573
|
+
path: "/collection/kinds",
|
|
26574
|
+
scopes: READ2,
|
|
26575
|
+
tag: "Collection",
|
|
26576
|
+
summary: "List the Space's own kinds",
|
|
26577
|
+
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`.",
|
|
26578
|
+
status: 200,
|
|
26579
|
+
response: { description: "The kinds." }
|
|
26580
|
+
},
|
|
26581
|
+
createKind: {
|
|
26582
|
+
method: "post",
|
|
26583
|
+
path: "/collection/kinds",
|
|
26584
|
+
scopes: WRITE2,
|
|
26585
|
+
tag: "Collection",
|
|
26586
|
+
summary: "Add a kind",
|
|
26587
|
+
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.",
|
|
26588
|
+
body: createCollectionKindInputSchema,
|
|
26589
|
+
status: 201,
|
|
26590
|
+
response: { description: "The kind." },
|
|
26591
|
+
errors: { 400: true, 409: "The Space already has a kind with this key." }
|
|
26592
|
+
},
|
|
26593
|
+
getKind: {
|
|
26594
|
+
method: "get",
|
|
26595
|
+
path: "/collection/kinds/{kindId}",
|
|
26596
|
+
pathParams: kindParams,
|
|
26597
|
+
scopes: READ2,
|
|
26598
|
+
tag: "Collection",
|
|
26599
|
+
summary: "A kind of the Space's own",
|
|
26600
|
+
description: "The same shape as a row of the list.",
|
|
26601
|
+
status: 200,
|
|
26602
|
+
response: { description: "The kind." },
|
|
26603
|
+
errors: { 404: true }
|
|
26604
|
+
},
|
|
26605
|
+
updateKind: {
|
|
26606
|
+
method: "patch",
|
|
26607
|
+
path: "/collection/kinds/{kindId}",
|
|
26608
|
+
pathParams: kindParams,
|
|
26609
|
+
scopes: WRITE2,
|
|
26610
|
+
tag: "Collection",
|
|
26611
|
+
summary: "Change a kind",
|
|
26612
|
+
description: "Its name, one/many, icon, `fields` (replaces the list) or `statusWords`; a field left out stays. The key never changes.",
|
|
26613
|
+
body: updateCollectionKindInputSchema,
|
|
26614
|
+
status: 200,
|
|
26615
|
+
response: { description: "The kind." },
|
|
26616
|
+
errors: { 400: true, 404: true }
|
|
26617
|
+
},
|
|
26618
|
+
removeKind: {
|
|
26619
|
+
method: "delete",
|
|
26620
|
+
path: "/collection/kinds/{kindId}",
|
|
26621
|
+
pathParams: kindParams,
|
|
26622
|
+
scopes: WRITE2,
|
|
26623
|
+
tag: "Collection",
|
|
26624
|
+
summary: "Remove a kind",
|
|
26625
|
+
description: "Only a kind with no Items (409 otherwise: move or remove them first).",
|
|
26626
|
+
status: 204,
|
|
26627
|
+
response: { description: "Removed." },
|
|
26628
|
+
errors: { 404: true, 409: "The kind still has Items." }
|
|
26629
|
+
},
|
|
26207
26630
|
backfillCovers: {
|
|
26208
26631
|
method: "post",
|
|
26209
26632
|
path: "/collection/covers",
|
|
@@ -31309,9 +31732,9 @@ var eventFields = {
|
|
|
31309
31732
|
note: eventTextSchema(1000).nullish(),
|
|
31310
31733
|
sort: number2().int().min(0).max(1e4).optional()
|
|
31311
31734
|
};
|
|
31312
|
-
var
|
|
31313
|
-
var createGuestListEventInputSchema = object({ id: ulidSchema, guestListId: ulidSchema, key: guestEventKeySchema, ...eventFields }).strict().refine(
|
|
31314
|
-
var updateGuestListEventInputSchema = object(eventFields).partial().strict().refine(
|
|
31735
|
+
var endsAfterStart3 = (e) => !e.startsAt || !e.endsAt || e.endsAt >= e.startsAt;
|
|
31736
|
+
var createGuestListEventInputSchema = object({ id: ulidSchema, guestListId: ulidSchema, key: guestEventKeySchema, ...eventFields }).strict().refine(endsAfterStart3, { message: "endsAt is before startsAt", path: ["endsAt"] });
|
|
31737
|
+
var updateGuestListEventInputSchema = object(eventFields).partial().strict().refine(endsAfterStart3, { message: "endsAt is before startsAt", path: ["endsAt"] });
|
|
31315
31738
|
var guestListEventsQuerySchema = object({ guestListId: ulidSchema });
|
|
31316
31739
|
var guestTableSchema = createSelectSchema(guestTables, {
|
|
31317
31740
|
createdAt: exports_coerce.date(),
|
|
@@ -40340,18 +40763,18 @@ var runPlayStatusValues = [
|
|
|
40340
40763
|
"dropped"
|
|
40341
40764
|
];
|
|
40342
40765
|
var runPlayStatusSchema = _enum2(runPlayStatusValues);
|
|
40343
|
-
var
|
|
40766
|
+
var name3 = string2().trim().min(1).max(200);
|
|
40344
40767
|
var text5 = string2().trim().max(2000);
|
|
40345
40768
|
var shortText2 = string2().trim().max(300);
|
|
40346
40769
|
var isoDate = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "must be an ISO date (YYYY-MM-DD)");
|
|
40347
40770
|
var ref = string2().trim().min(1).max(200);
|
|
40348
40771
|
var runCharacterSchema = object({
|
|
40349
|
-
name:
|
|
40772
|
+
name: name3,
|
|
40350
40773
|
pronoun: _enum2(["he", "she", "they"]).nullish(),
|
|
40351
40774
|
subtitle: shortText2.nullish(),
|
|
40352
40775
|
level: number2().int().min(0).max(1e4).nullish(),
|
|
40353
40776
|
build: shortText2.nullish(),
|
|
40354
|
-
stats: array(object({ k:
|
|
40777
|
+
stats: array(object({ k: name3, v: union([number2(), shortText2]) }).strict()).max(40).optional(),
|
|
40355
40778
|
traits: array(shortText2).max(20).optional(),
|
|
40356
40779
|
backstory: text5.nullish(),
|
|
40357
40780
|
rules: array(shortText2).max(30).optional(),
|
|
@@ -40360,12 +40783,12 @@ var runCharacterSchema = object({
|
|
|
40360
40783
|
var runArcSchema = object({
|
|
40361
40784
|
title: shortText2.nullish(),
|
|
40362
40785
|
chapters: array(object({
|
|
40363
|
-
key:
|
|
40364
|
-
name:
|
|
40786
|
+
key: name3,
|
|
40787
|
+
name: name3,
|
|
40365
40788
|
range: shortText2.nullish(),
|
|
40366
40789
|
moral: text5.nullish()
|
|
40367
40790
|
}).strict()).max(40),
|
|
40368
|
-
current:
|
|
40791
|
+
current: name3.nullish()
|
|
40369
40792
|
}).strict();
|
|
40370
40793
|
var runStepStatusValues = ["done", "now", "todo", "skipped"];
|
|
40371
40794
|
var runStepStatusSchema = _enum2(runStepStatusValues);
|
|
@@ -40378,7 +40801,7 @@ var runQuestStatusValues = ["active", "paused", "planned", "done", "failed"];
|
|
|
40378
40801
|
var runQuestStatusSchema = _enum2(runQuestStatusValues);
|
|
40379
40802
|
var runQuestSchema = object({
|
|
40380
40803
|
ref: ref.nullish(),
|
|
40381
|
-
name:
|
|
40804
|
+
name: name3,
|
|
40382
40805
|
line: shortText2.nullish(),
|
|
40383
40806
|
status: runQuestStatusSchema.default("active"),
|
|
40384
40807
|
objective: text5.nullish(),
|
|
@@ -40393,7 +40816,7 @@ var runQuestSchema = object({
|
|
|
40393
40816
|
}).strict()).max(40).optional(),
|
|
40394
40817
|
pausedAt: shortText2.nullish(),
|
|
40395
40818
|
why: text5.nullish(),
|
|
40396
|
-
revisitAt:
|
|
40819
|
+
revisitAt: name3.nullish()
|
|
40397
40820
|
}).strict();
|
|
40398
40821
|
var runNextStepsSchema = object({
|
|
40399
40822
|
items: array(shortText2.pipe(string2().min(1))).max(3),
|
|
@@ -40402,50 +40825,50 @@ var runNextStepsSchema = object({
|
|
|
40402
40825
|
}).strict();
|
|
40403
40826
|
var runChoiceSchema = object({
|
|
40404
40827
|
ref: ref.nullish(),
|
|
40405
|
-
title:
|
|
40828
|
+
title: name3,
|
|
40406
40829
|
place: shortText2.nullish(),
|
|
40407
40830
|
status: _enum2(["made", "planned"]).default("made"),
|
|
40408
40831
|
options: array(shortText2).max(6).optional(),
|
|
40409
40832
|
why: text5.nullish(),
|
|
40410
40833
|
consequence: text5.nullish(),
|
|
40411
|
-
revisitAt:
|
|
40412
|
-
chapter:
|
|
40834
|
+
revisitAt: name3.nullish(),
|
|
40835
|
+
chapter: name3.nullish(),
|
|
40413
40836
|
tone: _enum2(["good", "grey", "dark"]).nullish(),
|
|
40414
40837
|
on: isoDate.nullish()
|
|
40415
40838
|
}).strict();
|
|
40416
40839
|
var runHomeSchema = object({
|
|
40417
40840
|
ref: ref.nullish(),
|
|
40418
|
-
name:
|
|
40841
|
+
name: name3,
|
|
40419
40842
|
role: _enum2(["home", "collector", "storage", "planned", "later"]).default("home"),
|
|
40420
40843
|
place: shortText2.nullish(),
|
|
40421
|
-
upgrades: array(object({ name:
|
|
40844
|
+
upgrades: array(object({ name: name3, done: boolean2().default(false) }).strict()).max(40).optional(),
|
|
40422
40845
|
steward: shortText2.nullish(),
|
|
40423
40846
|
note: text5.nullish()
|
|
40424
40847
|
}).strict();
|
|
40425
40848
|
var runPersonSchema = object({
|
|
40426
40849
|
ref: ref.nullish(),
|
|
40427
|
-
name:
|
|
40850
|
+
name: name3,
|
|
40428
40851
|
role: _enum2(["child", "spouse", "steward", "follower", "pet", "rival", "other"]),
|
|
40429
40852
|
status: _enum2(["with", "planned", "lost"]).default("with"),
|
|
40430
40853
|
home: shortText2.nullish(),
|
|
40431
40854
|
note: text5.nullish()
|
|
40432
40855
|
}).strict();
|
|
40433
40856
|
var runMountSchema = object({
|
|
40434
|
-
name:
|
|
40857
|
+
name: name3,
|
|
40435
40858
|
status: _enum2(["with", "planned", "lost"]).default("with"),
|
|
40436
40859
|
note: text5.nullish()
|
|
40437
40860
|
}).strict();
|
|
40438
40861
|
var runUniqueSchema = object({
|
|
40439
40862
|
ref: ref.nullish(),
|
|
40440
|
-
name:
|
|
40863
|
+
name: name3,
|
|
40441
40864
|
status: _enum2(["have", "now", "want"]).default("have"),
|
|
40442
40865
|
source: shortText2.nullish(),
|
|
40443
40866
|
displayAt: shortText2.nullish(),
|
|
40444
|
-
set:
|
|
40867
|
+
set: name3.nullish()
|
|
40445
40868
|
}).strict();
|
|
40446
40869
|
var runChecklistSchema = object({
|
|
40447
40870
|
key: string2().trim().min(1).max(60).regex(/^[a-z0-9][a-z0-9_-]*$/, "must be a lowercase slug"),
|
|
40448
|
-
label:
|
|
40871
|
+
label: name3,
|
|
40449
40872
|
total: number2().int().min(0).max(5000).nullish(),
|
|
40450
40873
|
items: array(object({ id: ref, label: shortText2.nullish() }).strict()).max(5000).optional(),
|
|
40451
40874
|
done: array(ref).max(5000),
|
|
@@ -40454,7 +40877,7 @@ var runChecklistSchema = object({
|
|
|
40454
40877
|
legend: shortText2.nullish()
|
|
40455
40878
|
}).strict();
|
|
40456
40879
|
var runTeamMemberSchema = object({
|
|
40457
|
-
species:
|
|
40880
|
+
species: name3,
|
|
40458
40881
|
nick: shortText2.nullish(),
|
|
40459
40882
|
level: number2().int().min(1).max(100).nullish(),
|
|
40460
40883
|
nature: shortText2.nullish(),
|
|
@@ -40468,8 +40891,8 @@ var runAchievementsSchema = object({
|
|
|
40468
40891
|
source: _enum2(["steam", "xbox", "psn", "manual"]).default("manual"),
|
|
40469
40892
|
total: number2().int().min(0).max(5000).nullish(),
|
|
40470
40893
|
enabled: boolean2().default(true),
|
|
40471
|
-
unlocked: array(object({ name:
|
|
40472
|
-
locked: array(object({ name:
|
|
40894
|
+
unlocked: array(object({ name: name3, on: isoDate.nullish(), hint: shortText2.nullish(), key: ref.nullish() }).strict()).max(5000),
|
|
40895
|
+
locked: array(object({ name: name3, hint: shortText2.nullish(), key: ref.nullish() }).strict()).max(5000).optional(),
|
|
40473
40896
|
syncedAt: string2().datetime({ offset: true }).nullish()
|
|
40474
40897
|
}).strict();
|
|
40475
40898
|
var runRareFindsSchema = object({
|
|
@@ -40479,7 +40902,7 @@ var runRareFindsSchema = object({
|
|
|
40479
40902
|
}).strict();
|
|
40480
40903
|
var runInstallSchema = object({
|
|
40481
40904
|
edition: shortText2.nullish(),
|
|
40482
|
-
mods: array(object({ name:
|
|
40905
|
+
mods: array(object({ name: name3, url: string2().url().max(2000).nullish() }).strict()).max(200).default([]),
|
|
40483
40906
|
savePath: string2().trim().max(500).nullish(),
|
|
40484
40907
|
lastBackup: isoDate.nullish(),
|
|
40485
40908
|
notes: text5.nullish()
|
|
@@ -40489,7 +40912,7 @@ var runSaveFields = {
|
|
|
40489
40912
|
game: _enum2(["skyrim"]).default("skyrim"),
|
|
40490
40913
|
fileName: shortText2.nullish(),
|
|
40491
40914
|
saveNumber: number2().int().min(0).max(1e9),
|
|
40492
|
-
playerName:
|
|
40915
|
+
playerName: name3,
|
|
40493
40916
|
level: number2().int().min(0).max(1e4),
|
|
40494
40917
|
location: shortText2,
|
|
40495
40918
|
race: shortText2.nullish(),
|
|
@@ -40535,7 +40958,7 @@ var runFacetSchema = object({
|
|
|
40535
40958
|
install: runInstallSchema.nullish(),
|
|
40536
40959
|
save: runSaveSchema.nullish(),
|
|
40537
40960
|
money: object({ goal: shortText2.nullish(), purpose: shortText2.nullish() }).strict().nullish(),
|
|
40538
|
-
links: array(object({ label:
|
|
40961
|
+
links: array(object({ label: name3, url: string2().url().max(2000) }).strict()).max(50).optional()
|
|
40539
40962
|
}).strict();
|
|
40540
40963
|
var runListSectionValues = [
|
|
40541
40964
|
"orderOfPlay",
|
|
@@ -40689,12 +41112,12 @@ var runSaveHeaderResultSchema = object({
|
|
|
40689
41112
|
var createRunInputSchema = object({
|
|
40690
41113
|
id: ulidSchema,
|
|
40691
41114
|
gameId: ulidSchema,
|
|
40692
|
-
title:
|
|
41115
|
+
title: name3,
|
|
40693
41116
|
status: runPlayStatusSchema.optional(),
|
|
40694
41117
|
facet: runFacetSchema.optional()
|
|
40695
41118
|
}).strict();
|
|
40696
41119
|
var updateRunInputSchema = object({
|
|
40697
|
-
title:
|
|
41120
|
+
title: name3.optional(),
|
|
40698
41121
|
status: runPlayStatusSchema.optional(),
|
|
40699
41122
|
facet: runFacetSchema.optional()
|
|
40700
41123
|
}).strict();
|
|
@@ -46064,6 +46487,172 @@ var commands2 = [
|
|
|
46064
46487
|
return { data: { ok: true, animalId: id }, render: renderRecord };
|
|
46065
46488
|
}
|
|
46066
46489
|
},
|
|
46490
|
+
{
|
|
46491
|
+
spec: {
|
|
46492
|
+
path: ["animals", "medicines"],
|
|
46493
|
+
summary: "List the animals' medicines and where each stands today.",
|
|
46494
|
+
args: [],
|
|
46495
|
+
flags: [
|
|
46496
|
+
{ name: "animal", type: "string", description: "Only this animal's (ULID)." },
|
|
46497
|
+
{
|
|
46498
|
+
name: "day",
|
|
46499
|
+
type: "string",
|
|
46500
|
+
description: "The day to read for, YYYY-MM-DD (default UTC today)."
|
|
46501
|
+
},
|
|
46502
|
+
{ name: "include-ended", type: "boolean", description: "Ended courses too." }
|
|
46503
|
+
],
|
|
46504
|
+
scopes: [...animalOperations.listMedicines.scopes],
|
|
46505
|
+
returns: "AnimalMedicineView[]",
|
|
46506
|
+
notes: `${routeOf(animalOperations.listMedicines)}. Each with its animals, dose, how often, the course's day N of M, the next day, the stock (low or not), and dueToday / doneToday.`
|
|
46507
|
+
},
|
|
46508
|
+
run: async ({ flags, requireClient }) => {
|
|
46509
|
+
const raw = {};
|
|
46510
|
+
const animal = flagString(flags, "animal");
|
|
46511
|
+
const day = flagString(flags, "day");
|
|
46512
|
+
if (animal)
|
|
46513
|
+
raw.animalId = animal;
|
|
46514
|
+
if (day)
|
|
46515
|
+
raw.day = day;
|
|
46516
|
+
if (flagBool(flags, "include-ended"))
|
|
46517
|
+
raw.includeEnded = "true";
|
|
46518
|
+
parseInput(animalMedicinesQuerySchema, raw);
|
|
46519
|
+
return {
|
|
46520
|
+
data: await requireClient().getPage(pathOf(animalOperations.listMedicines), { query: raw }),
|
|
46521
|
+
render: renderList
|
|
46522
|
+
};
|
|
46523
|
+
}
|
|
46524
|
+
},
|
|
46525
|
+
{
|
|
46526
|
+
spec: {
|
|
46527
|
+
path: ["animals", "medicine"],
|
|
46528
|
+
summary: "One medicine, as it stands today.",
|
|
46529
|
+
args: [{ name: "id", required: true, description: "Medicine ULID." }],
|
|
46530
|
+
flags: [],
|
|
46531
|
+
scopes: [...animalOperations.getMedicine.scopes],
|
|
46532
|
+
returns: "AnimalMedicineView",
|
|
46533
|
+
notes: `${routeOf(animalOperations.getMedicine)}.`
|
|
46534
|
+
},
|
|
46535
|
+
run: readOperation(animalOperations.getMedicine, renderRecord, { medicineId: "medicine id" })
|
|
46536
|
+
},
|
|
46537
|
+
{
|
|
46538
|
+
spec: {
|
|
46539
|
+
path: ["animals", "medicine-add"],
|
|
46540
|
+
summary: "Add a medicine for one animal or a few: daily, a course, or one that comes round.",
|
|
46541
|
+
args: [],
|
|
46542
|
+
flags: [
|
|
46543
|
+
{
|
|
46544
|
+
name: "data",
|
|
46545
|
+
type: "string",
|
|
46546
|
+
description: 'JSON: `{ "title": "Joint tablet", "animalIds": ["\u2026"], "dose": "1 tablet with breakfast", "timeOfDay": "morning", "stock": 22, "unit": "tablets", "lowAt": 5 }`; a course adds `startsOn`/`endsOn`, one that comes round `everyCount`/`everyUnit` (`day`, `week`, `month`) and `nextOn`. The id is minted.'
|
|
46547
|
+
}
|
|
46548
|
+
],
|
|
46549
|
+
scopes: [...animalOperations.createMedicine.scopes],
|
|
46550
|
+
returns: "AnimalMedicineView",
|
|
46551
|
+
notes: `${routeOf(animalOperations.createMedicine)}. Daily unless said; each dose takes \`perDose\` (default 1) from a counted stock.`
|
|
46552
|
+
},
|
|
46553
|
+
run: async ({ flags, requireClient }) => {
|
|
46554
|
+
const body = parseInput(createAnimalMedicineInputSchema, {
|
|
46555
|
+
id: ulid3(),
|
|
46556
|
+
...readDataFlag(flags)
|
|
46557
|
+
});
|
|
46558
|
+
return {
|
|
46559
|
+
data: await requireClient().post(pathOf(animalOperations.createMedicine), body),
|
|
46560
|
+
render: renderRecord
|
|
46561
|
+
};
|
|
46562
|
+
}
|
|
46563
|
+
},
|
|
46564
|
+
{
|
|
46565
|
+
spec: {
|
|
46566
|
+
path: ["animals", "medicine-update"],
|
|
46567
|
+
summary: "Change a medicine (a new box: set its stock).",
|
|
46568
|
+
args: [{ name: "id", required: true, description: "Medicine ULID." }],
|
|
46569
|
+
flags: [
|
|
46570
|
+
{
|
|
46571
|
+
name: "data",
|
|
46572
|
+
type: "string",
|
|
46573
|
+
description: "UpdateAnimalMedicineInput JSON; null clears a field."
|
|
46574
|
+
}
|
|
46575
|
+
],
|
|
46576
|
+
scopes: [...animalOperations.updateMedicine.scopes],
|
|
46577
|
+
returns: "AnimalMedicineView",
|
|
46578
|
+
notes: `${routeOf(animalOperations.updateMedicine)}. \`animalIds\` replaces who it's for.`
|
|
46579
|
+
},
|
|
46580
|
+
run: async ({ args, flags, requireClient }) => {
|
|
46581
|
+
const medicineId = requireArg(args, 0, "medicine id");
|
|
46582
|
+
const body = parseInput(updateAnimalMedicineInputSchema, readDataFlag(flags));
|
|
46583
|
+
return {
|
|
46584
|
+
data: await requireClient().patch(pathOf(animalOperations.updateMedicine, { medicineId }), body),
|
|
46585
|
+
render: renderRecord
|
|
46586
|
+
};
|
|
46587
|
+
}
|
|
46588
|
+
},
|
|
46589
|
+
{
|
|
46590
|
+
spec: {
|
|
46591
|
+
path: ["animals", "medicine-remove"],
|
|
46592
|
+
summary: "Remove a medicine, with the doses given.",
|
|
46593
|
+
args: [{ name: "id", required: true, description: "Medicine ULID." }],
|
|
46594
|
+
flags: [],
|
|
46595
|
+
scopes: [...animalOperations.removeMedicine.scopes],
|
|
46596
|
+
returns: "void",
|
|
46597
|
+
notes: `${routeOf(animalOperations.removeMedicine)}. Destructive: the doses go too, so it needs --allow-destructive; to stop a course and keep it, set its endsOn.`
|
|
46598
|
+
},
|
|
46599
|
+
run: async ({ args, flags, requireClient }) => {
|
|
46600
|
+
const medicineId = requireArg(args, 0, "medicine id");
|
|
46601
|
+
assertDestructiveAllowed(flags, `remove medicine ${medicineId} and its doses`);
|
|
46602
|
+
await requireClient().delete(pathOf(animalOperations.removeMedicine, { medicineId }));
|
|
46603
|
+
return { data: { ok: true, medicineId }, render: renderRecord };
|
|
46604
|
+
}
|
|
46605
|
+
},
|
|
46606
|
+
{
|
|
46607
|
+
spec: {
|
|
46608
|
+
path: ["animals", "medicine-dose"],
|
|
46609
|
+
summary: "Give a medicine's dose (today, or --day).",
|
|
46610
|
+
args: [{ name: "id", required: true, description: "Medicine ULID." }],
|
|
46611
|
+
flags: [
|
|
46612
|
+
{
|
|
46613
|
+
name: "day",
|
|
46614
|
+
type: "string",
|
|
46615
|
+
description: "The day it's for, YYYY-MM-DD (default UTC today)."
|
|
46616
|
+
}
|
|
46617
|
+
],
|
|
46618
|
+
scopes: [...animalOperations.giveMedicineDose.scopes],
|
|
46619
|
+
returns: "AnimalMedicineView",
|
|
46620
|
+
notes: `${routeOf(animalOperations.giveMedicineDose)}. Takes \`perDose\` from a counted stock and moves the next day on; again that day changes nothing.`
|
|
46621
|
+
},
|
|
46622
|
+
run: async ({ args, flags, requireClient }) => {
|
|
46623
|
+
const medicineId = requireArg(args, 0, "medicine id");
|
|
46624
|
+
const day = flagString(flags, "day");
|
|
46625
|
+
const body = parseInput(animalMedicineDoseInputSchema, day ? { day } : {});
|
|
46626
|
+
return {
|
|
46627
|
+
data: await requireClient().post(pathOf(animalOperations.giveMedicineDose, { medicineId }), body),
|
|
46628
|
+
render: renderRecord
|
|
46629
|
+
};
|
|
46630
|
+
}
|
|
46631
|
+
},
|
|
46632
|
+
{
|
|
46633
|
+
spec: {
|
|
46634
|
+
path: ["animals", "medicine-undose"],
|
|
46635
|
+
summary: "Take a medicine's dose back.",
|
|
46636
|
+
args: [
|
|
46637
|
+
{ name: "id", required: true, description: "Medicine ULID." },
|
|
46638
|
+
{ name: "day", required: true, description: "The day it was given for, YYYY-MM-DD." }
|
|
46639
|
+
],
|
|
46640
|
+
flags: [],
|
|
46641
|
+
scopes: [...animalOperations.undoMedicineDose.scopes],
|
|
46642
|
+
returns: "AnimalMedicineView",
|
|
46643
|
+
notes: `${routeOf(animalOperations.undoMedicineDose)}. The stock and the next day go back to before it.`
|
|
46644
|
+
},
|
|
46645
|
+
run: async ({ args, requireClient }) => {
|
|
46646
|
+
const medicineId = requireArg(args, 0, "medicine id");
|
|
46647
|
+
const { day } = parseInput(animalMedicineDoseInputSchema, {
|
|
46648
|
+
day: requireArg(args, 1, "day")
|
|
46649
|
+
});
|
|
46650
|
+
return {
|
|
46651
|
+
data: await requireClient().delete(pathOf(animalOperations.undoMedicineDose, { medicineId, day })),
|
|
46652
|
+
render: renderRecord
|
|
46653
|
+
};
|
|
46654
|
+
}
|
|
46655
|
+
},
|
|
46067
46656
|
{
|
|
46068
46657
|
spec: {
|
|
46069
46658
|
path: ["animals", "acquisition"],
|
|
@@ -47132,6 +47721,106 @@ var commands9 = [
|
|
|
47132
47721
|
return { data: types, render: renderList };
|
|
47133
47722
|
}
|
|
47134
47723
|
},
|
|
47724
|
+
{
|
|
47725
|
+
spec: {
|
|
47726
|
+
path: ["collection", "kinds"],
|
|
47727
|
+
summary: "List the Space's own kinds (vinyl, board games, \u2026) with their fields and words.",
|
|
47728
|
+
args: [],
|
|
47729
|
+
flags: [],
|
|
47730
|
+
scopes: [...collectionOperations.listKinds.scopes],
|
|
47731
|
+
returns: "CollectionKind[]",
|
|
47732
|
+
notes: `${routeOf(collectionOperations.listKinds)}. Each kind's \`key\` is what an Item of it carries as its \`type\`.`
|
|
47733
|
+
},
|
|
47734
|
+
run: async ({ requireClient }) => ({
|
|
47735
|
+
data: await requireClient().getPage(pathOf(collectionOperations.listKinds)),
|
|
47736
|
+
render: renderList
|
|
47737
|
+
})
|
|
47738
|
+
},
|
|
47739
|
+
{
|
|
47740
|
+
spec: {
|
|
47741
|
+
path: ["collection", "kind"],
|
|
47742
|
+
summary: "One of the Space's own kinds.",
|
|
47743
|
+
args: [{ name: "id", required: true, description: "Kind ULID." }],
|
|
47744
|
+
flags: [],
|
|
47745
|
+
scopes: [...collectionOperations.getKind.scopes],
|
|
47746
|
+
returns: "CollectionKind",
|
|
47747
|
+
notes: `${routeOf(collectionOperations.getKind)}.`
|
|
47748
|
+
},
|
|
47749
|
+
run: readOperation(collectionOperations.getKind, renderRecord, { kindId: "kind id" })
|
|
47750
|
+
},
|
|
47751
|
+
{
|
|
47752
|
+
spec: {
|
|
47753
|
+
path: ["collection", "kind-add"],
|
|
47754
|
+
summary: "Add a kind: from a preset (lego, vinyl, board, custom) or from scratch.",
|
|
47755
|
+
args: [{ name: "name", required: true, description: 'Its name ("Vinyl").' }],
|
|
47756
|
+
flags: [
|
|
47757
|
+
{
|
|
47758
|
+
name: "preset",
|
|
47759
|
+
type: "string",
|
|
47760
|
+
description: `Start from ${Object.keys(COLLECTION_KIND_PRESETS).join(", ")}; what's left out comes from it.`
|
|
47761
|
+
},
|
|
47762
|
+
{
|
|
47763
|
+
name: "data",
|
|
47764
|
+
type: "string",
|
|
47765
|
+
description: 'More JSON: `{ "key": "\u2026", "one": "record", "many": "records", "icon": "disc", "fields": [{ "key": "artist", "label": "Artist", "type": "text" }], "statusWords": { \u2026 } }`. The id is minted.'
|
|
47766
|
+
}
|
|
47767
|
+
],
|
|
47768
|
+
scopes: [...collectionOperations.createKind.scopes],
|
|
47769
|
+
returns: "CollectionKind",
|
|
47770
|
+
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\`.`
|
|
47771
|
+
},
|
|
47772
|
+
run: async ({ args, flags, requireClient }) => {
|
|
47773
|
+
const name = requireArg(args, 0, "name");
|
|
47774
|
+
const preset = flagString(flags, "preset");
|
|
47775
|
+
if (preset)
|
|
47776
|
+
parseInput(collectionKindPresetSchema, preset);
|
|
47777
|
+
const body = parseInput(createCollectionKindInputSchema, {
|
|
47778
|
+
id: ulid3(),
|
|
47779
|
+
name,
|
|
47780
|
+
...preset ? { preset } : {},
|
|
47781
|
+
...readDataFlag(flags)
|
|
47782
|
+
});
|
|
47783
|
+
return {
|
|
47784
|
+
data: await requireClient().post(pathOf(collectionOperations.createKind), body),
|
|
47785
|
+
render: renderRecord
|
|
47786
|
+
};
|
|
47787
|
+
}
|
|
47788
|
+
},
|
|
47789
|
+
{
|
|
47790
|
+
spec: {
|
|
47791
|
+
path: ["collection", "kind-update"],
|
|
47792
|
+
summary: "Change a kind: its name, one/many, icon, fields or status words (the key stays).",
|
|
47793
|
+
args: [{ name: "id", required: true, description: "Kind ULID." }],
|
|
47794
|
+
flags: [{ name: "data", type: "string", description: "UpdateCollectionKindInput JSON." }],
|
|
47795
|
+
scopes: [...collectionOperations.updateKind.scopes],
|
|
47796
|
+
returns: "CollectionKind",
|
|
47797
|
+
notes: `${routeOf(collectionOperations.updateKind)}. \`fields\` replaces the list.`
|
|
47798
|
+
},
|
|
47799
|
+
run: async ({ args, flags, requireClient }) => {
|
|
47800
|
+
const kindId = requireArg(args, 0, "kind id");
|
|
47801
|
+
const body = parseInput(updateCollectionKindInputSchema, readDataFlag(flags));
|
|
47802
|
+
return {
|
|
47803
|
+
data: await requireClient().patch(pathOf(collectionOperations.updateKind, { kindId }), body),
|
|
47804
|
+
render: renderRecord
|
|
47805
|
+
};
|
|
47806
|
+
}
|
|
47807
|
+
},
|
|
47808
|
+
{
|
|
47809
|
+
spec: {
|
|
47810
|
+
path: ["collection", "kind-remove"],
|
|
47811
|
+
summary: "Remove a kind that has no Items.",
|
|
47812
|
+
args: [{ name: "id", required: true, description: "Kind ULID." }],
|
|
47813
|
+
flags: [],
|
|
47814
|
+
scopes: [...collectionOperations.removeKind.scopes],
|
|
47815
|
+
returns: "void",
|
|
47816
|
+
notes: `${routeOf(collectionOperations.removeKind)}. A 409 while it still has Items.`
|
|
47817
|
+
},
|
|
47818
|
+
run: async ({ args, requireClient }) => {
|
|
47819
|
+
const kindId = requireArg(args, 0, "kind id");
|
|
47820
|
+
await requireClient().delete(pathOf(collectionOperations.removeKind, { kindId }));
|
|
47821
|
+
return { data: { ok: true, kindId }, render: renderRecord };
|
|
47822
|
+
}
|
|
47823
|
+
},
|
|
47135
47824
|
{
|
|
47136
47825
|
spec: {
|
|
47137
47826
|
path: ["collection", "list"],
|
package/package.json
CHANGED