@csbeker/medusa-product-attributes 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/admin/index.js +9012 -0
- package/.medusa/server/src/admin/index.mjs +9010 -0
- package/.medusa/server/src/api/admin/middlewares.js +10 -0
- package/.medusa/server/src/api/admin/plugin/attribute-set/[id]/attributes/route.js +17 -0
- package/.medusa/server/src/api/admin/plugin/attribute-set/[id]/route.js +33 -0
- package/.medusa/server/src/api/admin/plugin/attribute-set/middlewares.js +44 -0
- package/.medusa/server/src/api/admin/plugin/attribute-set/query-config.js +22 -0
- package/.medusa/server/src/api/admin/plugin/attribute-set/route.js +25 -0
- package/.medusa/server/src/api/admin/plugin/attribute-set/validators.js +37 -0
- package/.medusa/server/src/api/admin/plugin/attributes/[id]/route.js +68 -0
- package/.medusa/server/src/api/admin/plugin/attributes/[id]/values/[valueId]/route.js +37 -0
- package/.medusa/server/src/api/admin/plugin/attributes/[id]/values/route.js +31 -0
- package/.medusa/server/src/api/admin/plugin/attributes/middlewares.js +103 -0
- package/.medusa/server/src/api/admin/plugin/attributes/query-config.js +41 -0
- package/.medusa/server/src/api/admin/plugin/attributes/route.js +28 -0
- package/.medusa/server/src/api/admin/plugin/attributes/validators.js +69 -0
- package/.medusa/server/src/api/admin/plugin/route.js +7 -0
- package/.medusa/server/src/api/middlewares.js +12 -0
- package/.medusa/server/src/api/store/middlewares.js +8 -0
- package/.medusa/server/src/api/store/plugin/attributes/middlewares.js +64 -0
- package/.medusa/server/src/api/store/plugin/attributes/products/middlewares.js +100 -0
- package/.medusa/server/src/api/store/plugin/attributes/products/query-config.js +20 -0
- package/.medusa/server/src/api/store/plugin/attributes/products/route.js +48 -0
- package/.medusa/server/src/api/store/plugin/attributes/products/validators.js +39 -0
- package/.medusa/server/src/api/store/plugin/attributes/query-config.js +21 -0
- package/.medusa/server/src/api/store/plugin/attributes/route.js +15 -0
- package/.medusa/server/src/api/store/plugin/attributes/validators.js +14 -0
- package/.medusa/server/src/api/store/plugin/route.js +7 -0
- package/.medusa/server/src/api/utils/common-validators.js +23 -0
- package/.medusa/server/src/api/utils/constants.js +6 -0
- package/.medusa/server/src/api/utils/middlewares.js +34 -0
- package/.medusa/server/src/links/attribute-product-category.js +16 -0
- package/.medusa/server/src/links/attribute-value-product.js +16 -0
- package/.medusa/server/src/modules/attribute/events/index.js +8 -0
- package/.medusa/server/src/modules/attribute/index.js +13 -0
- package/.medusa/server/src/modules/attribute/migrations/Migration20250319161229.js +24 -0
- package/.medusa/server/src/modules/attribute/migrations/Migration20250320182643.js +16 -0
- package/.medusa/server/src/modules/attribute/migrations/Migration20250321162638.js +14 -0
- package/.medusa/server/src/modules/attribute/migrations/Migration20250505144933.js +23 -0
- package/.medusa/server/src/modules/attribute/migrations/Migration20250505201747.js +21 -0
- package/.medusa/server/src/modules/attribute/migrations/Migration20250506162300.js +14 -0
- package/.medusa/server/src/modules/attribute/migrations/Migration20250611160552.js +14 -0
- package/.medusa/server/src/modules/attribute/migrations/Migration20250611173345.js +16 -0
- package/.medusa/server/src/modules/attribute/migrations/Migration20250612192857.js +16 -0
- package/.medusa/server/src/modules/attribute/models/attribute-possible-value.js +24 -0
- package/.medusa/server/src/modules/attribute/models/attribute-set.js +22 -0
- package/.medusa/server/src/modules/attribute/models/attribute-value.js +17 -0
- package/.medusa/server/src/modules/attribute/models/attribute.js +27 -0
- package/.medusa/server/src/modules/attribute/service.js +84 -0
- package/.medusa/server/src/modules/attribute/types/attribute/common.js +13 -0
- package/.medusa/server/src/modules/attribute/types/attribute/index.js +18 -0
- package/.medusa/server/src/modules/attribute/types/attribute-set/index.js +18 -0
- package/.medusa/server/src/modules/attribute/types/attribute-set/mutations.js +3 -0
- package/.medusa/server/src/modules/attribute/types/attribute-value/index.js +18 -0
- package/.medusa/server/src/modules/attribute/types/attribute-value/mutations.js +3 -0
- package/.medusa/server/src/modules/attribute/types/index.js +20 -0
- package/.medusa/server/src/types/attribute/common.js +3 -0
- package/.medusa/server/src/types/attribute/http/attribute/admin/index.js +3 -0
- package/.medusa/server/src/types/attribute/http/attribute/index.js +18 -0
- package/.medusa/server/src/types/attribute/http/attribute-set/index.js +3 -0
- package/.medusa/server/src/types/attribute/http/index.js +19 -0
- package/.medusa/server/src/types/attribute/index.js +19 -0
- package/.medusa/server/src/utils/index.js +18 -0
- package/.medusa/server/src/utils/products-created-handler.js +22 -0
- package/.medusa/server/src/utils/products-updated-handler.js +58 -0
- package/.medusa/server/src/utils/validate-attribute-values-to-link.js +43 -0
- package/.medusa/server/src/workflows/attribute/index.js +19 -0
- package/.medusa/server/src/workflows/attribute/steps/create-attribute-possible-values.js +18 -0
- package/.medusa/server/src/workflows/attribute/steps/create-attributes.js +27 -0
- package/.medusa/server/src/workflows/attribute/steps/delete-attribute.js +31 -0
- package/.medusa/server/src/workflows/attribute/steps/index.js +21 -0
- package/.medusa/server/src/workflows/attribute/steps/update-attributes.js +34 -0
- package/.medusa/server/src/workflows/attribute/workflows/create-attribute-possible-values.js +11 -0
- package/.medusa/server/src/workflows/attribute/workflows/create-attributes.js +46 -0
- package/.medusa/server/src/workflows/attribute/workflows/delete-attribute.js +10 -0
- package/.medusa/server/src/workflows/attribute/workflows/index.js +20 -0
- package/.medusa/server/src/workflows/attribute/workflows/update-attributes.js +73 -0
- package/.medusa/server/src/workflows/attribute-set/steps/batch-link-attribute-set-attributes.js +66 -0
- package/.medusa/server/src/workflows/attribute-set/steps/create-attribute-set.js +24 -0
- package/.medusa/server/src/workflows/attribute-set/steps/index.js +20 -0
- package/.medusa/server/src/workflows/attribute-set/steps/update-attribute-set.js +22 -0
- package/.medusa/server/src/workflows/attribute-set/workflows/batch-link-attribute-set-attributes.js +10 -0
- package/.medusa/server/src/workflows/attribute-set/workflows/create-attribute-set.js +11 -0
- package/.medusa/server/src/workflows/attribute-set/workflows/index.js +20 -0
- package/.medusa/server/src/workflows/attribute-set/workflows/update-attribute-set.js +10 -0
- package/.medusa/server/src/workflows/attribute-value/steps/create-attribute-value.js +18 -0
- package/.medusa/server/src/workflows/attribute-value/steps/delete-attribute-value.js +18 -0
- package/.medusa/server/src/workflows/attribute-value/steps/index.js +20 -0
- package/.medusa/server/src/workflows/attribute-value/steps/validate-attribute-value.js +53 -0
- package/.medusa/server/src/workflows/attribute-value/workflow/create-attribute-value.js +28 -0
- package/.medusa/server/src/workflows/attribute-value/workflow/delete-attribute-value.js +38 -0
- package/.medusa/server/src/workflows/attribute-value/workflow/index.js +19 -0
- package/.medusa/server/src/workflows/attribute_possible_value/index.js +19 -0
- package/.medusa/server/src/workflows/attribute_possible_value/steps/index.js +18 -0
- package/.medusa/server/src/workflows/attribute_possible_value/steps/update-attribute-possible-value.js +18 -0
- package/.medusa/server/src/workflows/attribute_possible_value/workflows/index.js +18 -0
- package/.medusa/server/src/workflows/attribute_possible_value/workflows/update-attribute-possible-value.js +11 -0
- package/.medusa/server/src/workflows/index.js +18 -0
- package/CHANGELOG.md +104 -0
- package/README.md +86 -0
- package/package.json +90 -0
- package/src/admin/README.md +31 -0
- package/src/admin/components/metadata-editor/index.tsx +101 -0
- package/src/admin/components/section-row.tsx +41 -0
- package/src/admin/hooks/api/attribute-set.ts +122 -0
- package/src/admin/hooks/api/attributes.ts +126 -0
- package/src/admin/hooks/table/columns/index.ts +1 -0
- package/src/admin/hooks/table/columns/use-attribute-table-columns.tsx +280 -0
- package/src/admin/layouts/single-column.tsx +11 -0
- package/src/admin/lib/config.ts +8 -0
- package/src/admin/lib/query-key-factory.ts +53 -0
- package/src/admin/routes/attributes/[id]/edit/page.tsx +133 -0
- package/src/admin/routes/attributes/[id]/edit-possible-value/page.tsx +174 -0
- package/src/admin/routes/attributes/[id]/page.tsx +127 -0
- package/src/admin/routes/attributes/components/AttributeForm.tsx +301 -0
- package/src/admin/routes/attributes/components/AttributeSetTable.tsx +108 -0
- package/src/admin/routes/attributes/components/category-selection-modal.tsx +82 -0
- package/src/admin/routes/attributes/components/possible-values-table.tsx +119 -0
- package/src/admin/routes/attributes/create/components/MultiSelectCategory.tsx +148 -0
- package/src/admin/routes/attributes/create/components/PossibleValuesList.tsx +151 -0
- package/src/admin/routes/attributes/create/page.tsx +123 -0
- package/src/admin/routes/attributes/create-set/page.tsx +110 -0
- package/src/admin/routes/attributes/page.tsx +346 -0
- package/src/admin/routes/attributes/set/[id]/attributes/page.tsx +35 -0
- package/src/admin/routes/attributes/set/[id]/components/AttributeSetAttributesSection.tsx +114 -0
- package/src/admin/routes/attributes/set/[id]/components/AttributeSetGeneralSection.tsx +42 -0
- package/src/admin/routes/attributes/set/[id]/components/attribute-set-attributes-form.tsx +143 -0
- package/src/admin/routes/attributes/set/[id]/components/index.ts +2 -0
- package/src/admin/routes/attributes/set/[id]/edit/page.tsx +119 -0
- package/src/admin/routes/attributes/set/[id]/page.tsx +45 -0
- package/src/admin/tsconfig.json +27 -0
- package/src/admin/types/global.d.ts +3 -0
- package/src/admin/vite-env.d.ts +1 -0
- package/src/api/README.md +133 -0
- package/src/api/admin/middlewares.ts +8 -0
- package/src/api/admin/plugin/attribute-set/[id]/attributes/route.ts +17 -0
- package/src/api/admin/plugin/attribute-set/[id]/route.ts +41 -0
- package/src/api/admin/plugin/attribute-set/middlewares.ts +42 -0
- package/src/api/admin/plugin/attribute-set/query-config.ts +20 -0
- package/src/api/admin/plugin/attribute-set/route.ts +34 -0
- package/src/api/admin/plugin/attribute-set/validators.ts +45 -0
- package/src/api/admin/plugin/attributes/[id]/route.ts +85 -0
- package/src/api/admin/plugin/attributes/[id]/values/[valueId]/route.ts +41 -0
- package/src/api/admin/plugin/attributes/[id]/values/route.ts +39 -0
- package/src/api/admin/plugin/attributes/middlewares.ts +91 -0
- package/src/api/admin/plugin/attributes/query-config.ts +42 -0
- package/src/api/admin/plugin/attributes/route.ts +33 -0
- package/src/api/admin/plugin/attributes/validators.ts +91 -0
- package/src/api/admin/plugin/route.ts +8 -0
- package/src/api/middlewares.ts +10 -0
- package/src/api/store/middlewares.ts +6 -0
- package/src/api/store/plugin/attributes/middlewares.ts +33 -0
- package/src/api/store/plugin/attributes/products/middlewares.ts +73 -0
- package/src/api/store/plugin/attributes/products/query-config.ts +19 -0
- package/src/api/store/plugin/attributes/products/route.ts +68 -0
- package/src/api/store/plugin/attributes/products/validators.ts +55 -0
- package/src/api/store/plugin/attributes/query-config.ts +19 -0
- package/src/api/store/plugin/attributes/route.ts +13 -0
- package/src/api/store/plugin/attributes/validators.ts +14 -0
- package/src/api/store/plugin/route.ts +8 -0
- package/src/api/utils/common-validators.ts +24 -0
- package/src/api/utils/constants.ts +2 -0
- package/src/api/utils/middlewares.ts +31 -0
- package/src/jobs/README.md +36 -0
- package/src/links/README.md +26 -0
- package/src/links/attribute-product-category.ts +14 -0
- package/src/links/attribute-value-product.ts +14 -0
- package/src/modules/README.md +116 -0
- package/src/modules/attribute/events/index.ts +4 -0
- package/src/modules/attribute/index.ts +8 -0
- package/src/modules/attribute/migrations/.snapshot-medusa-attribute.json +624 -0
- package/src/modules/attribute/migrations/Migration20250319161229.ts +27 -0
- package/src/modules/attribute/migrations/Migration20250320182643.ts +15 -0
- package/src/modules/attribute/migrations/Migration20250321162638.ts +13 -0
- package/src/modules/attribute/migrations/Migration20250505144933.ts +26 -0
- package/src/modules/attribute/migrations/Migration20250505201747.ts +23 -0
- package/src/modules/attribute/migrations/Migration20250506162300.ts +13 -0
- package/src/modules/attribute/migrations/Migration20250611160552.ts +13 -0
- package/src/modules/attribute/migrations/Migration20250611173345.ts +17 -0
- package/src/modules/attribute/migrations/Migration20250612192857.ts +17 -0
- package/src/modules/attribute/models/attribute-possible-value.ts +20 -0
- package/src/modules/attribute/models/attribute-set.ts +18 -0
- package/src/modules/attribute/models/attribute-value.ts +13 -0
- package/src/modules/attribute/models/attribute.ts +23 -0
- package/src/modules/attribute/service.ts +102 -0
- package/src/modules/attribute/types/attribute/common.ts +94 -0
- package/src/modules/attribute/types/attribute/index.ts +1 -0
- package/src/modules/attribute/types/attribute-set/index.ts +1 -0
- package/src/modules/attribute/types/attribute-set/mutations.ts +7 -0
- package/src/modules/attribute/types/attribute-value/index.ts +1 -0
- package/src/modules/attribute/types/attribute-value/mutations.ts +5 -0
- package/src/modules/attribute/types/index.ts +3 -0
- package/src/providers/README.md +30 -0
- package/src/subscribers/README.md +59 -0
- package/src/types/attribute/common.ts +173 -0
- package/src/types/attribute/http/attribute/admin/index.ts +0 -0
- package/src/types/attribute/http/attribute/index.ts +42 -0
- package/src/types/attribute/http/attribute-set/index.ts +10 -0
- package/src/types/attribute/http/index.ts +2 -0
- package/src/types/attribute/index.ts +2 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/products-created-handler.ts +35 -0
- package/src/utils/products-updated-handler.ts +74 -0
- package/src/utils/validate-attribute-values-to-link.ts +67 -0
- package/src/workflows/README.md +79 -0
- package/src/workflows/attribute/index.ts +2 -0
- package/src/workflows/attribute/steps/create-attribute-possible-values.ts +29 -0
- package/src/workflows/attribute/steps/create-attributes.ts +35 -0
- package/src/workflows/attribute/steps/delete-attribute.ts +41 -0
- package/src/workflows/attribute/steps/index.ts +4 -0
- package/src/workflows/attribute/steps/update-attributes.ts +45 -0
- package/src/workflows/attribute/workflows/create-attribute-possible-values.ts +17 -0
- package/src/workflows/attribute/workflows/create-attributes.ts +56 -0
- package/src/workflows/attribute/workflows/delete-attribute.ts +15 -0
- package/src/workflows/attribute/workflows/index.ts +3 -0
- package/src/workflows/attribute/workflows/update-attributes.ts +103 -0
- package/src/workflows/attribute-set/steps/batch-link-attribute-set-attributes.ts +82 -0
- package/src/workflows/attribute-set/steps/create-attribute-set.ts +34 -0
- package/src/workflows/attribute-set/steps/index.ts +3 -0
- package/src/workflows/attribute-set/steps/update-attribute-set.ts +32 -0
- package/src/workflows/attribute-set/workflows/batch-link-attribute-set-attributes.ts +12 -0
- package/src/workflows/attribute-set/workflows/create-attribute-set.ts +17 -0
- package/src/workflows/attribute-set/workflows/index.ts +3 -0
- package/src/workflows/attribute-set/workflows/update-attribute-set.ts +14 -0
- package/src/workflows/attribute-value/steps/create-attribute-value.ts +26 -0
- package/src/workflows/attribute-value/steps/delete-attribute-value.ts +26 -0
- package/src/workflows/attribute-value/steps/index.ts +3 -0
- package/src/workflows/attribute-value/steps/validate-attribute-value.ts +95 -0
- package/src/workflows/attribute-value/workflow/create-attribute-value.ts +36 -0
- package/src/workflows/attribute-value/workflow/delete-attribute-value.ts +46 -0
- package/src/workflows/attribute-value/workflow/index.ts +2 -0
- package/src/workflows/attribute_possible_value/index.ts +2 -0
- package/src/workflows/attribute_possible_value/steps/index.ts +1 -0
- package/src/workflows/attribute_possible_value/steps/update-attribute-possible-value.ts +25 -0
- package/src/workflows/attribute_possible_value/workflows/index.ts +1 -0
- package/src/workflows/attribute_possible_value/workflows/update-attribute-possible-value.ts +15 -0
- package/src/workflows/index.ts +1 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { defineRouteConfig } from "@medusajs/admin-sdk";
|
|
2
|
+
import { AttributeSet } from "../../../../../../types/attribute";
|
|
3
|
+
import { useForm } from "react-hook-form";
|
|
4
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
5
|
+
import {
|
|
6
|
+
useAttributeSet,
|
|
7
|
+
useUpdateAttributeSet,
|
|
8
|
+
} from "../../../../../hooks/api/attribute-set";
|
|
9
|
+
import { AdminUpdateAttributeSet } from "../../../../../../api/admin/plugin/attribute-set/validators";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { Button, Drawer, Input, Label, Textarea, toast } from "@medusajs/ui";
|
|
12
|
+
import { useNavigate, useParams } from "react-router-dom";
|
|
13
|
+
import { useEffect } from "react";
|
|
14
|
+
|
|
15
|
+
type Props = {
|
|
16
|
+
attributeSet: AttributeSet;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const FormSchema = AdminUpdateAttributeSet;
|
|
20
|
+
type FormValues = z.infer<typeof FormSchema>;
|
|
21
|
+
|
|
22
|
+
const AttributeSetEditPage = () => {
|
|
23
|
+
const { id } = useParams();
|
|
24
|
+
const navigate = useNavigate();
|
|
25
|
+
|
|
26
|
+
const { attributeSet, isLoading } = useAttributeSet(
|
|
27
|
+
id!,
|
|
28
|
+
{
|
|
29
|
+
fields: "name, handle, description",
|
|
30
|
+
},
|
|
31
|
+
{ enabled: !!id }
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const form = useForm<FormValues>({
|
|
35
|
+
resolver: zodResolver(FormSchema),
|
|
36
|
+
defaultValues: {
|
|
37
|
+
name: attributeSet?.name ?? "",
|
|
38
|
+
description: attributeSet?.description ?? "",
|
|
39
|
+
handle: attributeSet?.handle ?? "",
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (attributeSet) {
|
|
45
|
+
form.reset({
|
|
46
|
+
name: attributeSet?.name ?? "",
|
|
47
|
+
description: attributeSet?.description ?? "",
|
|
48
|
+
handle: attributeSet?.handle ?? "",
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
}, [attributeSet, form])
|
|
52
|
+
|
|
53
|
+
const { mutateAsync, isPending } = useUpdateAttributeSet(attributeSet?.id ?? "");
|
|
54
|
+
|
|
55
|
+
const handleSubmit = form.handleSubmit(async (data) => {
|
|
56
|
+
await mutateAsync(data, {
|
|
57
|
+
onSuccess: () => {
|
|
58
|
+
toast.success("Attribute set edited");
|
|
59
|
+
navigate(-1);
|
|
60
|
+
},
|
|
61
|
+
onError: (error) => {
|
|
62
|
+
toast.error(error.message);
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const handleClose = () => {
|
|
68
|
+
navigate(-1);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
if (!attributeSet) {
|
|
72
|
+
return <p>Not found...</p>;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<Drawer
|
|
77
|
+
open={true}
|
|
78
|
+
onOpenChange={(open) => {
|
|
79
|
+
if (!open) {
|
|
80
|
+
handleClose();
|
|
81
|
+
}
|
|
82
|
+
}}
|
|
83
|
+
>
|
|
84
|
+
<Drawer.Content>
|
|
85
|
+
<Drawer.Header>Edit Attribute Set</Drawer.Header>
|
|
86
|
+
<Drawer.Body>
|
|
87
|
+
<form id='attribute-set-edit-form' onSubmit={handleSubmit}>
|
|
88
|
+
<div className="flex flex-col gap-4">
|
|
89
|
+
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
90
|
+
<div className="flex flex-col gap-2">
|
|
91
|
+
<Label htmlFor="name">Name</Label>
|
|
92
|
+
<Input aria-invalid={!!form.formState.errors.name} size="small" {...form.register("name")} />
|
|
93
|
+
</div>
|
|
94
|
+
<div className="flex flex-col gap-2">
|
|
95
|
+
<Label htmlFor="handle">Handle</Label>
|
|
96
|
+
<Input size="small" {...form.register("handle")} />
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
<div className="flex flex-col gap-2">
|
|
100
|
+
<Label htmlFor="description">Description</Label>
|
|
101
|
+
<Textarea {...form.register("description")} />
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</form>
|
|
105
|
+
</Drawer.Body>
|
|
106
|
+
<Drawer.Footer>
|
|
107
|
+
<Drawer.Close onClick={handleClose} asChild>
|
|
108
|
+
<Button disabled={isPending} variant="secondary">Cancel</Button>
|
|
109
|
+
</Drawer.Close>
|
|
110
|
+
<Button disabled={isPending} type="submit" form="attribute-set-edit-form" >Save</Button>
|
|
111
|
+
</Drawer.Footer>
|
|
112
|
+
</Drawer.Content>
|
|
113
|
+
</Drawer>
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export const config = defineRouteConfig({});
|
|
118
|
+
|
|
119
|
+
export default AttributeSetEditPage;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useAttributeSet } from "../../../../hooks/api/attribute-set";
|
|
2
|
+
import { useParams } from "react-router-dom";
|
|
3
|
+
import {
|
|
4
|
+
Container,
|
|
5
|
+
DropdownMenu,
|
|
6
|
+
Heading,
|
|
7
|
+
IconButton,
|
|
8
|
+
Text,
|
|
9
|
+
} from "@medusajs/ui";
|
|
10
|
+
import { SingleColumnLayout } from "../../../../layouts/single-column";
|
|
11
|
+
import { EllipsisHorizontal, PencilSquare, Trash } from "@medusajs/icons";
|
|
12
|
+
import { SectionRow } from "../../../../components/section-row";
|
|
13
|
+
import { AttributeSetGeneralSection, AttributeSetAttributesSection } from "./components";
|
|
14
|
+
|
|
15
|
+
export default function AttributeSetDetail() {
|
|
16
|
+
const { id } = useParams();
|
|
17
|
+
const { attributeSet, isLoading } = useAttributeSet(id || "");
|
|
18
|
+
|
|
19
|
+
if (!id) {
|
|
20
|
+
return <div>Invalid attribute set ID</div>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (isLoading) {
|
|
24
|
+
return <div>Loading...</div>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!attributeSet) {
|
|
28
|
+
return <div>Attribute set not found</div>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<SingleColumnLayout>
|
|
33
|
+
<AttributeSetGeneralSection attributeSet={attributeSet} />
|
|
34
|
+
|
|
35
|
+
<AttributeSetAttributesSection attributeSet={attributeSet} />
|
|
36
|
+
|
|
37
|
+
{/* Metadata Section */}
|
|
38
|
+
<Container>
|
|
39
|
+
<div className="flex flex-col gap-y-4 p-4">
|
|
40
|
+
<Heading level="h2">Metadata</Heading>
|
|
41
|
+
</div>
|
|
42
|
+
</Container>
|
|
43
|
+
</SingleColumnLayout>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"jsx": "react-jsx",
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true,
|
|
22
|
+
|
|
23
|
+
/* Type Declarations */
|
|
24
|
+
"typeRoots": ["./types", "./node_modules/@types"]
|
|
25
|
+
},
|
|
26
|
+
"include": [".", "types/**/*.d.ts"]
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Custom API Routes
|
|
2
|
+
|
|
3
|
+
An API Route is a REST API endpoint.
|
|
4
|
+
|
|
5
|
+
An API Route is created in a TypeScript or JavaScript file under the `/src/api` directory of your Medusa application. The file’s name must be `route.ts` or `route.js`.
|
|
6
|
+
|
|
7
|
+
For example, to create a `GET` API Route at `/store/hello-world`, create the file `src/api/store/hello-world/route.ts` with the following content:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http";
|
|
11
|
+
|
|
12
|
+
export async function GET(req: MedusaRequest, res: MedusaResponse) {
|
|
13
|
+
res.json({
|
|
14
|
+
message: "Hello world!",
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Supported HTTP methods
|
|
20
|
+
|
|
21
|
+
The file based routing supports the following HTTP methods:
|
|
22
|
+
|
|
23
|
+
- GET
|
|
24
|
+
- POST
|
|
25
|
+
- PUT
|
|
26
|
+
- PATCH
|
|
27
|
+
- DELETE
|
|
28
|
+
- OPTIONS
|
|
29
|
+
- HEAD
|
|
30
|
+
|
|
31
|
+
You can define a handler for each of these methods by exporting a function with the name of the method in the paths `route.ts` file.
|
|
32
|
+
|
|
33
|
+
For example:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http";
|
|
37
|
+
|
|
38
|
+
export async function GET(req: MedusaRequest, res: MedusaResponse) {
|
|
39
|
+
// Handle GET requests
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function POST(req: MedusaRequest, res: MedusaResponse) {
|
|
43
|
+
// Handle POST requests
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export async function PUT(req: MedusaRequest, res: MedusaResponse) {
|
|
47
|
+
// Handle PUT requests
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Parameters
|
|
52
|
+
|
|
53
|
+
To create an API route that accepts a path parameter, create a directory within the route's path whose name is of the format `[param]`.
|
|
54
|
+
|
|
55
|
+
For example, if you want to define a route that takes a `productId` parameter, you can do so by creating a file called `/api/products/[productId]/route.ts`:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import type {
|
|
59
|
+
MedusaRequest,
|
|
60
|
+
MedusaResponse,
|
|
61
|
+
} from "@medusajs/framework/http"
|
|
62
|
+
|
|
63
|
+
export async function GET(req: MedusaRequest, res: MedusaResponse) {
|
|
64
|
+
const { productId } = req.params;
|
|
65
|
+
|
|
66
|
+
res.json({
|
|
67
|
+
message: `You're looking for product ${productId}`
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
To create an API route that accepts multiple path parameters, create within the file's path multiple directories whose names are of the format `[param]`.
|
|
73
|
+
|
|
74
|
+
For example, if you want to define a route that takes both a `productId` and a `variantId` parameter, you can do so by creating a file called `/api/products/[productId]/variants/[variantId]/route.ts`.
|
|
75
|
+
|
|
76
|
+
## Using the container
|
|
77
|
+
|
|
78
|
+
The Medusa container is available on `req.scope`. Use it to access modules' main services and other registered resources:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import type {
|
|
82
|
+
MedusaRequest,
|
|
83
|
+
MedusaResponse,
|
|
84
|
+
} from "@medusajs/framework/http"
|
|
85
|
+
|
|
86
|
+
export const GET = async (
|
|
87
|
+
req: MedusaRequest,
|
|
88
|
+
res: MedusaResponse
|
|
89
|
+
) => {
|
|
90
|
+
const productModuleService = req.scope.resolve("product")
|
|
91
|
+
|
|
92
|
+
const [, count] = await productModuleService.listAndCount()
|
|
93
|
+
|
|
94
|
+
res.json({
|
|
95
|
+
count,
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Middleware
|
|
101
|
+
|
|
102
|
+
You can apply middleware to your routes by creating a file called `/api/middlewares.ts`. This file must export a configuration object with what middleware you want to apply to which routes.
|
|
103
|
+
|
|
104
|
+
For example, if you want to apply a custom middleware function to the `/store/custom` route, you can do so by adding the following to your `/api/middlewares.ts` file:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import { defineMiddlewares } from "@medusajs/framework/http"
|
|
108
|
+
import type {
|
|
109
|
+
MedusaRequest,
|
|
110
|
+
MedusaResponse,
|
|
111
|
+
MedusaNextFunction,
|
|
112
|
+
} from "@medusajs/framework/http";
|
|
113
|
+
|
|
114
|
+
async function logger(
|
|
115
|
+
req: MedusaRequest,
|
|
116
|
+
res: MedusaResponse,
|
|
117
|
+
next: MedusaNextFunction
|
|
118
|
+
) {
|
|
119
|
+
console.log("Request received");
|
|
120
|
+
next();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export default defineMiddlewares({
|
|
124
|
+
routes: [
|
|
125
|
+
{
|
|
126
|
+
matcher: "/store/custom",
|
|
127
|
+
middlewares: [logger],
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
})
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The `matcher` property can be either a string or a regular expression. The `middlewares` property accepts an array of middleware functions.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { MiddlewareRoute } from "@medusajs/framework";
|
|
2
|
+
import { adminAttributeRoutesMiddlewares } from "./plugin/attributes/middlewares";
|
|
3
|
+
import { adminAttributeSetMiddlewares } from "./plugin/attribute-set/middlewares";
|
|
4
|
+
|
|
5
|
+
export const adminRoutesMiddlewares: MiddlewareRoute[] = [
|
|
6
|
+
...adminAttributeRoutesMiddlewares,
|
|
7
|
+
...adminAttributeSetMiddlewares,
|
|
8
|
+
]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MedusaRequest, MedusaResponse } from "@medusajs/framework";
|
|
2
|
+
import { AdminBatchLinkAttributeSetAttributesType } from "../../validators";
|
|
3
|
+
import { batchLinkAttributeSetAttributesWorkflow } from "../../../../../../workflows/attribute-set/workflows";
|
|
4
|
+
|
|
5
|
+
export const POST = async (req: MedusaRequest<AdminBatchLinkAttributeSetAttributesType>, res: MedusaResponse) => {
|
|
6
|
+
const attributeSetId = req.params.id
|
|
7
|
+
const payload = req.validatedBody
|
|
8
|
+
|
|
9
|
+
await batchLinkAttributeSetAttributesWorkflow(req.scope).run({
|
|
10
|
+
input: {
|
|
11
|
+
...payload,
|
|
12
|
+
id: attributeSetId
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
return res.status(200).json({})
|
|
17
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { MedusaRequest, MedusaResponse, refetchEntity } from "@medusajs/framework";
|
|
2
|
+
import { AdminGetAttributeParamsType } from "../../attributes/validators";
|
|
3
|
+
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
|
|
4
|
+
import { updateAttributeSetWorkflow } from "../../../../../workflows/attribute-set/workflows";
|
|
5
|
+
import { AdminUpdateAttributeSetType } from "../validators";
|
|
6
|
+
|
|
7
|
+
export const GET = async (req: MedusaRequest<AdminGetAttributeParamsType>, res: MedusaResponse) => {
|
|
8
|
+
const id = req.params.id
|
|
9
|
+
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
|
|
10
|
+
|
|
11
|
+
const { data: [attributeSet] } = await query.graph({
|
|
12
|
+
entity: 'attribute_set',
|
|
13
|
+
filters: { id },
|
|
14
|
+
...req.queryConfig,
|
|
15
|
+
}, {
|
|
16
|
+
throwIfKeyNotFound: true,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
return res.status(200).json({ attributeSet })
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const POST = async (req: MedusaRequest<AdminUpdateAttributeSetType>, res: MedusaResponse) => {
|
|
23
|
+
const id = req.params.id
|
|
24
|
+
const body = req.validatedBody
|
|
25
|
+
|
|
26
|
+
await updateAttributeSetWorkflow(req.scope).run({
|
|
27
|
+
input: {
|
|
28
|
+
...body,
|
|
29
|
+
id,
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const attributeSet = await refetchEntity(
|
|
34
|
+
'attribute_set',
|
|
35
|
+
id,
|
|
36
|
+
req.scope,
|
|
37
|
+
req.queryConfig.fields,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
return res.status(200).json({ attributeSet })
|
|
41
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AdminBatchLinkAttributeSetAttributes, AdminCreateAttributeSet, AdminGetAttributeSetParams, AdminGetAttributeSetsParams, AdminUpdateAttributeSet } from "./validators";
|
|
2
|
+
import { MiddlewareRoute, validateAndTransformBody, validateAndTransformQuery } from "@medusajs/framework";
|
|
3
|
+
|
|
4
|
+
import { listAttributeSetQueryConfig, retrieveAttributeSetQueryConfig } from "./query-config";
|
|
5
|
+
|
|
6
|
+
export const adminAttributeSetMiddlewares: MiddlewareRoute[] = [
|
|
7
|
+
{
|
|
8
|
+
matcher: '/admin/plugin/attribute-set',
|
|
9
|
+
method: ['GET'],
|
|
10
|
+
middlewares: [validateAndTransformQuery(AdminGetAttributeSetsParams, listAttributeSetQueryConfig)]
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
matcher: '/admin/plugin/attribute-set',
|
|
14
|
+
methods: ['POST'],
|
|
15
|
+
middlewares: [
|
|
16
|
+
validateAndTransformQuery(AdminGetAttributeSetParams, retrieveAttributeSetQueryConfig),
|
|
17
|
+
validateAndTransformBody(AdminCreateAttributeSet)
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
matcher: '/admin/plugin/attribute-set/:id',
|
|
22
|
+
method: ['GET'],
|
|
23
|
+
middlewares: [
|
|
24
|
+
validateAndTransformQuery(AdminGetAttributeSetParams, retrieveAttributeSetQueryConfig)
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
matcher: '/admin/plugin/attribute-set/:id',
|
|
29
|
+
method: ['POST'],
|
|
30
|
+
middlewares: [
|
|
31
|
+
validateAndTransformQuery(AdminGetAttributeSetParams, retrieveAttributeSetQueryConfig),
|
|
32
|
+
validateAndTransformBody(AdminUpdateAttributeSet)
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
matcher: '/admin/plugin/attribute-set/:id/attributes',
|
|
37
|
+
method: ['POST'],
|
|
38
|
+
middlewares: [
|
|
39
|
+
validateAndTransformBody(AdminBatchLinkAttributeSetAttributes)
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const defaultAdminAttributeSetFields = [
|
|
2
|
+
'id',
|
|
3
|
+
'name',
|
|
4
|
+
'description',
|
|
5
|
+
'handle',
|
|
6
|
+
'metadata',
|
|
7
|
+
'*attributes',
|
|
8
|
+
'*attributes.possible_values',
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
export const retrieveAttributeSetQueryConfig = {
|
|
12
|
+
defaults: defaultAdminAttributeSetFields,
|
|
13
|
+
isList: false,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const listAttributeSetQueryConfig = {
|
|
17
|
+
...retrieveAttributeSetQueryConfig,
|
|
18
|
+
defaultLimit: 50,
|
|
19
|
+
isList: true,
|
|
20
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { MedusaRequest, MedusaResponse, refetchEntity } from "@medusajs/framework";
|
|
2
|
+
|
|
3
|
+
import { AdminCreateAttributeSetType, AdminGetAttributesSetsParamsType } from "./validators";
|
|
4
|
+
import { createAttributeSetWorkflow } from "../../../../workflows/attribute-set/workflows/create-attribute-set";
|
|
5
|
+
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
|
|
6
|
+
import { AttributeSet } from "../../../../types/attribute";
|
|
7
|
+
import { PaginatedResponse } from "@medusajs/framework/types";
|
|
8
|
+
|
|
9
|
+
export const POST = async (req: MedusaRequest<AdminCreateAttributeSetType>, res: MedusaResponse) => {
|
|
10
|
+
const { result: [attributeSet] } = await createAttributeSetWorkflow(req.scope).run({
|
|
11
|
+
input: [req.validatedBody]
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
const response = await refetchEntity(
|
|
15
|
+
'attribute_set',
|
|
16
|
+
attributeSet.id,
|
|
17
|
+
req.scope,
|
|
18
|
+
req.queryConfig.fields,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
return res.status(201).json({ attribute_set: response })
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const GET = async (req:MedusaRequest<AdminGetAttributesSetsParamsType>, res: MedusaResponse) => {
|
|
25
|
+
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
|
|
26
|
+
|
|
27
|
+
const { data: attributeSets, metadata } = await query.graph({
|
|
28
|
+
entity: 'attribute_set',
|
|
29
|
+
filters: req.filterableFields,
|
|
30
|
+
...req.queryConfig
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
return res.status(200).json({ attributeSets, count: metadata?.count, offset: metadata?.skip, limit: metadata?.take })
|
|
34
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { applyAndAndOrOperators } from '@medusajs/medusa/api/utils/common-validators/common'
|
|
2
|
+
import { createFindParams, createOperatorMap, createSelectParams } from '@medusajs/medusa/api/utils/validators'
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
|
|
5
|
+
export const AdminGetAttributeSetParams = createSelectParams()
|
|
6
|
+
export type AdminGetAttributeSetParamsType = z.infer<typeof AdminGetAttributeSetParams>
|
|
7
|
+
|
|
8
|
+
export const GetAttributeSetsParams = z.object({
|
|
9
|
+
id: z.string().optional(),
|
|
10
|
+
name: z.string().optional(),
|
|
11
|
+
handle: z.string().optional(),
|
|
12
|
+
created_at: createOperatorMap().optional(),
|
|
13
|
+
updated_at: createOperatorMap().optional(),
|
|
14
|
+
deleted_at: createOperatorMap().optional(),
|
|
15
|
+
})
|
|
16
|
+
export const AdminGetAttributeSetsParams = createFindParams({
|
|
17
|
+
offset: 0,
|
|
18
|
+
limit: 50,
|
|
19
|
+
})
|
|
20
|
+
.merge(applyAndAndOrOperators(GetAttributeSetsParams))
|
|
21
|
+
.merge(GetAttributeSetsParams)
|
|
22
|
+
|
|
23
|
+
export type AdminGetAttributesSetsParamsType = z.infer<typeof AdminGetAttributeSetsParams>
|
|
24
|
+
|
|
25
|
+
const AdminBaseAttributeSet = z.object({
|
|
26
|
+
name: z.string().optional(),
|
|
27
|
+
description: z.string().optional(),
|
|
28
|
+
handle: z.string().optional(),
|
|
29
|
+
metadata: z.record(z.unknown()).nullish(),
|
|
30
|
+
attributes: z.array(z.string()).optional(),
|
|
31
|
+
}).strict()
|
|
32
|
+
|
|
33
|
+
export type AdminCreateAttributeSetType = z.infer<typeof AdminCreateAttributeSet>
|
|
34
|
+
export const AdminCreateAttributeSet = AdminBaseAttributeSet.merge(z.object({
|
|
35
|
+
name: z.string().min(1),
|
|
36
|
+
})).strict()
|
|
37
|
+
|
|
38
|
+
export type AdminUpdateAttributeSetType = z.infer<typeof AdminUpdateAttributeSet>
|
|
39
|
+
export const AdminUpdateAttributeSet = AdminBaseAttributeSet.merge(z.object({ name: z.string().min(1) }))
|
|
40
|
+
|
|
41
|
+
export type AdminBatchLinkAttributeSetAttributesType = z.infer<typeof AdminBatchLinkAttributeSetAttributes>
|
|
42
|
+
export const AdminBatchLinkAttributeSetAttributes = z.object({
|
|
43
|
+
add: z.array(z.string()).optional(),
|
|
44
|
+
remove: z.array(z.string()).optional(),
|
|
45
|
+
})
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { MedusaRequest, MedusaResponse, refetchEntities } from "@medusajs/framework";
|
|
2
|
+
import { AdminGetAttributeParamsType, AdminUpdateAttributeType } from "../validators";
|
|
3
|
+
import { ContainerRegistrationKeys, MedusaError, MedusaErrorTypes } from "@medusajs/framework/utils";
|
|
4
|
+
import { updateAttributesWorkflow } from "../../../../../workflows";
|
|
5
|
+
import { UpdateAttributeDTO } from "../../../../../modules/attribute/types/attribute/common";
|
|
6
|
+
import { deleteAttributeWorkflow } from "../../../../../workflows/attribute/workflows/delete-attribute";
|
|
7
|
+
|
|
8
|
+
export const POST = async (req: MedusaRequest<UpdateAttributeDTO>, res: MedusaResponse) => {
|
|
9
|
+
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
|
|
10
|
+
|
|
11
|
+
const attributeId = req.params.id
|
|
12
|
+
|
|
13
|
+
const { data: [existingAttribute] } = await query.graph({
|
|
14
|
+
entity: 'attribute',
|
|
15
|
+
fields: ['id'],
|
|
16
|
+
filters: {
|
|
17
|
+
id: attributeId
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
if (!existingAttribute) {
|
|
22
|
+
throw new MedusaError(MedusaErrorTypes.NOT_FOUND, `Attribute with id '${attributeId}' not found`)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
await updateAttributesWorkflow(req.scope).run({
|
|
26
|
+
input: { attributes: [{
|
|
27
|
+
...req.validatedBody,
|
|
28
|
+
id: attributeId
|
|
29
|
+
}] }
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const attribute = await refetchEntities(
|
|
33
|
+
'attribute',
|
|
34
|
+
attributeId,
|
|
35
|
+
req.scope,
|
|
36
|
+
req.queryConfig.fields
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
return res.status(201).json({ attribute })
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const GET = async (req: MedusaRequest<AdminGetAttributeParamsType>, res: MedusaResponse) => {
|
|
43
|
+
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
|
|
44
|
+
|
|
45
|
+
const attributeId = req.params.id
|
|
46
|
+
|
|
47
|
+
const { data: [attribute] } = await query.graph({
|
|
48
|
+
entity: 'attribute',
|
|
49
|
+
...req.queryConfig,
|
|
50
|
+
filters: {
|
|
51
|
+
id: attributeId,
|
|
52
|
+
},
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
if (!attribute) {
|
|
56
|
+
throw new MedusaError(MedusaErrorTypes.NOT_FOUND, 'Attribute not found')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return res.status(200).json({ attribute })
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => {
|
|
63
|
+
const attributeId = req.params.id
|
|
64
|
+
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
|
|
65
|
+
|
|
66
|
+
const { data: [attribute] } = await query.graph({
|
|
67
|
+
entity: 'attribute',
|
|
68
|
+
fields: ['id'],
|
|
69
|
+
filters: {
|
|
70
|
+
id: attributeId,
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
if (!attribute) {
|
|
75
|
+
throw new MedusaError(MedusaErrorTypes.NOT_FOUND, 'Attribute not found')
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
await deleteAttributeWorkflow(req.scope).run({
|
|
79
|
+
input: {
|
|
80
|
+
id: attributeId
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
return res.status(200).json({})
|
|
85
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ContainerRegistrationKeys, MedusaError, MedusaErrorTypes } from "@medusajs/framework/utils";
|
|
2
|
+
import { MedusaRequest, MedusaResponse, refetchEntity } from "@medusajs/framework";
|
|
3
|
+
|
|
4
|
+
import { AdminGetAttributeValueParamsType, AdminUpdateAttributeValueType } from "../../../validators";
|
|
5
|
+
import { updateAttributePossibleValueWorkflow } from "../../../../../../../workflows/attribute_possible_value";
|
|
6
|
+
|
|
7
|
+
export const GET = async (req: MedusaRequest<AdminGetAttributeValueParamsType>, res: MedusaResponse) => {
|
|
8
|
+
const attributeId = req.params.valueId
|
|
9
|
+
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
|
|
10
|
+
|
|
11
|
+
const { data: [attributePossibleValue] } = await query.graph({
|
|
12
|
+
entity: 'attribute_possible_value',
|
|
13
|
+
...req.queryConfig,
|
|
14
|
+
filters: {
|
|
15
|
+
...req.filterableFields,
|
|
16
|
+
id: attributeId
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
if (!attributePossibleValue) {
|
|
21
|
+
throw new MedusaError(MedusaErrorTypes.NOT_FOUND, `Attribute possible value with id '${attributeId}' was not found`)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return res.status(200).json({ attributePossibleValue })
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const POST = async (req: MedusaRequest<AdminUpdateAttributeValueType>, res: MedusaResponse) => {
|
|
28
|
+
const { valueId } = req.params
|
|
29
|
+
const body = req.validatedBody
|
|
30
|
+
|
|
31
|
+
await updateAttributePossibleValueWorkflow(req.scope).run({
|
|
32
|
+
input: {
|
|
33
|
+
...body,
|
|
34
|
+
id: valueId
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const attributePossibleValue = await refetchEntity('attribute_possible_value', valueId, req.scope, req.queryConfig.fields)
|
|
39
|
+
|
|
40
|
+
return res.status(200).json({ attributePossibleValue: attributePossibleValue })
|
|
41
|
+
}
|