From 21c618f0603c848bfa3667dc7782d08094551e55 Mon Sep 17 00:00:00 2001 From: "Ronald A. Richardson" Date: Tue, 24 Dec 2024 15:58:20 +0800 Subject: [PATCH] christmas patches --- rollup.config.js | 54 +++++++++++++++++++++++++++---------- src/resolver.js | 43 ++++++++++++++++++++--------- src/resources/checkout.js | 57 ++++++++++++++++++++++++++++++++++++--- src/resources/customer.js | 12 +++++++++ src/storefront.js | 8 +++++- 5 files changed, 142 insertions(+), 32 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index 227fdf9..1a8d6ed 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,24 +1,22 @@ -// rollup.config.js import { terser } from 'rollup-plugin-terser'; -// import { eslint } from 'rollup-plugin-eslint'; import { nodeResolve } from '@rollup/plugin-node-resolve'; import babel from '@rollup/plugin-babel'; import pkg from './package.json'; -const input = ['src/storefront.js']; +const inputFiles = ['src/storefront.js', 'src/resolver.js']; export default [ + // Base UMD config for storefront.js { - // umd - input, + input: 'src/storefront.js', plugins: [ nodeResolve({ browser: true, modulesOnly: true, }), babel({ - babelHelpers: 'bundled', - }), + babelHelpers: 'bundled', + }), terser(), ], output: [ @@ -36,18 +34,46 @@ export default [ include: ['lib/**'], }, }, + // Additional UMD config for resolver.js { - // esm and cjs - input, + input: 'src/resolver.js', plugins: [ nodeResolve({ browser: true, modulesOnly: true, }), - babel({ - babelHelpers: 'bundled', - }), - terser() + babel({ + babelHelpers: 'bundled', + }), + terser(), + ], + output: [ + { + file: `dist/${pkg.name}/resolver.min.js`, + format: 'umd', + name: '@fleetbase/storefront/resolver', + esModule: false, + exports: 'named', + sourcemap: true, + }, + ], + watch: { + exclude: ['node_modules/**'], + include: ['lib/**'], + }, + }, + // Config for ESM and CJS + { + input: inputFiles, + plugins: [ + nodeResolve({ + browser: true, + modulesOnly: true, + }), + babel({ + babelHelpers: 'bundled', + }), + terser(), ], output: [ { @@ -63,6 +89,6 @@ export default [ sourcemap: true, }, ], - external: ['axios'] + external: ['axios'], }, ]; diff --git a/src/resolver.js b/src/resolver.js index 9cdb389..ad338bc 100644 --- a/src/resolver.js +++ b/src/resolver.js @@ -1,17 +1,34 @@ import { Product, Category, Customer, Cart, DeliveryServiceQuote, Store, StoreLocation, StoreHour, Checkout, Review } from './resources'; import { BrowserAdapter, NodeAdapter, pluralize, singularize } from '@fleetbase/sdk'; -const resources = { - Product, Category, Customer, Cart, DeliveryServiceQuote, Store, StoreLocation, StoreHour, Checkout, Review +export const resources = { + Product, + Category, + Customer, + Cart, + DeliveryServiceQuote, + Store, + StoreLocation, + StoreHour, + Checkout, + Review, }; const adapters = { BrowserAdapter, - NodeAdapter + NodeAdapter, }; +function toStudlyCase(str) { + return str + .split(/[^a-zA-Z0-9]/) // Split by non-alphanumeric characters + .filter(Boolean) // Remove empty elements + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) // Capitalize the first letter of each word + .join(''); // Join the words together without spaces +} + class Resolver { - constructor () { + constructor() { this.resources = resources; this.adapters = adapters; @@ -20,25 +37,25 @@ class Resolver { lookup(type, className) { const key = pluralize(type); - const params = [ ...arguments ].slice(2); + const classKey = toStudlyCase(className); + const params = [...arguments].slice(2); if (!this[key]) { throw new Error('Attempted to resolve invalid type'); } - if (!this[key][className]) { - throw new Error(`No ${singularize(type)} named ${className} to resolve`); + if (!this[key][classKey]) { + throw new Error(`No ${singularize(type)} named ${className} (${classKey}) to resolve`); } - return new this[key][className](...params); + return new this[key][classKey](...params); } } -const lookup = function() { +const lookup = function () { return new Resolver(...arguments); }; -export { - Resolver, - lookup -}; +export { Resolver, lookup }; + +export default Resolver; diff --git a/src/resources/checkout.js b/src/resources/checkout.js index ad10038..b735bdb 100644 --- a/src/resources/checkout.js +++ b/src/resources/checkout.js @@ -2,6 +2,31 @@ import Resource from '../resource'; import Product from './product'; import { StoreActions, isResource, Order } from '@fleetbase/sdk'; +const objectToParams = (obj = {}, prefix = null) => { + if (obj === null || obj === undefined) { + return {}; + } + + const parsed = {}; + const keys = Object.keys(obj); + + for (let index = 0; index < keys.length; index++) { + const key = keys[index]; + const value = obj[key]; + + if (key && value) { + if (prefix && typeof prefix === 'string') { + parsed[`${prefix}[${key}]`] = value; + continue; + } + + parsed[key] = value; + } + } + + return parsed; +}; + const checkoutActions = new StoreActions({ create: undefined, findAll: undefined, @@ -24,13 +49,37 @@ const checkoutActions = new StoreActions({ if (isResource(gateway)) { gateway = gateway.getAttribute('code'); } - - return this.adapter.get(`${this.namespace}/before`, { ...orderOptions, customer, cart, serviceQuote, gateway}, options); + + return this.adapter.get(`${this.namespace}/before`, { ...orderOptions, customer, cart, serviceQuote, gateway }, options); }, captureOrder: function (token, transactionDetails = {}, options = {}) { - return this.adapter.get(`${this.namespace}/capture`, { token, transactionDetails }, options).then(orderJson => new Order(orderJson)); - } + return this.adapter.post(`${this.namespace}/capture`, { token, transactionDetails }, options).then((orderJson) => new Order(orderJson)); + }, + + createStripeSetupIntent: function (customer, options = {}) { + if (isResource(customer)) { + customer = customer.id; + } + + return this.adapter.post(`${this.namespace}/stripe-setup-intent`, { customer }, options); + }, + + updateStripePaymentIntent: function (paymentIntent, customer, cart, serviceQuote, orderOptions = {}, options = {}) { + if (isResource(customer)) { + customer = customer.id; + } + + if (isResource(cart)) { + cart = cart.id; + } + + if (isResource(serviceQuote)) { + serviceQuote = serviceQuote.id; + } + + return this.adapter.put(`${this.namespace}/stripe-update-payment-intent`, { paymentIntent, customer, cart, serviceQuote, ...orderOptions }, options); + }, }); export default class Checkout extends Resource { diff --git a/src/resources/customer.js b/src/resources/customer.js index d90c72a..f61b142 100644 --- a/src/resources/customer.js +++ b/src/resources/customer.js @@ -86,6 +86,18 @@ export default class Customer extends Resource { return new Collection(orders.map((attributes) => new Order(attributes, this.adapter))); }); } + + getStripeEphemeralKey(params = {}) { + return this.adapter + .setHeaders({ 'Customer-Token': this.token }) + .post('customers/stripe-ephemeral-key', params); + } + + getStripeSetupIntent(params = {}) { + return this.adapter + .setHeaders({ 'Customer-Token': this.token }) + .post('customers/stripe-setup-intent', params); + } } export { customerActions }; diff --git a/src/storefront.js b/src/storefront.js index edbfb97..dd58e0d 100644 --- a/src/storefront.js +++ b/src/storefront.js @@ -1,5 +1,6 @@ import StorefrontStore from './store'; import { detectAdapter, isKeyValid } from './utils'; +import { lookup } from './resolver'; import { Product, Category, Customer, Cart, Store, StoreLocation, StoreHour, DeliveryServiceQuote, Checkout, PaymentGateway, Review, Network } from './resources'; import { cartActions } from './resources/cart'; import { customerActions } from './resources/customer'; @@ -51,6 +52,11 @@ export default class Storefront { return this.adapter.get('about'); } + /** lookup a specific store or network provided the ID */ + lookup(id) { + return this.adapter.get(`lookup/${id}`); + } + /** search products in store or network */ search(query, options = {}) { return this.adapter.get('search', { query, ...options }).then(products => { @@ -71,4 +77,4 @@ export default class Storefront { } } -export { Product, Category, Customer, Cart, Store, StoreLocation, StoreHour, DeliveryServiceQuote, Checkout, PaymentGateway, Review, Network }; +export { Product, Category, Customer, Cart, Store, StoreLocation, StoreHour, DeliveryServiceQuote, Checkout, PaymentGateway, Review, Network, lookup };