whale-code 6.5.8 → 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.
Files changed (99) hide show
  1. package/dist/cli/services/agent-loop.js +26 -2
  2. package/dist/cli/services/agent-loop.js.map +1 -1
  3. package/dist/cli/services/hooks.js +2 -1
  4. package/dist/cli/services/hooks.js.map +1 -1
  5. package/dist/cli/services/telemetry-spans.js +1 -0
  6. package/dist/cli/services/telemetry-spans.js.map +1 -1
  7. package/dist/cli/services/telemetry.d.ts +23 -0
  8. package/dist/cli/services/telemetry.js +45 -1
  9. package/dist/cli/services/telemetry.js.map +1 -1
  10. package/dist/server/handlers/__test-utils__/test-db.d.ts +17 -3
  11. package/dist/server/handlers/__test-utils__/test-db.js +113 -14
  12. package/dist/server/handlers/__test-utils__/test-db.js.map +1 -1
  13. package/dist/server/handlers/affiliates.d.ts +9 -0
  14. package/dist/server/handlers/affiliates.js +197 -0
  15. package/dist/server/handlers/affiliates.js.map +1 -0
  16. package/dist/server/handlers/api-docs.d.ts +4 -2
  17. package/dist/server/handlers/api-docs.js +204 -1681
  18. package/dist/server/handlers/api-docs.js.map +1 -1
  19. package/dist/server/handlers/campaigns.d.ts +9 -0
  20. package/dist/server/handlers/campaigns.js +237 -0
  21. package/dist/server/handlers/campaigns.js.map +1 -0
  22. package/dist/server/handlers/catalog-schemas.js +9 -9
  23. package/dist/server/handlers/catalog-schemas.js.map +1 -1
  24. package/dist/server/handlers/catalog.js +1 -1
  25. package/dist/server/handlers/catalog.js.map +1 -1
  26. package/dist/server/handlers/comms-documents.js +28 -2
  27. package/dist/server/handlers/comms-documents.js.map +1 -1
  28. package/dist/server/handlers/comms-pdf-generation.js +25 -3
  29. package/dist/server/handlers/comms-pdf-generation.js.map +1 -1
  30. package/dist/server/handlers/comms-pdf-helpers.js +4 -4
  31. package/dist/server/handlers/comms-pdf-helpers.js.map +1 -1
  32. package/dist/server/handlers/comms.d.ts +100 -0
  33. package/dist/server/handlers/comms.js +146 -12
  34. package/dist/server/handlers/comms.js.map +1 -1
  35. package/dist/server/handlers/coupons.d.ts +9 -0
  36. package/dist/server/handlers/coupons.js +220 -0
  37. package/dist/server/handlers/coupons.js.map +1 -0
  38. package/dist/server/handlers/embeddings.js +1 -1
  39. package/dist/server/handlers/embeddings.js.map +1 -1
  40. package/dist/server/handlers/enrichment.js +2 -622
  41. package/dist/server/handlers/enrichment.js.map +1 -1
  42. package/dist/server/handlers/fulfillment.d.ts +9 -0
  43. package/dist/server/handlers/fulfillment.js +209 -0
  44. package/dist/server/handlers/fulfillment.js.map +1 -0
  45. package/dist/server/handlers/google-ads.d.ts +24 -0
  46. package/dist/server/handlers/google-ads.js +2199 -0
  47. package/dist/server/handlers/google-ads.js.map +1 -0
  48. package/dist/server/handlers/invoices.d.ts +9 -0
  49. package/dist/server/handlers/invoices.js +252 -0
  50. package/dist/server/handlers/invoices.js.map +1 -0
  51. package/dist/server/handlers/loyalty.d.ts +9 -0
  52. package/dist/server/handlers/loyalty.js +197 -0
  53. package/dist/server/handlers/loyalty.js.map +1 -0
  54. package/dist/server/handlers/meta-ads-graph-api.js +18 -3
  55. package/dist/server/handlers/meta-ads-graph-api.js.map +1 -1
  56. package/dist/server/handlers/phone.d.ts +9 -0
  57. package/dist/server/handlers/phone.js +197 -0
  58. package/dist/server/handlers/phone.js.map +1 -0
  59. package/dist/server/handlers/pipeline.d.ts +9 -0
  60. package/dist/server/handlers/pipeline.js +277 -0
  61. package/dist/server/handlers/pipeline.js.map +1 -0
  62. package/dist/server/handlers/qr-codes.d.ts +9 -0
  63. package/dist/server/handlers/qr-codes.js +198 -0
  64. package/dist/server/handlers/qr-codes.js.map +1 -0
  65. package/dist/server/handlers/reviews.d.ts +9 -0
  66. package/dist/server/handlers/reviews.js +171 -0
  67. package/dist/server/handlers/reviews.js.map +1 -0
  68. package/dist/server/handlers/segments.d.ts +9 -0
  69. package/dist/server/handlers/segments.js +229 -0
  70. package/dist/server/handlers/segments.js.map +1 -0
  71. package/dist/server/handlers/social.d.ts +9 -0
  72. package/dist/server/handlers/social.js +81 -0
  73. package/dist/server/handlers/social.js.map +1 -0
  74. package/dist/server/handlers/tax.d.ts +9 -0
  75. package/dist/server/handlers/tax.js +182 -0
  76. package/dist/server/handlers/tax.js.map +1 -0
  77. package/dist/server/handlers/wallet.d.ts +9 -0
  78. package/dist/server/handlers/wallet.js +203 -0
  79. package/dist/server/handlers/wallet.js.map +1 -0
  80. package/dist/server/handlers/webhooks-mgmt.d.ts +9 -0
  81. package/dist/server/handlers/webhooks-mgmt.js +181 -0
  82. package/dist/server/handlers/webhooks-mgmt.js.map +1 -0
  83. package/dist/server/handlers/wholesale.d.ts +9 -0
  84. package/dist/server/handlers/wholesale.js +219 -0
  85. package/dist/server/handlers/wholesale.js.map +1 -0
  86. package/dist/server/index.js +20 -9
  87. package/dist/server/index.js.map +1 -1
  88. package/dist/server/lib/clickhouse-buffer.js +1 -0
  89. package/dist/server/lib/clickhouse-buffer.js.map +1 -1
  90. package/dist/server/lib/coa-renderer.d.ts +1 -1
  91. package/dist/server/lib/coa-renderer.js +32 -10
  92. package/dist/server/lib/coa-renderer.js.map +1 -1
  93. package/dist/server/server-worker.d.ts +1 -0
  94. package/dist/server/server-worker.js +464 -3
  95. package/dist/server/server-worker.js.map +1 -1
  96. package/dist/server/tool-router.js +118 -4
  97. package/dist/server/tool-router.js.map +1 -1
  98. package/package.json +26 -3
  99. package/vendor/ink/package.json +0 -2
@@ -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":[]}