@fayz-ai/plugin-shop 0.20.1 → 0.21.1

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.
@@ -0,0 +1,20 @@
1
+ import type { ShippingSink, CheckoutQuote, CheckoutSession, CheckoutSink } from '@fayz-ai/contracts';
2
+ /**
3
+ * The plugin's server-side code: the checkout sink the integration service
4
+ * calls (ADR 0003, phase 2). One SQL function per method, migration 0121 of
5
+ * @fayz-ai/shop; no rule here. Never imports React; the service is its only
6
+ * consumer.
7
+ */
8
+ /** The slice of a Postgres client this needs; `pg.Pool` satisfies it. */
9
+ export interface SqlClient {
10
+ query<Row = Record<string, unknown>>(text: string, params?: unknown[]): Promise<{
11
+ rows: Row[];
12
+ }>;
13
+ }
14
+ type Json = Record<string, unknown>;
15
+ export declare function toQuote(raw: Json): CheckoutQuote;
16
+ export declare function toSession(row: Json | null | undefined): CheckoutSession | null;
17
+ export declare function createV2ShippingSink(db: SqlClient): ShippingSink;
18
+ export declare function createV2CheckoutSink(db: SqlClient): CheckoutSink;
19
+ export {};
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,YAAY,EAEZ,aAAa,EACb,eAAe,EACf,YAAY,EAKb,MAAM,oBAAoB,CAAA;AAE3B;;;;;GAKG;AAEH,yEAAyE;AACzE,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC,CAAA;CACjG;AAED,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAWnC,wBAAgB,OAAO,CAAC,GAAG,EAAE,IAAI,GAAG,aAAa,CAqBhD;AAcD,wBAAgB,SAAS,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,eAAe,GAAG,IAAI,CAgB9E;AAQD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,SAAS,GAAG,YAAY,CAyBhE;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,SAAS,GAAG,YAAY,CAsIhE"}
@@ -0,0 +1,216 @@
1
+ // src/server/index.ts
2
+ var num = (value) => {
3
+ const n = Number(value);
4
+ return Number.isFinite(n) ? n : 0;
5
+ };
6
+ var str = (value) => {
7
+ const s = typeof value === "string" ? value.trim() : value == null ? "" : String(value);
8
+ return s ? s : null;
9
+ };
10
+ function toQuote(raw) {
11
+ const items = Array.isArray(raw.items) ? raw.items : [];
12
+ return {
13
+ items: items.map(
14
+ (item) => ({
15
+ productId: String(item.product_id ?? ""),
16
+ name: String(item.name ?? ""),
17
+ quantity: Math.trunc(num(item.quantity)),
18
+ unitPrice: num(item.unit_price),
19
+ optionsLabel: str(item.options_label),
20
+ sku: str(item.sku),
21
+ category: str(item.category)
22
+ })
23
+ ),
24
+ subtotal: num(raw.subtotal),
25
+ shippingTotal: num(raw.shipping_total),
26
+ discountTotal: num(raw.discount_total),
27
+ total: num(raw.total),
28
+ currency: str(raw.currency) ?? "BRL",
29
+ discountCode: str(raw.discount_code)
30
+ };
31
+ }
32
+ function storedLines(quote) {
33
+ return quote.items.map((line) => ({
34
+ sku: line.sku,
35
+ name: line.name,
36
+ quantity: line.quantity,
37
+ product_id: line.productId,
38
+ unit_price: line.unitPrice,
39
+ options_label: line.optionsLabel
40
+ }));
41
+ }
42
+ function toSession(row) {
43
+ if (!row || !row.id) return null;
44
+ return {
45
+ id: String(row.id),
46
+ tenantId: String(row.tenant_id),
47
+ provider: String(row.provider),
48
+ status: String(row.status),
49
+ method: str(row.payment_method) ?? null,
50
+ chargeId: str(row.charge_id),
51
+ orderId: str(row.order_id),
52
+ total: num(row.total),
53
+ currency: str(row.currency) ?? "BRL",
54
+ expiresAt: str(row.expires_at),
55
+ failureReason: str(row.failure_reason),
56
+ chargePayload: row.charge_payload ?? null
57
+ };
58
+ }
59
+ function toMarket(raw) {
60
+ const row = raw;
61
+ if (!row || !row.id) return null;
62
+ return { id: String(row.id), code: String(row.code ?? ""), locale: str(row.locale) };
63
+ }
64
+ function createV2ShippingSink(db) {
65
+ return {
66
+ async packages(tenantId) {
67
+ const { rows } = await db.query("SELECT public.shop_shipping_packages($1) AS r", [tenantId]);
68
+ return (rows[0]?.r ?? []).map((p) => ({
69
+ id: String(p.id),
70
+ name: String(p.name ?? ""),
71
+ kind: str(p.kind),
72
+ heightCm: num(p.height_cm),
73
+ widthCm: num(p.width_cm),
74
+ lengthCm: num(p.length_cm),
75
+ emptyWeightGrams: num(p.empty_weight_grams),
76
+ isDefault: p.is_default === true
77
+ }));
78
+ },
79
+ async saveQuote(input) {
80
+ const { rows } = await db.query(
81
+ "SELECT public.shop_shipping_quote_save($1, $2, $3, $4, $5::jsonb, $6) AS id",
82
+ [input.tenantId, input.postalCode, input.subtotal, input.connector, JSON.stringify(input.options), input.expiresAt]
83
+ );
84
+ const id = rows[0]?.id;
85
+ if (!id) throw new Error("shop_shipping_quote_save returned no id");
86
+ return String(id);
87
+ }
88
+ };
89
+ }
90
+ function createV2CheckoutSink(db) {
91
+ return {
92
+ async open(input) {
93
+ const { rows } = await db.query(
94
+ "SELECT public.shop_checkout_open($1, $2, $3, $4::jsonb, $5::jsonb, $6, $7) AS r",
95
+ [
96
+ input.tenantId,
97
+ input.provider,
98
+ input.method,
99
+ JSON.stringify({
100
+ items: input.lines.map((l) => ({
101
+ product_id: l.productId,
102
+ quantity: l.quantity,
103
+ options_label: l.optionsLabel ?? null
104
+ })),
105
+ discount_code: input.discountCode,
106
+ postal_code: input.postalCode,
107
+ market: input.market ?? null,
108
+ country: input.country ?? null
109
+ }),
110
+ JSON.stringify({
111
+ name: input.buyer.name,
112
+ email: input.buyer.email,
113
+ document: input.buyer.document,
114
+ address: input.buyer.address
115
+ }),
116
+ input.expiresAt,
117
+ input.providerRef
118
+ ]
119
+ );
120
+ const r = rows[0]?.r ?? {};
121
+ if (r.ok !== true) {
122
+ return { ok: false, reason: String(r.reason ?? "cart_unavailable"), detail: r };
123
+ }
124
+ return {
125
+ ok: true,
126
+ sessionId: String(r.session_id),
127
+ quote: toQuote(r.quote ?? {}),
128
+ storeName: str(r.store_name),
129
+ market: toMarket(r.market)
130
+ };
131
+ },
132
+ async reusable(tenantId, provider, quote) {
133
+ const { rows } = await db.query(
134
+ "SELECT public.shop_checkout_reusable($1, $2, $3, $4::jsonb) AS r",
135
+ [tenantId, provider, quote.total, JSON.stringify(storedLines(quote))]
136
+ );
137
+ return (rows[0]?.r ?? []).map((row) => ({
138
+ sessionId: String(row.id),
139
+ chargeId: String(row.charge_id),
140
+ expiresAt: str(row.expires_at),
141
+ total: num(row.total),
142
+ currency: str(row.currency) ?? "BRL"
143
+ }));
144
+ },
145
+ async reusableFor(tenantId, provider, method, quote) {
146
+ const { rows } = await db.query(
147
+ "SELECT public.shop_checkout_reusable_for($1, $2, $3, $4, $5, $6::jsonb) AS r",
148
+ [tenantId, provider, method, quote.currency, quote.total, JSON.stringify(storedLines(quote))]
149
+ );
150
+ return (rows[0]?.r ?? []).map((row) => ({
151
+ sessionId: String(row.id),
152
+ chargeId: String(row.charge_id),
153
+ expiresAt: str(row.expires_at),
154
+ total: num(row.total),
155
+ currency: str(row.currency) ?? "BRL",
156
+ chargePayload: row.charge_payload ?? null,
157
+ method: str(row.method) ?? null
158
+ }));
159
+ },
160
+ async setMethod(sessionId, method) {
161
+ await db.query("SELECT public.shop_checkout_set_method($1, $2)", [sessionId, method]);
162
+ },
163
+ async productLinks(tenantId, source, kind, productIds) {
164
+ const { rows } = await db.query("SELECT public.shop_product_links($1, $2, $3, $4::uuid[]) AS r", [
165
+ tenantId,
166
+ source,
167
+ kind,
168
+ productIds
169
+ ]);
170
+ return (rows[0]?.r ?? []).map((row) => ({ productId: String(row.product_id), externalId: String(row.external_id) }));
171
+ },
172
+ async attach(sessionId, chargeId, payload, expiresAt) {
173
+ await db.query("SELECT public.shop_checkout_attach($1, $2, $3::jsonb, $4)", [
174
+ sessionId,
175
+ chargeId,
176
+ JSON.stringify(payload ?? null),
177
+ expiresAt
178
+ ]);
179
+ },
180
+ async fail(sessionId, reason, status = "failed") {
181
+ await db.query("SELECT public.shop_checkout_fail($1, $2, $3)", [sessionId, reason, status]);
182
+ },
183
+ async get(tenantId, sessionId) {
184
+ const { rows } = await db.query("SELECT public.shop_checkout_get($1, $2) AS r", [
185
+ tenantId,
186
+ sessionId
187
+ ]);
188
+ return toSession(rows[0]?.r);
189
+ },
190
+ async byCharge(provider, chargeId) {
191
+ const { rows } = await db.query("SELECT public.shop_checkout_by_charge($1, $2) AS r", [
192
+ provider,
193
+ chargeId
194
+ ]);
195
+ return toSession(rows[0]?.r);
196
+ },
197
+ async byReference(provider, reference) {
198
+ const { rows } = await db.query("SELECT public.shop_checkout_by_reference($1, $2) AS r", [
199
+ provider,
200
+ reference
201
+ ]);
202
+ return toSession(rows[0]?.r);
203
+ },
204
+ async settle(sessionId) {
205
+ const { rows } = await db.query("SELECT public.shop_checkout_settle($1) AS r", [sessionId]);
206
+ const placed = rows[0]?.r ?? {};
207
+ const orderId = str(placed.order_id) ?? str(placed.id);
208
+ if (!orderId) throw new Error("shop_checkout_settle returned no order id");
209
+ return { orderId };
210
+ }
211
+ };
212
+ }
213
+
214
+ export { createV2CheckoutSink, createV2ShippingSink, toQuote, toSession };
215
+ //# sourceMappingURL=index.js.map
216
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type {\n CheckoutMarket,\n ShippingPackage,\n ShippingSink,\n CheckoutOpened,\n CheckoutQuote,\n CheckoutSession,\n CheckoutSink,\n CheckoutStatus,\n CheckoutMethod,\n QuotedLine,\n ReusableCharge,\n} from '@fayz-ai/contracts'\n\n/**\n * The plugin's server-side code: the checkout sink the integration service\n * calls (ADR 0003, phase 2). One SQL function per method, migration 0121 of\n * @fayz-ai/shop; no rule here. Never imports React; the service is its only\n * consumer.\n */\n\n/** The slice of a Postgres client this needs; `pg.Pool` satisfies it. */\nexport interface SqlClient {\n query<Row = Record<string, unknown>>(text: string, params?: unknown[]): Promise<{ rows: Row[] }>\n}\n\ntype Json = Record<string, unknown>\n\nconst num = (value: unknown): number => {\n const n = Number(value)\n return Number.isFinite(n) ? n : 0\n}\nconst str = (value: unknown): string | null => {\n const s = typeof value === 'string' ? value.trim() : value == null ? '' : String(value)\n return s ? s : null\n}\n\nexport function toQuote(raw: Json): CheckoutQuote {\n const items = Array.isArray(raw.items) ? (raw.items as Json[]) : []\n return {\n items: items.map(\n (item): QuotedLine => ({\n productId: String(item.product_id ?? ''),\n name: String(item.name ?? ''),\n quantity: Math.trunc(num(item.quantity)),\n unitPrice: num(item.unit_price),\n optionsLabel: str(item.options_label),\n sku: str(item.sku),\n category: str(item.category),\n }),\n ),\n subtotal: num(raw.subtotal),\n shippingTotal: num(raw.shipping_total),\n discountTotal: num(raw.discount_total),\n total: num(raw.total),\n currency: str(raw.currency) ?? 'BRL',\n discountCode: str(raw.discount_code),\n }\n}\n\n/** The quote's lines in the shape the session stored them, to match a reusable cart. */\nfunction storedLines(quote: CheckoutQuote): Json[] {\n return quote.items.map((line) => ({\n sku: line.sku,\n name: line.name,\n quantity: line.quantity,\n product_id: line.productId,\n unit_price: line.unitPrice,\n options_label: line.optionsLabel,\n }))\n}\n\nexport function toSession(row: Json | null | undefined): CheckoutSession | null {\n if (!row || !row.id) return null\n return {\n id: String(row.id),\n tenantId: String(row.tenant_id),\n provider: String(row.provider),\n status: String(row.status) as CheckoutStatus,\n method: (str(row.payment_method) as CheckoutMethod | null) ?? null,\n chargeId: str(row.charge_id),\n orderId: str(row.order_id),\n total: num(row.total),\n currency: str(row.currency) ?? 'BRL',\n expiresAt: str(row.expires_at),\n failureReason: str(row.failure_reason),\n chargePayload: (row.charge_payload as Json | null) ?? null,\n }\n}\n\nfunction toMarket(raw: unknown): CheckoutMarket | null {\n const row = raw as Json | null\n if (!row || !row.id) return null\n return { id: String(row.id), code: String(row.code ?? ''), locale: str(row.locale) }\n}\n\nexport function createV2ShippingSink(db: SqlClient): ShippingSink {\n return {\n async packages(tenantId): Promise<ShippingPackage[]> {\n const { rows } = await db.query<{ r: Json[] }>('SELECT public.shop_shipping_packages($1) AS r', [tenantId])\n return (rows[0]?.r ?? []).map((p) => ({\n id: String(p.id),\n name: String(p.name ?? ''),\n kind: str(p.kind),\n heightCm: num(p.height_cm),\n widthCm: num(p.width_cm),\n lengthCm: num(p.length_cm),\n emptyWeightGrams: num(p.empty_weight_grams),\n isDefault: p.is_default === true,\n }))\n },\n async saveQuote(input) {\n const { rows } = await db.query<{ id: string }>(\n 'SELECT public.shop_shipping_quote_save($1, $2, $3, $4, $5::jsonb, $6) AS id',\n [input.tenantId, input.postalCode, input.subtotal, input.connector, JSON.stringify(input.options), input.expiresAt],\n )\n const id = rows[0]?.id\n if (!id) throw new Error('shop_shipping_quote_save returned no id')\n return String(id)\n },\n }\n}\n\nexport function createV2CheckoutSink(db: SqlClient): CheckoutSink {\n return {\n async open(input): Promise<CheckoutOpened> {\n const { rows } = await db.query<{ r: Json }>(\n 'SELECT public.shop_checkout_open($1, $2, $3, $4::jsonb, $5::jsonb, $6, $7) AS r',\n [\n input.tenantId,\n input.provider,\n input.method,\n JSON.stringify({\n items: input.lines.map((l) => ({\n product_id: l.productId,\n quantity: l.quantity,\n options_label: l.optionsLabel ?? null,\n })),\n discount_code: input.discountCode,\n postal_code: input.postalCode,\n market: input.market ?? null,\n country: input.country ?? null,\n }),\n JSON.stringify({\n name: input.buyer.name,\n email: input.buyer.email,\n document: input.buyer.document,\n address: input.buyer.address,\n }),\n input.expiresAt,\n input.providerRef,\n ],\n )\n const r = rows[0]?.r ?? {}\n if (r.ok !== true) {\n return { ok: false, reason: String(r.reason ?? 'cart_unavailable'), detail: r }\n }\n return {\n ok: true,\n sessionId: String(r.session_id),\n quote: toQuote((r.quote as Json) ?? {}),\n storeName: str(r.store_name),\n market: toMarket(r.market),\n }\n },\n\n async reusable(tenantId, provider, quote): Promise<ReusableCharge[]> {\n const { rows } = await db.query<{ r: Json[] }>(\n 'SELECT public.shop_checkout_reusable($1, $2, $3, $4::jsonb) AS r',\n [tenantId, provider, quote.total, JSON.stringify(storedLines(quote))],\n )\n return (rows[0]?.r ?? []).map((row) => ({\n sessionId: String(row.id),\n chargeId: String(row.charge_id),\n expiresAt: str(row.expires_at),\n total: num(row.total),\n currency: str(row.currency) ?? 'BRL',\n }))\n },\n\n async reusableFor(tenantId, provider, method, quote) {\n const { rows } = await db.query<{ r: Json[] }>(\n 'SELECT public.shop_checkout_reusable_for($1, $2, $3, $4, $5, $6::jsonb) AS r',\n [tenantId, provider, method, quote.currency, quote.total, JSON.stringify(storedLines(quote))],\n )\n return (rows[0]?.r ?? []).map((row) => ({\n sessionId: String(row.id),\n chargeId: String(row.charge_id),\n expiresAt: str(row.expires_at),\n total: num(row.total),\n currency: str(row.currency) ?? 'BRL',\n chargePayload: (row.charge_payload as Json | null) ?? null,\n method: (str(row.method) as CheckoutMethod | null) ?? null,\n }))\n },\n\n async setMethod(sessionId, method) {\n await db.query('SELECT public.shop_checkout_set_method($1, $2)', [sessionId, method])\n },\n\n async productLinks(tenantId, source, kind, productIds) {\n const { rows } = await db.query<{ r: Json[] }>('SELECT public.shop_product_links($1, $2, $3, $4::uuid[]) AS r', [\n tenantId,\n source,\n kind,\n productIds,\n ])\n return (rows[0]?.r ?? []).map((row) => ({ productId: String(row.product_id), externalId: String(row.external_id) }))\n },\n\n async attach(sessionId, chargeId, payload, expiresAt) {\n await db.query('SELECT public.shop_checkout_attach($1, $2, $3::jsonb, $4)', [\n sessionId,\n chargeId,\n JSON.stringify(payload ?? null),\n expiresAt,\n ])\n },\n\n async fail(sessionId, reason, status = 'failed') {\n await db.query('SELECT public.shop_checkout_fail($1, $2, $3)', [sessionId, reason, status])\n },\n\n async get(tenantId, sessionId) {\n const { rows } = await db.query<{ r: Json | null }>('SELECT public.shop_checkout_get($1, $2) AS r', [\n tenantId,\n sessionId,\n ])\n return toSession(rows[0]?.r)\n },\n\n async byCharge(provider, chargeId) {\n const { rows } = await db.query<{ r: Json | null }>('SELECT public.shop_checkout_by_charge($1, $2) AS r', [\n provider,\n chargeId,\n ])\n return toSession(rows[0]?.r)\n },\n\n async byReference(provider, reference) {\n const { rows } = await db.query<{ r: Json | null }>('SELECT public.shop_checkout_by_reference($1, $2) AS r', [\n provider,\n reference,\n ])\n return toSession(rows[0]?.r)\n },\n\n async settle(sessionId) {\n const { rows } = await db.query<{ r: Json | null }>('SELECT public.shop_checkout_settle($1) AS r', [sessionId])\n const placed = rows[0]?.r ?? {}\n // shop_place_order_from_session answers { order_id, … }; `id` is accepted\n // for the older shape so a cluster behind on migrations still settles.\n const orderId = str(placed.order_id) ?? str(placed.id)\n if (!orderId) throw new Error('shop_checkout_settle returned no order id')\n return { orderId }\n },\n }\n}\n"]}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "status": "preview",
5
5
  "dependencies": []
6
6
  },
7
- "version": "0.20.1",
7
+ "version": "0.21.1",
8
8
  "description": "[experimental] Fayz SDK — plugin-shop plugin",
9
9
  "type": "module",
10
10
  "sideEffects": false,
@@ -15,6 +15,10 @@
15
15
  ".": {
16
16
  "types": "./dist/index.d.ts",
17
17
  "import": "./dist/index.js"
18
+ },
19
+ "./server": {
20
+ "types": "./dist/server/index.d.ts",
21
+ "import": "./dist/server/index.js"
18
22
  }
19
23
  },
20
24
  "files": [
@@ -28,12 +32,13 @@
28
32
  },
29
33
  "dependencies": {
30
34
  "@tanstack/react-table": "^8.20.0",
31
- "@fayz-ai/admin": "^0.49.0",
32
- "@fayz-ai/core": "^0.49.0",
33
- "@fayz-ai/financial": "^0.1.1",
34
- "@fayz-ai/inventory": "^0.1.1",
35
- "@fayz-ai/shop": "^0.49.2",
36
- "@fayz-ai/ui": "^0.49.0"
35
+ "@fayz-ai/admin": "^0.51.0",
36
+ "@fayz-ai/core": "^0.50.0",
37
+ "@fayz-ai/financial": "^0.1.2",
38
+ "@fayz-ai/inventory": "^0.1.2",
39
+ "@fayz-ai/shop": "^0.50.0",
40
+ "@fayz-ai/ui": "^0.50.0",
41
+ "@fayz-ai/contracts": "^0.2.0"
37
42
  },
38
43
  "devDependencies": {
39
44
  "@types/node": "^20.0.0",