From 64949dc721a6c697e3eb7091db9f2d261111a766 Mon Sep 17 00:00:00 2001 From: Kasper Fabricius Kristensen <45367945+kasperkristensen@users.noreply.github.com> Date: Mon, 12 Sep 2022 19:28:43 +0200 Subject: [PATCH] feat(medusa-js,medusa-react,medusa): Add missing Currency endpoints (#2185) --- .changeset/hot-dancers-smile.md | 7 +++ .../src/resources/admin/currencies.ts | 53 +++++++++++++++++++ .../medusa-js/src/resources/admin/index.ts | 2 + .../medusa-react/mocks/data/fixtures.json | 27 ++++++---- packages/medusa-react/mocks/handlers/admin.ts | 30 +++++++++-- .../src/hooks/admin/currencies/index.ts | 2 + .../src/hooks/admin/currencies/mutations.ts | 30 +++++++++++ .../src/hooks/admin/currencies/queries.ts | 32 +++++++++++ .../medusa-react/src/hooks/admin/index.ts | 3 +- .../hooks/admin/currencies/mutation.test.ts | 31 +++++++++++ .../hooks/admin/currencies/queries.test.ts | 18 +++++++ packages/medusa/src/api/index.js | 1 + .../src/api/routes/admin/currencies/index.ts | 14 ++++- 13 files changed, 233 insertions(+), 17 deletions(-) create mode 100644 .changeset/hot-dancers-smile.md create mode 100644 packages/medusa-js/src/resources/admin/currencies.ts create mode 100644 packages/medusa-react/src/hooks/admin/currencies/index.ts create mode 100644 packages/medusa-react/src/hooks/admin/currencies/mutations.ts create mode 100644 packages/medusa-react/src/hooks/admin/currencies/queries.ts create mode 100644 packages/medusa-react/test/hooks/admin/currencies/mutation.test.ts create mode 100644 packages/medusa-react/test/hooks/admin/currencies/queries.test.ts diff --git a/.changeset/hot-dancers-smile.md b/.changeset/hot-dancers-smile.md new file mode 100644 index 0000000000..51b0fad03c --- /dev/null +++ b/.changeset/hot-dancers-smile.md @@ -0,0 +1,7 @@ +--- +"@medusajs/medusa": patch +"@medusajs/medusa-js": patch +"medusa-react": patch +--- + +Adds missing response types for currency endpoints and exports route. Adds currency endpoints to medusa-js and medusa-react. diff --git a/packages/medusa-js/src/resources/admin/currencies.ts b/packages/medusa-js/src/resources/admin/currencies.ts new file mode 100644 index 0000000000..76ba922018 --- /dev/null +++ b/packages/medusa-js/src/resources/admin/currencies.ts @@ -0,0 +1,53 @@ +import { + AdminCurrenciesListRes, + AdminCurrenciesRes, + AdminGetCurrenciesParams, + AdminPostCurrenciesCurrencyReq, +} from "@medusajs/medusa" +import qs from "qs" +import { ResponsePromise } from "../../typings" +import BaseResource from "../base" + +class AdminCurrenciesResource extends BaseResource { + /** + * @description Lists currencies. + * @experimental This feature is under development and may change in the future. + * To use this feature please enable featureflag `tax_inclusive_pricing` in your medusa backend project. + * @param payload optional + * @param customHeaders + * @returns the list of currencies as well as the pagination properties. + */ + list( + query?: AdminGetCurrenciesParams, + customHeaders: Record = {} + ): ResponsePromise { + let path = `/admin/currencies` + + if (query) { + const queryString = qs.stringify(query) + path += `?${queryString}` + } + + return this.client.request("GET", path, undefined, {}, customHeaders) + } + + /** + * @description Updates a currency + * @experimental This feature is under development and may change in the future. + * To use this feature please enable featureflag `tax_inclusive_pricing` in your medusa backend project. + * @param code code of the currency to update. + * @param payload update to apply to currency. + * @param customHeaders + * @returns the updated currency. + */ + update( + code: string, + payload: AdminPostCurrenciesCurrencyReq, + customHeaders: Record = {} + ): ResponsePromise { + const path = `/admin/currencies/${code}` + return this.client.request("POST", path, payload, {}, customHeaders) + } +} + +export default AdminCurrenciesResource diff --git a/packages/medusa-js/src/resources/admin/index.ts b/packages/medusa-js/src/resources/admin/index.ts index c44709d11b..cc03715e74 100644 --- a/packages/medusa-js/src/resources/admin/index.ts +++ b/packages/medusa-js/src/resources/admin/index.ts @@ -2,6 +2,7 @@ import BaseResource from "../base" import AdminAuthResource from "./auth" import AdminBatchJobsResource from "./batch-jobs" import CollectionsResource from "./collections" +import AdminCurrenciesResource from "./currencies" import AdminCustomerGroupsResource from "./customer-groups" import AdminCustomersResource from "./customers" import AdminDiscountsResource from "./discounts" @@ -34,6 +35,7 @@ class Admin extends BaseResource { public customers = new AdminCustomersResource(this.client) public customerGroups = new AdminCustomerGroupsResource(this.client) public discounts = new AdminDiscountsResource(this.client) + public currencies = new AdminCurrenciesResource(this.client) public collections = new CollectionsResource(this.client) public draftOrders = new AdminDraftOrdersResource(this.client) public giftCards = new AdminGiftCardsResource(this.client) diff --git a/packages/medusa-react/mocks/data/fixtures.json b/packages/medusa-react/mocks/data/fixtures.json index ce795f566d..31ea7a1c51 100644 --- a/packages/medusa-react/mocks/data/fixtures.json +++ b/packages/medusa-react/mocks/data/fixtures.json @@ -1,5 +1,12 @@ { "resources": { + "currency": { + "symbol": "$", + "name": "US Dollar", + "symbol_native": "$", + "code": "USD", + "includes_tax": false + }, "region": { "id": "reg_01F0YES4R67TXXC1QBQ8P54A8Y", "name": "Test Region", @@ -1271,14 +1278,16 @@ "created_at": "2022-07-05T15:16:01.959Z", "deleted_at": null }, - "sales_channels": [{ - "id": "sc_01F0YES4R67TXXC1QBQ8P54A8Y", - "name": "sales channel 1 name", - "description": "sales channel 1 description", - "is_disabled": false, - "updated_at": "2022-07-05T15:16:01.959Z", - "created_at": "2022-07-05T15:16:01.959Z", - "deleted_at": null - }] + "sales_channels": [ + { + "id": "sc_01F0YES4R67TXXC1QBQ8P54A8Y", + "name": "sales channel 1 name", + "description": "sales channel 1 description", + "is_disabled": false, + "updated_at": "2022-07-05T15:16:01.959Z", + "created_at": "2022-07-05T15:16:01.959Z", + "deleted_at": null + } + ] } } diff --git a/packages/medusa-react/mocks/handlers/admin.ts b/packages/medusa-react/mocks/handlers/admin.ts index 0f861bd7e5..3c8f6fe620 100644 --- a/packages/medusa-react/mocks/handlers/admin.ts +++ b/packages/medusa-react/mocks/handlers/admin.ts @@ -1,5 +1,4 @@ import { rest } from "msw" -import { body } from "msw/lib/types/context" import { fixtures } from "../data" export const adminHandlers = [ @@ -114,8 +113,8 @@ export const adminHandlers = [ ctx.json({ collection: { ...fixtures.get("product_collection"), - products: [fixtures.get("product")] - } + products: [fixtures.get("product")], + }, }) ) }), @@ -126,7 +125,7 @@ export const adminHandlers = [ ctx.json({ id: req.params.id, object: "product-collection", - removed_products: [fixtures.get("product").id] + removed_products: [fixtures.get("product").id], }) ) }), @@ -892,7 +891,7 @@ export const adminHandlers = [ discount_condition: { ...fixtures .get("discount") - .rule.conditions.find(c => c.id === req.params.conditionId), + .rule.conditions.find((c) => c.id === req.params.conditionId), }, }) ) @@ -1767,4 +1766,25 @@ export const adminHandlers = [ }) ) }), + + rest.get("/admin/currencies", (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + count: 1, + limit: 20, + offset: 20, + currencies: fixtures.list("currency", 1), + }) + ) + }), + + rest.post("/admin/currencies/:code", (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + currency: { ...fixtures.get("currency"), ...(req.body as any) }, + }) + ) + }), ] diff --git a/packages/medusa-react/src/hooks/admin/currencies/index.ts b/packages/medusa-react/src/hooks/admin/currencies/index.ts new file mode 100644 index 0000000000..97c3d1d4b8 --- /dev/null +++ b/packages/medusa-react/src/hooks/admin/currencies/index.ts @@ -0,0 +1,2 @@ +export * from "./mutations" +export * from "./queries" diff --git a/packages/medusa-react/src/hooks/admin/currencies/mutations.ts b/packages/medusa-react/src/hooks/admin/currencies/mutations.ts new file mode 100644 index 0000000000..4ad1c49f8a --- /dev/null +++ b/packages/medusa-react/src/hooks/admin/currencies/mutations.ts @@ -0,0 +1,30 @@ +import { + AdminCurrenciesRes, + AdminPostCurrenciesCurrencyReq, +} from "@medusajs/medusa" +import { Response } from "@medusajs/medusa-js" +import { useMutation, UseMutationOptions, useQueryClient } from "react-query" +import { adminCurrenciesKeys } from "." +import { useMedusa } from "../../../contexts/medusa" +import { buildOptions } from "../../utils/buildOptions" + +export const useAdminUpdateCurrency = ( + code: string, + options?: UseMutationOptions< + Response, + Error, + AdminPostCurrenciesCurrencyReq + > +) => { + const { client } = useMedusa() + const queryClient = useQueryClient() + return useMutation( + (payload: AdminPostCurrenciesCurrencyReq) => + client.admin.currencies.update(code, payload), + buildOptions( + queryClient, + [adminCurrenciesKeys.lists(), adminCurrenciesKeys.detail(code)], + options + ) + ) +} diff --git a/packages/medusa-react/src/hooks/admin/currencies/queries.ts b/packages/medusa-react/src/hooks/admin/currencies/queries.ts new file mode 100644 index 0000000000..e8018fe18e --- /dev/null +++ b/packages/medusa-react/src/hooks/admin/currencies/queries.ts @@ -0,0 +1,32 @@ +import { + AdminCurrenciesListRes, + AdminGetCurrenciesParams, +} from "@medusajs/medusa" +import { Response } from "@medusajs/medusa-js" +import { useQuery } from "react-query" +import { useMedusa } from "../../../contexts" +import { UseQueryOptionsWrapper } from "../../../types" +import { queryKeysFactory } from "../../utils/index" + +const ADMIN_CURRENCIES_QUERY_KEY = `admin_currencies` as const + +export const adminCurrenciesKeys = queryKeysFactory(ADMIN_CURRENCIES_QUERY_KEY) + +type CurrenciesQueryKey = typeof adminCurrenciesKeys + +export const useAdminCurrencies = ( + query?: AdminGetCurrenciesParams, + options?: UseQueryOptionsWrapper< + Response, + Error, + ReturnType + > +) => { + const { client } = useMedusa() + const { data, ...rest } = useQuery( + adminCurrenciesKeys.list(query), + () => client.admin.currencies.list(query), + options + ) + return { ...data, ...rest } as const +} diff --git a/packages/medusa-react/src/hooks/admin/index.ts b/packages/medusa-react/src/hooks/admin/index.ts index 7b45420c5a..54437cdba3 100644 --- a/packages/medusa-react/src/hooks/admin/index.ts +++ b/packages/medusa-react/src/hooks/admin/index.ts @@ -2,6 +2,7 @@ export * from "./auth" export * from "./batch-jobs" export * from "./claims" export * from "./collections" +export * from "./currencies" export * from "./customer-groups" export * from "./customers" export * from "./discounts" @@ -24,6 +25,6 @@ export * from "./shipping-profiles" export * from "./store" export * from "./swaps" export * from "./tax-rates" +export * from "./uploads" export * from "./users" export * from "./variants" -export * from "./uploads" diff --git a/packages/medusa-react/test/hooks/admin/currencies/mutation.test.ts b/packages/medusa-react/test/hooks/admin/currencies/mutation.test.ts new file mode 100644 index 0000000000..b329059d29 --- /dev/null +++ b/packages/medusa-react/test/hooks/admin/currencies/mutation.test.ts @@ -0,0 +1,31 @@ +import { renderHook } from "@testing-library/react-hooks" +import { fixtures } from "../../../../mocks/data" +import { useAdminUpdateCurrency } from "../../../../src/" +import { createWrapper } from "../../../utils" + +describe("useAdminUpdateCurrency hook", () => { + test("updates a currency and returns it", async () => { + const update = { + includes_tax: true, + } + + const { result, waitFor } = renderHook( + () => useAdminUpdateCurrency(fixtures.get("currency").code), + { + wrapper: createWrapper(), + } + ) + + result.current.mutate(update) + + await waitFor(() => result.current.isSuccess) + + expect(result.current.data?.response.status).toEqual(200) + expect(result.current.data?.currency).toEqual( + expect.objectContaining({ + ...fixtures.get("currency"), + ...update, + }) + ) + }) +}) diff --git a/packages/medusa-react/test/hooks/admin/currencies/queries.test.ts b/packages/medusa-react/test/hooks/admin/currencies/queries.test.ts new file mode 100644 index 0000000000..f32dedfbcc --- /dev/null +++ b/packages/medusa-react/test/hooks/admin/currencies/queries.test.ts @@ -0,0 +1,18 @@ +import { renderHook } from "@testing-library/react-hooks" +import { fixtures } from "../../../../mocks/data" +import { useAdminCurrencies } from "../../../../src" +import { createWrapper } from "../../../utils" + +describe("useAdminCurrencies hook", () => { + test("returns a list of currencies", async () => { + const currencies = fixtures.list("currency", 1) + const { result, waitFor } = renderHook(() => useAdminCurrencies(), { + wrapper: createWrapper(), + }) + + await waitFor(() => result.current.isSuccess) + + expect(result.current.response?.status).toEqual(200) + expect(result.current.currencies).toEqual(currencies) + }) +}) diff --git a/packages/medusa/src/api/index.js b/packages/medusa/src/api/index.js index 0ac8f38db0..13055bbf04 100644 --- a/packages/medusa/src/api/index.js +++ b/packages/medusa/src/api/index.js @@ -19,6 +19,7 @@ export default (container, config) => { export * from "./routes/admin/auth" export * from "./routes/admin/batch" export * from "./routes/admin/collections" +export * from "./routes/admin/currencies" export * from "./routes/admin/customer-groups" export * from "./routes/admin/customers" export * from "./routes/admin/discounts" diff --git a/packages/medusa/src/api/routes/admin/currencies/index.ts b/packages/medusa/src/api/routes/admin/currencies/index.ts index 305cbe508b..b222985739 100644 --- a/packages/medusa/src/api/routes/admin/currencies/index.ts +++ b/packages/medusa/src/api/routes/admin/currencies/index.ts @@ -1,12 +1,14 @@ import { Router } from "express" +import { Currency } from "../../../.." +import TaxInclusivePricingFeatureFlag from "../../../../loaders/feature-flags/tax-inclusive-pricing" +import { PaginatedResponse } from "../../../../types/common" import middlewares, { transformBody, transformQuery, } from "../../../middlewares" +import { isFeatureFlagEnabled } from "../../../middlewares/feature-flag-enabled" import { AdminGetCurrenciesParams } from "./list-currencies" import { AdminPostCurrenciesCurrencyReq } from "./update-currency" -import { isFeatureFlagEnabled } from "../../../middlewares/feature-flag-enabled" -import TaxInclusivePricingFeatureFlag from "../../../../loaders/feature-flags/tax-inclusive-pricing" export default (app) => { const route = Router() @@ -33,5 +35,13 @@ export default (app) => { return app } +export type AdminCurrenciesListRes = PaginatedResponse & { + currencies: Currency[] +} + +export type AdminCurrenciesRes = { + currency: Currency +} + export * from "./list-currencies" export * from "./update-currency"