diff --git a/packages/medusa-js/src/resources/admin/index.ts b/packages/medusa-js/src/resources/admin/index.ts index 3d7780f266..8f5cd31a82 100644 --- a/packages/medusa-js/src/resources/admin/index.ts +++ b/packages/medusa-js/src/resources/admin/index.ts @@ -17,6 +17,7 @@ import AdminPriceListResource from "./price-lists" import AdminProductTagsResource from "./product-tags" import AdminProductTypesResource from "./product-types" import AdminProductsResource from "./products" +import AdminPublishableApiKeyResource from "./publishable-api-keys" import AdminRegionsResource from "./regions" import AdminReturnReasonsResource from "./return-reasons" import AdminReturnsResource from "./returns" @@ -50,6 +51,7 @@ class Admin extends BaseResource { public returns = new AdminReturnsResource(this.client) public orders = new AdminOrdersResource(this.client) public orderEdits = new AdminOrderEditsResource(this.client) + public publishableApiKeys = new AdminPublishableApiKeyResource(this.client) public returnReasons = new AdminReturnReasonsResource(this.client) public variants = new AdminVariantsResource(this.client) public salesChannels = new AdminSalesChannelsResource(this.client) diff --git a/packages/medusa-js/src/resources/admin/publishable-api-keys.ts b/packages/medusa-js/src/resources/admin/publishable-api-keys.ts new file mode 100644 index 0000000000..ed839bca9e --- /dev/null +++ b/packages/medusa-js/src/resources/admin/publishable-api-keys.ts @@ -0,0 +1,68 @@ +import qs from "qs" + +import { + AdminPublishableApiKeyDeleteRes, + AdminPublishableApiKeysRes, + GetPublishableApiKeysParams, + AdminPublishableApiKeysListRes, +} from "@medusajs/medusa" + +import { ResponsePromise } from "../../typings" +import BaseResource from "../base" + +class AdminPublishableApiKeyResource extends BaseResource { + retrieve( + id: string, + query?: {}, + customHeaders: Record = {} + ): ResponsePromise { + let path = `/admin/publishable-api-keys/${id}` + + if (query) { + const queryString = qs.stringify(query) + path += `?${queryString}` + } + + return this.client.request("GET", path, undefined, {}, customHeaders) + } + + list( + query?: GetPublishableApiKeysParams, + customHeaders: Record = {} + ): ResponsePromise { + let path = `/admin/publishable-api-keys` + + if (query) { + const queryString = qs.stringify(query) + path += `?${queryString}` + } + + return this.client.request("GET", path, undefined, {}, customHeaders) + } + + create( + payload: {}, + customHeaders: Record = {} + ): ResponsePromise { + const path = `/admin/publishable-api-keys` + return this.client.request("POST", path, payload, {}, customHeaders) + } + + delete( + id: string, + customHeaders: Record = {} + ): ResponsePromise { + const path = `/admin/publishable-api-keys/${id}` + return this.client.request("DELETE", path, undefined, {}, customHeaders) + } + + revoke( + id: string, + customHeaders: Record = {} + ): ResponsePromise { + const path = `/admin/publishable-api-keys/${id}/revoke` + return this.client.request("POST", path, {}, {}, customHeaders) + } +} + +export default AdminPublishableApiKeyResource diff --git a/packages/medusa-react/mocks/data/fixtures.json b/packages/medusa-react/mocks/data/fixtures.json index 3286f0c6b5..4ef6309f11 100644 --- a/packages/medusa-react/mocks/data/fixtures.json +++ b/packages/medusa-react/mocks/data/fixtures.json @@ -1151,6 +1151,14 @@ "updated_at": "2021-03-17 12:09:59.156058+01", "metadata": null }, + "publishable_api_key": { + "id": "pubkey_1234", + "created_by": "admin_user", + "created_at": "2021-11-08 11:58:56.975971+01", + "updated_at": "2021-11-08 11:58:56.975971+01", + "revoked_by": null, + "revoked_at": null + }, "draft_order": { "id": "dorder_01FGKMYKMJ4E8HP3RGEW28E7CZ", "status": "open", diff --git a/packages/medusa-react/mocks/handlers/admin.ts b/packages/medusa-react/mocks/handlers/admin.ts index 6325448d05..e280ae5a3f 100644 --- a/packages/medusa-react/mocks/handlers/admin.ts +++ b/packages/medusa-react/mocks/handlers/admin.ts @@ -962,6 +962,60 @@ export const adminHandlers = [ } ), + rest.get("/admin/publishable-api-keys/", (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + publishable_api_keys: fixtures.list("publishable_api_key"), + }) + ) + }), + + rest.get("/admin/publishable-api-keys/:id", (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + publishable_api_key: fixtures.get("publishable_api_key"), + }) + ) + }), + + rest.post("/admin/publishable-api-keys/", (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + publishable_api_key: { + ...fixtures.get("publishable_api_key"), + ...(req.body as any), + }, + }) + ) + }), + + rest.post("/admin/publishable-api-keys/:id/revoke", (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + publishable_api_key: { + ...fixtures.get("publishable_api_key"), + revoked_at: "2022-11-10 11:17:46.666Z", + revoked_by: "admin_user", + }, + }) + ) + }), + + rest.delete("/admin/publishable-api-keys/:id", (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + id: fixtures.get("publishable_api_key").id, + object: "publishable_api_key", + deleted: true, + }) + ) + }), + rest.get("/admin/draft-orders/", (req, res, ctx) => { return res( ctx.status(200), diff --git a/packages/medusa-react/src/hooks/admin/index.ts b/packages/medusa-react/src/hooks/admin/index.ts index a28e15f041..3e09bd4eb2 100644 --- a/packages/medusa-react/src/hooks/admin/index.ts +++ b/packages/medusa-react/src/hooks/admin/index.ts @@ -17,6 +17,7 @@ export * from "./price-lists" export * from "./product-tags" export * from "./product-types" export * from "./products" +export * from "./publishable-api-keys" export * from "./regions" export * from "./return-reasons" export * from "./returns" diff --git a/packages/medusa-react/src/hooks/admin/publishable-api-keys/index.ts b/packages/medusa-react/src/hooks/admin/publishable-api-keys/index.ts new file mode 100644 index 0000000000..a494946b87 --- /dev/null +++ b/packages/medusa-react/src/hooks/admin/publishable-api-keys/index.ts @@ -0,0 +1,2 @@ +export * from "./queries" +export * from "./mutations" diff --git a/packages/medusa-react/src/hooks/admin/publishable-api-keys/mutations.ts b/packages/medusa-react/src/hooks/admin/publishable-api-keys/mutations.ts new file mode 100644 index 0000000000..ab2bb1048a --- /dev/null +++ b/packages/medusa-react/src/hooks/admin/publishable-api-keys/mutations.ts @@ -0,0 +1,66 @@ +import { useMutation, UseMutationOptions, useQueryClient } from "react-query" +import { Response } from "@medusajs/medusa-js" + +import { + AdminPublishableApiKeyDeleteRes, + AdminPublishableApiKeysRes, +} from "@medusajs/medusa" + +import { buildOptions } from "../../utils/buildOptions" +import { useMedusa } from "../../../contexts" +import { adminPublishableApiKeysKeys } from "." + +export const useAdminCreatePublishableApiKey = ( + options?: UseMutationOptions, Error, {}> +) => { + const { client } = useMedusa() + const queryClient = useQueryClient() + return useMutation( + (payload: {}) => client.admin.publishableApiKeys.create(payload), + buildOptions(queryClient, [adminPublishableApiKeysKeys.lists()], options) + ) +} + +export const useAdminDeletePublishableApiKey = ( + id: string, + options?: UseMutationOptions< + Response, + Error, + void + > +) => { + const { client } = useMedusa() + const queryClient = useQueryClient() + + return useMutation( + () => client.admin.publishableApiKeys.delete(id), + buildOptions( + queryClient, + [ + adminPublishableApiKeysKeys.detail(id), + adminPublishableApiKeysKeys.lists(), + ], + options + ) + ) +} + +export const useAdminRevokePublishableApiKey = ( + id: string, + options?: UseMutationOptions, Error> +) => { + const { client } = useMedusa() + const queryClient = useQueryClient() + + return useMutation( + () => client.admin.publishableApiKeys.revoke(id), + buildOptions( + queryClient, + [ + adminPublishableApiKeysKeys.lists(), + adminPublishableApiKeysKeys.detail(id), + ], + options + ) + ) +} diff --git a/packages/medusa-react/src/hooks/admin/publishable-api-keys/queries.ts b/packages/medusa-react/src/hooks/admin/publishable-api-keys/queries.ts new file mode 100644 index 0000000000..1b1f7cd4fd --- /dev/null +++ b/packages/medusa-react/src/hooks/admin/publishable-api-keys/queries.ts @@ -0,0 +1,54 @@ +import { + AdminPublishableApiKeysListRes, + AdminPublishableApiKeysRes, + GetPublishableApiKeysParams, +} from "@medusajs/medusa" +import { useQuery } from "react-query" +import { Response } from "@medusajs/medusa-js" + +import { queryKeysFactory } from "../../utils" +import { useMedusa } from "../../../contexts" +import { UseQueryOptionsWrapper } from "../../../types" + +const ADMIN_PUBLISHABLE_API_KEYS_QUERY_KEY = + `admin_publishable_api_keys` as const + +export const adminPublishableApiKeysKeys = queryKeysFactory( + ADMIN_PUBLISHABLE_API_KEYS_QUERY_KEY +) +type PublishableApiKeyQueryKeys = typeof adminPublishableApiKeysKeys + +export const useAdminPublishableApiKey = ( + id: string, + query?: GetPublishableApiKeysParams, + options?: UseQueryOptionsWrapper< + Response, + Error, + ReturnType + > +) => { + const { client } = useMedusa() + const { data, ...rest } = useQuery( + adminPublishableApiKeysKeys.detail(id), + () => client.admin.publishableApiKeys.retrieve(id, query), + options + ) + return { ...data, ...rest } as const +} + +export const useAdminPublishableApiKeys = ( + query?: GetPublishableApiKeysParams, + options?: UseQueryOptionsWrapper< + Response, + Error, + ReturnType + > +) => { + const { client } = useMedusa() + const { data, ...rest } = useQuery( + adminPublishableApiKeysKeys.list(query), + () => client.admin.publishableApiKeys.list(query), + options + ) + return { ...data, ...rest } as const +} diff --git a/packages/medusa-react/test/hooks/admin/order-edits/mutations.test.ts b/packages/medusa-react/test/hooks/admin/order-edits/mutations.test.ts index 6d14effbb1..1714dcfe73 100644 --- a/packages/medusa-react/test/hooks/admin/order-edits/mutations.test.ts +++ b/packages/medusa-react/test/hooks/admin/order-edits/mutations.test.ts @@ -8,7 +8,6 @@ import { useAdminOrderEditUpdateLineItem, useAdminRequestOrderEditConfirmation, useAdminOrderEditAddLineItem, - useAdminCancelOrderEdit, useAdminUpdateOrderEdit, useAdminOrderEditDeleteLineItem, } from "../../../../src/" @@ -68,7 +67,7 @@ describe("useAdminDeleteOrderEditItemChange hook", () => { }) }) -describe("useAdminDelete hook", () => { +describe("useAdminDeleteOrderEdit hook", () => { test("Deletes an order edit", async () => { const id = "oe_1" const { result, waitFor } = renderHook(() => useAdminDeleteOrderEdit(id), { diff --git a/packages/medusa-react/test/hooks/admin/publishable-api-keys/mutations.test.ts b/packages/medusa-react/test/hooks/admin/publishable-api-keys/mutations.test.ts new file mode 100644 index 0000000000..96182e0538 --- /dev/null +++ b/packages/medusa-react/test/hooks/admin/publishable-api-keys/mutations.test.ts @@ -0,0 +1,85 @@ +import { renderHook } from "@testing-library/react-hooks" + +import { createWrapper } from "../../../utils" +import { + useAdminDeletePublishableApiKey, + useAdminRevokePublishableApiKey, +} from "../../../../src" +import { fixtures } from "../../../../mocks/data" +import { useAdminCreatePublishableApiKey } from "../../../../src" + +describe("useAdminCreatePublishableApiKey hook", () => { + test("Created a publishable api key", async () => { + const { result, waitFor } = renderHook( + () => useAdminCreatePublishableApiKey(), + { + wrapper: createWrapper(), + } + ) + + result.current.mutate({}) + + await waitFor(() => result.current.isSuccess) + + expect(result.current.data.response.status).toEqual(200) + expect(result.current.data).toEqual( + expect.objectContaining({ + publishable_api_key: { + ...fixtures.get("publishable_api_key"), + }, + }) + ) + }) +}) + +describe("useAdminRevokePublishableApiKey hook", () => { + test("Revoke a publishable api key", async () => { + const id = "pubkey_1234" + const { result, waitFor } = renderHook( + () => useAdminRevokePublishableApiKey(id), + { + wrapper: createWrapper(), + } + ) + + result.current.mutate() + + await waitFor(() => result.current.isSuccess) + + expect(result.current.data.response.status).toEqual(200) + expect(result.current.data).toEqual( + expect.objectContaining({ + publishable_api_key: { + ...fixtures.get("publishable_api_key"), + revoked_at: "2022-11-10 11:17:46.666Z", + revoked_by: "admin_user", + id, + }, + }) + ) + }) +}) + +describe("useAdminDeletePublishableApiKey hook", () => { + test("Deletes a publishable api key", async () => { + const id = "pubkey_1234" + const { result, waitFor } = renderHook( + () => useAdminDeletePublishableApiKey(id), + { + wrapper: createWrapper(), + } + ) + + result.current.mutate() + await waitFor(() => result.current.isSuccess) + + expect(result.current.data.response.status).toEqual(200) + expect(result.current.data).toEqual( + expect.objectContaining({ + id, + object: "publishable_api_key", + deleted: true, + }) + ) + }) +}) diff --git a/packages/medusa-react/test/hooks/admin/publishable-api-keys/queries.test.ts b/packages/medusa-react/test/hooks/admin/publishable-api-keys/queries.test.ts new file mode 100644 index 0000000000..f0c5a4bc4a --- /dev/null +++ b/packages/medusa-react/test/hooks/admin/publishable-api-keys/queries.test.ts @@ -0,0 +1,41 @@ +import { renderHook } from "@testing-library/react-hooks" + +import { + useAdminPublishableApiKey, + useAdminPublishableApiKeys, +} from "../../../../src" +import { createWrapper } from "../../../utils" +import { fixtures } from "../../../../mocks/data" + +describe("useAdminPublishableApiKey hook", () => { + test("returns an publishable api key", async () => { + const publishable_api_key = fixtures.get("publishable_api_key") + const { result, waitFor } = renderHook( + () => useAdminPublishableApiKey(publishable_api_key.id), + { + wrapper: createWrapper(), + } + ) + + await waitFor(() => result.current.isSuccess) + + expect(result.current.response.status).toEqual(200) + expect(result.current.publishable_api_key).toEqual(publishable_api_key) + }) +}) + +describe("useAdminPublishableApiKeys hook", () => { + test("returns a list of publishable api keys", async () => { + const publishable_api_key = fixtures.get("publishable_api_key") + const { result, waitFor } = renderHook(() => useAdminPublishableApiKeys(), { + wrapper: createWrapper(), + }) + + await waitFor(() => result.current.isSuccess) + + expect(result.current.response.status).toEqual(200) + expect(result.current.publishable_api_keys).toEqual( + expect.arrayContaining([publishable_api_key]) + ) + }) +})