@medusajs/query 2.22.0-snapshot-20261020204851 → 2.22.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 (3) hide show
  1. package/AGENTS.md +68 -0
  2. package/README.md +80 -0
  3. package/package.json +8 -4
package/AGENTS.md ADDED
@@ -0,0 +1,68 @@
1
+ # @medusajs/query
2
+
3
+ Implements Query, the cross-module read layer: it takes `query.graph()` / `query.index()` / `query.search()` input, plans it against every queryable module's joiner config and link definitions (`RemoteJoiner`), fetches from each module service, and stitches the results. `@medusajs/modules-sdk` builds the instance that is registered as `query` in the container.
4
+
5
+ ## Using this package
6
+
7
+ Do not import this package directly. Resolve Query from the container:
8
+
9
+ ```ts
10
+ import { ContainerRegistrationKeys, QueryContext } from "@medusajs/framework/utils"
11
+
12
+ const query = container.resolve(ContainerRegistrationKeys.QUERY)
13
+
14
+ const { data: products, metadata } = await query.graph(
15
+ {
16
+ entity: "product",
17
+ fields: ["id", "title", "variants.*", "post.*"],
18
+ filters: { status: "published" },
19
+ pagination: { skip: 0, take: 20, order: { created_at: "DESC" } },
20
+ context: {
21
+ variants: {
22
+ calculated_price: QueryContext({
23
+ region_id: "reg_123",
24
+ currency_code: "usd",
25
+ }),
26
+ },
27
+ },
28
+ },
29
+ { throwIfKeyNotFound: true }
30
+ )
31
+ ```
32
+
33
+ - In API routes use `req.scope.resolve(ContainerRegistrationKeys.QUERY)`; in workflows prefer `useQueryGraphStep` from `@medusajs/core-flows`.
34
+ - `query.graph(input, options)` input: `entity`, `fields`, `filters`, `pagination` (`skip`, `take`, `order`), `context`, `withDeleted`, `strategy` (`"joined" | "select-in" | "balanced"`). Returns `{ data, metadata }` (`metadata` holds `count`/`skip`/`take` when paginated).
35
+ - Options (`RemoteJoinerOptions`): `throwIfKeyNotFound`, `throwIfRelationNotFound`, `initialData`, `initialDataOnly`, `locale` (applies translations), `cache` (`enable`, `key`, `ttl`, `tags`, `autoInvalidate`, `providers`).
36
+ - `query.index(...)` filters through the Index Module and accepts `joinFilters`; throws `Index module is not loaded.` without it.
37
+ - `query.search(...)` runs through the Search Module and hydrates fields the index doesn't store with `query.graph`; throws `Search module is not loaded.` without it.
38
+ - Legacy: calling `query(...)` / `query.gql(...)` (old remote query) still works.
39
+ - Entity names and field typings come from `.medusa/types/query-entry-points` generated on `medusa develop`.
40
+ - Docs: https://docs.medusajs.com/learn/fundamentals/query.md, https://docs.medusajs.com/learn/fundamentals/query/query-context.md, https://docs.medusajs.com/learn/fundamentals/query/index-module.md, https://docs.medusajs.com/learn/fundamentals/query/search.md
41
+
42
+ ## Architecture
43
+
44
+ - `src/query/query.ts`: `Query` class and `createQuery()` (only modules with `isQueryable` definitions are included). `graph` and `index` are wrapped with `@Cached(queryCacheDecoratorOptions)` from `cache.ts`.
45
+ - `src/query/to-remote-query.ts`, `to-remote-joiner-query.ts`: convert `{ entity, fields, filters }` input into the joiner query shape.
46
+ - `src/query/module-data-fetcher.ts`: calls each module's `list`/`listAndCount`.
47
+ - `src/joiner/`: `RemoteJoiner` pipeline `GraphCatalog` (`catalog.ts`, indexes joiner configs) -> `compileQuery` (`compile.ts`, query -> plan) -> `executePlan` (`execute.ts`, fetch + join + shortcuts).
48
+ - `src/joiner/cross-module-joins/`: filters/sorts on linked-module fields are pushed down to SQL (`EXISTS`/scalar subqueries) when every hop is a link, read-only link FK, or DML relation in the same database and the field is a non-computed column; anything else becomes a residual filter applied in memory after fetching (`in-memory-filter.ts`).
49
+ - Tracing hooks: `Query.instrument.graphQuery/remoteQuery/remoteDataFetch` (wired by `packages/medusa/src/instrumentation`).
50
+
51
+ ## Development
52
+
53
+ ```bash
54
+ yarn build
55
+ yarn test # jest --bail --forceExit (src and integration-tests)
56
+ yarn test src/joiner/__tests__/cross-module-joins.spec.ts
57
+ ```
58
+
59
+ - `integration-tests/__tests__/query.spec.ts` uses mocked module services from `integration-tests/__fixtures__/setup`; no database needed.
60
+ - Real end-to-end Query behavior is exercised in `integration-tests/modules/` and `integration-tests/http/` at the repo root.
61
+
62
+ ## Gotchas
63
+
64
+ - Caching is off unless `options.cache` is passed with `enable: true` or any of `key`/`ttl`/`tags`/`computeAutomaticTags`/`autoInvalidate`/`providers`; `cache.enable: false` always wins.
65
+ - Cross-module filter pushdown restricts root rows (same semantics as `query.index`), and expand nodes that existed only to carry those filters are dropped.
66
+ - `createQuery` throws `Duplicated instance of module <name> is not allowed.` if two loaded modules share a key.
67
+ - `query.index` and `query.search` pass `pagination.take` into the follow-up `graph` call on purpose: it forces the `select-in` strategy.
68
+ - `throwIfKeyNotFound` requires the primary key in `filters`; otherwise it throws `Primary key(s) [...] not found in filters` even if other filters match.
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ <p align="center">
2
+ <a href="https://www.medusajs.com">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/59018053/229103275-b5e482bb-4601-46e6-8142-244f531cebdb.svg">
5
+ <source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
6
+ <img alt="Medusa logo" src="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
7
+ </picture>
8
+ </a>
9
+ </p>
10
+ <h1 align="center">
11
+ @medusajs/query
12
+ </h1>
13
+
14
+ <h4 align="center">
15
+ <a href="https://docs.medusajs.com">Documentation</a> |
16
+ <a href="https://www.medusajs.com">Website</a>
17
+ </h4>
18
+
19
+ <p align="center">
20
+ Building blocks for digital commerce
21
+ </p>
22
+ <p align="center">
23
+ <a href="https://github.com/medusajs/medusa/blob/develop/LICENSE">
24
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="Medusa is released under the MIT license." />
25
+ </a>
26
+ <a href="https://github.com/medusajs/medusa/blob/develop/CONTRIBUTING.md">
27
+ <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="PRs welcome!" />
28
+ </a>
29
+ <a href="https://discord.gg/xpCwq3Kfn8">
30
+ <img src="https://img.shields.io/badge/chat-on%20discord-7289DA.svg" alt="Discord Chat" />
31
+ </a>
32
+ <a href="https://twitter.com/intent/follow?screen_name=medusajs">
33
+ <img src="https://img.shields.io/twitter/follow/medusajs.svg?label=Follow%20@medusajs" alt="Follow @medusajs" />
34
+ </a>
35
+ </p>
36
+
37
+ Query and Remote Joiner for Medusa: the engine behind Query, which retrieves data across modules and their links in a single call. You don't import this package directly in a Medusa application; resolve Query from the Medusa container with `ContainerRegistrationKeys.QUERY` (`"query"`), or use `useQueryGraphStep` from `@medusajs/medusa/core-flows` inside workflows.
38
+
39
+ ## At a glance
40
+
41
+ | | |
42
+ | --- | --- |
43
+ | Package | `@medusajs/query` |
44
+ | Type | Core library |
45
+ | Import from | Resolved from the container as `ContainerRegistrationKeys.QUERY` (`"query"`) |
46
+
47
+ ## Features
48
+
49
+ - `query.graph()` to retrieve records of a data model and their linked records from other modules.
50
+ - `query.index()` to filter across linked modules using the Index Module.
51
+ - `query.search()` to run search queries through the Search Module.
52
+ - `RemoteJoiner`, which resolves and joins data across module services.
53
+
54
+ ## Installation
55
+
56
+ No separate installation is needed in a Medusa application. It's installed with `@medusajs/framework` through `@medusajs/modules-sdk`.
57
+
58
+ ## Usage
59
+
60
+ ```ts
61
+ import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
62
+ import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
63
+
64
+ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
65
+ const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
66
+
67
+ const { data: products } = await query.graph({
68
+ entity: "product",
69
+ fields: ["id", "title", "variants.*"],
70
+ })
71
+
72
+ res.json({ products })
73
+ }
74
+ ```
75
+
76
+ ## Resources
77
+
78
+ - [Query](https://docs.medusajs.com/learn/fundamentals/query)
79
+ - [Query with the Index Module](https://docs.medusajs.com/learn/fundamentals/query/index-module)
80
+ - [Query search](https://docs.medusajs.com/learn/fundamentals/query/search)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medusajs/query",
3
- "version": "2.22.0-snapshot-20261020204851",
3
+ "version": "2.22.0",
4
4
  "description": "Medusa remote query and joiner",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -22,10 +22,14 @@
22
22
  },
23
23
  "files": [
24
24
  "dist",
25
+ "AGENTS.md",
25
26
  "!dist/**/__tests__",
26
27
  "!dist/**/__fixtures__",
27
28
  "!dist/**/__mocks__"
28
29
  ],
30
+ "llms": "https://docs.medusajs.com/llms.txt",
31
+ "llmsFull": "https://docs.medusajs.com/llms-full.txt",
32
+ "mcpServer": "https://docs.medusajs.com/mcp",
29
33
  "author": "Medusa",
30
34
  "license": "MIT",
31
35
  "scripts": {
@@ -34,10 +38,10 @@
34
38
  "watch": "yarn run -T tsc --build --watch"
35
39
  },
36
40
  "devDependencies": {
37
- "@medusajs/types": "2.22.0-snapshot-20261020204851"
41
+ "@medusajs/types": "2.22.0"
38
42
  },
39
43
  "dependencies": {
40
- "@medusajs/deps": "2.22.0-snapshot-20261020204851",
41
- "@medusajs/utils": "2.22.0-snapshot-20261020204851"
44
+ "@medusajs/deps": "2.22.0",
45
+ "@medusajs/utils": "2.22.0"
42
46
  }
43
47
  }