whale-code 6.5.7 → 6.5.9
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 +14 -2
- package/dist/cli/services/agent-loop.js +26 -2
- package/dist/cli/services/agent-loop.js.map +1 -1
- package/dist/cli/services/hooks.js +2 -1
- package/dist/cli/services/hooks.js.map +1 -1
- package/dist/cli/services/telemetry-spans.js +1 -0
- package/dist/cli/services/telemetry-spans.js.map +1 -1
- package/dist/cli/services/telemetry.d.ts +23 -0
- package/dist/cli/services/telemetry.js +45 -1
- package/dist/cli/services/telemetry.js.map +1 -1
- package/dist/server/handlers/__test-utils__/test-db.d.ts +17 -3
- package/dist/server/handlers/__test-utils__/test-db.js +113 -14
- package/dist/server/handlers/__test-utils__/test-db.js.map +1 -1
- package/dist/server/handlers/affiliates.d.ts +9 -0
- package/dist/server/handlers/affiliates.js +197 -0
- package/dist/server/handlers/affiliates.js.map +1 -0
- package/dist/server/handlers/api-docs.d.ts +4 -2
- package/dist/server/handlers/api-docs.js +204 -1681
- package/dist/server/handlers/api-docs.js.map +1 -1
- package/dist/server/handlers/campaigns.d.ts +9 -0
- package/dist/server/handlers/campaigns.js +237 -0
- package/dist/server/handlers/campaigns.js.map +1 -0
- package/dist/server/handlers/catalog-schemas.js +9 -9
- package/dist/server/handlers/catalog-schemas.js.map +1 -1
- package/dist/server/handlers/catalog.js +1 -1
- package/dist/server/handlers/catalog.js.map +1 -1
- package/dist/server/handlers/comms-documents.js +28 -2
- package/dist/server/handlers/comms-documents.js.map +1 -1
- package/dist/server/handlers/comms-pdf-generation.js +25 -3
- package/dist/server/handlers/comms-pdf-generation.js.map +1 -1
- package/dist/server/handlers/comms-pdf-helpers.js +4 -4
- package/dist/server/handlers/comms-pdf-helpers.js.map +1 -1
- package/dist/server/handlers/comms.d.ts +100 -0
- package/dist/server/handlers/comms.js +146 -12
- package/dist/server/handlers/comms.js.map +1 -1
- package/dist/server/handlers/coupons.d.ts +9 -0
- package/dist/server/handlers/coupons.js +220 -0
- package/dist/server/handlers/coupons.js.map +1 -0
- package/dist/server/handlers/embeddings.js +1 -1
- package/dist/server/handlers/embeddings.js.map +1 -1
- package/dist/server/handlers/enrichment.js +2 -622
- package/dist/server/handlers/enrichment.js.map +1 -1
- package/dist/server/handlers/fulfillment.d.ts +9 -0
- package/dist/server/handlers/fulfillment.js +209 -0
- package/dist/server/handlers/fulfillment.js.map +1 -0
- package/dist/server/handlers/google-ads.d.ts +24 -0
- package/dist/server/handlers/google-ads.js +2199 -0
- package/dist/server/handlers/google-ads.js.map +1 -0
- package/dist/server/handlers/invoices.d.ts +9 -0
- package/dist/server/handlers/invoices.js +252 -0
- package/dist/server/handlers/invoices.js.map +1 -0
- package/dist/server/handlers/loyalty.d.ts +9 -0
- package/dist/server/handlers/loyalty.js +197 -0
- package/dist/server/handlers/loyalty.js.map +1 -0
- package/dist/server/handlers/meta-ads-graph-api.js +18 -3
- package/dist/server/handlers/meta-ads-graph-api.js.map +1 -1
- package/dist/server/handlers/phone.d.ts +9 -0
- package/dist/server/handlers/phone.js +197 -0
- package/dist/server/handlers/phone.js.map +1 -0
- package/dist/server/handlers/pipeline.d.ts +9 -0
- package/dist/server/handlers/pipeline.js +277 -0
- package/dist/server/handlers/pipeline.js.map +1 -0
- package/dist/server/handlers/qr-codes.d.ts +9 -0
- package/dist/server/handlers/qr-codes.js +198 -0
- package/dist/server/handlers/qr-codes.js.map +1 -0
- package/dist/server/handlers/reviews.d.ts +9 -0
- package/dist/server/handlers/reviews.js +171 -0
- package/dist/server/handlers/reviews.js.map +1 -0
- package/dist/server/handlers/segments.d.ts +9 -0
- package/dist/server/handlers/segments.js +229 -0
- package/dist/server/handlers/segments.js.map +1 -0
- package/dist/server/handlers/social.d.ts +9 -0
- package/dist/server/handlers/social.js +81 -0
- package/dist/server/handlers/social.js.map +1 -0
- package/dist/server/handlers/tax.d.ts +9 -0
- package/dist/server/handlers/tax.js +182 -0
- package/dist/server/handlers/tax.js.map +1 -0
- package/dist/server/handlers/wallet.d.ts +9 -0
- package/dist/server/handlers/wallet.js +203 -0
- package/dist/server/handlers/wallet.js.map +1 -0
- package/dist/server/handlers/webhooks-mgmt.d.ts +9 -0
- package/dist/server/handlers/webhooks-mgmt.js +181 -0
- package/dist/server/handlers/webhooks-mgmt.js.map +1 -0
- package/dist/server/handlers/wholesale.d.ts +9 -0
- package/dist/server/handlers/wholesale.js +219 -0
- package/dist/server/handlers/wholesale.js.map +1 -0
- package/dist/server/index.js +20 -9
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/clickhouse-buffer.js +1 -0
- package/dist/server/lib/clickhouse-buffer.js.map +1 -1
- package/dist/server/lib/coa-renderer.d.ts +1 -1
- package/dist/server/lib/coa-renderer.js +32 -10
- package/dist/server/lib/coa-renderer.js.map +1 -1
- package/dist/server/server-worker.d.ts +1 -0
- package/dist/server/server-worker.js +464 -3
- package/dist/server/server-worker.js.map +1 -1
- package/dist/server/tool-router.js +118 -4
- package/dist/server/tool-router.js.map +1 -1
- package/package.json +28 -4
- package/vendor/ink/package.json +0 -2
- package/whale-logo.png +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
// server/handlers/tax.ts — Tax rate management
|
|
2
|
+
|
|
3
|
+
export async function handleTax(sb, args, storeId) {
|
|
4
|
+
const sid = storeId;
|
|
5
|
+
switch (args.action) {
|
|
6
|
+
// ---- LIST: list all tax rates ----
|
|
7
|
+
case "list":
|
|
8
|
+
{
|
|
9
|
+
let q = sb.from("tax_rates").select("*").eq("store_id", sid).order("state", {
|
|
10
|
+
ascending: true
|
|
11
|
+
});
|
|
12
|
+
if (args.is_active !== undefined) q = q.eq("is_active", args.is_active);
|
|
13
|
+
if (args.state) q = q.eq("state", args.state);
|
|
14
|
+
if (args.country) q = q.eq("country", args.country);
|
|
15
|
+
const {
|
|
16
|
+
data,
|
|
17
|
+
error
|
|
18
|
+
} = await q;
|
|
19
|
+
return error ? {
|
|
20
|
+
success: false,
|
|
21
|
+
error: error.message
|
|
22
|
+
} : {
|
|
23
|
+
success: true,
|
|
24
|
+
count: data?.length,
|
|
25
|
+
data
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ---- GET: get a single tax rate ----
|
|
30
|
+
case "get":
|
|
31
|
+
{
|
|
32
|
+
const taxId = args.tax_id;
|
|
33
|
+
if (!taxId) return {
|
|
34
|
+
success: false,
|
|
35
|
+
error: "tax_id is required"
|
|
36
|
+
};
|
|
37
|
+
const {
|
|
38
|
+
data,
|
|
39
|
+
error
|
|
40
|
+
} = await sb.from("tax_rates").select("*").eq("id", taxId).eq("store_id", sid).single();
|
|
41
|
+
return error ? {
|
|
42
|
+
success: false,
|
|
43
|
+
error: error.message
|
|
44
|
+
} : {
|
|
45
|
+
success: true,
|
|
46
|
+
data
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ---- CREATE: add a new tax rate ----
|
|
51
|
+
case "create":
|
|
52
|
+
{
|
|
53
|
+
const state = args.state;
|
|
54
|
+
const rate = args.rate;
|
|
55
|
+
if (!state || rate === undefined) return {
|
|
56
|
+
success: false,
|
|
57
|
+
error: "state and rate are required"
|
|
58
|
+
};
|
|
59
|
+
const record = {
|
|
60
|
+
store_id: sid,
|
|
61
|
+
state,
|
|
62
|
+
rate
|
|
63
|
+
};
|
|
64
|
+
if (args.country !== undefined) record.country = args.country;
|
|
65
|
+
if (args.name !== undefined) record.name = args.name;
|
|
66
|
+
const {
|
|
67
|
+
data,
|
|
68
|
+
error
|
|
69
|
+
} = await sb.from("tax_rates").insert(record).select().single();
|
|
70
|
+
return error ? {
|
|
71
|
+
success: false,
|
|
72
|
+
error: error.message
|
|
73
|
+
} : {
|
|
74
|
+
success: true,
|
|
75
|
+
data
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ---- UPDATE: modify a tax rate ----
|
|
80
|
+
case "update":
|
|
81
|
+
{
|
|
82
|
+
const taxId = args.tax_id;
|
|
83
|
+
if (!taxId) return {
|
|
84
|
+
success: false,
|
|
85
|
+
error: "tax_id is required"
|
|
86
|
+
};
|
|
87
|
+
const updates = {
|
|
88
|
+
updated_at: new Date().toISOString()
|
|
89
|
+
};
|
|
90
|
+
if (args.state !== undefined) updates.state = args.state;
|
|
91
|
+
if (args.rate !== undefined) updates.rate = args.rate;
|
|
92
|
+
if (args.country !== undefined) updates.country = args.country;
|
|
93
|
+
if (args.name !== undefined) updates.name = args.name;
|
|
94
|
+
if (args.is_active !== undefined) updates.is_active = args.is_active;
|
|
95
|
+
const {
|
|
96
|
+
data,
|
|
97
|
+
error
|
|
98
|
+
} = await sb.from("tax_rates").update(updates).eq("id", taxId).eq("store_id", sid).select().single();
|
|
99
|
+
return error ? {
|
|
100
|
+
success: false,
|
|
101
|
+
error: error.message
|
|
102
|
+
} : {
|
|
103
|
+
success: true,
|
|
104
|
+
data
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ---- DELETE: deactivate a tax rate ----
|
|
109
|
+
case "delete":
|
|
110
|
+
{
|
|
111
|
+
const taxId = args.tax_id;
|
|
112
|
+
if (!taxId) return {
|
|
113
|
+
success: false,
|
|
114
|
+
error: "tax_id is required"
|
|
115
|
+
};
|
|
116
|
+
const {
|
|
117
|
+
error
|
|
118
|
+
} = await sb.from("tax_rates").update({
|
|
119
|
+
is_active: false,
|
|
120
|
+
updated_at: new Date().toISOString()
|
|
121
|
+
}).eq("id", taxId).eq("store_id", sid);
|
|
122
|
+
return error ? {
|
|
123
|
+
success: false,
|
|
124
|
+
error: error.message
|
|
125
|
+
} : {
|
|
126
|
+
success: true,
|
|
127
|
+
data: {
|
|
128
|
+
deactivated: true
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ---- CALCULATE: calculate tax for a given amount and state ----
|
|
134
|
+
case "calculate":
|
|
135
|
+
{
|
|
136
|
+
const amount = args.amount;
|
|
137
|
+
const state = args.state;
|
|
138
|
+
if (amount === undefined || !state) return {
|
|
139
|
+
success: false,
|
|
140
|
+
error: "amount and state are required"
|
|
141
|
+
};
|
|
142
|
+
const {
|
|
143
|
+
data: taxRate,
|
|
144
|
+
error
|
|
145
|
+
} = await sb.from("tax_rates").select("rate, name, state, country").eq("store_id", sid).eq("state", state).eq("is_active", true).maybeSingle();
|
|
146
|
+
if (error) return {
|
|
147
|
+
success: false,
|
|
148
|
+
error: error.message
|
|
149
|
+
};
|
|
150
|
+
if (!taxRate) return {
|
|
151
|
+
success: true,
|
|
152
|
+
data: {
|
|
153
|
+
amount,
|
|
154
|
+
state,
|
|
155
|
+
tax_rate: 0,
|
|
156
|
+
tax_amount: 0,
|
|
157
|
+
total: amount,
|
|
158
|
+
note: "No tax rate configured for this state"
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const taxAmount = Math.round(amount * Number(taxRate.rate) * 100) / 100;
|
|
162
|
+
return {
|
|
163
|
+
success: true,
|
|
164
|
+
data: {
|
|
165
|
+
amount,
|
|
166
|
+
state: taxRate.state,
|
|
167
|
+
country: taxRate.country,
|
|
168
|
+
tax_rate: taxRate.rate,
|
|
169
|
+
tax_name: taxRate.name,
|
|
170
|
+
tax_amount: taxAmount,
|
|
171
|
+
total: Math.round((amount + taxAmount) * 100) / 100
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
default:
|
|
176
|
+
return {
|
|
177
|
+
success: false,
|
|
178
|
+
error: `Unknown tax action: ${args.action}. Valid: list, get, create, update, delete, calculate`
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=tax.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tax.js","names":["handleTax","sb","args","storeId","sid","action","q","from","select","eq","order","ascending","is_active","undefined","state","country","data","error","success","message","count","length","taxId","tax_id","single","rate","record","store_id","name","insert","updates","updated_at","Date","toISOString","update","deactivated","amount","taxRate","maybeSingle","tax_rate","tax_amount","total","note","taxAmount","Math","round","Number","tax_name"],"sources":["../../../src/server/handlers/tax.ts"],"sourcesContent":["// server/handlers/tax.ts — Tax rate management\n\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\n\ntype Result = { success: boolean; data?: unknown; error?: string; [key: string]: unknown };\n\nexport async function handleTax(\n sb: SupabaseClient,\n args: Record<string, unknown>,\n storeId?: string,\n): Promise<Result> {\n const sid = storeId as string;\n\n switch (args.action) {\n // ---- LIST: list all tax rates ----\n case \"list\": {\n let q = sb.from(\"tax_rates\")\n .select(\"*\")\n .eq(\"store_id\", sid)\n .order(\"state\", { ascending: true });\n if (args.is_active !== undefined) q = q.eq(\"is_active\", args.is_active as boolean);\n if (args.state) q = q.eq(\"state\", args.state as string);\n if (args.country) q = q.eq(\"country\", args.country as string);\n const { data, error } = await q;\n return error ? { success: false, error: error.message } : { success: true, count: data?.length, data };\n }\n\n // ---- GET: get a single tax rate ----\n case \"get\": {\n const taxId = args.tax_id as string;\n if (!taxId) return { success: false, error: \"tax_id is required\" };\n const { data, error } = await sb.from(\"tax_rates\")\n .select(\"*\")\n .eq(\"id\", taxId)\n .eq(\"store_id\", sid)\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- CREATE: add a new tax rate ----\n case \"create\": {\n const state = args.state as string;\n const rate = args.rate as number;\n if (!state || rate === undefined) return { success: false, error: \"state and rate are required\" };\n const record: Record<string, unknown> = {\n store_id: sid,\n state,\n rate,\n };\n if (args.country !== undefined) record.country = args.country;\n if (args.name !== undefined) record.name = args.name;\n\n const { data, error } = await sb.from(\"tax_rates\")\n .insert(record)\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- UPDATE: modify a tax rate ----\n case \"update\": {\n const taxId = args.tax_id as string;\n if (!taxId) return { success: false, error: \"tax_id is required\" };\n const updates: Record<string, unknown> = { updated_at: new Date().toISOString() };\n if (args.state !== undefined) updates.state = args.state;\n if (args.rate !== undefined) updates.rate = args.rate;\n if (args.country !== undefined) updates.country = args.country;\n if (args.name !== undefined) updates.name = args.name;\n if (args.is_active !== undefined) updates.is_active = args.is_active;\n\n const { data, error } = await sb.from(\"tax_rates\")\n .update(updates)\n .eq(\"id\", taxId)\n .eq(\"store_id\", sid)\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- DELETE: deactivate a tax rate ----\n case \"delete\": {\n const taxId = args.tax_id as string;\n if (!taxId) return { success: false, error: \"tax_id is required\" };\n const { error } = await sb.from(\"tax_rates\")\n .update({ is_active: false, updated_at: new Date().toISOString() })\n .eq(\"id\", taxId)\n .eq(\"store_id\", sid);\n return error ? { success: false, error: error.message } : { success: true, data: { deactivated: true } };\n }\n\n // ---- CALCULATE: calculate tax for a given amount and state ----\n case \"calculate\": {\n const amount = args.amount as number;\n const state = args.state as string;\n if (amount === undefined || !state) return { success: false, error: \"amount and state are required\" };\n const { data: taxRate, error } = await sb.from(\"tax_rates\")\n .select(\"rate, name, state, country\")\n .eq(\"store_id\", sid)\n .eq(\"state\", state)\n .eq(\"is_active\", true)\n .maybeSingle();\n if (error) return { success: false, error: error.message };\n if (!taxRate) return { success: true, data: { amount, state, tax_rate: 0, tax_amount: 0, total: amount, note: \"No tax rate configured for this state\" } };\n const taxAmount = Math.round(amount * Number(taxRate.rate) * 100) / 100;\n return {\n success: true,\n data: {\n amount,\n state: taxRate.state,\n country: taxRate.country,\n tax_rate: taxRate.rate,\n tax_name: taxRate.name,\n tax_amount: taxAmount,\n total: Math.round((amount + taxAmount) * 100) / 100,\n },\n };\n }\n\n default:\n return { success: false, error: `Unknown tax action: ${args.action}. Valid: list, get, create, update, delete, calculate` };\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
type Result = {
|
|
3
|
+
success: boolean;
|
|
4
|
+
data?: unknown;
|
|
5
|
+
error?: string;
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
};
|
|
8
|
+
export declare function handleWallet(sb: SupabaseClient, args: Record<string, unknown>, storeId?: string): Promise<Result>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
// server/handlers/wallet.ts — Apple Wallet pass management
|
|
2
|
+
|
|
3
|
+
export async function handleWallet(sb, args, storeId) {
|
|
4
|
+
const sid = storeId;
|
|
5
|
+
switch (args.action) {
|
|
6
|
+
// ---- LIST: list wallet passes ----
|
|
7
|
+
case "list":
|
|
8
|
+
{
|
|
9
|
+
let q = sb.from("wallet_passes").select("id, customer_id, pass_type, pass_serial_number, is_active, status, times_downloaded, times_updated, added_to_wallet_at, push_enabled, created_at").eq("store_id", sid).order("created_at", {
|
|
10
|
+
ascending: false
|
|
11
|
+
});
|
|
12
|
+
if (args.pass_type) q = q.eq("pass_type", args.pass_type);
|
|
13
|
+
if (args.status) q = q.eq("status", args.status);
|
|
14
|
+
if (args.is_active !== undefined) q = q.eq("is_active", args.is_active);
|
|
15
|
+
if (args.customer_id) q = q.eq("customer_id", args.customer_id);
|
|
16
|
+
q = q.limit(args.limit || 50);
|
|
17
|
+
const {
|
|
18
|
+
data,
|
|
19
|
+
error
|
|
20
|
+
} = await q;
|
|
21
|
+
return error ? {
|
|
22
|
+
success: false,
|
|
23
|
+
error: error.message
|
|
24
|
+
} : {
|
|
25
|
+
success: true,
|
|
26
|
+
count: data?.length,
|
|
27
|
+
data
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ---- GET: get wallet pass detail ----
|
|
32
|
+
case "get":
|
|
33
|
+
{
|
|
34
|
+
const passId = args.pass_id;
|
|
35
|
+
if (!passId) return {
|
|
36
|
+
success: false,
|
|
37
|
+
error: "pass_id is required"
|
|
38
|
+
};
|
|
39
|
+
const {
|
|
40
|
+
data,
|
|
41
|
+
error
|
|
42
|
+
} = await sb.from("wallet_passes").select("*").eq("id", passId).eq("store_id", sid).single();
|
|
43
|
+
if (error) return {
|
|
44
|
+
success: false,
|
|
45
|
+
error: error.message
|
|
46
|
+
};
|
|
47
|
+
// Strip auth token from response
|
|
48
|
+
const {
|
|
49
|
+
authentication_token,
|
|
50
|
+
...safe
|
|
51
|
+
} = data;
|
|
52
|
+
return {
|
|
53
|
+
success: true,
|
|
54
|
+
data: safe
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ---- CREATE: create a wallet pass for a customer ----
|
|
59
|
+
case "create":
|
|
60
|
+
{
|
|
61
|
+
const customerId = args.customer_id;
|
|
62
|
+
const passType = args.pass_type;
|
|
63
|
+
if (!customerId || !passType) return {
|
|
64
|
+
success: false,
|
|
65
|
+
error: "customer_id and pass_type are required"
|
|
66
|
+
};
|
|
67
|
+
const serialNumber = `${sid.slice(0, 8)}-${customerId.slice(0, 8)}-${Date.now()}`;
|
|
68
|
+
const record = {
|
|
69
|
+
store_id: sid,
|
|
70
|
+
customer_id: customerId,
|
|
71
|
+
pass_type: passType,
|
|
72
|
+
pass_serial_number: serialNumber,
|
|
73
|
+
pass_data: args.pass_data || {},
|
|
74
|
+
status: "active",
|
|
75
|
+
is_active: true
|
|
76
|
+
};
|
|
77
|
+
if (args.apple_wallet_url !== undefined) record.apple_wallet_url = args.apple_wallet_url;
|
|
78
|
+
if (args.google_wallet_url !== undefined) record.google_wallet_url = args.google_wallet_url;
|
|
79
|
+
const {
|
|
80
|
+
data,
|
|
81
|
+
error
|
|
82
|
+
} = await sb.from("wallet_passes").insert(record).select().single();
|
|
83
|
+
return error ? {
|
|
84
|
+
success: false,
|
|
85
|
+
error: error.message
|
|
86
|
+
} : {
|
|
87
|
+
success: true,
|
|
88
|
+
data
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ---- UPDATE: update pass data or status ----
|
|
93
|
+
case "update":
|
|
94
|
+
{
|
|
95
|
+
const passId = args.pass_id;
|
|
96
|
+
if (!passId) return {
|
|
97
|
+
success: false,
|
|
98
|
+
error: "pass_id is required"
|
|
99
|
+
};
|
|
100
|
+
const updates = {
|
|
101
|
+
last_updated_at: new Date().toISOString()
|
|
102
|
+
};
|
|
103
|
+
if (args.pass_data !== undefined) updates.pass_data = args.pass_data;
|
|
104
|
+
if (args.is_active !== undefined) updates.is_active = args.is_active;
|
|
105
|
+
if (args.status !== undefined) updates.status = args.status;
|
|
106
|
+
if (args.push_enabled !== undefined) updates.push_enabled = args.push_enabled;
|
|
107
|
+
const {
|
|
108
|
+
data,
|
|
109
|
+
error
|
|
110
|
+
} = await sb.from("wallet_passes").update(updates).eq("id", passId).eq("store_id", sid).select().single();
|
|
111
|
+
return error ? {
|
|
112
|
+
success: false,
|
|
113
|
+
error: error.message
|
|
114
|
+
} : {
|
|
115
|
+
success: true,
|
|
116
|
+
data
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ---- REVOKE: revoke a wallet pass ----
|
|
121
|
+
case "revoke":
|
|
122
|
+
{
|
|
123
|
+
const passId = args.pass_id;
|
|
124
|
+
if (!passId) return {
|
|
125
|
+
success: false,
|
|
126
|
+
error: "pass_id is required"
|
|
127
|
+
};
|
|
128
|
+
const {
|
|
129
|
+
data,
|
|
130
|
+
error
|
|
131
|
+
} = await sb.from("wallet_passes").update({
|
|
132
|
+
status: "revoked",
|
|
133
|
+
is_active: false,
|
|
134
|
+
last_updated_at: new Date().toISOString()
|
|
135
|
+
}).eq("id", passId).eq("store_id", sid).select().single();
|
|
136
|
+
return error ? {
|
|
137
|
+
success: false,
|
|
138
|
+
error: error.message
|
|
139
|
+
} : {
|
|
140
|
+
success: true,
|
|
141
|
+
data
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ---- PUSH_QUEUE: list pending push notifications for wallet passes ----
|
|
146
|
+
case "push_queue":
|
|
147
|
+
{
|
|
148
|
+
let q = sb.from("wallet_push_queue").select("*").eq("store_id", sid).order("created_at", {
|
|
149
|
+
ascending: false
|
|
150
|
+
});
|
|
151
|
+
if (args.status) q = q.eq("status", args.status);
|
|
152
|
+
if (args.customer_id) q = q.eq("customer_id", args.customer_id);
|
|
153
|
+
q = q.limit(args.limit || 50);
|
|
154
|
+
const {
|
|
155
|
+
data,
|
|
156
|
+
error
|
|
157
|
+
} = await q;
|
|
158
|
+
return error ? {
|
|
159
|
+
success: false,
|
|
160
|
+
error: error.message
|
|
161
|
+
} : {
|
|
162
|
+
success: true,
|
|
163
|
+
count: data?.length,
|
|
164
|
+
data
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ---- STATS: wallet pass statistics ----
|
|
169
|
+
case "stats":
|
|
170
|
+
{
|
|
171
|
+
const {
|
|
172
|
+
data: passes,
|
|
173
|
+
error
|
|
174
|
+
} = await sb.from("wallet_passes").select("pass_type, status, is_active, times_downloaded, added_to_wallet_at").eq("store_id", sid);
|
|
175
|
+
if (error) return {
|
|
176
|
+
success: false,
|
|
177
|
+
error: error.message
|
|
178
|
+
};
|
|
179
|
+
const all = passes || [];
|
|
180
|
+
const active = all.filter(p => p.is_active);
|
|
181
|
+
const installed = all.filter(p => p.added_to_wallet_at);
|
|
182
|
+
const byType = {};
|
|
183
|
+
for (const p of all) byType[p.pass_type] = (byType[p.pass_type] || 0) + 1;
|
|
184
|
+
const totalDownloads = all.reduce((s, p) => s + (p.times_downloaded || 0), 0);
|
|
185
|
+
return {
|
|
186
|
+
success: true,
|
|
187
|
+
data: {
|
|
188
|
+
total_passes: all.length,
|
|
189
|
+
active_passes: active.length,
|
|
190
|
+
installed_in_wallet: installed.length,
|
|
191
|
+
total_downloads: totalDownloads,
|
|
192
|
+
by_type: byType
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
default:
|
|
197
|
+
return {
|
|
198
|
+
success: false,
|
|
199
|
+
error: `Unknown wallet action: ${args.action}. Valid: list, get, create, update, revoke, push_queue, stats`
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=wallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.js","names":["handleWallet","sb","args","storeId","sid","action","q","from","select","eq","order","ascending","pass_type","status","is_active","undefined","customer_id","limit","data","error","success","message","count","length","passId","pass_id","single","authentication_token","safe","customerId","passType","serialNumber","slice","Date","now","record","store_id","pass_serial_number","pass_data","apple_wallet_url","google_wallet_url","insert","updates","last_updated_at","toISOString","push_enabled","update","passes","all","active","filter","p","installed","added_to_wallet_at","byType","totalDownloads","reduce","s","times_downloaded","total_passes","active_passes","installed_in_wallet","total_downloads","by_type"],"sources":["../../../src/server/handlers/wallet.ts"],"sourcesContent":["// server/handlers/wallet.ts — Apple Wallet pass management\n\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\n\ntype Result = { success: boolean; data?: unknown; error?: string; [key: string]: unknown };\n\nexport async function handleWallet(\n sb: SupabaseClient,\n args: Record<string, unknown>,\n storeId?: string,\n): Promise<Result> {\n const sid = storeId as string;\n\n switch (args.action) {\n // ---- LIST: list wallet passes ----\n case \"list\": {\n let q = sb.from(\"wallet_passes\")\n .select(\"id, customer_id, pass_type, pass_serial_number, is_active, status, times_downloaded, times_updated, added_to_wallet_at, push_enabled, created_at\")\n .eq(\"store_id\", sid)\n .order(\"created_at\", { ascending: false });\n if (args.pass_type) q = q.eq(\"pass_type\", args.pass_type as string);\n if (args.status) q = q.eq(\"status\", args.status as string);\n if (args.is_active !== undefined) q = q.eq(\"is_active\", args.is_active as boolean);\n if (args.customer_id) q = q.eq(\"customer_id\", args.customer_id as string);\n q = q.limit(args.limit as number || 50);\n const { data, error } = await q;\n return error ? { success: false, error: error.message } : { success: true, count: data?.length, data };\n }\n\n // ---- GET: get wallet pass detail ----\n case \"get\": {\n const passId = args.pass_id as string;\n if (!passId) return { success: false, error: \"pass_id is required\" };\n const { data, error } = await sb.from(\"wallet_passes\")\n .select(\"*\")\n .eq(\"id\", passId)\n .eq(\"store_id\", sid)\n .single();\n if (error) return { success: false, error: error.message };\n // Strip auth token from response\n const { authentication_token, ...safe } = data as Record<string, unknown>;\n return { success: true, data: safe };\n }\n\n // ---- CREATE: create a wallet pass for a customer ----\n case \"create\": {\n const customerId = args.customer_id as string;\n const passType = args.pass_type as string;\n if (!customerId || !passType) return { success: false, error: \"customer_id and pass_type are required\" };\n const serialNumber = `${sid.slice(0, 8)}-${customerId.slice(0, 8)}-${Date.now()}`;\n const record: Record<string, unknown> = {\n store_id: sid,\n customer_id: customerId,\n pass_type: passType,\n pass_serial_number: serialNumber,\n pass_data: args.pass_data || {},\n status: \"active\",\n is_active: true,\n };\n if (args.apple_wallet_url !== undefined) record.apple_wallet_url = args.apple_wallet_url;\n if (args.google_wallet_url !== undefined) record.google_wallet_url = args.google_wallet_url;\n\n const { data, error } = await sb.from(\"wallet_passes\")\n .insert(record)\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- UPDATE: update pass data or status ----\n case \"update\": {\n const passId = args.pass_id as string;\n if (!passId) return { success: false, error: \"pass_id is required\" };\n const updates: Record<string, unknown> = { last_updated_at: new Date().toISOString() };\n if (args.pass_data !== undefined) updates.pass_data = args.pass_data;\n if (args.is_active !== undefined) updates.is_active = args.is_active;\n if (args.status !== undefined) updates.status = args.status;\n if (args.push_enabled !== undefined) updates.push_enabled = args.push_enabled;\n\n const { data, error } = await sb.from(\"wallet_passes\")\n .update(updates)\n .eq(\"id\", passId)\n .eq(\"store_id\", sid)\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- REVOKE: revoke a wallet pass ----\n case \"revoke\": {\n const passId = args.pass_id as string;\n if (!passId) return { success: false, error: \"pass_id is required\" };\n const { data, error } = await sb.from(\"wallet_passes\")\n .update({ status: \"revoked\", is_active: false, last_updated_at: new Date().toISOString() })\n .eq(\"id\", passId)\n .eq(\"store_id\", sid)\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- PUSH_QUEUE: list pending push notifications for wallet passes ----\n case \"push_queue\": {\n let q = sb.from(\"wallet_push_queue\")\n .select(\"*\")\n .eq(\"store_id\", sid)\n .order(\"created_at\", { ascending: false });\n if (args.status) q = q.eq(\"status\", args.status as string);\n if (args.customer_id) q = q.eq(\"customer_id\", args.customer_id as string);\n q = q.limit(args.limit as number || 50);\n const { data, error } = await q;\n return error ? { success: false, error: error.message } : { success: true, count: data?.length, data };\n }\n\n // ---- STATS: wallet pass statistics ----\n case \"stats\": {\n const { data: passes, error } = await sb.from(\"wallet_passes\")\n .select(\"pass_type, status, is_active, times_downloaded, added_to_wallet_at\")\n .eq(\"store_id\", sid);\n if (error) return { success: false, error: error.message };\n\n const all = passes || [];\n const active = all.filter(p => p.is_active);\n const installed = all.filter(p => p.added_to_wallet_at);\n const byType: Record<string, number> = {};\n for (const p of all) byType[p.pass_type] = (byType[p.pass_type] || 0) + 1;\n const totalDownloads = all.reduce((s, p) => s + (p.times_downloaded || 0), 0);\n\n return {\n success: true,\n data: {\n total_passes: all.length,\n active_passes: active.length,\n installed_in_wallet: installed.length,\n total_downloads: totalDownloads,\n by_type: byType,\n },\n };\n }\n\n default:\n return { success: false, error: `Unknown wallet action: ${args.action}. Valid: list, get, create, update, revoke, push_queue, stats` };\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
type Result = {
|
|
3
|
+
success: boolean;
|
|
4
|
+
data?: unknown;
|
|
5
|
+
error?: string;
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
};
|
|
8
|
+
export declare function handleWebhooksMgmt(sb: SupabaseClient, args: Record<string, unknown>, storeId?: string): Promise<Result>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// server/handlers/webhooks-mgmt.ts — Webhook endpoint CRUD and testing
|
|
2
|
+
|
|
3
|
+
export async function handleWebhooksMgmt(sb, args, storeId) {
|
|
4
|
+
const sid = storeId;
|
|
5
|
+
switch (args.action) {
|
|
6
|
+
// ---- LIST: list webhook endpoints ----
|
|
7
|
+
case "list":
|
|
8
|
+
{
|
|
9
|
+
let q = sb.from("webhook_endpoints").select("id, name, description, slug, is_active, max_requests_per_minute, total_received, last_received_at, workflow_id, sync_response, created_at").eq("store_id", sid).order("created_at", {
|
|
10
|
+
ascending: false
|
|
11
|
+
});
|
|
12
|
+
if (args.is_active !== undefined) q = q.eq("is_active", args.is_active);
|
|
13
|
+
q = q.limit(args.limit || 50);
|
|
14
|
+
const {
|
|
15
|
+
data,
|
|
16
|
+
error
|
|
17
|
+
} = await q;
|
|
18
|
+
return error ? {
|
|
19
|
+
success: false,
|
|
20
|
+
error: error.message
|
|
21
|
+
} : {
|
|
22
|
+
success: true,
|
|
23
|
+
count: data?.length,
|
|
24
|
+
data
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ---- GET: get a single webhook with full config ----
|
|
29
|
+
case "get":
|
|
30
|
+
{
|
|
31
|
+
const webhookId = args.webhook_id;
|
|
32
|
+
if (!webhookId) return {
|
|
33
|
+
success: false,
|
|
34
|
+
error: "webhook_id is required"
|
|
35
|
+
};
|
|
36
|
+
const {
|
|
37
|
+
data,
|
|
38
|
+
error
|
|
39
|
+
} = await sb.from("webhook_endpoints").select("*").eq("id", webhookId).eq("store_id", sid).single();
|
|
40
|
+
if (error) return {
|
|
41
|
+
success: false,
|
|
42
|
+
error: error.message
|
|
43
|
+
};
|
|
44
|
+
// Strip signing_secret from response for security
|
|
45
|
+
const {
|
|
46
|
+
signing_secret,
|
|
47
|
+
...safe
|
|
48
|
+
} = data;
|
|
49
|
+
return {
|
|
50
|
+
success: true,
|
|
51
|
+
data: {
|
|
52
|
+
...safe,
|
|
53
|
+
has_signing_secret: !!signing_secret
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ---- CREATE: create a new webhook endpoint ----
|
|
59
|
+
case "create":
|
|
60
|
+
{
|
|
61
|
+
const name = args.name;
|
|
62
|
+
const slug = args.slug;
|
|
63
|
+
const workflowId = args.workflow_id;
|
|
64
|
+
if (!name || !slug || !workflowId) {
|
|
65
|
+
return {
|
|
66
|
+
success: false,
|
|
67
|
+
error: "name, slug, and workflow_id are required"
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const record = {
|
|
71
|
+
store_id: sid,
|
|
72
|
+
name,
|
|
73
|
+
slug,
|
|
74
|
+
workflow_id: workflowId
|
|
75
|
+
};
|
|
76
|
+
if (args.description !== undefined) record.description = args.description;
|
|
77
|
+
if (args.verify_signature !== undefined) record.verify_signature = args.verify_signature;
|
|
78
|
+
if (args.max_requests_per_minute !== undefined) record.max_requests_per_minute = args.max_requests_per_minute;
|
|
79
|
+
if (args.payload_transform !== undefined) record.payload_transform = args.payload_transform;
|
|
80
|
+
if (args.sync_response !== undefined) record.sync_response = args.sync_response;
|
|
81
|
+
if (args.sync_timeout_seconds !== undefined) record.sync_timeout_seconds = args.sync_timeout_seconds;
|
|
82
|
+
const {
|
|
83
|
+
data,
|
|
84
|
+
error
|
|
85
|
+
} = await sb.from("webhook_endpoints").insert(record).select("id, name, slug, workflow_id, is_active, signing_secret, created_at").single();
|
|
86
|
+
return error ? {
|
|
87
|
+
success: false,
|
|
88
|
+
error: error.message
|
|
89
|
+
} : {
|
|
90
|
+
success: true,
|
|
91
|
+
data
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ---- UPDATE: modify a webhook endpoint ----
|
|
96
|
+
case "update":
|
|
97
|
+
{
|
|
98
|
+
const webhookId = args.webhook_id;
|
|
99
|
+
if (!webhookId) return {
|
|
100
|
+
success: false,
|
|
101
|
+
error: "webhook_id is required"
|
|
102
|
+
};
|
|
103
|
+
const updates = {
|
|
104
|
+
updated_at: new Date().toISOString()
|
|
105
|
+
};
|
|
106
|
+
if (args.name !== undefined) updates.name = args.name;
|
|
107
|
+
if (args.description !== undefined) updates.description = args.description;
|
|
108
|
+
if (args.slug !== undefined) updates.slug = args.slug;
|
|
109
|
+
if (args.is_active !== undefined) updates.is_active = args.is_active;
|
|
110
|
+
if (args.workflow_id !== undefined) updates.workflow_id = args.workflow_id;
|
|
111
|
+
if (args.verify_signature !== undefined) updates.verify_signature = args.verify_signature;
|
|
112
|
+
if (args.max_requests_per_minute !== undefined) updates.max_requests_per_minute = args.max_requests_per_minute;
|
|
113
|
+
if (args.payload_transform !== undefined) updates.payload_transform = args.payload_transform;
|
|
114
|
+
if (args.sync_response !== undefined) updates.sync_response = args.sync_response;
|
|
115
|
+
const {
|
|
116
|
+
data,
|
|
117
|
+
error
|
|
118
|
+
} = await sb.from("webhook_endpoints").update(updates).eq("id", webhookId).eq("store_id", sid).select("id, name, slug, is_active, workflow_id, created_at, updated_at").single();
|
|
119
|
+
return error ? {
|
|
120
|
+
success: false,
|
|
121
|
+
error: error.message
|
|
122
|
+
} : {
|
|
123
|
+
success: true,
|
|
124
|
+
data
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ---- DELETE: remove a webhook endpoint ----
|
|
129
|
+
case "delete":
|
|
130
|
+
{
|
|
131
|
+
const webhookId = args.webhook_id;
|
|
132
|
+
if (!webhookId) return {
|
|
133
|
+
success: false,
|
|
134
|
+
error: "webhook_id is required"
|
|
135
|
+
};
|
|
136
|
+
const {
|
|
137
|
+
error
|
|
138
|
+
} = await sb.from("webhook_endpoints").delete().eq("id", webhookId).eq("store_id", sid);
|
|
139
|
+
return error ? {
|
|
140
|
+
success: false,
|
|
141
|
+
error: error.message
|
|
142
|
+
} : {
|
|
143
|
+
success: true,
|
|
144
|
+
data: {
|
|
145
|
+
deleted: true
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// ---- ROTATE_SECRET: regenerate signing secret ----
|
|
151
|
+
case "rotate_secret":
|
|
152
|
+
{
|
|
153
|
+
const webhookId = args.webhook_id;
|
|
154
|
+
if (!webhookId) return {
|
|
155
|
+
success: false,
|
|
156
|
+
error: "webhook_id is required"
|
|
157
|
+
};
|
|
158
|
+
// Generate a new secret via SQL default
|
|
159
|
+
const {
|
|
160
|
+
data,
|
|
161
|
+
error
|
|
162
|
+
} = await sb.from("webhook_endpoints").update({
|
|
163
|
+
signing_secret: crypto.randomUUID() + crypto.randomUUID(),
|
|
164
|
+
updated_at: new Date().toISOString()
|
|
165
|
+
}).eq("id", webhookId).eq("store_id", sid).select("id, signing_secret, updated_at").single();
|
|
166
|
+
return error ? {
|
|
167
|
+
success: false,
|
|
168
|
+
error: error.message
|
|
169
|
+
} : {
|
|
170
|
+
success: true,
|
|
171
|
+
data
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
default:
|
|
175
|
+
return {
|
|
176
|
+
success: false,
|
|
177
|
+
error: `Unknown webhooks_mgmt action: ${args.action}. Valid: list, get, create, update, delete, rotate_secret`
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=webhooks-mgmt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks-mgmt.js","names":["handleWebhooksMgmt","sb","args","storeId","sid","action","q","from","select","eq","order","ascending","is_active","undefined","limit","data","error","success","message","count","length","webhookId","webhook_id","single","signing_secret","safe","has_signing_secret","name","slug","workflowId","workflow_id","record","store_id","description","verify_signature","max_requests_per_minute","payload_transform","sync_response","sync_timeout_seconds","insert","updates","updated_at","Date","toISOString","update","delete","deleted","crypto","randomUUID"],"sources":["../../../src/server/handlers/webhooks-mgmt.ts"],"sourcesContent":["// server/handlers/webhooks-mgmt.ts — Webhook endpoint CRUD and testing\n\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\n\ntype Result = { success: boolean; data?: unknown; error?: string; [key: string]: unknown };\n\nexport async function handleWebhooksMgmt(\n sb: SupabaseClient,\n args: Record<string, unknown>,\n storeId?: string,\n): Promise<Result> {\n const sid = storeId as string;\n\n switch (args.action) {\n // ---- LIST: list webhook endpoints ----\n case \"list\": {\n let q = sb.from(\"webhook_endpoints\")\n .select(\"id, name, description, slug, is_active, max_requests_per_minute, total_received, last_received_at, workflow_id, sync_response, created_at\")\n .eq(\"store_id\", sid)\n .order(\"created_at\", { ascending: false });\n if (args.is_active !== undefined) q = q.eq(\"is_active\", args.is_active as boolean);\n q = q.limit(args.limit as number || 50);\n const { data, error } = await q;\n return error ? { success: false, error: error.message } : { success: true, count: data?.length, data };\n }\n\n // ---- GET: get a single webhook with full config ----\n case \"get\": {\n const webhookId = args.webhook_id as string;\n if (!webhookId) return { success: false, error: \"webhook_id is required\" };\n const { data, error } = await sb.from(\"webhook_endpoints\")\n .select(\"*\")\n .eq(\"id\", webhookId)\n .eq(\"store_id\", sid)\n .single();\n if (error) return { success: false, error: error.message };\n // Strip signing_secret from response for security\n const { signing_secret, ...safe } = data as Record<string, unknown>;\n return { success: true, data: { ...safe, has_signing_secret: !!signing_secret } };\n }\n\n // ---- CREATE: create a new webhook endpoint ----\n case \"create\": {\n const name = args.name as string;\n const slug = args.slug as string;\n const workflowId = args.workflow_id as string;\n if (!name || !slug || !workflowId) {\n return { success: false, error: \"name, slug, and workflow_id are required\" };\n }\n const record: Record<string, unknown> = {\n store_id: sid,\n name,\n slug,\n workflow_id: workflowId,\n };\n if (args.description !== undefined) record.description = args.description;\n if (args.verify_signature !== undefined) record.verify_signature = args.verify_signature;\n if (args.max_requests_per_minute !== undefined) record.max_requests_per_minute = args.max_requests_per_minute;\n if (args.payload_transform !== undefined) record.payload_transform = args.payload_transform;\n if (args.sync_response !== undefined) record.sync_response = args.sync_response;\n if (args.sync_timeout_seconds !== undefined) record.sync_timeout_seconds = args.sync_timeout_seconds;\n\n const { data, error } = await sb.from(\"webhook_endpoints\")\n .insert(record)\n .select(\"id, name, slug, workflow_id, is_active, signing_secret, created_at\")\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- UPDATE: modify a webhook endpoint ----\n case \"update\": {\n const webhookId = args.webhook_id as string;\n if (!webhookId) return { success: false, error: \"webhook_id is required\" };\n const updates: Record<string, unknown> = { updated_at: new Date().toISOString() };\n if (args.name !== undefined) updates.name = args.name;\n if (args.description !== undefined) updates.description = args.description;\n if (args.slug !== undefined) updates.slug = args.slug;\n if (args.is_active !== undefined) updates.is_active = args.is_active;\n if (args.workflow_id !== undefined) updates.workflow_id = args.workflow_id;\n if (args.verify_signature !== undefined) updates.verify_signature = args.verify_signature;\n if (args.max_requests_per_minute !== undefined) updates.max_requests_per_minute = args.max_requests_per_minute;\n if (args.payload_transform !== undefined) updates.payload_transform = args.payload_transform;\n if (args.sync_response !== undefined) updates.sync_response = args.sync_response;\n\n const { data, error } = await sb.from(\"webhook_endpoints\")\n .update(updates)\n .eq(\"id\", webhookId)\n .eq(\"store_id\", sid)\n .select(\"id, name, slug, is_active, workflow_id, created_at, updated_at\")\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- DELETE: remove a webhook endpoint ----\n case \"delete\": {\n const webhookId = args.webhook_id as string;\n if (!webhookId) return { success: false, error: \"webhook_id is required\" };\n const { error } = await sb.from(\"webhook_endpoints\")\n .delete()\n .eq(\"id\", webhookId)\n .eq(\"store_id\", sid);\n return error ? { success: false, error: error.message } : { success: true, data: { deleted: true } };\n }\n\n // ---- ROTATE_SECRET: regenerate signing secret ----\n case \"rotate_secret\": {\n const webhookId = args.webhook_id as string;\n if (!webhookId) return { success: false, error: \"webhook_id is required\" };\n // Generate a new secret via SQL default\n const { data, error } = await sb.from(\"webhook_endpoints\")\n .update({ signing_secret: crypto.randomUUID() + crypto.randomUUID(), updated_at: new Date().toISOString() })\n .eq(\"id\", webhookId)\n .eq(\"store_id\", sid)\n .select(\"id, signing_secret, updated_at\")\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n default:\n return { success: false, error: `Unknown webhooks_mgmt action: ${args.action}. Valid: list, get, create, update, delete, rotate_secret` };\n }\n}\n"],"mappings":"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","ignoreList":[]}
|