@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.
Files changed (2) hide show
  1. package/dist/do.js +286 -182
  2. 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.393.0";
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: '--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"}}}\'`.'
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbeverhelst/do",
3
- "version": "1.393.0",
3
+ "version": "1.394.0",
4
4
  "private": false,
5
5
  "description": "do — the agent-drivable CLI over the public /api/v1 surface",
6
6
  "homepage": "https://github.com/robbeverhelst/do/tree/main/apps/cli",