@things-factory/integration-sellercraft 8.0.0-beta.0 → 8.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/package.json +13 -13
  2. package/server/constants/index.ts +0 -2
  3. package/server/constants/order-status-mapping.ts +0 -28
  4. package/server/constants/platform.ts +0 -6
  5. package/server/controllers/index.ts +0 -5
  6. package/server/controllers/sellercraft/apis/add-inbound-order.ts +0 -50
  7. package/server/controllers/sellercraft/apis/echo.ts +0 -14
  8. package/server/controllers/sellercraft/apis/fetch-order-document.ts +0 -18
  9. package/server/controllers/sellercraft/apis/index.ts +0 -8
  10. package/server/controllers/sellercraft/apis/initiate-order-document.ts +0 -17
  11. package/server/controllers/sellercraft/apis/initiate-order-shipment.ts +0 -29
  12. package/server/controllers/sellercraft/apis/pack-marketplace-order.ts +0 -35
  13. package/server/controllers/sellercraft/apis/update-marketplace-order.ts +0 -14
  14. package/server/controllers/sellercraft/apis/update-product.ts +0 -21
  15. package/server/controllers/sellercraft/index.ts +0 -7
  16. package/server/controllers/sellercraft/platform-action.ts +0 -39
  17. package/server/controllers/sellercraft/sellercraft.ts +0 -109
  18. package/server/controllers/sellercraft-api/decorators.ts +0 -52
  19. package/server/controllers/sellercraft-api/index.ts +0 -51
  20. package/server/controllers/sellercraft-api/types.ts +0 -0
  21. package/server/controllers/sellercraft-channel-integration/apis/echo.ts +0 -14
  22. package/server/controllers/sellercraft-channel-integration/apis/index.ts +0 -6
  23. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.ts +0 -37
  24. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-category-attributes.ts +0 -65
  25. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-order-package.ts +0 -62
  26. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.ts +0 -92
  27. package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.ts +0 -97
  28. package/server/controllers/sellercraft-channel-integration/index.ts +0 -7
  29. package/server/controllers/sellercraft-channel-integration/platform-action.ts +0 -39
  30. package/server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.ts +0 -115
  31. package/server/controllers/sellercraft-channel-integration-api/decorators.ts +0 -45
  32. package/server/controllers/sellercraft-channel-integration-api/index.ts +0 -45
  33. package/server/controllers/sellercraft-channel-integration-api/types.ts +0 -0
  34. package/server/index.ts +0 -7
  35. package/server/middlewares/index.ts +0 -3
  36. package/server/migrations/index.ts +0 -9
  37. package/server/routers/sellercraft-router.ts +0 -326
  38. package/server/routes.ts +0 -32
  39. package/server/service/index.ts +0 -23
  40. package/server/service/marketplace-channel/index.ts +0 -6
  41. package/server/service/marketplace-channel/marketplace-channel-order-mutation.ts +0 -456
  42. package/server/service/marketplace-channel/marketplace-channel-product-mutation.ts +0 -282
  43. package/server/service/marketplace-channel/marketplace-channel.ts +0 -76
  44. package/server/service/sellercraft/index.ts +0 -6
  45. package/server/service/sellercraft/sellercraft-mutation.ts +0 -126
  46. package/server/service/sellercraft/sellercraft-query.ts +0 -43
  47. package/server/service/sellercraft/sellercraft-type.ts +0 -54
  48. package/server/service/sellercraft/sellercraft.ts +0 -96
  49. package/server/utils/tokencraft-util.ts +0 -60
  50. package/tsconfig.json +0 -9
@@ -1,65 +0,0 @@
1
- /* https://docs.sellercraft.co/docs/api-integrations/b3A6MjQzODUxMTE-ingest-channel-category-attributes */
2
-
3
- export function ingestChannelCategoryAttributes() {
4
- return {
5
- method: 'post',
6
- path: '/channel/ingest/category/attribute',
7
- denormalize(req) {
8
- let { channelAttributeKeys, scAttributeKeys } = req
9
-
10
- let channel_attribute_keys = channelAttributeKeys.map(e => {
11
- const {
12
- channelCode: channel_code,
13
- channelCountry: channel_country,
14
- nativeCategoryId: native_category_id,
15
- attributeKey: attribute_key,
16
- valueType: value_type,
17
- valueOptions: value_options,
18
- displayName: display_name,
19
- isCore: is_core,
20
- isSearchProp: is_search_prop,
21
- isOptional: is_optional
22
- } = e
23
-
24
- return {
25
- channel_code,
26
- channel_country,
27
- native_category_id,
28
- attribute_key,
29
- value_type,
30
- value_options,
31
- display_name,
32
- is_core,
33
- is_search_prop,
34
- is_optional
35
- }
36
- })
37
-
38
- let sc_attribute_keys = scAttributeKeys.map(e => {
39
- const {
40
- channelCode: channel_code,
41
- channelCountry: channel_country,
42
- attributeKey: attribute_key,
43
- displayName: display_name
44
- } = e
45
-
46
- return {
47
- channel_code,
48
- channel_country,
49
- attribute_key,
50
- display_name
51
- }
52
- })
53
-
54
- return {
55
- payload: {
56
- channel_attribute_keys,
57
- sc_attribute_keys
58
- }
59
- }
60
- },
61
- normalize(res) {
62
- return res
63
- }
64
- }
65
- }
@@ -1,62 +0,0 @@
1
- /* https://docs.sellercraft.co/docs/api-integrations/b3A6MjQzODUxMTQ-ingest-channel-order-package */
2
-
3
- export function ingestChannelOrderPackage() {
4
- return {
5
- method: 'post',
6
- path: '/channel/ingest/order/package',
7
- denormalize(req) {
8
- let {
9
- channelShopId: channel_shop_id,
10
- nativeOrderId: native_order_id,
11
- nativePackageId: native_package_id,
12
- shippingTrackingCode: shipping_tracking_code,
13
- shippingTypeValue: shipping_type_value,
14
- warehouseCode: warehouse_code,
15
- shipper,
16
- documents,
17
- shipperLastMile: shipper_last_mile,
18
- orderItemIds: order_item_ids
19
- } = req
20
-
21
- documents = documents.map(e => {
22
- const { fileTypeValue: file_type_value, mimeType: mime_type, file } = e
23
-
24
- return {
25
- file_type_value,
26
- mime_type,
27
- file
28
- }
29
- })
30
-
31
- shipper = {
32
- is_cod_supported: shipper.isCodSupported,
33
- name: shipper.name
34
- }
35
-
36
- shipper_last_mile = {
37
- is_cod_supported: shipper_last_mile.isCodSupported,
38
- name: shipper_last_mile.name
39
- }
40
-
41
- let newOrderPackage: any = {
42
- channel_shop_id,
43
- native_order_id,
44
- native_package_id: native_package_id.toString(),
45
- shipping_tracking_code,
46
- shipping_type_value,
47
- warehouse_code,
48
- shipper,
49
- documents,
50
- shipper_last_mile,
51
- order_item_ids
52
- }
53
-
54
- return {
55
- payload: { ...newOrderPackage }
56
- }
57
- },
58
- normalize(res) {
59
- return res
60
- }
61
- }
62
- }
@@ -1,92 +0,0 @@
1
- /* https://docs.sellercraft.co/docs/api-integrations/b3A6MjQzODQ4OTg-ingest-channel-order */
2
-
3
- import { ORDER_STATUS } from '../../../constants'
4
-
5
- export function ingestChannelOrder() {
6
- return {
7
- method: 'post',
8
- path: '/channel/ingest/order',
9
- denormalize(req) {
10
- const { orders } = req
11
-
12
- let newOrders = orders.map(order => {
13
- return {
14
- organisation_id: order.organisationId,
15
- channel_shop_id: order.channelShopId,
16
- native_order_id: order.id.toString(),
17
- native_order_display_id: order?.sellercraftDisplayOrderNo,
18
- ordered_at_date: new Date(order.createdAt).toISOString().slice(0, -5) + 'Z',
19
- ordered_at_time: new Date(order.createdAt).toISOString().slice(0, -5) + 'Z',
20
- updated_at_date: new Date(order.updatedAt).toISOString().slice(0, -5) + 'Z',
21
- updated_at_time: new Date(order.updatedAt).toISOString().slice(0, -5) + 'Z',
22
- customer_first_name: order.custFirstName,
23
- customer_last_name: order.custLastName,
24
- charges: order.charges.map(charge => {
25
- return {
26
- charge_type_value: charge.name,
27
- amount_gross: parseFloat(charge.grossAmount) || 0,
28
- amount_nett: parseFloat(charge.nettAmount) || 0
29
- }
30
- }),
31
- address_shipping: order?.shipAddress1 ? {
32
- first_name: order.shipFirstName,
33
- last_name: order.shipLastName,
34
- line_1: order.shipAddress1,
35
- line_2: order.shipAddress2,
36
- line_3: order.shipAddress3,
37
- line_4: order.shipAddress4,
38
- line_5: order.shipAddress5,
39
- city: order.shipCity,
40
- postal_code: order.shipPostalCode,
41
- country: order.shipCountry,
42
- phone_1: order.shipPhone1,
43
- phone_2: order.shipPhone2
44
- } : null,
45
- address_billing: {
46
- first_name: order.billFirstName,
47
- last_name: order.billLastName,
48
- line_1: order.billAddress1,
49
- line_2: order.billAddress2,
50
- line_3: order.billAddress3,
51
- line_4: order.billAddress4,
52
- line_5: order.billAddress5,
53
- city: order.billCity,
54
- postal_code: order.billPostalCode,
55
- country: order.billCountry,
56
- phone_1: order.billPhone1,
57
- phone_2: order.billPhone2
58
- },
59
- order_items: order.mappedOrderItems.map(orderItem => {
60
- return {
61
- native_item_id: orderItem.id.toString(),
62
- native_variant_id: orderItem.variationId.toString(),
63
- currency_code: orderItem.currency,
64
- ordered_at_date: new Date(order.createdAt).toISOString().slice(0, -5) + 'Z',
65
- ordered_at_time: new Date(order.createdAt).toISOString().slice(0, -5) + 'Z',
66
- updated_at_date: new Date(order.updatedAt).toISOString().slice(0, -5) + 'Z',
67
- updated_at_time: new Date(order.updatedAt).toISOString().slice(0, -5) + 'Z',
68
- sla_expires_at: orderItem?.slaExpiresAt ? new Date(orderItem.slaExpiresAt).toISOString() : null,
69
- charges: orderItem.charges.map(charge => {
70
- return {
71
- charge_type_value: charge.name,
72
- amount_gross: parseFloat(charge.grossAmount) || 0,
73
- amount_nett: parseFloat(charge.nettAmount) || 0
74
- }
75
- }),
76
- order_status_value: ORDER_STATUS[`${order.status}`]
77
- }
78
- }),
79
- seller_logistics: order?.isSOF,
80
- shipping_type: order?.shipAddress1 ? 'DROP_SHIPPING' : 'SELF_PICKUP'
81
- }
82
- })
83
-
84
- return {
85
- payload: [...newOrders]
86
- }
87
- },
88
- normalize(res) {
89
- return res
90
- }
91
- }
92
- }
@@ -1,97 +0,0 @@
1
- /* https://docs.sellercraft.co/docs/api-integrations/b3A6MTY4NjQxODU-initiate-order-shipment */
2
-
3
- export function ingestChannelProduct() {
4
- return {
5
- method: 'post',
6
- path: '/channel/ingest/product',
7
- denormalize(req) {
8
- const { products } = req
9
-
10
- let newProducts = products.map(product => {
11
- let productVariations: any[] = product.variations.map(variant => {
12
- return {
13
- seller_sku: variant.variationSku,
14
- native_variant_id: variant.variationId.toString(),
15
- label: variant.name,
16
- is_enabled: variant.isEnabled || true,
17
- is_sellable: variant.isSellable || true,
18
- is_deleted: false, // default
19
- variant_attributes: variant?.attributes
20
- ? variant?.attributes.map(attribute => {
21
- return {
22
- ...attribute,
23
- native_attribute_id: attribute?.native_attribute_id?.toString()
24
- }
25
- })
26
- : [],
27
- stock_locked: variant?.stockLocked ? variant.stockLocked : 0,
28
- native_stock_reported: variant?.stockReported ? variant.stockReported : 0,
29
- price_full: variant.fullPrice || 0,
30
- price_discounted: variant.priceDiscounted || variant.fullPrice || 0,
31
- inventory_products: variant?.inventoryProducts
32
- ? variant.inventoryProducts.map(inventoryProduct => {
33
- return {
34
- quantity: inventoryProduct.qty || 0,
35
- name: inventoryProduct.name,
36
- inventory_sku: inventoryProduct.sku,
37
- product_versions: inventoryProduct?.productVersions
38
- ? inventoryProduct.productVersions.map(productVersion => {
39
- return {
40
- label: productVersion.label,
41
- package_content: productVersion.packageContent,
42
- package_length_mm: productVersion?.packageLengthMM ? productVersion.packageLengthMM : 0,
43
- package_width_mm: productVersion?.packageWidthMM ? productVersion.packageWidthMM : 0,
44
- package_height_mm: productVersion?.packageHeightMM ? productVersion.packageHeightMM : 0,
45
- package_weight_gram: productVersion?.packageWeightGram
46
- ? productVersion.packageWeightGram
47
- : 0,
48
- stock_available: productVersion.qty || 0
49
- }
50
- })
51
- : []
52
- }
53
- })
54
- : [],
55
- extra_metadata: variant?.extraMetadata
56
- }
57
- })
58
-
59
- return {
60
- organisation_id: product.organisationId,
61
- channel_shop_id: product.channelShopId,
62
- channel_code: product.channelCode,
63
- channel_country: product.channelCountry,
64
- native_category_id: product.categoryId.toString(),
65
- native_product_id: product.productId.toString(),
66
- label: product.name,
67
- brand: product.brand || '',
68
- is_verified: product.isVerified || true,
69
- flexible_attributes:
70
- product.channelCode == 'WCM' || product.channelCode == 'MGT' || product.channelCode == 'SPF' ? true : false, // add channels that do not support category_attributes ingestion
71
- images:
72
- product?.images?.map(image => {
73
- return {
74
- file_url: image.url
75
- }
76
- }) || [],
77
- product_attributes:
78
- product?.attributes?.map(attribute => {
79
- return {
80
- ...attribute,
81
- native_attribute_id: attribute.native_attribute_id.toString()
82
- }
83
- }) || [],
84
- variants: productVariations,
85
- has_all_variants: product.channelCode == 'MGT' ? false : true
86
- }
87
- })
88
-
89
- return {
90
- payload: [...newProducts]
91
- }
92
- },
93
- normalize(res) {
94
- return res
95
- }
96
- }
97
- }
@@ -1,7 +0,0 @@
1
- import { SellercraftChannelIntegrationAPI } from '../sellercraft-channel-integration-api'
2
- import * as APIS from './apis'
3
- import { action } from './platform-action'
4
-
5
- export * from './sellercraft-channel-integration'
6
-
7
- SellercraftChannelIntegrationAPI.registerPlatform('sellercraftChannelIntegration', action, APIS)
@@ -1,39 +0,0 @@
1
- import { config } from '@things-factory/env'
2
-
3
- import { SellercraftChannelIntegration } from './sellercraft-channel-integration'
4
-
5
- const sellercraftConfig = config.get('sellercraftChannelIntegrationConfig', {})
6
- const { apiKey } = sellercraftConfig
7
-
8
- function substitute(path, obj) {
9
- var props = []
10
- var re = /{([^}]+)}/g
11
- var text
12
-
13
- while ((text = re.exec(path))) {
14
- props.push(text[1])
15
- }
16
-
17
- var result = path
18
- props.forEach(prop => {
19
- let value = obj[prop.trim()]
20
- result = result.replace(`{${prop}}`, value === undefined ? '' : value)
21
- })
22
-
23
- return result
24
- }
25
-
26
- export const action = async ({ method = 'get', path, request }) => {
27
- const client = new SellercraftChannelIntegration({ apiKey })
28
-
29
- const { resource = {}, payload = {} } = request
30
-
31
- path = substitute(path, resource)
32
-
33
- var response = await client[method](path, payload)
34
- if (response.errors) {
35
- throw response
36
- }
37
-
38
- return response
39
- }
@@ -1,115 +0,0 @@
1
- import fetch from 'node-fetch'
2
- import { v4 as uuidv4 } from 'uuid'
3
- import { createPayloadLog } from '@things-factory/integration-base'
4
-
5
- const debug = require('debug')('things-factory:integration-sellercraft:sellercraft')
6
-
7
- export type SellercraftConfig = {
8
- apiKey: string
9
- }
10
-
11
- export class SellercraftChannelIntegration {
12
- private config: SellercraftConfig
13
-
14
- constructor(config: SellercraftConfig) {
15
- this.config = {
16
- ...config
17
- }
18
- }
19
-
20
- getBaseUrl() {
21
- return `https://open.sellercraft.co/v1`
22
- }
23
-
24
- generateRequestId() {
25
- return uuidv4()
26
- }
27
-
28
- async post(path: string, data: any = {}) {
29
- const { apiKey } = this.config
30
-
31
- debug('data', data)
32
-
33
- const jsondata = JSON.stringify(data)
34
- const requestId: string = this.generateRequestId()
35
- const fullPath: string = `${this.getBaseUrl()}${path}`
36
-
37
- const response: any = await fetch(fullPath, {
38
- method: 'post',
39
- headers: {
40
- 'Content-Type': 'application/json',
41
- request_id: requestId,
42
- 'X-Api-Key': apiKey
43
- },
44
- body: jsondata
45
- })
46
-
47
- const result = await response.json()
48
- try {
49
- createPayloadLog(JSON.parse(jsondata)[0]?.channel_shop_id || requestId, fullPath, jsondata, result, {
50
- state: { domain: null }
51
- })
52
- } catch (e) {}
53
- if (response.ok) {
54
- return result
55
- } else {
56
- throw new Error(`(${response.status}) ${result.detail}`)
57
- }
58
- }
59
-
60
- async put(path: string, data: any = {}) {
61
- const { apiKey } = this.config
62
-
63
- const jsondata = JSON.stringify(data)
64
- const requestId: string = this.generateRequestId()
65
- const fullPath: string = `${this.getBaseUrl()}${path}`
66
- debug('data', data)
67
-
68
- const response: any = await fetch(fullPath, {
69
- method: 'put',
70
- headers: {
71
- 'Content-Type': 'application/json',
72
- request_id: requestId,
73
- 'x-api-key': apiKey
74
- },
75
- body: jsondata
76
- })
77
-
78
- if (response.ok) {
79
- return await response.json()
80
- } else {
81
- const result = await response.json()
82
- throw new Error(`(${response.status}) ${result.message}`)
83
- }
84
- }
85
-
86
- async get(path: string, data: any = {}) {
87
- const { apiKey } = this.config
88
-
89
- const qs = Object.entries(data)
90
- .map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
91
- .join('&')
92
-
93
- const fullPath: string = `${this.getBaseUrl()}${path}`
94
- const endpoint = `${fullPath}${qs ? '?' + qs : ''}`
95
- debug('endpoint', endpoint)
96
-
97
- const requestId: string = this.generateRequestId()
98
-
99
- const response: any = await fetch(endpoint, {
100
- method: 'get',
101
- headers: {
102
- 'Content-Type': 'application/json',
103
- request_id: requestId,
104
- 'x-api-key': apiKey
105
- }
106
- })
107
-
108
- if (response.ok) {
109
- return await response.json()
110
- } else {
111
- const result = await response.json()
112
- throw new Error(`(${response.status}) ${result.message}`)
113
- }
114
- }
115
- }
@@ -1,45 +0,0 @@
1
- import Debug from 'debug'
2
-
3
- import { Sellercraft } from '../../service'
4
-
5
- const debug = Debug('things-factory:integration-marketplace:store-api-decorator')
6
-
7
- const NOOP = v => v
8
-
9
- export const api = (target: Object, property: string, descriptor: TypedPropertyDescriptor<any>): any => {
10
- const method = descriptor.value
11
-
12
- descriptor.value = async function (store: Sellercraft, request) {
13
- const SellercraftChannelIntegrationAPI = this
14
-
15
- var { platform } = store
16
-
17
- var { action: platformAction, apis } = SellercraftChannelIntegrationAPI.getPlatform(platform)
18
-
19
- var m = apis[method.name]
20
- if (!m) {
21
- throw Error(`Sellercraft doesn't have API ${method.name}`)
22
- }
23
-
24
- var {
25
- path,
26
- method: httpMethod = 'post',
27
- denormalize = NOOP,
28
- normalize = NOOP,
29
- action = platformAction
30
- } = m.apply(this, [request])
31
-
32
- var denormalized = await denormalize(request || {}, { store })
33
- debug('request', denormalized)
34
-
35
- var response = await action.apply(this, [
36
- { store, method: httpMethod, path, request: denormalized, platformAction }
37
- ])
38
-
39
- debug('response', response)
40
-
41
- return await normalize(response, { store })
42
- }
43
-
44
- return descriptor
45
- }
@@ -1,45 +0,0 @@
1
- import { getRepository } from '@things-factory/shell'
2
-
3
- import { Sellercraft } from '../../service'
4
- import { api } from './decorators'
5
-
6
- export class SellercraftChannelIntegrationAPI {
7
- static platforms = {}
8
-
9
- static registerPlatform(name, action, apis) {
10
- SellercraftChannelIntegrationAPI.platforms[name] = {
11
- action,
12
- apis
13
- }
14
- }
15
-
16
- static getPlatform(name) {
17
- return SellercraftChannelIntegrationAPI.platforms[name]
18
- }
19
-
20
- static async getSellercraft(id) {
21
- const repository = getRepository(Sellercraft)
22
- return await repository.findOne({
23
- where: { id },
24
- relations: ['domain']
25
- })
26
- }
27
-
28
- @api
29
- static echo(sellercraft, req): any {}
30
-
31
- @api
32
- static ingestChannelCategories(sellercraft, req): any {}
33
-
34
- @api
35
- static ingestChannelCategoryAttributes(sellercraft, req): any {}
36
-
37
- @api
38
- static ingestChannelOrderPackage(sellercraft, req): any {}
39
-
40
- @api
41
- static ingestChannelOrder(sellercraft, req): any {}
42
-
43
- @api
44
- static ingestChannelProduct(sellercraft, req): any {}
45
- }
package/server/index.ts DELETED
@@ -1,7 +0,0 @@
1
- import './routes'
2
-
3
- export * from './migrations'
4
- export * from './middlewares'
5
- export * from './controllers'
6
- export * from './service'
7
- export * from './constants'
@@ -1,3 +0,0 @@
1
- export function initMiddlewares(app) {
2
- /* can add middlewares into app */
3
- }
@@ -1,9 +0,0 @@
1
- const glob = require('glob')
2
- const path = require('path')
3
-
4
- export var migrations = []
5
-
6
- glob.sync(path.resolve(__dirname, '.', '**', '*.js')).forEach(function(file) {
7
- if (file.indexOf('index.js') !== -1) return
8
- migrations = migrations.concat(Object.values(require(path.resolve(file))) || [])
9
- })