@weareseeed/medusa-athos-plugin 0.0.1

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 +259 -0
  2. package/.medusa/server/src/admin/index.mjs +258 -0
  3. package/.medusa/server/src/api/admin/athos/config/route.d.ts +4 -0
  4. package/.medusa/server/src/api/admin/athos/config/route.js +21 -0
  5. package/.medusa/server/src/api/admin/athos/middlewares.d.ts +11 -0
  6. package/.medusa/server/src/api/admin/athos/middlewares.js +20 -0
  7. package/.medusa/server/src/api/admin/plugin/route.d.ts +2 -0
  8. package/.medusa/server/src/api/admin/plugin/route.js +7 -0
  9. package/.medusa/server/src/api/athos/feed/route.d.ts +2 -0
  10. package/.medusa/server/src/api/athos/feed/route.js +249 -0
  11. package/.medusa/server/src/api/athos/middlewares.d.ts +2 -0
  12. package/.medusa/server/src/api/athos/middlewares.js +26 -0
  13. package/.medusa/server/src/api/middlewares.d.ts +2 -0
  14. package/.medusa/server/src/api/middlewares.js +9 -0
  15. package/.medusa/server/src/api/store/plugin/route.d.ts +2 -0
  16. package/.medusa/server/src/api/store/plugin/route.js +7 -0
  17. package/.medusa/server/src/modules/athosConfig/index.d.ts +21 -0
  18. package/.medusa/server/src/modules/athosConfig/index.js +13 -0
  19. package/.medusa/server/src/modules/athosConfig/migrations/Migration20260518000000.d.ts +5 -0
  20. package/.medusa/server/src/modules/athosConfig/migrations/Migration20260518000000.js +26 -0
  21. package/.medusa/server/src/modules/athosConfig/migrations/Migration20260518000001.d.ts +5 -0
  22. package/.medusa/server/src/modules/athosConfig/migrations/Migration20260518000001.js +14 -0
  23. package/.medusa/server/src/modules/athosConfig/models/athos-config.d.ts +9 -0
  24. package/.medusa/server/src/modules/athosConfig/models/athos-config.js +13 -0
  25. package/.medusa/server/src/modules/athosConfig/service.d.ts +17 -0
  26. package/.medusa/server/src/modules/athosConfig/service.js +32 -0
  27. package/.medusa/server/src/modules/athosConfig/types.d.ts +15 -0
  28. package/.medusa/server/src/modules/athosConfig/types.js +3 -0
  29. package/.medusa/server/src/workflows/steps/upsert-athos-config-step.d.ts +9 -0
  30. package/.medusa/server/src/workflows/steps/upsert-athos-config-step.js +31 -0
  31. package/.medusa/server/src/workflows/upsert-athos-config.d.ts +9 -0
  32. package/.medusa/server/src/workflows/upsert-athos-config.js +10 -0
  33. package/README.md +198 -0
  34. package/package.json +73 -0
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+ # @weareseeed/medusa-athos-plugin
2
+
3
+ Medusa v2 plugin that generates a streaming [NDJSON](https://ndjson.org/) product feed for [Athos Commerce](https://athos.com) integration.
4
+
5
+ ## Features
6
+
7
+ - Streaming NDJSON product feed (one line per variant + one product summary line)
8
+ - Token-based feed authentication
9
+ - Price filtering by region
10
+ - Product filtering by sales channel
11
+ - Configurable swatch options
12
+ - Extensible via `extraProductFields` and `transformLine` hooks
13
+ - Admin API to manage plugin configuration
14
+
15
+ ## Requirements
16
+
17
+ - Medusa v2
18
+ - Node.js >= 20
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ yarn add @weareseeed/medusa-athos-plugin
24
+ ```
25
+
26
+ ## Setup
27
+
28
+ ### 1. Register the plugin
29
+
30
+ ```ts
31
+ // medusa-config.ts
32
+ import { defineConfig } from "@medusajs/framework/config"
33
+
34
+ export default defineConfig({
35
+ plugins: [
36
+ {
37
+ resolve: "@weareseeed/medusa-athos-plugin",
38
+ options: {},
39
+ },
40
+ ],
41
+ })
42
+ ```
43
+
44
+ ### 2. Run migrations
45
+
46
+ ```bash
47
+ npx medusa db:migrate
48
+ ```
49
+
50
+ ### 3. Configure via Admin API
51
+
52
+ Set the plugin configuration through the authenticated admin endpoint:
53
+
54
+ ```bash
55
+ curl -X POST http://localhost:9000/admin/athos/config \
56
+ -H "Authorization: Bearer <admin_token>" \
57
+ -H "Content-Type: application/json" \
58
+ -d '{
59
+ "storefront_url": "https://mystore.com",
60
+ "feed_token": "a-secret-token",
61
+ "region_id": "reg_01...",
62
+ "sales_channel_ids": ["sc_01..."],
63
+ "swatch_option_titles": ["color", "colour"]
64
+ }'
65
+ ```
66
+
67
+ | Field | Type | Required | Description |
68
+ |---|---|---|---|
69
+ | `storefront_url` | `string` | Yes | Base URL prepended to `/products/<handle>` for each product URL |
70
+ | `feed_token` | `string` | Yes | Secret token required to access the feed endpoint |
71
+ | `region_id` | `string` | No | When set, prices are filtered to the region's currency |
72
+ | `sales_channel_ids` | `string[]` | No | When set, only products in these sales channels are included |
73
+ | `swatch_option_titles` | `string[]` | No | Option titles treated as swatches (default: `["color", "colour"]`) |
74
+
75
+ ## Feed Endpoint
76
+
77
+ ```
78
+ GET /athos/feed?token=<feed_token>
79
+ ```
80
+
81
+ Returns an `application/x-ndjson` stream. Each product produces:
82
+
83
+ 1. One **variant line** per variant
84
+ 2. One **product summary line**
85
+
86
+ ### Variant line fields
87
+
88
+ | Field | Description |
89
+ |---|---|
90
+ | `Product ID` | Variant ID |
91
+ | `SKU` | Variant SKU |
92
+ | `Name` | Variant title |
93
+ | `Product URL` | `<storefront_url>/products/<handle>` |
94
+ | `Price` | Lowest price for the variant (filtered by region if configured) |
95
+ | `Retail Price` | `compare_at_price` |
96
+ | `Thumbnail URL` | Product thumbnail |
97
+ | `Description` | Product description |
98
+ | `Category` | Array of category path strings (e.g. `"Parent>Child"`) |
99
+ | `Category ID` | Array of category IDs |
100
+ | `Search Keywords` | Comma-separated product tags |
101
+ | `__parent_id` | Parent product ID |
102
+ | `__parent_title` | Parent product title |
103
+ | `__parent_image` | Parent product thumbnail |
104
+ | `__variant_position` | 1-based position within the product |
105
+ | `__in_stock` | `true` if the variant is available |
106
+ | `__in_stock_pct` | % of variants in stock across the product |
107
+ | `__standard_options` | All product options with positions and values |
108
+ | `__selected_options` | This variant's chosen option values |
109
+ | `__swatch_options` | Values of configured swatch options (product-level) |
110
+
111
+ ### Product summary line fields
112
+
113
+ Same as variant line minus all `__` private fields, with `Product ID` set to the product ID and `Price` set to the lowest price across all variants.
114
+
115
+ ### Example
116
+
117
+ ```json
118
+ {"Product ID":"variant_01...","SKU":"1","Name":"blue, m","Product URL":"https://mystore.com/products/example","Price":10,"Thumbnail URL":"https://...","Description":"...","Category":["Tops"],"Category ID":["pcat_01..."],"__parent_id":"prod_01...","__parent_title":"Example Product","__parent_image":"https://...","__variant_position":1,"__in_stock":true,"__in_stock_pct":100,"__standard_options":{"color":{"position":0,"values":["red","blue"]},"size":{"position":1,"values":["s","m"]}},"__selected_options":{"color":{"value":"blue"},"size":{"value":"m"}},"__swatch_options":{"red":{"value":"red"},"blue":{"value":"blue"}}}
119
+ {"Product ID":"prod_01...","Name":"Example Product","Product URL":"https://mystore.com/products/example","Price":10,"Thumbnail URL":"https://...","Description":"...","Category":["Tops"],"Category ID":["pcat_01..."]}
120
+ ```
121
+
122
+ ## Plugin Options
123
+
124
+ Pass options when registering the plugin in `medusa-config.ts` to extend the feed.
125
+
126
+ ```ts
127
+ import { defineConfig } from "@medusajs/framework/config"
128
+ import type { FeedLineContext } from "@weareseeed/medusa-athos-plugin/types"
129
+
130
+ export default defineConfig({
131
+ plugins: [
132
+ {
133
+ resolve: "@weareseeed/medusa-athos-plugin",
134
+ options: {
135
+ feed: {
136
+ extraProductFields: ["metadata", "variants.metadata"],
137
+ transformLine: (line, ctx: FeedLineContext) => {
138
+ line["Brand"] = (ctx.product as any).metadata?.brand ?? undefined
139
+
140
+ if (ctx.type === "variant") {
141
+ line["Custom Variant Field"] = (ctx.variant as any).metadata?.custom ?? undefined
142
+ }
143
+
144
+ if (ctx.type === "product") {
145
+ line["Custom Product Field"] = (ctx.product as any).metadata?.custom ?? undefined
146
+ }
147
+
148
+ return line
149
+ },
150
+ },
151
+ },
152
+ },
153
+ ],
154
+ })
155
+ ```
156
+
157
+ ### `feed.extraProductFields`
158
+
159
+ `string[]` — Additional Medusa product fields to fetch and make available inside `transformLine`. Uses the same dot-notation field paths as Medusa's `query.graph`.
160
+
161
+ ```ts
162
+ extraProductFields: [
163
+ "metadata",
164
+ "variants.metadata",
165
+ "images.url",
166
+ "collection.title",
167
+ ]
168
+ ```
169
+
170
+ ### `feed.transformLine`
171
+
172
+ ```ts
173
+ (line: Record<string, unknown>, ctx: FeedLineContext) =>
174
+ Record<string, unknown> | Promise<Record<string, unknown>>
175
+ ```
176
+
177
+ Called for every line written to the feed. Use it to add, remove, or transform fields. The `ctx` argument provides typed access to the raw product and variant data:
178
+
179
+ ```ts
180
+ type FeedLineContext =
181
+ | { type: "variant"; product: Record<string, unknown>; variant: Record<string, unknown>; variantIndex: number }
182
+ | { type: "product"; product: Record<string, unknown> }
183
+ ```
184
+
185
+ > Fields that resolve to `undefined` are automatically stripped from the output.
186
+
187
+ ## Admin API
188
+
189
+ Both endpoints require an authenticated admin JWT.
190
+
191
+ | Method | Path | Description |
192
+ |---|---|---|
193
+ | `GET` | `/admin/athos/config` | Retrieve the current configuration |
194
+ | `POST` | `/admin/athos/config` | Create or update the configuration |
195
+
196
+ ## License
197
+
198
+ MIT — [Seeed](https://seeed.us/)
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@weareseeed/medusa-athos-plugin",
3
+ "version": "0.0.1",
4
+ "description": "Medusa Athos Integration Plugin.",
5
+ "author": "Seeed (https://seeed.us/)",
6
+ "license": "MIT",
7
+ "files": [
8
+ ".medusa/server"
9
+ ],
10
+ "exports": {
11
+ "./package.json": "./package.json",
12
+ "./types": {
13
+ "types": "./.medusa/server/src/modules/athosConfig/types.d.ts",
14
+ "default": "./.medusa/server/src/modules/athosConfig/types.js"
15
+ },
16
+ "./workflows": "./.medusa/server/src/workflows/index.js",
17
+ "./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
18
+ "./modules/*": "./.medusa/server/src/modules/*/index.js",
19
+ "./providers/*": "./.medusa/server/src/providers/*/index.js",
20
+ "./*": "./.medusa/server/src/*.js",
21
+ "./admin": {
22
+ "import": "./.medusa/server/src/admin/index.mjs",
23
+ "require": "./.medusa/server/src/admin/index.js",
24
+ "default": "./.medusa/server/src/admin/index.js"
25
+ }
26
+ },
27
+ "keywords": [
28
+ "medusa",
29
+ "plugin",
30
+ "medusa-plugin",
31
+ "medusa-plugin-integration",
32
+ "medusa-v2",
33
+ "medusa-plugin-search"
34
+ ],
35
+ "scripts": {
36
+ "build": "medusa plugin:build && tsc --emitDeclarationOnly --noEmit false",
37
+ "dev": "medusa plugin:develop",
38
+ "prepublishOnly": "medusa plugin:build"
39
+ },
40
+ "devDependencies": {
41
+ "@medusajs/admin-sdk": "2.14.2",
42
+ "@medusajs/cli": "2.14.2",
43
+ "@medusajs/framework": "2.14.2",
44
+ "@medusajs/icons": "2.14.2",
45
+ "@medusajs/medusa": "2.14.2",
46
+ "@medusajs/test-utils": "2.14.2",
47
+ "@medusajs/ui": "4.1.9",
48
+ "@swc/core": "^1.7.28",
49
+ "@types/node": "^20.0.0",
50
+ "@types/react": "^18.3.2",
51
+ "@types/react-dom": "^18.2.25",
52
+ "prop-types": "^15.8.1",
53
+ "react": "^18.2.0",
54
+ "react-dom": "^18.2.0",
55
+ "ts-node": "^10.9.2",
56
+ "typescript": "^5.6.2",
57
+ "vite": "^5.2.11",
58
+ "yalc": "^1.0.0-pre.53"
59
+ },
60
+ "peerDependencies": {
61
+ "@medusajs/admin-sdk": "2.14.2",
62
+ "@medusajs/cli": "2.14.2",
63
+ "@medusajs/framework": "2.14.2",
64
+ "@medusajs/icons": "2.14.2",
65
+ "@medusajs/medusa": "2.14.2",
66
+ "@medusajs/test-utils": "2.14.2",
67
+ "@medusajs/ui": "4.1.9"
68
+ },
69
+ "engines": {
70
+ "node": ">=20"
71
+ },
72
+ "packageManager": "yarn@4.9.2"
73
+ }