Skip to content
This repository was archived by the owner on Nov 20, 2024. It is now read-only.

Commit 8ce0acf

Browse files
Merge pull request #10 from diconium/feature/release_2.2
Feature/release 2.2
2 parents 10339bb + 77b7c09 commit 8ce0acf

File tree

154 files changed

+12712
-1430
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

154 files changed

+12712
-1430
lines changed

CHANGELOG.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
[![CircleCI](https://circleci.com/gh/adobe/commerce-cif-graphql-integration-reference.svg?style=svg)](https://circleci.com/gh/adobe/commerce-cif-graphql-integration-reference)
2+
[![codecov](https://codecov.io/gh/adobe/commerce-cif-graphql-integration-reference/branch/master/graph/badge.svg)](https://codecov.io/gh/adobe/commerce-cif-graphql-integration-reference)
3+
4+
# 3rd-Party GraphQL integration with AEM Commerce and CIF on Adobe I/O Runtime
5+
6+
## 2.3 (Unreleased)
7+
8+
## 2.2 (June 11, 2021)
9+
##### ENHANCEMENTS:
10+
* Functionality for Individual Package deployments are added to store the node modules independently with respect to each module.
11+
* Added Sinon Spies for data loaders in order to test function callback handing.
12+
* Code Optimisation and improvisation on security code check
13+
14+
##### BUGFIXES:
15+
* Sonar fixes on Code smell issues.
16+
17+
18+
## 2.1 (June 3, 2021)
19+
20+
##### ENHANCEMENTS:
21+
22+
* Options.JSON is changed to options.yml to store constants
23+
* Removal of deprecated attribute category_id and cart_item_id and replaced with uid as per latest schema
24+
* Sort functionality Implementation
25+
* Code Optimization
26+
27+
28+
##### BUGFIXES:
29+
30+
* Updated Unit test Cases
31+
32+
## 2.0 (May 21, 2021)
33+
34+
##### ENHANCEMENTS:
35+
* Implementation of latest Schema on I/O Connector
36+
* Implementation of latest CIF and query API changes
37+
* Project Execution of AEM CIF - Hybris connectivity through GraphQL API and adapting rest response from Hybris
38+
* Implementation of complete commerce flow from fetching products to order generation
39+
* Revert of all previous code modifications and schema modifications done in 1.0 as Schema was upgraded and core cif components are released with latest patch.
40+
* Removal of request promise
41+
42+
##### BUGFIXES:
43+
44+
* Unit test upgrade
45+
* Introspection query changes
46+
* Hybris URL endpoint configuration management
47+
48+
## 1.0 (August 16, 2020)
49+
##### ENHANCEMENTS:
50+
* Initial Commit of Topology design and Architecture planning of I/O Connector
51+
* Project Creation of I/O Connector to connect Hybris and Adobe CIF using Magento Graphql Schema 2.3 version.
52+
* Implementation of complete commerce flow from fetching products to order generation
53+
* Schema modifications as per required input and output for different endpoints
54+
* CIF Core components modification to fetch media based URL
55+
* Schema Attribute changes for cart_item_id from Int to String as per Hybris data retrieval.
56+

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ OpenWhisk CLI must be available in your systems PATH and set up correctly to eit
6464

6565
### Configuration
6666
To be able to use this CIF connector you will need to provid some Hybris configurations to connect to your Hybris endpoint.
67-
Under [cif/common/options.json.example](cif/common/options.json.example) you will find an example json file you should use as an example.
67+
Under [cif/common/options.yml.example](cif/common/options.yml.example) you will find an example yml file you should use as an example.
6868

6969
The example file should look something like this
7070
```
@@ -80,7 +80,7 @@ The example file should look something like this
8080
}
8181
```
8282

83-
You should copy the example file to an options.json file under the same path, this will be the real file that will have your configurations.
83+
You should copy the example file to an options.yml file under the same path, this will be the real file that will have your configurations.
8484
This file is under .gitignore and should not be commited to the repository since it has client secrets.
8585

8686

@@ -92,12 +92,17 @@ $ npm install
9292
$ npm test
9393
```
9494

95+
To deploy the actions on the Adobe I/O Runtime platform, we use the [serverless](https://serverless.com/framework/docs/providers/openwhisk/) framework. The deployment of independent packages and actions is defined in each package `serverless.yml` file. To deploy everything individually, simply run:
96+
```
97+
$ npm run deploy-packages
98+
```
99+
95100
To deploy the actions on the Adobe I/O Runtime platform, we use the [serverless](https://serverless.com/framework/docs/providers/openwhisk/) framework. The deployment of packages and actions is defined in the `serverless.yml` file. To deploy everything, simply run:
96101
```
97102
$ npm run deploy
98103
```
99104

100-
This will deploy the `graphql-reference/dispatcher` and all other actions like cart, oder etc in your namespace (Complete list in serverless.yml file). The dispatcher is a web action that is accessible with the URL `https://adobeioruntime.net/api/v1/web/NAMESPACE/graphql-reference/dispatcher`. To test the GraphQL endpoint, you can for example use the `GraphiQL` plugin in the Chrome browser.
105+
This will deploy the `hybris-graphql/dispatcher` and all other actions like cart, oder etc in your namespace (Complete list in serverless.yml file). The dispatcher is a web action that is accessible with the URL `https://adobeioruntime.net/api/v1/web/NAMESPACE/graphql-reference/dispatcher`. To test the GraphQL endpoint, you can for example use the `GraphiQL` plugin in the Chrome browser.
101106

102107
### Contributing
103108

cif/cart/src/AddProductToCartLoader.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class AddProductToCartResolverLoader {
2424
*/
2525
constructor(actionParameters) {
2626
this.actionParameters = actionParameters;
27-
let loadingFunction = inputs => {
27+
const loadingFunction = inputs => {
2828
return Promise.resolve(
2929
inputs.map(input => {
3030
console.debug(`--> Fetching cart with id ${JSON.stringify(input)}`);
@@ -71,7 +71,7 @@ class AddProductToCartResolverLoader {
7171
const { cart_id, cart_items } = input;
7272
const { data } = cart_items[0];
7373

74-
let body = {
74+
const body = {
7575
product: {
7676
code: data.sku,
7777
},

cif/cart/src/ApplyCouponToCart.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,21 @@ class ApplyCouponToCart {
5050

5151
/**
5252
* get cart method call cart loader to get the cart entries
53+
* @returns {Promise} a promise return null after resolved successfully other wise return the error.
5354
*/
5455
get cart() {
5556
const { cart_id: cartId } = this.input;
5657

57-
return this.__load().then(() => {
58-
return new Cart({
59-
graphqlContext: this.graphqlContext,
60-
actionParameters: this.actionParameters,
61-
cartLoader: this.cartLoader,
62-
cartId: cartId,
63-
});
64-
});
58+
return this.__load()
59+
.then(() => {
60+
return new Cart({
61+
graphqlContext: this.graphqlContext,
62+
actionParameters: this.actionParameters,
63+
cartLoader: this.cartLoader,
64+
cartId: cartId,
65+
});
66+
})
67+
.catch(errorOutput => Promise.reject(errorOutput));
6568
}
6669
}
6770

cif/cart/src/ApplyCouponToCartLoader.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class ApplyCouponToCartLoader {
2121
* @param {Object} [actionParameters] Some optional parameters of the I/O Runtime action, like for example customerId, bearer token, query and url info.
2222
*/
2323
constructor(actionParameters) {
24-
let loadingFunction = inputs => {
24+
const loadingFunction = inputs => {
2525
return Promise.resolve(
2626
inputs.map(input => {
2727
console.debug(`--> Fetching cart with id ${JSON.stringify(input)}`);
@@ -65,7 +65,7 @@ class ApplyCouponToCartLoader {
6565

6666
const { cart_id, coupon_code } = input;
6767
const uri = `${HB_PROTOCOL}://${HB_API_HOST}${HB_API_BASE_PATH}${HB_BASESITEID}/users/${customerId}/carts/${cart_id}/vouchers?voucherId=${coupon_code}`;
68-
let body = {};
68+
const body = {};
6969
const config = {
7070
headers: {
7171
Authorization: `Bearer ${bearer}`,

cif/cart/src/Cart.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@ class Cart {
6262
*/
6363
getRegionCode(address) {
6464
let code = address !== undefined ? address.region.isocode.split('-') : '';
65-
code = code !== '' ? (code.length === 2 ? code[1] : code[0]) : '';
65+
if (code !== '') {
66+
code = code.length === 2 ? code[1] : code[0];
67+
} else {
68+
code = '';
69+
}
6670
return code;
6771
}
6872

@@ -71,7 +75,7 @@ class Cart {
7175
* @returns {[]}
7276
*/
7377
getShippingMethods(deliveryModes) {
74-
let shippingMethods = [];
78+
const shippingMethods = [];
7579
deliveryModes.map(shippingMethod => {
7680
if (shippingMethod.code !== 'pickup') {
7781
shippingMethods.push({
@@ -116,12 +120,12 @@ class Cart {
116120
deliveryModes,
117121
deliveryMode,
118122
} = data;
119-
let regionCode = this.getRegionCode(deliveryAddress);
120-
let billingRegionCode =
123+
const regionCode = this.getRegionCode(deliveryAddress);
124+
const billingRegionCode =
121125
paymentInfo !== undefined
122126
? this.getRegionCode(paymentInfo.billingAddress)
123127
: '';
124-
let availableShippingMethods =
128+
const availableShippingMethods =
125129
deliveryModes !== undefined ? this.getShippingMethods(deliveryModes) : [];
126130
const { appliedVouchers } = data;
127131
const { items } = new CartItemInterface(data.entries);

cif/cart/src/CartLoader.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@ const axios = require('axios');
2020
class CartLoader {
2121
/**
2222
* @param {Object} [actionParameters] Some optional parameters of the I/O Runtime action, like for example authentication info.
23+
* @returns {loadingFunction} -This loader loads each cart one by one, but if the 3rd party backend allows it,
24+
* it could also fetch all carts in one single request. In this case, the method must still return an Array of
25+
* carts with the same order as the keys.
26+
* @param {Array} [cartIds] is an Array of cart ids
2327
*/
2428
constructor(actionParameters) {
25-
let loadingFunction = cartIds => {
26-
/**
27-
* This loader loads each cart one by one, but if the 3rd party backend allows it,
28-
*it could also fetch all carts in one single request. In this case, the method
29-
*must still return an Array of carts with the same order as the keys.
30-
*/
29+
const loadingFunction = cartIds => {
3130
return Promise.resolve(
3231
cartIds.map(cartId => {
3332
console.debug(`--> Fetching cart with id ${cartId}`);

cif/cart/src/CreateEmptyCart.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class CreateEmptyCart {
6262
HB_PROTOCOL,
6363
HB_BASESITEID,
6464
} = actionParameters.context.settings;
65-
let uri = `${HB_PROTOCOL}://${HB_API_HOST}${HB_API_BASE_PATH}${HB_BASESITEID}/users/${customerId}/carts?fields=DEFAULT`;
65+
const uri = `${HB_PROTOCOL}://${HB_API_HOST}${HB_API_BASE_PATH}${HB_BASESITEID}/users/${customerId}/carts?fields=DEFAULT`;
6666
const config = {
6767
headers: {
6868
Authorization: `Bearer ${bearer}`,

cif/cart/src/RemoveCouponFromCart.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class RemoveCouponFromCart {
2626
* @param {String} parameters.vouchersList parameter contains the vouchersList
2727
* @param {Object} [parameters.graphqlContext] The optional GraphQL execution context passed to the resolver.
2828
* @param {Object} [parameters.actionParameters] Some optional parameters of the I/O Runtime action, like for example customerId, bearer token, query and url info.
29+
* LoaderProxy class returns a Proxy to avoid having to implement a getter for all properties.
2930
*/
3031
constructor(parameters) {
3132
this.cartId = parameters.cartId;
@@ -36,24 +37,24 @@ class RemoveCouponFromCart {
3637
parameters
3738
);
3839
this.cartLoader = new CartLoader(parameters.actionParameters);
39-
/**
40-
* This class returns a Proxy to avoid having to implement a getter for all properties.
41-
*/
4240
return new LoaderProxy(this);
4341
}
4442

4543
/**
4644
* method used to get the cart details based on the cart Id
45+
* @returns {Promise} a promise return null after resolved successfully other wise return the error.
4746
*/
4847
get cart() {
49-
return this.__load().then(() => {
50-
return new Cart({
51-
graphqlContext: this.graphqlContext,
52-
actionParameters: this.actionParameters,
53-
cartLoader: this.cartLoader,
54-
cartId: this.cartId,
55-
});
56-
});
48+
return this.__load()
49+
.then(() => {
50+
return new Cart({
51+
graphqlContext: this.graphqlContext,
52+
actionParameters: this.actionParameters,
53+
cartLoader: this.cartLoader,
54+
cartId: this.cartId,
55+
});
56+
})
57+
.catch(errorOutput => Promise.reject(errorOutput));
5758
}
5859

5960
/**

cif/cart/src/RemoveCouponFromCartLoader.js

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,17 @@ const axios = require('axios');
1919
class RemoveCouponFromCartLoader {
2020
/**
2121
* @param {Object} [actionParameters] Some optional parameters of the I/O Runtime action, like for example customerId, bearer token, query and url info.
22+
* @returns {loadingFunction} -This loader loads each cart one by one, but if the 3rd party backend allows it,
23+
* it could also fetch all carts in one single request. In this case, the method must still return an Array of
24+
* carts with the same order as the keys.
25+
* @param {Array} [cartIds] is an Array of cart ids.
2226
*/
2327

2428
constructor(actionParameters) {
2529
this.vouchersList = actionParameters.vouchersList;
2630
this.actionParameters = actionParameters.actionParameters;
27-
/**
28-
*this.actionParameters = parameters.actionParameters;
29-
*The loading function: "cartIds" is an Array of cart ids
30-
*/
31-
let loadingFunction = cartIds => {
32-
/**
33-
*This loader loads each cart one by one, but if the 3rd party backend allows it,
34-
*it could also fetch all carts in one single request. In this case, the method
35-
*must still return an Array of carts with the same order as the keys.
36-
*/
31+
32+
const loadingFunction = cartIds => {
3733
return Promise.resolve(
3834
cartIds.map(cartId => {
3935
return this._removeCouponsFromCart(
@@ -77,7 +73,7 @@ class RemoveCouponFromCartLoader {
7773
return new Promise((resolve, reject) => {
7874
vouchersList &&
7975
vouchersList.vouchers.map(({ code }) => {
80-
let uri = `${HB_PROTOCOL}://${HB_API_HOST}${HB_API_BASE_PATH}${HB_BASESITEID}/users/${customerId}/carts/${cartId}/vouchers/${code}?fields=FULL`;
76+
const uri = `${HB_PROTOCOL}://${HB_API_HOST}${HB_API_BASE_PATH}${HB_BASESITEID}/users/${customerId}/carts/${cartId}/vouchers/${code}?fields=FULL`;
8177
axios
8278
.delete(uri, {
8379
params: {

0 commit comments

Comments
 (0)