diff --git a/.gitignore b/.gitignore index fdeae86..e0dd51f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ /yarn.lock /node_modules/ -/test/config.json \ No newline at end of file +/test/config.json + +*.js +*.d.ts diff --git a/index.js b/index.js deleted file mode 100644 index 5b9f09d..0000000 --- a/index.js +++ /dev/null @@ -1,42 +0,0 @@ -const RestClient = require('./lib/rest_client').RestClient; -const user = require('./lib/user'); -const cart = require('./lib/cart'); -const order = require('./lib/order'); -const stock = require('./lib/stock'); -const contact = require('./lib/contact'); -const wishlist = require('./lib/wishlist'); -const stockAlert = require('./lib/stock_alert'); -const newsletter = require('./lib/newsletter'); -const address = require('./lib/address'); - -const MAGENTO_API_VERSION = 'V1'; - -module.exports.Magento1Client = function (options) { - let instance = { - addMethods (key, module) { - let client = RestClient(options); - if (module) { - if (this[key]) - this[key] = Object.assign(this[key], module(client)); - else - this[key] = module(client); - } - } - }; - - options.version = MAGENTO_API_VERSION; - - let client = RestClient(options); - - instance.user = user(client); - instance.cart = cart(client); - instance.order = order(client); - instance.stock = stock(client); - instance.contact = contact(client); - instance.wishlist = wishlist(client); - instance.stockAlert = stockAlert(client); - instance.newsletter = newsletter(client); - instance.address = address(client); - - return instance; -}; diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..753eaae --- /dev/null +++ b/index.ts @@ -0,0 +1,50 @@ +import { RestClient, RestClientInstance, RestClientOptions } from "./lib/rest_client"; +import cart, { CartModule } from "./lib/cart"; +import address, { AddressModule } from "./lib/address"; +import order, { OrderModule } from "./lib/order"; +import newsletter, { NewsletterModule } from "./lib/newsletter"; +import user, { UserModule } from "./lib/user"; +import stock, { StockModule } from "./lib/stock"; +import contact, { ContactModule } from "./lib/contact"; +import wishlist, { WishlistModule } from "./lib/wishlist"; +import stockAlert, { StockAlertModule } from "./lib/stock_alert"; + +const MAGENTO_API_VERSION = 'V1'; + +interface Magento1ClientInstance { + user: UserModule + cart: CartModule + order: OrderModule + stock: StockModule + contact: ContactModule + wishlist: WishlistModule + stockAlert: StockAlertModule + newsletter: NewsletterModule + address: AddressModule + addMethods: (key: string, module: (restClient: RestClientInstance) => Record any>) => void +} + +export function Magento1Client(options: RestClientOptions): Magento1ClientInstance { + options.version = MAGENTO_API_VERSION; + let client = RestClient(options); + + return { + addMethods (key, module) { + if (module) { + if (this[key]) + this[key] = Object.assign(this[key], module(client)); + else + this[key] = module(client); + } + }, + user: user(client), + cart: cart(client), + order: order(client), + stock: stock(client), + contact: contact(client), + wishlist: wishlist(client), + stockAlert: stockAlert(client), + newsletter: newsletter(client), + address: address(client) + }; +}; diff --git a/lib/address.js b/lib/address.js deleted file mode 100644 index ef22d35..0000000 --- a/lib/address.js +++ /dev/null @@ -1,36 +0,0 @@ -module.exports = function (restClient) { - let module = {}; - let url = 'address/'; - function getResponse(data){ - if (data.code === 200){ - return data.result; - } - - return false; - } - module.list = function (customerToken) { - url += `list?token=${customerToken}` - return restClient.get(url).then((data)=> { - return getResponse(data); - }); - }, - module.update = function (customerToken, addressData) { - url += `update?token=${customerToken}` - return restClient.post(url, {address: addressData}).then((data)=> { - return getResponse(data); - }); - } - module.get = function (customerToken, addressId) { - url += `get?token=${customerToken}&addressId=${addressId}` - return restClient.get(url).then((data)=> { - return getResponse(data); - }); - } - module.delete = function (customerToken, addressData) { - url += `delete?token=${customerToken}` - return restClient.post(url, {address: addressData}).then((data)=> { - return getResponse(data); - }); - } - return module; -} diff --git a/lib/address.ts b/lib/address.ts new file mode 100644 index 0000000..9943aed --- /dev/null +++ b/lib/address.ts @@ -0,0 +1,57 @@ +import { getResponse, RequestResponse, CustomerToken } from "./helper"; +import { RestClientInstance } from "./rest_client"; + +interface ListCall { + (customerToken: CustomerToken): Promise +} +interface UpdateCall { + (customerToken: CustomerToken, addressData: any): Promise +} +interface GetCall { + (customerToken: CustomerToken, addressId: string|number): Promise +} +interface DeleteCall { + (customerToken: CustomerToken, addressData: any): Promise +} + +export interface AddressModule { + list: ListCall + update: UpdateCall + get: GetCall + delete: DeleteCall +} + +export default function (restClient: RestClientInstance): AddressModule { + let url = 'address/'; + + const listCall: ListCall = function (customerToken) { + url += `list?token=${customerToken}` + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + const updateCall: UpdateCall = function (customerToken, addressData) { + url += `update?token=${customerToken}` + return restClient.post(url, {address: addressData}).then((data)=> { + return getResponse(data); + }); + } + const getCall: GetCall = function (customerToken, addressId) { + url += `get?token=${customerToken}&addressId=${addressId}` + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + const deleteCall: DeleteCall = function (customerToken, addressData) { + url += `delete?token=${customerToken}` + return restClient.post(url, {address: addressData}).then((data)=> { + return getResponse(data); + }); + } + return { + list: listCall, + update: updateCall, + get: getCall, + delete: deleteCall + }; +} diff --git a/lib/cart.js b/lib/cart.js deleted file mode 100644 index 69d80bd..0000000 --- a/lib/cart.js +++ /dev/null @@ -1,82 +0,0 @@ -function isNumeric(val) { - return Number(parseFloat(val)).toString() === val; -} - -module.exports = function (restClient) { - let module = {}; - const urlPrefix = 'cart/'; - let url = urlPrefix; - function getResponse(data){ - if(data.code === 200){ - return data.result; - } - return false; - } - module.create = (customerToken) => { - url += `create?token=${customerToken}`; - return restClient.post(url).then((data)=> { - return getResponse(data); - }); - } - module.update = (customerToken, cartId, cartItem) => { - url += `update?token=${customerToken}&cartId=${cartId}`; - return restClient.post(url, { cartItem: cartItem }).then((data)=> { - return getResponse(data); - }); - } - module.applyCoupon = (customerToken, cartId, coupon) => { - url += `applyCoupon?token=${customerToken}&cartId=${cartId}&coupon=${coupon}`; - return restClient.post(url).then((data)=> { - return getResponse(data); - }); - } - module.deleteCoupon = (customerToken, cartId) => { - url += `deleteCoupon?token=${customerToken}&cartId=${cartId}`; - return restClient.post(url).then((data)=> { - return getResponse(data); - }); - } - module.delete = (customerToken, cartId, cartItem) => { - url += `delete?token=${customerToken}&cartId=${cartId}`; - return restClient.post(url, { cartItem: cartItem }).then((data)=> { - return getResponse(data); - }); - } - module.pull = (customerToken, cartId) => { - url += `pull?token=${customerToken}&cartId=${cartId}`; - return restClient.get(url).then((data)=> { - return getResponse(data); - }); - } - module.totals = (customerToken, cartId) => { - url += `totals?token=${customerToken}&cartId=${cartId}`; - return restClient.get(url).then((data)=> { - return getResponse(data); - }); - } - module.shippingInformation = (customerToken, cartId, body) => { - url += `totals?token=${customerToken}&cartId=${cartId}`; - return restClient.post(url, body).then((data)=> { - return getResponse(data); - }); - } - module.shippingMethods = (customerToken, cartId, address) => { - url += `shippingMethods?token=${customerToken}&cartId=${cartId}`; - return restClient.post(url, { address: address }).then((data)=> { - return getResponse(data); - }); - } - module.paymentMethods = (customerToken, cartId) => { - url += `paymentMethods?token=${customerToken}&cartId=${cartId}`; - return restClient.get(url).then((data)=> { - return getResponse(data); - }); - } - module.getCoupon = (customerToken, cartId) => { - url += `coupon?token=${customerToken}&cartId=${cartId}`; - return restClient.get(url).then((data)=> { - return getResponse(data); - }); - } - return module; -} diff --git a/lib/cart.ts b/lib/cart.ts new file mode 100644 index 0000000..d3f5238 --- /dev/null +++ b/lib/cart.ts @@ -0,0 +1,135 @@ +import { RestClientInstance } from "./rest_client"; +import { getResponse, RequestResponse, CustomerToken } from "./helper"; + +interface CreateCall { + (customerToken: CustomerToken): Promise +} +interface UpdateCall { + (customerToken: CustomerToken, cartId: string|number, cartItem: any): Promise +} +interface ApplyCouponCall { + (customerToken: CustomerToken, cartId: string|number, coupon: string): Promise +} +interface DeleteCouponCall { + (customerToken: CustomerToken, cartId: string|number): Promise +} +interface DeleteCall { + (customerToken: CustomerToken, cartId: string|number, cartItem: any): Promise +} +interface PullCall { + (customerToken: CustomerToken, cartId: string|number): Promise +} +interface TotalsCall { + (customerToken: CustomerToken, cartId: string|number): Promise +} +interface ShippingInformationCall { + (customerToken: CustomerToken, cartId: string|number, body: any): Promise +} +interface ShippingMethodsCall { + (customerToken: CustomerToken, cartId: string|number, address: any): Promise +} +interface PaymentMethodsCall { + (customerToken: CustomerToken, cartId: string|number): Promise +} +interface GetCouponCall { + (customerToken: CustomerToken, cartId: string|number): Promise +} + + +export interface CartModule { + create: CreateCall + update: UpdateCall + applyCoupon: ApplyCouponCall + deleteCoupon: DeleteCouponCall + delete: DeleteCall + pull: PullCall + totals: TotalsCall + shippingInformation: ShippingInformationCall + shippingMethods: ShippingMethodsCall + paymentMethods: PaymentMethodsCall + getCoupon: GetCouponCall +} + +export default function (restClient: RestClientInstance): CartModule { + let url = 'cart/'; + + const createCall: CreateCall = (customerToken: CustomerToken) => { + url += `create?token=${customerToken}`; + return restClient.post(url).then((data)=> { + return getResponse(data); + }); + } + const updateCall: UpdateCall = (customerToken: CustomerToken, cartId: string|number, cartItem: any) => { + url += `update?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url, { cartItem: cartItem }).then((data)=> { + return getResponse(data); + }); + } + const applyCouponCall: ApplyCouponCall = (customerToken: CustomerToken, cartId: string|number, coupon: string) => { + url += `applyCoupon?token=${customerToken}&cartId=${cartId}&coupon=${coupon}`; + return restClient.post(url).then((data)=> { + return getResponse(data); + }); + } + const deleteCouponCall: DeleteCouponCall = (customerToken: CustomerToken, cartId: string|number) => { + url += `deleteCoupon?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url).then((data)=> { + return getResponse(data); + }); + } + const deleteCall: DeleteCall = (customerToken: CustomerToken, cartId: string|number, cartItem: any) => { + url += `delete?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url, { cartItem: cartItem }).then((data)=> { + return getResponse(data); + }); + } + const pullCall: PullCall = (customerToken: CustomerToken, cartId: string|number) => { + url += `pull?token=${customerToken}&cartId=${cartId}`; + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + const totalsCall: TotalsCall = (customerToken: CustomerToken, cartId: string|number) => { + url += `totals?token=${customerToken}&cartId=${cartId}`; + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + const shippingInformationCall: ShippingInformationCall = (customerToken: CustomerToken, cartId: string|number, body) => { + url += `totals?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url, body).then((data)=> { + return getResponse(data); + }); + } + const shippingMethodsCall: ShippingMethodsCall = (customerToken: CustomerToken, cartId: string|number, address) => { + url += `shippingMethods?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url, { address: address }).then((data)=> { + return getResponse(data); + }); + } + const paymentMethodsCall: PaymentMethodsCall = (customerToken: CustomerToken, cartId: string|number) => { + url += `paymentMethods?token=${customerToken}&cartId=${cartId}`; + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + const getCouponCall: GetCouponCall = (customerToken: CustomerToken, cartId: string|number) => { + url += `coupon?token=${customerToken}&cartId=${cartId}`; + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + return { + create: createCall, + update: updateCall, + applyCoupon: applyCouponCall, + deleteCoupon: deleteCouponCall, + delete: deleteCall, + pull: pullCall, + totals: totalsCall, + shippingInformation: shippingInformationCall, + shippingMethods: shippingMethodsCall, + paymentMethods: paymentMethodsCall, + getCoupon: getCouponCall, + }; +} diff --git a/lib/contact.js b/lib/contact.js deleted file mode 100644 index 996698e..0000000 --- a/lib/contact.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = function (restClient) { - let module = {}; - const urlPrefix = 'contact/'; - let url = urlPrefix; - function getResponse(data){ - if(data.code === 200){ - return data.result; - } - return false; - } - module.submit = (form) => { - url += `submit`; - return restClient.post(url, {form}).then((data)=> { - return getResponse(data); - }); - }; - return module; -}; diff --git a/lib/contact.ts b/lib/contact.ts new file mode 100644 index 0000000..e215964 --- /dev/null +++ b/lib/contact.ts @@ -0,0 +1,24 @@ +import { getResponse, RequestResponse } from "./helper"; +import { RestClientInstance } from "./rest_client"; + +interface SubmitCall { + (form): Promise +} + +export interface ContactModule { + submit: SubmitCall +} + +export default function (restClient: RestClientInstance): ContactModule { + let url = 'contact/'; + + const submitCall: SubmitCall = (form) => { + url += `submit`; + return restClient.post(url, {form}).then((data)=> { + return getResponse(data); + }); + }; + return { + submit: submitCall + }; +}; diff --git a/lib/helper.ts b/lib/helper.ts new file mode 100644 index 0000000..a3902de --- /dev/null +++ b/lib/helper.ts @@ -0,0 +1,13 @@ +export type RequestResponse = any|boolean +export type CustomerToken = string + +export function getResponse(data: any): RequestResponse { + if(isResponseValid(data)){ + return data.result; + } + return false; +} + +export function isResponseValid(data: any): boolean { + return data.code === 200; +} diff --git a/lib/log.js b/lib/log.ts similarity index 93% rename from lib/log.js rename to lib/log.ts index 50c6520..e16ac1f 100644 --- a/lib/log.js +++ b/lib/log.ts @@ -16,4 +16,4 @@ var logger = new winston.Logger({ logger.info('Winston logging library initialized.'); -module.exports = logger; +export default logger; diff --git a/lib/newsletter.js b/lib/newsletter.js deleted file mode 100644 index 9c1396e..0000000 --- a/lib/newsletter.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = function (restClient) { - let module = {}; - const urlPrefix = 'newsletter/'; - let url = urlPrefix; - function getResponse(data){ - if(data.code === 200){ - return data.result; - } - return false; - } - module.subscribe = (emailAddress) => { - url += `subscribe`; - return restClient.post(url, {emailAddress: emailAddress}).then((data)=> { - return getResponse(data); - }); - }; - module.unsubscribe = (customerToken) => { - url += `unsubscribe?token=${customerToken}`; - return restClient.post(url).then((data)=> { - return getResponse(data); - }); - }; - return module; -}; diff --git a/lib/newsletter.ts b/lib/newsletter.ts new file mode 100644 index 0000000..30649fb --- /dev/null +++ b/lib/newsletter.ts @@ -0,0 +1,35 @@ +import { getResponse, RequestResponse, CustomerToken } from "./helper"; +import { RestClientInstance } from "./rest_client"; + +interface SubscribeCall { + (emailAddress: string): Promise +} +interface UnsubscribeCall { + (customerToken: CustomerToken): Promise +} + + +export interface NewsletterModule { + subscribe: SubscribeCall, + unsubscribe: UnsubscribeCall +} + +export default function (restClient: RestClientInstance): NewsletterModule { + let url = 'newsletter/'; + const subscribeCall: SubscribeCall = (emailAddress) => { + url += `subscribe`; + return restClient.post(url, {emailAddress: emailAddress}).then((data)=> { + return getResponse(data); + }); + }; + const unsubscribeCall: UnsubscribeCall = (customerToken) => { + url += `unsubscribe?token=${customerToken}`; + return restClient.post(url).then((data)=> { + return getResponse(data); + }); + }; + return { + subscribe: subscribeCall, + unsubscribe: unsubscribeCall + }; +}; diff --git a/lib/order.js b/lib/order.js deleted file mode 100644 index 023831a..0000000 --- a/lib/order.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = function (restClient) { - let module = {}; - const urlPrefix = 'order/'; - let url = urlPrefix; - function isResponseValid(data) { - return data.code === 200; - } - function getResponse(data){ - if(isResponseValid(data)){ - return data.result; - } - return false; - } - module.create = (orderData) => { - url += `create`; - return restClient.post(url, orderData).then((data)=> { - if (isResponseValid(data)) { - data.result = { - magentoOrderId: data.result, - backendOrderId: data.result, - transferedAt: new Date() - }; - } - return getResponse(data); - }); - } - return module; -} diff --git a/lib/order.ts b/lib/order.ts new file mode 100644 index 0000000..535536c --- /dev/null +++ b/lib/order.ts @@ -0,0 +1,31 @@ +import { getResponse, isResponseValid, RequestResponse } from "./helper"; +import { RestClientInstance } from "./rest_client"; + +interface CreateCall { + (oderData: any): Promise +} + +export interface OrderModule { + create: CreateCall +} + +export default function (restClient: RestClientInstance): OrderModule { + let url = 'order/'; + + const createCall:CreateCall = (orderData) => { + url += `create`; + return restClient.post(url, orderData).then((data)=> { + if (isResponseValid(data)) { + data.result = { + magentoOrderId: data.result, + backendOrderId: data.result, + transferedAt: new Date() + }; + } + return getResponse(data); + }); + } + return { + create: createCall + }; +} diff --git a/lib/rest_client.js b/lib/rest_client.js deleted file mode 100644 index 6db954c..0000000 --- a/lib/rest_client.js +++ /dev/null @@ -1,138 +0,0 @@ -'use strict'; - -const OAuth = require('oauth-1.0a'); -const request = require('request'); -const logger = require('./log'); - -module.exports.RestClient = function (options) { - let instance = {}; - - var servelrUrl = options.url; - var oauth = OAuth({ - consumer: { - public: options.consumerKey, - secret: options.consumerSecret - }, - signature_method: 'HMAC-SHA1' - }); - var token = { - public: options.accessToken, - secret: options.accessTokenSecret - }; - - function apiCall(request_data, request_token = '') { - logger.debug('Calling API endpoint: ' + request_data.method + ' ' + request_data.url + ' token: ' + request_token); - - logger.info({ - url: request_data.url, - method: request_data.method, - headers: request_token ? { 'Authorization': 'Bearer ' + request_token } : oauth.toHeader(oauth.authorize(request_data, token)), - json: true, - body: request_data.body, - }); - /* eslint no-undef: off*/ - return new Promise(function (resolve, reject) { - request({ - url: request_data.url, - method: request_data.method, - headers: request_token ? { 'Authorization': 'Bearer ' + request_token } : oauth.toHeader(oauth.authorize(request_data, token)), - json: true, - body: request_data.body, - }, function (error, response, body) { - logger.debug('Response received') - if (error) { - logger.error('Error occured: ' + error); - reject(error); - return; - } else if (!httpCallSucceeded(response)) { - let errorMessage = '' - - if (body) { - errorMessage = 'HTTP ERROR ' + body.code; - } else { - errorMessage = 'HTTP ERROR ' + response.code; - } - - if (body && body.hasOwnProperty('result')) - errorMessage = errorString(body.result, body.hasOwnProperty('parameters') ? body.parameters : {}); - - logger.error('API call failed: ' + errorMessage); - reject(errorMessage); - } - resolve(body); - }); - }); - } - - instance.consumerToken = function (login_data) { - return apiCall({ - url: createUrl('/integration/customer/token'), - method: 'POST', - body: login_data - }) - } - - function httpCallSucceeded(response) { - return response.statusCode >= 200 && response.statusCode < 300; - } - - function errorString(message, parameters) { - if (parameters === null) { - return message; - } - let parameterPlaceholder - if (parameters instanceof Array) { - for (let i = 0; i < parameters.length; i++) { - parameterPlaceholder = '%' + (i + 1).toString(); - message = message.replace(parameterPlaceholder, parameters[i]); - } - } else if (parameters instanceof Object) { - for (let key in parameters) { - parameterPlaceholder = '%' + key; - message = message.replace(parameterPlaceholder, parameters[key]); - } - } - - return message; - } - - instance.get = function (resourceUrl, request_token = '') { - const request_data = { - url: createUrl(resourceUrl), - method: 'GET' - }; - return apiCall(request_data, request_token); - } - - function createUrl(resourceUrl) { - return servelrUrl + '/' + resourceUrl; - } - - instance.post = function (resourceUrl, data, request_token = '') { - const request_data = { - url: createUrl(resourceUrl), - method: 'POST', - body: data - }; - return apiCall(request_data, request_token); - } - - instance.put = function (resourceUrl, data, request_token = '') { - const request_data = { - url: createUrl(resourceUrl), - method: 'PUT', - body: data - }; - return apiCall(request_data, request_token); - } - - instance.delete = function (resourceUrl, request_token = '') { - const request_data = { - url: createUrl(resourceUrl), - method: 'DELETE' - }; - return apiCall(request_data, request_token); - } - - return instance; -} diff --git a/lib/rest_client.ts b/lib/rest_client.ts new file mode 100644 index 0000000..a55d7f9 --- /dev/null +++ b/lib/rest_client.ts @@ -0,0 +1,195 @@ +'use strict'; + +import logger from "./log"; + +const OAuth = require('oauth-1.0a'); +const request = require('request'); + +export interface RestClientOptions { + version: string + url: string + consumerKey?: string + consumerSecret?: string + accessToken?: string + accessTokenSecret?: string + basicAuth?: { + user?: string + password?: string + enabled: boolean + } +} + +type RequestToken = string + +interface GetCall { + (resourceUrl: string, request_token?: RequestToken): Promise +} +interface PostCall { + (resourceUrl: string,data?: any, request_token?: RequestToken): Promise +} +interface PutCall { + (resourceUrl: string,data?: any, request_token?: RequestToken): Promise +} +interface DeleteCall { + (resourceUrl: string, request_token?: RequestToken): Promise +} + +interface RequestData { + url: string + method: string, + body?: any +} + +export interface RestClientInstance { + consumerToken: (login_data: any) => any + get: GetCall + post: PostCall + put: PutCall + delete: DeleteCall +} + +export const RestClient = function (options: RestClientOptions): RestClientInstance { + + const serverUrl = options.url; + let oauth = OAuth({ + consumer: { + public: options.consumerKey, + secret: options.consumerSecret + }, + signature_method: 'HMAC-SHA1' + }); + let token = { + public: options.accessToken, + secret: options.accessTokenSecret + }; + + function apiCall(request_data: RequestData, request_token: RequestToken ='') { + logger.debug('Calling API endpoint: ' + request_data.method + ' ' + request_data.url + ' token: ' + request_token); + + let requestParameter: Record = { + url: request_data.url, + method: request_data.method, + json: true, + body: request_data.body, + } + + if (options.basicAuth?.enabled) { + const { password, user } = options.basicAuth + if (password && user) { + requestParameter.auth = { + user: user, + pass: password, + sendImmediately: false + } + } + } else { + requestParameter.headers = request_token ? { 'Authorization': 'Bearer ' + request_token } : oauth.toHeader(oauth.authorize(request_data, token)) + } + + logger.info(requestParameter); + /* eslint no-undef: off*/ + return new Promise(function (resolve, reject) { + request(requestParameter, function (error, response, body) { + logger.debug('Response received') + if (error) { + logger.error('Error occured: ' + error); + reject(error); + return; + } else if (!httpCallSucceeded(response)) { + let errorMessage = '' + + if (body) { + errorMessage = 'HTTP ERROR ' + body.code; + } else { + errorMessage = 'HTTP ERROR ' + response.code; + } + + if (body && body.hasOwnProperty('result')) + errorMessage = errorString(body.result, body.hasOwnProperty('parameters') ? body.parameters : {}); + + logger.error('API call failed: ' + errorMessage); + reject(errorMessage); + } + resolve(body); + }); + }); + } + + const consumerToken = (login_data: any) => { + return apiCall({ + url: createUrl('/integration/customer/token'), + method: 'POST', + body: login_data + }) + } + + const getCall: GetCall = (resourceUrl, request_token: RequestToken ='') => { + const request_data: RequestData = { + url: createUrl(resourceUrl), + method: 'GET' + }; + return apiCall(request_data, request_token); + } + + const postCall: PostCall = (resourceUrl, data, request_token: RequestToken ='') => { + const request_data: RequestData = { + url: createUrl(resourceUrl), + method: 'POST', + body: data + }; + return apiCall(request_data, request_token); + } + + const putCall: PutCall = (resourceUrl, data, request_token: RequestToken ='') => { + const request_data: RequestData = { + url: createUrl(resourceUrl), + method: 'PUT', + body: data + }; + return apiCall(request_data, request_token); + } + + const deleteCall: DeleteCall = (resourceUrl, request_token: RequestToken ='') => { + const request_data: RequestData = { + url: createUrl(resourceUrl), + method: 'DELETE' + }; + return apiCall(request_data, request_token); + } + + function httpCallSucceeded(response: any) { + return response.statusCode >= 200 && response.statusCode < 300; + } + + function errorString(message: string, parameters: null|Array|object): string { + if (parameters === null) { + return message; + } + let parameterPlaceholder + if (parameters instanceof Array) { + for (let i = 0; i < parameters.length; i++) { + parameterPlaceholder = '%' + (i + 1).toString(); + message = message.replace(parameterPlaceholder, parameters[i]); + } + } else if (parameters instanceof Object) { + for (let key in parameters) { + parameterPlaceholder = '%' + key; + message = message.replace(parameterPlaceholder, parameters[key]); + } + } + + return message; + } + + function createUrl(resourceUrl: string) { + return serverUrl + '/' + resourceUrl; + } + + return { + consumerToken, + get: getCall, + post: postCall, + put: putCall, + delete: deleteCall + }; +} diff --git a/lib/stock.js b/lib/stock.js deleted file mode 100644 index 8cd3e95..0000000 --- a/lib/stock.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = function (restClient) { - let module = {}; - const urlPrefix = 'stock/'; - let url = urlPrefix; - function getResponse(data){ - if(data.code === 200){ - return data.result; - } - return false; - } - module.check = (sku) => { - url += `check?sku=${sku}`; - return restClient.get(url).then((data)=> { - return getResponse(data); - }); - }; - return module; -}; diff --git a/lib/stock.ts b/lib/stock.ts new file mode 100644 index 0000000..ca606e3 --- /dev/null +++ b/lib/stock.ts @@ -0,0 +1,30 @@ +import { RequestResponse } from "./helper"; +import { RestClientInstance } from "./rest_client"; + +interface CeckCall { + (sku: string|number): Promise +} + +export interface StockModule { + check: CeckCall +} + +export default function (restClient: RestClientInstance): StockModule { + const urlPrefix = 'stock/'; + let url = urlPrefix; + function getResponse(data){ + if(data.code === 200){ + return data.result; + } + return false; + } + const checkCall: CeckCall = (sku) => { + url += `check?sku=${sku}`; + return restClient.get(url).then((data) => { + return getResponse(data); + }); + }; + return { + check: checkCall + }; +}; diff --git a/lib/stock_alert.js b/lib/stock_alert.js deleted file mode 100644 index 1168ac9..0000000 --- a/lib/stock_alert.js +++ /dev/null @@ -1,32 +0,0 @@ -module.exports = function (restClient) { - let module = {}; - const urlPrefix = 'stockalert/'; - let url = urlPrefix; - function getResponse(data){ - if (data.code === 200){ - return data.result; - } - - return false; - } - module.subscribe = (customerToken, productId, emailAddress) => { - url += `add`; - - if (typeof customerToken !== 'undefined' && customerToken) { - url += `?token=${customerToken}` - } - - let alertData = { - productId: productId - } - - if (emailAddress) { - alertData.emailAddress = emailAddress - } - - return restClient.post(url, alertData).then((data)=> { - return getResponse(data); - }); - }; - return module; -}; diff --git a/lib/stock_alert.ts b/lib/stock_alert.ts new file mode 100644 index 0000000..df3bfe9 --- /dev/null +++ b/lib/stock_alert.ts @@ -0,0 +1,42 @@ +import { getResponse, RequestResponse, CustomerToken } from "./helper"; +import { RestClientInstance } from "./rest_client"; + +interface SubscribeCall { + (customerToken: CustomerToken|undefined, productId: string|number, emailAddress?: string): Promise +} + +interface AlertData { + productId: string|number + emailAddress?: string +} + +export interface StockAlertModule { + subscribe: SubscribeCall +} + +export default function (restClient: RestClientInstance): StockAlertModule { + let url = 'stockalert/'; + + const subscribeCall: SubscribeCall = (customerToken = undefined, productId, emailAddress) => { + url += `add`; + + if (typeof customerToken !== 'undefined' && customerToken) { + url += `?token=${customerToken}` + } + + let alertData: AlertData = { + productId: productId + } + + if (emailAddress) { + alertData.emailAddress = emailAddress + } + + return restClient.post(url, alertData).then((data)=> { + return getResponse(data); + }); + }; + return { + subscribe: subscribeCall + }; +}; diff --git a/lib/user.js b/lib/user.js deleted file mode 100644 index 2dc8e2c..0000000 --- a/lib/user.js +++ /dev/null @@ -1,68 +0,0 @@ -module.exports = function (restClient) { - let module = {}; - let url = 'user/'; - function getResponse(data){ - if (data.code === 200){ - return data.result; - } - - return false; - } - module.login = (userData) => { - url += 'login'; - return restClient.post(url, userData).then((data)=> { - return getResponse(data); - }); - } - module.resetPassword = function (emailData) { - url += `resetPassword`; - return restClient.post(url, {email: emailData.email}).then((data)=> { - return getResponse(data); - }); - } - module.changePassword = function (passwordData) { - url += `changePassword?token=${passwordData.token}`; - return restClient.post(url, passwordData.body).then((data)=> { - return getResponse(data); - }); - } - module.create = function (userData) { - url += `create`; - return restClient.post(url, userData).then((data)=> { - return getResponse(data); - }); - } - module.creditValue = function (customerToken) { - const getCreditUrl = `user_credit/get?token=${customerToken}` - - return restClient.get(getCreditUrl).then((data)=> { - return getResponse(data); - }); - } - module.refillCredit = function (customerToken, creditCode) { - const getCreditUrl = `user_credit/refill?token=${customerToken}` - - return restClient.post(getCreditUrl, {credit_code: creditCode}).then((data)=> { - return getResponse(data); - }); - } - module.orderHistory = function (customerToken, page, pageSize) { - url += `orderHistory?token=${customerToken}`; - return restClient.get(url, {page: page, pageSize: pageSize}).then((data)=> { - return getResponse(data); - }); - } - module.update = function (userData) { - url += `me?token=${userData.token}` - return restClient.post(url, userData.body).then((data)=> { - return getResponse(data); - }); - } - module.me = function (customerToken) { - const url = `user/me?token=${customerToken}` - return restClient.get(url).then((data)=> { - return getResponse(data); - }); - } - return module; -} diff --git a/lib/user.ts b/lib/user.ts new file mode 100644 index 0000000..b85a9b7 --- /dev/null +++ b/lib/user.ts @@ -0,0 +1,131 @@ +import { getResponse, RequestResponse, CustomerToken } from "./helper"; +import { RestClientInstance } from "./rest_client"; + +interface EmailData { + email: string +} +interface PasswordData { + token: string + body: string +} + +interface LoginCall { + (userData: any): Promise +} +interface ResetPasswordCall { + (emailData: EmailData): Promise +} +interface ChangePasswordCall { + (passwordData: PasswordData): Promise +} +interface CreateCall { + (userData: any): Promise +} +interface CreditValueCall { + (customerToken: CustomerToken): Promise +} +interface RefillCreditCall { + (customerToken: CustomerToken, creditCode: string|any): Promise +} +interface OrderHistoryCall { + (customerToken: CustomerToken, page?: string|number, pageSize?: string|number): Promise +} +interface UpdateCall { + (userData: any): Promise +} +interface MeCall { + (customerToken: CustomerToken): Promise +} + +export interface UserModule { + login :LoginCall + resetPassword :ResetPasswordCall + changePassword :ChangePasswordCall + create :CreateCall + creditValue :CreditValueCall + refillCredit :RefillCreditCall + orderHistory :OrderHistoryCall + update :UpdateCall + me :MeCall +} + +export default function (restClient: RestClientInstance): UserModule { + let url = 'user/'; + + const loginCall: LoginCall = function (userData) { + url += 'login'; + return restClient.post(url, userData).then((data)=> { + return getResponse(data); + }); + } + const resetPasswordCall: ResetPasswordCall = function (emailData) { + url += `resetPassword`; + return restClient.post(url, {email: emailData.email}).then((data)=> { + return getResponse(data); + }); + } + const changePasswordCall: ChangePasswordCall = function (passwordData) { + url += `changePassword?token=${passwordData.token}`; + return restClient.post(url, passwordData.body).then((data)=> { + return getResponse(data); + }); + } + const createCall: CreateCall = function (userData) { + url += `create`; + return restClient.post(url, userData).then((data)=> { + return getResponse(data); + }); + } + const creditValueCall: CreditValueCall = function (customerToken) { + const getCreditUrl = `user_credit/get?token=${customerToken}` + + return restClient.get(getCreditUrl).then((data)=> { + return getResponse(data); + }); + } + const refillCreditCall: RefillCreditCall = function (customerToken, creditCode) { + const getCreditUrl = `user_credit/refill?token=${customerToken}` + + return restClient.post(getCreditUrl, {credit_code: creditCode}).then((data)=> { + return getResponse(data); + }); + } + const orderHistoryCall: OrderHistoryCall = function (customerToken, page, pageSize) { + url += `orderHistory?token=${customerToken}`; + + if (page) { + url += `&page=${page}` + } + + if (pageSize) { + url += `&pageSize=${pageSize}` + } + + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + const updateCall: UpdateCall = function (userData) { + url += `me?token=${userData.token}` + return restClient.post(url, userData.body).then((data)=> { + return getResponse(data); + }); + } + const meCall: MeCall = function (customerToken) { + const url = `user/me?token=${customerToken}` + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + return { + login: loginCall, + resetPassword: resetPasswordCall, + changePassword: changePasswordCall, + create: createCall, + creditValue: creditValueCall, + refillCredit: refillCreditCall, + orderHistory: orderHistoryCall, + update: updateCall, + me: meCall, + }; +} diff --git a/lib/wishlist.js b/lib/wishlist.js deleted file mode 100644 index 50992a0..0000000 --- a/lib/wishlist.js +++ /dev/null @@ -1,36 +0,0 @@ -module.exports = function (restClient) { - let module = {}; - const urlPrefix = 'wishlist/'; - let url = urlPrefix; - function getResponse(data){ - if(data.code === 200){ - return data.result; - } - return false; - } - module.pull = (customerToken) => { - url += `pull?token=${customerToken}`; - return restClient.get(url).then((data)=> { - return getResponse(data); - }); - }; - module.update = (customerToken, wishListItem) => { - url += `update?token=${customerToken}`; - return restClient.post(url, {wishListItem: wishListItem}).then((data)=> { - return getResponse(data); - }); - }; - module.delete = (customerToken, wishListItem) => { - url += `delete?token=${customerToken}`; - return restClient.post(url, {wishListItem: wishListItem}).then((data)=> { - return getResponse(data); - }); - }; - module.moveToCart = (customerToken, cartId, wishListItem) => { - url += `moveToCart?token=${customerToken}&cartId=${cartId}`; - return restClient.post(url, {wishListItem: wishListItem}).then((data)=> { - return getResponse(data); - }); - }; - return module; -}; diff --git a/lib/wishlist.ts b/lib/wishlist.ts new file mode 100644 index 0000000..158513d --- /dev/null +++ b/lib/wishlist.ts @@ -0,0 +1,60 @@ +import { getResponse, RequestResponse, CustomerToken } from "./helper"; +import { RestClientInstance } from "./rest_client"; + +interface PullCall { + (customerToken: CustomerToken): Promise +} + +interface UpdateCall { + (customerToken: CustomerToken, wishListItem): Promise +} + +interface DeleteCall { + (customerToken: CustomerToken, wishListItem): Promise +} + +interface MoveToCartCall { + (customerToken: CustomerToken, cartId: string|number, wishListItem: any): Promise +} + +export interface WishlistModule { + pull: PullCall + update: UpdateCall + delete: DeleteCall + moveToCart: MoveToCartCall +} + +export default function (restClient: RestClientInstance): WishlistModule { + let url = 'wishlist/'; + + const pullCall: PullCall = (customerToken) => { + url += `pull?token=${customerToken}`; + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + }; + const updateCall: UpdateCall = (customerToken, wishListItem) => { + url += `update?token=${customerToken}`; + return restClient.post(url, {wishListItem: wishListItem}).then((data)=> { + return getResponse(data); + }); + }; + const deleteCall: DeleteCall = (customerToken, wishListItem) => { + url += `delete?token=${customerToken}`; + return restClient.post(url, {wishListItem: wishListItem}).then((data)=> { + return getResponse(data); + }); + }; + const moveToCartCall: MoveToCartCall = (customerToken, cartId, wishListItem) => { + url += `moveToCart?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url, {wishListItem: wishListItem}).then((data)=> { + return getResponse(data); + }); + }; + return { + pull: pullCall, + update: updateCall, + delete: deleteCall, + moveToCart: moveToCartCall, + }; +}; diff --git a/package.json b/package.json index 2859e3f..0cb648d 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,11 @@ "version": "0.1.0", "license": "MIT", "deprecated": false, + "scripts": { + "build": "tsc --build", + "prepublishOnly": "npm run build", + "prebuild": "rimraf \"lib/*.{d.ts,js}\" \"index.{d.ts,js}\"" + }, "dependencies": { "oauth-1.0a": "^1.0.1", "request": "^2.72.0", @@ -12,6 +17,12 @@ "directories": { "lib": "./lib" }, + "files": [ + "lib/*.d.ts", + "index.d.ts", + "lib/*.js", + "index.js" + ], "homepage": "https://github.com/DivanteLtd/magento1-vsbridge-client", "keywords": [ "magento1", @@ -19,5 +30,11 @@ "VsBridge", "API" ], - "main": "index.js" + "main": "index.js", + "devDependencies": { + "@types/node": "^13.13.5", + "@types/request": "^2.48.4", + "rimraf": "^3.0.2", + "typescript": "3.8.*" + } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c024785 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "es2017", + "declaration": true, + "strict": false, + "allowJs": false, + "importHelpers": false, + "module": "commonjs", + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "noLib": false, + "skipLibCheck": true, + "sourceMap": false, + "baseUrl": ".", + "lib": ["es7"] + }, + "include": [ + "lib/**/*", + "index.ts" + ] +}