-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(medusa): added admin create endpoint for nested categories #2985
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
2bbcf6b
chore: added admin create endpoint for nested categories
riqwan f0d7e42
Merge branch 'develop' into feat/nested-category-create-endpoint
riqwan d8d59f6
chore: move factory create into test
riqwan 989cdf9
chore: address pr review comments
riqwan ada3937
Merge branch 'develop' into feat/nested-category-create-endpoint
riqwan 107f28d
chore: remove optional comment from oas
riqwan 98d2f93
chore: make handle optional, create before insert
riqwan 1399cb4
chore: update oas description for handle
riqwan bbc0b3e
Merge branch 'develop' into feat/nested-category-create-endpoint
olivermrbl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@medusajs/medusa": patch | ||
--- | ||
|
||
feat(medusa): added admin create endpoint for product categories |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
126 changes: 126 additions & 0 deletions
126
packages/medusa/src/api/routes/admin/product-categories/create-product-category.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import { IsNotEmpty, IsOptional, IsString, IsBoolean } from "class-validator" | ||
import { Request, Response } from "express" | ||
import { EntityManager } from "typeorm" | ||
|
||
import { ProductCategoryService } from "../../../../services" | ||
import { AdminProductCategoriesReqBase } from "../../../../types/product-category" | ||
import { FindParams } from "../../../../types/common" | ||
|
||
/** | ||
* @oas [post] /product-categories | ||
* operationId: "PostProductCategories" | ||
* summary: "Create a Product Category" | ||
* description: "Creates a Product Category." | ||
* x-authenticated: true | ||
* parameters: | ||
* - (query) expand {string} (Comma separated) Which fields should be expanded in each product category. | ||
* - (query) fields {string} (Comma separated) Which fields should be retrieved in each product category. | ||
* requestBody: | ||
* content: | ||
* application/json: | ||
* schema: | ||
* $ref: "#/components/schemas/AdminPostProductCategoriesReq" | ||
* 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.productCategories.create({ | ||
* name: 'Jeans', | ||
* }) | ||
* .then(({ productCategory }) => { | ||
* console.log(productCategory.id); | ||
* }); | ||
* - lang: Shell | ||
* label: cURL | ||
* source: | | ||
* curl --location --request POST 'https://medusa-url.com/admin/product-categories' \ | ||
* --header 'Authorization: Bearer {api_token}' \ | ||
* --header 'Content-Type: application/json' \ | ||
* --data-raw '{ | ||
* "name": "Jeans", | ||
* }' | ||
* security: | ||
* - api_token: [] | ||
* - cookie_auth: [] | ||
* tags: | ||
* - Product Category | ||
* responses: | ||
* "200": | ||
* description: OK | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* properties: | ||
* productCategory: | ||
* $ref: "#/components/schemas/ProductCategory" | ||
* "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 { validatedBody } = req as { | ||
validatedBody: AdminPostProductCategoriesReq | ||
} | ||
|
||
const productCategoryService: ProductCategoryService = req.scope.resolve( | ||
"productCategoryService" | ||
) | ||
|
||
const manager: EntityManager = req.scope.resolve("manager") | ||
const created = await manager.transaction(async (transactionManager) => { | ||
return await productCategoryService | ||
.withTransaction(transactionManager) | ||
.create(validatedBody) | ||
}) | ||
|
||
const productCategory = await productCategoryService.retrieve( | ||
created.id, | ||
req.retrieveConfig, | ||
) | ||
|
||
res.status(200).json({ product_category: productCategory }) | ||
} | ||
|
||
/** | ||
* @schema AdminPostProductCategoriesReq | ||
riqwan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* type: object | ||
* required: | ||
* - name | ||
* properties: | ||
* name: | ||
* type: string | ||
* description: The name to identify the Product Category by. | ||
* handle: | ||
* type: string | ||
* description: An optional handle to be used in slugs, if none is provided we will kebab-case the title. | ||
* is_internal: | ||
* type: boolean | ||
* description: A flag to make product category an internal category for admins | ||
* is_active: | ||
* type: boolean | ||
* description: A flag to make product category visible/hidden in the store front | ||
* parent_category_id: | ||
* type: string | ||
* description: The ID of the parent product category | ||
*/ | ||
// eslint-disable-next-line max-len | ||
export class AdminPostProductCategoriesReq extends AdminProductCategoriesReqBase { | ||
@IsString() | ||
@IsNotEmpty() | ||
name: string | ||
} | ||
|
||
export class AdminPostProductCategoriesParams extends FindParams {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import { generateEntityId } from "../utils/generate-entity-id" | ||
import { SoftDeletableEntity } from "../interfaces/models/soft-deletable-entity" | ||
import { kebabCase } from "lodash" | ||
import { | ||
BeforeInsert, | ||
Index, | ||
|
@@ -41,14 +42,18 @@ export class ProductCategory extends SoftDeletableEntity { | |
|
||
// Typeorm also keeps track of the category's parent at all times. | ||
@Column() | ||
parent_category_id: ProductCategory | ||
parent_category_id: string | null | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice catch 🙏 |
||
|
||
@TreeChildren({ cascade: true }) | ||
category_children: ProductCategory[] | ||
|
||
@BeforeInsert() | ||
private beforeInsert(): void { | ||
this.id = generateEntityId(this.id, "pcat") | ||
|
||
if (!this.handle) { | ||
this.handle = kebabCase(this.name) | ||
} | ||
} | ||
} | ||
|
||
|
@@ -60,7 +65,6 @@ export class ProductCategory extends SoftDeletableEntity { | |
* type: object | ||
* required: | ||
* - name | ||
* - handle | ||
* properties: | ||
* id: | ||
* type: string | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
non blocking: should we add a tests without passing the handle to also assert that this behaviour do not broke at some point?