Commit Graph

89 Commits

Author SHA1 Message Date
Oli Juhl
215553792b chore: Force select-in strategy by passing pagination through (#11556)
* chore: Force select-in by passing pagination through

* chore: Force select-in by passing pagination through
2025-02-23 14:42:19 +01:00
Adrien de Peretti
065df75e7d fix(): handle empty q filters - allow to query deleted records from graph API - staled_at fixes (#11544)
* fix(): Allow to query deleted records from graph API

* fix(): Allow to query deleted records from graph API

* handle empty q value

* update staled at sync

* rename integration tests file

* Create strong-houses-marry.md

* try to fix flacky tests

* fix pricing context

* update changeset

* update changeset

* fix import

* skip test for now

---------

Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
2025-02-21 13:24:12 +01:00
Adrien de Peretti
448dbcb596 feat(medusa): Rollout index engine behind feature flag (#11431)
**What**
- Add index engine feature flag
- apply it to the `store/products` end point as well as `admin/products`
- Query builder various fixes
- search capabilities on full data of every entities. The `q` search will be applied to all involved joined table for selection/where clauses

Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
2025-02-18 13:49:57 +00:00
Carlos R. L. Rodrigues
22276648ad feat: query.index (#11348)
What:
 - `query.index` helper. It queries the index module, and aggregate the rest of requested fields/relations if needed like `query.graph`.
 
Not covered in this PR:
 - Hydrate only sub entities returned by the query. Example: 1 out of 5 variants have returned, it should only hydrate the data of the single entity, currently it will merge all the variants of the product.
 - Generate types of indexed data
 
 example:
 ```ts
 const query = container.resolve(ContainerRegistrationKeys.QUERY)
        
 await query.index({
  entity: "product",
  fields: [
    "id",
    "description",
    "status",
    "variants.sku",
    "variants.barcode",
    "variants.material",
    "variants.options.value",
    "variants.prices.amount",
    "variants.prices.currency_code",
    "variants.inventory_items.inventory.sku",
    "variants.inventory_items.inventory.description",
  ],
  filters: {
    "variants.sku": { $like: "%-1" },
    "variants.prices.amount": { $gt: 30 },
  },
  pagination: {
    order: {
      "variants.prices.amount": "DESC",
    },
  },
})
```
This query return all products where at least one variant has the title ending in `-1` and at least one price bigger than `30`.
 
The Index Module only hold the data used to paginate and filter, and the returned object is:
```json
{
  "id": "prod_01JKEAM2GJZ14K64R0DHK0JE72",
  "title": null,
  "variants": [
    {
      "id": "variant_01JKEAM2HC89GWS95F6GF9C6YA",
      "sku": "extra-variant-1",
      "prices": [
        {
          "id": "price_01JKEAM2JADEWWX72F8QDP6QXT",
          "amount": 80,
          "currency_code": "USD"
        }
      ]
    }
  ]
}
```

All the rest of the fields will be hydrated from their respective modules, and the final result will be:

```json
{
  "id": "prod_01JKEAY2RJTF8TW9A23KTGY1GD",
  "description": "extra description",
  "status": "draft",
  "variants": [
    {
      "sku": "extra-variant-1",
      "barcode": null,
      "material": null,
      "id": "variant_01JKEAY2S945CRZ6X4QZJ7GVBJ",
      "options": [
        {
          "value": "Red"
        }
      ],
      "prices": [
        {
          "amount": 20,
          "currency_code": "CAD",
          "id": "price_01JKEAY2T2EEYSWZHPGG11B7W7"
        },
        {
          "amount": 80,
          "currency_code": "USD",
          "id": "price_01JKEAY2T2NJK2E5468RK84CAR"
        }
      ],
      "inventory_items": [
        {
          "variant_id": "variant_01JKEAY2S945CRZ6X4QZJ7GVBJ",
          "inventory_item_id": "iitem_01JKEAY2SNY2AWEHPZN0DDXVW6",
          "inventory": {
            "sku": "extra-variant-1",
            "description": "extra variant 1",
            "id": "iitem_01JKEAY2SNY2AWEHPZN0DDXVW6"
          }
        }
      ]
    }
  ]
}
```

Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
2025-02-12 12:55:09 +00:00
Adrien de Peretti
a33aebd895 feat(index): full sync operations (#11178)
Closes: FRMW-2892, FRMW-2893

**What**
Wired up the building block that we merged previously in order to manage data synchronization. The flow is as follow
- On application start
  - Build schema object representation from configuration
  - Check configuration changes
    - if new entities configured
      - Data synchronizer initialize orchestrator and start sync
        - for each entity
          - acquire lock
          - mark existing data as staled
          - sync all data by batch
          - marked them not staled anymore
          - acknowledge each processed batch and renew lock
          - update metadata with last synced cursor for entity X
          - release lock
      - remove all remaining staled data
    - if any entities removed from last configuration
      - remove the index data and relations

Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
2025-02-05 16:49:18 +00:00
Harminder Virk
c1930bd656 feat: Merge plugin modules (#10895)
Fixes: FRMW-2858

This PR merge the modules exported by the plugins with the modules defined within the user config. As a result, all modules get loaded without changing the internals of the loader.

However, you cannot disable the module of a plugin by re-adding it to the `modules` array. That is something we should handle separately. 

We've added the breaking change label because of the following fix:
We did broke the ability to completely disable modules in the past pr's, in this pr we re add the ability to disable a module and that this modules does not get loaded at all. ([here](6dd164f783))

Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
2025-01-10 10:02:09 +00:00
Stevche Radevski
fde73dbfae feat(auth-google,auth-github): Allow passing a custom callbackUrl to … (#10829)
* feat(auth-google,auth-github): Allow passing a custom callbackUrl to oauth providers

* feat: Add state management in auth providers

* chore: Changes based on PR review
2025-01-06 17:33:29 +01:00
Harminder Virk
ecc09fd77d feat: generate modules mappings at runtime (#10791) 2025-01-03 15:49:47 +05:30
Harminder Virk
bbf790ea44 feat: deprecate remote link (#10768)
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
2024-12-30 14:57:43 +05:30
Carlos R. L. Rodrigues
b0448a7c35 chore: locking-postgres provider dml (#10478) 2024-12-06 10:14:14 -03:00
Harminder Virk
1e0f6188ec fix: resolve paths using require.resolve (#9665) 2024-10-18 13:30:29 +00:00
Adrien de Peretti
876d8072e7 chore: Update modules providers configuration with 'identifier' and 'PROVIDER' (#9636)
* chore: Update modules providers configuration with 'identifier' and 'PROVIDER'

* update check

* fix tests

* type

* normalize auth provider

* emailpass

* providers

---------

Co-authored-by: Carlos R. L. Rodrigues <rodrigolr@gmail.com>
Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
2024-10-18 09:24:15 +02:00
Carlos R. L. Rodrigues
902ac12f73 chore: remove internal module resources option (#9582)
What:
* removes resouces type "shared" or "isolated" from internal modules.
* modules can have an isolated database connection by providing a database config as part of their options on `medusa-config`

CLOSES: FRMW-2593
2024-10-17 21:31:46 +00:00
Adrien de Peretti
e911c6aebf fix(modules-sdk): Add missing paths to require.resolve in load resources (#9608)
FIXES FRMW-2747

**What**

Add missing `paths` options
2024-10-16 17:20:56 +00:00
Harminder Virk
20428dac71 fix: resolve provider path before requiring it (#9601) 2024-10-16 14:17:55 +05:30
Carlos R. L. Rodrigues
4a03bdbb86 feat(providers): locking redis (#9544) 2024-10-15 12:40:24 -03:00
Adrien de Peretti
827b32cffd chore: Remove Query Filter (#9403)
**What**
Cleanup old QueryFilter
2024-10-15 10:41:53 +00:00
Carlos R. L. Rodrigues
c8b375ae2d feat(locking): Locking module (#9524)
**What**
- Locking Module to manage concurrency
- Default `in-memory` provider
2024-10-11 16:30:06 +00:00
Adrien de Peretti
1d8939df3a chore(): Allow to register modules through array (#9522) 2024-10-11 15:17:00 +02:00
Harminder Virk
1560d7ed5f breaking: Standalone builds (#9496)
Fixes: FRMW-2742

In this PR, we fix the build output of the backend source code, which eliminates a lot of magic between the development and production environments.

Right now, we only compile the source files from the `src` directory and write them within the `dist` directory.

**Here's how the `src` directory with a custom module looks like**

```
src
├── modules
│   └── hello
│       ├── index.ts
```

**Here's the build output**

```
dist
├── modules
│   └── hello
│       ├── index.js
```

Let's imagine a file at the root of your project (maybe the `medusa-config.js` file) that wants to import the `modules/hello/index` file. How can we ensure that the import will work in both the development and production environments?

If we write the import targeting the `src` directory, it will break in production because it should target the `dist` directory.

## Solution
The solution is to compile everything within the project and mimic the file structure in the build output, not just the `src` directory.

**Here's how the fixed output should look like**

```
dist
├── src
│  ├── modules
│  │   └── hello
│  │       ├── index.js
├── medusa-config.js
├── yarn.lock
├── package.json
```

If you notice carefully, we also have `medusa-config.js`, `yarn.lock`, and `package.json` within the `dist` directory. We do so to create a standalone built application, something you can copy/paste to your server and run without relying on the original source code.

- This results in small containers since you are not copying unnecessary files.
- Clear distinction between the development and the production code. If you want to run the production server, then `cd` into the `dist` directory and run it from there.

## Changes in the PR

- Breaking: Remove the `dist` and `build` folders. Instead, write them production artefacts within the `.medusa` directory as `.medusa/admin` and `.medusa/server`.
- Breaking: Change the output of the `.medusa/server` folder to mimic the root project structure.
- Refactor: Remove `Symbol.for("ts-node.register.instance")]` check to find from where to load the source code.
- Refactor: Use `tsc` for creating the production build. This ensures we respect `tsconfig` settings when creating the build and also perform type-checking.

Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
2024-10-09 15:59:08 +00:00
Carlos R. L. Rodrigues
cc77ca1413 chore(types): index module type (#9473) 2024-10-04 16:54:43 +00:00
Carlos R. L. Rodrigues
d06ea6985d fix: add order to pagination types (#9471) 2024-10-04 12:57:44 +00:00
Harminder Virk
d98f22c7d6 Feat: Move container bindings declaration merging within the framework (#9467) 2024-10-04 15:47:06 +05:30
Harminder Virk
48e00169d2 breaking: move shared HTTP utils to the framework (#9402)
Fixes: FRMW-2728, FRMW-2729

After this PR gets merged the following middleware will be exported from the `@medusajs/framework/http` import path.

- applyParamsAsFilters
- clearFiltersByKey
- applyDefaultFilters
- setContext
- getQueryConfig
- httpCompression
- maybeApplyLinkFilter
- refetchEntities
- unlessPath
- validateBody
- validateQuery

Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
2024-10-03 09:42:00 +00:00
Adrien de Peretti
8753b178da chore: Processing filters deeply looking at the current joiner first (#9428)
* chore: Processing filters deeply looking at the current joiner first

* fix

* fix
2024-10-02 14:17:12 +02:00
Harminder Virk
a578313db9 feature: bundle all modules (#9324) 2024-09-30 09:04:03 +02:00
Carlos R. L. Rodrigues
ef15c60386 chore(modules-sdk): load modules in sequence (#9327)
What:
- The time taken to load in sequence is the same as in parallel, and it doesn't create multiple db queries simultaneously when starting each module.
- Rework modules bootstrap (now all dependencies are available from the constructor and cross deps are allowed without any topological sort needed. It also allow improvements in the future)
  - First load all modules
  - then resolve and register instances


Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
2024-09-26 16:33:35 +00:00
Adrien de Peretti
fba78c0fb1 chore: remove direct usage from graphql (#9316)
**What**
Remove direct usage of graphql toold and instead consume it from utils to have a single entry point to graphql tooling
2024-09-26 08:18:26 +00:00
Carlos R. L. Rodrigues
11d8264062 fix(modules-sdk): default db options (#9313) 2024-09-25 19:44:12 -03:00
Adrien de Peretti
74cdb9d4b6 fix(modules-sdk): Fix dynamic import usage (#9304)
* fix(modules-sdk): Fix dynamic import usage

* missing new line
2024-09-25 13:29:00 +02:00
Adrien de Peretti
358435d715 chore: Move graphl to a single place (#9303)
* chore: Move graphl to a single place

* add new line
2024-09-25 12:04:25 +02:00
Harminder Virk
9e711720dd chore: upgrade moduleResolution to Node16 (#9269) 2024-09-24 17:19:20 +05:30
Adrien de Peretti
919d19095a refactor(modules-sdk): Align configuration and fixes (#9239)
* refactor(modules-sdk): Align configuration and fixes

* typo

* fix configuration
2024-09-23 12:12:26 +02:00
Adrien de Peretti
3084008fc9 feat(index): Provide a similar API to Query (#9193)
**What**
Align the index engine API to be similar to the Query API

## Example

```ts
        // Benefit from the same level of typing like the remote query

        const { data, metadata } = await indexEngine.query<'product'>({
          fields: [
            "product.*",
            "product.variants.*",
            "product.variants.prices.*",
          ],
          filters: {
            product: {
              variants: {
                prices: {
                  amount: { $gt: 50 },
                },
              },
            },
          },
          pagination: {
            order: {
              product: {
                variants: {
                  prices: {
                    amount: "DESC",
                  },
                },
              },
            },
          },
        })
```
2024-09-20 10:02:42 +00:00
Carlos R. L. Rodrigues
1215a7c094 chore(orchestrator): remote joiner using entitymap (#9205) 2024-09-20 05:30:08 -03:00
Adrien de Peretti
58167b5dfa feat(index): Index module foundation (#9095)
**What**
Index module foundation

Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
2024-09-18 19:04:04 +00:00
Adrien de Peretti
c6795dfc47 feat(modules-sdk): Parse filters based on loaded modules graph (#9158) 2024-09-17 14:20:04 -03:00
Carlos R. L. Rodrigues
8829f89402 chore: query graph api (#9125)
CLOSES: FRMW-2704

**What**
Re-structure the Query graph API as well as introduce dynamic typing from schemas on the filters and better handling of relation treatment for fields/filters inference

Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
2024-09-16 11:32:44 +00:00
Carlos R. L. Rodrigues
950cf9af79 chore: remove container registration name (#9137) 2024-09-16 06:22:24 -03:00
Adrien de Peretti
03d6b64a20 fix(): Query Missing bindings (#9131) 2024-09-13 18:22:38 +02:00
Harminder Virk
c97ea9546d feature: add tracing to remote query (#9128) 2024-09-13 14:09:59 +05:30
Adrien de Peretti
a01e7e4ffe chore: Register Query in container (#9103)
* chore(framework): Register the query

* chore(framework): Register the query
2024-09-11 15:08:46 +02:00
Carlos R. L. Rodrigues
fdd0543011 chore: joiner config entity property (#9084) 2024-09-11 06:25:25 -03:00
Adrien de Peretti
423bae1d73 chore(modules-sdk): Move Query and cleanup (#9054)
* chore(modules-sdk): Move Query and cleanup

* cleanup

* fix memoization
2024-09-09 12:42:17 +02:00
Harminder Virk
32ebfa619f feature: introduce types for query.graph method (#9031) 2024-09-09 13:26:40 +05:30
Adrien de Peretti
2c5e72d141 feat: Application types generation from project GQL schema's (#8995) 2024-09-06 15:15:32 +05:30
Carlos R. L. Rodrigues
5a097d8954 feat(utils): dml to graphql (#8951) 2024-09-04 06:15:07 -03:00
Adrien de Peretti
77b874f272 feat: Add support for providers to validate their options at loading time (#8853)
* feat: Add support for providers to validate their options at loading time

* fix missing removal

* fix integration tests

* add tests
2024-08-29 09:08:49 +02:00
Carlos R. L. Rodrigues
058378970a chore: dependecies reorg (#8535) 2024-08-23 07:16:04 -03:00
Shahed Nasser
848d0892d9 chore(core-flows,modules-sdk): add TSDocs to helper steps (#8355) 2024-07-30 18:59:02 +03:00