@purveyors/cli 0.2.1 → 0.3.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/commands/catalog.d.ts +4 -56
- package/dist/commands/catalog.d.ts.map +1 -1
- package/dist/commands/catalog.js +14 -81
- package/dist/commands/catalog.js.map +1 -1
- package/dist/commands/inventory.d.ts +2 -25
- package/dist/commands/inventory.d.ts.map +1 -1
- package/dist/commands/inventory.js +47 -147
- package/dist/commands/inventory.js.map +1 -1
- package/dist/commands/roast.d.ts +2 -41
- package/dist/commands/roast.d.ts.map +1 -1
- package/dist/commands/roast.js +138 -125
- package/dist/commands/roast.js.map +1 -1
- package/dist/commands/sales.d.ts +2 -10
- package/dist/commands/sales.d.ts.map +1 -1
- package/dist/commands/sales.js +30 -109
- package/dist/commands/sales.js.map +1 -1
- package/dist/commands/tasting.d.ts +4 -38
- package/dist/commands/tasting.d.ts.map +1 -1
- package/dist/commands/tasting.js +18 -108
- package/dist/commands/tasting.js.map +1 -1
- package/dist/lib/artisan/db.d.ts +37 -0
- package/dist/lib/artisan/db.d.ts.map +1 -0
- package/dist/lib/artisan/db.js +51 -0
- package/dist/lib/artisan/db.js.map +1 -0
- package/dist/lib/artisan/import.d.ts +16 -0
- package/dist/lib/artisan/import.d.ts.map +1 -0
- package/dist/lib/artisan/import.js +447 -0
- package/dist/lib/artisan/import.js.map +1 -0
- package/dist/lib/artisan/index.d.ts +9 -0
- package/dist/lib/artisan/index.d.ts.map +1 -0
- package/dist/lib/artisan/index.js +7 -0
- package/dist/lib/artisan/index.js.map +1 -0
- package/dist/lib/artisan/parser.d.ts +19 -0
- package/dist/lib/artisan/parser.d.ts.map +1 -0
- package/dist/lib/artisan/parser.js +376 -0
- package/dist/lib/artisan/parser.js.map +1 -0
- package/dist/lib/artisan/temperature.d.ts +52 -0
- package/dist/lib/artisan/temperature.d.ts.map +1 -0
- package/dist/lib/artisan/temperature.js +101 -0
- package/dist/lib/artisan/temperature.js.map +1 -0
- package/dist/lib/artisan/types.d.ts +195 -0
- package/dist/lib/artisan/types.d.ts.map +1 -0
- package/dist/lib/artisan/types.js +35 -0
- package/dist/lib/artisan/types.js.map +1 -0
- package/dist/lib/artisan/validator.d.ts +14 -0
- package/dist/lib/artisan/validator.d.ts.map +1 -0
- package/dist/lib/artisan/validator.js +228 -0
- package/dist/lib/artisan/validator.js.map +1 -0
- package/dist/lib/catalog.d.ts +87 -0
- package/dist/lib/catalog.d.ts.map +1 -0
- package/dist/lib/catalog.js +111 -0
- package/dist/lib/catalog.js.map +1 -0
- package/dist/lib/index.d.ts +6 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +11 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/inventory.d.ts +80 -0
- package/dist/lib/inventory.d.ts.map +1 -0
- package/dist/lib/inventory.js +205 -0
- package/dist/lib/inventory.js.map +1 -0
- package/dist/lib/roast.d.ts +127 -0
- package/dist/lib/roast.d.ts.map +1 -0
- package/dist/lib/roast.js +284 -0
- package/dist/lib/roast.js.map +1 -0
- package/dist/lib/sales.d.ts +53 -0
- package/dist/lib/sales.d.ts.map +1 -0
- package/dist/lib/sales.js +155 -0
- package/dist/lib/sales.js.map +1 -0
- package/dist/lib/tasting.d.ts +76 -0
- package/dist/lib/tasting.d.ts.map +1 -0
- package/dist/lib/tasting.js +136 -0
- package/dist/lib/tasting.js.map +1 -0
- package/package.json +13 -2
|
@@ -1,60 +1,8 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*/
|
|
7
|
-
export declare function sanitizeFilterValue(value: string): string;
|
|
8
|
-
export interface CatalogItem {
|
|
9
|
-
id: number;
|
|
10
|
-
name: string | null;
|
|
11
|
-
source: string | null;
|
|
12
|
-
continent: string | null;
|
|
13
|
-
country: string | null;
|
|
14
|
-
region: string | null;
|
|
15
|
-
processing: string | null;
|
|
16
|
-
drying_method: string | null;
|
|
17
|
-
cultivar_detail: string | null;
|
|
18
|
-
grade: string | null;
|
|
19
|
-
appearance: string | null;
|
|
20
|
-
type: string | null;
|
|
21
|
-
description_short: string | null;
|
|
22
|
-
description_long: string | null;
|
|
23
|
-
farm_notes: string | null;
|
|
24
|
-
cupping_notes: string | null;
|
|
25
|
-
ai_description: string | null;
|
|
26
|
-
roast_recs: string | null;
|
|
27
|
-
cost_lb: number | null;
|
|
28
|
-
lot_size: string | null;
|
|
29
|
-
bag_size: string | null;
|
|
30
|
-
score_value: number | null;
|
|
31
|
-
stocked: boolean | null;
|
|
32
|
-
stocked_date: string | null;
|
|
33
|
-
unstocked_date: string | null;
|
|
34
|
-
arrival_date: string | null;
|
|
35
|
-
last_updated: string | null;
|
|
36
|
-
public_coffee: boolean | null;
|
|
37
|
-
wholesale: boolean | null;
|
|
38
|
-
price_tiers: Array<{
|
|
39
|
-
min_lbs: number;
|
|
40
|
-
price: number;
|
|
41
|
-
}> | null;
|
|
42
|
-
}
|
|
43
|
-
export interface CatalogStats {
|
|
44
|
-
total: number;
|
|
45
|
-
stocked: number;
|
|
46
|
-
byOrigin: Record<string, number>;
|
|
47
|
-
avgPricePerLb: number | null;
|
|
48
|
-
priceRange: {
|
|
49
|
-
min: number | null;
|
|
50
|
-
max: number | null;
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Aggregate stats from an array of catalog items.
|
|
55
|
-
* Pure function — no I/O, safe to unit test.
|
|
56
|
-
*/
|
|
57
|
-
export declare function computeCatalogStats(items: CatalogItem[]): CatalogStats;
|
|
2
|
+
import { computeCatalogStats, sanitizeFilterValue } from '../lib/catalog.js';
|
|
3
|
+
import type { CatalogItem, CatalogStats } from '../lib/catalog.js';
|
|
4
|
+
export type { CatalogItem, CatalogStats };
|
|
5
|
+
export { sanitizeFilterValue, computeCatalogStats };
|
|
58
6
|
/**
|
|
59
7
|
* `purvey catalog` — Browse the public coffee catalog.
|
|
60
8
|
* The coffee_catalog table is publicly readable; no auth required.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/commands/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/commands/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAIL,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAInE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,CAAC;AAIpD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAmE7C"}
|
package/dist/commands/catalog.js
CHANGED
|
@@ -2,37 +2,8 @@ import { Command } from 'commander';
|
|
|
2
2
|
import { createAnonClient } from '../lib/supabase.js';
|
|
3
3
|
import { outputData, info } from '../lib/output.js';
|
|
4
4
|
import { withErrorHandling } from '../lib/errors.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* Strip PostgREST special characters from user-supplied filter values.
|
|
8
|
-
* Prevents injection into .or() filter strings where values are interpolated directly.
|
|
9
|
-
* Removes: ( ) , . * % that have meaning in PostgREST filter syntax.
|
|
10
|
-
*/
|
|
11
|
-
export function sanitizeFilterValue(value) {
|
|
12
|
-
return value.replace(/[(),.*]/g, '');
|
|
13
|
-
}
|
|
14
|
-
// ─── Pure logic (exported for unit testing) ───────────────────────────────────
|
|
15
|
-
/**
|
|
16
|
-
* Aggregate stats from an array of catalog items.
|
|
17
|
-
* Pure function — no I/O, safe to unit test.
|
|
18
|
-
*/
|
|
19
|
-
export function computeCatalogStats(items) {
|
|
20
|
-
const stocked = items.filter((i) => i.stocked === true).length;
|
|
21
|
-
const byOrigin = {};
|
|
22
|
-
for (const item of items) {
|
|
23
|
-
const key = item.country ?? item.continent ?? 'Unknown';
|
|
24
|
-
byOrigin[key] = (byOrigin[key] ?? 0) + 1;
|
|
25
|
-
}
|
|
26
|
-
const prices = items.map((i) => i.cost_lb).filter((p) => p !== null);
|
|
27
|
-
const avgPricePerLb = prices.length > 0
|
|
28
|
-
? Math.round((prices.reduce((a, b) => a + b, 0) / prices.length) * 100) / 100
|
|
29
|
-
: null;
|
|
30
|
-
const priceRange = {
|
|
31
|
-
min: prices.length > 0 ? Math.min(...prices) : null,
|
|
32
|
-
max: prices.length > 0 ? Math.max(...prices) : null,
|
|
33
|
-
};
|
|
34
|
-
return { total: items.length, stocked, byOrigin, avgPricePerLb, priceRange };
|
|
35
|
-
}
|
|
5
|
+
import { searchCatalog, getCatalog, getCatalogStats, computeCatalogStats, sanitizeFilterValue, } from '../lib/catalog.js';
|
|
6
|
+
export { sanitizeFilterValue, computeCatalogStats };
|
|
36
7
|
// ─── Command builder ──────────────────────────────────────────────────────────
|
|
37
8
|
/**
|
|
38
9
|
* `purvey catalog` — Browse the public coffee catalog.
|
|
@@ -54,43 +25,16 @@ export function buildCatalogCommand() {
|
|
|
54
25
|
.action(withErrorHandling(async (opts, cmd) => {
|
|
55
26
|
const globalOpts = cmd.optsWithGlobals();
|
|
56
27
|
const supabase = createAnonClient();
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
if (opts.priceMax !== undefined) {
|
|
69
|
-
query = query.lte('cost_lb', parseFloat(opts.priceMax));
|
|
70
|
-
}
|
|
71
|
-
if (opts.flavor) {
|
|
72
|
-
const keywords = opts.flavor
|
|
73
|
-
.split(',')
|
|
74
|
-
.map((k) => sanitizeFilterValue(k.trim()))
|
|
75
|
-
.filter(Boolean);
|
|
76
|
-
const flavorFilters = keywords
|
|
77
|
-
.flatMap((kw) => [
|
|
78
|
-
`description_short.ilike.%${kw}%`,
|
|
79
|
-
`description_long.ilike.%${kw}%`,
|
|
80
|
-
`cupping_notes.ilike.%${kw}%`,
|
|
81
|
-
`farm_notes.ilike.%${kw}%`,
|
|
82
|
-
])
|
|
83
|
-
.join(',');
|
|
84
|
-
query = query.or(flavorFilters);
|
|
85
|
-
}
|
|
86
|
-
if (opts.stocked) {
|
|
87
|
-
query = query.eq('stocked', true);
|
|
88
|
-
}
|
|
89
|
-
const limit = Math.max(1, parseInt(opts.limit, 10));
|
|
90
|
-
const { data, error } = await query.limit(limit);
|
|
91
|
-
if (error)
|
|
92
|
-
throw error;
|
|
93
|
-
if (!data || data.length === 0) {
|
|
28
|
+
const data = await searchCatalog(supabase, {
|
|
29
|
+
origin: opts.origin,
|
|
30
|
+
process: opts.process,
|
|
31
|
+
priceMin: opts.priceMin !== undefined ? parseFloat(opts.priceMin) : undefined,
|
|
32
|
+
priceMax: opts.priceMax !== undefined ? parseFloat(opts.priceMax) : undefined,
|
|
33
|
+
flavor: opts.flavor,
|
|
34
|
+
stocked: opts.stocked ? true : undefined,
|
|
35
|
+
limit: Math.max(1, parseInt(opts.limit, 10)),
|
|
36
|
+
});
|
|
37
|
+
if (data.length === 0) {
|
|
94
38
|
info('No coffees found matching your criteria.');
|
|
95
39
|
return;
|
|
96
40
|
}
|
|
@@ -103,13 +47,7 @@ export function buildCatalogCommand() {
|
|
|
103
47
|
.action(withErrorHandling(async (id, _opts, cmd) => {
|
|
104
48
|
const globalOpts = cmd.optsWithGlobals();
|
|
105
49
|
const supabase = createAnonClient();
|
|
106
|
-
const
|
|
107
|
-
.from('coffee_catalog')
|
|
108
|
-
.select('*')
|
|
109
|
-
.eq('id', parseInt(id, 10))
|
|
110
|
-
.single();
|
|
111
|
-
if (error)
|
|
112
|
-
throw error;
|
|
50
|
+
const data = await getCatalog(supabase, parseInt(id, 10));
|
|
113
51
|
outputData(data, globalOpts);
|
|
114
52
|
}));
|
|
115
53
|
// ── catalog stats ─────────────────────────────────────────────────────────
|
|
@@ -119,12 +57,7 @@ export function buildCatalogCommand() {
|
|
|
119
57
|
.action(withErrorHandling(async (_opts, cmd) => {
|
|
120
58
|
const globalOpts = cmd.optsWithGlobals();
|
|
121
59
|
const supabase = createAnonClient();
|
|
122
|
-
const
|
|
123
|
-
.from('coffee_catalog')
|
|
124
|
-
.select('id, country, continent, cost_lb, stocked');
|
|
125
|
-
if (error)
|
|
126
|
-
throw error;
|
|
127
|
-
const stats = computeCatalogStats((data ?? []));
|
|
60
|
+
const stats = await getCatalogStats(supabase);
|
|
128
61
|
outputData(stats, globalOpts);
|
|
129
62
|
}));
|
|
130
63
|
return catalog;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/commands/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/commands/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
rank: number | null;
|
|
5
|
-
notes: string | null;
|
|
6
|
-
cupping_notes: string | null;
|
|
7
|
-
purchase_date: string | null;
|
|
8
|
-
purchased_qty_lbs: number | null;
|
|
9
|
-
bean_cost: number | null;
|
|
10
|
-
tax_ship_cost: number | null;
|
|
11
|
-
last_updated: string;
|
|
12
|
-
user: string;
|
|
13
|
-
catalog_id: number | null;
|
|
14
|
-
stocked: boolean | null;
|
|
15
|
-
coffee_catalog: {
|
|
16
|
-
id: number;
|
|
17
|
-
name: string | null;
|
|
18
|
-
source: string | null;
|
|
19
|
-
country: string | null;
|
|
20
|
-
region: string | null;
|
|
21
|
-
processing: string | null;
|
|
22
|
-
cost_lb: number | null;
|
|
23
|
-
description_short: string | null;
|
|
24
|
-
stocked: boolean | null;
|
|
25
|
-
} | null;
|
|
26
|
-
}
|
|
2
|
+
import type { InventoryItem } from '../lib/inventory.js';
|
|
3
|
+
export type { InventoryItem };
|
|
27
4
|
/**
|
|
28
5
|
* `purvey inventory` — Manage your green coffee inventory.
|
|
29
6
|
* Requires authentication.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../../src/commands/inventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../../src/commands/inventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIzD,YAAY,EAAE,aAAa,EAAE,CAAC;AAI9B;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CA+O/C"}
|
|
@@ -3,22 +3,7 @@ import { createAuthenticatedClient } from '../lib/supabase.js';
|
|
|
3
3
|
import { outputData, info, success } from '../lib/output.js';
|
|
4
4
|
import { withErrorHandling, AuthError, PrvrsError } from '../lib/errors.js';
|
|
5
5
|
import { confirm, todayIso } from '../lib/prompts.js';
|
|
6
|
-
|
|
7
|
-
const LIST_SELECT = [
|
|
8
|
-
'id',
|
|
9
|
-
'rank',
|
|
10
|
-
'notes',
|
|
11
|
-
'cupping_notes',
|
|
12
|
-
'purchase_date',
|
|
13
|
-
'purchased_qty_lbs',
|
|
14
|
-
'bean_cost',
|
|
15
|
-
'tax_ship_cost',
|
|
16
|
-
'last_updated',
|
|
17
|
-
'user',
|
|
18
|
-
'catalog_id',
|
|
19
|
-
'stocked',
|
|
20
|
-
'coffee_catalog!catalog_id (id, name, source, country, region, processing, cost_lb, description_short, stocked)',
|
|
21
|
-
].join(', ');
|
|
6
|
+
import { listInventory, getInventory, addInventory, updateInventory, deleteInventory, } from '../lib/inventory.js';
|
|
22
7
|
// ─── Command builder ──────────────────────────────────────────────────────────
|
|
23
8
|
/**
|
|
24
9
|
* `purvey inventory` — Manage your green coffee inventory.
|
|
@@ -39,17 +24,11 @@ export function buildInventoryCommand() {
|
|
|
39
24
|
if (!user) {
|
|
40
25
|
throw new AuthError('Not logged in. Run `purvey auth login` first.');
|
|
41
26
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const { data, error } = await query
|
|
48
|
-
.order('last_updated', { ascending: false })
|
|
49
|
-
.limit(limit);
|
|
50
|
-
if (error)
|
|
51
|
-
throw error;
|
|
52
|
-
if (!data || data.length === 0) {
|
|
27
|
+
const data = await listInventory(supabase, user.id, {
|
|
28
|
+
stocked: opts.stocked ? true : undefined,
|
|
29
|
+
limit: Math.max(1, parseInt(opts.limit, 10)),
|
|
30
|
+
});
|
|
31
|
+
if (data.length === 0) {
|
|
53
32
|
info('No inventory items found.');
|
|
54
33
|
return;
|
|
55
34
|
}
|
|
@@ -66,33 +45,7 @@ export function buildInventoryCommand() {
|
|
|
66
45
|
if (!user) {
|
|
67
46
|
throw new AuthError('Not logged in. Run `purvey auth login` first.');
|
|
68
47
|
}
|
|
69
|
-
const
|
|
70
|
-
'id',
|
|
71
|
-
'rank',
|
|
72
|
-
'notes',
|
|
73
|
-
'cupping_notes',
|
|
74
|
-
'purchase_date',
|
|
75
|
-
'purchased_qty_lbs',
|
|
76
|
-
'bean_cost',
|
|
77
|
-
'tax_ship_cost',
|
|
78
|
-
'last_updated',
|
|
79
|
-
'user',
|
|
80
|
-
'catalog_id',
|
|
81
|
-
'stocked',
|
|
82
|
-
'coffee_catalog!catalog_id (id, name, source, country, region, processing, cost_lb, description_short, description_long, farm_notes, cupping_notes, stocked)',
|
|
83
|
-
].join(', ');
|
|
84
|
-
const { data, error } = await supabase
|
|
85
|
-
.from('green_coffee_inv')
|
|
86
|
-
.select(selectColumns)
|
|
87
|
-
.eq('id', parseInt(id, 10))
|
|
88
|
-
.eq('user', user.id)
|
|
89
|
-
.single();
|
|
90
|
-
if (error) {
|
|
91
|
-
if (error.code === 'PGRST116') {
|
|
92
|
-
throw new AuthError(`Inventory item ${id} not found or does not belong to you.`);
|
|
93
|
-
}
|
|
94
|
-
throw error;
|
|
95
|
-
}
|
|
48
|
+
const data = await getInventory(supabase, user.id, parseInt(id, 10));
|
|
96
49
|
outputData(data, globalOpts);
|
|
97
50
|
}));
|
|
98
51
|
// ── inventory add ─────────────────────────────────────────────────────────
|
|
@@ -120,43 +73,23 @@ export function buildInventoryCommand() {
|
|
|
120
73
|
if (isNaN(qty) || qty <= 0) {
|
|
121
74
|
throw new PrvrsError('INVALID_ARGUMENT', `Invalid --qty: "${opts.qty}". Must be a positive number.`);
|
|
122
75
|
}
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
if (opts.notes !== undefined) {
|
|
142
|
-
insertPayload.notes = opts.notes;
|
|
143
|
-
}
|
|
144
|
-
const { data: inserted, error: insertError } = await supabase
|
|
145
|
-
.from('green_coffee_inv')
|
|
146
|
-
.insert(insertPayload)
|
|
147
|
-
.select('id')
|
|
148
|
-
.single();
|
|
149
|
-
if (insertError)
|
|
150
|
-
throw insertError;
|
|
151
|
-
// Re-fetch the full row with catalog join
|
|
152
|
-
const { data, error } = await supabase
|
|
153
|
-
.from('green_coffee_inv')
|
|
154
|
-
.select(LIST_SELECT)
|
|
155
|
-
.eq('id', inserted.id)
|
|
156
|
-
.single();
|
|
157
|
-
if (error)
|
|
158
|
-
throw error;
|
|
159
|
-
success(`Inventory item ${inserted.id} created.`);
|
|
76
|
+
const cost = opts.cost !== undefined ? parseFloat(opts.cost) : undefined;
|
|
77
|
+
if (cost !== undefined && isNaN(cost)) {
|
|
78
|
+
throw new PrvrsError('INVALID_ARGUMENT', `Invalid --cost: "${opts.cost}".`);
|
|
79
|
+
}
|
|
80
|
+
const taxShip = opts.taxShip !== undefined ? parseFloat(opts.taxShip) : undefined;
|
|
81
|
+
if (taxShip !== undefined && isNaN(taxShip)) {
|
|
82
|
+
throw new PrvrsError('INVALID_ARGUMENT', `Invalid --tax-ship: "${opts.taxShip}".`);
|
|
83
|
+
}
|
|
84
|
+
const data = await addInventory(supabase, user.id, {
|
|
85
|
+
catalogId,
|
|
86
|
+
qty,
|
|
87
|
+
cost,
|
|
88
|
+
taxShip,
|
|
89
|
+
notes: opts.notes,
|
|
90
|
+
purchaseDate: opts.purchaseDate ?? todayIso(),
|
|
91
|
+
});
|
|
92
|
+
success(`Inventory item ${data.id} created.`);
|
|
160
93
|
outputData(data, globalOpts);
|
|
161
94
|
}));
|
|
162
95
|
// ── inventory update <id> ─────────────────────────────────────────────────
|
|
@@ -179,64 +112,47 @@ export function buildInventoryCommand() {
|
|
|
179
112
|
if (isNaN(itemId)) {
|
|
180
113
|
throw new PrvrsError('INVALID_ARGUMENT', `Invalid inventory ID: "${id}".`);
|
|
181
114
|
}
|
|
182
|
-
//
|
|
183
|
-
|
|
184
|
-
.from('green_coffee_inv')
|
|
185
|
-
.select('id')
|
|
186
|
-
.eq('id', itemId)
|
|
187
|
-
.eq('user', user.id)
|
|
188
|
-
.single();
|
|
189
|
-
if (fetchError || !existing) {
|
|
190
|
-
throw new AuthError(`Inventory item ${id} not found or does not belong to you.`);
|
|
191
|
-
}
|
|
192
|
-
// Build partial update — only include fields that were explicitly passed
|
|
193
|
-
const updates = {};
|
|
115
|
+
// Parse CLI strings into typed values
|
|
116
|
+
let qty;
|
|
194
117
|
if (opts.qty !== undefined) {
|
|
195
|
-
|
|
118
|
+
qty = parseFloat(opts.qty);
|
|
196
119
|
if (isNaN(qty) || qty <= 0)
|
|
197
120
|
throw new PrvrsError('INVALID_ARGUMENT', `Invalid --qty: "${opts.qty}".`);
|
|
198
|
-
updates.purchased_qty_lbs = qty;
|
|
199
121
|
}
|
|
122
|
+
let cost;
|
|
200
123
|
if (opts.cost !== undefined) {
|
|
201
|
-
|
|
124
|
+
cost = parseFloat(opts.cost);
|
|
202
125
|
if (isNaN(cost))
|
|
203
126
|
throw new PrvrsError('INVALID_ARGUMENT', `Invalid --cost: "${opts.cost}".`);
|
|
204
|
-
updates.bean_cost = cost;
|
|
205
127
|
}
|
|
128
|
+
let taxShip;
|
|
206
129
|
if (opts.taxShip !== undefined) {
|
|
207
|
-
|
|
130
|
+
taxShip = parseFloat(opts.taxShip);
|
|
208
131
|
if (isNaN(taxShip))
|
|
209
132
|
throw new PrvrsError('INVALID_ARGUMENT', `Invalid --tax-ship: "${opts.taxShip}".`);
|
|
210
|
-
updates.tax_ship_cost = taxShip;
|
|
211
|
-
}
|
|
212
|
-
if (opts.notes !== undefined) {
|
|
213
|
-
updates.notes = opts.notes;
|
|
214
133
|
}
|
|
134
|
+
let stocked;
|
|
215
135
|
if (opts.stocked !== undefined) {
|
|
216
136
|
const stockedStr = opts.stocked.toLowerCase();
|
|
217
137
|
if (stockedStr !== 'true' && stockedStr !== 'false') {
|
|
218
138
|
throw new PrvrsError('INVALID_ARGUMENT', `--stocked must be "true" or "false".`);
|
|
219
139
|
}
|
|
220
|
-
|
|
140
|
+
stocked = stockedStr === 'true';
|
|
221
141
|
}
|
|
222
|
-
if (
|
|
142
|
+
if (qty === undefined &&
|
|
143
|
+
cost === undefined &&
|
|
144
|
+
taxShip === undefined &&
|
|
145
|
+
opts.notes === undefined &&
|
|
146
|
+
stocked === undefined) {
|
|
223
147
|
throw new PrvrsError('INVALID_ARGUMENT', 'No update fields provided. Pass at least one of: --qty, --cost, --tax-ship, --notes, --stocked.');
|
|
224
148
|
}
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
.
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
// Re-fetch the updated row
|
|
233
|
-
const { data, error } = await supabase
|
|
234
|
-
.from('green_coffee_inv')
|
|
235
|
-
.select(LIST_SELECT)
|
|
236
|
-
.eq('id', itemId)
|
|
237
|
-
.single();
|
|
238
|
-
if (error)
|
|
239
|
-
throw error;
|
|
149
|
+
const data = await updateInventory(supabase, user.id, itemId, {
|
|
150
|
+
qty,
|
|
151
|
+
cost,
|
|
152
|
+
taxShip,
|
|
153
|
+
notes: opts.notes,
|
|
154
|
+
stocked,
|
|
155
|
+
});
|
|
240
156
|
success(`Inventory item ${itemId} updated.`);
|
|
241
157
|
outputData(data, globalOpts);
|
|
242
158
|
}));
|
|
@@ -246,7 +162,7 @@ export function buildInventoryCommand() {
|
|
|
246
162
|
.description('Delete an inventory item (must be yours)')
|
|
247
163
|
.option('-y, --yes', 'Skip confirmation prompt')
|
|
248
164
|
.action(withErrorHandling(async (id, opts, cmd) => {
|
|
249
|
-
void cmd;
|
|
165
|
+
void cmd;
|
|
250
166
|
const supabase = await createAuthenticatedClient();
|
|
251
167
|
const { data: { user }, } = await supabase.auth.getUser();
|
|
252
168
|
if (!user) {
|
|
@@ -256,16 +172,6 @@ export function buildInventoryCommand() {
|
|
|
256
172
|
if (isNaN(itemId)) {
|
|
257
173
|
throw new PrvrsError('INVALID_ARGUMENT', `Invalid inventory ID: "${id}".`);
|
|
258
174
|
}
|
|
259
|
-
// Verify ownership
|
|
260
|
-
const { data: existing, error: fetchError } = await supabase
|
|
261
|
-
.from('green_coffee_inv')
|
|
262
|
-
.select('id, catalog_id')
|
|
263
|
-
.eq('id', itemId)
|
|
264
|
-
.eq('user', user.id)
|
|
265
|
-
.single();
|
|
266
|
-
if (fetchError || !existing) {
|
|
267
|
-
throw new AuthError(`Inventory item ${id} not found or does not belong to you.`);
|
|
268
|
-
}
|
|
269
175
|
if (!opts.yes) {
|
|
270
176
|
const ok = await confirm(`Delete inventory item ${itemId}?`);
|
|
271
177
|
if (!ok) {
|
|
@@ -273,13 +179,7 @@ export function buildInventoryCommand() {
|
|
|
273
179
|
return;
|
|
274
180
|
}
|
|
275
181
|
}
|
|
276
|
-
|
|
277
|
-
.from('green_coffee_inv')
|
|
278
|
-
.delete()
|
|
279
|
-
.eq('id', itemId)
|
|
280
|
-
.eq('user', user.id);
|
|
281
|
-
if (deleteError)
|
|
282
|
-
throw deleteError;
|
|
182
|
+
await deleteInventory(supabase, user.id, itemId);
|
|
283
183
|
success(`Inventory item ${itemId} deleted.`);
|
|
284
184
|
}));
|
|
285
185
|
return inventory;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inventory.js","sourceRoot":"","sources":["../../src/commands/inventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"inventory.js","sourceRoot":"","sources":["../../src/commands/inventory.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/roast.d.ts
CHANGED
|
@@ -1,45 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
batch_name: string | null;
|
|
5
|
-
coffee_id: number | null;
|
|
6
|
-
coffee_name: string | null;
|
|
7
|
-
roast_date: string | null;
|
|
8
|
-
oz_in: number | null;
|
|
9
|
-
oz_out: number | null;
|
|
10
|
-
weight_loss_percent: number | null;
|
|
11
|
-
roast_notes: string | null;
|
|
12
|
-
user: string;
|
|
13
|
-
last_updated: string;
|
|
14
|
-
roaster_type: string | null;
|
|
15
|
-
roaster_size: string | null;
|
|
16
|
-
temperature_unit: string | null;
|
|
17
|
-
charge_time: number | null;
|
|
18
|
-
drop_time: number | null;
|
|
19
|
-
fc_start_time: number | null;
|
|
20
|
-
fc_end_time: number | null;
|
|
21
|
-
fc_start_temp: number | null;
|
|
22
|
-
drop_temp: number | null;
|
|
23
|
-
charge_temp: number | null;
|
|
24
|
-
dry_percent: number | null;
|
|
25
|
-
maillard_percent: number | null;
|
|
26
|
-
development_percent: number | null;
|
|
27
|
-
total_roast_time: number | null;
|
|
28
|
-
data_source: string | null;
|
|
29
|
-
roast_uuid: string | null;
|
|
30
|
-
}
|
|
31
|
-
export interface TemperatureEntry {
|
|
32
|
-
roast_id: number;
|
|
33
|
-
time_seconds: number;
|
|
34
|
-
bean_temp: number | null;
|
|
35
|
-
environmental_temp: number | null;
|
|
36
|
-
}
|
|
37
|
-
export interface RoastEventEntry {
|
|
38
|
-
roast_id: number;
|
|
39
|
-
time_seconds: number;
|
|
40
|
-
event_type: number | null;
|
|
41
|
-
event_value: string | null;
|
|
42
|
-
}
|
|
2
|
+
import type { RoastProfile, TemperatureEntry, RoastEventEntry } from '../lib/roast.js';
|
|
3
|
+
export type { RoastProfile, TemperatureEntry, RoastEventEntry };
|
|
43
4
|
/**
|
|
44
5
|
* `purvey roast` — Browse and manage your roast profiles.
|
|
45
6
|
* Requires authentication.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roast.d.ts","sourceRoot":"","sources":["../../src/commands/roast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"roast.d.ts","sourceRoot":"","sources":["../../src/commands/roast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAEhB,MAAM,iBAAiB,CAAC;AAIzB,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;AAIhE;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAiO3C"}
|