@porulle/plugin-marketplace 0.64.0 → 0.65.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -59
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -11
- package/dist/routes/b2b.d.ts +1 -3
- package/dist/routes/b2b.d.ts.map +1 -1
- package/dist/routes/b2b.js +2 -70
- package/dist/routes/sub-orders.js +3 -3
- package/dist/routes/vendor-portal.js +6 -6
- package/dist/schema.d.ts +0 -194
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +0 -14
- package/dist/schemas/b2b.d.ts +0 -986
- package/dist/schemas/b2b.d.ts.map +1 -1
- package/dist/schemas/b2b.js +1 -184
- package/dist/schemas/commission.d.ts +0 -495
- package/dist/schemas/commission.d.ts.map +1 -1
- package/dist/schemas/commission.js +1 -78
- package/dist/schemas/disputes-returns-reviews.d.ts +0 -1354
- package/dist/schemas/disputes-returns-reviews.d.ts.map +1 -1
- package/dist/schemas/disputes-returns-reviews.js +1 -208
- package/dist/schemas/sub-orders.d.ts +0 -290
- package/dist/schemas/sub-orders.d.ts.map +1 -1
- package/dist/schemas/sub-orders.js +1 -59
- package/dist/schemas/vendor-portal.d.ts +0 -1755
- package/dist/schemas/vendor-portal.d.ts.map +1 -1
- package/dist/schemas/vendor-portal.js +1 -247
- package/dist/schemas/vendors.d.ts +0 -1321
- package/dist/schemas/vendors.d.ts.map +1 -1
- package/dist/schemas/vendors.js +1 -205
- package/dist/services/sub-order.d.ts +1 -31
- package/dist/services/sub-order.d.ts.map +1 -1
- package/dist/services/sub-order.js +14 -22
- package/dist/types.d.ts +0 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -4
- package/package.json +2 -2
- package/src/index.ts +3 -11
- package/src/routes/b2b.ts +1 -76
- package/src/routes/sub-orders.ts +3 -3
- package/src/routes/vendor-portal.ts +6 -6
- package/src/schema.ts +0 -16
- package/src/schemas/b2b.ts +1 -208
- package/src/schemas/commission.ts +1 -86
- package/src/schemas/disputes-returns-reviews.ts +1 -225
- package/src/schemas/sub-orders.ts +1 -65
- package/src/schemas/vendor-portal.ts +1 -269
- package/src/schemas/vendors.ts +1 -222
- package/src/services/sub-order.ts +16 -18
- package/src/types.ts +0 -28
- package/dist/schemas/payouts.d.ts +0 -375
- package/dist/schemas/payouts.d.ts.map +0 -1
- package/dist/schemas/payouts.js +0 -78
- package/dist/services/contract-price.d.ts +0 -64
- package/dist/services/contract-price.d.ts.map +0 -1
- package/dist/services/contract-price.js +0 -57
- package/src/schemas/payouts.ts +0 -90
- package/src/services/contract-price.ts +0 -80
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vendors.d.ts","sourceRoot":"","sources":["../../src/schemas/vendors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"vendors.d.ts","sourceRoot":"","sources":["../../src/schemas/vendors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAItC,eAAO,MAAM,sBAAsB;;;;;;iBAOF,CAAC;AAIlC,eAAO,MAAM,sBAAsB;;;;;;;iBAOF,CAAC;AAIlC,eAAO,MAAM,sBAAsB;;iBAEF,CAAC;AAIlC,eAAO,MAAM,uBAAuB;;iBAEF,CAAC;AAInC,eAAO,MAAM,wBAAwB;;;iBAGI,CAAC"}
|
package/dist/schemas/vendors.js
CHANGED
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
import { z
|
|
2
|
-
const ErrorSchema = z.object({
|
|
3
|
-
error: z.object({
|
|
4
|
-
code: z.string(),
|
|
5
|
-
message: z.string(),
|
|
6
|
-
}),
|
|
7
|
-
});
|
|
8
|
-
const errorResponses = {
|
|
9
|
-
401: { content: { "application/json": { schema: ErrorSchema } }, description: "Authentication required." },
|
|
10
|
-
403: { content: { "application/json": { schema: ErrorSchema } }, description: "Insufficient permissions." },
|
|
11
|
-
404: { content: { "application/json": { schema: ErrorSchema } }, description: "Not found." },
|
|
12
|
-
422: { content: { "application/json": { schema: ErrorSchema } }, description: "Validation error." },
|
|
13
|
-
500: { content: { "application/json": { schema: ErrorSchema } }, description: "Server error." },
|
|
14
|
-
};
|
|
15
|
-
const VendorResponseSchema = z.object({ data: z.any() });
|
|
1
|
+
import { z } from "@hono/zod-openapi";
|
|
16
2
|
// ─── Create Vendor ───────────────────────────────────────────────────────────
|
|
17
3
|
export const CreateVendorBodySchema = z.object({
|
|
18
4
|
name: z.string().min(1).openapi({ example: "Acme Co" }),
|
|
@@ -22,19 +8,6 @@ export const CreateVendorBodySchema = z.object({
|
|
|
22
8
|
.openapi({ example: 1000, description: "Basis points (100 = 1%)" }),
|
|
23
9
|
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
24
10
|
}).openapi("CreateVendorRequest");
|
|
25
|
-
export const createVendorRoute = createRoute({
|
|
26
|
-
method: "post",
|
|
27
|
-
path: "/api/marketplace/vendors",
|
|
28
|
-
tags: ["Marketplace - Vendors"],
|
|
29
|
-
summary: "Create a vendor",
|
|
30
|
-
request: {
|
|
31
|
-
body: { content: { "application/json": { schema: CreateVendorBodySchema } }, required: true },
|
|
32
|
-
},
|
|
33
|
-
responses: {
|
|
34
|
-
201: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Vendor created." },
|
|
35
|
-
...errorResponses,
|
|
36
|
-
},
|
|
37
|
-
});
|
|
38
11
|
// ─── Update Vendor ───────────────────────────────────────────────────────────
|
|
39
12
|
export const UpdateVendorBodySchema = z.object({
|
|
40
13
|
name: z.string().optional(),
|
|
@@ -44,202 +17,25 @@ export const UpdateVendorBodySchema = z.object({
|
|
|
44
17
|
tier: z.string().optional(),
|
|
45
18
|
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
46
19
|
}).openapi("UpdateVendorRequest");
|
|
47
|
-
export const updateVendorRoute = createRoute({
|
|
48
|
-
method: "patch",
|
|
49
|
-
path: "/api/marketplace/vendors/{id}",
|
|
50
|
-
tags: ["Marketplace - Vendors"],
|
|
51
|
-
summary: "Update a vendor",
|
|
52
|
-
request: {
|
|
53
|
-
params: z.object({ id: z.uuid() }),
|
|
54
|
-
body: { content: { "application/json": { schema: UpdateVendorBodySchema } }, required: true },
|
|
55
|
-
},
|
|
56
|
-
responses: {
|
|
57
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Vendor updated." },
|
|
58
|
-
...errorResponses,
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
20
|
// ─── Reject Vendor ───────────────────────────────────────────────────────────
|
|
62
21
|
export const RejectVendorBodySchema = z.object({
|
|
63
22
|
reason: z.string().min(1).openapi({ example: "Incomplete documentation" }),
|
|
64
23
|
}).openapi("RejectVendorRequest");
|
|
65
|
-
export const rejectVendorRoute = createRoute({
|
|
66
|
-
method: "post",
|
|
67
|
-
path: "/api/marketplace/vendors/{id}/reject",
|
|
68
|
-
tags: ["Marketplace - Vendors"],
|
|
69
|
-
summary: "Reject a vendor application",
|
|
70
|
-
request: {
|
|
71
|
-
params: z.object({ id: z.uuid() }),
|
|
72
|
-
body: { content: { "application/json": { schema: RejectVendorBodySchema } }, required: true },
|
|
73
|
-
},
|
|
74
|
-
responses: {
|
|
75
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Vendor rejected." },
|
|
76
|
-
...errorResponses,
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
24
|
// ─── Suspend Vendor ──────────────────────────────────────────────────────────
|
|
80
25
|
export const SuspendVendorBodySchema = z.object({
|
|
81
26
|
reason: z.string().min(1).openapi({ example: "Policy violation" }),
|
|
82
27
|
}).openapi("SuspendVendorRequest");
|
|
83
|
-
export const suspendVendorRoute = createRoute({
|
|
84
|
-
method: "post",
|
|
85
|
-
path: "/api/marketplace/vendors/{id}/suspend",
|
|
86
|
-
tags: ["Marketplace - Vendors"],
|
|
87
|
-
summary: "Suspend a vendor",
|
|
88
|
-
request: {
|
|
89
|
-
params: z.object({ id: z.uuid() }),
|
|
90
|
-
body: { content: { "application/json": { schema: SuspendVendorBodySchema } }, required: true },
|
|
91
|
-
},
|
|
92
|
-
responses: {
|
|
93
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Vendor suspended." },
|
|
94
|
-
...errorResponses,
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
28
|
// ─── Upload Document ─────────────────────────────────────────────────────────
|
|
98
29
|
export const UploadDocumentBodySchema = z.object({
|
|
99
30
|
type: z.string().min(1).openapi({ example: "business_license" }),
|
|
100
31
|
fileUrl: z.string().url().openapi({ example: "https://storage.example.com/doc.pdf" }),
|
|
101
32
|
}).openapi("UploadVendorDocumentRequest");
|
|
102
|
-
export const uploadDocumentRoute = createRoute({
|
|
103
|
-
method: "post",
|
|
104
|
-
path: "/api/marketplace/vendors/{id}/documents",
|
|
105
|
-
tags: ["Marketplace - Vendors"],
|
|
106
|
-
summary: "Upload a vendor document",
|
|
107
|
-
request: {
|
|
108
|
-
params: z.object({ id: z.uuid() }),
|
|
109
|
-
body: { content: { "application/json": { schema: UploadDocumentBodySchema } }, required: true },
|
|
110
|
-
},
|
|
111
|
-
responses: {
|
|
112
|
-
201: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Document uploaded." },
|
|
113
|
-
...errorResponses,
|
|
114
|
-
},
|
|
115
|
-
});
|
|
116
33
|
// ─── List Vendors ───────────────────────────────────────────────────────────
|
|
117
|
-
export const listVendorsRoute = createRoute({
|
|
118
|
-
method: "get",
|
|
119
|
-
path: "/api/marketplace/vendors",
|
|
120
|
-
tags: ["Marketplace - Vendors"],
|
|
121
|
-
summary: "List all vendors",
|
|
122
|
-
request: {
|
|
123
|
-
query: z.object({
|
|
124
|
-
status: z.string().optional(),
|
|
125
|
-
tier: z.string().optional(),
|
|
126
|
-
search: z.string().optional(),
|
|
127
|
-
}),
|
|
128
|
-
},
|
|
129
|
-
responses: {
|
|
130
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Success" },
|
|
131
|
-
...errorResponses,
|
|
132
|
-
},
|
|
133
|
-
});
|
|
134
34
|
// ─── Get Vendor ─────────────────────────────────────────────────────────────
|
|
135
|
-
export const getVendorRoute = createRoute({
|
|
136
|
-
method: "get",
|
|
137
|
-
path: "/api/marketplace/vendors/{id}",
|
|
138
|
-
tags: ["Marketplace - Vendors"],
|
|
139
|
-
summary: "Get vendor detail",
|
|
140
|
-
request: {
|
|
141
|
-
params: z.object({ id: z.uuid() }),
|
|
142
|
-
},
|
|
143
|
-
responses: {
|
|
144
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Success" },
|
|
145
|
-
...errorResponses,
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
35
|
// ─── Approve Vendor ─────────────────────────────────────────────────────────
|
|
149
|
-
export const approveVendorRoute = createRoute({
|
|
150
|
-
method: "post",
|
|
151
|
-
path: "/api/marketplace/vendors/{id}/approve",
|
|
152
|
-
tags: ["Marketplace - Vendors"],
|
|
153
|
-
summary: "Approve a vendor application",
|
|
154
|
-
request: {
|
|
155
|
-
params: z.object({ id: z.uuid() }),
|
|
156
|
-
},
|
|
157
|
-
responses: {
|
|
158
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Vendor approved." },
|
|
159
|
-
...errorResponses,
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
36
|
// ─── Reinstate Vendor ───────────────────────────────────────────────────────
|
|
163
|
-
export const reinstateVendorRoute = createRoute({
|
|
164
|
-
method: "post",
|
|
165
|
-
path: "/api/marketplace/vendors/{id}/reinstate",
|
|
166
|
-
tags: ["Marketplace - Vendors"],
|
|
167
|
-
summary: "Reinstate a suspended vendor",
|
|
168
|
-
request: {
|
|
169
|
-
params: z.object({ id: z.uuid() }),
|
|
170
|
-
},
|
|
171
|
-
responses: {
|
|
172
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Vendor reinstated." },
|
|
173
|
-
...errorResponses,
|
|
174
|
-
},
|
|
175
|
-
});
|
|
176
37
|
// ─── List Vendor Documents ──────────────────────────────────────────────────
|
|
177
|
-
export const listVendorDocumentsRoute = createRoute({
|
|
178
|
-
method: "get",
|
|
179
|
-
path: "/api/marketplace/vendors/{id}/documents",
|
|
180
|
-
tags: ["Marketplace - Vendors"],
|
|
181
|
-
summary: "List vendor documents",
|
|
182
|
-
request: {
|
|
183
|
-
params: z.object({ id: z.uuid() }),
|
|
184
|
-
},
|
|
185
|
-
responses: {
|
|
186
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Success" },
|
|
187
|
-
...errorResponses,
|
|
188
|
-
},
|
|
189
|
-
});
|
|
190
38
|
// ─── Approve Document ───────────────────────────────────────────────────────
|
|
191
|
-
export const approveDocumentRoute = createRoute({
|
|
192
|
-
method: "post",
|
|
193
|
-
path: "/api/marketplace/vendors/{id}/documents/{docId}/approve",
|
|
194
|
-
tags: ["Marketplace - Vendors"],
|
|
195
|
-
summary: "Approve a vendor document",
|
|
196
|
-
request: {
|
|
197
|
-
params: z.object({ id: z.uuid(), docId: z.uuid() }),
|
|
198
|
-
},
|
|
199
|
-
responses: {
|
|
200
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Document approved." },
|
|
201
|
-
...errorResponses,
|
|
202
|
-
},
|
|
203
|
-
});
|
|
204
39
|
// ─── Reject Document ────────────────────────────────────────────────────────
|
|
205
|
-
export const rejectDocumentRoute = createRoute({
|
|
206
|
-
method: "post",
|
|
207
|
-
path: "/api/marketplace/vendors/{id}/documents/{docId}/reject",
|
|
208
|
-
tags: ["Marketplace - Vendors"],
|
|
209
|
-
summary: "Reject a vendor document",
|
|
210
|
-
request: {
|
|
211
|
-
params: z.object({ id: z.uuid(), docId: z.uuid() }),
|
|
212
|
-
},
|
|
213
|
-
responses: {
|
|
214
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Document rejected." },
|
|
215
|
-
...errorResponses,
|
|
216
|
-
},
|
|
217
|
-
});
|
|
218
40
|
// ─── Vendor Balance ─────────────────────────────────────────────────────────
|
|
219
|
-
export const vendorBalanceRoute = createRoute({
|
|
220
|
-
method: "get",
|
|
221
|
-
path: "/api/marketplace/vendors/{id}/balance",
|
|
222
|
-
tags: ["Marketplace - Vendors"],
|
|
223
|
-
summary: "Get vendor balance",
|
|
224
|
-
request: {
|
|
225
|
-
params: z.object({ id: z.uuid() }),
|
|
226
|
-
},
|
|
227
|
-
responses: {
|
|
228
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Success" },
|
|
229
|
-
...errorResponses,
|
|
230
|
-
},
|
|
231
|
-
});
|
|
232
41
|
// ─── Vendor Performance ─────────────────────────────────────────────────────
|
|
233
|
-
export const vendorPerformanceRoute = createRoute({
|
|
234
|
-
method: "get",
|
|
235
|
-
path: "/api/marketplace/vendors/{id}/performance",
|
|
236
|
-
tags: ["Marketplace - Vendors"],
|
|
237
|
-
summary: "Get vendor performance metrics",
|
|
238
|
-
request: {
|
|
239
|
-
params: z.object({ id: z.uuid() }),
|
|
240
|
-
},
|
|
241
|
-
responses: {
|
|
242
|
-
200: { content: { "application/json": { schema: VendorResponseSchema } }, description: "Success" },
|
|
243
|
-
...errorResponses,
|
|
244
|
-
},
|
|
245
|
-
});
|
|
@@ -43,37 +43,6 @@ export declare class SubOrderService {
|
|
|
43
43
|
createdAt: Date;
|
|
44
44
|
updatedAt: Date;
|
|
45
45
|
} | null>;
|
|
46
|
-
listByOrder(orderId: string): Promise<{
|
|
47
|
-
id: string;
|
|
48
|
-
orderId: string;
|
|
49
|
-
vendorId: string;
|
|
50
|
-
status: string;
|
|
51
|
-
subtotal: number;
|
|
52
|
-
commissionAmount: number;
|
|
53
|
-
payoutAmount: number;
|
|
54
|
-
notified: boolean;
|
|
55
|
-
lineItems: {
|
|
56
|
-
entityId: string;
|
|
57
|
-
quantity: number;
|
|
58
|
-
totalPrice: number;
|
|
59
|
-
}[] | null;
|
|
60
|
-
trackingNumber: string | null;
|
|
61
|
-
trackingUrl: string | null;
|
|
62
|
-
carrier: string | null;
|
|
63
|
-
fulfillmentStatus: string;
|
|
64
|
-
confirmedAt: Date | null;
|
|
65
|
-
shippedAt: Date | null;
|
|
66
|
-
deliveredAt: Date | null;
|
|
67
|
-
cancelledAt: Date | null;
|
|
68
|
-
cancellationReason: string | null;
|
|
69
|
-
vendorNotes: string | null;
|
|
70
|
-
externalOrderId: string | null;
|
|
71
|
-
externalOrderUrl: string | null;
|
|
72
|
-
externalSyncStatus: string | null;
|
|
73
|
-
metadata: Record<string, unknown> | null;
|
|
74
|
-
createdAt: Date;
|
|
75
|
-
updatedAt: Date;
|
|
76
|
-
}[]>;
|
|
77
46
|
listByVendor(vendorId: string, filters?: {
|
|
78
47
|
status?: string;
|
|
79
48
|
}): Promise<{
|
|
@@ -143,6 +112,7 @@ export declare class SubOrderService {
|
|
|
143
112
|
updatedAt: Date;
|
|
144
113
|
}[]>;
|
|
145
114
|
private assertTransition;
|
|
115
|
+
private requireSubOrder;
|
|
146
116
|
confirm(id: string): Promise<{
|
|
147
117
|
id: string;
|
|
148
118
|
orderId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sub-order.d.ts","sourceRoot":"","sources":["../../src/services/sub-order.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sub-order.d.ts","sourceRoot":"","sources":["../../src/services/sub-order.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGtD,MAAM,WAAW,sBAAsB;IACrC,CAAC,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxH;AAED,qBAAa,eAAe;IAGd,OAAO,CAAC,EAAE;IAFtB,OAAO,CAAC,QAAQ,CAAC,CAAqC;gBAElC,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,sBAAsB;IAIvD,OAAO,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAKlB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAS5D,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAY7E,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,eAAe;IAOjB,OAAO,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAYlB,OAAO,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAWlB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAclE,OAAO,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAYlB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAkBlC,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOrD"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { eq, and, desc } from "@porulle/core/drizzle";
|
|
2
|
+
import { CommerceInvalidTransitionError, CommerceNotFoundError } from "@porulle/core";
|
|
2
3
|
import { vendorSubOrders } from "../schema.js";
|
|
3
4
|
import { SUB_ORDER_TRANSITIONS } from "../types.js";
|
|
4
5
|
export class SubOrderService {
|
|
@@ -12,11 +13,6 @@ export class SubOrderService {
|
|
|
12
13
|
const [sub] = await this.db.select().from(vendorSubOrders).where(eq(vendorSubOrders.id, id));
|
|
13
14
|
return sub ?? null;
|
|
14
15
|
}
|
|
15
|
-
async listByOrder(orderId) {
|
|
16
|
-
return this.db.select().from(vendorSubOrders)
|
|
17
|
-
.where(eq(vendorSubOrders.orderId, orderId))
|
|
18
|
-
.orderBy(desc(vendorSubOrders.createdAt));
|
|
19
|
-
}
|
|
20
16
|
async listByVendor(vendorId, filters) {
|
|
21
17
|
const conditions = [eq(vendorSubOrders.vendorId, vendorId)];
|
|
22
18
|
if (filters?.status)
|
|
@@ -42,13 +38,18 @@ export class SubOrderService {
|
|
|
42
38
|
assertTransition(current, next) {
|
|
43
39
|
const allowed = SUB_ORDER_TRANSITIONS[current];
|
|
44
40
|
if (!allowed?.includes(next)) {
|
|
45
|
-
throw new
|
|
41
|
+
throw new CommerceInvalidTransitionError(`Cannot transition sub-order from "${current}" to "${next}".`);
|
|
46
42
|
}
|
|
47
43
|
}
|
|
44
|
+
requireSubOrder(id) {
|
|
45
|
+
return this.getById(id).then((sub) => {
|
|
46
|
+
if (!sub)
|
|
47
|
+
throw new CommerceNotFoundError("Sub-order not found.");
|
|
48
|
+
return sub;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
48
51
|
async confirm(id) {
|
|
49
|
-
const sub = await this.
|
|
50
|
-
if (!sub)
|
|
51
|
-
throw new Error("Sub-order not found.");
|
|
52
|
+
const sub = await this.requireSubOrder(id);
|
|
52
53
|
this.assertTransition(sub.status, "confirmed");
|
|
53
54
|
const [updated] = await this.db.update(vendorSubOrders).set({
|
|
54
55
|
status: "confirmed",
|
|
@@ -58,9 +59,7 @@ export class SubOrderService {
|
|
|
58
59
|
return updated;
|
|
59
60
|
}
|
|
60
61
|
async process(id) {
|
|
61
|
-
const sub = await this.
|
|
62
|
-
if (!sub)
|
|
63
|
-
throw new Error("Sub-order not found.");
|
|
62
|
+
const sub = await this.requireSubOrder(id);
|
|
64
63
|
this.assertTransition(sub.status, "processing");
|
|
65
64
|
const [updated] = await this.db.update(vendorSubOrders).set({
|
|
66
65
|
status: "processing",
|
|
@@ -69,9 +68,7 @@ export class SubOrderService {
|
|
|
69
68
|
return updated;
|
|
70
69
|
}
|
|
71
70
|
async ship(id, data) {
|
|
72
|
-
const sub = await this.
|
|
73
|
-
if (!sub)
|
|
74
|
-
throw new Error("Sub-order not found.");
|
|
71
|
+
const sub = await this.requireSubOrder(id);
|
|
75
72
|
this.assertTransition(sub.status, "shipped");
|
|
76
73
|
const [updated] = await this.db.update(vendorSubOrders).set({
|
|
77
74
|
status: "shipped",
|
|
@@ -83,9 +80,7 @@ export class SubOrderService {
|
|
|
83
80
|
return updated;
|
|
84
81
|
}
|
|
85
82
|
async deliver(id) {
|
|
86
|
-
const sub = await this.
|
|
87
|
-
if (!sub)
|
|
88
|
-
throw new Error("Sub-order not found.");
|
|
83
|
+
const sub = await this.requireSubOrder(id);
|
|
89
84
|
this.assertTransition(sub.status, "delivered");
|
|
90
85
|
const [updated] = await this.db.update(vendorSubOrders).set({
|
|
91
86
|
status: "delivered",
|
|
@@ -95,9 +90,7 @@ export class SubOrderService {
|
|
|
95
90
|
return updated;
|
|
96
91
|
}
|
|
97
92
|
async cancel(id, reason) {
|
|
98
|
-
const sub = await this.
|
|
99
|
-
if (!sub)
|
|
100
|
-
throw new Error("Sub-order not found.");
|
|
93
|
+
const sub = await this.requireSubOrder(id);
|
|
101
94
|
this.assertTransition(sub.status, "cancelled");
|
|
102
95
|
const [updated] = await this.db.update(vendorSubOrders).set({
|
|
103
96
|
status: "cancelled",
|
|
@@ -105,7 +98,6 @@ export class SubOrderService {
|
|
|
105
98
|
cancellationReason: reason,
|
|
106
99
|
updatedAt: new Date(),
|
|
107
100
|
}).where(eq(vendorSubOrders.id, id)).returning();
|
|
108
|
-
// Trigger side effects: release inventory + reverse ledger
|
|
109
101
|
if (this.onCancel && sub) {
|
|
110
102
|
await this.onCancel(sub);
|
|
111
103
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -19,27 +19,11 @@ export type RFQStatus = "open" | "closed" | "awarded" | "cancelled";
|
|
|
19
19
|
export type RFQResponseStatus = "submitted" | "shortlisted" | "accepted" | "rejected" | "withdrawn";
|
|
20
20
|
export interface MarketplacePluginOptions {
|
|
21
21
|
defaultCommissionRateBps?: number;
|
|
22
|
-
vendorApprovalMode?: VendorApprovalMode;
|
|
23
|
-
requiredDocuments?: DocumentType[];
|
|
24
|
-
defaultPayoutSchedule?: PayoutSchedule;
|
|
25
22
|
defaultPayoutMinimumCents?: number;
|
|
26
|
-
defaultHoldbackDays?: number;
|
|
27
23
|
vendorResponseDeadlineDays?: number;
|
|
28
|
-
autoEscalateOnMissedDeadline?: boolean;
|
|
29
|
-
returnWindowDays?: number;
|
|
30
|
-
autoApproveReturnsOnVendorTimeout?: boolean;
|
|
31
|
-
vendorReturnResponseDays?: number;
|
|
32
|
-
requireVerifiedPurchase?: boolean;
|
|
33
24
|
reviewModerationEnabled?: boolean;
|
|
34
25
|
b2b?: {
|
|
35
26
|
rfq?: boolean;
|
|
36
|
-
contractPricing?: boolean;
|
|
37
|
-
};
|
|
38
|
-
performanceThresholds?: {
|
|
39
|
-
minRating?: number;
|
|
40
|
-
maxDefectRatePercent?: number;
|
|
41
|
-
maxLateShipmentRatePercent?: number;
|
|
42
|
-
maxCancellationRatePercent?: number;
|
|
43
27
|
};
|
|
44
28
|
}
|
|
45
29
|
/**
|
|
@@ -63,5 +47,4 @@ export interface RouteContext {
|
|
|
63
47
|
json(data: unknown, status?: number): Response;
|
|
64
48
|
get(key: string): unknown;
|
|
65
49
|
}
|
|
66
|
-
export declare function errorMessage(err: unknown): string;
|
|
67
50
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,WAAW,GACX,YAAY,GACZ,SAAS,GACT,WAAW,GACX,WAAW,CAAC;AAEhB,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,cAAc,EAAE,cAAc,EAAE,CAO1E,CAAC;AAIF,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAChE,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,qBAAqB,GAAG,UAAU,GAAG,UAAU,CAAC;AAChG,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AACrE,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AACpF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,CAAC;AAIlE,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,aAAa,GAAG,aAAa,GAAG,aAAa,CAAC;AAI5F,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,yBAAyB,GACzB,iBAAiB,GACjB,UAAU,GACV,WAAW,GACX,QAAQ,CAAC;AAEb,MAAM,MAAM,aAAa,GACrB,mBAAmB,GACnB,uBAAuB,GACvB,WAAW,GACX,YAAY,GACZ,OAAO,CAAC;AAEZ,MAAM,MAAM,iBAAiB,GACzB,aAAa,GACb,gBAAgB,GAChB,aAAa,GACb,UAAU,GACV,cAAc,GACd,aAAa,CAAC;AAIlB,MAAM,MAAM,YAAY,GACpB,WAAW,GACX,iBAAiB,GACjB,iBAAiB,GACjB,cAAc,GACd,UAAU,GACV,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,MAAM,YAAY,GACpB,WAAW,GACX,YAAY,GACZ,kBAAkB,GAClB,cAAc,GACd,OAAO,CAAC;AAIZ,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,YAAY,GACZ,kBAAkB,GAClB,YAAY,GACZ,QAAQ,CAAC;AAIb,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,CAAC;AACjG,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAIjE,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAI1E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;AACpE,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;AAIpG,MAAM,WAAW,wBAAwB;IACvC,wBAAwB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -7,7 +7,3 @@ export const SUB_ORDER_TRANSITIONS = {
|
|
|
7
7
|
delivered: [],
|
|
8
8
|
cancelled: [],
|
|
9
9
|
};
|
|
10
|
-
// ─── Error helper ────────────────────────────────────────────────────────────
|
|
11
|
-
export function errorMessage(err) {
|
|
12
|
-
return err instanceof Error ? err.message : "Internal server error";
|
|
13
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@porulle/plugin-marketplace",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.65.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@hono/zod-openapi": "^1.2.2",
|
|
22
22
|
"hono": "^4.12.5",
|
|
23
|
-
"@porulle/core": "0.
|
|
23
|
+
"@porulle/core": "0.65.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/node": "^24.5.2",
|
package/src/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
vendors, vendorEntities, vendorSubOrders, vendorPayouts,
|
|
5
5
|
vendorDocuments, commissionRules, vendorBalances,
|
|
6
6
|
disputes, vendorReviews, returnRequests,
|
|
7
|
-
rfqs, rfqResponses,
|
|
7
|
+
rfqs, rfqResponses,
|
|
8
8
|
} from "./schema.js";
|
|
9
9
|
import { VendorService } from "./services/vendor.js";
|
|
10
10
|
import { SubOrderService } from "./services/sub-order.js";
|
|
@@ -14,7 +14,6 @@ import { DisputeService } from "./services/dispute.js";
|
|
|
14
14
|
import { ReturnService } from "./services/return.js";
|
|
15
15
|
import { ReviewService } from "./services/review.js";
|
|
16
16
|
import { RFQService } from "./services/rfq.js";
|
|
17
|
-
import { ContractPriceService } from "./services/contract-price.js";
|
|
18
17
|
import { buildHooks } from "./hooks.js";
|
|
19
18
|
import { buildVendorRoutes } from "./routes/vendors.js";
|
|
20
19
|
import { buildVendorPortalRoutes } from "./routes/vendor-portal.js";
|
|
@@ -35,11 +34,8 @@ function createServices(db: Db, options: MarketplacePluginOptions, kernelService
|
|
|
35
34
|
const returnSvc = new ReturnService(db);
|
|
36
35
|
const review = new ReviewService(db, options);
|
|
37
36
|
const rfq = options.b2b?.rfq ? new RFQService(db) : undefined;
|
|
38
|
-
const contractPrice = options.b2b?.contractPricing ? new ContractPriceService(db) : undefined;
|
|
39
37
|
|
|
40
|
-
// Cancel callback: release inventory on parent order + reverse balance
|
|
41
38
|
const subOrder = new SubOrderService(db, async (sub) => {
|
|
42
|
-
// Release inventory for cancelled vendor's line items
|
|
43
39
|
const inventory = kernelServices?.inventory as
|
|
44
40
|
{ release(input: Record<string, unknown>): Promise<unknown> } | undefined;
|
|
45
41
|
if (inventory?.release && sub.lineItems) {
|
|
@@ -53,7 +49,6 @@ function createServices(db: Db, options: MarketplacePluginOptions, kernelService
|
|
|
53
49
|
}
|
|
54
50
|
}
|
|
55
51
|
|
|
56
|
-
// Reverse balance: debit the sale credit
|
|
57
52
|
if (sub.payoutAmount > 0) {
|
|
58
53
|
await payout.addLedgerEntry({
|
|
59
54
|
vendorId: sub.vendorId,
|
|
@@ -66,7 +61,7 @@ function createServices(db: Db, options: MarketplacePluginOptions, kernelService
|
|
|
66
61
|
}
|
|
67
62
|
});
|
|
68
63
|
|
|
69
|
-
return { vendor, subOrder, commission, payout, dispute, return: returnSvc, review, rfq
|
|
64
|
+
return { vendor, subOrder, commission, payout, dispute, return: returnSvc, review, rfq };
|
|
70
65
|
}
|
|
71
66
|
|
|
72
67
|
export function marketplacePlugin(options: MarketplacePluginOptions = {}) {
|
|
@@ -87,7 +82,6 @@ export function marketplacePlugin(options: MarketplacePluginOptions = {}) {
|
|
|
87
82
|
returnRequests,
|
|
88
83
|
rfqs,
|
|
89
84
|
rfqResponses,
|
|
90
|
-
contractPrices,
|
|
91
85
|
}),
|
|
92
86
|
|
|
93
87
|
hooks: () => buildHooks(options),
|
|
@@ -105,9 +99,7 @@ export function marketplacePlugin(options: MarketplacePluginOptions = {}) {
|
|
|
105
99
|
...buildCommissionRoutes(services),
|
|
106
100
|
...buildPayoutRoutes(services),
|
|
107
101
|
...buildDisputesReturnsReviewsRoutes(services),
|
|
108
|
-
...(options.b2b?.rfq
|
|
109
|
-
? buildB2BRoutes(services, options)
|
|
110
|
-
: []),
|
|
102
|
+
...(options.b2b?.rfq ? buildB2BRoutes(services, options) : []),
|
|
111
103
|
];
|
|
112
104
|
},
|
|
113
105
|
|
package/src/routes/b2b.ts
CHANGED
|
@@ -2,27 +2,19 @@ import { router } from "@porulle/core";
|
|
|
2
2
|
import type { PluginRouteRegistration } from "@porulle/core";
|
|
3
3
|
import type { z } from "@hono/zod-openapi";
|
|
4
4
|
import type { RFQService } from "../services/rfq.js";
|
|
5
|
-
import type { ContractPriceService } from "../services/contract-price.js";
|
|
6
5
|
import type { MarketplacePluginOptions } from "../types.js";
|
|
7
6
|
import {
|
|
8
7
|
CreateRFQBodySchema,
|
|
9
8
|
RespondRFQBodySchema,
|
|
10
9
|
AwardRFQBodySchema,
|
|
11
|
-
CreateContractPriceBodySchema,
|
|
12
|
-
UpdateContractPriceBodySchema,
|
|
13
10
|
} from "../schemas/b2b.js";
|
|
14
11
|
import { stripUndefined } from "./util.js";
|
|
15
12
|
|
|
16
13
|
export function buildB2BRoutes(services: {
|
|
17
14
|
rfq?: RFQService | undefined;
|
|
18
|
-
|
|
19
|
-
}, options: MarketplacePluginOptions): PluginRouteRegistration[] {
|
|
15
|
+
}, _options: MarketplacePluginOptions): PluginRouteRegistration[] {
|
|
20
16
|
const allRoutes: PluginRouteRegistration[] = [];
|
|
21
17
|
|
|
22
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
23
|
-
// RFQ (Request for Quote)
|
|
24
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
25
|
-
|
|
26
18
|
if (services.rfq) {
|
|
27
19
|
const rfqSvc = services.rfq;
|
|
28
20
|
const rfq = router("Marketplace - B2B", "/marketplace/rfq");
|
|
@@ -108,72 +100,5 @@ export function buildB2BRoutes(services: {
|
|
|
108
100
|
allRoutes.push(...rfq.routes());
|
|
109
101
|
}
|
|
110
102
|
|
|
111
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
112
|
-
// CONTRACT PRICES
|
|
113
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
114
|
-
|
|
115
|
-
if (services.contractPrice) {
|
|
116
|
-
const cpSvc = services.contractPrice;
|
|
117
|
-
const cp = router("Marketplace - B2B", "/marketplace/contract-prices");
|
|
118
|
-
|
|
119
|
-
cp.get("/")
|
|
120
|
-
.summary("List contract prices")
|
|
121
|
-
.auth()
|
|
122
|
-
.handler(async ({ query }) => {
|
|
123
|
-
return cpSvc.list(stripUndefined({
|
|
124
|
-
vendorId: query.vendorId as string | undefined,
|
|
125
|
-
buyerId: query.buyerId as string | undefined,
|
|
126
|
-
}));
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
cp.post("/")
|
|
130
|
-
.summary("Create a contract price")
|
|
131
|
-
.auth()
|
|
132
|
-
.permission("marketplace:admin")
|
|
133
|
-
.input(CreateContractPriceBodySchema)
|
|
134
|
-
.handler(async ({ input }) => {
|
|
135
|
-
const body = input as z.infer<typeof CreateContractPriceBodySchema>;
|
|
136
|
-
return cpSvc.create(stripUndefined({
|
|
137
|
-
vendorId: body.vendorId,
|
|
138
|
-
buyerId: body.buyerId,
|
|
139
|
-
entityId: body.entityId,
|
|
140
|
-
variantId: body.variantId,
|
|
141
|
-
priceCents: body.priceCents,
|
|
142
|
-
minQuantity: body.minQuantity,
|
|
143
|
-
currency: body.currency,
|
|
144
|
-
validFrom: body.validFrom ? new Date(body.validFrom) : undefined,
|
|
145
|
-
validUntil: body.validUntil ? new Date(body.validUntil) : undefined,
|
|
146
|
-
}));
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
cp.patch("/{id}")
|
|
150
|
-
.summary("Update a contract price")
|
|
151
|
-
.auth()
|
|
152
|
-
.permission("marketplace:admin")
|
|
153
|
-
.input(UpdateContractPriceBodySchema)
|
|
154
|
-
.handler(async ({ params, input }) => {
|
|
155
|
-
const body = input as z.infer<typeof UpdateContractPriceBodySchema>;
|
|
156
|
-
const updateData: Record<string, unknown> = {};
|
|
157
|
-
if (body.priceCents !== undefined) updateData.priceCents = body.priceCents;
|
|
158
|
-
if (body.minQuantity !== undefined) updateData.minQuantity = body.minQuantity;
|
|
159
|
-
if (body.validFrom !== undefined) updateData.validFrom = body.validFrom ? new Date(body.validFrom) : null;
|
|
160
|
-
if (body.validUntil !== undefined) updateData.validUntil = body.validUntil ? new Date(body.validUntil) : null;
|
|
161
|
-
const updated = await cpSvc.update(params.id!, updateData);
|
|
162
|
-
if (!updated) throw new Error("Contract price not found");
|
|
163
|
-
return updated;
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
cp.delete("/{id}")
|
|
167
|
-
.summary("Delete a contract price")
|
|
168
|
-
.auth()
|
|
169
|
-
.permission("marketplace:admin")
|
|
170
|
-
.handler(async ({ params }) => {
|
|
171
|
-
await cpSvc.delete(params.id!);
|
|
172
|
-
return { deleted: true };
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
allRoutes.push(...cp.routes());
|
|
176
|
-
}
|
|
177
|
-
|
|
178
103
|
return allRoutes;
|
|
179
104
|
}
|
package/src/routes/sub-orders.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { router } from "@porulle/core";
|
|
1
|
+
import { router, CommerceNotFoundError } from "@porulle/core";
|
|
2
2
|
import type { PluginRouteRegistration } from "@porulle/core";
|
|
3
3
|
import type { z } from "@hono/zod-openapi";
|
|
4
4
|
import type { SubOrderService } from "../services/sub-order.js";
|
|
@@ -29,7 +29,7 @@ export function buildSubOrderRoutes(services: {
|
|
|
29
29
|
.permission("marketplace:admin")
|
|
30
30
|
.handler(async ({ params }) => {
|
|
31
31
|
const subOrder = await services.subOrder.getById(params.id!);
|
|
32
|
-
if (!subOrder) throw new
|
|
32
|
+
if (!subOrder) throw new CommerceNotFoundError("Sub-order not found.");
|
|
33
33
|
return subOrder;
|
|
34
34
|
});
|
|
35
35
|
|
|
@@ -41,7 +41,7 @@ export function buildSubOrderRoutes(services: {
|
|
|
41
41
|
.handler(async ({ params, input }) => {
|
|
42
42
|
const body = input as z.infer<typeof UpdateSubOrderStatusBodySchema>;
|
|
43
43
|
const subOrder = await services.subOrder.getById(params.id!);
|
|
44
|
-
if (!subOrder) throw new
|
|
44
|
+
if (!subOrder) throw new CommerceNotFoundError("Sub-order not found.");
|
|
45
45
|
|
|
46
46
|
// Use cancel() for cancelled status to trigger side effects
|
|
47
47
|
// (inventory release + ledger reversal)
|