@purveyors/cli 0.27.0 → 0.30.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/README.md +39 -44
- package/dist/commands/auth.d.ts +6 -2
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +119 -71
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/inventory.js +1 -1
- package/dist/commands/inventory.js.map +1 -1
- package/dist/commands/roast.d.ts +3 -3
- package/dist/commands/roast.d.ts.map +1 -1
- package/dist/commands/roast.js +15 -18
- package/dist/commands/roast.js.map +1 -1
- package/dist/commands/sales.d.ts +17 -1
- package/dist/commands/sales.d.ts.map +1 -1
- package/dist/commands/sales.js +23 -20
- package/dist/commands/sales.js.map +1 -1
- package/dist/commands/tasting.d.ts.map +1 -1
- package/dist/commands/tasting.js +19 -7
- package/dist/commands/tasting.js.map +1 -1
- package/dist/lib/ai.d.ts +2 -2
- package/dist/lib/ai.d.ts.map +1 -1
- package/dist/lib/ai.js.map +1 -1
- package/dist/lib/auth-client.d.ts +33 -0
- package/dist/lib/auth-client.d.ts.map +1 -0
- package/dist/lib/auth-client.js +63 -0
- package/dist/lib/auth-client.js.map +1 -0
- package/dist/lib/auth-guard.d.ts +3 -3
- package/dist/lib/auth-guard.d.ts.map +1 -1
- package/dist/lib/auth-guard.js +2 -2
- package/dist/lib/auth-guard.js.map +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +23 -2
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/interactive/forms.d.ts +3 -4
- package/dist/lib/interactive/forms.d.ts.map +1 -1
- package/dist/lib/interactive/forms.js +15 -36
- package/dist/lib/interactive/forms.js.map +1 -1
- package/dist/lib/interactive/watch.d.ts +5 -2
- package/dist/lib/interactive/watch.d.ts.map +1 -1
- package/dist/lib/interactive/watch.js +35 -15
- package/dist/lib/interactive/watch.js.map +1 -1
- package/dist/lib/inventory.d.ts +2 -2
- package/dist/lib/inventory.d.ts.map +1 -1
- package/dist/lib/inventory.js +4 -4
- package/dist/lib/inventory.js.map +1 -1
- package/dist/lib/manifest.d.ts.map +1 -1
- package/dist/lib/manifest.js +13 -12
- package/dist/lib/manifest.js.map +1 -1
- package/dist/lib/market.d.ts.map +1 -1
- package/dist/lib/parchment.d.ts +4 -4
- package/dist/lib/parchment.js +4 -4
- package/dist/lib/sales.d.ts +6 -17
- package/dist/lib/sales.d.ts.map +1 -1
- package/dist/lib/sales.js +87 -129
- package/dist/lib/sales.js.map +1 -1
- package/dist/lib/tasting.d.ts +3 -4
- package/dist/lib/tasting.d.ts.map +1 -1
- package/dist/lib/tasting.js +9 -41
- package/dist/lib/tasting.js.map +1 -1
- package/dist/program.js +1 -1
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +3 -5
- package/dist/lib/supabase.d.ts +0 -22
- package/dist/lib/supabase.d.ts.map +0 -1
- package/dist/lib/supabase.js +0 -108
- package/dist/lib/supabase.js.map +0 -1
- package/dist/types/database.types.d.ts +0 -13
- package/dist/types/database.types.d.ts.map +0 -1
- package/dist/types/database.types.js +0 -8
- package/dist/types/database.types.js.map +0 -1
package/dist/lib/sales.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
3
2
|
export interface Sale {
|
|
4
3
|
id: number;
|
|
5
4
|
roast_id?: number | null;
|
|
@@ -17,6 +16,8 @@ export interface Sale {
|
|
|
17
16
|
wholesale?: boolean;
|
|
18
17
|
}
|
|
19
18
|
export interface ResolvedSaleTarget {
|
|
19
|
+
greenCoffeeInvId?: number;
|
|
20
|
+
batchName?: string;
|
|
20
21
|
roastId: number;
|
|
21
22
|
mode: 'exact' | 'resolved';
|
|
22
23
|
}
|
|
@@ -57,21 +58,9 @@ export declare const deleteSaleSchema: z.ZodObject<{
|
|
|
57
58
|
id: z.ZodNumber;
|
|
58
59
|
}, z.core.$strip>;
|
|
59
60
|
export type DeleteSaleInput = z.input<typeof deleteSaleSchema>;
|
|
60
|
-
/**
|
|
61
|
-
* List sales for a user (newest first, with roast profile join).
|
|
62
|
-
*/
|
|
63
61
|
export declare function listSales(opts?: ListSalesInput, tokenOverride?: string): Promise<Sale[]>;
|
|
64
|
-
export declare function resolveSaleRoast(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
export declare function recordSale(supabase: SupabaseClient, userId: string, input: RecordSaleInput): Promise<Sale>;
|
|
69
|
-
/**
|
|
70
|
-
* Update an existing sale (must belong to userId).
|
|
71
|
-
*/
|
|
72
|
-
export declare function updateSale(supabase: SupabaseClient, userId: string, id: number, input: UpdateSaleInput): Promise<Sale>;
|
|
73
|
-
/**
|
|
74
|
-
* Delete a sale (must belong to userId).
|
|
75
|
-
*/
|
|
76
|
-
export declare function deleteSale(supabase: SupabaseClient, userId: string, id: number): Promise<void>;
|
|
62
|
+
export declare function resolveSaleRoast(input: SaleTargetSelectorInput, tokenOverride?: string): Promise<ResolvedSaleTarget>;
|
|
63
|
+
export declare function recordSale(input: RecordSaleInput, tokenOverride?: string): Promise<Sale>;
|
|
64
|
+
export declare function updateSale(id: number, input: UpdateSaleInput, tokenOverride?: string): Promise<Sale>;
|
|
65
|
+
export declare function deleteSale(id: number, tokenOverride?: string): Promise<void>;
|
|
77
66
|
//# sourceMappingURL=sales.d.ts.map
|
package/dist/lib/sales.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sales.d.ts","sourceRoot":"","sources":["../../src/lib/sales.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sales.d.ts","sourceRoot":"","sources":["../../src/lib/sales.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;CAC5B;AAED,eAAO,MAAM,WAAW,4EACmD,CAAC;AAE5E,eAAO,MAAM,eAAe;;;;;;;iBAO1B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAwC7D,eAAO,MAAM,wBAAwB;;;;iBAEK,CAAC;AAC3C,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE/E,eAAO,MAAM,gBAAgB;;;;;;;;iBAQa,CAAC;AAC3C,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE/D,eAAO,MAAM,gBAAgB;;;;;iBASzB,CAAC;AACL,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE/D,eAAO,MAAM,gBAAgB;;iBAAgD,CAAC;AAC9E,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAgD/D,wBAAsB,SAAS,CAC7B,IAAI,GAAE,cAAmB,EACzB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,EAAE,CAAC,CAejB;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,uBAAuB,EAC9B,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,kBAAkB,CAAC,CAoD7B;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,eAAe,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB9F;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,eAAe,EACtB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOlF"}
|
package/dist/lib/sales.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
+
import { PrvrsError } from './errors.js';
|
|
3
4
|
import { createParchmentClient, unwrapParchment } from './parchment.js';
|
|
4
|
-
// ─── Shared select columns ────────────────────────────────────────────────────
|
|
5
5
|
export const SALE_SELECT = 'id, roast_id, oz_sold, sale_price, buyer, sell_date, user, last_updated';
|
|
6
|
-
// ─── Zod schemas ──────────────────────────────────────────────────────────────
|
|
7
6
|
export const listSalesSchema = z.object({
|
|
8
7
|
limit: z.number().int().min(1).default(20),
|
|
9
8
|
offset: z.number().int().min(0).optional(),
|
|
@@ -64,16 +63,38 @@ export const updateSaleSchema = z
|
|
|
64
63
|
buyer: z.string().optional(),
|
|
65
64
|
sellDate: z.string().optional(),
|
|
66
65
|
})
|
|
67
|
-
.refine((v) => Object.
|
|
66
|
+
.refine((v) => Object.values(v).some((value) => value !== undefined), {
|
|
68
67
|
message: 'No update fields provided. Pass at least one of: oz, price, buyer, sellDate.',
|
|
69
68
|
});
|
|
70
|
-
export const deleteSaleSchema = z.object({
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
69
|
+
export const deleteSaleSchema = z.object({ id: z.number().int().positive() });
|
|
70
|
+
async function listExactSaleRoastMatches(client, coffeeId, batchName) {
|
|
71
|
+
const exactMatches = [];
|
|
72
|
+
const pageSize = 100;
|
|
73
|
+
let offset = 0;
|
|
74
|
+
const seenRoastIds = new Set();
|
|
75
|
+
do {
|
|
76
|
+
const envelope = unwrapParchment(await client.roasts.list({
|
|
77
|
+
coffee_id: coffeeId,
|
|
78
|
+
batch_name: batchName,
|
|
79
|
+
limit: pageSize,
|
|
80
|
+
offset,
|
|
81
|
+
}), 'Sale roast selector');
|
|
82
|
+
const rows = envelope.data;
|
|
83
|
+
if (rows.length === 0)
|
|
84
|
+
break;
|
|
85
|
+
const unseenRows = rows.filter((row) => !seenRoastIds.has(row.roast_id));
|
|
86
|
+
if (unseenRows.length === 0) {
|
|
87
|
+
throw new PrvrsError('GENERAL_ERROR', 'Sale roast selector pagination did not advance. Retry the request.');
|
|
88
|
+
}
|
|
89
|
+
for (const row of unseenRows)
|
|
90
|
+
seenRoastIds.add(row.roast_id);
|
|
91
|
+
exactMatches.push(...unseenRows.filter((row) => row.coffee_id === coffeeId && (row.batch_name ?? undefined) === batchName));
|
|
92
|
+
if (exactMatches.length > 1)
|
|
93
|
+
break;
|
|
94
|
+
offset += unseenRows.length;
|
|
95
|
+
} while (true);
|
|
96
|
+
return exactMatches;
|
|
97
|
+
}
|
|
77
98
|
export async function listSales(opts = {}, tokenOverride) {
|
|
78
99
|
const parsed = listSalesSchema.parse(opts);
|
|
79
100
|
const client = await createParchmentClient('member', tokenOverride);
|
|
@@ -87,138 +108,75 @@ export async function listSales(opts = {}, tokenOverride) {
|
|
|
87
108
|
}), 'Sales list');
|
|
88
109
|
return envelope.data;
|
|
89
110
|
}
|
|
90
|
-
export async function resolveSaleRoast(
|
|
111
|
+
export async function resolveSaleRoast(input, tokenOverride) {
|
|
91
112
|
const parsed = saleTargetSelectorSchema.parse(input);
|
|
113
|
+
const client = await createParchmentClient('member', tokenOverride);
|
|
92
114
|
if (parsed.roastId !== undefined) {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
.single();
|
|
99
|
-
if (roastError || !roastExists) {
|
|
100
|
-
throw new AuthError(`Roast profile ${parsed.roastId} not found or does not belong to you.`);
|
|
115
|
+
const getRoast = Promise.resolve(client.roasts.get(String(parsed.roastId))).then((result) => unwrapParchment(result, 'Sale roast selector'));
|
|
116
|
+
const envelope = await getRoast;
|
|
117
|
+
const roast = envelope.data;
|
|
118
|
+
if (roast.coffee_id == null) {
|
|
119
|
+
throw new PrvrsError('INVALID_ARGUMENT', `Roast profile ${parsed.roastId} is not linked to a green coffee inventory item.`);
|
|
101
120
|
}
|
|
102
|
-
|
|
121
|
+
const batchName = roast.batch_name ?? undefined;
|
|
122
|
+
const exactMatches = await listExactSaleRoastMatches(client, roast.coffee_id, batchName);
|
|
123
|
+
if (exactMatches.length > 1) {
|
|
124
|
+
throw new PrvrsError('INVALID_ARGUMENT', `Roast profile ${parsed.roastId} shares inventory item ${roast.coffee_id} and batch name "${batchName ?? ''}" with roast IDs ${exactMatches.map((row) => row.roast_id).join(', ')}. The canonical sales record cannot retain a roast ID; give each roast a unique batch name before recording this sale.`);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
greenCoffeeInvId: roast.coffee_id,
|
|
128
|
+
batchName,
|
|
129
|
+
roastId: roast.roast_id,
|
|
130
|
+
mode: 'exact',
|
|
131
|
+
};
|
|
103
132
|
}
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
.select('roast_id, batch_name')
|
|
107
|
-
.eq('user', userId)
|
|
108
|
-
.eq('coffee_id', parsed.coffeeId)
|
|
109
|
-
.eq('batch_name', parsed.batchName)
|
|
110
|
-
.limit(2);
|
|
111
|
-
if (lookupError)
|
|
112
|
-
throw lookupError;
|
|
113
|
-
const resolvedMatches = (matches ?? []);
|
|
114
|
-
if (resolvedMatches.length === 0) {
|
|
133
|
+
const exactMatches = await listExactSaleRoastMatches(client, parsed.coffeeId, parsed.batchName);
|
|
134
|
+
if (exactMatches.length === 0) {
|
|
115
135
|
throw new PrvrsError('NOT_FOUND', `No roast profile found for --coffee-id ${parsed.coffeeId} with batch name "${parsed.batchName}". Use 'purvey roast list --coffee-id ${parsed.coffeeId}' to inspect candidates, or pass --roast-id directly.`);
|
|
116
136
|
}
|
|
117
|
-
if (
|
|
118
|
-
|
|
119
|
-
throw new PrvrsError('INVALID_ARGUMENT', `Multiple roast profiles match --coffee-id ${parsed.coffeeId} and batch name "${parsed.batchName}". Matching roast IDs: ${matchIds}. Re-run with --roast-id.`);
|
|
137
|
+
if (exactMatches.length > 1) {
|
|
138
|
+
throw new PrvrsError('INVALID_ARGUMENT', `Multiple roast profiles match --coffee-id ${parsed.coffeeId} and batch name "${parsed.batchName}". Matching roast IDs: ${exactMatches.map((row) => row.roast_id).join(', ')}. The canonical sales record cannot retain a roast ID; give each roast a unique batch name before recording this sale.`);
|
|
120
139
|
}
|
|
121
|
-
return {
|
|
140
|
+
return {
|
|
141
|
+
greenCoffeeInvId: parsed.coffeeId,
|
|
142
|
+
batchName: parsed.batchName,
|
|
143
|
+
roastId: exactMatches[0].roast_id,
|
|
144
|
+
mode: 'resolved',
|
|
145
|
+
};
|
|
122
146
|
}
|
|
123
|
-
|
|
124
|
-
* Record a new sale (target roast must belong to userId).
|
|
125
|
-
*/
|
|
126
|
-
export async function recordSale(supabase, userId, input) {
|
|
147
|
+
export async function recordSale(input, tokenOverride) {
|
|
127
148
|
const parsed = recordSaleSchema.parse(input);
|
|
128
|
-
const target = await resolveSaleRoast(
|
|
129
|
-
const
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
149
|
+
const target = await resolveSaleRoast(parsed, tokenOverride);
|
|
150
|
+
const client = await createParchmentClient('member', tokenOverride);
|
|
151
|
+
const body = {
|
|
152
|
+
greenCoffeeInvId: target.greenCoffeeInvId,
|
|
153
|
+
ozSold: parsed.oz,
|
|
154
|
+
price: parsed.price,
|
|
155
|
+
...(parsed.buyer !== undefined ? { buyer: parsed.buyer } : {}),
|
|
156
|
+
...(target.batchName !== undefined ? { batchName: target.batchName } : {}),
|
|
157
|
+
...(parsed.sellDate !== undefined ? { sellDate: parsed.sellDate } : {}),
|
|
136
158
|
};
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const { data: inserted, error: insertError } = await supabase
|
|
140
|
-
.from('sales')
|
|
141
|
-
.insert(insertPayload)
|
|
142
|
-
.select('id')
|
|
143
|
-
.single();
|
|
144
|
-
if (insertError)
|
|
145
|
-
throw insertError;
|
|
146
|
-
// Re-fetch the full row with roast join
|
|
147
|
-
const { data, error } = await supabase
|
|
148
|
-
.from('sales')
|
|
149
|
-
.select(`${SALE_SELECT}, roast_profiles!roast_id (batch_name, coffee_name)`)
|
|
150
|
-
.eq('id', inserted.id)
|
|
151
|
-
.single();
|
|
152
|
-
if (error)
|
|
153
|
-
throw error;
|
|
154
|
-
return data;
|
|
159
|
+
const envelope = unwrapParchment(await client.sales.create(body, { idempotencyKey: randomUUID() }), 'Sale create');
|
|
160
|
+
return envelope.data;
|
|
155
161
|
}
|
|
156
|
-
|
|
157
|
-
* Update an existing sale (must belong to userId).
|
|
158
|
-
*/
|
|
159
|
-
export async function updateSale(supabase, userId, id, input) {
|
|
162
|
+
export async function updateSale(id, input, tokenOverride) {
|
|
160
163
|
deleteSaleSchema.parse({ id });
|
|
161
164
|
const parsed = updateSaleSchema.parse(input);
|
|
162
|
-
|
|
163
|
-
const
|
|
164
|
-
.
|
|
165
|
-
.
|
|
166
|
-
.
|
|
167
|
-
.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const updates = {};
|
|
173
|
-
if (parsed.oz !== undefined)
|
|
174
|
-
updates.oz_sold = parsed.oz;
|
|
175
|
-
if (parsed.price !== undefined)
|
|
176
|
-
updates.sale_price = parsed.price;
|
|
177
|
-
if (parsed.buyer !== undefined)
|
|
178
|
-
updates.buyer = parsed.buyer;
|
|
179
|
-
if (parsed.sellDate !== undefined)
|
|
180
|
-
updates.sell_date = parsed.sellDate;
|
|
181
|
-
if (Object.keys(updates).length === 0) {
|
|
182
|
-
throw new PrvrsError('INVALID_ARGUMENT', 'No update fields provided. Pass at least one of: oz, price, buyer, sellDate.');
|
|
183
|
-
}
|
|
184
|
-
const { error: updateError } = await supabase
|
|
185
|
-
.from('sales')
|
|
186
|
-
.update(updates)
|
|
187
|
-
.eq('id', id)
|
|
188
|
-
.eq('user', userId);
|
|
189
|
-
if (updateError)
|
|
190
|
-
throw updateError;
|
|
191
|
-
// Re-fetch the updated row
|
|
192
|
-
const { data, error } = await supabase
|
|
193
|
-
.from('sales')
|
|
194
|
-
.select(`${SALE_SELECT}, roast_profiles!roast_id (batch_name, coffee_name)`)
|
|
195
|
-
.eq('id', id)
|
|
196
|
-
.single();
|
|
197
|
-
if (error)
|
|
198
|
-
throw error;
|
|
199
|
-
return data;
|
|
165
|
+
const client = await createParchmentClient('member', tokenOverride);
|
|
166
|
+
const body = {
|
|
167
|
+
...(parsed.oz !== undefined ? { ozSold: parsed.oz } : {}),
|
|
168
|
+
...(parsed.price !== undefined ? { price: parsed.price } : {}),
|
|
169
|
+
...(parsed.buyer !== undefined ? { buyer: parsed.buyer } : {}),
|
|
170
|
+
...(parsed.sellDate !== undefined ? { sellDate: parsed.sellDate } : {}),
|
|
171
|
+
};
|
|
172
|
+
const update = Promise.resolve(client.sales.update(id, body)).then((result) => unwrapParchment(result, 'Sale update'));
|
|
173
|
+
const envelope = await update;
|
|
174
|
+
return envelope.data;
|
|
200
175
|
}
|
|
201
|
-
|
|
202
|
-
* Delete a sale (must belong to userId).
|
|
203
|
-
*/
|
|
204
|
-
export async function deleteSale(supabase, userId, id) {
|
|
176
|
+
export async function deleteSale(id, tokenOverride) {
|
|
205
177
|
deleteSaleSchema.parse({ id });
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
.select('id')
|
|
210
|
-
.eq('id', id)
|
|
211
|
-
.eq('user', userId)
|
|
212
|
-
.single();
|
|
213
|
-
if (fetchError || !existing) {
|
|
214
|
-
throw new AuthError(`Sale ${id} not found or does not belong to you.`);
|
|
215
|
-
}
|
|
216
|
-
const { error: deleteError } = await supabase
|
|
217
|
-
.from('sales')
|
|
218
|
-
.delete()
|
|
219
|
-
.eq('id', id)
|
|
220
|
-
.eq('user', userId);
|
|
221
|
-
if (deleteError)
|
|
222
|
-
throw deleteError;
|
|
178
|
+
const client = await createParchmentClient('member', tokenOverride);
|
|
179
|
+
const remove = Promise.resolve(client.sales.delete(id)).then((result) => unwrapParchment(result, 'Sale delete'));
|
|
180
|
+
await remove;
|
|
223
181
|
}
|
|
224
182
|
//# sourceMappingURL=sales.js.map
|
package/dist/lib/sales.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sales.js","sourceRoot":"","sources":["../../src/lib/sales.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sales.js","sourceRoot":"","sources":["../../src/lib/sales.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AA0BxE,MAAM,CAAC,MAAM,WAAW,GACtB,yEAAyE,CAAC;AAE5E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC1C,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACxD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC;AAGH,MAAM,gBAAgB,GAAG;IACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC/C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAChD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC/C,CAAC;AAEF,SAAS,0BAA0B,CACjC,KAAkE,EAClE,GAAoB;IAEpB,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC;IAC/C,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC;IACjD,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC;IACnD,IAAI,UAAU,IAAI,CAAC,WAAW,IAAI,YAAY,CAAC,EAAE,CAAC;QAChD,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,SAAS,CAAC;YACjB,OAAO,EAAE,uDAAuD;SACjE,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,IAAI,CAAC,UAAU,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,EAAE,CAAC;QACjD,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,SAAS,CAAC;YACjB,OAAO,EAAE,0CAA0C;SACpD,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,IAAI,CAAC,UAAU,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC;QAChD,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;YAChD,OAAO,EAAE,0EAA0E;SACpF,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC;KACtC,MAAM,CAAC,gBAAgB,CAAC;KACxB,WAAW,CAAC,0BAA0B,CAAC,CAAC;AAG3C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC;KAC9B,MAAM,CAAC;IACN,GAAG,gBAAgB;IACnB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC;KACD,WAAW,CAAC,0BAA0B,CAAC,CAAC;AAG3C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC;KAC9B,MAAM,CAAC;IACN,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACpC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACnC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC;KACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,EAAE;IACpE,OAAO,EAAE,8EAA8E;CACxF,CAAC,CAAC;AAGL,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAK9E,KAAK,UAAU,yBAAyB,CACtC,MAA4B,EAC5B,QAAgB,EAChB,SAA6B;IAE7B,MAAM,YAAY,GAIb,EAAE,CAAC;IACR,MAAM,QAAQ,GAAG,GAAG,CAAC;IACrB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,GAAG,CAAC;QACF,MAAM,QAAQ,GAAG,eAAe,CAC9B,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YACvB,SAAS,EAAE,QAAQ;YACnB,UAAU,EAAE,SAAS;YACrB,KAAK,EAAE,QAAQ;YACf,MAAM;SACP,CAAC,EACF,qBAAqB,CACtB,CAAC;QACF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM;QAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,oEAAoE,CACrE,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,UAAU;YAAE,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7D,YAAY,CAAC,IAAI,CACf,GAAG,UAAU,CAAC,MAAM,CAClB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,SAAS,CAAC,KAAK,SAAS,CACnF,CACF,CAAC;QACF,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM;QACnC,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC;IAC9B,CAAC,QAAQ,IAAI,EAAE;IACf,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAuB,EAAE,EACzB,aAAsB;IAEtB,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,eAAe,CAC9B,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;QACtB,mBAAmB,EAAE,MAAM,CAAC,gBAAgB;QAC5C,UAAU,EAAE,MAAM,CAAC,SAAS;QAC5B,QAAQ,EAAE,MAAM,CAAC,OAAO;QACxB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,EACF,YAAY,CACb,CAAC;IACF,OAAO,QAAQ,CAAC,IAAc,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAA8B,EAC9B,aAAsB;IAEtB,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAEpE,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAC1F,eAAe,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAC/C,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC;QAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC5B,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,EAAE,CAAC;YAC5B,MAAM,IAAI,UAAU,CAClB,kBAAkB,EAClB,iBAAiB,MAAM,CAAC,OAAO,kDAAkD,CAClF,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,IAAI,SAAS,CAAC;QAChD,MAAM,YAAY,GAAG,MAAM,yBAAyB,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACzF,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,UAAU,CAClB,kBAAkB,EAClB,iBAAiB,MAAM,CAAC,OAAO,0BAA0B,KAAK,CAAC,SAAS,oBAAoB,SAAS,IAAI,EAAE,oBAAoB,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,wHAAwH,CAC1S,CAAC;QACJ,CAAC;QACD,OAAO;YACL,gBAAgB,EAAE,KAAK,CAAC,SAAS;YACjC,SAAS;YACT,OAAO,EAAE,KAAK,CAAC,QAAQ;YACvB,IAAI,EAAE,OAAO;SACd,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,QAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAEjG,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,UAAU,CAClB,WAAW,EACX,0CAA0C,MAAM,CAAC,QAAQ,qBAAqB,MAAM,CAAC,SAAS,yCAAyC,MAAM,CAAC,QAAQ,uDAAuD,CAC9M,CAAC;IACJ,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAClB,kBAAkB,EAClB,6CAA6C,MAAM,CAAC,QAAQ,oBAAoB,MAAM,CAAC,SAAS,0BAA0B,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,wHAAwH,CACrS,CAAC;IACJ,CAAC;IACD,OAAO;QACL,gBAAgB,EAAE,MAAM,CAAC,QAAS;QAClC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ;QACjC,IAAI,EAAE,UAAU;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAsB,EAAE,aAAsB;IAC7E,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG;QACX,gBAAgB,EAAE,MAAM,CAAC,gBAAiB;QAC1C,MAAM,EAAE,MAAM,CAAC,EAAE;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxE,CAAC;IACF,MAAM,QAAQ,GAAG,eAAe,CAC9B,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,EAAE,CAAC,EACjE,aAAa,CACd,CAAC;IACF,OAAO,QAAQ,CAAC,IAAY,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,EAAU,EACV,KAAsB,EACtB,aAAsB;IAEtB,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG;QACX,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxE,CAAC;IACF,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAC5E,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC,CACvC,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC;IAC9B,OAAO,QAAQ,CAAC,IAAY,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,EAAU,EAAE,aAAsB;IACjE,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CACtE,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC,CACvC,CAAC;IACF,MAAM,MAAM,CAAC;AACf,CAAC"}
|
package/dist/lib/tasting.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import type
|
|
3
|
-
import type { InventoryItem } from './inventory.js';
|
|
2
|
+
import { type InventoryItem } from './inventory.js';
|
|
4
3
|
export type TastingFilter = 'user' | 'supplier' | 'both';
|
|
5
4
|
export interface SupplierTastingNotes {
|
|
6
5
|
source: 'supplier';
|
|
@@ -70,7 +69,7 @@ export declare function parseCuppingScore(raw: string, flag: string): number;
|
|
|
70
69
|
*/
|
|
71
70
|
export declare function getTastingNotes(id: number, filter?: TastingFilter): Promise<TastingData>;
|
|
72
71
|
/**
|
|
73
|
-
* Rate
|
|
72
|
+
* Rate an owned inventory lot through the canonical Parchment API.
|
|
74
73
|
*/
|
|
75
|
-
export declare function rateCoffee(
|
|
74
|
+
export declare function rateCoffee(id: number, input: RateCoffeeInput, tokenOverride?: string): Promise<InventoryItem>;
|
|
76
75
|
//# sourceMappingURL=tasting.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasting.d.ts","sourceRoot":"","sources":["../../src/lib/tasting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"tasting.d.ts","sourceRoot":"","sources":["../../src/lib/tasting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAKlE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,eAAO,MAAM,mBAAmB;;;;EAAuC,CAAC;AAExE,eAAO,MAAM,qBAAqB;;;;;;;iBAGhC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEzE,eAAO,MAAM,kBAAkB,aAAiC,CAAC;AAEjE,eAAO,MAAM,gBAAgB;;;;;;;;iBAQ3B,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAI/D,wDAAwD;AACxD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CASnE;AAID;;;GAGG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,MAAM,EACV,MAAM,GAAE,aAAsB,GAC7B,OAAO,CAAC,WAAW,CAAC,CAQtB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,eAAe,EACtB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,aAAa,CAAC,CAOxB"}
|
package/dist/lib/tasting.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
2
|
+
import { PrvrsError } from './errors.js';
|
|
3
|
+
import { getInventory } from './inventory.js';
|
|
3
4
|
import { createParchmentClient, unwrapParchment } from './parchment.js';
|
|
4
5
|
// ─── Zod schemas ──────────────────────────────────────────────────────────────
|
|
5
6
|
export const tastingFilterSchema = z.enum(['user', 'supplier', 'both']);
|
|
@@ -42,47 +43,14 @@ export async function getTastingNotes(id, filter = 'both') {
|
|
|
42
43
|
return envelope.data;
|
|
43
44
|
}
|
|
44
45
|
/**
|
|
45
|
-
* Rate
|
|
46
|
+
* Rate an owned inventory lot through the canonical Parchment API.
|
|
46
47
|
*/
|
|
47
|
-
export async function rateCoffee(
|
|
48
|
+
export async function rateCoffee(id, input, tokenOverride) {
|
|
48
49
|
const parsed = rateCoffeeSchema.parse(input);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
.eq('user', userId)
|
|
55
|
-
.single();
|
|
56
|
-
if (fetchError || !existing) {
|
|
57
|
-
throw new AuthError(`Inventory item ${id} not found or does not belong to you.`);
|
|
58
|
-
}
|
|
59
|
-
const cupping = {
|
|
60
|
-
aroma: parsed.aroma,
|
|
61
|
-
body: parsed.body,
|
|
62
|
-
acidity: parsed.acidity,
|
|
63
|
-
sweetness: parsed.sweetness,
|
|
64
|
-
aftertaste: parsed.aftertaste,
|
|
65
|
-
rated_at: new Date().toISOString(),
|
|
66
|
-
};
|
|
67
|
-
if (parsed.brewMethod !== undefined)
|
|
68
|
-
cupping.brew_method = parsed.brewMethod;
|
|
69
|
-
if (parsed.notes !== undefined)
|
|
70
|
-
cupping.notes = parsed.notes;
|
|
71
|
-
const { error: updateError } = await supabase
|
|
72
|
-
.from('green_coffee_inv')
|
|
73
|
-
.update({ cupping_notes: cupping })
|
|
74
|
-
.eq('id', id)
|
|
75
|
-
.eq('user', userId);
|
|
76
|
-
if (updateError)
|
|
77
|
-
throw updateError;
|
|
78
|
-
// Re-fetch the updated row
|
|
79
|
-
const { data, error } = await supabase
|
|
80
|
-
.from('green_coffee_inv')
|
|
81
|
-
.select('id, catalog_id, cupping_notes, notes, last_updated')
|
|
82
|
-
.eq('id', id)
|
|
83
|
-
.single();
|
|
84
|
-
if (error)
|
|
85
|
-
throw error;
|
|
86
|
-
return data;
|
|
50
|
+
const client = await createParchmentClient('member', tokenOverride);
|
|
51
|
+
unwrapParchment(await client.tasting.rate(id, parsed), 'Tasting rate');
|
|
52
|
+
// Preserve the public CLI/helper output contract: callers historically receive
|
|
53
|
+
// the refreshed inventory row rather than the mutation-specific API payload.
|
|
54
|
+
return getInventory(id, tokenOverride);
|
|
87
55
|
}
|
|
88
56
|
//# sourceMappingURL=tasting.js.map
|
package/dist/lib/tasting.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasting.js","sourceRoot":"","sources":["../../src/lib/tasting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"tasting.js","sourceRoot":"","sources":["../../src/lib/tasting.ts"],"names":[],"mappings":"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"}
|
package/dist/program.js
CHANGED
|
@@ -96,7 +96,7 @@ Market intelligence (canonical API; entitled slices require Parchment Intelligen
|
|
|
96
96
|
procurement get Get a saved sourcing brief by id
|
|
97
97
|
procurement matches Page through catalog matches for a brief
|
|
98
98
|
|
|
99
|
-
Local and reference commands (no pre-existing
|
|
99
|
+
Local and reference commands (no pre-existing credentials required):
|
|
100
100
|
config list Show all config values
|
|
101
101
|
config get Get a config value
|
|
102
102
|
config set Set a config value
|
package/dist/types/index.d.ts
CHANGED
|
@@ -7,9 +7,9 @@ export interface GlobalOptions {
|
|
|
7
7
|
json?: boolean;
|
|
8
8
|
}
|
|
9
9
|
export interface StoredCredentials {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
apiKey: string;
|
|
11
|
+
keyId: string;
|
|
12
|
+
createdAt: string;
|
|
13
13
|
user: {
|
|
14
14
|
id: string;
|
|
15
15
|
email: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAiB,SAAQ,QAAQ;IAChD,KAAK,EAAE,IAAI,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@purveyors/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "The official CLI for purveyors.io — coffee intelligence from your terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,8 +33,7 @@
|
|
|
33
33
|
"cli",
|
|
34
34
|
"purveyors",
|
|
35
35
|
"green-coffee",
|
|
36
|
-
"roasting"
|
|
37
|
-
"supabase"
|
|
36
|
+
"roasting"
|
|
38
37
|
],
|
|
39
38
|
"author": "Reed Whetstone",
|
|
40
39
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -57,8 +56,7 @@
|
|
|
57
56
|
},
|
|
58
57
|
"dependencies": {
|
|
59
58
|
"@clack/prompts": "^1.1.0",
|
|
60
|
-
"@purveyors/sdk": "^0.
|
|
61
|
-
"@supabase/supabase-js": "^2.49.1",
|
|
59
|
+
"@purveyors/sdk": "^0.9.0",
|
|
62
60
|
"chalk": "^5.4.1",
|
|
63
61
|
"commander": "^13.1.0",
|
|
64
62
|
"ora": "^8.2.0",
|
package/dist/lib/supabase.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { type SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
-
/**
|
|
3
|
-
* Create a Supabase client with no session (anonymous/unauthenticated).
|
|
4
|
-
* Used for login flows before we have a token.
|
|
5
|
-
*/
|
|
6
|
-
export declare function createAnonClient(): SupabaseClient;
|
|
7
|
-
/**
|
|
8
|
-
* Create a Supabase client initialized with stored credentials.
|
|
9
|
-
* Throws AuthError if no credentials are found.
|
|
10
|
-
*/
|
|
11
|
-
export declare function createAuthenticatedClient(): Promise<SupabaseClient>;
|
|
12
|
-
/**
|
|
13
|
-
* Validate stored credentials by making a lightweight Supabase auth call.
|
|
14
|
-
* Returns the user object if valid, null if expired/invalid.
|
|
15
|
-
*/
|
|
16
|
-
export declare function validateSession(): Promise<{
|
|
17
|
-
id: string;
|
|
18
|
-
email?: string;
|
|
19
|
-
role?: string;
|
|
20
|
-
expiresAt: number;
|
|
21
|
-
} | null>;
|
|
22
|
-
//# sourceMappingURL=supabase.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/lib/supabase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAiB1E;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,CAOjD;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,cAAc,CAAC,CAuCzE;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CAAC,CA+CR"}
|