feat(medusa, medusa-js, medusa-react): PublishableApiKey "update" endpoint & add "title" property (#2609)
**What** - update PK endpoint - medusa-js/react implementation - add a title property to the entity - update the migration file - pass a title on create - list PKs by title - update the client libs with new param signatures - change id prefix to: "pk_"
This commit is contained in:
@@ -82,9 +82,15 @@ describe("[MEDUSA_FF_PUBLISHABLE_API_KEYS] Publishable API keys", () => {
|
||||
beforeEach(async () => {
|
||||
await adminSeeder(dbConnection)
|
||||
|
||||
await simplePublishableApiKeyFactory(dbConnection, {})
|
||||
await simplePublishableApiKeyFactory(dbConnection, {})
|
||||
await simplePublishableApiKeyFactory(dbConnection, {})
|
||||
await simplePublishableApiKeyFactory(dbConnection, {
|
||||
title: "just a title",
|
||||
})
|
||||
await simplePublishableApiKeyFactory(dbConnection, {
|
||||
title: "special title 1",
|
||||
})
|
||||
await simplePublishableApiKeyFactory(dbConnection, {
|
||||
title: "special title 2",
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
@@ -105,6 +111,30 @@ describe("[MEDUSA_FF_PUBLISHABLE_API_KEYS] Publishable API keys", () => {
|
||||
expect(response.data.offset).toBe(0)
|
||||
expect(response.data.publishable_api_keys).toHaveLength(2)
|
||||
})
|
||||
|
||||
it("list publishable keys with query search", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api.get(
|
||||
`/admin/publishable-api-keys?q=special`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data.count).toBe(2)
|
||||
expect(response.data.limit).toBe(20)
|
||||
expect(response.data.offset).toBe(0)
|
||||
expect(response.data.publishable_api_keys).toHaveLength(2)
|
||||
expect(response.data.publishable_api_keys).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
title: "special title 1",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
title: "special title 2",
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /admin/publishable-api-keys", () => {
|
||||
@@ -122,7 +152,7 @@ describe("[MEDUSA_FF_PUBLISHABLE_API_KEYS] Publishable API keys", () => {
|
||||
|
||||
const response = await api.post(
|
||||
`/admin/publishable-api-keys`,
|
||||
{},
|
||||
{ title: "Store api key" },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
@@ -130,6 +160,45 @@ describe("[MEDUSA_FF_PUBLISHABLE_API_KEYS] Publishable API keys", () => {
|
||||
expect(response.data.publishable_api_key).toMatchObject({
|
||||
created_by: "admin_user",
|
||||
id: expect.any(String),
|
||||
title: "Store api key",
|
||||
revoked_by: null,
|
||||
revoked_at: null,
|
||||
created_at: expect.any(String),
|
||||
updated_at: expect.any(String),
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /admin/publishable-api-keys/:id", () => {
|
||||
const pubKeyId = IdMap.getId("pubkey-get-id-update")
|
||||
|
||||
beforeEach(async () => {
|
||||
await adminSeeder(dbConnection)
|
||||
|
||||
await simplePublishableApiKeyFactory(dbConnection, {
|
||||
id: pubKeyId,
|
||||
title: "Initial key title",
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
const db = useDb()
|
||||
return await db.teardown()
|
||||
})
|
||||
|
||||
it("update a publishable key", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api.post(
|
||||
`/admin/publishable-api-keys/${pubKeyId}`,
|
||||
{ title: "Changed title" },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
expect(response.data.publishable_api_key).toMatchObject({
|
||||
id: pubKeyId,
|
||||
title: "Changed title",
|
||||
revoked_by: null,
|
||||
revoked_at: null,
|
||||
created_at: expect.any(String),
|
||||
|
||||
@@ -9,7 +9,6 @@ const adminSeeder = require("../../helpers/admin-seeder")
|
||||
const {
|
||||
simpleSalesChannelFactory,
|
||||
simpleProductFactory,
|
||||
simpleCartFactory,
|
||||
} = require("../../factories")
|
||||
const { simpleOrderFactory } = require("../../factories")
|
||||
const orderSeeder = require("../../helpers/order-seeder")
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
MoneyAmount,
|
||||
PriceListType,
|
||||
PriceListStatus,
|
||||
CustomerGroup,
|
||||
} from "@medusajs/medusa"
|
||||
import faker from "faker"
|
||||
import { Connection } from "typeorm"
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import faker from "faker"
|
||||
import { Connection } from "typeorm"
|
||||
|
||||
import { PublishableApiKey } from "@medusajs/medusa"
|
||||
|
||||
export type PublishableApiKeyData = {
|
||||
@@ -6,6 +8,7 @@ export type PublishableApiKeyData = {
|
||||
revoked_at?: Date
|
||||
revoked_by?: string
|
||||
created_by?: string
|
||||
title?: string
|
||||
}
|
||||
|
||||
export const simplePublishableApiKeyFactory = async (
|
||||
@@ -14,7 +17,10 @@ export const simplePublishableApiKeyFactory = async (
|
||||
): Promise<PublishableApiKey> => {
|
||||
const manager = connection.manager
|
||||
|
||||
const pubKey = manager.create(PublishableApiKey, data)
|
||||
const pubKey = manager.create(PublishableApiKey, {
|
||||
...data,
|
||||
title: data.title || `${faker.commerce.department()} API key`,
|
||||
})
|
||||
|
||||
return await manager.save(pubKey)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import {
|
||||
AdminPublishableApiKeysRes,
|
||||
GetPublishableApiKeysParams,
|
||||
AdminPublishableApiKeysListRes,
|
||||
AdminPostPublishableApiKeysReq,
|
||||
AdminPostPublishableApiKeysPublishableApiKeyReq,
|
||||
} from "@medusajs/medusa"
|
||||
|
||||
import { ResponsePromise } from "../../typings"
|
||||
@@ -41,13 +43,22 @@ class AdminPublishableApiKeyResource extends BaseResource {
|
||||
}
|
||||
|
||||
create(
|
||||
payload: {},
|
||||
payload: AdminPostPublishableApiKeysReq,
|
||||
customHeaders: Record<string, any> = {}
|
||||
): ResponsePromise<AdminPublishableApiKeysRes> {
|
||||
const path = `/admin/publishable-api-keys`
|
||||
return this.client.request("POST", path, payload, {}, customHeaders)
|
||||
}
|
||||
|
||||
update(
|
||||
id: string,
|
||||
payload: AdminPostPublishableApiKeysPublishableApiKeyReq,
|
||||
customHeaders: Record<string, any> = {}
|
||||
) {
|
||||
const path = `/admin/publishable-api-keys/${id}`
|
||||
return this.client.request("POST", path, payload, {}, customHeaders)
|
||||
}
|
||||
|
||||
delete(
|
||||
id: string,
|
||||
customHeaders: Record<string, any> = {}
|
||||
|
||||
@@ -980,6 +980,18 @@ export const adminHandlers = [
|
||||
)
|
||||
}),
|
||||
|
||||
rest.post("/admin/publishable-api-keys/:id", (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/", (req, res, ctx) => {
|
||||
return res(
|
||||
ctx.status(200),
|
||||
|
||||
@@ -4,6 +4,8 @@ import { Response } from "@medusajs/medusa-js"
|
||||
import {
|
||||
AdminPublishableApiKeyDeleteRes,
|
||||
AdminPublishableApiKeysRes,
|
||||
AdminPostPublishableApiKeysPublishableApiKeyReq,
|
||||
AdminPostPublishableApiKeysReq,
|
||||
} from "@medusajs/medusa"
|
||||
|
||||
import { buildOptions } from "../../utils/buildOptions"
|
||||
@@ -11,16 +13,47 @@ import { useMedusa } from "../../../contexts"
|
||||
import { adminPublishableApiKeysKeys } from "."
|
||||
|
||||
export const useAdminCreatePublishableApiKey = (
|
||||
options?: UseMutationOptions<Response<AdminPublishableApiKeysRes>, Error, {}>
|
||||
options?: UseMutationOptions<
|
||||
Response<AdminPublishableApiKeysRes>,
|
||||
Error,
|
||||
AdminPostPublishableApiKeysReq
|
||||
>
|
||||
) => {
|
||||
const { client } = useMedusa()
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation(
|
||||
(payload: {}) => client.admin.publishableApiKeys.create(payload),
|
||||
(payload: AdminPostPublishableApiKeysReq) =>
|
||||
client.admin.publishableApiKeys.create(payload),
|
||||
buildOptions(queryClient, [adminPublishableApiKeysKeys.lists()], options)
|
||||
)
|
||||
}
|
||||
|
||||
export const useAdminUpdatePublishableApiKey = (
|
||||
id: string,
|
||||
options?: UseMutationOptions<
|
||||
Response<AdminPublishableApiKeysRes>,
|
||||
Error,
|
||||
AdminPostPublishableApiKeysPublishableApiKeyReq
|
||||
>
|
||||
) => {
|
||||
const { client } = useMedusa()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation(
|
||||
(payload: AdminPostPublishableApiKeysPublishableApiKeyReq) =>
|
||||
client.admin.publishableApiKeys.update(id, payload),
|
||||
buildOptions(
|
||||
queryClient,
|
||||
[
|
||||
adminPublishableApiKeysKeys.lists(),
|
||||
adminPublishableApiKeysKeys.detail(id),
|
||||
adminPublishableApiKeysKeys.details(),
|
||||
],
|
||||
options
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export const useAdminDeletePublishableApiKey = (
|
||||
id: string,
|
||||
options?: UseMutationOptions<
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { renderHook } from "@testing-library/react-hooks"
|
||||
|
||||
import { createWrapper } from "../../../utils"
|
||||
import {
|
||||
useAdminDeletePublishableApiKey,
|
||||
useAdminRevokePublishableApiKey,
|
||||
useAdminUpdatePublishableApiKey,
|
||||
useAdminCreatePublishableApiKey,
|
||||
} from "../../../../src"
|
||||
import { createWrapper } from "../../../utils"
|
||||
import { fixtures } from "../../../../mocks/data"
|
||||
import { useAdminCreatePublishableApiKey } from "../../../../src"
|
||||
|
||||
describe("useAdminCreatePublishableApiKey hook", () => {
|
||||
test("Created a publishable api key", async () => {
|
||||
@@ -17,7 +18,7 @@ describe("useAdminCreatePublishableApiKey hook", () => {
|
||||
}
|
||||
)
|
||||
|
||||
result.current.mutate({})
|
||||
result.current.mutate({ title: "Mandatory title" })
|
||||
|
||||
await waitFor(() => result.current.isSuccess)
|
||||
|
||||
@@ -25,6 +26,7 @@ describe("useAdminCreatePublishableApiKey hook", () => {
|
||||
expect(result.current.data).toEqual(
|
||||
expect.objectContaining({
|
||||
publishable_api_key: {
|
||||
title: "Mandatory title",
|
||||
...fixtures.get("publishable_api_key"),
|
||||
},
|
||||
})
|
||||
@@ -32,6 +34,34 @@ describe("useAdminCreatePublishableApiKey hook", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("useAdminUpdatePublishableApiKey hook", () => {
|
||||
test("updates an publishable key and returns it", async () => {
|
||||
const pubKey = {
|
||||
title: "changed title",
|
||||
}
|
||||
|
||||
const { result, waitFor } = renderHook(
|
||||
() =>
|
||||
useAdminUpdatePublishableApiKey(fixtures.get("publishable_api_key").id),
|
||||
{
|
||||
wrapper: createWrapper(),
|
||||
}
|
||||
)
|
||||
|
||||
result.current.mutate(pubKey)
|
||||
|
||||
await waitFor(() => result.current.isSuccess)
|
||||
|
||||
expect(result.current.data.response.status).toEqual(200)
|
||||
expect(result.current.data.publishable_api_key).toEqual(
|
||||
expect.objectContaining({
|
||||
...fixtures.get("publishable_api_key"),
|
||||
...pubKey,
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("useAdminRevokePublishableApiKey hook", () => {
|
||||
test("Revoke a publishable api key", async () => {
|
||||
const id = "pubkey_1234"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Request, Response } from "express"
|
||||
import { EntityManager } from "typeorm"
|
||||
import { IsString } from "class-validator"
|
||||
|
||||
import PublishableApiKeyService from "../../../../services/publishable-api-key"
|
||||
|
||||
@@ -8,6 +9,16 @@ import PublishableApiKeyService from "../../../../services/publishable-api-key"
|
||||
* operationId: "PostPublishableApiKeys"
|
||||
* summary: "Create a PublishableApiKey"
|
||||
* description: "Creates a PublishableApiKey."
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* required:
|
||||
* - title
|
||||
* properties:
|
||||
* title:
|
||||
* description: A title for the publishable api key
|
||||
* type: string
|
||||
* x-authenticated: true
|
||||
* x-codeSamples:
|
||||
* - lang: JavaScript
|
||||
@@ -59,14 +70,20 @@ export default async (req: Request, res: Response) => {
|
||||
) as PublishableApiKeyService
|
||||
|
||||
const manager = req.scope.resolve("manager") as EntityManager
|
||||
const data = req.validatedBody as AdminPostPublishableApiKeysReq
|
||||
|
||||
const loggedInUserId = (req.user?.id ?? req.user?.userId) as string
|
||||
|
||||
const pubKey = await manager.transaction(async (transactionManager) => {
|
||||
return await publishableApiKeyService
|
||||
.withTransaction(transactionManager)
|
||||
.create({ loggedInUserId })
|
||||
.create(data, { loggedInUserId })
|
||||
})
|
||||
|
||||
return res.status(200).json({ publishable_api_key: pubKey })
|
||||
}
|
||||
|
||||
export class AdminPostPublishableApiKeysReq {
|
||||
@IsString()
|
||||
title: string
|
||||
}
|
||||
|
||||
@@ -2,10 +2,15 @@ import { Router } from "express"
|
||||
|
||||
import { isFeatureFlagEnabled } from "../../../middlewares/feature-flag-enabled"
|
||||
import PublishableAPIKeysFeatureFlag from "../../../../loaders/feature-flags/publishable-api-keys"
|
||||
import middlewares, { transformQuery } from "../../../middlewares"
|
||||
import middlewares, {
|
||||
transformBody,
|
||||
transformQuery,
|
||||
} from "../../../middlewares"
|
||||
import { GetPublishableApiKeysParams } from "./list-publishable-api-keys"
|
||||
import { PublishableApiKey } from "../../../../models"
|
||||
import { DeleteResponse, PaginatedResponse } from "../../../../types/common"
|
||||
import { AdminPostPublishableApiKeysReq } from "./create-publishable-api-key"
|
||||
import { AdminPostPublishableApiKeysPublishableApiKeyReq } from "./update-publishable-api-key"
|
||||
|
||||
const route = Router()
|
||||
|
||||
@@ -18,6 +23,7 @@ export default (app) => {
|
||||
|
||||
route.post(
|
||||
"/",
|
||||
transformBody(AdminPostPublishableApiKeysReq),
|
||||
middlewares.wrap(require("./create-publishable-api-key").default)
|
||||
)
|
||||
|
||||
@@ -26,6 +32,12 @@ export default (app) => {
|
||||
middlewares.wrap(require("./get-publishable-api-key").default)
|
||||
)
|
||||
|
||||
route.post(
|
||||
"/:id",
|
||||
transformBody(AdminPostPublishableApiKeysPublishableApiKeyReq),
|
||||
middlewares.wrap(require("./update-publishable-api-key").default)
|
||||
)
|
||||
|
||||
route.delete(
|
||||
"/:id",
|
||||
middlewares.wrap(require("./delete-publishable-api-key").default)
|
||||
@@ -54,3 +66,5 @@ export type AdminPublishableApiKeysListRes = PaginatedResponse & {
|
||||
export type AdminPublishableApiKeyDeleteRes = DeleteResponse
|
||||
|
||||
export * from "./list-publishable-api-keys"
|
||||
export * from "./create-publishable-api-key"
|
||||
export * from "./update-publishable-api-key"
|
||||
|
||||
@@ -11,7 +11,7 @@ import PublishableApiKeyService from "../../../../services/publishable-api-key"
|
||||
* description: "List PublishableApiKeys."
|
||||
* x-authenticated: true
|
||||
* parameters:
|
||||
* - (query) order_id {string} List publishable keys by id.
|
||||
* - (query) q {string} Query used for searching publishable api keys by title.
|
||||
* - (query) limit=20 {number} The number of items in the response
|
||||
* - (query) offset=0 {number} The offset of items in response
|
||||
* - (query) expand {string} Comma separated list of relations to include in the results.
|
||||
@@ -84,4 +84,8 @@ export default async (req: Request, res: Response) => {
|
||||
export class GetPublishableApiKeysParams extends extendedFindParamsMixin({
|
||||
limit: 20,
|
||||
offset: 0,
|
||||
}) {}
|
||||
}) {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
q?: string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import { Request, Response } from "express"
|
||||
import { IsOptional, IsString } from "class-validator"
|
||||
import { EntityManager } from "typeorm"
|
||||
|
||||
import PublishableApiKeyService from "../../../../services/publishable-api-key"
|
||||
|
||||
/**
|
||||
* @oas [post] /publishable-api-key/{id}
|
||||
* operationId: "PostPublishableApiKysPublishableApiKey"
|
||||
* summary: "Updates a PublishableApiKey"
|
||||
* description: "Updates a PublishableApiKey."
|
||||
* x-authenticated: true
|
||||
* parameters:
|
||||
* - (path) id=* {string} The ID of the PublishableApiKey.
|
||||
* requestBody:
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* title:
|
||||
* description: A title to update for the key.
|
||||
* type: string
|
||||
* x-codeSamples:
|
||||
* - lang: JavaScript
|
||||
* label: JS Client
|
||||
* source: |
|
||||
* import Medusa from "@medusajs/medusa-js"
|
||||
* const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 })
|
||||
* // must be previously logged in or use api token
|
||||
* medusa.admin.publishableApiKey.update(publishable_key_id, {
|
||||
* title: "new title"
|
||||
* })
|
||||
* .then(({ publishable_api_key }) => {
|
||||
* console.log(publishable_api_key.id)
|
||||
* })
|
||||
* - lang: Shell
|
||||
* label: cURL
|
||||
* source: |
|
||||
* curl --location --request POST 'https://medusa-url.com/admin/publishable-api-key/{id}' \
|
||||
* --header 'Authorization: Bearer {api_token}' \
|
||||
* --header 'Content-Type: application/json' \
|
||||
* --data-raw '{
|
||||
* "title": "updated title"
|
||||
* }'
|
||||
* security:
|
||||
* - api_token: []
|
||||
* - cookie_auth: []
|
||||
* tags:
|
||||
* - PublishableApiKey
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* publishable_api_key:
|
||||
* $ref: "#/components/schemas/publishable_api_key"
|
||||
* "400":
|
||||
* $ref: "#/components/responses/400_error"
|
||||
* "401":
|
||||
* $ref: "#/components/responses/unauthorized"
|
||||
* "404":
|
||||
* $ref: "#/components/responses/not_found_error"
|
||||
* "409":
|
||||
* $ref: "#/components/responses/invalid_state_error"
|
||||
* "422":
|
||||
* $ref: "#/components/responses/invalid_request_error"
|
||||
* "500":
|
||||
* $ref: "#/components/responses/500_error"
|
||||
*/
|
||||
export default async (req: Request, res: Response) => {
|
||||
const { id } = req.params
|
||||
const { validatedBody } = req as {
|
||||
validatedBody: AdminPostPublishableApiKeysPublishableApiKeyReq
|
||||
}
|
||||
|
||||
const publishableApiKeysService: PublishableApiKeyService = req.scope.resolve(
|
||||
"publishableApiKeyService"
|
||||
)
|
||||
|
||||
const manager: EntityManager = req.scope.resolve("manager")
|
||||
|
||||
const updatedKey = await manager.transaction(async (transactionManager) => {
|
||||
return await publishableApiKeysService
|
||||
.withTransaction(transactionManager)
|
||||
.update(id, validatedBody)
|
||||
})
|
||||
|
||||
res.status(200).json({ publishable_api_key: updatedKey })
|
||||
}
|
||||
|
||||
export class AdminPostPublishableApiKeysPublishableApiKeyReq {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
title?: string
|
||||
}
|
||||
@@ -12,7 +12,7 @@ export class publishableApiKey1667815005070 implements MigrationInterface {
|
||||
`CREATE TABLE "publishable_api_key_sales_channel" ("sales_channel_id" character varying NOT NULL, "publishable_key_id" character varying NOT NULL, CONSTRAINT "PK_68eaeb14bdac8954460054c567c" PRIMARY KEY ("sales_channel_id", "publishable_key_id"))`
|
||||
)
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "publishable_api_key" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "created_by" character varying, "revoked_by" character varying, "revoked_at" TIMESTAMP WITH TIME ZONE, CONSTRAINT "PK_9e613278673a87de92c606b4494" PRIMARY KEY ("id"))`
|
||||
`CREATE TABLE "publishable_api_key" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "created_by" character varying, "revoked_by" character varying, "revoked_at" TIMESTAMP WITH TIME ZONE, "title" character varying NOT NULL, CONSTRAINT "PK_9e613278673a87de92c606b4494" PRIMARY KEY ("id"))`
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,12 @@ export class PublishableApiKey extends BaseEntity {
|
||||
@Column({ type: resolveDbType("timestamptz"), nullable: true })
|
||||
revoked_at?: Date
|
||||
|
||||
@Column()
|
||||
title: string
|
||||
|
||||
@BeforeInsert()
|
||||
private beforeInsert(): void {
|
||||
this.id = generateEntityId(this.id, "pubkey")
|
||||
this.id = generateEntityId(this.id, "pk")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +35,7 @@ export class PublishableApiKey extends BaseEntity {
|
||||
* id:
|
||||
* type: string
|
||||
* description: The key's ID
|
||||
* example: pak_01G1G5V27GYX4QXNARRQCW1N8T
|
||||
* example: pk_01G1G5V27GYX4QXNARRQCW1N8T
|
||||
* created_by:
|
||||
* type: string
|
||||
* description: "The unique identifier of the user that created the key."
|
||||
|
||||
@@ -48,13 +48,17 @@ describe("PublishableApiKeyService", () => {
|
||||
})
|
||||
|
||||
it("should create a publishable api key and call the repository with the right arguments as well as the event bus service", async () => {
|
||||
await publishableApiKeyService.create({
|
||||
loggedInUserId: IdMap.getId("admin_user"),
|
||||
})
|
||||
await publishableApiKeyService.create(
|
||||
{ title: "API key title" },
|
||||
{
|
||||
loggedInUserId: IdMap.getId("admin_user"),
|
||||
}
|
||||
)
|
||||
|
||||
expect(publishableApiKeyRepository.create).toHaveBeenCalledTimes(1)
|
||||
expect(publishableApiKeyRepository.create).toHaveBeenCalledWith({
|
||||
created_by: IdMap.getId("admin_user"),
|
||||
title: "API key title",
|
||||
})
|
||||
expect(EventBusServiceMock.emit).toHaveBeenCalledTimes(1)
|
||||
expect(EventBusServiceMock.emit).toHaveBeenCalledWith(
|
||||
@@ -63,6 +67,19 @@ describe("PublishableApiKeyService", () => {
|
||||
)
|
||||
})
|
||||
|
||||
it("should update a publishable api key", async () => {
|
||||
await publishableApiKeyService.update(pubKeyToRetrieve.id, {
|
||||
title: "new title",
|
||||
})
|
||||
|
||||
expect(publishableApiKeyRepository.save).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
id: pubKeyToRetrieve.id,
|
||||
title: "new title",
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should revoke a publishable api key", async () => {
|
||||
await publishableApiKeyService.revoke("id", {
|
||||
loggedInUserId: IdMap.getId("admin_user"),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { EntityManager } from "typeorm"
|
||||
import { EntityManager, ILike } from "typeorm"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
|
||||
import { PublishableApiKeyRepository } from "../repositories/publishable-api-key"
|
||||
@@ -6,7 +6,11 @@ import { FindConfig, Selector } from "../types/common"
|
||||
import { PublishableApiKey } from "../models"
|
||||
import { TransactionBaseService } from "../interfaces"
|
||||
import EventBusService from "./event-bus"
|
||||
import { buildQuery } from "../utils"
|
||||
import { buildQuery, isDefined, isString } from "../utils"
|
||||
import {
|
||||
CreatePublishableApiKeyInput,
|
||||
UpdatePublishableApiKeyInput,
|
||||
} from "../types/publishable-api-key"
|
||||
|
||||
type InjectedDependencies = {
|
||||
manager: EntityManager
|
||||
@@ -45,17 +49,22 @@ class PublishableApiKeyService extends TransactionBaseService {
|
||||
/**
|
||||
* Create a PublishableApiKey record.
|
||||
*
|
||||
* @params context - key creation context object
|
||||
* @param data - partial data for creating the entity
|
||||
* @param context - key creation context object
|
||||
*/
|
||||
async create(context: {
|
||||
loggedInUserId: string
|
||||
}): Promise<PublishableApiKey | never> {
|
||||
async create(
|
||||
data: CreatePublishableApiKeyInput,
|
||||
context: {
|
||||
loggedInUserId: string
|
||||
}
|
||||
): Promise<PublishableApiKey | never> {
|
||||
return await this.atomicPhase_(async (manager) => {
|
||||
const publishableApiKeyRepo = manager.getCustomRepository(
|
||||
this.publishableApiKeyRepository_
|
||||
)
|
||||
|
||||
const publishableApiKey = publishableApiKeyRepo.create({
|
||||
...data,
|
||||
created_by: context.loggedInUserId,
|
||||
})
|
||||
|
||||
@@ -122,7 +131,7 @@ class PublishableApiKeyService extends TransactionBaseService {
|
||||
* @return an array containing publishable API keys and a total count of records that matches the query
|
||||
*/
|
||||
async listAndCount(
|
||||
selector: Selector<PublishableApiKey>,
|
||||
selector: Selector<PublishableApiKey> & { q?: string },
|
||||
config: FindConfig<PublishableApiKey> = {
|
||||
skip: 0,
|
||||
take: 20,
|
||||
@@ -133,11 +142,44 @@ class PublishableApiKeyService extends TransactionBaseService {
|
||||
this.publishableApiKeyRepository_
|
||||
)
|
||||
|
||||
let q
|
||||
if (isString(selector.q)) {
|
||||
q = selector.q
|
||||
delete selector.q
|
||||
}
|
||||
|
||||
const query = buildQuery(selector, config)
|
||||
|
||||
if (q) {
|
||||
query.where.title = ILike(`%${q}%`)
|
||||
}
|
||||
|
||||
return await pubKeyRepo.findAndCount(query)
|
||||
}
|
||||
|
||||
async update(
|
||||
publishableApiKeyId: string,
|
||||
data: UpdatePublishableApiKeyInput
|
||||
): Promise<PublishableApiKey> {
|
||||
{
|
||||
return await this.atomicPhase_(async (manager) => {
|
||||
const publishableApiKeyRepository = manager.getCustomRepository(
|
||||
this.publishableApiKeyRepository_
|
||||
)
|
||||
|
||||
const pubKey = await this.retrieve(publishableApiKeyId)
|
||||
|
||||
for (const key of Object.keys(data)) {
|
||||
if (isDefined(data[key])) {
|
||||
pubKey[key] = data[key]
|
||||
}
|
||||
}
|
||||
|
||||
return await publishableApiKeyRepository.save(pubKey)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Publishable API key.
|
||||
*
|
||||
|
||||
7
packages/medusa/src/types/publishable-api-key.ts
Normal file
7
packages/medusa/src/types/publishable-api-key.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export type CreatePublishableApiKeyInput = {
|
||||
title: string
|
||||
}
|
||||
|
||||
export type UpdatePublishableApiKeyInput = {
|
||||
title?: string
|
||||
}
|
||||
Reference in New Issue
Block a user