Spaces:
Runtime error
Runtime error
Commit
·
146b1cb
1
Parent(s):
68fe061
...
Browse files- .file +97 -0
- api/index.js +1730 -0
- cache.js +92 -0
- chat.html +337 -0
- functions.js +364 -0
- index.js +850 -58
- package.json +1 -0
- swagger.json +223 -21
- swagger.yaml +159 -19
- utils.js +1 -1
- vercel.json +15 -0
- yarn.lock +159 -1
.file
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @swagger
|
| 3 |
+
* /company/{companyId}/departments:
|
| 4 |
+
* get:
|
| 5 |
+
* summary: Retrieve departments for a specific company
|
| 6 |
+
* description: Fetches a list of departments associated with the given company ID.
|
| 7 |
+
* tags: [Company]
|
| 8 |
+
* operationId: getCompanyDepartments
|
| 9 |
+
* parameters:
|
| 10 |
+
* - in: path
|
| 11 |
+
* name: companyId
|
| 12 |
+
* required: true
|
| 13 |
+
* schema:
|
| 14 |
+
* type: string
|
| 15 |
+
* description: The unique identifier of the company
|
| 16 |
+
* responses:
|
| 17 |
+
* 200:
|
| 18 |
+
* description: An array of department objects
|
| 19 |
+
* content:
|
| 20 |
+
* application/json:
|
| 21 |
+
* schema:
|
| 22 |
+
* type: array
|
| 23 |
+
* items:
|
| 24 |
+
* type: object
|
| 25 |
+
* properties:
|
| 26 |
+
* name:
|
| 27 |
+
* type: string
|
| 28 |
+
* description: Name of the department
|
| 29 |
+
* slug:
|
| 30 |
+
* type: string
|
| 31 |
+
* description: slug or identifier of the department
|
| 32 |
+
*/
|
| 33 |
+
|
| 34 |
+
app.get("/company/:companyId/departments", async (req, res, next) => {
|
| 35 |
+
try {
|
| 36 |
+
const { companyId } = req.params;
|
| 37 |
+
const client = await initClient(companyId);
|
| 38 |
+
let departments = await client.catalog.listDepartmentsData({
|
| 39 |
+
isActive: true, pageSize: 100, pageNo: 1
|
| 40 |
+
});
|
| 41 |
+
departments = departments?.items?.map(i => { return { name: i.name, slug: i.slug } })
|
| 42 |
+
res.json(departments);
|
| 43 |
+
|
| 44 |
+
} catch (e) { next(e) }
|
| 45 |
+
})
|
| 46 |
+
/**
|
| 47 |
+
* @swagger
|
| 48 |
+
* /company/{companyId}/departments/{departmentSlug}:
|
| 49 |
+
* get:
|
| 50 |
+
* summary: Retrieve categories for a specific department
|
| 51 |
+
* description: Retrieve categories for a specific department.
|
| 52 |
+
* tags: [Company]
|
| 53 |
+
* operationId: getDepartmentCategories
|
| 54 |
+
* parameters:
|
| 55 |
+
* - in: path
|
| 56 |
+
* name: companyId
|
| 57 |
+
* required: true
|
| 58 |
+
* schema:
|
| 59 |
+
* type: string
|
| 60 |
+
* description: The unique identifier of the company
|
| 61 |
+
* - in: path
|
| 62 |
+
* name: departmentSlug
|
| 63 |
+
* required: true
|
| 64 |
+
* schema:
|
| 65 |
+
* type: string
|
| 66 |
+
* description: The unique skug of the department to get categories
|
| 67 |
+
* responses:
|
| 68 |
+
* 200:
|
| 69 |
+
* description: An array of department objects
|
| 70 |
+
* content:
|
| 71 |
+
* application/json:
|
| 72 |
+
* schema:
|
| 73 |
+
* type: array
|
| 74 |
+
* items:
|
| 75 |
+
* type: object
|
| 76 |
+
* properties:
|
| 77 |
+
* name:
|
| 78 |
+
* type: string
|
| 79 |
+
* description: Name of the category
|
| 80 |
+
* slug:
|
| 81 |
+
* type: string
|
| 82 |
+
* description: slug or identifier of the catrgory
|
| 83 |
+
*/
|
| 84 |
+
|
| 85 |
+
app.get("/company/:companyId/departments/:departmentSlug", async (req, res, next) => {
|
| 86 |
+
try {
|
| 87 |
+
const { companyId, departmentSlug } = req.params;
|
| 88 |
+
const { item_type = 'single' } = req.query;
|
| 89 |
+
const client = await initClient(companyId);
|
| 90 |
+
let categories = await client.catalog.listProductTemplateCategories({
|
| 91 |
+
departments: departmentSlug, pageNo: 1, pageSize: 100, itemType: item_type
|
| 92 |
+
});
|
| 93 |
+
categories = categories?.items?.map(i => { return { name: i.name, slug: i.slug } })
|
| 94 |
+
res.json(categories);
|
| 95 |
+
|
| 96 |
+
} catch (e) { next(e) }
|
| 97 |
+
})
|
api/index.js
ADDED
|
@@ -0,0 +1,1730 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import express from "express";
|
| 2 |
+
import Redis from "ioredis";
|
| 3 |
+
import { initClient } from './utils.js';
|
| 4 |
+
import { errorHandler } from './middleware.js';
|
| 5 |
+
import swaggerJSDoc from 'swagger-jsdoc';
|
| 6 |
+
import yaml from 'js-yaml'
|
| 7 |
+
import fs from 'fs';
|
| 8 |
+
import { RedisListCache } from './cache.js';
|
| 9 |
+
const listCache = new RedisListCache({ namespace: "fc" })
|
| 10 |
+
const redis = new Redis();
|
| 11 |
+
|
| 12 |
+
const app = express();
|
| 13 |
+
const port = process.env.PORT;
|
| 14 |
+
app.use(express.json({}));
|
| 15 |
+
const swaggerDefinition = {
|
| 16 |
+
openapi: '3.0.0',
|
| 17 |
+
info: {
|
| 18 |
+
title: 'Express API Documentation',
|
| 19 |
+
version: '1.0.0',
|
| 20 |
+
description: 'This is the API documentation for my Express application.'
|
| 21 |
+
},
|
| 22 |
+
servers: [{
|
| 23 |
+
url: "https://934a-45-119-30-178.ngrok-free.app"
|
| 24 |
+
}]
|
| 25 |
+
};
|
| 26 |
+
const options = {
|
| 27 |
+
swaggerDefinition,
|
| 28 |
+
// Path to the API docs
|
| 29 |
+
apis: ['./index.js'], // Adjust the path according to your file structure
|
| 30 |
+
};
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
/**
|
| 35 |
+
* @swagger
|
| 36 |
+
* components:
|
| 37 |
+
* schemas:
|
| 38 |
+
* CompanyCreds:
|
| 39 |
+
* type: object
|
| 40 |
+
* properties:
|
| 41 |
+
* clientId:
|
| 42 |
+
* type: string
|
| 43 |
+
* description: Client ID for the company
|
| 44 |
+
* clientSecret:
|
| 45 |
+
* type: string
|
| 46 |
+
* description: Client secret for the company
|
| 47 |
+
* required:
|
| 48 |
+
* - clientId
|
| 49 |
+
* - clientSecret
|
| 50 |
+
* CreateUpdateLocation:
|
| 51 |
+
* type: object
|
| 52 |
+
* required:
|
| 53 |
+
* - code
|
| 54 |
+
* - name
|
| 55 |
+
* - gst
|
| 56 |
+
* - manager
|
| 57 |
+
* - address
|
| 58 |
+
* properties:
|
| 59 |
+
* code:
|
| 60 |
+
* type: string
|
| 61 |
+
* description: Unique code for the location
|
| 62 |
+
* name:
|
| 63 |
+
* type: string
|
| 64 |
+
* description: Name of the location
|
| 65 |
+
* gst:
|
| 66 |
+
* type: object
|
| 67 |
+
* required:
|
| 68 |
+
* - legal_name
|
| 69 |
+
* - value
|
| 70 |
+
* properties:
|
| 71 |
+
* legal_name:
|
| 72 |
+
* type: string
|
| 73 |
+
* description: Legal name for GST purposes
|
| 74 |
+
* value:
|
| 75 |
+
* type: string
|
| 76 |
+
* description: GST value
|
| 77 |
+
* manager:
|
| 78 |
+
* type: object
|
| 79 |
+
* required:
|
| 80 |
+
* - manager_name
|
| 81 |
+
* - email
|
| 82 |
+
* - number
|
| 83 |
+
* - country_code
|
| 84 |
+
* properties:
|
| 85 |
+
* manager_name:
|
| 86 |
+
* type: string
|
| 87 |
+
* description: Name of the manager
|
| 88 |
+
* email:
|
| 89 |
+
* type: string
|
| 90 |
+
* description: Email of the manager
|
| 91 |
+
* number:
|
| 92 |
+
* type: string
|
| 93 |
+
* description: Contact number of the manager
|
| 94 |
+
* country_code:
|
| 95 |
+
* type: string
|
| 96 |
+
* description: Country code for the manager's contact number
|
| 97 |
+
* address:
|
| 98 |
+
* type: object
|
| 99 |
+
* required:
|
| 100 |
+
* - address1
|
| 101 |
+
* - country
|
| 102 |
+
* - pincode
|
| 103 |
+
* - city
|
| 104 |
+
* - state
|
| 105 |
+
* properties:
|
| 106 |
+
* address1:
|
| 107 |
+
* type: string
|
| 108 |
+
* description: Primary address line
|
| 109 |
+
* address2:
|
| 110 |
+
* type: string
|
| 111 |
+
* description: Secondary address line
|
| 112 |
+
* country:
|
| 113 |
+
* type: string
|
| 114 |
+
* description: Country of the location
|
| 115 |
+
* pincode:
|
| 116 |
+
* type: string
|
| 117 |
+
* description: Postal code of the location
|
| 118 |
+
* city:
|
| 119 |
+
* type: string
|
| 120 |
+
* description: City of the location
|
| 121 |
+
* state:
|
| 122 |
+
* type: string
|
| 123 |
+
* description: State of the location
|
| 124 |
+
* latitude:
|
| 125 |
+
* type: number
|
| 126 |
+
* description: Latitude for the location
|
| 127 |
+
* longitude:
|
| 128 |
+
* type: number
|
| 129 |
+
* description: Longitude for the location
|
| 130 |
+
* landmark:
|
| 131 |
+
* type: string
|
| 132 |
+
* description: Landmark near the location
|
| 133 |
+
* Brand:
|
| 134 |
+
* type: object
|
| 135 |
+
* properties:
|
| 136 |
+
* name:
|
| 137 |
+
* type: string
|
| 138 |
+
* logo:
|
| 139 |
+
* type: string
|
| 140 |
+
* id:
|
| 141 |
+
* type: string
|
| 142 |
+
* BrandCreation:
|
| 143 |
+
* type: object
|
| 144 |
+
* required:
|
| 145 |
+
* - name
|
| 146 |
+
* - logo
|
| 147 |
+
* - description
|
| 148 |
+
* properties:
|
| 149 |
+
* name:
|
| 150 |
+
* type: string
|
| 151 |
+
* logo:
|
| 152 |
+
* type: string
|
| 153 |
+
* description:
|
| 154 |
+
* type: string
|
| 155 |
+
* ErrorResponse:
|
| 156 |
+
* type: object
|
| 157 |
+
* properties:
|
| 158 |
+
* message:
|
| 159 |
+
* type: string
|
| 160 |
+
* description: Error message
|
| 161 |
+
*/
|
| 162 |
+
|
| 163 |
+
app.get(['/swagger.yaml', '/swagger.json'], (req, res) => {
|
| 164 |
+
// Initialize swagger-jsdoc
|
| 165 |
+
const swaggerSpec = swaggerJSDoc(options);
|
| 166 |
+
|
| 167 |
+
// Convert to YAML
|
| 168 |
+
const swaggerYAML = yaml.dump(swaggerSpec);
|
| 169 |
+
switch (req.path.split('.').pop()) {
|
| 170 |
+
case 'json':
|
| 171 |
+
res.setHeader('Content-Type', 'application/json');
|
| 172 |
+
return res.send(JSON.stringify(swaggerSpec, null, 2));
|
| 173 |
+
case 'yaml':
|
| 174 |
+
res.setHeader('Content-Type', 'text/yaml');
|
| 175 |
+
return res.send(swaggerYAML);
|
| 176 |
+
}
|
| 177 |
+
});
|
| 178 |
+
|
| 179 |
+
/**
|
| 180 |
+
* @swagger
|
| 181 |
+
* /_healthz:
|
| 182 |
+
* get:
|
| 183 |
+
* operationId: getHealthZ
|
| 184 |
+
* description: Check server health
|
| 185 |
+
* responses:
|
| 186 |
+
* 200:
|
| 187 |
+
* description: Server is healthy
|
| 188 |
+
* content:
|
| 189 |
+
* text/plain:
|
| 190 |
+
* schema:
|
| 191 |
+
* type: string
|
| 192 |
+
* example: Hello World!
|
| 193 |
+
*/
|
| 194 |
+
app.get("/_healthz", (req, res) => {
|
| 195 |
+
res.send('Hello World!');
|
| 196 |
+
});
|
| 197 |
+
app.get("/privacy", (req, res) => {
|
| 198 |
+
res.send('This is the privacy policy page!');
|
| 199 |
+
});
|
| 200 |
+
|
| 201 |
+
/**
|
| 202 |
+
* @swagger
|
| 203 |
+
* /company/{companyId}:
|
| 204 |
+
* get:
|
| 205 |
+
* operationId: getOrVerifyCompanyCredentials
|
| 206 |
+
* description: Retrieve company credentials
|
| 207 |
+
* tags: [Company]
|
| 208 |
+
* parameters:
|
| 209 |
+
* - in: path
|
| 210 |
+
* name: companyId
|
| 211 |
+
* required: true
|
| 212 |
+
* schema:
|
| 213 |
+
* type: string
|
| 214 |
+
* description: The company ID
|
| 215 |
+
* responses:
|
| 216 |
+
* 200:
|
| 217 |
+
* description: Company credentials retrieved successfully
|
| 218 |
+
* content:
|
| 219 |
+
* application/json:
|
| 220 |
+
* schema:
|
| 221 |
+
* $ref: '#/components/schemas/CompanyCreds'
|
| 222 |
+
* 404:
|
| 223 |
+
* description: Company credentials not found
|
| 224 |
+
* content:
|
| 225 |
+
* application/json:
|
| 226 |
+
* schema:
|
| 227 |
+
* $ref: '#/components/schemas/ErrorResponse'
|
| 228 |
+
*/
|
| 229 |
+
app.get("/company/:companyId", async (req, res, next) => {
|
| 230 |
+
try {
|
| 231 |
+
const { companyId } = req.params;
|
| 232 |
+
const creds = await redis.get(`${companyId}:creds`);
|
| 233 |
+
if (!creds) {
|
| 234 |
+
throw {
|
| 235 |
+
message: "company creds not found"
|
| 236 |
+
}
|
| 237 |
+
}
|
| 238 |
+
res.json({ ...JSON.parse(creds), companyId })
|
| 239 |
+
} catch (e) {
|
| 240 |
+
next(e)
|
| 241 |
+
}
|
| 242 |
+
})
|
| 243 |
+
|
| 244 |
+
/**
|
| 245 |
+
* @swagger
|
| 246 |
+
* /company/{companyId}:
|
| 247 |
+
* put:
|
| 248 |
+
* operationId: updateCompanyCredentials
|
| 249 |
+
* description: Update company credentials
|
| 250 |
+
* tags: [Company]
|
| 251 |
+
* parameters:
|
| 252 |
+
* - in: path
|
| 253 |
+
* name: companyId
|
| 254 |
+
* required: true
|
| 255 |
+
* schema:
|
| 256 |
+
* type: string
|
| 257 |
+
* description: The company ID
|
| 258 |
+
* requestBody:
|
| 259 |
+
* required: true
|
| 260 |
+
* content:
|
| 261 |
+
* application/json:
|
| 262 |
+
* schema:
|
| 263 |
+
* $ref: '#/components/schemas/CompanyCreds'
|
| 264 |
+
* responses:
|
| 265 |
+
* 200:
|
| 266 |
+
* description: Company credentials updated successfully
|
| 267 |
+
* content:
|
| 268 |
+
* application/json:
|
| 269 |
+
* schema:
|
| 270 |
+
* type: object
|
| 271 |
+
* properties:
|
| 272 |
+
* message:
|
| 273 |
+
* type: string
|
| 274 |
+
* 400:
|
| 275 |
+
* description: Invalid input
|
| 276 |
+
* content:
|
| 277 |
+
* application/json:
|
| 278 |
+
* schema:
|
| 279 |
+
* $ref: '#/components/schemas/ErrorResponse'
|
| 280 |
+
*/
|
| 281 |
+
app.put("/company/:companyId", async (req, res, next) => {
|
| 282 |
+
try {
|
| 283 |
+
const { companyId } = req.params;
|
| 284 |
+
const { clientId, clientSecret } = req.body
|
| 285 |
+
const creds = await redis.set(`${companyId}:creds`, JSON.stringify({ clientId, clientSecret }));
|
| 286 |
+
res.json({ message: "company creds saved" })
|
| 287 |
+
} catch (e) {
|
| 288 |
+
next(e)
|
| 289 |
+
}
|
| 290 |
+
})
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
|
| 294 |
+
/**
|
| 295 |
+
* @swagger
|
| 296 |
+
* /company/{companyId}/applications:
|
| 297 |
+
* get:
|
| 298 |
+
* operationId: getSalesChannelByCompany
|
| 299 |
+
* description: Retrieve applications for a specific company
|
| 300 |
+
* tags: [Company]
|
| 301 |
+
* parameters:
|
| 302 |
+
* - in: path
|
| 303 |
+
* name: companyId
|
| 304 |
+
* required: true
|
| 305 |
+
* schema:
|
| 306 |
+
* type: string
|
| 307 |
+
* description: The ID of the company to retrieve applications for
|
| 308 |
+
* responses:
|
| 309 |
+
* 200:
|
| 310 |
+
* description: List of applications for the specified company
|
| 311 |
+
* content:
|
| 312 |
+
* application/json:
|
| 313 |
+
* schema:
|
| 314 |
+
* type: array
|
| 315 |
+
* items:
|
| 316 |
+
* type: object
|
| 317 |
+
* properties:
|
| 318 |
+
* name:
|
| 319 |
+
* type: string
|
| 320 |
+
* description: Name of the application
|
| 321 |
+
* id:
|
| 322 |
+
* type: string
|
| 323 |
+
* description: ID of the application
|
| 324 |
+
* token:
|
| 325 |
+
* type: string
|
| 326 |
+
* description: Token associated with the application
|
| 327 |
+
* domain:
|
| 328 |
+
* type: string
|
| 329 |
+
* description: Primary domain of the application
|
| 330 |
+
* logo:
|
| 331 |
+
* type: string
|
| 332 |
+
* description: Logo URL of the application
|
| 333 |
+
* 500:
|
| 334 |
+
* description: Server error
|
| 335 |
+
* content:
|
| 336 |
+
* application/json:
|
| 337 |
+
* schema:
|
| 338 |
+
* $ref: '#/components/schemas/ErrorResponse'
|
| 339 |
+
*/
|
| 340 |
+
app.get("/company/:companyId/applications", async (req, res, next) => {
|
| 341 |
+
try {
|
| 342 |
+
const { companyId } = req.params;
|
| 343 |
+
const client = await initClient(companyId);
|
| 344 |
+
let applications = await client.configuration.getApplications({ pageSize: 100 });
|
| 345 |
+
applications = applications.items.map(i => {
|
| 346 |
+
return {
|
| 347 |
+
name: i.name,
|
| 348 |
+
id: i.id,
|
| 349 |
+
token: i.token,
|
| 350 |
+
domain: i.domains?.find(i => i.is_primary)?.name,
|
| 351 |
+
logo: i.logo?.secure_url
|
| 352 |
+
}
|
| 353 |
+
})
|
| 354 |
+
res.json(applications)
|
| 355 |
+
} catch (e) {
|
| 356 |
+
next(e)
|
| 357 |
+
}
|
| 358 |
+
})
|
| 359 |
+
|
| 360 |
+
/**
|
| 361 |
+
* @swagger
|
| 362 |
+
* /company/{companyId}/brands:
|
| 363 |
+
* get:
|
| 364 |
+
* summary: Retrieves a list of brands for a specific company
|
| 365 |
+
* tags: [Brands]
|
| 366 |
+
* operationId: getCompanyBrands
|
| 367 |
+
* description: Fetches a list of brands associated with the given company ID.
|
| 368 |
+
* parameters:
|
| 369 |
+
* - in: path
|
| 370 |
+
* name: companyId
|
| 371 |
+
* required: true
|
| 372 |
+
* schema:
|
| 373 |
+
* type: string
|
| 374 |
+
* description: The unique identifier of the company
|
| 375 |
+
* responses:
|
| 376 |
+
* 200:
|
| 377 |
+
* description: A list of brands
|
| 378 |
+
* content:
|
| 379 |
+
* application/json:
|
| 380 |
+
* schema:
|
| 381 |
+
* type: array
|
| 382 |
+
* items:
|
| 383 |
+
* $ref: '#/components/schemas/Brand'
|
| 384 |
+
*/
|
| 385 |
+
app.get("/company/:companyId/brands", async (req, res, next) => {
|
| 386 |
+
try {
|
| 387 |
+
const { companyId } = req.params;
|
| 388 |
+
const client = await initClient(companyId);
|
| 389 |
+
let brands = await client.companyProfile.getBrands({ pageSize: 300 });
|
| 390 |
+
brands = brands.items.map(i => {
|
| 391 |
+
return {
|
| 392 |
+
name: i?.brand?.name,
|
| 393 |
+
logo: i?.brand?.logo,
|
| 394 |
+
id: i?.brand?.uid,
|
| 395 |
+
}
|
| 396 |
+
})
|
| 397 |
+
res.json(brands)
|
| 398 |
+
} catch (e) {
|
| 399 |
+
next(e)
|
| 400 |
+
}
|
| 401 |
+
})
|
| 402 |
+
|
| 403 |
+
/**
|
| 404 |
+
* @swagger
|
| 405 |
+
* /company/{companyId}/brands:
|
| 406 |
+
* post:
|
| 407 |
+
* summary: Creates a new brand for a specific company
|
| 408 |
+
* tags: [Brands]
|
| 409 |
+
* operationId: createCompanyBrand
|
| 410 |
+
* description: Adds a new brand to the company profile.
|
| 411 |
+
* parameters:
|
| 412 |
+
* - in: path
|
| 413 |
+
* name: companyId
|
| 414 |
+
* required: true
|
| 415 |
+
* schema:
|
| 416 |
+
* type: string
|
| 417 |
+
* description: The unique identifier of the company
|
| 418 |
+
* requestBody:
|
| 419 |
+
* required: true
|
| 420 |
+
* content:
|
| 421 |
+
* application/json:
|
| 422 |
+
* schema:
|
| 423 |
+
* $ref: '#/components/schemas/BrandCreation'
|
| 424 |
+
* responses:
|
| 425 |
+
* 200:
|
| 426 |
+
* description: Brand created successfully
|
| 427 |
+
* content:
|
| 428 |
+
* application/json:
|
| 429 |
+
* schema:
|
| 430 |
+
* type: object
|
| 431 |
+
* properties:
|
| 432 |
+
* message:
|
| 433 |
+
* type: string
|
| 434 |
+
* id:
|
| 435 |
+
* type: string
|
| 436 |
+
*
|
| 437 |
+
* /company/{companyId}/brands/{brandId}:
|
| 438 |
+
* put:
|
| 439 |
+
* summary: Creates a new brand for a specific company
|
| 440 |
+
* tags: [Brands]
|
| 441 |
+
* operationId: updateCompanyBrand
|
| 442 |
+
* description: updated an existing brand.
|
| 443 |
+
* parameters:
|
| 444 |
+
* - in: path
|
| 445 |
+
* name: companyId
|
| 446 |
+
* required: true
|
| 447 |
+
* schema:
|
| 448 |
+
* type: string
|
| 449 |
+
* description: The unique identifier of the company
|
| 450 |
+
* - in: path
|
| 451 |
+
* name: brandId
|
| 452 |
+
* required: true
|
| 453 |
+
* schema:
|
| 454 |
+
* type: number
|
| 455 |
+
* description: The unique identifier of the brand
|
| 456 |
+
* requestBody:
|
| 457 |
+
* required: true
|
| 458 |
+
* content:
|
| 459 |
+
* application/json:
|
| 460 |
+
* schema:
|
| 461 |
+
* $ref: '#/components/schemas/BrandCreation'
|
| 462 |
+
* responses:
|
| 463 |
+
* 200:
|
| 464 |
+
* description: Brand updated successfully
|
| 465 |
+
* content:
|
| 466 |
+
* application/json:
|
| 467 |
+
* schema:
|
| 468 |
+
* type: object
|
| 469 |
+
* properties:
|
| 470 |
+
* message:
|
| 471 |
+
* type: string
|
| 472 |
+
* id:
|
| 473 |
+
* type: string
|
| 474 |
+
*/
|
| 475 |
+
app.post("/company/:companyId/brands", async (req, res, next) => {
|
| 476 |
+
try {
|
| 477 |
+
const { companyId } = req.params;
|
| 478 |
+
const client = await initClient(companyId);
|
| 479 |
+
const {
|
| 480 |
+
name,
|
| 481 |
+
logo = "https://cdn.pixelbin.io/v2/falling-surf-7c8bb8/fyprod/wrkr/platform/pictures/favicon/original/ZWTmgEoFQ-platform-favicon.png",
|
| 482 |
+
description
|
| 483 |
+
} = req.body
|
| 484 |
+
let brands = await client.companyProfile.createBrand({
|
| 485 |
+
body: {
|
| 486 |
+
name,
|
| 487 |
+
description,
|
| 488 |
+
logo,
|
| 489 |
+
banner: { portrait: logo, landscape: logo }
|
| 490 |
+
}
|
| 491 |
+
});
|
| 492 |
+
res.json({ message: "brand created", id: brands?.id })
|
| 493 |
+
} catch (e) {
|
| 494 |
+
next(e)
|
| 495 |
+
}
|
| 496 |
+
})
|
| 497 |
+
app.put("/company/:companyId/brands/:brandId", async (req, res, next) => {
|
| 498 |
+
try {
|
| 499 |
+
const { companyId, brandId } = req.params;
|
| 500 |
+
const client = await initClient(companyId);
|
| 501 |
+
const {
|
| 502 |
+
name,
|
| 503 |
+
logo = "https://cdn.pixelbin.io/v2/falling-surf-7c8bb8/fyprod/wrkr/platform/pictures/favicon/original/ZWTmgEoFQ-platform-favicon.png",
|
| 504 |
+
description
|
| 505 |
+
} = req.body
|
| 506 |
+
let brands = await client.companyProfile.editBrand({
|
| 507 |
+
brandId,
|
| 508 |
+
body: {
|
| 509 |
+
name,
|
| 510 |
+
description,
|
| 511 |
+
logo,
|
| 512 |
+
banner: { portrait: logo, landscape: logo }
|
| 513 |
+
}
|
| 514 |
+
});
|
| 515 |
+
res.json({ message: "brand updated", id: brands?.id })
|
| 516 |
+
} catch (e) {
|
| 517 |
+
next(e)
|
| 518 |
+
}
|
| 519 |
+
})
|
| 520 |
+
|
| 521 |
+
/**
|
| 522 |
+
* @swagger
|
| 523 |
+
* /company/{companyId}/locations:
|
| 524 |
+
* get:
|
| 525 |
+
* operationId: getLocationsByCompany
|
| 526 |
+
* description: get all company locations
|
| 527 |
+
* tags: [Company]
|
| 528 |
+
* parameters:
|
| 529 |
+
* - in: path
|
| 530 |
+
* name: companyId
|
| 531 |
+
* required: true
|
| 532 |
+
* schema:
|
| 533 |
+
* type: string
|
| 534 |
+
* description: The ID of the company to add a location for
|
| 535 |
+
* responses:
|
| 536 |
+
* 200:
|
| 537 |
+
* description: location list
|
| 538 |
+
* content:
|
| 539 |
+
* application/json:
|
| 540 |
+
* schema:
|
| 541 |
+
* type: array
|
| 542 |
+
* items:
|
| 543 |
+
* properties:
|
| 544 |
+
* id:
|
| 545 |
+
* type: number
|
| 546 |
+
* description: Location id
|
| 547 |
+
* code:
|
| 548 |
+
* type: string
|
| 549 |
+
* description: Location code
|
| 550 |
+
* name:
|
| 551 |
+
* type: string
|
| 552 |
+
* description: Location code
|
| 553 |
+
* documents:
|
| 554 |
+
* type: array
|
| 555 |
+
* description: Location gst documents
|
| 556 |
+
* items:
|
| 557 |
+
* type: object
|
| 558 |
+
* properties:
|
| 559 |
+
* type:
|
| 560 |
+
* type: string
|
| 561 |
+
* description: document type
|
| 562 |
+
* value:
|
| 563 |
+
* type: string
|
| 564 |
+
* description: document number
|
| 565 |
+
* verified:
|
| 566 |
+
* type: boolean
|
| 567 |
+
* description: document number verification status
|
| 568 |
+
* legal_name:
|
| 569 |
+
* type: boolean
|
| 570 |
+
* description: document owner
|
| 571 |
+
* 400:
|
| 572 |
+
* description: Invalid input
|
| 573 |
+
* content:
|
| 574 |
+
* application/json:
|
| 575 |
+
* schema:
|
| 576 |
+
* $ref: '#/components/schemas/ErrorResponse'
|
| 577 |
+
*/
|
| 578 |
+
app.get("/company/:companyId/locations", async (req, res, next) => {
|
| 579 |
+
try {
|
| 580 |
+
const { companyId } = req.params;
|
| 581 |
+
const client = await initClient(companyId.toString());
|
| 582 |
+
let locations = await client.companyProfile.getLocations({ pageSize: 100 });
|
| 583 |
+
locations = locations.items.map(i => {
|
| 584 |
+
return {
|
| 585 |
+
name: i.name,
|
| 586 |
+
id: i.uid,
|
| 587 |
+
code: i.code,
|
| 588 |
+
documents: i.documents
|
| 589 |
+
}
|
| 590 |
+
})
|
| 591 |
+
res.json(locations)
|
| 592 |
+
} catch (e) {
|
| 593 |
+
next(e)
|
| 594 |
+
}
|
| 595 |
+
})
|
| 596 |
+
/**
|
| 597 |
+
* @swagger
|
| 598 |
+
* /company/{companyId}/locations:
|
| 599 |
+
* post:
|
| 600 |
+
* operationId: createLocationsForCompany
|
| 601 |
+
* description: Add a new location for a specific company
|
| 602 |
+
* tags: [Company]
|
| 603 |
+
* parameters:
|
| 604 |
+
* - in: path
|
| 605 |
+
* name: companyId
|
| 606 |
+
* required: true
|
| 607 |
+
* schema:
|
| 608 |
+
* type: string
|
| 609 |
+
* description: The ID of the company to add a location for
|
| 610 |
+
* requestBody:
|
| 611 |
+
* required: true
|
| 612 |
+
* content:
|
| 613 |
+
* application/json:
|
| 614 |
+
* schema:
|
| 615 |
+
* $ref: '#/components/schemas/CreateUpdateLocation'
|
| 616 |
+
* responses:
|
| 617 |
+
* 200:
|
| 618 |
+
* description: Location created successfully
|
| 619 |
+
* content:
|
| 620 |
+
* application/json:
|
| 621 |
+
* schema:
|
| 622 |
+
* type: object
|
| 623 |
+
* properties:
|
| 624 |
+
* message:
|
| 625 |
+
* type: string
|
| 626 |
+
* id:
|
| 627 |
+
* type: string
|
| 628 |
+
* description: Location id
|
| 629 |
+
* 400:
|
| 630 |
+
* description: Invalid input
|
| 631 |
+
* content:
|
| 632 |
+
* application/json:
|
| 633 |
+
* schema:
|
| 634 |
+
* $ref: '#/components/schemas/ErrorResponse'
|
| 635 |
+
* /company/{companyId}/locations/{locationId}:
|
| 636 |
+
* put:
|
| 637 |
+
* operationId: updateLocationByCompany
|
| 638 |
+
* description: update a location for a specific company
|
| 639 |
+
* tags: [Company]
|
| 640 |
+
* parameters:
|
| 641 |
+
* - in: path
|
| 642 |
+
* name: companyId
|
| 643 |
+
* required: true
|
| 644 |
+
* schema:
|
| 645 |
+
* type: string
|
| 646 |
+
* description: The ID of the company to add a location for
|
| 647 |
+
* - in: path
|
| 648 |
+
* name: locationId
|
| 649 |
+
* required: true
|
| 650 |
+
* schema:
|
| 651 |
+
* type: string
|
| 652 |
+
* description: The ID of the location to be updated
|
| 653 |
+
* requestBody:
|
| 654 |
+
* required: true
|
| 655 |
+
* content:
|
| 656 |
+
* application/json:
|
| 657 |
+
* schema:
|
| 658 |
+
* $ref: '#/components/schemas/CreateUpdateLocation'
|
| 659 |
+
* responses:
|
| 660 |
+
* 200:
|
| 661 |
+
* description: Location updated successfully
|
| 662 |
+
* content:
|
| 663 |
+
* application/json:
|
| 664 |
+
* schema:
|
| 665 |
+
* type: object
|
| 666 |
+
* properties:
|
| 667 |
+
* message:
|
| 668 |
+
* type: string
|
| 669 |
+
* id:
|
| 670 |
+
* type: string
|
| 671 |
+
* description: Location id
|
| 672 |
+
* 400:
|
| 673 |
+
* description: Invalid input
|
| 674 |
+
* content:
|
| 675 |
+
* application/json:
|
| 676 |
+
* schema:
|
| 677 |
+
* $ref: '#/components/schemas/ErrorResponse'
|
| 678 |
+
*/
|
| 679 |
+
app.post("/company/:companyId/locations", async (req, res, next) => {
|
| 680 |
+
try {
|
| 681 |
+
const { companyId } = req.params;
|
| 682 |
+
const { code,
|
| 683 |
+
name,
|
| 684 |
+
gst: {
|
| 685 |
+
legal_name,
|
| 686 |
+
value
|
| 687 |
+
},
|
| 688 |
+
manager: {
|
| 689 |
+
manager_name, email, number, country_code
|
| 690 |
+
},
|
| 691 |
+
address: {
|
| 692 |
+
address1,
|
| 693 |
+
address2,
|
| 694 |
+
country,
|
| 695 |
+
pincode,
|
| 696 |
+
city,
|
| 697 |
+
state,
|
| 698 |
+
latitude = 19.2762702,
|
| 699 |
+
longitude = 72.8929,
|
| 700 |
+
landmark = ""
|
| 701 |
+
},
|
| 702 |
+
|
| 703 |
+
} = req.body
|
| 704 |
+
const client = await initClient(companyId);
|
| 705 |
+
let locations = await client.companyProfile.createLocation({
|
| 706 |
+
body: {
|
| 707 |
+
name,
|
| 708 |
+
display_name: name,
|
| 709 |
+
code,
|
| 710 |
+
company: parseInt(companyId),
|
| 711 |
+
documents: [{
|
| 712 |
+
type: "gst",
|
| 713 |
+
legal_name: legal_name,
|
| 714 |
+
value: value, verified: true
|
| 715 |
+
}],
|
| 716 |
+
address: {
|
| 717 |
+
"address1": address1,
|
| 718 |
+
"address2": address2,
|
| 719 |
+
"country": country,
|
| 720 |
+
"pincode": pincode,
|
| 721 |
+
"city": city,
|
| 722 |
+
"state": state,
|
| 723 |
+
"latitude": latitude,
|
| 724 |
+
"longitude": longitude,
|
| 725 |
+
"landmark": landmark
|
| 726 |
+
},
|
| 727 |
+
manager: {
|
| 728 |
+
"name": manager_name,
|
| 729 |
+
"email": email,
|
| 730 |
+
"mobile_no": {
|
| 731 |
+
"number": number,
|
| 732 |
+
"country_code": country_code
|
| 733 |
+
}
|
| 734 |
+
},
|
| 735 |
+
contact_numbers: [
|
| 736 |
+
{
|
| 737 |
+
"number": number,
|
| 738 |
+
"country_code": country_code
|
| 739 |
+
}
|
| 740 |
+
],
|
| 741 |
+
store_type: "high_street"
|
| 742 |
+
|
| 743 |
+
}
|
| 744 |
+
});
|
| 745 |
+
|
| 746 |
+
res.json({ message: "location added", id: locations?.id })
|
| 747 |
+
} catch (e) {
|
| 748 |
+
next(e)
|
| 749 |
+
}
|
| 750 |
+
})
|
| 751 |
+
app.put("/company/:companyId/locations/locationId", async (req, res, next) => {
|
| 752 |
+
try {
|
| 753 |
+
const { companyId } = req.params;
|
| 754 |
+
const { code,
|
| 755 |
+
name,
|
| 756 |
+
gst: {
|
| 757 |
+
legal_name,
|
| 758 |
+
value
|
| 759 |
+
},
|
| 760 |
+
manager: {
|
| 761 |
+
manager_name, email, number, country_code
|
| 762 |
+
},
|
| 763 |
+
address: {
|
| 764 |
+
address1,
|
| 765 |
+
address2,
|
| 766 |
+
country,
|
| 767 |
+
pincode,
|
| 768 |
+
city,
|
| 769 |
+
state,
|
| 770 |
+
latitude = 19.2762702,
|
| 771 |
+
longitude = 72.8929,
|
| 772 |
+
landmark = ""
|
| 773 |
+
},
|
| 774 |
+
|
| 775 |
+
} = req.body
|
| 776 |
+
const client = await initClient(companyId);
|
| 777 |
+
let locations = await client.companyProfile.createLocation({
|
| 778 |
+
body: {
|
| 779 |
+
name,
|
| 780 |
+
display_name: name,
|
| 781 |
+
code,
|
| 782 |
+
company: parseInt(companyId),
|
| 783 |
+
documents: [{
|
| 784 |
+
type: "gst",
|
| 785 |
+
legal_name: legal_name,
|
| 786 |
+
value: value, verified: true
|
| 787 |
+
}],
|
| 788 |
+
address: {
|
| 789 |
+
"address1": address1,
|
| 790 |
+
"address2": address2,
|
| 791 |
+
"country": country,
|
| 792 |
+
"pincode": pincode,
|
| 793 |
+
"city": city,
|
| 794 |
+
"state": state,
|
| 795 |
+
"latitude": latitude,
|
| 796 |
+
"longitude": longitude,
|
| 797 |
+
"landmark": landmark
|
| 798 |
+
},
|
| 799 |
+
manager: {
|
| 800 |
+
"name": manager_name,
|
| 801 |
+
"email": email,
|
| 802 |
+
"mobile_no": {
|
| 803 |
+
"number": number,
|
| 804 |
+
"country_code": country_code
|
| 805 |
+
}
|
| 806 |
+
},
|
| 807 |
+
contact_numbers: [
|
| 808 |
+
{
|
| 809 |
+
"number": number,
|
| 810 |
+
"country_code": country_code
|
| 811 |
+
}
|
| 812 |
+
],
|
| 813 |
+
store_type: "high_street"
|
| 814 |
+
|
| 815 |
+
}
|
| 816 |
+
});
|
| 817 |
+
|
| 818 |
+
res.json({ message: "location updated", id: locations?.id })
|
| 819 |
+
} catch (e) {
|
| 820 |
+
next(e)
|
| 821 |
+
}
|
| 822 |
+
})
|
| 823 |
+
|
| 824 |
+
|
| 825 |
+
|
| 826 |
+
/**
|
| 827 |
+
* @swagger
|
| 828 |
+
* /company/{companyId}/products:
|
| 829 |
+
* post:
|
| 830 |
+
* summary: Creates a new product for a given company.
|
| 831 |
+
* description: This endpoint creates a new product with various attributes including name, slug, pricing, and more.
|
| 832 |
+
* operationId: createProduct
|
| 833 |
+
* tags:
|
| 834 |
+
* - Products
|
| 835 |
+
* parameters:
|
| 836 |
+
* - in: path
|
| 837 |
+
* name: companyId
|
| 838 |
+
* required: true
|
| 839 |
+
* schema:
|
| 840 |
+
* type: string
|
| 841 |
+
* description: Unique identifier of the company.
|
| 842 |
+
* requestBody:
|
| 843 |
+
* required: true
|
| 844 |
+
* content:
|
| 845 |
+
* application/json:
|
| 846 |
+
* schema:
|
| 847 |
+
* type: object
|
| 848 |
+
* required:
|
| 849 |
+
* - name
|
| 850 |
+
* - slug
|
| 851 |
+
* - seller_identifier
|
| 852 |
+
* - brand_id
|
| 853 |
+
* properties:
|
| 854 |
+
* name:
|
| 855 |
+
* type: string
|
| 856 |
+
* description: Name of the product.
|
| 857 |
+
* slug:
|
| 858 |
+
* type: string
|
| 859 |
+
* description: URL-friendly identifier for the product.
|
| 860 |
+
* seller_identifier:
|
| 861 |
+
* type: string
|
| 862 |
+
* description: Unique identifier for the seller.
|
| 863 |
+
* brand_id:
|
| 864 |
+
* type: string
|
| 865 |
+
* description: Unique identifier for the brand.
|
| 866 |
+
* location_id:
|
| 867 |
+
* type: string
|
| 868 |
+
* description: Location identifier for the product.
|
| 869 |
+
* mrp:
|
| 870 |
+
* type: number
|
| 871 |
+
* default: 999
|
| 872 |
+
* description: Maximum retail price of the product.
|
| 873 |
+
* selling_price:
|
| 874 |
+
* type: number
|
| 875 |
+
* default: 499
|
| 876 |
+
* description: Selling price of the product.
|
| 877 |
+
* responses:
|
| 878 |
+
* 200:
|
| 879 |
+
* description: Successful creation of the product.
|
| 880 |
+
* content:
|
| 881 |
+
* application/json:
|
| 882 |
+
* schema:
|
| 883 |
+
* type: object
|
| 884 |
+
* properties:
|
| 885 |
+
* message:
|
| 886 |
+
* type: string
|
| 887 |
+
* id:
|
| 888 |
+
* type: string
|
| 889 |
+
* seller_identifier:
|
| 890 |
+
* type: string
|
| 891 |
+
*/
|
| 892 |
+
|
| 893 |
+
app.post("/company/:companyId/products", async (req, res, next) => {
|
| 894 |
+
try {
|
| 895 |
+
const { companyId } = req.params;
|
| 896 |
+
const { name,
|
| 897 |
+
slug,
|
| 898 |
+
seller_identifier,
|
| 899 |
+
brand_id, location_id, mrp = 999, selling_price = 499
|
| 900 |
+
} = req.body;
|
| 901 |
+
const obj = {
|
| 902 |
+
"name": name,
|
| 903 |
+
"slug": slug,
|
| 904 |
+
"brand_uid": brand_id,
|
| 905 |
+
"item_code": seller_identifier,
|
| 906 |
+
"teaser_tag": {},
|
| 907 |
+
"net_quantity": {},
|
| 908 |
+
"tax_identifier": {
|
| 909 |
+
"reporting_hsn": "1202355241H1",
|
| 910 |
+
"hsn_code": "1202355241",
|
| 911 |
+
"hsn_code_id": "65769883ba99dcf407a2b1ed"
|
| 912 |
+
},
|
| 913 |
+
"country_of_origin": "India",
|
| 914 |
+
"variants": {},
|
| 915 |
+
"variant_media": {},
|
| 916 |
+
"description": "PHA+WW91ciBwcm9kdWN0IGRlc2NyaXB0aW9uPC9wPg==",
|
| 917 |
+
"short_description": "Your product description",
|
| 918 |
+
"highlights": [],
|
| 919 |
+
"company_id": 10,
|
| 920 |
+
"template_tag": "c2-0-template",
|
| 921 |
+
"currency": "INR",
|
| 922 |
+
"media": [],
|
| 923 |
+
"is_set": false,
|
| 924 |
+
"sizes": [
|
| 925 |
+
{
|
| 926 |
+
"size": "OS",
|
| 927 |
+
"price": mrp,
|
| 928 |
+
"price_effective": selling_price,
|
| 929 |
+
"price_transfer": 0,
|
| 930 |
+
"currency": "INR",
|
| 931 |
+
"item_length": 1,
|
| 932 |
+
"item_width": 1,
|
| 933 |
+
"item_height": 1,
|
| 934 |
+
"item_weight": 1,
|
| 935 |
+
"item_dimensions_unit_of_measure": "cm",
|
| 936 |
+
"item_weight_unit_of_measure": "gram",
|
| 937 |
+
"track_inventory": true,
|
| 938 |
+
"identifiers": [
|
| 939 |
+
{
|
| 940 |
+
"gtin_value": seller_identifier,
|
| 941 |
+
"gtin_type": "ean",
|
| 942 |
+
"primary": true
|
| 943 |
+
}
|
| 944 |
+
],
|
| 945 |
+
"_custom_json": {},
|
| 946 |
+
"name": "OS"
|
| 947 |
+
}
|
| 948 |
+
],
|
| 949 |
+
"_custom_json": {},
|
| 950 |
+
"size_guide": "",
|
| 951 |
+
"product_group_tag": [],
|
| 952 |
+
"product_publish": {
|
| 953 |
+
"product_online_date": "2023-12-11T08:38:10.082Z",
|
| 954 |
+
"is_set": false
|
| 955 |
+
},
|
| 956 |
+
"is_active": true,
|
| 957 |
+
"custom_order": {
|
| 958 |
+
"is_custom_order": false,
|
| 959 |
+
"manufacturing_time": 0,
|
| 960 |
+
"manufacturing_time_unit": "hours"
|
| 961 |
+
},
|
| 962 |
+
"multi_size": false,
|
| 963 |
+
"no_of_boxes": 1,
|
| 964 |
+
"is_dependent": false,
|
| 965 |
+
"item_type": "digital",
|
| 966 |
+
"tags": [],
|
| 967 |
+
"departments": [
|
| 968 |
+
19771
|
| 969 |
+
],
|
| 970 |
+
return_config: {
|
| 971 |
+
"returnable": false
|
| 972 |
+
},
|
| 973 |
+
"category_slug": "c2-0-cat",
|
| 974 |
+
"trader": [
|
| 975 |
+
{
|
| 976 |
+
"type": "Manufacturer",
|
| 977 |
+
"name": "Manufacturer",
|
| 978 |
+
"address": [
|
| 979 |
+
"Manufacturer Address"
|
| 980 |
+
]
|
| 981 |
+
}
|
| 982 |
+
],
|
| 983 |
+
"return_config": {
|
| 984 |
+
"returnable": true,
|
| 985 |
+
time: 3,
|
| 986 |
+
unit: "days"
|
| 987 |
+
}
|
| 988 |
+
}
|
| 989 |
+
const client = await initClient(companyId);
|
| 990 |
+
let product = await client.catalog.createProduct({
|
| 991 |
+
body: obj
|
| 992 |
+
});
|
| 993 |
+
product = await client.catalog.getProduct({
|
| 994 |
+
itemId: product.uid
|
| 995 |
+
});
|
| 996 |
+
res.json({
|
| 997 |
+
message: "product created",
|
| 998 |
+
id: product.data.uid,
|
| 999 |
+
seller_identifier: product?.data?.sizes?.[0]?.seller_identifier
|
| 1000 |
+
});
|
| 1001 |
+
} catch (e) { next(e) }
|
| 1002 |
+
})
|
| 1003 |
+
|
| 1004 |
+
/**
|
| 1005 |
+
* @swagger
|
| 1006 |
+
* /company/{companyId}/products/{productId}/inventory:
|
| 1007 |
+
* post:
|
| 1008 |
+
* summary: Updates inventory for a specific product.
|
| 1009 |
+
* description: This endpoint updates the inventory details for a given product, including location, pricing, and quantity.
|
| 1010 |
+
* operationId: updateInventory
|
| 1011 |
+
* tags:
|
| 1012 |
+
* - Inventory
|
| 1013 |
+
* parameters:
|
| 1014 |
+
* - in: path
|
| 1015 |
+
* name: companyId
|
| 1016 |
+
* required: true
|
| 1017 |
+
* schema:
|
| 1018 |
+
* type: string
|
| 1019 |
+
* description: Unique identifier of the company.
|
| 1020 |
+
* - in: path
|
| 1021 |
+
* name: productId
|
| 1022 |
+
* required: true
|
| 1023 |
+
* schema:
|
| 1024 |
+
* type: string
|
| 1025 |
+
* description: Unique identifier of the product.
|
| 1026 |
+
* requestBody:
|
| 1027 |
+
* required: true
|
| 1028 |
+
* content:
|
| 1029 |
+
* application/json:
|
| 1030 |
+
* schema:
|
| 1031 |
+
* type: object
|
| 1032 |
+
* required:
|
| 1033 |
+
* - location_id
|
| 1034 |
+
* - seller_identifier
|
| 1035 |
+
* properties:
|
| 1036 |
+
* location_id:
|
| 1037 |
+
* type: string
|
| 1038 |
+
* description: Location identifier where the inventory is stored.
|
| 1039 |
+
* mrp:
|
| 1040 |
+
* type: number
|
| 1041 |
+
* default: 999
|
| 1042 |
+
* description: Maximum retail price of the product.
|
| 1043 |
+
* selling_price:
|
| 1044 |
+
* type: number
|
| 1045 |
+
* default: 499
|
| 1046 |
+
* description: Selling price of the product.
|
| 1047 |
+
* seller_identifier:
|
| 1048 |
+
* type: string
|
| 1049 |
+
* description: Unique identifier for the seller.
|
| 1050 |
+
* responses:
|
| 1051 |
+
* 200:
|
| 1052 |
+
* description: Successful update of inventory.
|
| 1053 |
+
* content:
|
| 1054 |
+
* application/json:
|
| 1055 |
+
* schema:
|
| 1056 |
+
* type: object
|
| 1057 |
+
* properties:
|
| 1058 |
+
* message:
|
| 1059 |
+
* type: string
|
| 1060 |
+
*/
|
| 1061 |
+
app.post("/company/:companyId/products/:productId/inventory", async (req, res, next) => {
|
| 1062 |
+
try {
|
| 1063 |
+
const { companyId, productId } = req.params;
|
| 1064 |
+
const { location_id, mrp = 999, selling_price = 499, id, seller_identifier } = req.body;
|
| 1065 |
+
const client = await initClient(companyId);
|
| 1066 |
+
let product = await client.catalog.getProduct({
|
| 1067 |
+
itemId: productId
|
| 1068 |
+
});
|
| 1069 |
+
let inv = await client.catalog.updateRealtimeInventory({
|
| 1070 |
+
itemId: product.data.uid,
|
| 1071 |
+
sellerIdentifier: seller_identifier,
|
| 1072 |
+
body: {
|
| 1073 |
+
company_id: companyId,
|
| 1074 |
+
payload: [{
|
| 1075 |
+
"seller_identifier": seller_identifier,
|
| 1076 |
+
"store_id": location_id,
|
| 1077 |
+
"price_marked": mrp,
|
| 1078 |
+
"price_effective": selling_price,
|
| 1079 |
+
"total_quantity": 10,
|
| 1080 |
+
"tags": []
|
| 1081 |
+
}]
|
| 1082 |
+
}
|
| 1083 |
+
})
|
| 1084 |
+
|
| 1085 |
+
res.json({ message: "inv created" });
|
| 1086 |
+
} catch (e) { next(e) }
|
| 1087 |
+
})
|
| 1088 |
+
|
| 1089 |
+
|
| 1090 |
+
/**
|
| 1091 |
+
* @swagger
|
| 1092 |
+
* /company/{companyId}/sales_channel:
|
| 1093 |
+
* post:
|
| 1094 |
+
* operationId: addSalesChannel
|
| 1095 |
+
* summary: Create a sales channel for a given company
|
| 1096 |
+
* description: This endpoint creates a new sales channel for the specified company.
|
| 1097 |
+
* tags:
|
| 1098 |
+
* - Sales Channel
|
| 1099 |
+
* parameters:
|
| 1100 |
+
* - in: path
|
| 1101 |
+
* name: companyId
|
| 1102 |
+
* required: true
|
| 1103 |
+
* schema:
|
| 1104 |
+
* type: string
|
| 1105 |
+
* description: The ID of the company
|
| 1106 |
+
* requestBody:
|
| 1107 |
+
* required: true
|
| 1108 |
+
* content:
|
| 1109 |
+
* application/json:
|
| 1110 |
+
* schema:
|
| 1111 |
+
* type: object
|
| 1112 |
+
* properties:
|
| 1113 |
+
* brand_ids:
|
| 1114 |
+
* type: array
|
| 1115 |
+
* items:
|
| 1116 |
+
* type: integer
|
| 1117 |
+
* description: Array of brand IDs to be associated with the sales channel
|
| 1118 |
+
* name:
|
| 1119 |
+
* type: string
|
| 1120 |
+
* description: Name of the sales channel
|
| 1121 |
+
* subdomain:
|
| 1122 |
+
* type: string
|
| 1123 |
+
* description: subdomain associated with the sales channel
|
| 1124 |
+
* responses:
|
| 1125 |
+
* 200:
|
| 1126 |
+
* description: Sales channel successfully created
|
| 1127 |
+
* content:
|
| 1128 |
+
* application/json:
|
| 1129 |
+
* schema:
|
| 1130 |
+
* type: object
|
| 1131 |
+
* properties:
|
| 1132 |
+
* message:
|
| 1133 |
+
* type: string
|
| 1134 |
+
* app:
|
| 1135 |
+
* type: object
|
| 1136 |
+
* description: Details of the created sales channel
|
| 1137 |
+
* 400:
|
| 1138 |
+
* description: Bad request
|
| 1139 |
+
* 500:
|
| 1140 |
+
* description: Internal server error
|
| 1141 |
+
*/
|
| 1142 |
+
|
| 1143 |
+
app.post("/company/:companyId/sales_channel", async (req, res, next) => {
|
| 1144 |
+
try {
|
| 1145 |
+
const { companyId } = req.params;
|
| 1146 |
+
const { brand_ids, name, subdomain } = req.body;
|
| 1147 |
+
const client = await initClient(companyId);
|
| 1148 |
+
|
| 1149 |
+
let app = await client.configuration.createApplication({
|
| 1150 |
+
body: {
|
| 1151 |
+
"app": {
|
| 1152 |
+
"company_id": (1).toString(),
|
| 1153 |
+
"channel_type": "website-and-mobile-apps",
|
| 1154 |
+
"auth": {
|
| 1155 |
+
"enabled": true
|
| 1156 |
+
},
|
| 1157 |
+
"name": name,
|
| 1158 |
+
"desc": "",
|
| 1159 |
+
"mode": "live"
|
| 1160 |
+
},
|
| 1161 |
+
"configuration": {
|
| 1162 |
+
"inventory": {
|
| 1163 |
+
"brand": {
|
| 1164 |
+
"criteria": "all",
|
| 1165 |
+
"brands": []
|
| 1166 |
+
},
|
| 1167 |
+
"store": {
|
| 1168 |
+
"criteria": "filter",
|
| 1169 |
+
"rules": [
|
| 1170 |
+
{
|
| 1171 |
+
"companies": [companyId],
|
| 1172 |
+
"brands": brand_ids
|
| 1173 |
+
}
|
| 1174 |
+
],
|
| 1175 |
+
"stores": []
|
| 1176 |
+
},
|
| 1177 |
+
"image": ["standard", "substandard", "default"],
|
| 1178 |
+
"franchise_enabled": false,
|
| 1179 |
+
"out_of_stock": true
|
| 1180 |
+
},
|
| 1181 |
+
"payment": {
|
| 1182 |
+
"mode_of_payment": "ECOMM",
|
| 1183 |
+
"source": "ECOMM"
|
| 1184 |
+
},
|
| 1185 |
+
"article_assignment": {
|
| 1186 |
+
"post_order_reassignment": true,
|
| 1187 |
+
"enforced_stores": [],
|
| 1188 |
+
"rules": {
|
| 1189 |
+
"store_priority": {
|
| 1190 |
+
"enabled": false,
|
| 1191 |
+
"storetype_order": []
|
| 1192 |
+
}
|
| 1193 |
+
}
|
| 1194 |
+
}
|
| 1195 |
+
},
|
| 1196 |
+
"domain": {
|
| 1197 |
+
"name": `${subdomain}.hostx5.de`
|
| 1198 |
+
}
|
| 1199 |
+
}
|
| 1200 |
+
})
|
| 1201 |
+
|
| 1202 |
+
res.json({ message: "inv created", app });
|
| 1203 |
+
} catch (e) { next(e) }
|
| 1204 |
+
})
|
| 1205 |
+
|
| 1206 |
+
const chatHtml = fs.readFileSync('./chat.html', 'utf-8');
|
| 1207 |
+
|
| 1208 |
+
app.get('/', async (req, res, next) => {
|
| 1209 |
+
try {
|
| 1210 |
+
res.send(chatHtml);
|
| 1211 |
+
} catch (error) {
|
| 1212 |
+
console.error(error);
|
| 1213 |
+
res.send('Something needs to be fixed!');
|
| 1214 |
+
}
|
| 1215 |
+
});
|
| 1216 |
+
|
| 1217 |
+
app.get('/talk', async (req, res, next) => {
|
| 1218 |
+
try {
|
| 1219 |
+
res.send(chatHtml);
|
| 1220 |
+
} catch (error) {
|
| 1221 |
+
console.error(error);
|
| 1222 |
+
res.send('Something needs to be fixed!');
|
| 1223 |
+
}
|
| 1224 |
+
});
|
| 1225 |
+
|
| 1226 |
+
app.post(
|
| 1227 |
+
'/openai',
|
| 1228 |
+
async (req, res, next) => {
|
| 1229 |
+
const functions = [
|
| 1230 |
+
{
|
| 1231 |
+
"type": "function",
|
| 1232 |
+
"function": {
|
| 1233 |
+
"name": "getCompanyCreds",
|
| 1234 |
+
"description": "Retrieves credentials for a specific company based on its ID.",
|
| 1235 |
+
"parameters": {
|
| 1236 |
+
"type": "object",
|
| 1237 |
+
"properties": {
|
| 1238 |
+
"company_id": {
|
| 1239 |
+
"type": "number",
|
| 1240 |
+
"description": "Unique identifier of the company."
|
| 1241 |
+
}
|
| 1242 |
+
},
|
| 1243 |
+
"required": ["company_id"]
|
| 1244 |
+
}
|
| 1245 |
+
}
|
| 1246 |
+
},
|
| 1247 |
+
{
|
| 1248 |
+
"type": "function",
|
| 1249 |
+
"function": {
|
| 1250 |
+
"name": "createUpdateCompanyCreds",
|
| 1251 |
+
"description": "Creates or updates credentials for a company.",
|
| 1252 |
+
"parameters": {
|
| 1253 |
+
"type": "object",
|
| 1254 |
+
"properties": {
|
| 1255 |
+
"company_id": {
|
| 1256 |
+
"type": "number",
|
| 1257 |
+
"description": "Unique identifier of the company."
|
| 1258 |
+
},
|
| 1259 |
+
"clientId": {
|
| 1260 |
+
"type": "string",
|
| 1261 |
+
"description": "Client ID for authentication."
|
| 1262 |
+
},
|
| 1263 |
+
"clientSecret": {
|
| 1264 |
+
"type": "string",
|
| 1265 |
+
"description": "Client secret for authentication."
|
| 1266 |
+
}
|
| 1267 |
+
},
|
| 1268 |
+
"required": ["company_id", "clientId", "clientSecret"]
|
| 1269 |
+
}
|
| 1270 |
+
}
|
| 1271 |
+
},
|
| 1272 |
+
{
|
| 1273 |
+
"type": "function",
|
| 1274 |
+
"function": {
|
| 1275 |
+
"name": "getApplications",
|
| 1276 |
+
"description": "Retrieves a list of applications associated with a specific company ID.",
|
| 1277 |
+
"parameters": {
|
| 1278 |
+
"type": "object",
|
| 1279 |
+
"properties": {
|
| 1280 |
+
"company_id": {
|
| 1281 |
+
"type": "number",
|
| 1282 |
+
"description": "Unique identifier of the company."
|
| 1283 |
+
}
|
| 1284 |
+
},
|
| 1285 |
+
"required": ["company_id"]
|
| 1286 |
+
}
|
| 1287 |
+
}
|
| 1288 |
+
},
|
| 1289 |
+
{
|
| 1290 |
+
"type": "function",
|
| 1291 |
+
"function": {
|
| 1292 |
+
"name": "createBrand",
|
| 1293 |
+
"description": "Creates a new brand under a specific company.",
|
| 1294 |
+
"parameters": {
|
| 1295 |
+
"type": "object",
|
| 1296 |
+
"properties": {
|
| 1297 |
+
"company_id": {
|
| 1298 |
+
"type": "number",
|
| 1299 |
+
"description": "Unique identifier of the company."
|
| 1300 |
+
},
|
| 1301 |
+
"name": {
|
| 1302 |
+
"type": "string",
|
| 1303 |
+
"description": "Name of the new brand."
|
| 1304 |
+
},
|
| 1305 |
+
"description": {
|
| 1306 |
+
"type": "string",
|
| 1307 |
+
"description": "Description of the new brand."
|
| 1308 |
+
},
|
| 1309 |
+
"logo": {
|
| 1310 |
+
"type": "string",
|
| 1311 |
+
"description": "URL of the brand's logo."
|
| 1312 |
+
}
|
| 1313 |
+
},
|
| 1314 |
+
"required": ["company_id", "name", "description"]
|
| 1315 |
+
}
|
| 1316 |
+
}
|
| 1317 |
+
},
|
| 1318 |
+
{
|
| 1319 |
+
"type": "function",
|
| 1320 |
+
"function": {
|
| 1321 |
+
"name": "updateBrand",
|
| 1322 |
+
"description": "Updates the details of an existing brand within a company.",
|
| 1323 |
+
"parameters": {
|
| 1324 |
+
"type": "object",
|
| 1325 |
+
"properties": {
|
| 1326 |
+
"company_id": {
|
| 1327 |
+
"type": "number",
|
| 1328 |
+
"description": "Unique identifier of the company."
|
| 1329 |
+
},
|
| 1330 |
+
"brand_id": {
|
| 1331 |
+
"type": "string",
|
| 1332 |
+
"description": "Unique identifier of the brand to be updated."
|
| 1333 |
+
},
|
| 1334 |
+
"name": {
|
| 1335 |
+
"type": "string",
|
| 1336 |
+
"description": "New name for the brand."
|
| 1337 |
+
},
|
| 1338 |
+
"description": {
|
| 1339 |
+
"type": "string",
|
| 1340 |
+
"description": "New description for the brand."
|
| 1341 |
+
},
|
| 1342 |
+
"logo": {
|
| 1343 |
+
"type": "string",
|
| 1344 |
+
"description": "New URL for the brand's logo."
|
| 1345 |
+
},
|
| 1346 |
+
},
|
| 1347 |
+
"required": ["company_id", "brand_id", "name", "description"]
|
| 1348 |
+
}
|
| 1349 |
+
}
|
| 1350 |
+
},
|
| 1351 |
+
{
|
| 1352 |
+
"type": "function",
|
| 1353 |
+
"function": {
|
| 1354 |
+
"name": "getBrands",
|
| 1355 |
+
"description": "Retrieves a list of all brands associated with a specific company.",
|
| 1356 |
+
"parameters": {
|
| 1357 |
+
"type": "object",
|
| 1358 |
+
"properties": {
|
| 1359 |
+
"company_id": {
|
| 1360 |
+
"type": "number",
|
| 1361 |
+
"description": "Unique identifier of the company for which brands are being retrieved."
|
| 1362 |
+
}
|
| 1363 |
+
},
|
| 1364 |
+
"required": ["company_id"]
|
| 1365 |
+
}
|
| 1366 |
+
}
|
| 1367 |
+
},
|
| 1368 |
+
{
|
| 1369 |
+
"type": "function",
|
| 1370 |
+
"function": {
|
| 1371 |
+
"name": "getLocations",
|
| 1372 |
+
"description": "Retrieves a list of all locations associated with a specific company.",
|
| 1373 |
+
"parameters": {
|
| 1374 |
+
"type": "object",
|
| 1375 |
+
"properties": {
|
| 1376 |
+
"company_id": {
|
| 1377 |
+
"type": "number",
|
| 1378 |
+
"description": "Unique identifier of the company for which locations are being retrieved."
|
| 1379 |
+
}
|
| 1380 |
+
},
|
| 1381 |
+
"required": ["company_id"]
|
| 1382 |
+
}
|
| 1383 |
+
}
|
| 1384 |
+
},
|
| 1385 |
+
{
|
| 1386 |
+
"type": "function",
|
| 1387 |
+
"function": {
|
| 1388 |
+
"name": "createLocation",
|
| 1389 |
+
"description": "Creates a new location for a specified company.",
|
| 1390 |
+
"parameters": {
|
| 1391 |
+
"type": "object",
|
| 1392 |
+
"properties": {
|
| 1393 |
+
"company_id": {
|
| 1394 |
+
"type": "number",
|
| 1395 |
+
"description": "Unique identifier of the company."
|
| 1396 |
+
},
|
| 1397 |
+
"address1": {
|
| 1398 |
+
"type": "string",
|
| 1399 |
+
"description": "Primary address line of the new location."
|
| 1400 |
+
},
|
| 1401 |
+
"address2": {
|
| 1402 |
+
"type": "string",
|
| 1403 |
+
"description": "Secondary address line of the new location."
|
| 1404 |
+
},
|
| 1405 |
+
"pincode": {
|
| 1406 |
+
"type": "string",
|
| 1407 |
+
"description": "Postal code of the new location."
|
| 1408 |
+
},
|
| 1409 |
+
"state": {
|
| 1410 |
+
"type": "string",
|
| 1411 |
+
"description": "State where the new location is situated."
|
| 1412 |
+
},
|
| 1413 |
+
"city": {
|
| 1414 |
+
"type": "string",
|
| 1415 |
+
"description": "City where the new location is situated."
|
| 1416 |
+
},
|
| 1417 |
+
"number": {
|
| 1418 |
+
"type": "string",
|
| 1419 |
+
"description": "Contact number for the new location."
|
| 1420 |
+
},
|
| 1421 |
+
"country_code": {
|
| 1422 |
+
"type": "string",
|
| 1423 |
+
"description": "Country code for the contact number."
|
| 1424 |
+
},
|
| 1425 |
+
"gst_name": {
|
| 1426 |
+
"type": "string",
|
| 1427 |
+
"description": "GST registered name associated with the new location."
|
| 1428 |
+
},
|
| 1429 |
+
"gst_no": {
|
| 1430 |
+
"type": "string",
|
| 1431 |
+
"description": "GST number associated with the new location."
|
| 1432 |
+
},
|
| 1433 |
+
"latitude": {
|
| 1434 |
+
"type": "number",
|
| 1435 |
+
"description": "Latitude coordinate for the new location."
|
| 1436 |
+
},
|
| 1437 |
+
"longitude": {
|
| 1438 |
+
"type": "number",
|
| 1439 |
+
"description": "Longitude coordinate for the new location."
|
| 1440 |
+
}
|
| 1441 |
+
},
|
| 1442 |
+
"required": ["company_id", "address1", "city", "state", "pincode", "country_code", "gst_name", "gst_no"]
|
| 1443 |
+
}
|
| 1444 |
+
}
|
| 1445 |
+
},
|
| 1446 |
+
{
|
| 1447 |
+
"type": "function",
|
| 1448 |
+
"function": {
|
| 1449 |
+
"name": "updateLocation",
|
| 1450 |
+
"description": "update a existing location for a specified company.",
|
| 1451 |
+
"parameters": {
|
| 1452 |
+
"type": "object",
|
| 1453 |
+
"properties": {
|
| 1454 |
+
"company_id": {
|
| 1455 |
+
"type": "number",
|
| 1456 |
+
"description": "Unique identifier of the company."
|
| 1457 |
+
},
|
| 1458 |
+
"location_id": {
|
| 1459 |
+
"type": "number",
|
| 1460 |
+
"description": "Unique identifier of the location."
|
| 1461 |
+
},
|
| 1462 |
+
"address1": {
|
| 1463 |
+
"type": "string",
|
| 1464 |
+
"description": "Primary address line of the new location."
|
| 1465 |
+
},
|
| 1466 |
+
"address2": {
|
| 1467 |
+
"type": "string",
|
| 1468 |
+
"description": "Secondary address line of the new location."
|
| 1469 |
+
},
|
| 1470 |
+
"pincode": {
|
| 1471 |
+
"type": "string",
|
| 1472 |
+
"description": "Postal code of the new location."
|
| 1473 |
+
},
|
| 1474 |
+
"state": {
|
| 1475 |
+
"type": "string",
|
| 1476 |
+
"description": "State where the new location is situated."
|
| 1477 |
+
},
|
| 1478 |
+
"city": {
|
| 1479 |
+
"type": "string",
|
| 1480 |
+
"description": "City where the new location is situated."
|
| 1481 |
+
},
|
| 1482 |
+
"number": {
|
| 1483 |
+
"type": "string",
|
| 1484 |
+
"description": "Contact number for the new location."
|
| 1485 |
+
},
|
| 1486 |
+
"country_code": {
|
| 1487 |
+
"type": "string",
|
| 1488 |
+
"description": "Country code for the contact number."
|
| 1489 |
+
},
|
| 1490 |
+
"gst_name": {
|
| 1491 |
+
"type": "string",
|
| 1492 |
+
"description": "GST registered name associated with the new location."
|
| 1493 |
+
},
|
| 1494 |
+
"gst_no": {
|
| 1495 |
+
"type": "string",
|
| 1496 |
+
"description": "GST number associated with the new location."
|
| 1497 |
+
},
|
| 1498 |
+
"latitude": {
|
| 1499 |
+
"type": "number",
|
| 1500 |
+
"description": "Latitude coordinate for the new location."
|
| 1501 |
+
},
|
| 1502 |
+
"longitude": {
|
| 1503 |
+
"type": "number",
|
| 1504 |
+
"description": "Longitude coordinate for the new location."
|
| 1505 |
+
}
|
| 1506 |
+
},
|
| 1507 |
+
"required": ["company_id", 'brand_id', "address1", "city", "state", "pincode", "country_code", "gst_name", "gst_no"]
|
| 1508 |
+
}
|
| 1509 |
+
}
|
| 1510 |
+
},
|
| 1511 |
+
{
|
| 1512 |
+
"type": "function",
|
| 1513 |
+
"function": {
|
| 1514 |
+
"name": "createProduct",
|
| 1515 |
+
"description": "Creates a new product in the company's catalog.",
|
| 1516 |
+
"parameters": {
|
| 1517 |
+
"type": "object",
|
| 1518 |
+
"properties": {
|
| 1519 |
+
"name": {
|
| 1520 |
+
"type": "string",
|
| 1521 |
+
"description": "Name of the new product."
|
| 1522 |
+
},
|
| 1523 |
+
"company_id": {
|
| 1524 |
+
"type": "number",
|
| 1525 |
+
"description": "Unique identifier of the company."
|
| 1526 |
+
},
|
| 1527 |
+
"slug": {
|
| 1528 |
+
"type": "string",
|
| 1529 |
+
"description": "SEO-friendly URL segment for the product."
|
| 1530 |
+
},
|
| 1531 |
+
"seller_identifier": {
|
| 1532 |
+
"type": "string",
|
| 1533 |
+
"description": "Unique identifier for the seller of the product."
|
| 1534 |
+
},
|
| 1535 |
+
"brand_id": {
|
| 1536 |
+
"type": "number",
|
| 1537 |
+
"description": "Unique identifier of the brand associated with the product."
|
| 1538 |
+
},
|
| 1539 |
+
"mrp": {
|
| 1540 |
+
"type": "number",
|
| 1541 |
+
"description": "Maximum Retail Price of the product."
|
| 1542 |
+
},
|
| 1543 |
+
"selling_price": {
|
| 1544 |
+
"type": "number",
|
| 1545 |
+
"description": "Selling price of the product."
|
| 1546 |
+
}
|
| 1547 |
+
},
|
| 1548 |
+
"required": ["name", "company_id", "slug", "seller_identifier", "brand_id"]
|
| 1549 |
+
}
|
| 1550 |
+
}
|
| 1551 |
+
},
|
| 1552 |
+
{
|
| 1553 |
+
"type": "function",
|
| 1554 |
+
"function": {
|
| 1555 |
+
"name": "createInventory",
|
| 1556 |
+
"description": "Creates a new inventory record for a specific product in a company.",
|
| 1557 |
+
"parameters": {
|
| 1558 |
+
"type": "object",
|
| 1559 |
+
"properties": {
|
| 1560 |
+
"company_id": {
|
| 1561 |
+
"type": "number",
|
| 1562 |
+
"description": "Unique identifier of the company."
|
| 1563 |
+
},
|
| 1564 |
+
"product_id": {
|
| 1565 |
+
"type": "number",
|
| 1566 |
+
"description": "Unique identifier of the product."
|
| 1567 |
+
},
|
| 1568 |
+
"seller_identifier": {
|
| 1569 |
+
"type": "string",
|
| 1570 |
+
"description": "Unique identifier for the seller of the product."
|
| 1571 |
+
},
|
| 1572 |
+
"location_id": {
|
| 1573 |
+
"type": "number",
|
| 1574 |
+
"description": "Unique identifier of the location where the inventory is stored."
|
| 1575 |
+
},
|
| 1576 |
+
"mrp": {
|
| 1577 |
+
"type": "number",
|
| 1578 |
+
"description": "Maximum Retail Price of the product."
|
| 1579 |
+
},
|
| 1580 |
+
"selling_price": {
|
| 1581 |
+
"type": "number",
|
| 1582 |
+
"description": "Selling price of the product."
|
| 1583 |
+
}
|
| 1584 |
+
},
|
| 1585 |
+
"required": ["company_id", "product_id", "seller_identifier", "location_id"]
|
| 1586 |
+
}
|
| 1587 |
+
}
|
| 1588 |
+
},
|
| 1589 |
+
{
|
| 1590 |
+
"type": "function",
|
| 1591 |
+
"function": {
|
| 1592 |
+
"name": "createApplication",
|
| 1593 |
+
"description": "Creates a new application for a specified company.",
|
| 1594 |
+
"parameters": {
|
| 1595 |
+
"type": "object",
|
| 1596 |
+
"properties": {
|
| 1597 |
+
"company_id": {
|
| 1598 |
+
"type": "number",
|
| 1599 |
+
"description": "Unique identifier of the company."
|
| 1600 |
+
},
|
| 1601 |
+
"brand_ids": {
|
| 1602 |
+
"type": "array",
|
| 1603 |
+
"description": "Array of brand IDs associated with the application.",
|
| 1604 |
+
"items": {
|
| 1605 |
+
"type": "number"
|
| 1606 |
+
}
|
| 1607 |
+
},
|
| 1608 |
+
"name": {
|
| 1609 |
+
"type": "string",
|
| 1610 |
+
"description": "Name of the new application."
|
| 1611 |
+
},
|
| 1612 |
+
"subdomain": {
|
| 1613 |
+
"type": "string",
|
| 1614 |
+
"description": "Subdomain for the application's URL."
|
| 1615 |
+
}
|
| 1616 |
+
},
|
| 1617 |
+
"required": ["company_id", "brand_ids", "name", "subdomain"]
|
| 1618 |
+
}
|
| 1619 |
+
}
|
| 1620 |
+
}
|
| 1621 |
+
];
|
| 1622 |
+
|
| 1623 |
+
const messages = [{
|
| 1624 |
+
role: 'system',
|
| 1625 |
+
content: 'You are Jio Copilot. Introducing an all-encompassing tool, designed to seamlessly interact with TiraBeauty, JioCinema, JioMart, and JioFiber, catering to multiple facets of your digital lifestyle.\nOur JioMart integration simplifies your online shopping journey, providing a wide selection of products, from clothing and electronics to grocery items, all in one convenient location. JioMart can help to buy ingredients from recipes. Search each ingredient separately.\nWith TiraBeauty functionality, you can explore a wide array of health and beauty products, effortlessly manage your shopping cart, and share your cart selections via a QR code within the ecosystem of www.tirabeauty.com - your comprehensive ecommerce destination for beauty products and accessories.\nThe JioCinema feature takes you on an immersive streaming adventure, offering access to a diverse range of television shows, movies, sports content, and much more. Easily search and stream content to match your mood, directly from this interface.\nFinally, the JioFiber functionality empowers you to navigate through a range of lightning-fast internet and data plans from this leading broadband service provider. Explore and choose from a comprehensive list of prepaid and postpaid plans to meet your connectivity needs.\nEquip yourself with this multifunctional tool and experience a streamlined, efficient digital experience across a variety of platforms.'
|
| 1626 |
+
}];
|
| 1627 |
+
const session = req.jio_copilot_anonymous_session;
|
| 1628 |
+
if (session) {
|
| 1629 |
+
messages.push(...(await listCache.getAll(session)));
|
| 1630 |
+
}
|
| 1631 |
+
|
| 1632 |
+
const userMessage = { role: 'user', content: req.body.prompt };
|
| 1633 |
+
messages.push(userMessage);
|
| 1634 |
+
await listCache.setItems(session, userMessage);
|
| 1635 |
+
|
| 1636 |
+
res.setHeader('Cache-Control', 'no-cache');
|
| 1637 |
+
res.setHeader('Content-Type', 'text/event-stream');
|
| 1638 |
+
// res.setHeader('Access-Control-Allow-Origin', http://);
|
| 1639 |
+
res.setHeader('Connection', 'keep-alive');
|
| 1640 |
+
res.flushHeaders();
|
| 1641 |
+
|
| 1642 |
+
try {
|
| 1643 |
+
// await nextStep(session, messages, skills, functions, res);
|
| 1644 |
+
res.end();
|
| 1645 |
+
} catch (error) {
|
| 1646 |
+
if (error.code === 'context_length_exceeded') {
|
| 1647 |
+
res.write('You have exhausted the conversation limit, clear history and start again!');
|
| 1648 |
+
res.end();
|
| 1649 |
+
}
|
| 1650 |
+
res.write('There is some issue is going on. Please try again later.');
|
| 1651 |
+
res.end();
|
| 1652 |
+
}
|
| 1653 |
+
});
|
| 1654 |
+
|
| 1655 |
+
|
| 1656 |
+
app.use(errorHandler)
|
| 1657 |
+
|
| 1658 |
+
app.listen(port, async () => {
|
| 1659 |
+
console.log(`Example app listening at http://localhost:${port}`);
|
| 1660 |
+
const swaggerSpec = swaggerJSDoc(options);
|
| 1661 |
+
|
| 1662 |
+
// Convert to YAML
|
| 1663 |
+
const swaggerYAML = yaml.dump(swaggerSpec);
|
| 1664 |
+
await fs.writeFileSync("swagger.yaml", swaggerYAML, 'utf-8')
|
| 1665 |
+
await fs.writeFileSync("swagger.json", JSON.stringify(swaggerSpec, null, 2), 'utf-8')
|
| 1666 |
+
});
|
| 1667 |
+
|
| 1668 |
+
// async function nextStep(session, messages, skills, functions, res) {
|
| 1669 |
+
// const conn = new OpenAI({ apiKey: "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" });
|
| 1670 |
+
// const streamResponse = await conn
|
| 1671 |
+
// .chat.completions.create({
|
| 1672 |
+
// model: 'gpt-4-1106-preview',
|
| 1673 |
+
// messages,
|
| 1674 |
+
// functions,
|
| 1675 |
+
// function_call: 'auto',
|
| 1676 |
+
// temperature: 0.5,
|
| 1677 |
+
// stream: true
|
| 1678 |
+
// }).catch(async err => {
|
| 1679 |
+
// console.error(err);
|
| 1680 |
+
// const openAIError = new Error(err.error.message);
|
| 1681 |
+
// openAIError.code = err.error.code;
|
| 1682 |
+
// throw openAIError;
|
| 1683 |
+
// });
|
| 1684 |
+
|
| 1685 |
+
// let finalMessage = '';
|
| 1686 |
+
// const functionCall = { name: null, arguments: '' };
|
| 1687 |
+
|
| 1688 |
+
// for await (const line of streamResponse) {
|
| 1689 |
+
// const choice = line.choices[0];
|
| 1690 |
+
// if (choice.delta.function_call) {
|
| 1691 |
+
// const fc = choice.delta.function_call;
|
| 1692 |
+
// if (fc.name) {
|
| 1693 |
+
// // res.write(`Detected Function: ${fc.name}\n\n`);
|
| 1694 |
+
// // res.flush();
|
| 1695 |
+
// functionCall.name = fc.name;
|
| 1696 |
+
// }
|
| 1697 |
+
// if (fc.arguments) {
|
| 1698 |
+
// functionCall.arguments += fc.arguments;
|
| 1699 |
+
// }
|
| 1700 |
+
// } else if (!choice.finish_reason && choice.delta.content) {
|
| 1701 |
+
// finalMessage += choice.delta.content;
|
| 1702 |
+
// res.write(`${choice.delta.content}`);
|
| 1703 |
+
// res.flush();
|
| 1704 |
+
// }
|
| 1705 |
+
// }
|
| 1706 |
+
|
| 1707 |
+
// if (!functionCall.name) {
|
| 1708 |
+
// const assistantMessage = { role: 'assistant', content: finalMessage };
|
| 1709 |
+
// messages.push(assistantMessage);
|
| 1710 |
+
// await listCache.setItems(session, assistantMessage);
|
| 1711 |
+
// return;
|
| 1712 |
+
// }
|
| 1713 |
+
|
| 1714 |
+
// const functionName = functionCall.name;
|
| 1715 |
+
// const args = JSON.parse(functionCall.arguments);
|
| 1716 |
+
// if (!skills[functionName]) {
|
| 1717 |
+
// throw new Error(`No skill implemented for this function: ${functionName}`);
|
| 1718 |
+
// }
|
| 1719 |
+
|
| 1720 |
+
// // res.write(`Executing Function: ${functionName} with arguments ${JSON.stringify(args)} \n\n`);
|
| 1721 |
+
// // res.flush();
|
| 1722 |
+
// const skill = new skills[functionName]({ ...args, headers: { 'openai-ephemeral-user-id': session } });
|
| 1723 |
+
// const skillRes = await skill.performAction();
|
| 1724 |
+
// if (skillRes) {
|
| 1725 |
+
// const functionMessage = { role: 'function', name: functionName, content: JSON.stringify(skillRes) };
|
| 1726 |
+
// messages.push(functionMessage);
|
| 1727 |
+
// await listCache.setItems(session, functionMessage);
|
| 1728 |
+
// }
|
| 1729 |
+
// return nextStep(conn, session, messages, skills, functions, res);
|
| 1730 |
+
// }
|
cache.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
/**
|
| 3 |
+
* A simple in-memory cache implementation
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
import { Redis } from 'ioredis';
|
| 7 |
+
|
| 8 |
+
export class RedisListCache {
|
| 9 |
+
constructor(params = {}) {
|
| 10 |
+
this.redis = new Redis()
|
| 11 |
+
this.namespace = params.namespace ? params.namespace + ':' : '';
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
// Get a value from the list
|
| 15 |
+
async getItem(key, index) {
|
| 16 |
+
const namespacedKey = this.namespace + key;
|
| 17 |
+
const item = await this.redis.lindex(namespacedKey, index);
|
| 18 |
+
return item ? JSON.parse(item) : null;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
// Get a value from the list
|
| 22 |
+
async updateItem(key, index, newValue) {
|
| 23 |
+
const namespacedKey = this.namespace + key;
|
| 24 |
+
const length = await this.redis.llen(namespacedKey);
|
| 25 |
+
if (index >= length) {
|
| 26 |
+
throw new Error('Index out of range');
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
// Update the item at the specified index
|
| 30 |
+
await this.redis.lset(namespacedKey, index, JSON.stringify(newValue));
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
// Get a all keys
|
| 34 |
+
async keys(key) {
|
| 35 |
+
const namespacedKey = this.namespace + key;
|
| 36 |
+
return this.redis.keys(namespacedKey);
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
// check if key exists
|
| 40 |
+
async exists(key, index) {
|
| 41 |
+
const namespacedKey = this.namespace + key;
|
| 42 |
+
const item = await this.redis.exists(namespacedKey);
|
| 43 |
+
return item;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
// Set multiple values in the list
|
| 47 |
+
async setItems(key, ...values) {
|
| 48 |
+
const namespacedKey = this.namespace + key;
|
| 49 |
+
const items = values.map(value => JSON.stringify({
|
| 50 |
+
...value,
|
| 51 |
+
createdAt: new Date().toISOString()
|
| 52 |
+
}));
|
| 53 |
+
await this.redis.rpush(namespacedKey, ...items);
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
// Remove a value from the list
|
| 57 |
+
async removeItem(key, count, value) {
|
| 58 |
+
const namespacedKey = this.namespace + key;
|
| 59 |
+
const item = JSON.stringify(value);
|
| 60 |
+
return this.redis.lrem(namespacedKey, count, item);
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// Get the length of the list
|
| 64 |
+
async length(key) {
|
| 65 |
+
const namespacedKey = this.namespace + key;
|
| 66 |
+
return this.redis.llen(namespacedKey);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
// Get all items from the list
|
| 70 |
+
async getAll(key, page, limit) {
|
| 71 |
+
const namespacedKey = this.namespace + key;
|
| 72 |
+
const items = await this.redis.lrange(namespacedKey, 0, -1);
|
| 73 |
+
if (page && limit) {
|
| 74 |
+
const startIndex = (page - 1) * limit;
|
| 75 |
+
const endIndex = startIndex + limit;
|
| 76 |
+
const _items = items.slice(startIndex, endIndex);
|
| 77 |
+
return _items.map(item => JSON.parse(item));
|
| 78 |
+
}
|
| 79 |
+
return items.map(item => JSON.parse(item));
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
// Remove all items from the list
|
| 83 |
+
async clear(key) {
|
| 84 |
+
const namespacedKey = this.namespace + key;
|
| 85 |
+
return this.redis.del(namespacedKey);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
// Close the Redis connection
|
| 89 |
+
async close() {
|
| 90 |
+
await this.redis.quit();
|
| 91 |
+
}
|
| 92 |
+
}
|
chat.html
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html>
|
| 3 |
+
|
| 4 |
+
<head>
|
| 5 |
+
<title>Onboarder</title>
|
| 6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 7 |
+
<!-- Meta description -->
|
| 8 |
+
<meta name="description"
|
| 9 |
+
content="Experience the seamless interaction with your digital lifestyle needs using Jio Copilot. From shopping with JioMart, exploring health and beauty products with TiraBeauty, streaming content with JioCinema, to navigating internet plans with JioFiber, Jio Copilot caters to all. Enjoy a streamlined, efficient digital experience across multiple platforms." />
|
| 10 |
+
|
| 11 |
+
<!-- Open Graph -->
|
| 12 |
+
<meta property="og:type" content="website" />
|
| 13 |
+
<meta property="og:url" content="https://jio.copilot.live/" />
|
| 14 |
+
<meta property="og:title" content="Jio CoPilot" />
|
| 15 |
+
<meta property="og:description"
|
| 16 |
+
content="Experience the seamless interaction with your digital lifestyle needs using Jio Copilot. From shopping with JioMart, exploring health and beauty products with TiraBeauty, streaming content with JioCinema, to navigating internet plans with JioFiber, Jio Copilot caters to all. Enjoy a streamlined, efficient digital experience across multiple platforms." />
|
| 17 |
+
<meta property="og:image" content="https://cdn.copilot.live/v2/original/icons/JioGPT_icon.png" />
|
| 18 |
+
|
| 19 |
+
<link rel="stylesheet"
|
| 20 |
+
href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/4.0.0/github-markdown.min.css" />
|
| 21 |
+
<link rel="icon" href="https://cdn.copilot.live/v2/original/icons/JioGPT_icon.png" type="image/x-icon" />
|
| 22 |
+
|
| 23 |
+
<style>
|
| 24 |
+
body {
|
| 25 |
+
display: flex;
|
| 26 |
+
justify-content: center;
|
| 27 |
+
align-items: center;
|
| 28 |
+
height: 100vh;
|
| 29 |
+
margin: 0;
|
| 30 |
+
background-color: white;
|
| 31 |
+
font-family: Arial, sans-serif;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
#title-bar {
|
| 35 |
+
font-size: 20px;
|
| 36 |
+
display: flex;
|
| 37 |
+
align-items: center;
|
| 38 |
+
justify-content: center;
|
| 39 |
+
margin: 12px 0px;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
#chat-container {
|
| 43 |
+
width: 95%;
|
| 44 |
+
height: 100%;
|
| 45 |
+
max-width: 800px;
|
| 46 |
+
overflow: hidden;
|
| 47 |
+
display: flex;
|
| 48 |
+
flex-direction: column;
|
| 49 |
+
justify-content: space-between;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
#chat {
|
| 53 |
+
height: calc(100vh - 160px);
|
| 54 |
+
overflow: auto;
|
| 55 |
+
border-radius: 10px;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
.message {
|
| 59 |
+
padding: 10px;
|
| 60 |
+
margin-bottom: 10px;
|
| 61 |
+
border-radius: 10px;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
.user {
|
| 65 |
+
align-self: flex-end;
|
| 66 |
+
background-color: #f4a91e;
|
| 67 |
+
color: white;
|
| 68 |
+
display: flex;
|
| 69 |
+
align-items: flex-start;
|
| 70 |
+
justify-content: unset;
|
| 71 |
+
gap: 13px;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
.ai {
|
| 75 |
+
align-self: flex-start;
|
| 76 |
+
background-color: #eee;
|
| 77 |
+
color: black;
|
| 78 |
+
display: flex;
|
| 79 |
+
align-items: flex-start;
|
| 80 |
+
justify-content: unset;
|
| 81 |
+
gap: 13px;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
#input-container {
|
| 85 |
+
display: flex;
|
| 86 |
+
height: 70px;
|
| 87 |
+
border-radius: 10px;
|
| 88 |
+
margin-bottom: 10px;
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
#message {
|
| 92 |
+
width: 80%;
|
| 93 |
+
border: 0;
|
| 94 |
+
font-size: 16px;
|
| 95 |
+
padding: 10px;
|
| 96 |
+
border-radius: 10px 0 0 10px;
|
| 97 |
+
background-color: #eee;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
#message:focus-visible {
|
| 101 |
+
outline: 0;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
#send {
|
| 105 |
+
width: 20%;
|
| 106 |
+
max-width: 200px;
|
| 107 |
+
background-color: #3635f0;
|
| 108 |
+
color: white;
|
| 109 |
+
border: none;
|
| 110 |
+
font-size: 16px;
|
| 111 |
+
cursor: pointer;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
#clear-history {
|
| 115 |
+
width: 80px;
|
| 116 |
+
font-size: 16px;
|
| 117 |
+
border: none;
|
| 118 |
+
color: white;
|
| 119 |
+
background-color: #1ecbae;
|
| 120 |
+
border-radius: 0 10px 10px 0;
|
| 121 |
+
cursor: pointer;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
.disable-button {
|
| 125 |
+
background-color: #eee !important;
|
| 126 |
+
cursor: not-allowed !important;
|
| 127 |
+
color: #c3c3c3 !important;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
.cursor {
|
| 131 |
+
height: 1.2em;
|
| 132 |
+
width: 0.7em;
|
| 133 |
+
background-color: #374151;
|
| 134 |
+
animation: blink 1s infinite;
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
/* Animation */
|
| 138 |
+
@keyframes blink {
|
| 139 |
+
0% {
|
| 140 |
+
opacity: 1;
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
50% {
|
| 144 |
+
opacity: 0;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
100% {
|
| 148 |
+
opacity: 1;
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
</style>
|
| 152 |
+
</head>
|
| 153 |
+
|
| 154 |
+
<body>
|
| 155 |
+
<div id="chat-container">
|
| 156 |
+
<div id="title-bar">
|
| 157 |
+
<img src="https://cdn.copilot.live/v2/original/icons/JioGPT_icon.png" width="40px" height="40px" />
|
| 158 |
+
Jio CoPilot
|
| 159 |
+
</div>
|
| 160 |
+
<div id="chat"></div>
|
| 161 |
+
<div id="input-container">
|
| 162 |
+
<input id="message" type="text" placeholder="Type your message" />
|
| 163 |
+
<button id="send" title="Send Message">Send</button>
|
| 164 |
+
<button id="clear-history" title="Clear history">Clear</button>
|
| 165 |
+
</div>
|
| 166 |
+
</div>
|
| 167 |
+
|
| 168 |
+
<!-- Import marked.js for markdown rendering -->
|
| 169 |
+
<script src="https://cdn.jsdelivr.net/npm/marked@5.1.0/marked.min.js"></script>
|
| 170 |
+
|
| 171 |
+
<script>
|
| 172 |
+
const renderer = new marked.Renderer();
|
| 173 |
+
const linkRenderer = renderer.link;
|
| 174 |
+
renderer.link = (href, title, text) => {
|
| 175 |
+
const html = linkRenderer.call(renderer, href, title, text);
|
| 176 |
+
return html.replace(
|
| 177 |
+
/^<a /,
|
| 178 |
+
'<a target="_blank" rel="noopener noreferrer" '
|
| 179 |
+
);
|
| 180 |
+
};
|
| 181 |
+
marked.setOptions({ renderer });
|
| 182 |
+
|
| 183 |
+
class StateManager {
|
| 184 |
+
constructor(initialState = {}) {
|
| 185 |
+
this.state = initialState;
|
| 186 |
+
this.listeners = [];
|
| 187 |
+
}
|
| 188 |
+
getState() {
|
| 189 |
+
return this.state;
|
| 190 |
+
}
|
| 191 |
+
subscribe(listener) {
|
| 192 |
+
this.listeners.push(listener);
|
| 193 |
+
}
|
| 194 |
+
updateState(newState) {
|
| 195 |
+
this.state = { ...this.state, ...newState };
|
| 196 |
+
this.listeners.forEach((listener) => listener(this.state));
|
| 197 |
+
}
|
| 198 |
+
}
|
| 199 |
+
const stateManager = new StateManager({ inprogress: false });
|
| 200 |
+
|
| 201 |
+
const chatElement = document.getElementById("chat");
|
| 202 |
+
document.addEventListener("DOMContentLoaded", (event) => {
|
| 203 |
+
const messageElement = document.querySelector("#message");
|
| 204 |
+
const sendButton = document.querySelector("#send");
|
| 205 |
+
const clearButton = document.querySelector("#clear-history");
|
| 206 |
+
|
| 207 |
+
sendButton.addEventListener("click", sendMessage);
|
| 208 |
+
messageElement.addEventListener("keydown", (event) => {
|
| 209 |
+
if (event.key === "Enter") {
|
| 210 |
+
const inprogress = stateManager.getState().inprogress;
|
| 211 |
+
if (!inprogress) {
|
| 212 |
+
sendMessage();
|
| 213 |
+
}
|
| 214 |
+
}
|
| 215 |
+
});
|
| 216 |
+
clearButton.addEventListener("click", clearHistory);
|
| 217 |
+
|
| 218 |
+
loadChatHistory();
|
| 219 |
+
});
|
| 220 |
+
|
| 221 |
+
async function loadChatHistory() {
|
| 222 |
+
const response = await fetch("/v1/talk/history", { method: "GET" });
|
| 223 |
+
|
| 224 |
+
if (!response.ok) {
|
| 225 |
+
console.error("Failed to fetch chat history");
|
| 226 |
+
return;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
const chatHistory = await response.json();
|
| 230 |
+
|
| 231 |
+
for (const message of chatHistory) {
|
| 232 |
+
appendMessage(
|
| 233 |
+
message.content,
|
| 234 |
+
message.role === "user" ? "user" : "ai"
|
| 235 |
+
);
|
| 236 |
+
}
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
async function clearHistory() {
|
| 240 |
+
const response = await fetch("/v1/talk/history", { method: "DELETE" });
|
| 241 |
+
|
| 242 |
+
if (response.ok) {
|
| 243 |
+
chatElement.replaceChildren(chatElement.firstChild);
|
| 244 |
+
|
| 245 |
+
stateManager.updateState({ inprogress: false });
|
| 246 |
+
} else {
|
| 247 |
+
console.error("Failed to clear chat history");
|
| 248 |
+
}
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
async function sendMessage() {
|
| 252 |
+
const messageElement = document.querySelector("#message");
|
| 253 |
+
const message = messageElement.value;
|
| 254 |
+
messageElement.value = "";
|
| 255 |
+
appendMessage(message, "user");
|
| 256 |
+
const aiMessageContainer = appendMessage("", "ai");
|
| 257 |
+
const aiMessageElement = aiMessageContainer.childNodes[1];
|
| 258 |
+
const sendButton = document.getElementById("send");
|
| 259 |
+
sendButton.disabled = true;
|
| 260 |
+
sendButton.classList.add("disable-button");
|
| 261 |
+
const cursor = document.createElement("div");
|
| 262 |
+
cursor.classList.add("cursor");
|
| 263 |
+
aiMessageElement.appendChild(cursor)
|
| 264 |
+
const response = await fetch("/openai", {
|
| 265 |
+
method: "POST",
|
| 266 |
+
headers: { "Content-Type": "application/json" },
|
| 267 |
+
body: JSON.stringify({ prompt: message }),
|
| 268 |
+
});
|
| 269 |
+
|
| 270 |
+
const reader = response.body
|
| 271 |
+
.pipeThrough(new TextDecoderStream())
|
| 272 |
+
.getReader();
|
| 273 |
+
let serverMessage = "";
|
| 274 |
+
let count = 0;
|
| 275 |
+
while (true) {
|
| 276 |
+
stateManager.updateState({ inprogress: true });
|
| 277 |
+
const { value, done } = await reader.read();
|
| 278 |
+
if (done) {
|
| 279 |
+
stateManager.updateState({ inprogress: false });
|
| 280 |
+
document.getElementById("send").disabled = false;
|
| 281 |
+
sendButton.disabled = false;
|
| 282 |
+
sendButton.classList.remove("disable-button");
|
| 283 |
+
break;
|
| 284 |
+
}
|
| 285 |
+
serverMessage += value;
|
| 286 |
+
aiMessageElement.innerHTML = marked.parse(
|
| 287 |
+
serverMessage.replace(/\\n/g, "<br>"),
|
| 288 |
+
{ breaks: true }
|
| 289 |
+
);
|
| 290 |
+
if (
|
| 291 |
+
count % 10 == 0 &&
|
| 292 |
+
chatElement.scrollHeight -
|
| 293 |
+
chatElement.scrollTop -
|
| 294 |
+
chatElement.clientHeight <=
|
| 295 |
+
44
|
| 296 |
+
) {
|
| 297 |
+
aiMessageElement.scrollIntoView();
|
| 298 |
+
}
|
| 299 |
+
count++;
|
| 300 |
+
}
|
| 301 |
+
chatElement.scrollTop = chatElement.scrollHeight;
|
| 302 |
+
}
|
| 303 |
+
|
| 304 |
+
function appendMessage(message, sender) {
|
| 305 |
+
const div = document.createElement("div");
|
| 306 |
+
div.classList.add("message", "markdown-body", sender);
|
| 307 |
+
div.appendChild(createIcon(sender));
|
| 308 |
+
div.appendChild(createTextElement(message, sender));
|
| 309 |
+
chatElement.appendChild(div);
|
| 310 |
+
div.scrollIntoView();
|
| 311 |
+
chatElement.scrollTop = chatElement.scrollHeight;
|
| 312 |
+
return div;
|
| 313 |
+
}
|
| 314 |
+
|
| 315 |
+
function createIcon(sender) {
|
| 316 |
+
const icon = document.createElement("img");
|
| 317 |
+
icon.style.width = "40px";
|
| 318 |
+
icon.style.height = "40px";
|
| 319 |
+
icon.style.marginTop = "10px";
|
| 320 |
+
icon.style.backgroundColor = "unset";
|
| 321 |
+
icon.alt = sender.charAt(0).toUpperCase() + sender.slice(1) + " Icon";
|
| 322 |
+
icon.src =
|
| 323 |
+
sender === "ai"
|
| 324 |
+
? "https://cdn.copilot.live/v2/original/icons/JioGPT_icon.png"
|
| 325 |
+
: "https://img.icons8.com/?size=512&id=108296&format=png";
|
| 326 |
+
return icon;
|
| 327 |
+
}
|
| 328 |
+
|
| 329 |
+
function createTextElement(message, sender) {
|
| 330 |
+
const textElement = document.createElement("div");
|
| 331 |
+
textElement.innerHTML = marked.parse(message, { breaks: true });
|
| 332 |
+
return textElement;
|
| 333 |
+
}
|
| 334 |
+
</script>
|
| 335 |
+
</body>
|
| 336 |
+
|
| 337 |
+
</html>
|
functions.js
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import Redis from "ioredis";
|
| 2 |
+
import { initClient } from './utils.js';
|
| 3 |
+
|
| 4 |
+
const redis = new Redis();
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
export const getCompanyCreds = async ({ company_id }) => {
|
| 9 |
+
const creds = await redis.get(`${companyId}:creds`);
|
| 10 |
+
if (!creds) {
|
| 11 |
+
throw {
|
| 12 |
+
message: "company creds not found"
|
| 13 |
+
}
|
| 14 |
+
}
|
| 15 |
+
return { ...JSON.parse(creds), company_id }
|
| 16 |
+
}
|
| 17 |
+
export const createUpdateCompanyCreds = async ({ company_id, clientId, clientSecret }) => {
|
| 18 |
+
const creds = await redis.set(`${company_id}:creds`, JSON.stringify({ clientId, clientSecret }));
|
| 19 |
+
return { message: "company creds saved" }
|
| 20 |
+
}
|
| 21 |
+
export const getApplications = async ({ company_id }) => {
|
| 22 |
+
const client = await initClient(company_id);
|
| 23 |
+
let applications = await client.configuration.getApplications({ pageSize: 100 });
|
| 24 |
+
applications = applications.items.map(i => {
|
| 25 |
+
return {
|
| 26 |
+
name: i.name,
|
| 27 |
+
id: i.id,
|
| 28 |
+
token: i.token,
|
| 29 |
+
domain: i.domains?.find(i => i.is_primary)?.name,
|
| 30 |
+
logo: i.logo?.secure_url
|
| 31 |
+
}
|
| 32 |
+
})
|
| 33 |
+
return applications;
|
| 34 |
+
}
|
| 35 |
+
export const createBrand = async ({ company_id, name, description, logo = "https://cdn.pixelbin.io/v2/falling-surf-7c8bb8/fyprod/wrkr/platform/pictures/favicon/original/ZWTmgEoFQ-platform-favicon.png" }) => {
|
| 36 |
+
const client = await initClient(company_id);
|
| 37 |
+
let brands = await client.companyProfile.createBrand({
|
| 38 |
+
body: {
|
| 39 |
+
name,
|
| 40 |
+
description,
|
| 41 |
+
logo,
|
| 42 |
+
banner: { portrait: logo, landscape: logo }
|
| 43 |
+
}
|
| 44 |
+
});
|
| 45 |
+
return { message: "brand created", id: brands?.id };
|
| 46 |
+
}
|
| 47 |
+
export const getBrands = async ({ company_id }) => {
|
| 48 |
+
const client = await initClient(company_id);
|
| 49 |
+
let brands = await client.companyProfile.getBrands({ pageSize: 300 });
|
| 50 |
+
brands = brands.items.map(i => {
|
| 51 |
+
return {
|
| 52 |
+
name: i?.brand?.name,
|
| 53 |
+
logo: i?.brand?.logo,
|
| 54 |
+
id: i?.brand?.uid,
|
| 55 |
+
}
|
| 56 |
+
})
|
| 57 |
+
return brands
|
| 58 |
+
}
|
| 59 |
+
export const updateBrand = async ({ company_id, brand_id }) => {
|
| 60 |
+
const client = await initClient(company_id);
|
| 61 |
+
let brands = await client.companyProfile.editBrand({
|
| 62 |
+
brand_id,
|
| 63 |
+
body: {
|
| 64 |
+
name,
|
| 65 |
+
description,
|
| 66 |
+
logo,
|
| 67 |
+
banner: { portrait: logo, landscape: logo }
|
| 68 |
+
}
|
| 69 |
+
});
|
| 70 |
+
return { message: "brand updated" }
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
export const getLocations = async ({ company_id }) => {
|
| 74 |
+
const client = await initClient(company_id);
|
| 75 |
+
let locations = await client.companyProfile.getLocations({ pageSize: 100 });
|
| 76 |
+
locations = locations.items.map(i => {
|
| 77 |
+
return {
|
| 78 |
+
name: i.name,
|
| 79 |
+
id: i.uid,
|
| 80 |
+
code: i.code,
|
| 81 |
+
documents: i.documents
|
| 82 |
+
}
|
| 83 |
+
})
|
| 84 |
+
return locations;
|
| 85 |
+
}
|
| 86 |
+
export const createLocation = async ({ company_id, address1, address2, pincode, state, city, number, country_code, gst_name, gst_no, latitude = 19.2762702, longitude = 72.8929, }) => {
|
| 87 |
+
const client = await initClient(company_id);
|
| 88 |
+
let locations = await client.companyProfile.createLocation({
|
| 89 |
+
body: {
|
| 90 |
+
name,
|
| 91 |
+
display_name: name,
|
| 92 |
+
code,
|
| 93 |
+
company: parseInt(companyId),
|
| 94 |
+
documents: [{
|
| 95 |
+
type: "gst",
|
| 96 |
+
legal_name: gst_name,
|
| 97 |
+
value: gst_no,
|
| 98 |
+
verified: true
|
| 99 |
+
}],
|
| 100 |
+
address: {
|
| 101 |
+
"address1": address1,
|
| 102 |
+
"address2": address2,
|
| 103 |
+
"country": country,
|
| 104 |
+
"pincode": pincode,
|
| 105 |
+
"city": city,
|
| 106 |
+
"state": state,
|
| 107 |
+
"latitude": latitude,
|
| 108 |
+
"longitude": longitude,
|
| 109 |
+
"landmark": landmark
|
| 110 |
+
},
|
| 111 |
+
manager: {
|
| 112 |
+
"name": manager_name,
|
| 113 |
+
"email": email,
|
| 114 |
+
"mobile_no": {
|
| 115 |
+
"number": number,
|
| 116 |
+
"country_code": country_code
|
| 117 |
+
}
|
| 118 |
+
},
|
| 119 |
+
contact_numbers: [
|
| 120 |
+
{
|
| 121 |
+
"number": number,
|
| 122 |
+
"country_code": country_code
|
| 123 |
+
}
|
| 124 |
+
],
|
| 125 |
+
store_type: "high_street"
|
| 126 |
+
|
| 127 |
+
}
|
| 128 |
+
});
|
| 129 |
+
|
| 130 |
+
return { message: "location added", id: locations?.id };
|
| 131 |
+
}
|
| 132 |
+
export const updateLocation = async ({ company_id, location_id, address1, address2, pincode, state, city, number, country_code, gst_name, gst_no, latitude = 19.2762702, longitude = 72.8929,
|
| 133 |
+
}) => {
|
| 134 |
+
const client = await initClient(company_id);
|
| 135 |
+
let locations = await client.companyProfile.updateLocation({
|
| 136 |
+
locationId: location_id,
|
| 137 |
+
body: {
|
| 138 |
+
name,
|
| 139 |
+
display_name: name,
|
| 140 |
+
code,
|
| 141 |
+
company: parseInt(companyId),
|
| 142 |
+
documents: [{
|
| 143 |
+
type: "gst",
|
| 144 |
+
legal_name: gst_name,
|
| 145 |
+
value: gst_no,
|
| 146 |
+
verified: true
|
| 147 |
+
}],
|
| 148 |
+
address: {
|
| 149 |
+
"address1": address1,
|
| 150 |
+
"address2": address2,
|
| 151 |
+
"country": country,
|
| 152 |
+
"pincode": pincode,
|
| 153 |
+
"city": city,
|
| 154 |
+
"state": state,
|
| 155 |
+
"latitude": latitude,
|
| 156 |
+
"longitude": longitude,
|
| 157 |
+
"landmark": landmark
|
| 158 |
+
},
|
| 159 |
+
manager: {
|
| 160 |
+
"name": manager_name,
|
| 161 |
+
"email": email,
|
| 162 |
+
"mobile_no": {
|
| 163 |
+
"number": number,
|
| 164 |
+
"country_code": country_code
|
| 165 |
+
}
|
| 166 |
+
},
|
| 167 |
+
contact_numbers: [
|
| 168 |
+
{
|
| 169 |
+
"number": number,
|
| 170 |
+
"country_code": country_code
|
| 171 |
+
}
|
| 172 |
+
],
|
| 173 |
+
store_type: "high_street"
|
| 174 |
+
|
| 175 |
+
}
|
| 176 |
+
});
|
| 177 |
+
|
| 178 |
+
return { message: "location updated" };
|
| 179 |
+
}
|
| 180 |
+
export const createApplication = async ({ company_id, brand_ids, name, subdomain }) => {
|
| 181 |
+
const client = await initClient(company_id);
|
| 182 |
+
let app = await client.configuration.createApplication({
|
| 183 |
+
body: {
|
| 184 |
+
"app": {
|
| 185 |
+
"company_id": (1).toString(),
|
| 186 |
+
"channel_type": "website-and-mobile-apps",
|
| 187 |
+
"auth": {
|
| 188 |
+
"enabled": true
|
| 189 |
+
},
|
| 190 |
+
"name": name,
|
| 191 |
+
"desc": "",
|
| 192 |
+
"mode": "live"
|
| 193 |
+
},
|
| 194 |
+
"configuration": {
|
| 195 |
+
"inventory": {
|
| 196 |
+
"brand": {
|
| 197 |
+
"criteria": "all",
|
| 198 |
+
"brands": []
|
| 199 |
+
},
|
| 200 |
+
"store": {
|
| 201 |
+
"criteria": "filter",
|
| 202 |
+
"rules": [
|
| 203 |
+
{
|
| 204 |
+
"companies": [company_id],
|
| 205 |
+
"brands": brand_ids
|
| 206 |
+
}
|
| 207 |
+
],
|
| 208 |
+
"stores": []
|
| 209 |
+
},
|
| 210 |
+
"image": ["standard", "substandard", "default"],
|
| 211 |
+
"franchise_enabled": false,
|
| 212 |
+
"out_of_stock": true
|
| 213 |
+
},
|
| 214 |
+
"payment": {
|
| 215 |
+
"mode_of_payment": "ECOMM",
|
| 216 |
+
"source": "ECOMM"
|
| 217 |
+
},
|
| 218 |
+
"article_assignment": {
|
| 219 |
+
"post_order_reassignment": true,
|
| 220 |
+
"enforced_stores": [],
|
| 221 |
+
"rules": {
|
| 222 |
+
"store_priority": {
|
| 223 |
+
"enabled": false,
|
| 224 |
+
"storetype_order": []
|
| 225 |
+
}
|
| 226 |
+
}
|
| 227 |
+
}
|
| 228 |
+
},
|
| 229 |
+
"domain": {
|
| 230 |
+
"name": `${subdomain}.hostx5.de`
|
| 231 |
+
}
|
| 232 |
+
}
|
| 233 |
+
})
|
| 234 |
+
|
| 235 |
+
|
| 236 |
+
return { message: "location updated" };
|
| 237 |
+
}
|
| 238 |
+
export const createProduct = async ({ name, company_id, slug,
|
| 239 |
+
seller_identifier,
|
| 240 |
+
brand_id, mrp = 999, selling_price = 499 }) => {
|
| 241 |
+
const client = await initClient(company_id);
|
| 242 |
+
const obj = {
|
| 243 |
+
"name": name,
|
| 244 |
+
"slug": slug,
|
| 245 |
+
"brand_uid": brand_id,
|
| 246 |
+
"item_code": seller_identifier,
|
| 247 |
+
"teaser_tag": {},
|
| 248 |
+
"net_quantity": {},
|
| 249 |
+
"tax_identifier": {
|
| 250 |
+
"reporting_hsn": "1202355241H1",
|
| 251 |
+
"hsn_code": "1202355241",
|
| 252 |
+
"hsn_code_id": "65769883ba99dcf407a2b1ed"
|
| 253 |
+
},
|
| 254 |
+
"country_of_origin": "India",
|
| 255 |
+
"variants": {},
|
| 256 |
+
"variant_media": {},
|
| 257 |
+
"description": "PHA+WW91ciBwcm9kdWN0IGRlc2NyaXB0aW9uPC9wPg==",
|
| 258 |
+
"short_description": "Your product description",
|
| 259 |
+
"highlights": [],
|
| 260 |
+
"company_id": 10,
|
| 261 |
+
"template_tag": "c2-0-template",
|
| 262 |
+
"currency": "INR",
|
| 263 |
+
"media": [],
|
| 264 |
+
"is_set": false,
|
| 265 |
+
"sizes": [
|
| 266 |
+
{
|
| 267 |
+
"size": "OS",
|
| 268 |
+
"price": mrp,
|
| 269 |
+
"price_effective": selling_price,
|
| 270 |
+
"price_transfer": 0,
|
| 271 |
+
"currency": "INR",
|
| 272 |
+
"item_length": 1,
|
| 273 |
+
"item_width": 1,
|
| 274 |
+
"item_height": 1,
|
| 275 |
+
"item_weight": 1,
|
| 276 |
+
"item_dimensions_unit_of_measure": "cm",
|
| 277 |
+
"item_weight_unit_of_measure": "gram",
|
| 278 |
+
"track_inventory": true,
|
| 279 |
+
"identifiers": [
|
| 280 |
+
{
|
| 281 |
+
"gtin_value": seller_identifier,
|
| 282 |
+
"gtin_type": "ean",
|
| 283 |
+
"primary": true
|
| 284 |
+
}
|
| 285 |
+
],
|
| 286 |
+
"_custom_json": {},
|
| 287 |
+
"name": "OS"
|
| 288 |
+
}
|
| 289 |
+
],
|
| 290 |
+
"_custom_json": {},
|
| 291 |
+
"size_guide": "",
|
| 292 |
+
"product_group_tag": [],
|
| 293 |
+
"product_publish": {
|
| 294 |
+
"product_online_date": "2023-12-11T08:38:10.082Z",
|
| 295 |
+
"is_set": false
|
| 296 |
+
},
|
| 297 |
+
"is_active": true,
|
| 298 |
+
"custom_order": {
|
| 299 |
+
"is_custom_order": false,
|
| 300 |
+
"manufacturing_time": 0,
|
| 301 |
+
"manufacturing_time_unit": "hours"
|
| 302 |
+
},
|
| 303 |
+
"multi_size": false,
|
| 304 |
+
"no_of_boxes": 1,
|
| 305 |
+
"is_dependent": false,
|
| 306 |
+
"item_type": "digital",
|
| 307 |
+
"tags": [],
|
| 308 |
+
"departments": [
|
| 309 |
+
19771
|
| 310 |
+
],
|
| 311 |
+
return_config: {
|
| 312 |
+
"returnable": false
|
| 313 |
+
},
|
| 314 |
+
"category_slug": "c2-0-cat",
|
| 315 |
+
"trader": [
|
| 316 |
+
{
|
| 317 |
+
"type": "Manufacturer",
|
| 318 |
+
"name": "Manufacturer",
|
| 319 |
+
"address": [
|
| 320 |
+
"Manufacturer Address"
|
| 321 |
+
]
|
| 322 |
+
}
|
| 323 |
+
],
|
| 324 |
+
"return_config": {
|
| 325 |
+
"returnable": true,
|
| 326 |
+
time: 3,
|
| 327 |
+
unit: "days"
|
| 328 |
+
}
|
| 329 |
+
}
|
| 330 |
+
let product = await client.catalog.createProduct({
|
| 331 |
+
body: obj
|
| 332 |
+
});
|
| 333 |
+
product = await client.catalog.getProduct({
|
| 334 |
+
itemId: product.uid
|
| 335 |
+
});
|
| 336 |
+
return {
|
| 337 |
+
message: "product created",
|
| 338 |
+
id: product.data.uid,
|
| 339 |
+
seller_identifier: product?.data?.sizes?.[0]?.seller_identifier
|
| 340 |
+
};
|
| 341 |
+
}
|
| 342 |
+
export const createInventory = async ({ company_id, product_id, seller_identifier, location_id, mrp = 999, selling_price = 499 }) => {
|
| 343 |
+
const client = await initClient(company_id);
|
| 344 |
+
let product = await client.catalog.getProduct({
|
| 345 |
+
itemId: product_id
|
| 346 |
+
});
|
| 347 |
+
let inv = await client.catalog.updateRealtimeInventory({
|
| 348 |
+
itemId: product.data.uid,
|
| 349 |
+
sellerIdentifier: seller_identifier,
|
| 350 |
+
body: {
|
| 351 |
+
company_id: company_id,
|
| 352 |
+
payload: [{
|
| 353 |
+
"seller_identifier": seller_identifier,
|
| 354 |
+
"store_id": location_id,
|
| 355 |
+
"price_marked": mrp,
|
| 356 |
+
"price_effective": selling_price,
|
| 357 |
+
"total_quantity": 10,
|
| 358 |
+
"tags": []
|
| 359 |
+
}]
|
| 360 |
+
}
|
| 361 |
+
})
|
| 362 |
+
|
| 363 |
+
return { message: "inv created" };
|
| 364 |
+
}
|
index.js
CHANGED
|
@@ -5,7 +5,8 @@ import { errorHandler } from './middleware.js';
|
|
| 5 |
import swaggerJSDoc from 'swagger-jsdoc';
|
| 6 |
import yaml from 'js-yaml'
|
| 7 |
import fs from 'fs';
|
| 8 |
-
|
|
|
|
| 9 |
const redis = new Redis();
|
| 10 |
|
| 11 |
const app = express();
|
|
@@ -450,7 +451,7 @@ app.get("/company/:companyId/brands", async (req, res, next) => {
|
|
| 450 |
* name: brandId
|
| 451 |
* required: true
|
| 452 |
* schema:
|
| 453 |
-
* type:
|
| 454 |
* description: The unique identifier of the brand
|
| 455 |
* requestBody:
|
| 456 |
* required: true
|
|
@@ -577,7 +578,7 @@ app.put("/company/:companyId/brands/:brandId", async (req, res, next) => {
|
|
| 577 |
app.get("/company/:companyId/locations", async (req, res, next) => {
|
| 578 |
try {
|
| 579 |
const { companyId } = req.params;
|
| 580 |
-
const client = await initClient(companyId);
|
| 581 |
let locations = await client.companyProfile.getLocations({ pageSize: 100 });
|
| 582 |
locations = locations.items.map(i => {
|
| 583 |
return {
|
|
@@ -820,111 +821,838 @@ app.put("/company/:companyId/locations/locationId", async (req, res, next) => {
|
|
| 820 |
}
|
| 821 |
})
|
| 822 |
|
|
|
|
|
|
|
| 823 |
/**
|
| 824 |
* @swagger
|
| 825 |
-
* /company/{companyId}/
|
| 826 |
-
*
|
| 827 |
-
* summary:
|
| 828 |
-
* description:
|
| 829 |
-
*
|
| 830 |
-
*
|
|
|
|
| 831 |
* parameters:
|
| 832 |
* - in: path
|
| 833 |
* name: companyId
|
| 834 |
* required: true
|
| 835 |
* schema:
|
| 836 |
* type: string
|
| 837 |
-
* description:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 838 |
* responses:
|
| 839 |
* 200:
|
| 840 |
-
* description:
|
| 841 |
* content:
|
| 842 |
* application/json:
|
| 843 |
* schema:
|
| 844 |
-
* type:
|
| 845 |
-
*
|
| 846 |
-
*
|
| 847 |
-
*
|
| 848 |
-
*
|
| 849 |
-
*
|
| 850 |
-
*
|
| 851 |
-
*
|
| 852 |
-
* type: string
|
| 853 |
-
* description: slug or identifier of the department
|
| 854 |
*/
|
| 855 |
|
| 856 |
-
app.
|
| 857 |
try {
|
| 858 |
const { companyId } = req.params;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 859 |
const client = await initClient(companyId);
|
| 860 |
-
let
|
| 861 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 862 |
});
|
| 863 |
-
departments = departments?.items?.map(i => { return { name: i.name, slug: i.slug } })
|
| 864 |
-
res.json(departments);
|
| 865 |
-
|
| 866 |
} catch (e) { next(e) }
|
| 867 |
})
|
|
|
|
| 868 |
/**
|
| 869 |
* @swagger
|
| 870 |
-
* /company/{companyId}/
|
| 871 |
-
*
|
| 872 |
-
* summary:
|
| 873 |
-
* description:
|
| 874 |
-
*
|
| 875 |
-
*
|
|
|
|
| 876 |
* parameters:
|
| 877 |
* - in: path
|
| 878 |
* name: companyId
|
| 879 |
* required: true
|
| 880 |
* schema:
|
| 881 |
* type: string
|
| 882 |
-
* description:
|
| 883 |
-
* parameters:
|
| 884 |
* - in: path
|
| 885 |
-
* name:
|
| 886 |
* required: true
|
| 887 |
* schema:
|
| 888 |
* type: string
|
| 889 |
-
* description:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 890 |
* parameters:
|
| 891 |
-
* - in:
|
| 892 |
* name: companyId
|
| 893 |
* required: true
|
| 894 |
* schema:
|
| 895 |
* type: string
|
| 896 |
-
* description: The
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 897 |
* responses:
|
| 898 |
* 200:
|
| 899 |
-
* description:
|
| 900 |
* content:
|
| 901 |
* application/json:
|
| 902 |
* schema:
|
| 903 |
-
* type:
|
| 904 |
-
*
|
| 905 |
-
*
|
| 906 |
-
*
|
| 907 |
-
*
|
| 908 |
-
*
|
| 909 |
-
*
|
| 910 |
-
*
|
| 911 |
-
*
|
| 912 |
-
*
|
|
|
|
| 913 |
*/
|
| 914 |
-
|
|
|
|
| 915 |
try {
|
| 916 |
-
const { companyId
|
| 917 |
-
const {
|
| 918 |
const client = await initClient(companyId);
|
| 919 |
-
let categories = await client.catalog.listProductTemplateCategories({
|
| 920 |
-
departments: departmentSlug, pageNo: 1, pageSize: 100, itemType: item_type
|
| 921 |
-
});
|
| 922 |
-
categories = categories?.items?.map(i => { return { name: i.name, slug: i.slug } })
|
| 923 |
-
res.json(categories);
|
| 924 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 925 |
} catch (e) { next(e) }
|
| 926 |
})
|
| 927 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 928 |
app.use(errorHandler)
|
| 929 |
|
| 930 |
app.listen(port, async () => {
|
|
@@ -936,3 +1664,67 @@ app.listen(port, async () => {
|
|
| 936 |
await fs.writeFileSync("swagger.yaml", swaggerYAML, 'utf-8')
|
| 937 |
await fs.writeFileSync("swagger.json", JSON.stringify(swaggerSpec, null, 2), 'utf-8')
|
| 938 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
import swaggerJSDoc from 'swagger-jsdoc';
|
| 6 |
import yaml from 'js-yaml'
|
| 7 |
import fs from 'fs';
|
| 8 |
+
import { RedisListCache } from './cache.js';
|
| 9 |
+
const listCache = new RedisListCache({ namespace: "fc" })
|
| 10 |
const redis = new Redis();
|
| 11 |
|
| 12 |
const app = express();
|
|
|
|
| 451 |
* name: brandId
|
| 452 |
* required: true
|
| 453 |
* schema:
|
| 454 |
+
* type: number
|
| 455 |
* description: The unique identifier of the brand
|
| 456 |
* requestBody:
|
| 457 |
* required: true
|
|
|
|
| 578 |
app.get("/company/:companyId/locations", async (req, res, next) => {
|
| 579 |
try {
|
| 580 |
const { companyId } = req.params;
|
| 581 |
+
const client = await initClient(companyId.toString());
|
| 582 |
let locations = await client.companyProfile.getLocations({ pageSize: 100 });
|
| 583 |
locations = locations.items.map(i => {
|
| 584 |
return {
|
|
|
|
| 821 |
}
|
| 822 |
})
|
| 823 |
|
| 824 |
+
|
| 825 |
+
|
| 826 |
/**
|
| 827 |
* @swagger
|
| 828 |
+
* /company/{companyId}/products:
|
| 829 |
+
* post:
|
| 830 |
+
* summary: Creates a new product for a given company.
|
| 831 |
+
* description: This endpoint creates a new product with various attributes including name, slug, pricing, and more.
|
| 832 |
+
* operationId: createProduct
|
| 833 |
+
* tags:
|
| 834 |
+
* - Products
|
| 835 |
* parameters:
|
| 836 |
* - in: path
|
| 837 |
* name: companyId
|
| 838 |
* required: true
|
| 839 |
* schema:
|
| 840 |
* type: string
|
| 841 |
+
* description: Unique identifier of the company.
|
| 842 |
+
* requestBody:
|
| 843 |
+
* required: true
|
| 844 |
+
* content:
|
| 845 |
+
* application/json:
|
| 846 |
+
* schema:
|
| 847 |
+
* type: object
|
| 848 |
+
* required:
|
| 849 |
+
* - name
|
| 850 |
+
* - slug
|
| 851 |
+
* - seller_identifier
|
| 852 |
+
* - brand_id
|
| 853 |
+
* properties:
|
| 854 |
+
* name:
|
| 855 |
+
* type: string
|
| 856 |
+
* description: Name of the product.
|
| 857 |
+
* slug:
|
| 858 |
+
* type: string
|
| 859 |
+
* description: URL-friendly identifier for the product.
|
| 860 |
+
* seller_identifier:
|
| 861 |
+
* type: string
|
| 862 |
+
* description: Unique identifier for the seller.
|
| 863 |
+
* brand_id:
|
| 864 |
+
* type: string
|
| 865 |
+
* description: Unique identifier for the brand.
|
| 866 |
+
* location_id:
|
| 867 |
+
* type: string
|
| 868 |
+
* description: Location identifier for the product.
|
| 869 |
+
* mrp:
|
| 870 |
+
* type: number
|
| 871 |
+
* default: 999
|
| 872 |
+
* description: Maximum retail price of the product.
|
| 873 |
+
* selling_price:
|
| 874 |
+
* type: number
|
| 875 |
+
* default: 499
|
| 876 |
+
* description: Selling price of the product.
|
| 877 |
* responses:
|
| 878 |
* 200:
|
| 879 |
+
* description: Successful creation of the product.
|
| 880 |
* content:
|
| 881 |
* application/json:
|
| 882 |
* schema:
|
| 883 |
+
* type: object
|
| 884 |
+
* properties:
|
| 885 |
+
* message:
|
| 886 |
+
* type: string
|
| 887 |
+
* id:
|
| 888 |
+
* type: string
|
| 889 |
+
* seller_identifier:
|
| 890 |
+
* type: string
|
|
|
|
|
|
|
| 891 |
*/
|
| 892 |
|
| 893 |
+
app.post("/company/:companyId/products", async (req, res, next) => {
|
| 894 |
try {
|
| 895 |
const { companyId } = req.params;
|
| 896 |
+
const { name,
|
| 897 |
+
slug,
|
| 898 |
+
seller_identifier,
|
| 899 |
+
brand_id, location_id, mrp = 999, selling_price = 499
|
| 900 |
+
} = req.body;
|
| 901 |
+
const obj = {
|
| 902 |
+
"name": name,
|
| 903 |
+
"slug": slug,
|
| 904 |
+
"brand_uid": brand_id,
|
| 905 |
+
"item_code": seller_identifier,
|
| 906 |
+
"teaser_tag": {},
|
| 907 |
+
"net_quantity": {},
|
| 908 |
+
"tax_identifier": {
|
| 909 |
+
"reporting_hsn": "1202355241H1",
|
| 910 |
+
"hsn_code": "1202355241",
|
| 911 |
+
"hsn_code_id": "65769883ba99dcf407a2b1ed"
|
| 912 |
+
},
|
| 913 |
+
"country_of_origin": "India",
|
| 914 |
+
"variants": {},
|
| 915 |
+
"variant_media": {},
|
| 916 |
+
"description": "PHA+WW91ciBwcm9kdWN0IGRlc2NyaXB0aW9uPC9wPg==",
|
| 917 |
+
"short_description": "Your product description",
|
| 918 |
+
"highlights": [],
|
| 919 |
+
"company_id": 10,
|
| 920 |
+
"template_tag": "c2-0-template",
|
| 921 |
+
"currency": "INR",
|
| 922 |
+
"media": [],
|
| 923 |
+
"is_set": false,
|
| 924 |
+
"sizes": [
|
| 925 |
+
{
|
| 926 |
+
"size": "OS",
|
| 927 |
+
"price": mrp,
|
| 928 |
+
"price_effective": selling_price,
|
| 929 |
+
"price_transfer": 0,
|
| 930 |
+
"currency": "INR",
|
| 931 |
+
"item_length": 1,
|
| 932 |
+
"item_width": 1,
|
| 933 |
+
"item_height": 1,
|
| 934 |
+
"item_weight": 1,
|
| 935 |
+
"item_dimensions_unit_of_measure": "cm",
|
| 936 |
+
"item_weight_unit_of_measure": "gram",
|
| 937 |
+
"track_inventory": true,
|
| 938 |
+
"identifiers": [
|
| 939 |
+
{
|
| 940 |
+
"gtin_value": seller_identifier,
|
| 941 |
+
"gtin_type": "ean",
|
| 942 |
+
"primary": true
|
| 943 |
+
}
|
| 944 |
+
],
|
| 945 |
+
"_custom_json": {},
|
| 946 |
+
"name": "OS"
|
| 947 |
+
}
|
| 948 |
+
],
|
| 949 |
+
"_custom_json": {},
|
| 950 |
+
"size_guide": "",
|
| 951 |
+
"product_group_tag": [],
|
| 952 |
+
"product_publish": {
|
| 953 |
+
"product_online_date": "2023-12-11T08:38:10.082Z",
|
| 954 |
+
"is_set": false
|
| 955 |
+
},
|
| 956 |
+
"is_active": true,
|
| 957 |
+
"custom_order": {
|
| 958 |
+
"is_custom_order": false,
|
| 959 |
+
"manufacturing_time": 0,
|
| 960 |
+
"manufacturing_time_unit": "hours"
|
| 961 |
+
},
|
| 962 |
+
"multi_size": false,
|
| 963 |
+
"no_of_boxes": 1,
|
| 964 |
+
"is_dependent": false,
|
| 965 |
+
"item_type": "digital",
|
| 966 |
+
"tags": [],
|
| 967 |
+
"departments": [
|
| 968 |
+
19771
|
| 969 |
+
],
|
| 970 |
+
return_config: {
|
| 971 |
+
"returnable": false
|
| 972 |
+
},
|
| 973 |
+
"category_slug": "c2-0-cat",
|
| 974 |
+
"trader": [
|
| 975 |
+
{
|
| 976 |
+
"type": "Manufacturer",
|
| 977 |
+
"name": "Manufacturer",
|
| 978 |
+
"address": [
|
| 979 |
+
"Manufacturer Address"
|
| 980 |
+
]
|
| 981 |
+
}
|
| 982 |
+
],
|
| 983 |
+
"return_config": {
|
| 984 |
+
"returnable": true,
|
| 985 |
+
time: 3,
|
| 986 |
+
unit: "days"
|
| 987 |
+
}
|
| 988 |
+
}
|
| 989 |
const client = await initClient(companyId);
|
| 990 |
+
let product = await client.catalog.createProduct({
|
| 991 |
+
body: obj
|
| 992 |
+
});
|
| 993 |
+
product = await client.catalog.getProduct({
|
| 994 |
+
itemId: product.uid
|
| 995 |
+
});
|
| 996 |
+
res.json({
|
| 997 |
+
message: "product created",
|
| 998 |
+
id: product.data.uid,
|
| 999 |
+
seller_identifier: product?.data?.sizes?.[0]?.seller_identifier
|
| 1000 |
});
|
|
|
|
|
|
|
|
|
|
| 1001 |
} catch (e) { next(e) }
|
| 1002 |
})
|
| 1003 |
+
|
| 1004 |
/**
|
| 1005 |
* @swagger
|
| 1006 |
+
* /company/{companyId}/products/{productId}/inventory:
|
| 1007 |
+
* post:
|
| 1008 |
+
* summary: Updates inventory for a specific product.
|
| 1009 |
+
* description: This endpoint updates the inventory details for a given product, including location, pricing, and quantity.
|
| 1010 |
+
* operationId: updateInventory
|
| 1011 |
+
* tags:
|
| 1012 |
+
* - Inventory
|
| 1013 |
* parameters:
|
| 1014 |
* - in: path
|
| 1015 |
* name: companyId
|
| 1016 |
* required: true
|
| 1017 |
* schema:
|
| 1018 |
* type: string
|
| 1019 |
+
* description: Unique identifier of the company.
|
|
|
|
| 1020 |
* - in: path
|
| 1021 |
+
* name: productId
|
| 1022 |
* required: true
|
| 1023 |
* schema:
|
| 1024 |
* type: string
|
| 1025 |
+
* description: Unique identifier of the product.
|
| 1026 |
+
* requestBody:
|
| 1027 |
+
* required: true
|
| 1028 |
+
* content:
|
| 1029 |
+
* application/json:
|
| 1030 |
+
* schema:
|
| 1031 |
+
* type: object
|
| 1032 |
+
* required:
|
| 1033 |
+
* - location_id
|
| 1034 |
+
* - seller_identifier
|
| 1035 |
+
* properties:
|
| 1036 |
+
* location_id:
|
| 1037 |
+
* type: string
|
| 1038 |
+
* description: Location identifier where the inventory is stored.
|
| 1039 |
+
* mrp:
|
| 1040 |
+
* type: number
|
| 1041 |
+
* default: 999
|
| 1042 |
+
* description: Maximum retail price of the product.
|
| 1043 |
+
* selling_price:
|
| 1044 |
+
* type: number
|
| 1045 |
+
* default: 499
|
| 1046 |
+
* description: Selling price of the product.
|
| 1047 |
+
* seller_identifier:
|
| 1048 |
+
* type: string
|
| 1049 |
+
* description: Unique identifier for the seller.
|
| 1050 |
+
* responses:
|
| 1051 |
+
* 200:
|
| 1052 |
+
* description: Successful update of inventory.
|
| 1053 |
+
* content:
|
| 1054 |
+
* application/json:
|
| 1055 |
+
* schema:
|
| 1056 |
+
* type: object
|
| 1057 |
+
* properties:
|
| 1058 |
+
* message:
|
| 1059 |
+
* type: string
|
| 1060 |
+
*/
|
| 1061 |
+
app.post("/company/:companyId/products/:productId/inventory", async (req, res, next) => {
|
| 1062 |
+
try {
|
| 1063 |
+
const { companyId, productId } = req.params;
|
| 1064 |
+
const { location_id, mrp = 999, selling_price = 499, id, seller_identifier } = req.body;
|
| 1065 |
+
const client = await initClient(companyId);
|
| 1066 |
+
let product = await client.catalog.getProduct({
|
| 1067 |
+
itemId: productId
|
| 1068 |
+
});
|
| 1069 |
+
let inv = await client.catalog.updateRealtimeInventory({
|
| 1070 |
+
itemId: product.data.uid,
|
| 1071 |
+
sellerIdentifier: seller_identifier,
|
| 1072 |
+
body: {
|
| 1073 |
+
company_id: companyId,
|
| 1074 |
+
payload: [{
|
| 1075 |
+
"seller_identifier": seller_identifier,
|
| 1076 |
+
"store_id": location_id,
|
| 1077 |
+
"price_marked": mrp,
|
| 1078 |
+
"price_effective": selling_price,
|
| 1079 |
+
"total_quantity": 10,
|
| 1080 |
+
"tags": []
|
| 1081 |
+
}]
|
| 1082 |
+
}
|
| 1083 |
+
})
|
| 1084 |
+
|
| 1085 |
+
res.json({ message: "inv created" });
|
| 1086 |
+
} catch (e) { next(e) }
|
| 1087 |
+
})
|
| 1088 |
+
|
| 1089 |
+
|
| 1090 |
+
/**
|
| 1091 |
+
* @swagger
|
| 1092 |
+
* /company/{companyId}/sales_channel:
|
| 1093 |
+
* post:
|
| 1094 |
+
* operationId: addSalesChannel
|
| 1095 |
+
* summary: Create a sales channel for a given company
|
| 1096 |
+
* description: This endpoint creates a new sales channel for the specified company.
|
| 1097 |
+
* tags:
|
| 1098 |
+
* - Sales Channel
|
| 1099 |
* parameters:
|
| 1100 |
+
* - in: path
|
| 1101 |
* name: companyId
|
| 1102 |
* required: true
|
| 1103 |
* schema:
|
| 1104 |
* type: string
|
| 1105 |
+
* description: The ID of the company
|
| 1106 |
+
* requestBody:
|
| 1107 |
+
* required: true
|
| 1108 |
+
* content:
|
| 1109 |
+
* application/json:
|
| 1110 |
+
* schema:
|
| 1111 |
+
* type: object
|
| 1112 |
+
* properties:
|
| 1113 |
+
* brand_ids:
|
| 1114 |
+
* type: array
|
| 1115 |
+
* items:
|
| 1116 |
+
* type: integer
|
| 1117 |
+
* description: Array of brand IDs to be associated with the sales channel
|
| 1118 |
+
* name:
|
| 1119 |
+
* type: string
|
| 1120 |
+
* description: Name of the sales channel
|
| 1121 |
+
* subdomain:
|
| 1122 |
+
* type: string
|
| 1123 |
+
* description: subdomain associated with the sales channel
|
| 1124 |
* responses:
|
| 1125 |
* 200:
|
| 1126 |
+
* description: Sales channel successfully created
|
| 1127 |
* content:
|
| 1128 |
* application/json:
|
| 1129 |
* schema:
|
| 1130 |
+
* type: object
|
| 1131 |
+
* properties:
|
| 1132 |
+
* message:
|
| 1133 |
+
* type: string
|
| 1134 |
+
* app:
|
| 1135 |
+
* type: object
|
| 1136 |
+
* description: Details of the created sales channel
|
| 1137 |
+
* 400:
|
| 1138 |
+
* description: Bad request
|
| 1139 |
+
* 500:
|
| 1140 |
+
* description: Internal server error
|
| 1141 |
*/
|
| 1142 |
+
|
| 1143 |
+
app.post("/company/:companyId/sales_channel", async (req, res, next) => {
|
| 1144 |
try {
|
| 1145 |
+
const { companyId } = req.params;
|
| 1146 |
+
const { brand_ids, name, subdomain } = req.body;
|
| 1147 |
const client = await initClient(companyId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1148 |
|
| 1149 |
+
let app = await client.configuration.createApplication({
|
| 1150 |
+
body: {
|
| 1151 |
+
"app": {
|
| 1152 |
+
"company_id": (1).toString(),
|
| 1153 |
+
"channel_type": "website-and-mobile-apps",
|
| 1154 |
+
"auth": {
|
| 1155 |
+
"enabled": true
|
| 1156 |
+
},
|
| 1157 |
+
"name": name,
|
| 1158 |
+
"desc": "",
|
| 1159 |
+
"mode": "live"
|
| 1160 |
+
},
|
| 1161 |
+
"configuration": {
|
| 1162 |
+
"inventory": {
|
| 1163 |
+
"brand": {
|
| 1164 |
+
"criteria": "all",
|
| 1165 |
+
"brands": []
|
| 1166 |
+
},
|
| 1167 |
+
"store": {
|
| 1168 |
+
"criteria": "filter",
|
| 1169 |
+
"rules": [
|
| 1170 |
+
{
|
| 1171 |
+
"companies": [companyId],
|
| 1172 |
+
"brands": brand_ids
|
| 1173 |
+
}
|
| 1174 |
+
],
|
| 1175 |
+
"stores": []
|
| 1176 |
+
},
|
| 1177 |
+
"image": ["standard", "substandard", "default"],
|
| 1178 |
+
"franchise_enabled": false,
|
| 1179 |
+
"out_of_stock": true
|
| 1180 |
+
},
|
| 1181 |
+
"payment": {
|
| 1182 |
+
"mode_of_payment": "ECOMM",
|
| 1183 |
+
"source": "ECOMM"
|
| 1184 |
+
},
|
| 1185 |
+
"article_assignment": {
|
| 1186 |
+
"post_order_reassignment": true,
|
| 1187 |
+
"enforced_stores": [],
|
| 1188 |
+
"rules": {
|
| 1189 |
+
"store_priority": {
|
| 1190 |
+
"enabled": false,
|
| 1191 |
+
"storetype_order": []
|
| 1192 |
+
}
|
| 1193 |
+
}
|
| 1194 |
+
}
|
| 1195 |
+
},
|
| 1196 |
+
"domain": {
|
| 1197 |
+
"name": `${subdomain}.hostx5.de`
|
| 1198 |
+
}
|
| 1199 |
+
}
|
| 1200 |
+
})
|
| 1201 |
+
|
| 1202 |
+
res.json({ message: "inv created", app });
|
| 1203 |
} catch (e) { next(e) }
|
| 1204 |
})
|
| 1205 |
|
| 1206 |
+
const chatHtml = fs.readFileSync('./chat.html', 'utf-8');
|
| 1207 |
+
|
| 1208 |
+
app.get('/', async (req, res, next) => {
|
| 1209 |
+
try {
|
| 1210 |
+
res.send(chatHtml);
|
| 1211 |
+
} catch (error) {
|
| 1212 |
+
console.error(error);
|
| 1213 |
+
res.send('Something needs to be fixed!');
|
| 1214 |
+
}
|
| 1215 |
+
});
|
| 1216 |
+
|
| 1217 |
+
app.get('/talk', async (req, res, next) => {
|
| 1218 |
+
try {
|
| 1219 |
+
res.send(chatHtml);
|
| 1220 |
+
} catch (error) {
|
| 1221 |
+
console.error(error);
|
| 1222 |
+
res.send('Something needs to be fixed!');
|
| 1223 |
+
}
|
| 1224 |
+
});
|
| 1225 |
+
|
| 1226 |
+
app.post(
|
| 1227 |
+
'/openai',
|
| 1228 |
+
async (req, res, next) => {
|
| 1229 |
+
const functions = [
|
| 1230 |
+
{
|
| 1231 |
+
"type": "function",
|
| 1232 |
+
"function": {
|
| 1233 |
+
"name": "getCompanyCreds",
|
| 1234 |
+
"description": "Retrieves credentials for a specific company based on its ID.",
|
| 1235 |
+
"parameters": {
|
| 1236 |
+
"type": "object",
|
| 1237 |
+
"properties": {
|
| 1238 |
+
"company_id": {
|
| 1239 |
+
"type": "number",
|
| 1240 |
+
"description": "Unique identifier of the company."
|
| 1241 |
+
}
|
| 1242 |
+
},
|
| 1243 |
+
"required": ["company_id"]
|
| 1244 |
+
}
|
| 1245 |
+
}
|
| 1246 |
+
},
|
| 1247 |
+
{
|
| 1248 |
+
"type": "function",
|
| 1249 |
+
"function": {
|
| 1250 |
+
"name": "createUpdateCompanyCreds",
|
| 1251 |
+
"description": "Creates or updates credentials for a company.",
|
| 1252 |
+
"parameters": {
|
| 1253 |
+
"type": "object",
|
| 1254 |
+
"properties": {
|
| 1255 |
+
"company_id": {
|
| 1256 |
+
"type": "number",
|
| 1257 |
+
"description": "Unique identifier of the company."
|
| 1258 |
+
},
|
| 1259 |
+
"clientId": {
|
| 1260 |
+
"type": "string",
|
| 1261 |
+
"description": "Client ID for authentication."
|
| 1262 |
+
},
|
| 1263 |
+
"clientSecret": {
|
| 1264 |
+
"type": "string",
|
| 1265 |
+
"description": "Client secret for authentication."
|
| 1266 |
+
}
|
| 1267 |
+
},
|
| 1268 |
+
"required": ["company_id", "clientId", "clientSecret"]
|
| 1269 |
+
}
|
| 1270 |
+
}
|
| 1271 |
+
},
|
| 1272 |
+
{
|
| 1273 |
+
"type": "function",
|
| 1274 |
+
"function": {
|
| 1275 |
+
"name": "getApplications",
|
| 1276 |
+
"description": "Retrieves a list of applications associated with a specific company ID.",
|
| 1277 |
+
"parameters": {
|
| 1278 |
+
"type": "object",
|
| 1279 |
+
"properties": {
|
| 1280 |
+
"company_id": {
|
| 1281 |
+
"type": "number",
|
| 1282 |
+
"description": "Unique identifier of the company."
|
| 1283 |
+
}
|
| 1284 |
+
},
|
| 1285 |
+
"required": ["company_id"]
|
| 1286 |
+
}
|
| 1287 |
+
}
|
| 1288 |
+
},
|
| 1289 |
+
{
|
| 1290 |
+
"type": "function",
|
| 1291 |
+
"function": {
|
| 1292 |
+
"name": "createBrand",
|
| 1293 |
+
"description": "Creates a new brand under a specific company.",
|
| 1294 |
+
"parameters": {
|
| 1295 |
+
"type": "object",
|
| 1296 |
+
"properties": {
|
| 1297 |
+
"company_id": {
|
| 1298 |
+
"type": "number",
|
| 1299 |
+
"description": "Unique identifier of the company."
|
| 1300 |
+
},
|
| 1301 |
+
"name": {
|
| 1302 |
+
"type": "string",
|
| 1303 |
+
"description": "Name of the new brand."
|
| 1304 |
+
},
|
| 1305 |
+
"description": {
|
| 1306 |
+
"type": "string",
|
| 1307 |
+
"description": "Description of the new brand."
|
| 1308 |
+
},
|
| 1309 |
+
"logo": {
|
| 1310 |
+
"type": "string",
|
| 1311 |
+
"description": "URL of the brand's logo."
|
| 1312 |
+
}
|
| 1313 |
+
},
|
| 1314 |
+
"required": ["company_id", "name", "description"]
|
| 1315 |
+
}
|
| 1316 |
+
}
|
| 1317 |
+
},
|
| 1318 |
+
{
|
| 1319 |
+
"type": "function",
|
| 1320 |
+
"function": {
|
| 1321 |
+
"name": "updateBrand",
|
| 1322 |
+
"description": "Updates the details of an existing brand within a company.",
|
| 1323 |
+
"parameters": {
|
| 1324 |
+
"type": "object",
|
| 1325 |
+
"properties": {
|
| 1326 |
+
"company_id": {
|
| 1327 |
+
"type": "number",
|
| 1328 |
+
"description": "Unique identifier of the company."
|
| 1329 |
+
},
|
| 1330 |
+
"brand_id": {
|
| 1331 |
+
"type": "string",
|
| 1332 |
+
"description": "Unique identifier of the brand to be updated."
|
| 1333 |
+
},
|
| 1334 |
+
"name": {
|
| 1335 |
+
"type": "string",
|
| 1336 |
+
"description": "New name for the brand."
|
| 1337 |
+
},
|
| 1338 |
+
"description": {
|
| 1339 |
+
"type": "string",
|
| 1340 |
+
"description": "New description for the brand."
|
| 1341 |
+
},
|
| 1342 |
+
"logo": {
|
| 1343 |
+
"type": "string",
|
| 1344 |
+
"description": "New URL for the brand's logo."
|
| 1345 |
+
},
|
| 1346 |
+
},
|
| 1347 |
+
"required": ["company_id", "brand_id", "name", "description"]
|
| 1348 |
+
}
|
| 1349 |
+
}
|
| 1350 |
+
},
|
| 1351 |
+
{
|
| 1352 |
+
"type": "function",
|
| 1353 |
+
"function": {
|
| 1354 |
+
"name": "getBrands",
|
| 1355 |
+
"description": "Retrieves a list of all brands associated with a specific company.",
|
| 1356 |
+
"parameters": {
|
| 1357 |
+
"type": "object",
|
| 1358 |
+
"properties": {
|
| 1359 |
+
"company_id": {
|
| 1360 |
+
"type": "number",
|
| 1361 |
+
"description": "Unique identifier of the company for which brands are being retrieved."
|
| 1362 |
+
}
|
| 1363 |
+
},
|
| 1364 |
+
"required": ["company_id"]
|
| 1365 |
+
}
|
| 1366 |
+
}
|
| 1367 |
+
},
|
| 1368 |
+
{
|
| 1369 |
+
"type": "function",
|
| 1370 |
+
"function": {
|
| 1371 |
+
"name": "getLocations",
|
| 1372 |
+
"description": "Retrieves a list of all locations associated with a specific company.",
|
| 1373 |
+
"parameters": {
|
| 1374 |
+
"type": "object",
|
| 1375 |
+
"properties": {
|
| 1376 |
+
"company_id": {
|
| 1377 |
+
"type": "number",
|
| 1378 |
+
"description": "Unique identifier of the company for which locations are being retrieved."
|
| 1379 |
+
}
|
| 1380 |
+
},
|
| 1381 |
+
"required": ["company_id"]
|
| 1382 |
+
}
|
| 1383 |
+
}
|
| 1384 |
+
},
|
| 1385 |
+
{
|
| 1386 |
+
"type": "function",
|
| 1387 |
+
"function": {
|
| 1388 |
+
"name": "createLocation",
|
| 1389 |
+
"description": "Creates a new location for a specified company.",
|
| 1390 |
+
"parameters": {
|
| 1391 |
+
"type": "object",
|
| 1392 |
+
"properties": {
|
| 1393 |
+
"company_id": {
|
| 1394 |
+
"type": "number",
|
| 1395 |
+
"description": "Unique identifier of the company."
|
| 1396 |
+
},
|
| 1397 |
+
"address1": {
|
| 1398 |
+
"type": "string",
|
| 1399 |
+
"description": "Primary address line of the new location."
|
| 1400 |
+
},
|
| 1401 |
+
"address2": {
|
| 1402 |
+
"type": "string",
|
| 1403 |
+
"description": "Secondary address line of the new location."
|
| 1404 |
+
},
|
| 1405 |
+
"pincode": {
|
| 1406 |
+
"type": "string",
|
| 1407 |
+
"description": "Postal code of the new location."
|
| 1408 |
+
},
|
| 1409 |
+
"state": {
|
| 1410 |
+
"type": "string",
|
| 1411 |
+
"description": "State where the new location is situated."
|
| 1412 |
+
},
|
| 1413 |
+
"city": {
|
| 1414 |
+
"type": "string",
|
| 1415 |
+
"description": "City where the new location is situated."
|
| 1416 |
+
},
|
| 1417 |
+
"number": {
|
| 1418 |
+
"type": "string",
|
| 1419 |
+
"description": "Contact number for the new location."
|
| 1420 |
+
},
|
| 1421 |
+
"country_code": {
|
| 1422 |
+
"type": "string",
|
| 1423 |
+
"description": "Country code for the contact number."
|
| 1424 |
+
},
|
| 1425 |
+
"gst_name": {
|
| 1426 |
+
"type": "string",
|
| 1427 |
+
"description": "GST registered name associated with the new location."
|
| 1428 |
+
},
|
| 1429 |
+
"gst_no": {
|
| 1430 |
+
"type": "string",
|
| 1431 |
+
"description": "GST number associated with the new location."
|
| 1432 |
+
},
|
| 1433 |
+
"latitude": {
|
| 1434 |
+
"type": "number",
|
| 1435 |
+
"description": "Latitude coordinate for the new location."
|
| 1436 |
+
},
|
| 1437 |
+
"longitude": {
|
| 1438 |
+
"type": "number",
|
| 1439 |
+
"description": "Longitude coordinate for the new location."
|
| 1440 |
+
}
|
| 1441 |
+
},
|
| 1442 |
+
"required": ["company_id", "address1", "city", "state", "pincode", "country_code", "gst_name", "gst_no"]
|
| 1443 |
+
}
|
| 1444 |
+
}
|
| 1445 |
+
},
|
| 1446 |
+
{
|
| 1447 |
+
"type": "function",
|
| 1448 |
+
"function": {
|
| 1449 |
+
"name": "updateLocation",
|
| 1450 |
+
"description": "update a existing location for a specified company.",
|
| 1451 |
+
"parameters": {
|
| 1452 |
+
"type": "object",
|
| 1453 |
+
"properties": {
|
| 1454 |
+
"company_id": {
|
| 1455 |
+
"type": "number",
|
| 1456 |
+
"description": "Unique identifier of the company."
|
| 1457 |
+
},
|
| 1458 |
+
"location_id": {
|
| 1459 |
+
"type": "number",
|
| 1460 |
+
"description": "Unique identifier of the location."
|
| 1461 |
+
},
|
| 1462 |
+
"address1": {
|
| 1463 |
+
"type": "string",
|
| 1464 |
+
"description": "Primary address line of the new location."
|
| 1465 |
+
},
|
| 1466 |
+
"address2": {
|
| 1467 |
+
"type": "string",
|
| 1468 |
+
"description": "Secondary address line of the new location."
|
| 1469 |
+
},
|
| 1470 |
+
"pincode": {
|
| 1471 |
+
"type": "string",
|
| 1472 |
+
"description": "Postal code of the new location."
|
| 1473 |
+
},
|
| 1474 |
+
"state": {
|
| 1475 |
+
"type": "string",
|
| 1476 |
+
"description": "State where the new location is situated."
|
| 1477 |
+
},
|
| 1478 |
+
"city": {
|
| 1479 |
+
"type": "string",
|
| 1480 |
+
"description": "City where the new location is situated."
|
| 1481 |
+
},
|
| 1482 |
+
"number": {
|
| 1483 |
+
"type": "string",
|
| 1484 |
+
"description": "Contact number for the new location."
|
| 1485 |
+
},
|
| 1486 |
+
"country_code": {
|
| 1487 |
+
"type": "string",
|
| 1488 |
+
"description": "Country code for the contact number."
|
| 1489 |
+
},
|
| 1490 |
+
"gst_name": {
|
| 1491 |
+
"type": "string",
|
| 1492 |
+
"description": "GST registered name associated with the new location."
|
| 1493 |
+
},
|
| 1494 |
+
"gst_no": {
|
| 1495 |
+
"type": "string",
|
| 1496 |
+
"description": "GST number associated with the new location."
|
| 1497 |
+
},
|
| 1498 |
+
"latitude": {
|
| 1499 |
+
"type": "number",
|
| 1500 |
+
"description": "Latitude coordinate for the new location."
|
| 1501 |
+
},
|
| 1502 |
+
"longitude": {
|
| 1503 |
+
"type": "number",
|
| 1504 |
+
"description": "Longitude coordinate for the new location."
|
| 1505 |
+
}
|
| 1506 |
+
},
|
| 1507 |
+
"required": ["company_id", 'brand_id', "address1", "city", "state", "pincode", "country_code", "gst_name", "gst_no"]
|
| 1508 |
+
}
|
| 1509 |
+
}
|
| 1510 |
+
},
|
| 1511 |
+
{
|
| 1512 |
+
"type": "function",
|
| 1513 |
+
"function": {
|
| 1514 |
+
"name": "createProduct",
|
| 1515 |
+
"description": "Creates a new product in the company's catalog.",
|
| 1516 |
+
"parameters": {
|
| 1517 |
+
"type": "object",
|
| 1518 |
+
"properties": {
|
| 1519 |
+
"name": {
|
| 1520 |
+
"type": "string",
|
| 1521 |
+
"description": "Name of the new product."
|
| 1522 |
+
},
|
| 1523 |
+
"company_id": {
|
| 1524 |
+
"type": "number",
|
| 1525 |
+
"description": "Unique identifier of the company."
|
| 1526 |
+
},
|
| 1527 |
+
"slug": {
|
| 1528 |
+
"type": "string",
|
| 1529 |
+
"description": "SEO-friendly URL segment for the product."
|
| 1530 |
+
},
|
| 1531 |
+
"seller_identifier": {
|
| 1532 |
+
"type": "string",
|
| 1533 |
+
"description": "Unique identifier for the seller of the product."
|
| 1534 |
+
},
|
| 1535 |
+
"brand_id": {
|
| 1536 |
+
"type": "number",
|
| 1537 |
+
"description": "Unique identifier of the brand associated with the product."
|
| 1538 |
+
},
|
| 1539 |
+
"mrp": {
|
| 1540 |
+
"type": "number",
|
| 1541 |
+
"description": "Maximum Retail Price of the product."
|
| 1542 |
+
},
|
| 1543 |
+
"selling_price": {
|
| 1544 |
+
"type": "number",
|
| 1545 |
+
"description": "Selling price of the product."
|
| 1546 |
+
}
|
| 1547 |
+
},
|
| 1548 |
+
"required": ["name", "company_id", "slug", "seller_identifier", "brand_id"]
|
| 1549 |
+
}
|
| 1550 |
+
}
|
| 1551 |
+
},
|
| 1552 |
+
{
|
| 1553 |
+
"type": "function",
|
| 1554 |
+
"function": {
|
| 1555 |
+
"name": "createInventory",
|
| 1556 |
+
"description": "Creates a new inventory record for a specific product in a company.",
|
| 1557 |
+
"parameters": {
|
| 1558 |
+
"type": "object",
|
| 1559 |
+
"properties": {
|
| 1560 |
+
"company_id": {
|
| 1561 |
+
"type": "number",
|
| 1562 |
+
"description": "Unique identifier of the company."
|
| 1563 |
+
},
|
| 1564 |
+
"product_id": {
|
| 1565 |
+
"type": "number",
|
| 1566 |
+
"description": "Unique identifier of the product."
|
| 1567 |
+
},
|
| 1568 |
+
"seller_identifier": {
|
| 1569 |
+
"type": "string",
|
| 1570 |
+
"description": "Unique identifier for the seller of the product."
|
| 1571 |
+
},
|
| 1572 |
+
"location_id": {
|
| 1573 |
+
"type": "number",
|
| 1574 |
+
"description": "Unique identifier of the location where the inventory is stored."
|
| 1575 |
+
},
|
| 1576 |
+
"mrp": {
|
| 1577 |
+
"type": "number",
|
| 1578 |
+
"description": "Maximum Retail Price of the product."
|
| 1579 |
+
},
|
| 1580 |
+
"selling_price": {
|
| 1581 |
+
"type": "number",
|
| 1582 |
+
"description": "Selling price of the product."
|
| 1583 |
+
}
|
| 1584 |
+
},
|
| 1585 |
+
"required": ["company_id", "product_id", "seller_identifier", "location_id"]
|
| 1586 |
+
}
|
| 1587 |
+
}
|
| 1588 |
+
},
|
| 1589 |
+
{
|
| 1590 |
+
"type": "function",
|
| 1591 |
+
"function": {
|
| 1592 |
+
"name": "createApplication",
|
| 1593 |
+
"description": "Creates a new application for a specified company.",
|
| 1594 |
+
"parameters": {
|
| 1595 |
+
"type": "object",
|
| 1596 |
+
"properties": {
|
| 1597 |
+
"company_id": {
|
| 1598 |
+
"type": "number",
|
| 1599 |
+
"description": "Unique identifier of the company."
|
| 1600 |
+
},
|
| 1601 |
+
"brand_ids": {
|
| 1602 |
+
"type": "array",
|
| 1603 |
+
"description": "Array of brand IDs associated with the application.",
|
| 1604 |
+
"items": {
|
| 1605 |
+
"type": "number"
|
| 1606 |
+
}
|
| 1607 |
+
},
|
| 1608 |
+
"name": {
|
| 1609 |
+
"type": "string",
|
| 1610 |
+
"description": "Name of the new application."
|
| 1611 |
+
},
|
| 1612 |
+
"subdomain": {
|
| 1613 |
+
"type": "string",
|
| 1614 |
+
"description": "Subdomain for the application's URL."
|
| 1615 |
+
}
|
| 1616 |
+
},
|
| 1617 |
+
"required": ["company_id", "brand_ids", "name", "subdomain"]
|
| 1618 |
+
}
|
| 1619 |
+
}
|
| 1620 |
+
}
|
| 1621 |
+
];
|
| 1622 |
+
|
| 1623 |
+
const messages = [{
|
| 1624 |
+
role: 'system',
|
| 1625 |
+
content: 'You are Jio Copilot. Introducing an all-encompassing tool, designed to seamlessly interact with TiraBeauty, JioCinema, JioMart, and JioFiber, catering to multiple facets of your digital lifestyle.\nOur JioMart integration simplifies your online shopping journey, providing a wide selection of products, from clothing and electronics to grocery items, all in one convenient location. JioMart can help to buy ingredients from recipes. Search each ingredient separately.\nWith TiraBeauty functionality, you can explore a wide array of health and beauty products, effortlessly manage your shopping cart, and share your cart selections via a QR code within the ecosystem of www.tirabeauty.com - your comprehensive ecommerce destination for beauty products and accessories.\nThe JioCinema feature takes you on an immersive streaming adventure, offering access to a diverse range of television shows, movies, sports content, and much more. Easily search and stream content to match your mood, directly from this interface.\nFinally, the JioFiber functionality empowers you to navigate through a range of lightning-fast internet and data plans from this leading broadband service provider. Explore and choose from a comprehensive list of prepaid and postpaid plans to meet your connectivity needs.\nEquip yourself with this multifunctional tool and experience a streamlined, efficient digital experience across a variety of platforms.'
|
| 1626 |
+
}];
|
| 1627 |
+
const session = req.jio_copilot_anonymous_session;
|
| 1628 |
+
if (session) {
|
| 1629 |
+
messages.push(...(await listCache.getAll(session)));
|
| 1630 |
+
}
|
| 1631 |
+
|
| 1632 |
+
const userMessage = { role: 'user', content: req.body.prompt };
|
| 1633 |
+
messages.push(userMessage);
|
| 1634 |
+
await listCache.setItems(session, userMessage);
|
| 1635 |
+
|
| 1636 |
+
res.setHeader('Cache-Control', 'no-cache');
|
| 1637 |
+
res.setHeader('Content-Type', 'text/event-stream');
|
| 1638 |
+
// res.setHeader('Access-Control-Allow-Origin', http://);
|
| 1639 |
+
res.setHeader('Connection', 'keep-alive');
|
| 1640 |
+
res.flushHeaders();
|
| 1641 |
+
|
| 1642 |
+
try {
|
| 1643 |
+
// await nextStep(session, messages, skills, functions, res);
|
| 1644 |
+
res.end();
|
| 1645 |
+
} catch (error) {
|
| 1646 |
+
if (error.code === 'context_length_exceeded') {
|
| 1647 |
+
res.write('You have exhausted the conversation limit, clear history and start again!');
|
| 1648 |
+
res.end();
|
| 1649 |
+
}
|
| 1650 |
+
res.write('There is some issue is going on. Please try again later.');
|
| 1651 |
+
res.end();
|
| 1652 |
+
}
|
| 1653 |
+
});
|
| 1654 |
+
|
| 1655 |
+
|
| 1656 |
app.use(errorHandler)
|
| 1657 |
|
| 1658 |
app.listen(port, async () => {
|
|
|
|
| 1664 |
await fs.writeFileSync("swagger.yaml", swaggerYAML, 'utf-8')
|
| 1665 |
await fs.writeFileSync("swagger.json", JSON.stringify(swaggerSpec, null, 2), 'utf-8')
|
| 1666 |
});
|
| 1667 |
+
|
| 1668 |
+
// async function nextStep(session, messages, skills, functions, res) {
|
| 1669 |
+
// const conn = new OpenAI({ apiKey: "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" });
|
| 1670 |
+
// const streamResponse = await conn
|
| 1671 |
+
// .chat.completions.create({
|
| 1672 |
+
// model: 'gpt-4-1106-preview',
|
| 1673 |
+
// messages,
|
| 1674 |
+
// functions,
|
| 1675 |
+
// function_call: 'auto',
|
| 1676 |
+
// temperature: 0.5,
|
| 1677 |
+
// stream: true
|
| 1678 |
+
// }).catch(async err => {
|
| 1679 |
+
// console.error(err);
|
| 1680 |
+
// const openAIError = new Error(err.error.message);
|
| 1681 |
+
// openAIError.code = err.error.code;
|
| 1682 |
+
// throw openAIError;
|
| 1683 |
+
// });
|
| 1684 |
+
|
| 1685 |
+
// let finalMessage = '';
|
| 1686 |
+
// const functionCall = { name: null, arguments: '' };
|
| 1687 |
+
|
| 1688 |
+
// for await (const line of streamResponse) {
|
| 1689 |
+
// const choice = line.choices[0];
|
| 1690 |
+
// if (choice.delta.function_call) {
|
| 1691 |
+
// const fc = choice.delta.function_call;
|
| 1692 |
+
// if (fc.name) {
|
| 1693 |
+
// // res.write(`Detected Function: ${fc.name}\n\n`);
|
| 1694 |
+
// // res.flush();
|
| 1695 |
+
// functionCall.name = fc.name;
|
| 1696 |
+
// }
|
| 1697 |
+
// if (fc.arguments) {
|
| 1698 |
+
// functionCall.arguments += fc.arguments;
|
| 1699 |
+
// }
|
| 1700 |
+
// } else if (!choice.finish_reason && choice.delta.content) {
|
| 1701 |
+
// finalMessage += choice.delta.content;
|
| 1702 |
+
// res.write(`${choice.delta.content}`);
|
| 1703 |
+
// res.flush();
|
| 1704 |
+
// }
|
| 1705 |
+
// }
|
| 1706 |
+
|
| 1707 |
+
// if (!functionCall.name) {
|
| 1708 |
+
// const assistantMessage = { role: 'assistant', content: finalMessage };
|
| 1709 |
+
// messages.push(assistantMessage);
|
| 1710 |
+
// await listCache.setItems(session, assistantMessage);
|
| 1711 |
+
// return;
|
| 1712 |
+
// }
|
| 1713 |
+
|
| 1714 |
+
// const functionName = functionCall.name;
|
| 1715 |
+
// const args = JSON.parse(functionCall.arguments);
|
| 1716 |
+
// if (!skills[functionName]) {
|
| 1717 |
+
// throw new Error(`No skill implemented for this function: ${functionName}`);
|
| 1718 |
+
// }
|
| 1719 |
+
|
| 1720 |
+
// // res.write(`Executing Function: ${functionName} with arguments ${JSON.stringify(args)} \n\n`);
|
| 1721 |
+
// // res.flush();
|
| 1722 |
+
// const skill = new skills[functionName]({ ...args, headers: { 'openai-ephemeral-user-id': session } });
|
| 1723 |
+
// const skillRes = await skill.performAction();
|
| 1724 |
+
// if (skillRes) {
|
| 1725 |
+
// const functionMessage = { role: 'function', name: functionName, content: JSON.stringify(skillRes) };
|
| 1726 |
+
// messages.push(functionMessage);
|
| 1727 |
+
// await listCache.setItems(session, functionMessage);
|
| 1728 |
+
// }
|
| 1729 |
+
// return nextStep(conn, session, messages, skills, functions, res);
|
| 1730 |
+
// }
|
package.json
CHANGED
|
@@ -15,6 +15,7 @@
|
|
| 15 |
"express": "^4.18.2",
|
| 16 |
"ioredis": "^5.3.2",
|
| 17 |
"js-yaml": "^4.1.0",
|
|
|
|
| 18 |
"swagger-jsdoc": "^6.2.8"
|
| 19 |
}
|
| 20 |
}
|
|
|
|
| 15 |
"express": "^4.18.2",
|
| 16 |
"ioredis": "^5.3.2",
|
| 17 |
"js-yaml": "^4.1.0",
|
| 18 |
+
"openai": "^4.20.1",
|
| 19 |
"swagger-jsdoc": "^6.2.8"
|
| 20 |
}
|
| 21 |
}
|
swagger.json
CHANGED
|
@@ -302,7 +302,7 @@
|
|
| 302 |
"name": "brandId",
|
| 303 |
"required": true,
|
| 304 |
"schema": {
|
| 305 |
-
"type": "
|
| 306 |
},
|
| 307 |
"description": "The unique identifier of the brand"
|
| 308 |
}
|
|
@@ -551,14 +551,14 @@
|
|
| 551 |
}
|
| 552 |
}
|
| 553 |
},
|
| 554 |
-
"/company/{companyId}/
|
| 555 |
-
"
|
| 556 |
-
"summary": "
|
| 557 |
-
"description": "
|
|
|
|
| 558 |
"tags": [
|
| 559 |
-
"
|
| 560 |
],
|
| 561 |
-
"operationId": "getCompanyDepartments",
|
| 562 |
"parameters": [
|
| 563 |
{
|
| 564 |
"in": "path",
|
|
@@ -567,27 +567,73 @@
|
|
| 567 |
"schema": {
|
| 568 |
"type": "string"
|
| 569 |
},
|
| 570 |
-
"description": "
|
| 571 |
}
|
| 572 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 573 |
"responses": {
|
| 574 |
"200": {
|
| 575 |
-
"description": "
|
| 576 |
"content": {
|
| 577 |
"application/json": {
|
| 578 |
"schema": {
|
| 579 |
-
"type": "
|
| 580 |
-
"
|
| 581 |
-
"
|
| 582 |
-
|
| 583 |
-
|
| 584 |
-
|
| 585 |
-
|
| 586 |
-
|
| 587 |
-
|
| 588 |
-
|
| 589 |
-
"description": "slug or identifier of the department"
|
| 590 |
-
}
|
| 591 |
}
|
| 592 |
}
|
| 593 |
}
|
|
@@ -596,6 +642,162 @@
|
|
| 596 |
}
|
| 597 |
}
|
| 598 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 599 |
}
|
| 600 |
},
|
| 601 |
"components": {
|
|
|
|
| 302 |
"name": "brandId",
|
| 303 |
"required": true,
|
| 304 |
"schema": {
|
| 305 |
+
"type": "number"
|
| 306 |
},
|
| 307 |
"description": "The unique identifier of the brand"
|
| 308 |
}
|
|
|
|
| 551 |
}
|
| 552 |
}
|
| 553 |
},
|
| 554 |
+
"/company/{companyId}/products": {
|
| 555 |
+
"post": {
|
| 556 |
+
"summary": "Creates a new product for a given company.",
|
| 557 |
+
"description": "This endpoint creates a new product with various attributes including name, slug, pricing, and more.",
|
| 558 |
+
"operationId": "createProduct",
|
| 559 |
"tags": [
|
| 560 |
+
"Products"
|
| 561 |
],
|
|
|
|
| 562 |
"parameters": [
|
| 563 |
{
|
| 564 |
"in": "path",
|
|
|
|
| 567 |
"schema": {
|
| 568 |
"type": "string"
|
| 569 |
},
|
| 570 |
+
"description": "Unique identifier of the company."
|
| 571 |
}
|
| 572 |
],
|
| 573 |
+
"requestBody": {
|
| 574 |
+
"required": true,
|
| 575 |
+
"content": {
|
| 576 |
+
"application/json": {
|
| 577 |
+
"schema": {
|
| 578 |
+
"type": "object",
|
| 579 |
+
"required": [
|
| 580 |
+
"name",
|
| 581 |
+
"slug",
|
| 582 |
+
"seller_identifier",
|
| 583 |
+
"brand_id"
|
| 584 |
+
],
|
| 585 |
+
"properties": {
|
| 586 |
+
"name": {
|
| 587 |
+
"type": "string",
|
| 588 |
+
"description": "Name of the product."
|
| 589 |
+
},
|
| 590 |
+
"slug": {
|
| 591 |
+
"type": "string",
|
| 592 |
+
"description": "URL-friendly identifier for the product."
|
| 593 |
+
},
|
| 594 |
+
"seller_identifier": {
|
| 595 |
+
"type": "string",
|
| 596 |
+
"description": "Unique identifier for the seller."
|
| 597 |
+
},
|
| 598 |
+
"brand_id": {
|
| 599 |
+
"type": "string",
|
| 600 |
+
"description": "Unique identifier for the brand."
|
| 601 |
+
},
|
| 602 |
+
"location_id": {
|
| 603 |
+
"type": "string",
|
| 604 |
+
"description": "Location identifier for the product."
|
| 605 |
+
},
|
| 606 |
+
"mrp": {
|
| 607 |
+
"type": "number",
|
| 608 |
+
"default": 999,
|
| 609 |
+
"description": "Maximum retail price of the product."
|
| 610 |
+
},
|
| 611 |
+
"selling_price": {
|
| 612 |
+
"type": "number",
|
| 613 |
+
"default": 499,
|
| 614 |
+
"description": "Selling price of the product."
|
| 615 |
+
}
|
| 616 |
+
}
|
| 617 |
+
}
|
| 618 |
+
}
|
| 619 |
+
}
|
| 620 |
+
},
|
| 621 |
"responses": {
|
| 622 |
"200": {
|
| 623 |
+
"description": "Successful creation of the product.",
|
| 624 |
"content": {
|
| 625 |
"application/json": {
|
| 626 |
"schema": {
|
| 627 |
+
"type": "object",
|
| 628 |
+
"properties": {
|
| 629 |
+
"message": {
|
| 630 |
+
"type": "string"
|
| 631 |
+
},
|
| 632 |
+
"id": {
|
| 633 |
+
"type": "string"
|
| 634 |
+
},
|
| 635 |
+
"seller_identifier": {
|
| 636 |
+
"type": "string"
|
|
|
|
|
|
|
| 637 |
}
|
| 638 |
}
|
| 639 |
}
|
|
|
|
| 642 |
}
|
| 643 |
}
|
| 644 |
}
|
| 645 |
+
},
|
| 646 |
+
"/company/{companyId}/products/{productId}/inventory": {
|
| 647 |
+
"post": {
|
| 648 |
+
"summary": "Updates inventory for a specific product.",
|
| 649 |
+
"description": "This endpoint updates the inventory details for a given product, including location, pricing, and quantity.",
|
| 650 |
+
"operationId": "updateInventory",
|
| 651 |
+
"tags": [
|
| 652 |
+
"Inventory"
|
| 653 |
+
],
|
| 654 |
+
"parameters": [
|
| 655 |
+
{
|
| 656 |
+
"in": "path",
|
| 657 |
+
"name": "companyId",
|
| 658 |
+
"required": true,
|
| 659 |
+
"schema": {
|
| 660 |
+
"type": "string"
|
| 661 |
+
},
|
| 662 |
+
"description": "Unique identifier of the company."
|
| 663 |
+
},
|
| 664 |
+
{
|
| 665 |
+
"in": "path",
|
| 666 |
+
"name": "productId",
|
| 667 |
+
"required": true,
|
| 668 |
+
"schema": {
|
| 669 |
+
"type": "string"
|
| 670 |
+
},
|
| 671 |
+
"description": "Unique identifier of the product."
|
| 672 |
+
}
|
| 673 |
+
],
|
| 674 |
+
"requestBody": {
|
| 675 |
+
"required": true,
|
| 676 |
+
"content": {
|
| 677 |
+
"application/json": {
|
| 678 |
+
"schema": {
|
| 679 |
+
"type": "object",
|
| 680 |
+
"required": [
|
| 681 |
+
"location_id",
|
| 682 |
+
"seller_identifier"
|
| 683 |
+
],
|
| 684 |
+
"properties": {
|
| 685 |
+
"location_id": {
|
| 686 |
+
"type": "string",
|
| 687 |
+
"description": "Location identifier where the inventory is stored."
|
| 688 |
+
},
|
| 689 |
+
"mrp": {
|
| 690 |
+
"type": "number",
|
| 691 |
+
"default": 999,
|
| 692 |
+
"description": "Maximum retail price of the product."
|
| 693 |
+
},
|
| 694 |
+
"selling_price": {
|
| 695 |
+
"type": "number",
|
| 696 |
+
"default": 499,
|
| 697 |
+
"description": "Selling price of the product."
|
| 698 |
+
},
|
| 699 |
+
"seller_identifier": {
|
| 700 |
+
"type": "string",
|
| 701 |
+
"description": "Unique identifier for the seller."
|
| 702 |
+
}
|
| 703 |
+
}
|
| 704 |
+
}
|
| 705 |
+
}
|
| 706 |
+
}
|
| 707 |
+
},
|
| 708 |
+
"responses": {
|
| 709 |
+
"200": {
|
| 710 |
+
"description": "Successful update of inventory.",
|
| 711 |
+
"content": {
|
| 712 |
+
"application/json": {
|
| 713 |
+
"schema": {
|
| 714 |
+
"type": "object",
|
| 715 |
+
"properties": {
|
| 716 |
+
"message": {
|
| 717 |
+
"type": "string"
|
| 718 |
+
}
|
| 719 |
+
}
|
| 720 |
+
}
|
| 721 |
+
}
|
| 722 |
+
}
|
| 723 |
+
}
|
| 724 |
+
}
|
| 725 |
+
}
|
| 726 |
+
},
|
| 727 |
+
"/company/{companyId}/sales_channel": {
|
| 728 |
+
"post": {
|
| 729 |
+
"operationId": "addSalesChannel",
|
| 730 |
+
"summary": "Create a sales channel for a given company",
|
| 731 |
+
"description": "This endpoint creates a new sales channel for the specified company.",
|
| 732 |
+
"tags": [
|
| 733 |
+
"Sales Channel"
|
| 734 |
+
],
|
| 735 |
+
"parameters": [
|
| 736 |
+
{
|
| 737 |
+
"in": "path",
|
| 738 |
+
"name": "companyId",
|
| 739 |
+
"required": true,
|
| 740 |
+
"schema": {
|
| 741 |
+
"type": "string"
|
| 742 |
+
},
|
| 743 |
+
"description": "The ID of the company"
|
| 744 |
+
}
|
| 745 |
+
],
|
| 746 |
+
"requestBody": {
|
| 747 |
+
"required": true,
|
| 748 |
+
"content": {
|
| 749 |
+
"application/json": {
|
| 750 |
+
"schema": {
|
| 751 |
+
"type": "object",
|
| 752 |
+
"properties": {
|
| 753 |
+
"brand_ids": {
|
| 754 |
+
"type": "array",
|
| 755 |
+
"items": {
|
| 756 |
+
"type": "integer"
|
| 757 |
+
},
|
| 758 |
+
"description": "Array of brand IDs to be associated with the sales channel"
|
| 759 |
+
},
|
| 760 |
+
"name": {
|
| 761 |
+
"type": "string",
|
| 762 |
+
"description": "Name of the sales channel"
|
| 763 |
+
},
|
| 764 |
+
"subdomain": {
|
| 765 |
+
"type": "string",
|
| 766 |
+
"description": "subdomain associated with the sales channel"
|
| 767 |
+
}
|
| 768 |
+
}
|
| 769 |
+
}
|
| 770 |
+
}
|
| 771 |
+
}
|
| 772 |
+
},
|
| 773 |
+
"responses": {
|
| 774 |
+
"200": {
|
| 775 |
+
"description": "Sales channel successfully created",
|
| 776 |
+
"content": {
|
| 777 |
+
"application/json": {
|
| 778 |
+
"schema": {
|
| 779 |
+
"type": "object",
|
| 780 |
+
"properties": {
|
| 781 |
+
"message": {
|
| 782 |
+
"type": "string"
|
| 783 |
+
},
|
| 784 |
+
"app": {
|
| 785 |
+
"type": "object",
|
| 786 |
+
"description": "Details of the created sales channel"
|
| 787 |
+
}
|
| 788 |
+
}
|
| 789 |
+
}
|
| 790 |
+
}
|
| 791 |
+
}
|
| 792 |
+
},
|
| 793 |
+
"400": {
|
| 794 |
+
"description": "Bad request"
|
| 795 |
+
},
|
| 796 |
+
"500": {
|
| 797 |
+
"description": "Internal server error"
|
| 798 |
+
}
|
| 799 |
+
}
|
| 800 |
+
}
|
| 801 |
}
|
| 802 |
},
|
| 803 |
"components": {
|
swagger.yaml
CHANGED
|
@@ -194,7 +194,7 @@ paths:
|
|
| 194 |
name: brandId
|
| 195 |
required: true
|
| 196 |
schema:
|
| 197 |
-
type:
|
| 198 |
description: The unique identifier of the brand
|
| 199 |
requestBody:
|
| 200 |
required: true
|
|
@@ -350,36 +350,176 @@ paths:
|
|
| 350 |
application/json:
|
| 351 |
schema:
|
| 352 |
$ref: '#/components/schemas/ErrorResponse'
|
| 353 |
-
/company/{companyId}/
|
| 354 |
-
|
| 355 |
-
summary:
|
| 356 |
-
description:
|
|
|
|
|
|
|
|
|
|
| 357 |
tags:
|
| 358 |
-
-
|
| 359 |
-
operationId: getCompanyDepartments
|
| 360 |
parameters:
|
| 361 |
- in: path
|
| 362 |
name: companyId
|
| 363 |
required: true
|
| 364 |
schema:
|
| 365 |
type: string
|
| 366 |
-
description:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 367 |
responses:
|
| 368 |
'200':
|
| 369 |
-
description:
|
| 370 |
content:
|
| 371 |
application/json:
|
| 372 |
schema:
|
| 373 |
-
type:
|
| 374 |
-
|
| 375 |
-
|
| 376 |
-
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
|
| 382 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 383 |
components:
|
| 384 |
schemas:
|
| 385 |
CompanyCreds:
|
|
|
|
| 194 |
name: brandId
|
| 195 |
required: true
|
| 196 |
schema:
|
| 197 |
+
type: number
|
| 198 |
description: The unique identifier of the brand
|
| 199 |
requestBody:
|
| 200 |
required: true
|
|
|
|
| 350 |
application/json:
|
| 351 |
schema:
|
| 352 |
$ref: '#/components/schemas/ErrorResponse'
|
| 353 |
+
/company/{companyId}/products:
|
| 354 |
+
post:
|
| 355 |
+
summary: Creates a new product for a given company.
|
| 356 |
+
description: >-
|
| 357 |
+
This endpoint creates a new product with various attributes including
|
| 358 |
+
name, slug, pricing, and more.
|
| 359 |
+
operationId: createProduct
|
| 360 |
tags:
|
| 361 |
+
- Products
|
|
|
|
| 362 |
parameters:
|
| 363 |
- in: path
|
| 364 |
name: companyId
|
| 365 |
required: true
|
| 366 |
schema:
|
| 367 |
type: string
|
| 368 |
+
description: Unique identifier of the company.
|
| 369 |
+
requestBody:
|
| 370 |
+
required: true
|
| 371 |
+
content:
|
| 372 |
+
application/json:
|
| 373 |
+
schema:
|
| 374 |
+
type: object
|
| 375 |
+
required:
|
| 376 |
+
- name
|
| 377 |
+
- slug
|
| 378 |
+
- seller_identifier
|
| 379 |
+
- brand_id
|
| 380 |
+
properties:
|
| 381 |
+
name:
|
| 382 |
+
type: string
|
| 383 |
+
description: Name of the product.
|
| 384 |
+
slug:
|
| 385 |
+
type: string
|
| 386 |
+
description: URL-friendly identifier for the product.
|
| 387 |
+
seller_identifier:
|
| 388 |
+
type: string
|
| 389 |
+
description: Unique identifier for the seller.
|
| 390 |
+
brand_id:
|
| 391 |
+
type: string
|
| 392 |
+
description: Unique identifier for the brand.
|
| 393 |
+
location_id:
|
| 394 |
+
type: string
|
| 395 |
+
description: Location identifier for the product.
|
| 396 |
+
mrp:
|
| 397 |
+
type: number
|
| 398 |
+
default: 999
|
| 399 |
+
description: Maximum retail price of the product.
|
| 400 |
+
selling_price:
|
| 401 |
+
type: number
|
| 402 |
+
default: 499
|
| 403 |
+
description: Selling price of the product.
|
| 404 |
responses:
|
| 405 |
'200':
|
| 406 |
+
description: Successful creation of the product.
|
| 407 |
content:
|
| 408 |
application/json:
|
| 409 |
schema:
|
| 410 |
+
type: object
|
| 411 |
+
properties:
|
| 412 |
+
message:
|
| 413 |
+
type: string
|
| 414 |
+
id:
|
| 415 |
+
type: string
|
| 416 |
+
seller_identifier:
|
| 417 |
+
type: string
|
| 418 |
+
/company/{companyId}/products/{productId}/inventory:
|
| 419 |
+
post:
|
| 420 |
+
summary: Updates inventory for a specific product.
|
| 421 |
+
description: >-
|
| 422 |
+
This endpoint updates the inventory details for a given product,
|
| 423 |
+
including location, pricing, and quantity.
|
| 424 |
+
operationId: updateInventory
|
| 425 |
+
tags:
|
| 426 |
+
- Inventory
|
| 427 |
+
parameters:
|
| 428 |
+
- in: path
|
| 429 |
+
name: companyId
|
| 430 |
+
required: true
|
| 431 |
+
schema:
|
| 432 |
+
type: string
|
| 433 |
+
description: Unique identifier of the company.
|
| 434 |
+
- in: path
|
| 435 |
+
name: productId
|
| 436 |
+
required: true
|
| 437 |
+
schema:
|
| 438 |
+
type: string
|
| 439 |
+
description: Unique identifier of the product.
|
| 440 |
+
requestBody:
|
| 441 |
+
required: true
|
| 442 |
+
content:
|
| 443 |
+
application/json:
|
| 444 |
+
schema:
|
| 445 |
+
type: object
|
| 446 |
+
required:
|
| 447 |
+
- location_id
|
| 448 |
+
- seller_identifier
|
| 449 |
+
properties:
|
| 450 |
+
location_id:
|
| 451 |
+
type: string
|
| 452 |
+
description: Location identifier where the inventory is stored.
|
| 453 |
+
mrp:
|
| 454 |
+
type: number
|
| 455 |
+
default: 999
|
| 456 |
+
description: Maximum retail price of the product.
|
| 457 |
+
selling_price:
|
| 458 |
+
type: number
|
| 459 |
+
default: 499
|
| 460 |
+
description: Selling price of the product.
|
| 461 |
+
seller_identifier:
|
| 462 |
+
type: string
|
| 463 |
+
description: Unique identifier for the seller.
|
| 464 |
+
responses:
|
| 465 |
+
'200':
|
| 466 |
+
description: Successful update of inventory.
|
| 467 |
+
content:
|
| 468 |
+
application/json:
|
| 469 |
+
schema:
|
| 470 |
+
type: object
|
| 471 |
+
properties:
|
| 472 |
+
message:
|
| 473 |
+
type: string
|
| 474 |
+
/company/{companyId}/sales_channel:
|
| 475 |
+
post:
|
| 476 |
+
operationId: addSalesChannel
|
| 477 |
+
summary: Create a sales channel for a given company
|
| 478 |
+
description: This endpoint creates a new sales channel for the specified company.
|
| 479 |
+
tags:
|
| 480 |
+
- Sales Channel
|
| 481 |
+
parameters:
|
| 482 |
+
- in: path
|
| 483 |
+
name: companyId
|
| 484 |
+
required: true
|
| 485 |
+
schema:
|
| 486 |
+
type: string
|
| 487 |
+
description: The ID of the company
|
| 488 |
+
requestBody:
|
| 489 |
+
required: true
|
| 490 |
+
content:
|
| 491 |
+
application/json:
|
| 492 |
+
schema:
|
| 493 |
+
type: object
|
| 494 |
+
properties:
|
| 495 |
+
brand_ids:
|
| 496 |
+
type: array
|
| 497 |
+
items:
|
| 498 |
+
type: integer
|
| 499 |
+
description: Array of brand IDs to be associated with the sales channel
|
| 500 |
+
name:
|
| 501 |
+
type: string
|
| 502 |
+
description: Name of the sales channel
|
| 503 |
+
subdomain:
|
| 504 |
+
type: string
|
| 505 |
+
description: subdomain associated with the sales channel
|
| 506 |
+
responses:
|
| 507 |
+
'200':
|
| 508 |
+
description: Sales channel successfully created
|
| 509 |
+
content:
|
| 510 |
+
application/json:
|
| 511 |
+
schema:
|
| 512 |
+
type: object
|
| 513 |
+
properties:
|
| 514 |
+
message:
|
| 515 |
+
type: string
|
| 516 |
+
app:
|
| 517 |
+
type: object
|
| 518 |
+
description: Details of the created sales channel
|
| 519 |
+
'400':
|
| 520 |
+
description: Bad request
|
| 521 |
+
'500':
|
| 522 |
+
description: Internal server error
|
| 523 |
components:
|
| 524 |
schemas:
|
| 525 |
CompanyCreds:
|
utils.js
CHANGED
|
@@ -14,7 +14,7 @@ export const initClient = async (companyId) => {
|
|
| 14 |
apiKey: creds.clientId,
|
| 15 |
apiSecret: creds.clientSecret,
|
| 16 |
useAutoRenewTimer: true,
|
| 17 |
-
|
| 18 |
}
|
| 19 |
const platformConfig = new PlatformConfig(config)
|
| 20 |
let token = await redis.get(`${companyId}:client_token`)
|
|
|
|
| 14 |
apiKey: creds.clientId,
|
| 15 |
apiSecret: creds.clientSecret,
|
| 16 |
useAutoRenewTimer: true,
|
| 17 |
+
domain: "https://api.fyndx5.de"
|
| 18 |
}
|
| 19 |
const platformConfig = new PlatformConfig(config)
|
| 20 |
let token = await redis.get(`${companyId}:client_token`)
|
vercel.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": 2,
|
| 3 |
+
"builds": [
|
| 4 |
+
{
|
| 5 |
+
"src": "index.js",
|
| 6 |
+
"use": "@now/node"
|
| 7 |
+
}
|
| 8 |
+
],
|
| 9 |
+
"routes": [
|
| 10 |
+
{
|
| 11 |
+
"src": "/(.*)",
|
| 12 |
+
"dest": "index.js"
|
| 13 |
+
}
|
| 14 |
+
]
|
| 15 |
+
}
|
yarn.lock
CHANGED
|
@@ -174,11 +174,40 @@
|
|
| 174 |
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
|
| 175 |
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
|
| 176 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
"@ungap/structured-clone@^1.2.0":
|
| 178 |
version "1.2.0"
|
| 179 |
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
|
| 180 |
integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
|
| 181 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
accepts@~1.3.8:
|
| 183 |
version "1.3.8"
|
| 184 |
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
|
@@ -197,6 +226,13 @@ acorn@^8.9.0:
|
|
| 197 |
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b"
|
| 198 |
integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==
|
| 199 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
ajv@^6.12.4:
|
| 201 |
version "6.12.6"
|
| 202 |
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
|
@@ -247,6 +283,11 @@ balanced-match@^1.0.0:
|
|
| 247 |
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
| 248 |
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
| 249 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 250 |
body-parser@1.20.1:
|
| 251 |
version "1.20.1"
|
| 252 |
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
|
|
@@ -310,6 +351,11 @@ chalk@^4.0.0:
|
|
| 310 |
ansi-styles "^4.1.0"
|
| 311 |
supports-color "^7.1.0"
|
| 312 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 313 |
cluster-key-slot@^1.1.0:
|
| 314 |
version "1.1.2"
|
| 315 |
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac"
|
|
@@ -388,6 +434,11 @@ cross-spawn@^7.0.2:
|
|
| 388 |
shebang-command "^2.0.0"
|
| 389 |
which "^2.0.1"
|
| 390 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 391 |
crypto-js@^4.1.1:
|
| 392 |
version "4.2.0"
|
| 393 |
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631"
|
|
@@ -446,6 +497,14 @@ destroy@1.2.0:
|
|
| 446 |
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
|
| 447 |
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
|
| 448 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 449 |
doctrine@3.0.0, doctrine@^3.0.0:
|
| 450 |
version "3.0.0"
|
| 451 |
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
|
|
@@ -568,6 +627,11 @@ etag@~1.8.1:
|
|
| 568 |
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
| 569 |
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
|
| 570 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 571 |
express@^4.18.2:
|
| 572 |
version "4.18.2"
|
| 573 |
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
|
|
@@ -679,6 +743,11 @@ follow-redirects@^1.14.9:
|
|
| 679 |
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
|
| 680 |
integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==
|
| 681 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 682 |
form-data@^4.0.0:
|
| 683 |
version "4.0.0"
|
| 684 |
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
|
@@ -688,6 +757,14 @@ form-data@^4.0.0:
|
|
| 688 |
combined-stream "^1.0.8"
|
| 689 |
mime-types "^2.1.12"
|
| 690 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 691 |
forwarded@0.2.0:
|
| 692 |
version "0.2.0"
|
| 693 |
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
|
|
@@ -808,6 +885,13 @@ http-errors@2.0.0:
|
|
| 808 |
statuses "2.0.1"
|
| 809 |
toidentifier "1.0.1"
|
| 810 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 811 |
iconv-lite@0.4.24:
|
| 812 |
version "0.4.24"
|
| 813 |
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
|
@@ -866,6 +950,11 @@ ipaddr.js@1.9.1:
|
|
| 866 |
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
|
| 867 |
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
|
| 868 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 869 |
is-extglob@^2.1.1:
|
| 870 |
version "2.1.1"
|
| 871 |
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
|
@@ -983,6 +1072,15 @@ loglevel@^1.8.1:
|
|
| 983 |
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4"
|
| 984 |
integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==
|
| 985 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 986 |
media-typer@0.3.0:
|
| 987 |
version "0.3.0"
|
| 988 |
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
|
@@ -1032,7 +1130,7 @@ ms@2.1.2:
|
|
| 1032 |
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
| 1033 |
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
| 1034 |
|
| 1035 |
-
ms@2.1.3:
|
| 1036 |
version "2.1.3"
|
| 1037 |
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
| 1038 |
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
|
@@ -1047,6 +1145,18 @@ negotiator@0.6.3:
|
|
| 1047 |
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
| 1048 |
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
|
| 1049 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1050 |
object-inspect@^1.9.0:
|
| 1051 |
version "1.13.1"
|
| 1052 |
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2"
|
|
@@ -1066,6 +1176,21 @@ once@^1.3.0:
|
|
| 1066 |
dependencies:
|
| 1067 |
wrappy "1"
|
| 1068 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1069 |
optionator@^0.9.3:
|
| 1070 |
version "0.9.3"
|
| 1071 |
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64"
|
|
@@ -1358,6 +1483,11 @@ toidentifier@1.0.1:
|
|
| 1358 |
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
|
| 1359 |
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
|
| 1360 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1361 |
type-check@^0.4.0, type-check@~0.4.0:
|
| 1362 |
version "0.4.0"
|
| 1363 |
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
|
|
@@ -1378,6 +1508,11 @@ type-is@~1.6.18:
|
|
| 1378 |
media-typer "0.3.0"
|
| 1379 |
mime-types "~2.1.24"
|
| 1380 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1381 |
unpipe@1.0.0, unpipe@~1.0.0:
|
| 1382 |
version "1.0.0"
|
| 1383 |
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
|
@@ -1405,6 +1540,29 @@ vary@~1.1.2:
|
|
| 1405 |
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
| 1406 |
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
|
| 1407 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1408 |
which@^2.0.1:
|
| 1409 |
version "2.0.2"
|
| 1410 |
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
|
|
|
| 174 |
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
|
| 175 |
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
|
| 176 |
|
| 177 |
+
"@types/node-fetch@^2.6.4":
|
| 178 |
+
version "2.6.9"
|
| 179 |
+
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.9.tgz#15f529d247f1ede1824f7e7acdaa192d5f28071e"
|
| 180 |
+
integrity sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==
|
| 181 |
+
dependencies:
|
| 182 |
+
"@types/node" "*"
|
| 183 |
+
form-data "^4.0.0"
|
| 184 |
+
|
| 185 |
+
"@types/node@*":
|
| 186 |
+
version "20.10.4"
|
| 187 |
+
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.4.tgz#b246fd84d55d5b1b71bf51f964bd514409347198"
|
| 188 |
+
integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==
|
| 189 |
+
dependencies:
|
| 190 |
+
undici-types "~5.26.4"
|
| 191 |
+
|
| 192 |
+
"@types/node@^18.11.18":
|
| 193 |
+
version "18.19.3"
|
| 194 |
+
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.3.tgz#e4723c4cb385641d61b983f6fe0b716abd5f8fc0"
|
| 195 |
+
integrity sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==
|
| 196 |
+
dependencies:
|
| 197 |
+
undici-types "~5.26.4"
|
| 198 |
+
|
| 199 |
"@ungap/structured-clone@^1.2.0":
|
| 200 |
version "1.2.0"
|
| 201 |
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
|
| 202 |
integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
|
| 203 |
|
| 204 |
+
abort-controller@^3.0.0:
|
| 205 |
+
version "3.0.0"
|
| 206 |
+
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
|
| 207 |
+
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
|
| 208 |
+
dependencies:
|
| 209 |
+
event-target-shim "^5.0.0"
|
| 210 |
+
|
| 211 |
accepts@~1.3.8:
|
| 212 |
version "1.3.8"
|
| 213 |
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
|
|
|
| 226 |
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b"
|
| 227 |
integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==
|
| 228 |
|
| 229 |
+
agentkeepalive@^4.2.1:
|
| 230 |
+
version "4.5.0"
|
| 231 |
+
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923"
|
| 232 |
+
integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==
|
| 233 |
+
dependencies:
|
| 234 |
+
humanize-ms "^1.2.1"
|
| 235 |
+
|
| 236 |
ajv@^6.12.4:
|
| 237 |
version "6.12.6"
|
| 238 |
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
|
|
|
| 283 |
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
| 284 |
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
| 285 |
|
| 286 |
+
base-64@^0.1.0:
|
| 287 |
+
version "0.1.0"
|
| 288 |
+
resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb"
|
| 289 |
+
integrity sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==
|
| 290 |
+
|
| 291 |
body-parser@1.20.1:
|
| 292 |
version "1.20.1"
|
| 293 |
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
|
|
|
|
| 351 |
ansi-styles "^4.1.0"
|
| 352 |
supports-color "^7.1.0"
|
| 353 |
|
| 354 |
+
charenc@0.0.2:
|
| 355 |
+
version "0.0.2"
|
| 356 |
+
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
|
| 357 |
+
integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==
|
| 358 |
+
|
| 359 |
cluster-key-slot@^1.1.0:
|
| 360 |
version "1.1.2"
|
| 361 |
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac"
|
|
|
|
| 434 |
shebang-command "^2.0.0"
|
| 435 |
which "^2.0.1"
|
| 436 |
|
| 437 |
+
crypt@0.0.2:
|
| 438 |
+
version "0.0.2"
|
| 439 |
+
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
|
| 440 |
+
integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==
|
| 441 |
+
|
| 442 |
crypto-js@^4.1.1:
|
| 443 |
version "4.2.0"
|
| 444 |
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631"
|
|
|
|
| 497 |
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
|
| 498 |
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
|
| 499 |
|
| 500 |
+
digest-fetch@^1.3.0:
|
| 501 |
+
version "1.3.0"
|
| 502 |
+
resolved "https://registry.yarnpkg.com/digest-fetch/-/digest-fetch-1.3.0.tgz#898e69264d00012a23cf26e8a3e40320143fc661"
|
| 503 |
+
integrity sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==
|
| 504 |
+
dependencies:
|
| 505 |
+
base-64 "^0.1.0"
|
| 506 |
+
md5 "^2.3.0"
|
| 507 |
+
|
| 508 |
doctrine@3.0.0, doctrine@^3.0.0:
|
| 509 |
version "3.0.0"
|
| 510 |
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
|
|
|
|
| 627 |
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
| 628 |
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
|
| 629 |
|
| 630 |
+
event-target-shim@^5.0.0:
|
| 631 |
+
version "5.0.1"
|
| 632 |
+
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
|
| 633 |
+
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
|
| 634 |
+
|
| 635 |
express@^4.18.2:
|
| 636 |
version "4.18.2"
|
| 637 |
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
|
|
|
|
| 743 |
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
|
| 744 |
integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==
|
| 745 |
|
| 746 |
+
form-data-encoder@1.7.2:
|
| 747 |
+
version "1.7.2"
|
| 748 |
+
resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040"
|
| 749 |
+
integrity sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==
|
| 750 |
+
|
| 751 |
form-data@^4.0.0:
|
| 752 |
version "4.0.0"
|
| 753 |
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
|
|
|
| 757 |
combined-stream "^1.0.8"
|
| 758 |
mime-types "^2.1.12"
|
| 759 |
|
| 760 |
+
formdata-node@^4.3.2:
|
| 761 |
+
version "4.4.1"
|
| 762 |
+
resolved "https://registry.yarnpkg.com/formdata-node/-/formdata-node-4.4.1.tgz#23f6a5cb9cb55315912cbec4ff7b0f59bbd191e2"
|
| 763 |
+
integrity sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==
|
| 764 |
+
dependencies:
|
| 765 |
+
node-domexception "1.0.0"
|
| 766 |
+
web-streams-polyfill "4.0.0-beta.3"
|
| 767 |
+
|
| 768 |
forwarded@0.2.0:
|
| 769 |
version "0.2.0"
|
| 770 |
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
|
|
|
|
| 885 |
statuses "2.0.1"
|
| 886 |
toidentifier "1.0.1"
|
| 887 |
|
| 888 |
+
humanize-ms@^1.2.1:
|
| 889 |
+
version "1.2.1"
|
| 890 |
+
resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed"
|
| 891 |
+
integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==
|
| 892 |
+
dependencies:
|
| 893 |
+
ms "^2.0.0"
|
| 894 |
+
|
| 895 |
iconv-lite@0.4.24:
|
| 896 |
version "0.4.24"
|
| 897 |
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
|
|
|
| 950 |
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
|
| 951 |
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
|
| 952 |
|
| 953 |
+
is-buffer@~1.1.6:
|
| 954 |
+
version "1.1.6"
|
| 955 |
+
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
| 956 |
+
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
| 957 |
+
|
| 958 |
is-extglob@^2.1.1:
|
| 959 |
version "2.1.1"
|
| 960 |
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
|
|
|
| 1072 |
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4"
|
| 1073 |
integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==
|
| 1074 |
|
| 1075 |
+
md5@^2.3.0:
|
| 1076 |
+
version "2.3.0"
|
| 1077 |
+
resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
|
| 1078 |
+
integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
|
| 1079 |
+
dependencies:
|
| 1080 |
+
charenc "0.0.2"
|
| 1081 |
+
crypt "0.0.2"
|
| 1082 |
+
is-buffer "~1.1.6"
|
| 1083 |
+
|
| 1084 |
media-typer@0.3.0:
|
| 1085 |
version "0.3.0"
|
| 1086 |
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
|
|
|
| 1130 |
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
| 1131 |
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
| 1132 |
|
| 1133 |
+
ms@2.1.3, ms@^2.0.0:
|
| 1134 |
version "2.1.3"
|
| 1135 |
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
| 1136 |
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
|
|
|
| 1145 |
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
| 1146 |
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
|
| 1147 |
|
| 1148 |
+
node-domexception@1.0.0:
|
| 1149 |
+
version "1.0.0"
|
| 1150 |
+
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
|
| 1151 |
+
integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
|
| 1152 |
+
|
| 1153 |
+
node-fetch@^2.6.7:
|
| 1154 |
+
version "2.7.0"
|
| 1155 |
+
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
|
| 1156 |
+
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
|
| 1157 |
+
dependencies:
|
| 1158 |
+
whatwg-url "^5.0.0"
|
| 1159 |
+
|
| 1160 |
object-inspect@^1.9.0:
|
| 1161 |
version "1.13.1"
|
| 1162 |
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2"
|
|
|
|
| 1176 |
dependencies:
|
| 1177 |
wrappy "1"
|
| 1178 |
|
| 1179 |
+
openai@^4.20.1:
|
| 1180 |
+
version "4.20.1"
|
| 1181 |
+
resolved "https://registry.yarnpkg.com/openai/-/openai-4.20.1.tgz#afa0d496d125b5a0f6cebcb4b9aeabf71e00214e"
|
| 1182 |
+
integrity sha512-Dd3q8EvINfganZFtg6V36HjrMaihqRgIcKiHua4Nq9aw/PxOP48dhbsk8x5klrxajt5Lpnc1KTOG5i1S6BKAJA==
|
| 1183 |
+
dependencies:
|
| 1184 |
+
"@types/node" "^18.11.18"
|
| 1185 |
+
"@types/node-fetch" "^2.6.4"
|
| 1186 |
+
abort-controller "^3.0.0"
|
| 1187 |
+
agentkeepalive "^4.2.1"
|
| 1188 |
+
digest-fetch "^1.3.0"
|
| 1189 |
+
form-data-encoder "1.7.2"
|
| 1190 |
+
formdata-node "^4.3.2"
|
| 1191 |
+
node-fetch "^2.6.7"
|
| 1192 |
+
web-streams-polyfill "^3.2.1"
|
| 1193 |
+
|
| 1194 |
optionator@^0.9.3:
|
| 1195 |
version "0.9.3"
|
| 1196 |
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64"
|
|
|
|
| 1483 |
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
|
| 1484 |
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
|
| 1485 |
|
| 1486 |
+
tr46@~0.0.3:
|
| 1487 |
+
version "0.0.3"
|
| 1488 |
+
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
| 1489 |
+
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
|
| 1490 |
+
|
| 1491 |
type-check@^0.4.0, type-check@~0.4.0:
|
| 1492 |
version "0.4.0"
|
| 1493 |
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
|
|
|
|
| 1508 |
media-typer "0.3.0"
|
| 1509 |
mime-types "~2.1.24"
|
| 1510 |
|
| 1511 |
+
undici-types@~5.26.4:
|
| 1512 |
+
version "5.26.5"
|
| 1513 |
+
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
|
| 1514 |
+
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
| 1515 |
+
|
| 1516 |
unpipe@1.0.0, unpipe@~1.0.0:
|
| 1517 |
version "1.0.0"
|
| 1518 |
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
|
|
|
| 1540 |
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
| 1541 |
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
|
| 1542 |
|
| 1543 |
+
web-streams-polyfill@4.0.0-beta.3:
|
| 1544 |
+
version "4.0.0-beta.3"
|
| 1545 |
+
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz#2898486b74f5156095e473efe989dcf185047a38"
|
| 1546 |
+
integrity sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==
|
| 1547 |
+
|
| 1548 |
+
web-streams-polyfill@^3.2.1:
|
| 1549 |
+
version "3.2.1"
|
| 1550 |
+
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6"
|
| 1551 |
+
integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==
|
| 1552 |
+
|
| 1553 |
+
webidl-conversions@^3.0.0:
|
| 1554 |
+
version "3.0.1"
|
| 1555 |
+
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
| 1556 |
+
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
|
| 1557 |
+
|
| 1558 |
+
whatwg-url@^5.0.0:
|
| 1559 |
+
version "5.0.0"
|
| 1560 |
+
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
| 1561 |
+
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
|
| 1562 |
+
dependencies:
|
| 1563 |
+
tr46 "~0.0.3"
|
| 1564 |
+
webidl-conversions "^3.0.0"
|
| 1565 |
+
|
| 1566 |
which@^2.0.1:
|
| 1567 |
version "2.0.2"
|
| 1568 |
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|