Commit Graph

4652 Commits

Author SHA1 Message Date
Adrien de Peretti
1d91b7429b feat(fulfillment): implementation part 2 (#6408)
**What**

> [!NOTE]  
> I can see this pr becoming huge, so I d like to get this partial one merged 👍 


- Fixes shared connection usage (mikro orm compare the instance to its own package and therefore was resulting in not trully reusing the provided connection leading to exhausting the connection pool as multiple connections was created and end up not being all destroyed properly under the hood, discovered in my integration tests)
- Create shipping options method implementation
- DTO's definition and service interface update
- integration tests 
- Re work of the indexes with new util update
- Test runner utils to remove a big chunk of the boilerplate of the packages integrations

FIXES CORE-1742
2024-02-19 12:33:46 +00:00
Oli Juhl
680dfcdad3 feat(core-flow, medusa): Create cart with Sales Channel (#6427) 2024-02-19 09:42:11 +01:00
Oli Juhl
5db3ec09e2 feat: Cart Customer link + create cart with customer (#6426) 2024-02-19 08:28:44 +01:00
Philip Korsholm
f6d38163bb Feat(medusa, user, core-flows): User creation with invites (#6413)
**What**
- add accept invite endpoint 

**Invite accept flow**
- authenticate using the auth endpoint to create and auth-user
- invoke accept endpoint with token and info to create user
2024-02-19 05:29:15 +00:00
Sebastian Rindom
5977a38ef4 feat(tax): Add TaxRegion (#6421)
**What**
- Adds a TaxRegion entity.

**For context: High-level design of the Tax module**
- A TaxRegion scopes tax rates to a geographical place.
- You can define tax regions on two levels: country-level, province-level (this corresponds to state in US contexts)
- Each Tax Region can have a default Tax Rate.
-  [not yet done] - Each Tax Region can also have granularly defined tax rates for different products and shipping rates. For example, California can have a base rate for default products, but a reduced rate for groceries.
- Tax Rates specify if they can be combined with other rates - it's always the lowest level rate that wins.

The above allows a merchant to define their tax settings along the lines of this:

- Denmark (Region)
  - Default rate: 25% (TaxRate)
- Germany (Region)
  - Default rate: 19% (TaxRate)
  - Reduced rate (books): 9% (TaxRate w. rule)
- United States (Region)
  - Default rate: 0% (TaxRate)
  - California: (Region)
    - Default rate: 7.25% (TaxRate)
  - Arkansas: (Region)
    - Default rate: 6.5%
    - Reduced rate (groceries): 0.125% (TaxRate w. rule)

The TaxModule can then receive a list of products and the shipping address to determine what tax rates apply to the line items.
2024-02-18 13:31:50 +00:00
Oli Juhl
1ba35b02dd feat: Cart SalesChannel link + clean-up (#6418) 2024-02-16 20:48:56 +01:00
Darius
1df14de183 chore: Update teams.yml (#6419)
adding myself to medusa team
2024-02-16 16:57:54 +01:00
Shahed Nasser
68123c6ffd docs: add missing steps to enable medusa_v2 flag (#6406) 2024-02-16 14:20:52 +00:00
Oli Juhl
24fb102a56 feat: CartRegion link, definition + workflow (#6392) 2024-02-16 14:06:26 +00:00
Sebastian Rindom
7df4947ecf feat(tax): tax module scaffolding (#6417)
**What**
- Scaffolds the tax module
2024-02-16 13:24:23 +00:00
Shahed Nasser
0d68eadf84 docs: add ignore tag to isPaymentProcessor (#6410)
- Add ignore tags to `isPaymentProcessor` method and property
- Generate payment reference to move the associated section.
2024-02-16 12:51:14 +00:00
Stevche Radevski
35a4db29b7 Merge pull request #6416 from medusajs/chore/add-sradevski-teams
Add sradevski to teams.yml
2024-02-16 13:14:35 +01:00
Stevche Radevski
a4d43f05f0 Add sradevski to teams.yml 2024-02-16 13:00:15 +01:00
Stevche Radevski
076c1cd752 Merge pull request #6409 from medusajs/docs/fix-description-payment-processor
docs(payments): Fix incorrect reference in payment processor tsdoc
2024-02-16 09:36:19 +01:00
Stevche Radevski
b5369a4ff1 docs(payments): Fix incorrect reference in payment processor tsdoc 2024-02-16 08:41:05 +01:00
Carlos R. L. Rodrigues
586df9da25 fix: Loading custom modules (#6411)
What:
   fix custom modules loading in medusa project
   pass medusa logger reference to MedusaApp
2024-02-15 15:06:02 +00:00
Carlos R. L. Rodrigues
339a946f38 feat(order): module foundation (#6399)
What:
Initial Order module foundation.
Basic models and methods to manage entites like in Cart Module
2024-02-15 13:26:00 +00:00
Leonardo Cabeza
811a004c03 fix: typo in git checkout command (#6403)
typo in a git command
2024-02-15 08:34:09 +00:00
Adrien de Peretti
fafde4f54d feat(fulfillment): Module service implementation first iteration (#6381) 2024-02-14 18:43:42 +01:00
Philip Korsholm
02c53ec93f feat(medusa, types, core-flows): Add invite endpoints for api-v2 (#6395)
**What**
- Add invite endpoints for simple operations on invites
2024-02-14 15:33:26 +00:00
Oli Juhl
1ed5f918c3 feat(cart): POST /store/carts/:id (#6274)
Depends on:
- #6262 
- #6273
2024-02-14 15:03:02 +00:00
Adrien de Peretti
6500f18b9b chore(): Prevent from soft deleting all entities (#6396)
**What**
The internal service abstraction should return idempotently if an empty array is given in order to prevent full soft deletion of the full data
2024-02-14 14:29:10 +00:00
Philip Korsholm
4d51f095b3 feat(user, types): add invite and user properties + migration (#6327)
**What**
- Add invite model 
- Populate user model
2024-02-14 13:58:14 +00:00
Shahed Nasser
16927469eb docs: fixes to code snippets in Workflows documentation (#6393) 2024-02-14 13:25:35 +00:00
Oli Juhl
7ce15916ca feat(region): Create region with countries (#6372) 2024-02-14 12:48:43 +01:00
Carlos R. L. Rodrigues
0c2a460751 feat(medusa): workflow engine api (#6330)
What:

   Workflow Engine API.
   Endpoints for:
     - List workflow executions
     - Run a workflow
     - Set async steps as success or failure
     - Retrieve the details of a workflow run
2024-02-13 15:19:10 +00:00
Shahed Nasser
59ab66a773 docs-util: fix import issues following merge (#6390)
During the merge of #6338 the imports in the `git-manager.ts` causes an error during build which wasn't caught in the merge. This PR fixes the imports in the file.
2024-02-13 14:59:04 +00:00
Oli Juhl
ae79ff46f4 feat(region): Add store region get + list endpoints (#6342) 2024-02-13 15:29:29 +01:00
Shahed Nasser
d1f697c88e docs: new troubleshooting guide + cors fix (#6387)
- Fixed CORS middleware to account for routes of a single path (for example, `/custom` and not just `/custom/test`).
- Added a troubleshooting guide for admin webpack errors (see issue #6375)
2024-02-13 11:32:02 +00:00
Shahed Nasser
5ddae7ecd1 chore(docs): add empty changeset step to actions (#6377)
- Creates a script that runs the `yarn changeset --empty` command if there are file changes. This is important to not create PRs of just empty changesets if there are no file changes.
- Run script in all docs-generation PRs
- Fix to condition in `generate-docblock` action
2024-02-13 08:58:48 +00:00
Shahed Nasser
374a3f4dab docs-util: support generating OAS in docblock generator (#6338)
## What

This PR adds support for generating OAS in the docblock generator tool.

## How

As OAS are generated in a different manner/location than regular TSDocs, it requires a new type of generator within the tool. As such, the existing docblock generator now only handles files that aren't under the `packages/medusa/src/api` and `packages/medusa/src/api-v2` directories. The new generator handles files under these directories. However, it only considers a node to be an API route if it's a function having two parameters of types `MedusaRequest` and `MedusaResponse` respectively. So, only new API Routes are considered.

The new generator runs the same way as the existing docblock generator with the same method. The generators will detect whether they can run on the file or not and the docblocks/oas are generated based on that. I've also added a `--type` option to the CLI commands of the docblock generator tool to further filter and choose which generator to use.

When the OAS generator finds an API route, it will generate its OAS under the `docs-util/oas-output/operations` directory in a TypeScript file. I chose to generate in TS files rather than YAML files to maintain the functionality of `medusa-oas` without major changes.

Schemas detected in the OAS operation, such as the request and response schemas, are generated as OAS schemas under the `docs-util/oas-output/schemas` directory and referenced in operations and other resources.

The OAS generator also handles updating OAS. When you run the same command on a file/directory and an API route already has OAS associated with it, its information and associated schemas are updated instead of generating new schemas/operations. However, summaries and descriptions aren't updated unless they're not available or their values are the default value SUMMARY.

## API Route Handling

### Request and Response Types

The tool extracts the type of request/response schemas from the type arguments passed to the `MedusaRequest` and `MedusaResponse` respectively. For example:

```ts
export const POST = async (
  req: MedusaRequest<{
    id: string
  }>,
  res: MedusaResponse<ResponseType>
) => {
  // ...
}
```

If these types aren't provided, the request/response is considered empty.

### Path Parameters

Path parameters are extracted from the file's path name. For example, for `packages/medusa/src/api-v2/admin/campaigns/[id]/route.ts` the `id` path parameter is extracted.

### Query Parameters

The tool extracts the query parameters of an API route based on the type of `request.validatedQuery`. Once we narrow down how we're typing query parameters, we can revisit this implementation.

## Changes to Medusa Oas CLI

I added a `--v2` option to the Medusa OAS CLI to support loading OAS from `docs-util/oas-output` directory rather than the `medusa` package. This will output the OAS in `www/apps/api-reference/specs`, wiping out old OAS. This is only helpful for testing purposes to check how the new OAS looks like in the API reference. It also allows us to slowly start adapting the new OAS.

## Other Notes and Changes

- I've added a GitHub action that creates a PR for generated OAS when Version Packages is merged (similar to regular TSDocs). However, this will only generate the OAS in the `docs-util/oas-output` directory and will not affect the existing OAS in the API reference. Once we're ready to include it those OAS, we can talk about next steps.
- I've moved the base YAML from the `medusa` package to the `docs-util/oas-output/base` directory and changed the `medusa-oas` tool to load them from there.
- I added a `clean:oas` command to the docblock generator CLI tool that removes unused OAS operations, schemas, and tags from `docs-util/oas-output`. The tool also supports updating OAS operations and their associated schemas. However, I didn't add a specific mechanism to update schemas on their own as that's a bit tricky and would require the help of typedoc. I believe with the process of running the tool on the `api-v2` directory whenever there's a new release should be enough to update associated schemas, but if we find that not enough, we can revisit updating schemas individually.
- Because of the `clean:oas` command which makes changes to tags (removing the existing ones, more details on this one later), I've added new base YAML under `docs-util/oas-output/base-v2`. This is used by the tool when generating/cleaning OAS, and the Medusa OAS CLI when the `--v2` option is used.

## Testing

### Prerequisites

To test with request/response types, I recommend minimally modifying `packages/medusa/src/types/routing.ts` to allow type arguments of `MedusaRequest` and `MedusaResponse`:

```ts
import type { NextFunction, Request, Response } from "express"

import type { Customer, User } from "../models"
import type { MedusaContainer } from "./global"

export interface MedusaRequest<T = unknown> extends Request {
  user?: (User | Customer) & { customer_id?: string; userId?: string }
  scope: MedusaContainer
}

export type MedusaResponse<T = unknown> = Response

export type MedusaNextFunction = NextFunction

export type MedusaRequestHandler = (
  req: MedusaRequest,
  res: MedusaResponse,
  next: MedusaNextFunction
) => Promise<void> | void
```

You can then add type arguments to the routes in `packages/medusa/src/api-v2/admin/campaigns/[id]/route.ts`. For example:

```ts
import {
  deleteCampaignsWorkflow,
  updateCampaignsWorkflow,
} from "@medusajs/core-flows"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { CampaignDTO, IPromotionModuleService } from "@medusajs/types"
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"

interface ResponseType {
  campaign: CampaignDTO
}

export const GET = async (
  req: MedusaRequest,
  res: MedusaResponse<ResponseType>
) => {
  const promotionModuleService: IPromotionModuleService = req.scope.resolve(
    ModuleRegistrationName.PROMOTION
  )
  const campaign = await promotionModuleService.retrieveCampaign(
    req.params.id,
    {
      select: req.retrieveConfig.select,
      relations: req.retrieveConfig.relations,
    }
  )
  res.status(200).json({ campaign })
}

export const POST = async (
  req: MedusaRequest<{
    id: string
  }>,
  res: MedusaResponse<ResponseType>
) => {
  const updateCampaigns = updateCampaignsWorkflow(req.scope)
  const campaignsData = [
    {
      id: req.params.id,
      ...(req.validatedBody || {}),
    },
  ]
  const { result, errors } = await updateCampaigns.run({
    input: { campaignsData },
    throwOnError: false,
  })
  if (Array.isArray(errors) && errors[0]) {
    throw errors[0].error
  }
  res.status(200).json({ campaign: result[0] })
}

export const DELETE = async (
  req: MedusaRequest,
  res: MedusaResponse<{
    id: string
    object: string
    deleted: boolean
  }>
) => {
  const id = req.params.id
  const manager = req.scope.resolve("manager")
  const deleteCampaigns = deleteCampaignsWorkflow(req.scope)
  const { errors } = await deleteCampaigns.run({
    input: { ids: [id] },
    context: { manager },
    throwOnError: false,
  })
  if (Array.isArray(errors) && errors[0]) {
    throw errors[0].error
  }
  res.status(200).json({
    id,
    object: "campaign",
    deleted: true,
  })
}
```

### Generate OAS

- Install dependencies in the `docs-util` directory
- Run the following command in the `docs-util/packages/docblock-generator` directory:

```bash
yarn dev run "../../../packages/medusa/src/api-v2/admin/campaigns/[id]/route.ts"
```

This will generate the OAS operation and schemas and necessary and update the base YAML to include the new tags.

### Generate OAS with Examples

By default, the tool will only generate cURL examples for OAS operations. To generate templated JS Client and (placeholder) Medusa React examples, add the `--generate-examples` option to the command:

```bash
yarn dev run "../../../packages/medusa/src/api-v2/admin/campaigns/[id]/route.ts" --generate-examples
```

> Note: the command will update the existing OAS you generated in the previous test.

### Testing Updates

To test updating OAS, you can try updating request/response types, then running the command, and the associated OAS/schemas will be updated.

### Clean OAS

The `clean:oas` command will remove any unused operation, tags, or schemas. To test it out you can try:

- Remove an API Route => this removes its associated operation and schemas (if not referenced anywhere else).
- Remove all references to a schema => this removes the schema.
- Remove all operations in `docs-util/oas-output/operations` associated with a tag => this removes the tag from the base YAML.

```bash
yarn dev clean:oas
```

> Note: when running this command, existing tags in the base YAML (such as Products) will be removed since there are no operations using it. As it's running on the base YAML under `base-v2`, this doesn't affect base YAML used for the API reference.

### Medusa Oas CLI

- Install and build dependencies in the root of the monorepo
- Run the following command to generate reference OAS for v2 API Routes (must have generated OAS previously using the docblock generator tool):

```bash
yarn openapi:generate --v2
```

- This wipes out existing OAS in `www/apps/api-reference/specs` and replaces them with the new ones. At this point, you can view the new API routes in the API reference by running the `yarn dev` command in `www/apps/api-reference` (although not necessary for testing here).
- Run the command again without the `--v2` option:

```bash
yarn openapi:generate
```

The specs in `www/apps/api-reference/specs` are reverted back to the old routes.
2024-02-13 08:40:04 +00:00
Philip Korsholm
a86c87fe14 Feat(utils): psql unique index instead of constraint (#6386)
**What**
- always return an index expression, also for unique constraints

**why**
- constraints can't be partial, meaning `UNIQUE ... WHERE` is not possible with constraints
- constraints are indicies under the hood so it doesn't change the behavior of the system when we're not using constraint specific features but just using them for `UNIQUE`
2024-02-13 08:07:34 +00:00
Vinícius Gutierrez
aa9f66e16a fix(medusa-react): medusa provider needs a medusa client instance (#6363) 2024-02-12 22:29:45 +01:00
Frane Polić
a6a4b3f01a feat(payment): provider service (#6308) 2024-02-12 20:57:41 +01:00
github-actions[bot]
869dc751a0 chore(docs): Updated UI Reference (#6347)
* chore(docs): Generated UI Reference

* fixed props typing + added new alert page

* updated ui dependencies

---------

Co-authored-by: olivermrbl <olivermrbl@users.noreply.github.com>
Co-authored-by: Shahed Nasser <shahednasser@gmail.com>
2024-02-12 19:46:51 +01:00
Adrien de Peretti
e85463b2a7 chore(): Fix database test utils and utils (#6383)
**What**
Fix the test utils database to trully run the migrations, the migration path is deprecated and not used anymore as umzung infer the path under the hood. It also fix the schema so that it is possible to specify different schema if needed.

The index helper can now create named constraints for uniqueness. 

extracted [from](https://github.com/medusajs/medusa/pull/6381)
2024-02-12 18:07:15 +00:00
Shahed Nasser
1593e0b192 chore: small fixes to tsdocs (#6341)
Small fixes of the TSDocs for the upcoming release
2024-02-12 16:26:27 +00:00
Kasper Fabricius Kristensen
d37ff8024d feat(dashboard,medusa,ui): Manual gift cards + cleanup (#6380)
**Dashboard**
- Adds different views for managing manual/custom gift cards (not associated with a product gift card).
- Cleans up several table implementations to use new DataTable component.
- Minor cleanup of translation file.

**Medusa**
- Adds missing query params for list endpoints in the following admin domains: /customers, /customer-groups, /collections, and /gift-cards.

**UI**
- Adds new sizes for Badge component.

**Note for review**
Since this PR contains updates to the translation keys, it touches a lot of files. For the review the parts that are relevant are: the /gift-cards domain of admin, the table overview of collections, customers, and customer groups. And the changes to the list endpoints in the core.
2024-02-12 13:47:37 +00:00
Shahed Nasser
bc2a63782b docs: update next.js starter docs (#6378)
* docs: update next.js starter docs

* added empty changeset
2024-02-12 14:10:08 +01:00
Adrien de Peretti
1fd0457c15 feat(fulfillment): Init dtos work (#6329)
* feat(fulfillment): Init dtos work

* update DTO partially

* WIP

* more interfaces

* continue service definition

* cleanup

* cleanup

* preliminary filters

* cleanup

* cleanup

* Create angry-planets-wave.md
2024-02-12 11:28:31 +01:00
Nicklas Gellner
2afcf1c918 docs: clarification in text (#6361)
changed from payment to fulfillment provider in the text
2024-02-12 08:20:07 +00:00
Oli Juhl
95d0e58d31 feat(region): Add admin region get + list endpoints (#6322)
**What**
Add `GET /admin/regions`
Add `GET /admin/regions/:id`

Blocked by #6320 

Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
2024-02-11 17:13:49 +00:00
Adrien de Peretti
b91a1ca5b8 chore: cleanup inspection (#6358) 2024-02-09 14:40:09 +01:00
Oli Juhl
94062d28be feat: Add BigNumber implementation (#6253)
> This is a proposal - not necessarily the end result - to kick off the discussion about the implementation of the new totals utilities

### What
Introduces a BigNumber class implementation, enabling us to work with high-precision numeric values.

**Scope**
- Introduce the BigNumber class
- Remain somewhat backward-compatible (in behavior)
- Establish a foundation for handling high-precision values in more complex scenarios

**Not in scope**
- The implementation will not address complex use cases. However, the concept introduced now should be open for extensibility, so this can be added later without major changes to the calculation logic

### How
There are significant changes to three areas in this PR:
- Schemas
- (De)-Serialization
- Totals calculations

**Schemas**

Domains that need high-precision values will have two DB columns for each value in the database: a standard numeric column and a raw value column.

The standard column is for basic operations like sorting and filtering in the database and is what should be publicly exposed in our API.

The raw value is initially used solely for precise calculations and is stored as a JSONB column. Keeping it as JSONB is flexible and will allow us to extend the concept in future iterations. As of now, the raw value will only require a single property `value`.

**(De)-Serialization**

We cast the raw JSONB value to a `BigNumberRawValue` when reading from the database. 

We serialize the standard value to a `BigNumber` when reading from the database. 

We use the standard numeric value to construct the raw value upon writing to the database.

For example, the unit price and raw unit price on line items will be inserted as follows:
```ts
@BeforeCreate()
onCreate() {
  this.id = generateEntityId(this.id, "cali")
  
  const asBigNumber = new BigNumber(this.raw_unit_price ?? this.unit_price)
  
  this.unit_price = asBigNumber.numeric
  this.raw_unit_price = asBigNumber.raw
}
```

**Totals calculations**

For totals calculations, we will use the [`bignumber.js`](https://github.com/MikeMcl/bignumber.js/) library. The library ships with a `BigNumber` class with arithmetic methods for precise calculations. 

When we need to perform a calculation, we construct the BigNumber class from the library using the raw value from the database.

Let's have a look at an oversimplified example:
```ts
// create cart with line items
const [createdCart] = await service.create([
  {
    currency_code: "eur",
    items: [
      // li_1234
      {
        title: "test",
        quantity: 2,
        unit_price: 100,
      },
      // li_4321
      {
        title: "test",
        quantity: 3,
        // raw price creation
        unit_price: 200,
      },
    ],
  },
])
```

```ts
// calculating line item totals
import BN from "bignumber.js"

const lineItem1 = await service.retrieveLineItem("li_1234")
const lineItem2 = await service.retrieveLineItem("li_4321")

const bnUnitPrice1 = new BN(lineItem1.unit_price.raw)
const bnUnitPrice2 = new BN(lineItem2.unit_price.raw)

const line1Total = bnUnitPrice1.multipliedBy(lineItem1.quantity)
const line2Total = bnUnitPrice2.multipliedBy(lineItem2.quantity)

const total = line1Total.plus(line2Total)
```

**A note on backward compatibility**
Our BigNumber implementation is built to support the existing behavior of numeric values in the database. So even though we serialize the value to a BigNumber, you will still be able to treat it as a standard number, as we've always done.

For example, the following works perfectly fine:
```ts
const lineItem = await service.createLineItem({
  title: "test",
  quantity: 2,
  unit_price: 100,
})

console.log(lineItem.unit_price) // will print `100`
```

However, the type of `unit_price` will be `number | BigNumber`.
2024-02-09 10:56:50 +00:00
olivermrbl
dc88fd3507 chore: Release 2024-02-09 10:28:12 +01:00
github-actions[bot]
580143cd53 chore: Version Packages (#6348)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-09 10:25:33 +01:00
Kasper Fabricius Kristensen
85a44dfd01 fix(ui,ui-preset): Code component styles (#6357) 2024-02-09 10:11:22 +01:00
olivermrbl
20cefa0335 chore: Add missing changeset for medusa-js 2024-02-09 09:04:07 +01:00
github-actions[bot]
1d0a978ffe chore(docs): Generated References (#6351)
Generated the following references:
- `file`
- `fulfillment`
- `inventory`
- `js_client`
- `medusa`
- `medusa_config`
- `medusa_react`
- `modules`
- `notification`
- `payment`
- `price_selection`
- `pricing`
- `product`
- `services`
- `stock_location`
- `tax`
- `tax_calculation`
- `types`
- `workflows`

Co-authored-by: Shahed Nasser <27354907+shahednasser@users.noreply.github.com>
2024-02-08 21:18:10 +00:00
github-actions[bot]
e56c440911 chore(docs): Generated API Reference (#6346)
Co-authored-by: olivermrbl <olivermrbl@users.noreply.github.com>
2024-02-08 22:05:15 +01:00