@empty-complete-org/medusa-product-attributes 0.10.0 → 0.11.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.
Files changed (34) hide show
  1. package/.medusa/server/src/admin/index.js +325 -0
  2. package/.medusa/server/src/admin/index.mjs +324 -0
  3. package/.medusa/server/src/api/admin/category/[categoryId]/custom-attributes/route.d.ts +4 -0
  4. package/.medusa/server/src/api/admin/category/[categoryId]/custom-attributes/route.js +32 -0
  5. package/.medusa/server/src/api/admin/category/[categoryId]/custom-attributes/route.js.map +1 -0
  6. package/.medusa/server/src/api/admin/product/[productId]/custom-attributes/route.d.ts +3 -0
  7. package/.medusa/server/src/api/admin/product/[productId]/custom-attributes/route.js +42 -0
  8. package/.medusa/server/src/api/admin/product/[productId]/custom-attributes/route.js.map +1 -0
  9. package/{dist → .medusa/server/src/modules/product-attributes}/index.d.ts +0 -1
  10. package/.medusa/server/src/modules/product-attributes/index.js.map +1 -0
  11. package/{dist → .medusa/server/src/modules/product-attributes}/models/category-custom-attribute.d.ts +0 -1
  12. package/.medusa/server/src/modules/product-attributes/models/category-custom-attribute.js.map +1 -0
  13. package/{dist → .medusa/server/src/modules/product-attributes}/models/product-custom-attribute.d.ts +0 -1
  14. package/.medusa/server/src/modules/product-attributes/models/product-custom-attribute.js.map +1 -0
  15. package/{dist → .medusa/server/src/modules/product-attributes}/service.d.ts +0 -1
  16. package/.medusa/server/src/modules/product-attributes/service.js.map +1 -0
  17. package/package.json +35 -22
  18. package/dist/index.d.ts.map +0 -1
  19. package/dist/index.js.map +0 -1
  20. package/dist/models/category-custom-attribute.d.ts.map +0 -1
  21. package/dist/models/category-custom-attribute.js.map +0 -1
  22. package/dist/models/product-custom-attribute.d.ts.map +0 -1
  23. package/dist/models/product-custom-attribute.js.map +0 -1
  24. package/dist/service.d.ts.map +0 -1
  25. package/dist/service.js.map +0 -1
  26. package/src/admin/lib/sdk.ts +0 -9
  27. package/src/admin/widgets/category-attribute-templates.tsx +0 -237
  28. package/src/admin/widgets/product-attribute-values.tsx +0 -186
  29. package/src/api/admin/category/[categoryId]/custom-attributes/route.ts +0 -49
  30. package/src/api/admin/product/[productId]/custom-attributes/route.ts +0 -51
  31. /package/{dist → .medusa/server/src/modules/product-attributes}/index.js +0 -0
  32. /package/{dist → .medusa/server/src/modules/product-attributes}/models/category-custom-attribute.js +0 -0
  33. /package/{dist → .medusa/server/src/modules/product-attributes}/models/product-custom-attribute.js +0 -0
  34. /package/{dist → .medusa/server/src/modules/product-attributes}/service.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../../src/api/admin/category/[categoryId]/custom-attributes/route.ts"],"names":[],"mappings":";;AAIA,kBAOC;AAED,oBAoBC;AAED,sBAcC;AAhDD,kFAAmF;AAG5E,KAAK,UAAU,GAAG,CAAC,GAAkB,EAAE,GAAmB;IAC/D,MAAM,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IACjC,MAAM,OAAO,GAA2B,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,4CAAuB,CAAC,CAAA;IAElF,MAAM,0BAA0B,GAAG,MAAM,OAAO,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAA;IAElF,GAAG,CAAC,IAAI,CAAC,EAAE,0BAA0B,EAAE,CAAC,CAAA;AAC1C,CAAC;AAEM,KAAK,UAAU,IAAI,CAAC,GAAkB,EAAE,GAAmB;IAChE,MAAM,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IACjC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,IAK7C,CAAA;IAED,MAAM,OAAO,GAA2B,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,4CAAuB,CAAC,CAAA;IAElF,MAAM,yBAAyB,GAAG,MAAM,OAAO,CAAC,uBAAuB,CAAC;QACtE,KAAK;QACL,IAAI,EAAE,IAAI,IAAI,MAAM;QACpB,IAAI,EAAE,IAAI,IAAI,IAAI;QAClB,WAAW,EAAE,UAAU;QACvB,UAAU;KACX,CAAC,CAAA;IAEF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,yBAAyB,EAAE,CAAC,CAAA;AACrD,CAAC;AAEM,KAAK,UAAU,KAAK,CAAC,GAAkB,EAAE,GAAmB;IACjE,MAAM,OAAO,GAA2B,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,4CAAuB,CAAC,CAAA;IAClF,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,CAAC,IAO3B,CAAA;IAED,MAAM,yBAAyB,GAAG,MAAM,OAAO,CAAC,uBAAuB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IAEjF,GAAG,CAAC,IAAI,CAAC,EAAE,yBAAyB,EAAE,CAAC,CAAA;AACzC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http";
2
+ export declare function GET(req: MedusaRequest, res: MedusaResponse): Promise<void>;
3
+ export declare function POST(req: MedusaRequest, res: MedusaResponse): Promise<void>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = GET;
4
+ exports.POST = POST;
5
+ const product_attributes_1 = require("../../../../../modules/product-attributes");
6
+ async function GET(req, res) {
7
+ const { productId } = req.params;
8
+ const service = req.scope.resolve(product_attributes_1.CUSTOM_ATTRIBUTE_MODULE);
9
+ const product_custom_attributes = await service.getProductAttributes(productId);
10
+ res.json({ product_custom_attributes });
11
+ }
12
+ async function POST(req, res) {
13
+ const { productId } = req.params;
14
+ const { attributes } = req.body;
15
+ const service = req.scope.resolve(product_attributes_1.CUSTOM_ATTRIBUTE_MODULE);
16
+ // Get existing product attributes
17
+ const existing = await service.getProductAttributes(productId);
18
+ const results = [];
19
+ for (const attr of attributes) {
20
+ const existingAttr = existing.find((e) => e.category_custom_attribute?.id === attr.id);
21
+ if (existingAttr) {
22
+ // Update existing
23
+ const updated = await service.updateProductAttribute(existingAttr.id, {
24
+ value: attr.value,
25
+ value_numeric: isNaN(Number(attr.value)) ? null : Number(attr.value),
26
+ });
27
+ results.push(updated);
28
+ }
29
+ else {
30
+ // Create new
31
+ const created = await service.createProductAttribute({
32
+ product_id: productId,
33
+ category_custom_attribute_id: attr.id,
34
+ value: attr.value,
35
+ value_numeric: isNaN(Number(attr.value)) ? null : Number(attr.value),
36
+ });
37
+ results.push(created);
38
+ }
39
+ }
40
+ res.json({ product_custom_attributes: results });
41
+ }
42
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../../src/api/admin/product/[productId]/custom-attributes/route.ts"],"names":[],"mappings":";;AAIA,kBAOC;AAED,oBAsCC;AAlDD,kFAAmF;AAG5E,KAAK,UAAU,GAAG,CAAC,GAAkB,EAAE,GAAmB;IAC/D,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IAChC,MAAM,OAAO,GAA2B,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,4CAAuB,CAAC,CAAA;IAElF,MAAM,yBAAyB,GAAG,MAAM,OAAO,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAA;IAE/E,GAAG,CAAC,IAAI,CAAC,EAAE,yBAAyB,EAAE,CAAC,CAAA;AACzC,CAAC;AAEM,KAAK,UAAU,IAAI,CAAC,GAAkB,EAAE,GAAmB;IAChE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IAChC,MAAM,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,IAE1B,CAAA;IAED,MAAM,OAAO,GAA2B,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,4CAAuB,CAAC,CAAA;IAElF,kCAAkC;IAClC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAA;IAE9D,MAAM,OAAO,GAAG,EAAE,CAAA;IAElB,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAChC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,yBAAyB,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE,CACxD,CAAA;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,kBAAkB;YAClB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,sBAAsB,CAAC,YAAY,CAAC,EAAE,EAAE;gBACpE,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;aACrE,CAAC,CAAA;YACF,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACvB,CAAC;aAAM,CAAC;YACN,aAAa;YACb,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,sBAAsB,CAAC;gBACnD,UAAU,EAAE,SAAS;gBACrB,4BAA4B,EAAE,IAAI,CAAC,EAAE;gBACrC,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;aACrE,CAAC,CAAA;YACF,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACvB,CAAC;IACH,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,EAAE,yBAAyB,EAAE,OAAO,EAAE,CAAC,CAAA;AAClD,CAAC"}
@@ -33,4 +33,3 @@ declare const _default: import("@medusajs/types").ModuleExports<typeof CustomAtt
33
33
  };
34
34
  };
35
35
  export default _default;
36
- //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/modules/product-attributes/index.ts"],"names":[],"mappings":";;;;;;AAAA,qDAAkD;AAClD,wDAA8C;AAEjC,QAAA,uBAAuB,GAAG,uBAAuB,CAAA;AAE9D,kBAAe,IAAA,cAAM,EAAC,+BAAuB,EAAE;IAC7C,OAAO,EAAE,iBAAsB;CAChC,CAAC,CAAA"}
@@ -17,4 +17,3 @@ declare const CategoryCustomAttribute: import("@medusajs/framework/utils").DmlEn
17
17
  }>, "product_custom_attribute">>;
18
18
  }>, "category_custom_attribute">;
19
19
  export default CategoryCustomAttribute;
20
- //# sourceMappingURL=category-custom-attribute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"category-custom-attribute.js","sourceRoot":"","sources":["../../../../../../src/modules/product-attributes/models/category-custom-attribute.ts"],"names":[],"mappings":";;;;;AAAA,qDAAiD;AACjD,0FAA+D;AAE/D,MAAM,uBAAuB,GAAG,aAAK;KAClC,MAAM,CAAC,2BAA2B,EAAE;IACnC,EAAE,EAAE,aAAK,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE;IAC3B,GAAG,EAAE,aAAK,CAAC,IAAI,EAAE;IACjB,IAAI,EAAE,aAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;IAClC,KAAK,EAAE,aAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/B,IAAI,EAAE,aAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE,uCAAuC;IACtE,UAAU,EAAE,aAAK,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACrC,WAAW,EAAE,aAAK,CAAC,IAAI,EAAE;IACzB,WAAW,EAAE,aAAK,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,uDAAuD;IACpG,yBAAyB,EAAE,aAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,kCAAsB,CAAC;CACvE,CAAC;KACD,QAAQ,CAAC;IACR,MAAM,EAAE,CAAC,2BAA2B,CAAC;CACtC,CAAC,CAAA;AAEJ,kBAAe,uBAAuB,CAAA"}
@@ -17,4 +17,3 @@ declare const ProductCustomAttribute: import("@medusajs/framework/utils").DmlEnt
17
17
  }>, "category_custom_attribute">, undefined>;
18
18
  }>, "product_custom_attribute">;
19
19
  export default ProductCustomAttribute;
20
- //# sourceMappingURL=product-custom-attribute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-custom-attribute.js","sourceRoot":"","sources":["../../../../../../src/modules/product-attributes/models/product-custom-attribute.ts"],"names":[],"mappings":";;;;;AAAA,qDAAiD;AACjD,4FAAiE;AAEjE,MAAM,sBAAsB,GAAG,aAAK,CAAC,MAAM,CAAC,0BAA0B,EAAE;IACtE,EAAE,EAAE,aAAK,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE;IAC3B,UAAU,EAAE,aAAK,CAAC,IAAI,EAAE;IACxB,KAAK,EAAE,aAAK,CAAC,IAAI,EAAE;IACnB,aAAa,EAAE,aAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxC,UAAU,EAAE,aAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IACnC,yBAAyB,EAAE,aAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,mCAAuB,EAAE;QACxE,QAAQ,EAAE,2BAA2B;KACtC,CAAC;CACH,CAAC,CAAA;AAEF,kBAAe,sBAAsB,CAAA"}
@@ -220,4 +220,3 @@ declare class CustomAttributeService extends CustomAttributeService_base {
220
220
  private generateKey;
221
221
  }
222
222
  export default CustomAttributeService;
223
- //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../../../src/modules/product-attributes/service.ts"],"names":[],"mappings":";;;;;AAAA,qDAAyD;AACzD,mGAAwE;AACxE,iGAAsE;AAEtE,MAAM,MAAM,GAAG;IACb,uBAAuB,EAAvB,mCAAuB;IACvB,sBAAsB,EAAtB,kCAAsB;CACvB,CAAA;AAID,2EAA2E;AAC3E,MAAM,sBAAuB,SAAQ,IAAA,qBAAa,EAAC,MAAM,CAAC;IACxD,KAAK,CAAC,qBAAqB,CAAC,UAAkB;QAC5C,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,4BAA4B,CAAC;YAC7C,WAAW,EAAE,UAAU;YACvB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,IAO7B;QACC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACxC,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,8BAA8B,CAAC;YAC/C,GAAG,IAAI;YACP,GAAG;YACH,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;YACvB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,KAAK;YACtC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,CAAC;SACjC,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,uBAAuB,CAC3B,EAAU,EACV,IAMC;QAED,MAAM,UAAU,GAAwB,EAAE,GAAG,IAAI,EAAE,CAAA;QACnD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC/C,CAAC;QACD,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,8BAA8B,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC,CAAA;IAC3E,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,IAM5B;QACC,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,CAAA;IACvD,CAAC;IAED,KAAK,CAAC,sBAAsB,CAC1B,EAAU,EACV,IAKC;QAED,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,6BAA6B,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;IACpE,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,SAAiB;QAC1C,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,2BAA2B,CAAC;YAC5C,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,IAAI;SACjB,EAAE;YACD,SAAS,EAAE,CAAC,2BAA2B,CAAC;SACzC,CAAC,CAAA;IACJ,CAAC;IAEO,WAAW,CAAC,KAAa;QAC/B,OAAO,KAAK;aACT,WAAW,EAAE;aACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;aAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IAC1B,CAAC;CACF;AAED,kBAAe,sBAAsB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empty-complete-org/medusa-product-attributes",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Custom attributes module for Medusa v2 with support for text, number, file types and units of measurement",
5
5
  "author": "empty-complete",
6
6
  "license": "MIT",
@@ -10,33 +10,35 @@
10
10
  },
11
11
  "keywords": [
12
12
  "medusa",
13
- "medusajs-v2",
14
- "medusa-module",
13
+ "medusa-v2",
14
+ "medusa-plugin",
15
+ "medusa-plugin-integration",
15
16
  "custom-attributes",
16
17
  "product-attributes",
17
18
  "ecommerce",
18
- "typescript",
19
- "product"
19
+ "typescript"
20
20
  ],
21
21
  "files": [
22
- "dist",
23
- "src/admin",
24
- "src/api"
22
+ ".medusa/server",
23
+ "!.medusa/server/**/__tests__"
25
24
  ],
25
+ "main": ".medusa/server/src/index.js",
26
26
  "exports": {
27
- ".": {
28
- "import": "./dist/index.js",
29
- "require": "./dist/index.js"
27
+ "./package.json": "./package.json",
28
+ "./workflows": "./.medusa/server/src/workflows/index.js",
29
+ "./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
30
+ "./providers/*": "./.medusa/server/src/providers/*/index.js",
31
+ "./admin": {
32
+ "import": "./.medusa/server/src/admin/index.mjs",
33
+ "require": "./.medusa/server/src/admin/index.js",
34
+ "default": "./.medusa/server/src/admin/index.js"
30
35
  },
31
- "./models/*": "./dist/models/*.js",
32
- "./service": "./dist/service.js",
33
- "./admin/*": "./src/admin/*.tsx",
34
- "./api/*": "./src/api/*"
36
+ "./*": "./.medusa/server/src/*.js"
35
37
  },
36
38
  "scripts": {
37
- "build": "tsc",
38
- "clean": "rm -rf dist",
39
- "prepublishOnly": "npm run clean && npm run build",
39
+ "build": "medusa plugin:build",
40
+ "dev": "medusa plugin:develop",
41
+ "prepublishOnly": "medusa plugin:build",
40
42
  "test": "jest",
41
43
  "test:watch": "jest --watch",
42
44
  "test:coverage": "jest --coverage",
@@ -44,22 +46,33 @@
44
46
  "prepare": "husky"
45
47
  },
46
48
  "peerDependencies": {
47
- "@medusajs/framework": "^2.0.0",
48
- "@medusajs/admin-sdk": "^2.0.0",
49
+ "@medusajs/admin-sdk": "^2.13.0",
50
+ "@medusajs/cli": "^2.13.0",
51
+ "@medusajs/framework": "^2.13.0",
52
+ "@medusajs/js-sdk": "^2.13.0",
53
+ "@medusajs/medusa": "^2.13.0",
49
54
  "@medusajs/ui": "^4.0.0",
50
- "@medusajs/js-sdk": "^2.0.0",
51
55
  "@tanstack/react-query": "^5.0.0",
52
56
  "react": "^18.0.0 || ^19.0.0"
53
57
  },
54
58
  "devDependencies": {
55
59
  "@jest/globals": "^30.0.0",
60
+ "@medusajs/admin-sdk": "^2.13.1",
61
+ "@medusajs/cli": "^2.13.1",
56
62
  "@medusajs/framework": "^2.13.1",
63
+ "@medusajs/js-sdk": "^2.13.1",
64
+ "@medusajs/medusa": "^2.13.1",
65
+ "@medusajs/ui": "^4.0.27",
66
+ "@tanstack/react-query": "^5.64.2",
57
67
  "@types/jest": "^30.0.0",
58
68
  "@types/node": "^20.0.0",
69
+ "@types/react": "^19.0.0",
59
70
  "husky": "^9.1.7",
60
71
  "jest": "^30.3.0",
72
+ "react": "^19.0.0",
61
73
  "ts-jest": "^29.4.6",
62
- "typescript": "^5.0.0"
74
+ "typescript": "^5.0.0",
75
+ "yalc": "^1.0.0-pre.53"
63
76
  },
64
77
  "engines": {
65
78
  "node": ">=20"
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,sBAAsB,MAAM,WAAW,CAAA;AAE9C,eAAO,MAAM,uBAAuB,0BAA0B,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE9D,wBAEE"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,qDAAkD;AAClD,wDAA8C;AAEjC,QAAA,uBAAuB,GAAG,uBAAuB,CAAA;AAE9D,kBAAe,IAAA,cAAM,EAAC,+BAAuB,EAAE;IAC7C,OAAO,EAAE,iBAAsB;CAChC,CAAC,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"category-custom-attribute.d.ts","sourceRoot":"","sources":["../../src/models/category-custom-attribute.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,uBAAuB;;;;;;;;;;;;;;;;;gCAczB,CAAA;AAEJ,eAAe,uBAAuB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"category-custom-attribute.js","sourceRoot":"","sources":["../../src/models/category-custom-attribute.ts"],"names":[],"mappings":";;;;;AAAA,qDAAiD;AACjD,0FAA+D;AAE/D,MAAM,uBAAuB,GAAG,aAAK;KAClC,MAAM,CAAC,2BAA2B,EAAE;IACnC,EAAE,EAAE,aAAK,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE;IAC3B,GAAG,EAAE,aAAK,CAAC,IAAI,EAAE;IACjB,IAAI,EAAE,aAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;IAClC,KAAK,EAAE,aAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/B,IAAI,EAAE,aAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE,uCAAuC;IACtE,UAAU,EAAE,aAAK,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACrC,WAAW,EAAE,aAAK,CAAC,IAAI,EAAE;IACzB,WAAW,EAAE,aAAK,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,uDAAuD;IACpG,yBAAyB,EAAE,aAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,kCAAsB,CAAC;CACvE,CAAC;KACD,QAAQ,CAAC;IACR,MAAM,EAAE,CAAC,2BAA2B,CAAC;CACtC,CAAC,CAAA;AAEJ,kBAAe,uBAAuB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"product-custom-attribute.d.ts","sourceRoot":"","sources":["../../src/models/product-custom-attribute.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,sBAAsB;;;;;;;;;;;;;;;;;+BAS1B,CAAA;AAEF,eAAe,sBAAsB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"product-custom-attribute.js","sourceRoot":"","sources":["../../src/models/product-custom-attribute.ts"],"names":[],"mappings":";;;;;AAAA,qDAAiD;AACjD,4FAAiE;AAEjE,MAAM,sBAAsB,GAAG,aAAK,CAAC,MAAM,CAAC,0BAA0B,EAAE;IACtE,EAAE,EAAE,aAAK,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE;IAC3B,UAAU,EAAE,aAAK,CAAC,IAAI,EAAE;IACxB,KAAK,EAAE,aAAK,CAAC,IAAI,EAAE;IACnB,aAAa,EAAE,aAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxC,UAAU,EAAE,aAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IACnC,yBAAyB,EAAE,aAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,mCAAuB,EAAE;QACxE,QAAQ,EAAE,2BAA2B;KACtC,CAAC;CACH,CAAC,CAAA;AAEF,kBAAe,sBAAsB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,cAAM,sBAAuB,SAAQ,2BAAqB;IAClD,qBAAqB,CAAC,UAAU,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;IAQxC,uBAAuB,CAAC,IAAI,EAAE;QAClC,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACpB,WAAW,EAAE,MAAM,CAAA;QACnB,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB;;;;;;;;;;;;;;;;;;;;;;;;;;IAYK,uBAAuB,CAC3B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;QACJ,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACpB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB;;;;;;;;;;;;;;;;;;;;;;;;;;IAUG,sBAAsB,CAAC,IAAI,EAAE;QACjC,UAAU,EAAE,MAAM,CAAA;QAClB,4BAA4B,EAAE,MAAM,CAAA;QACpC,KAAK,EAAE,MAAM,CAAA;QACb,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;IAKK,sBAAsB,CAC1B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;QACJ,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB;;;;;;;;;;;;;;;;;;;;;;;;;;IAMG,oBAAoB,CAAC,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;IAU5C,OAAO,CAAC,WAAW;CAMpB;AAED,eAAe,sBAAsB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":";;;;;AAAA,qDAAyD;AACzD,mGAAwE;AACxE,iGAAsE;AAEtE,MAAM,MAAM,GAAG;IACb,uBAAuB,EAAvB,mCAAuB;IACvB,sBAAsB,EAAtB,kCAAsB;CACvB,CAAA;AAID,2EAA2E;AAC3E,MAAM,sBAAuB,SAAQ,IAAA,qBAAa,EAAC,MAAM,CAAC;IACxD,KAAK,CAAC,qBAAqB,CAAC,UAAkB;QAC5C,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,4BAA4B,CAAC;YAC7C,WAAW,EAAE,UAAU;YACvB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,IAO7B;QACC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACxC,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,8BAA8B,CAAC;YAC/C,GAAG,IAAI;YACP,GAAG;YACH,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;YACvB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,KAAK;YACtC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,CAAC;SACjC,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,uBAAuB,CAC3B,EAAU,EACV,IAMC;QAED,MAAM,UAAU,GAAwB,EAAE,GAAG,IAAI,EAAE,CAAA;QACnD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC/C,CAAC;QACD,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,8BAA8B,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC,CAAA;IAC3E,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,IAM5B;QACC,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,CAAA;IACvD,CAAC;IAED,KAAK,CAAC,sBAAsB,CAC1B,EAAU,EACV,IAKC;QAED,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,6BAA6B,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;IACpE,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,SAAiB;QAC1C,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,2BAA2B,CAAC;YAC5C,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,IAAI;SACjB,EAAE;YACD,SAAS,EAAE,CAAC,2BAA2B,CAAC;SACzC,CAAC,CAAA;IACJ,CAAC;IAEO,WAAW,CAAC,KAAa;QAC/B,OAAO,KAAK;aACT,WAAW,EAAE;aACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;aAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IAC1B,CAAC;CACF;AAED,kBAAe,sBAAsB,CAAA"}
@@ -1,9 +0,0 @@
1
- import Medusa from "@medusajs/js-sdk"
2
-
3
- export const sdk = new Medusa({
4
- baseUrl: import.meta.env.VITE_BACKEND_URL || "/",
5
- debug: import.meta.env.DEV,
6
- auth: {
7
- type: "session",
8
- },
9
- })
@@ -1,237 +0,0 @@
1
- import { defineWidgetConfig } from "@medusajs/admin-sdk"
2
- import {
3
- DetailWidgetProps,
4
- AdminProductCategory,
5
- } from "@medusajs/framework/types"
6
- import { Container, Heading, Button, Input, Text, Badge } from "@medusajs/ui"
7
- import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"
8
- import { useState } from "react"
9
- import { sdk } from "../lib/sdk"
10
-
11
- type CategoryCustomAttribute = {
12
- id: string
13
- label: string
14
- type: "text" | "number" | "file" | "boolean"
15
- category_id: string
16
- }
17
-
18
- type FormState = {
19
- label: string
20
- type: "text" | "number"
21
- }
22
-
23
- const emptyForm = (): FormState => ({ label: "", type: "text" })
24
-
25
- const CategoryAttributeTemplatesWidget = ({
26
- data,
27
- }: DetailWidgetProps<AdminProductCategory>) => {
28
- const categoryId = data.id
29
- const qc = useQueryClient()
30
- const queryKey = ["category-custom-attributes", categoryId]
31
-
32
- const [showAddForm, setShowAddForm] = useState(false)
33
- const [addForm, setAddForm] = useState<FormState>(emptyForm())
34
- const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null)
35
- const [mutationError, setMutationError] = useState<string | null>(null)
36
-
37
- const {
38
- data: result,
39
- isLoading,
40
- isError,
41
- } = useQuery<{
42
- category_custom_attributes: CategoryCustomAttribute[]
43
- }>({
44
- queryKey,
45
- queryFn: () =>
46
- sdk.client.fetch(`/admin/category/${categoryId}/custom-attributes`),
47
- })
48
-
49
- const attributes = result?.category_custom_attributes ?? []
50
-
51
- const createMutation = useMutation({
52
- mutationFn: (body: { label: string; type: string }) =>
53
- sdk.client.fetch(`/admin/category/${categoryId}/custom-attributes`, {
54
- method: "POST",
55
- body,
56
- }),
57
- onSuccess: () => {
58
- qc.invalidateQueries({ queryKey })
59
- setShowAddForm(false)
60
- setAddForm(emptyForm())
61
- setMutationError(null)
62
- },
63
- onError: (err: any) => {
64
- setMutationError(err?.message || "Ошибка при создании атрибута")
65
- },
66
- })
67
-
68
- const deleteMutation = useMutation({
69
- mutationFn: (id: string) =>
70
- sdk.client.fetch(`/admin/category/${categoryId}/custom-attributes`, {
71
- method: "PATCH",
72
- body: { id, deleted_at: new Date().toISOString() },
73
- }),
74
- onSuccess: () => {
75
- qc.invalidateQueries({ queryKey })
76
- setConfirmDeleteId(null)
77
- },
78
- })
79
-
80
- const handleAdd = () => {
81
- if (!addForm.label.trim()) return
82
- createMutation.mutate({
83
- label: addForm.label.trim(),
84
- type: addForm.type,
85
- })
86
- }
87
-
88
- return (
89
- <Container className="divide-y p-0">
90
- <div className="flex items-center justify-between px-6 py-4">
91
- <Heading level="h2">Атрибуты</Heading>
92
- {!showAddForm && (
93
- <Button
94
- variant="secondary"
95
- size="small"
96
- onClick={() => setShowAddForm(true)}
97
- >
98
- + Добавить
99
- </Button>
100
- )}
101
- </div>
102
-
103
- {isLoading && (
104
- <div className="px-6 py-4">
105
- <Text className="text-ui-fg-muted text-sm">Загрузка…</Text>
106
- </div>
107
- )}
108
-
109
- {isError && (
110
- <div className="px-6 py-4">
111
- <Text className="text-ui-fg-error text-sm">
112
- Не удалось загрузить атрибуты.
113
- </Text>
114
- </div>
115
- )}
116
-
117
- {!isLoading && !isError && attributes.length === 0 && !showAddForm && (
118
- <div className="px-6 py-4">
119
- <Text className="text-ui-fg-muted text-sm">
120
- Нет атрибутов. Добавьте первый.
121
- </Text>
122
- </div>
123
- )}
124
-
125
- {attributes.length > 0 && (
126
- <div className="divide-y">
127
- {attributes.map((attr) =>
128
- confirmDeleteId === attr.id ? (
129
- <div
130
- key={attr.id}
131
- className="flex items-center gap-3 px-6 py-3 text-sm"
132
- >
133
- <span className="flex-1 text-ui-fg-base">
134
- Удалить «{attr.label}»?
135
- </span>
136
- <Button
137
- size="small"
138
- variant="danger"
139
- onClick={() => deleteMutation.mutate(attr.id)}
140
- isLoading={deleteMutation.isPending}
141
- >
142
- Удалить
143
- </Button>
144
- <Button
145
- size="small"
146
- variant="secondary"
147
- onClick={() => setConfirmDeleteId(null)}
148
- >
149
- Отмена
150
- </Button>
151
- </div>
152
- ) : (
153
- <div
154
- key={attr.id}
155
- className="flex items-center gap-3 px-6 py-3"
156
- >
157
- <span className="flex-1 text-sm text-ui-fg-base">
158
- {attr.label}
159
- </span>
160
- <Badge size="2xsmall" color="grey">
161
- {attr.type === "text"
162
- ? "Текст"
163
- : attr.type === "number"
164
- ? "Число"
165
- : attr.type}
166
- </Badge>
167
- <button
168
- onClick={() => setConfirmDeleteId(attr.id)}
169
- className="text-xs text-ui-fg-error hover:underline"
170
- >
171
- Удалить
172
- </button>
173
- </div>
174
- )
175
- )}
176
- </div>
177
- )}
178
-
179
- {showAddForm && (
180
- <div className="flex items-center gap-2 px-6 py-3">
181
- <Input
182
- value={addForm.label}
183
- onChange={(e) =>
184
- setAddForm((f) => ({ ...f, label: e.target.value }))
185
- }
186
- placeholder="Название атрибута"
187
- className="flex-1 h-8 text-sm"
188
- autoFocus
189
- />
190
- <select
191
- value={addForm.type}
192
- onChange={(e) =>
193
- setAddForm((f) => ({
194
- ...f,
195
- type: e.target.value as "text" | "number",
196
- }))
197
- }
198
- className="h-8 rounded border border-ui-border-base bg-ui-bg-base px-2 text-sm"
199
- >
200
- <option value="text">Текст</option>
201
- <option value="number">Число</option>
202
- </select>
203
- <Button
204
- size="small"
205
- onClick={handleAdd}
206
- isLoading={createMutation.isPending}
207
- >
208
- Добавить
209
- </Button>
210
- <Button
211
- variant="secondary"
212
- size="small"
213
- onClick={() => {
214
- setShowAddForm(false)
215
- setAddForm(emptyForm())
216
- setMutationError(null)
217
- }}
218
- >
219
- Отмена
220
- </Button>
221
- </div>
222
- )}
223
-
224
- {mutationError && (
225
- <div className="px-6 py-2">
226
- <Text className="text-ui-fg-error text-sm">{mutationError}</Text>
227
- </div>
228
- )}
229
- </Container>
230
- )
231
- }
232
-
233
- export const config = defineWidgetConfig({
234
- zone: "product_category.details.after",
235
- })
236
-
237
- export default CategoryAttributeTemplatesWidget