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

Sign up to get free protection for your applications and to get access to all the features.
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
- })