## What
Pluralize OAS tags
## Why
OAS tags are commonly used by code generator to group routes under a name space based on a tag.
Our JS client convention is to use plural, e.g: client.products, client.customers. In order to minimize friction when migrating to a client generated from OAS, tags should be plural as well.
## How
Match tag naming with JS client resource naming.
## Test
* Run `yarn build`
* Run `yarn openapi:generate`
* Run `yarn redocly preview-docs docs/api/admin/openapi.yaml --config=./docs-util/redocly/config.yaml`
* Expect side menu items to be plural.
* Run `yarn redocly preview-docs docs/api/store/openapi.yaml --config=./docs-util/redocly/config.yaml`
* Expect side menu items to be plural.
## What
Add missing x-codegen + fix schema naming and $ref
## Why
OAS code generator was missing information to be able to match current JS client.
## How
Ensure OAS matches JS client methods.
## What
Include `/admin` and `/store` in OAS paths URLs
## Why
Allow for generating a combined OAS that include routes for both "admin" and "store" endpoint.
Fix potential issues with code generator where routes are not prefixed with "admin" and "store" leading to 404 errors.
## Test
* Run `yarn build`
* Run `yarn openapi:generate`
* Run `yarn redocly preview-docs docs/api/admin/openapi.yaml --config=./docs-util/redocly/config.yaml`
* Expect paths to be prefixed with /admin.
* Run `yarn redocly preview-docs docs/api/store/openapi.yaml --config=./docs-util/redocly/config.yaml`
* Expect paths to be prefixed with /store.
## What
Include packages/ subdirectories in medusa-dev packages discovery.
## Why
We started to use subdirectories in the monorepo `packages/` directory in order to better organize packages.
Packages in subdirectories were invisible to `medusa-dev` and could not be copied.
## How
Rely on monorepo package.json workspace glob patterns to discover packages that can be published to the local npm registry.
## What
Allow `medusa-oas` CLI to generate API client code from an OAS json file.
## Why
Manually maintaining API clients is time consuming and error prone. We wish to automate the process by using code generation strategies.
We also wish to eliminate direct import from `@medusajs/medusa` in clients which can lead to unwanted side effects like importing unnecessary dependencies.
## How
Fork and customize an OAS code generator library that is TypeScript friendly.
Attempt to match the interface and signature of our current client packages: `@medusajs/medusa-js`, `medusa-react`
Add a new `client` command to the `medusa-oas` CLI as the main interface to interact with the code generation tooling.
## Test
### Prerequisites
* From the root of the monorepo:
* `yarn install`
* `yarn build`
### Case - all in one build
* From the root of the monorepo:
* Run `yarn medusa-oas oas --out-dir ~/tmp/oas --type store`
* Run `yarn medusa-oas client --src-file ~/tmp/oas/store.oas.json --out-dir ~/tmp/client-store --type store`
* Expect `~/tmp/client-store` to contain the following files and directories:
```
core/
hooks/
models/
services/
index.ts
MedusaStore.ts
useMedusaStore.tsx
```
### Case - types only
* From the root of the monorepo:
* Run `yarn medusa-oas oas --out-dir ~/tmp/oas --type store`
* Run `yarn medusa-oas client --src-file ~/tmp/oas/store.oas.json --out-dir ~/tmp/client-types --type store --component types`
* Expect `~/tmp/client-types` to contain the following files and directories:
```
models/
index.ts
```
### Case - client only
* From the root of the monorepo:
* Run `yarn medusa-oas oas --out-dir ~/tmp/oas --type store`
* Run `yarn medusa-oas client --src-file ~/tmp/oas/store.oas.json --out-dir ~/tmp/client-only --type store --component client --types-package @medusajs/client-types`
* Expect `~/tmp/client-only` to contain the following files and directories:
```
core/
services/
index.ts
MedusaStore.ts
```
## Scope
Store routes
## What
Add OAS `required` to response schemas.
## Why
Code generator can use the `required` property of a schema to mark fields as optional or not when generating TS types.
## Test
* Run `yarn build`
* Run `yarn openapi:generate`
* Run `yarn redocly preview-docs docs/api/store/openapi.yaml --config=docs-util/redocly/config.yaml`
* Open the documentation preview URL in a browser (http://127.0.0.1:8080)
* Expect responses to have their fields declared as `required`
## Scope
Admin routes
## What
Add OAS `required` to response schemas.
## Why
Code generator can use the `required` property of a schema to mark fields as optional or not when generating TS types.
## Test
* Run `yarn build`
* Run `yarn openapi:generate`
* Run `yarn redocly preview-docs docs/api/admin/openapi.yaml --config=docs-util/redocly/config.yaml`
* Open the documentation preview URL in a browser (http://127.0.0.1:8080)
* Expect responses to have their fields declared as `required`
## What
Patch OAS circular references that causes the documentation to crash
## Test
* Run `yarn openapi:generate`
* Run `yarn redocly preview-docs docs/api/admin/openapi.yaml --config=./docs-util/redocly/config.yaml`
* Open preview docs url in a browser
* Expect the page to not crash
* Repeat with `yarn redocly preview-docs docs/api/store/openapi.yaml --config=./docs-util/redocly/config.yaml`
### What
Unhandled OAS circular references shall fail `openapi:generate` until they have been patched in `docs-util/redocly/config.yaml`
### Why
Prevent developers to commit new OAS changes that would cause to API documentation to crash.
Our API documentation rendering library will crash and not load if our OAS contains circular references. We have an automated mechanism to patch offending references but they must be identified and configured by hand.
### How
Let the `openapi:generate --dry-run` command reach OAS sanitization and circular reference check operations.
Fail the build script if unhandled circular references are detected.
Output the offending references to the stdout in order to help the developers identify and configure the required patch.
Since some the tooling involved only work with files, use the host system's temporary directory mechanism when using the `--dry-run` flag.
### Test
* Introduce a bug by removing an entry in `docs-util/redocly/config.yaml`
* Run `yarn openapi:generate --dry-run`
* Expect the script to exit before completing
* Expect the logs to contain `🔴 Unhandled circular references.`
* Expect the logs to contain an array of the offending references
## What
Introduce a CLI for extracting OAS from the core `medusa` package.
## Why
We need to decouple OAS tooling from documentation tooling in order to allow packages and external systems to leverage our OAS has a dependency.
## How
Introduce a new OAS workspace within packages in order to organize current and future OAS related package. Only 1 OAS package for now.
Introduce a new CLI only package to act as the main gateway for all upcoming OAS tooling. Only 1 command for now.
Update documentation tooling pertaining to OAS to use the CLI instead.
## Test
### Prerequisite
From the monorepo root:
* `yarn install`
* `yarn build`
### Documentation
#### Case - validation only - success
* Run `yarn openapi:generate --dry-run`
* Expect console output `🟢 Valid OAS` but no mention of `🔵 Exported OAS`
#### Case - validation only - invalid
* Introduce a bug by renaming `@schema Cart` to `@schema Kart` in [models/cart.ts](https://github.com/medusajs/medusa/blob/0adb0d9ff96087613b7a634cbc97a7e301b01121/packages/medusa/src/models/cart.ts#L2)
* Run `yarn build` to update `@medusajs/medusa` package with the bug.
* Run `yarn openapi:generate --dry-run`
* Expect console output `🔴 Invalid OAS` with a stack trace of the issue.
#### Case - docs generation
* Run `yarn openapi:generate`
* Expect `docs/api/` directory to contain:
* `admin.oas.json` (raw OAS)
* `store.oas.json` (raw OAS)
* `admin.oas.yaml` (sanitized OAS)
* `store.oas.yaml` (sanitized OAS)
* `admin/` (updated redocly split output)
* `store/` (updated redocly split output)
### CLI
#### Case - crawl additional paths
* From a local medusa server (`medusa-starter-default`), add an `index.ts` file in `src/models/`
* In the `index.ts`, add dummy OAS JSDoc like `/** @schema Foobar */`
* From the root of the monorepo, run `yarn medusa-oas --type store --paths path-to-medusa-server/src`
* Expect a `store.oas.json` to be created at the root of the monorepo.
* The `store.oas.json` should contain an additional `Foobar` entry in `components.schemas`.
### Scope
Models R to U
### What
Refactor OAS for models to accurately represent their shape in API responses.
### Why
About 33% of model fields are not accurately represented in the OAS. Most of the issues are:
- fields that can not be omitted in the response are not declared as `required`
- fields that could return `null` as their value are not declared as `nullable: true`
When using a code generator, these OAS issues would lead to inaccurate response shapes in the generated client.
### How
#### nullable
Fields meeting at least one of the following condition will be represented as `nullable: true` in OAS:
* The field is decorated with `@Column({ nullable: true })`
* The field is decorated with `@OneToOne`, `@ManyToOne`
* The field is decorated with `@DeleteDateColumn`
#### optional
Fields meeting at least one of the following conditions will never be listed as `required` in OAS and will be considered optional and could be omitted in the response:
* The field is decorated with `@OneToOne`, `@ManyToOne`, `@OneToMany`, `@ManyToMany`
* The field is decorated with `@FeatureFlagColumn`
* The field is decorated with `@Column({select: false})`
* The field is representing dynamic values not persisted in the database
Fields not meeting any of the conditions above will be declared as `required` and are expected to be present in the response.
### Test
* Ran OAS validator.
* Ran docs build script.
Expect OAS changes to be reflected in the API documentation.
### Scope
Models PA to PU
### What
Refactor OAS for models to accurately represent their shape in API responses.
### Why
About 33% of model fields are not accurately represented in the OAS. Most of the issues are:
- fields that can not be omitted in the response are not declared as `required`
- fields that could return `null` as their value are not declared as `nullable: true`
When using a code generator, these OAS issues would lead to inaccurate response shapes in the generated client.
### How
#### nullable
Fields meeting at least one of the following condition will be represented as `nullable: true` in OAS:
* The field is decorated with `@Column({ nullable: true })`
* The field is decorated with `@OneToOne`, `@ManyToOne`
* The field is decorated with `@DeleteDateColumn`
#### optional
Fields meeting at least one of the following conditions will never be listed as `required` in OAS and will be considered optional and could be omitted in the response:
* The field is decorated with `@OneToOne`, `@ManyToOne`, `@OneToMany`, `@ManyToMany`
* The field is decorated with `@FeatureFlagColumn`
* The field is decorated with `@Column({select: false})`
* The field is representing dynamic values not persisted in the database
Fields not meeting any of the conditions above will be declared as `required` and are expected to be present in the response.
### Test
* Ran OAS validator.
* Ran docs build script.
Expect OAS changes to be reflected in the API documentation.
### Scope
Models F to O
### What
Refactor OAS for models to accurately represent their shape in API responses.
### Why
About 33% of model fields are not accurately represented in the OAS. Most of the issues are:
- fields that can not be omitted in the response are not declared as `required`
- fields that could return `null` as their value are not declared as `nullable: true`
When using a code generator, these OAS issues would lead to inaccurate response shapes in the generated client.
### How
#### nullable
Fields meeting at least one of the following condition will be represented as `nullable: true` in OAS:
* The field is decorated with `@Column({ nullable: true })`
* The field is decorated with `@OneToOne`, `@ManyToOne`
* The field is decorated with `@DeleteDateColumn`
#### optional
Fields meeting at least one of the following conditions will never be listed as `required` in OAS and will be considered optional and could be omitted in the response:
* The field is decorated with `@OneToOne`, `@ManyToOne`, `@OneToMany`, `@ManyToMany`
* The field is decorated with `@FeatureFlagColumn`
* The field is decorated with `@Column({select: false})`
* The field is representing dynamic values not persisted in the database
Fields not meeting any of the conditions above will be declared as `required` and are expected to be present in the response.
### Test
* Ran OAS validator.
* Ran docs build script.
Expect OAS changes to be reflected in the API documentation.
### Scope
Models A to D
### What
Refactor OAS for models to accurately represent their shape in API responses.
### Why
About 33% of model fields are not accurately represented in the OAS. Most of the issues are:
- fields that can not be omitted in the response are not declared as `required`
- fields that could return `null` as their value are not declared as `nullable: true`
When using a code generator, these OAS issues would lead to inaccurate response shapes in the generated client.
### How
#### nullable
Fields meeting at least one of the following condition will be represented as `nullable: true` in OAS:
* The field is decorated with `@Column({ nullable: true })`
* The field is decorated with `@OneToOne`, `@ManyToOne`
* The field is decorated with `@DeleteDateColumn`
#### optional
Fields meeting at least one of the following conditions will never be listed as `required` in OAS and will be considered optional and could be omitted in the response:
* The field is decorated with `@OneToOne`, `@ManyToOne`, `@OneToMany`, `@ManyToMany`
* The field is decorated with `@FeatureFlagColumn`
* The field is decorated with `@Column({select: false})`
* The field is representing dynamic values not persisted in the database
Fields not meeting any of the conditions above will be declared as `required` and are expected to be present in the response.
### Test
* Ran OAS validator.
* Ran docs build script.
Expect OAS changes to be reflected in the API documentation.
### What
Add OAS build step to patch known circular references that prevent Redocly from rendering the API documentation.
### Why
We've encountered crashing and loading issues with Redocly when the OAS contained circular references. We have been working around the limitation by omitting some known problematic $ref in our source OAS. We wish to move away from this strategy in order to always explicitly include $ref in our OAS.
### How
We are introducing a custom Redocly CLI plugin that will replace `$ref` by `type: object` base on a configurable set of instructions. These instructions can be modified in `docs-util/redocly/config.yaml`
We are adding a `redocly bundle` step in the current OAS build process in order to sanitize problematic circular references.
We updated the redocly-cli package version in order to ensure that plugins are supported.
### Test
We will use [Cart.payment](https://github.com/medusajs/medusa/blob/fd5c18515931aca7cb5d29530f5dd03ebaf7e07e/packages/medusa/src/models/cart.ts#L72-L74) to ensure that the new process is properly sanitizing.
* Run `yarn openapi:generate`
* Open `docs/api/store/components/schemas/Cart.yaml`
* Expect the `payment` property to have been sanitized to `type: object`
* Run `yarn redocly preview-docs docs/api/store/openapi.yaml --config=docs-util/redocly/config.yaml`
* Visit http://127.0.0.1:8080/#tag/Cart/operation/GetCartsCart
* In the response, expect cart.payment to not list the properties of the Payment schema.
### What
Declare `x-codegen` in OAS for Admin routes - S to V.
### Why
We are introducing a new `x-codegen` OpenApi extension, also known as _vendor extension_, in order to help with passing information down to code generators.
In our case, we wish to declare the `method` name that we would expect to call on a client. This mimics our current JS client package.
E.g. `medusaClient.product.list` where `product` is the tag of the route and `list` is the x-codegen.method value.
We are also defining the name of a potential typed object for query parameters. OAS 3.0 does not allow to bundle query parameters under a single definition but it is not uncommon to see API clients handle all query parameters as a single typed object, like our JS client package. With x-codegen.queryParams, a code generator can create a named and typed object to bundle all query parameters for a given route.
E.g. `medusaClient.customer.retrieve(id: string, queryParams: AdminGetCustomerParams)`
### How
Declare `x-codegen` as an object with fields `method` and `queryParams` on all paths.
Match method and queryParams values with equivalent ones from our current JS client package.
### Test
* Ran OAS validator.
* Ran docs build script.
Expect no visible changes to the documentation.
### What
Declare `x-codegen` in OAS for Admin routes - S to V.
### Why
We are introducing a new `x-codegen` OpenApi extension, also known as _vendor extension_, in order to help with passing information down to code generators.
In our case, we wish to declare the `method` name that we would expect to call on a client. This mimics our current JS client package.
E.g. `medusaClient.product.list` where `product` is the tag of the route and `list` is the x-codegen.method value.
We are also defining the name of a potential typed object for query parameters. OAS 3.0 does not allow to bundle query parameters under a single definition but it is not uncommon to see API clients handle all query parameters as a single typed object, like our JS client package. With x-codegen.queryParams, a code generator can create a named and typed object to bundle all query parameters for a given route.
E.g. `medusaClient.customer.retrieve(id: string, queryParams: AdminGetCustomerParams)`
### How
Declare `x-codegen` as an object with fields `method` and `queryParams` on all paths.
Match method and queryParams values with equivalent ones from our current JS client package.
### Test
* Ran OAS validator.
* Ran docs build script.
Expect no visible changes to the documentation.
### What
Declare `x-codegen` in OAS for Admin routes - PRO to R.
### Why
We are introducing a new `x-codegen` OpenApi extension, also known as _vendor extension_, in order to help with passing information down to code generators.
In our case, we wish to declare the `method` name that we would expect to call on a client. This mimics our current JS client package.
E.g. `medusaClient.product.list` where `product` is the tag of the route and `list` is the x-codegen.method value.
We are also defining the name of a potential typed object for query parameters. OAS 3.0 does not allow to bundle query parameters under a single definition but it is not uncommon to see API clients handle all query parameters as a single typed object, like our JS client package. With x-codegen.queryParams, a code generator can create a named and typed object to bundle all query parameters for a given route.
E.g. `medusaClient.customer.retrieve(id: string, queryParams: AdminGetCustomerParams)`
### How
Declare `x-codegen` as an object with fields `method` and `queryParams` on all paths.
Match method and queryParams values with equivalent ones from our current JS client package.
### Test
* Ran OAS validator.
* Ran docs build script.
Expect no visible changes to the documentation.
### What
Declare `x-codegen` in OAS for Admin routes - D to PRI.
### Why
We are introducing a new `x-codegen` OpenApi extension, also known as _vendor extension_, in order to help with passing information down to code generators.
In our case, we wish to declare the `method` name that we would expect to call on a client. This mimics our current JS client package.
E.g. `medusaClient.product.list` where `product` is the tag of the route and `list` is the x-codegen.method value.
We are also defining the name of a potential typed object for query parameters. OAS 3.0 does not allow to bundle query parameters under a single definition but it is not uncommon to see API clients handle all query parameters as a single typed object, like our JS client package. With x-codegen.queryParams, a code generator can create a named and typed object to bundle all query parameters for a given route.
E.g. `medusaClient.customer.retrieve(id: string, queryParams: AdminGetCustomerParams)`
### How
Declare `x-codegen` as an object with fields `method` and `queryParams` on all paths.
Match method and queryParams values with equivalent ones from our current JS client package.
### Test
* Ran OAS validator.
* Ran docs build script.
Expect no visible changes to the documentation.
### What
Declare `x-codegen` in OAS for Admin routes - A to D.
### Why
We are introducing a new `x-codegen` OpenApi extension, also known as _vendor extension_, in order to help with passing information down to code generators.
In our case, we wish to declare the `method` name that we would expect to call on a client. This mimics our current JS client package.
E.g. `medusaClient.product.list` where `product` is the tag of the route and `list` is the x-codegen.method value.
We are also defining the name of a potential typed object for query parameters. OAS 3.0 does not allow to bundle query parameters under a single definition but it is not uncommon to see API clients handle all query parameters as a single typed object, like our JS client package. With x-codegen.queryParams, a code generator can create a named and typed object to bundle all query parameters for a given route.
E.g. `medusaClient.customer.retrieve(id: string, queryParams: AdminGetCustomerParams)`
### How
Declare `x-codegen` as an object with fields `method` and `queryParams` on all paths.
Match method and queryParams values with equivalent ones from our current JS client package.
### Test
* Ran OAS validator.
* Ran docs build script.
Expect no visible changes to the documentation.
### What
Declare `x-codegen` in OAS for Store routes.
### Why
We are introducing a new `x-codegen` OpenApi extension, also known as _vendor extension_, in order to help with passing information down to code generators.
In our case, we wish to declare the `method` name that we would expect to call on a client. This mimics our current JS client package.
E.g. `medusaClient.product.list` where `product` is the tag of the route and `list` is the x-codegen.method value.
We are also defining the name of a potential typed object for query parameters. OAS 3.0 does not allow to bundle query parameters under a single definition but it is not uncommon to see API clients handle all query parameters as a single typed object, like our JS client package. With x-codegen.queryParams, a code generator can create a named and typed object to bundle all query parameters for a given route.
E.g. `medusaClient.customer.retrieve(id: string, queryParams: AdminGetCustomerParams)`
### How
Declare `x-codegen` as an object with fields `method` and `queryParams` on all paths.
Match method and queryParams values with equivalent ones from our current JS client package.
### Test
* Ran OAS validator.
* Ran docs build script.
Expect no visible changes to the documentation.
### Scope
Store routes directories PRO to V.
### What
Move inline OAS response schema declaration under their respective class declarations in order to expose them through `#/components/schemas`. Replace inline OAS response schema with a `$ref` reference pointing to the newly declared schema.
### Why
Having response declared as its own "named" schema will allow OAS code generators to output typed entities/DTO that can be consumed without having to reference the route/operation.
### How
Declare a new @schema JSDoc for each "Res" class used to parse and validate request body. Move the current inline requestBody to the new @schema.
### Test
- Ran OAS validator.
- Ran docs build script.
Expect no visible changes to the documentation.
### Scope
Admin routes directories PRO to SAL.
### What
Move inline OAS response schema declaration under their respective class declarations in order to expose them through `#/components/schemas`. Replace inline OAS response schema with a `$ref` reference pointing to the newly declared schema.
### Why
Having response declared as its own "named" schema will allow OAS code generators to output typed entities/DTO that can be consumed without having to reference the route/operation.
### How
Declare a new @schema JSDoc for each "Res" class used to parse and validate request body. Move the current inline requestBody to the new @schema.
### Test
- Ran OAS validator.
- Ran docs build script.
Expect no visible changes to the documentation.
Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
### Scope
Admin routes directories SHI to V.
### What
Move inline OAS response schema declaration under their respective class declarations in order to expose them through `#/components/schemas`. Replace inline OAS response schema with a `$ref` reference pointing to the newly declared schema.
### Why
Having response declared as its own "named" schema will allow OAS code generators to output typed entities/DTO that can be consumed without having to reference the route/operation.
### How
Declare a new @schema JSDoc for each "Res" class used to parse and validate request body. Move the current inline requestBody to the new @schema.
### Test
- Ran OAS validator.
- Ran docs build script.
Expect no visible changes to the documentation.
Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
### Scope
Admin routes directories D to N.
### What
Move inline OAS response schema declaration under their respective class declarations in order to expose them through `#/components/schemas`. Replace inline OAS response schema with a `$ref` reference pointing to the newly declared schema.
### Why
Having response declared as its own "named" schema will allow OAS code generators to output typed entities/DTO that can be consumed without having to reference the route/operation.
### How
Declare a new @schema JSDoc for each "Res" class used to parse and validate request body. Move the current inline requestBody to the new @schema.
### Test
- Ran OAS validator.
- Ran docs build script.
Expect no visible changes to the documentation.
### Scope
Admin routes directories O to PRI.
### What
Move inline OAS response schema declaration under their respective class declarations in order to expose them through `#/components/schemas`. Replace inline OAS response schema with a `$ref` reference pointing to the newly declared schema.
### Why
Having response declared as its own "named" schema will allow OAS code generators to output typed entities/DTO that can be consumed without having to reference the route/operation.
### How
Declare a new @schema JSDoc for each "Res" class used to parse and validate request body. Move the current inline requestBody to the new @schema.
### Test
- Ran OAS validator.
- Ran docs build script.
Expect no visible changes to the documentation.
### What
Move inline OAS requestBody schema declaration under their respective class-validator classes in order to expose them through `#/components/schemas`. Replace inline OAS requestBody schema with a `$ref` reference pointing to the newly declared schema.
### Why
Having requestBody declared as its own "named" schema will allow OAS code generators to output typed entities/DTO that can be manipulate without having to reference the route/operation.
### How
Declare a new @schema JSDoc for each class-validator used to parse and validate request body. Move the current inline requestBody to the new @schema.
### Test
- Ran OAS validator.
- Ran docs build script.
Expect no visible changes to the documentation.
### Out-of-scope
requestBody of type `multipart/form-data` used for file uploads. These will be address as part of CORE-934
- [create-upload.ts](https://github.com/medusajs/medusa/blob/58d23a7b45b6dde8bdeed0bb268139a0017f1649/packages/medusa/src/api/routes/admin/uploads/create-upload.ts#L87-L90)
- [create-protected-upload.ts](https://github.com/medusajs/medusa/blob/58d23a7b45b6dde8bdeed0bb268139a0017f1649/packages/medusa/src/api/routes/admin/uploads/create-protected-upload.ts#L87-L90)
Path Parameter and Query Parameter. These will need more research and experimentation, part of CORE-931
---
Resolves CORE-853
### What
Rename all JSDoc OAS `@schema` and `$ref: #/components/schemas/` from snake_case to PascalCase, `foo_bar -> FooBar`
Extra scope: Remove `x-resourceId` from JSDoc OAS.
### Why
Classes use PascalCase as a convention but the OAS @schemas describing them were using snake_case. OAS code generators tend to use the schema name when generating typed models.
In order to avoid mismatch between source code, the OAS, and the generated client code, it is advised to align OAS @schemas formatting to the classes they represent.
Extra scope: x-resourceId is not a widely used OAS property. It's current usage in our OAS does not provide additional value. Therefore, we recommend to remove it in order to have one less item to maintain.
### How
Good old search & replace. Regex search to further make sure we didn't miss any.
The scope is limited to `@schema` definition and their usage in `$ref: #/components/schemas/`.
### Test
* Ran OAS validator.
* Ran docs build script.
Expect no visible changes to the documentation.
Resolves: CORE-852, CORE-859
### What
Explicitly declare `@medusajs/medusa` as a devDependency for `@medusajs/medusa-js` client package.
### Why
With our latest version upgrade of `turbo`, peerDependencies aren't taken into account in the build graph. The recommendation is to also explicitly declare them in devDependencies.
### Test
* Run `yarn build --graph`
* Expect to see medusa-js having a dependency on medusa
```
"[root] @medusajs/medusa-js#build" -> "[root] @medusajs/medusa#build"
```
### What
Explicitly declare `@medusajs/medusa` as a devDependency for `@medusajs/medusa-js` client package.
### Why
With our latest version upgrade of `turbo`, peerDependencies aren't taken into account in the build graph. The recommendation is to also explicitly declare them in devDependencies.
### Test
* Run `yarn build --graph`
* Expect to see medusa-js having a dependency on medusa
```
"[root] @medusajs/medusa-js#build" -> "[root] @medusajs/medusa#build"
```
### What
Flip Turborepo cache glob pattern from an allow-list to deny-list pattern.
### Why
Packages within medusa's monorepo will output their build to a `dist` directory.
This convention does not apply to plugins since the core plugin loader expects the content of plugin packages `src` directory to be outputted at the root of the package.
i.e. `packages/foobar-plugin/src/utils/index.ts` -> `packages/foobar-plugin/utils/index.js`
Manually maintaining an allow-list of known plugin output directories is not scalable. When a directory exists in a plugin package but is not know to the allow-list, the directory will not be re-built on subsequent builds. Troubleshooting the issue requires intimate knowledge of Turborepo caching strategies.
### How
By using a deny-list glob pattern, plugin packages can now declare any not-known directory within their `src` folder without facing any potential omission issues during the build process.
We declare `src` and its content as the only directory for turbo cache to ignore.
### Additional scope
* Use `turbo.json` file content in cache hashing algorithm in order to break CI cache when changes are made to the Turborepo config.
* Upgraded turbo minor verion.
* Added missing dependency to medusa package.
### Test
* Delete previously built output in packages. Run `yarn build --force` (replace any existing cache)
* Expect all src content to be outputted
* Run `yarn build` right after
* Expect a fast build time since cache will be fresh
* Add a new directory with an index.ts file in a plugin package src folder. Run `yarn build`
* Expect a fast build time, except for the modified plugin package.
* Expect the newly added directory to be outputted.
* Delete the newly outputted directory. Run `yarn build`
* Expect the outputted directory to reappear.
### References
* https://github.com/medusajs/medusa/blob/5093b82f3a28323e99b6b133ae87c76fac01a298/packages/medusa/src/loaders/plugins.ts
* https://turbo.build/repo/docs/reference/configuration#outputs
* https://turbo.build/repo/docs/reference/configuration#globaldependencies
Resolves CORE-891
### What
Leverage yarn workspaces and Turborepo for integration-tests in order to accelerate development and reduce DevX complexity.
### Why
The current solution for running integration tests requires using `medusa-dev-cli` in order to publish packages to a local npm repository. The package where the command is executed will have its package.json altered for any known medusa dependency in order to install from the local npm. The process is taxing on the host machine resources and prevents rapid iterations when working with integration tests.
For more information, see documentation: https://github.com/medusajs/medusa/blob/f0cc1b324c964680c26e0d5c1d45769cbd750176/docs/content/usage/local-development.md#run-api-integration-tests
### How
By declaring `integeration-tests/**/*` as a workspace, Turborepo can now be leveraged to build and run integration test as if there were packages. The build process will take care of interdependency between package in order to ensure local dependency are met.
In addition, within each integration-tests "packages", we can declare local dependencies as "*" which will translate to using the one that is part of the current build, regardless of the dependency's version number. No more fiddling with version numbers.
Github actions pertaining to integration-tests have been streamlined to use the new behavior.
The integration-tests packages have been marked as `private:true` in order to avoid publishing them to the public npm registry.
### Testing
```
cd root-of-medusajs-medusa-repo/
yarn install
yarn build
yarn test:integration:api
yarn test:integration:plugins
```
After a code change, `yarn build` must be run before re-running an integration test, which is the same procedure as for unit tests.
Resolves: CORE-845
### What
OAS: Explicitly declare type:object on schemas with properties.
### Why
While not officially required, schemas with properties should have their type explicitly declared as "object". Omitting the type translates to type: any with properties XYZ. The ambiguity can lead to issues when using code generators.
### How
Multiple regex searches to identify schemas missing type: object. Manually edit each schema. Spot check generated OAS.
### Testing
- Ran OAS validator.
- Ran docs build script
### Proof

RESOLVES CORE-847
**What**
Fix system error (500) with DraftOrder create operation when payload includes discount in a tax-inclusive context.
**How**
* Ensure newly created cart contains all required relation in order to calculate line item tax-inclusive pricing with discounts.
* Add resilience to TotalsService.getLineDiscounts()
* Ensure newly generate line items have variant relation loaded.
* fix TotalsService.getLineItemTotals to use the passed lineItem instead of relying on cartOrOrder.items.
**Test**
* Unit:
* TotalsService.getLineDiscounts - coverage
* Integration:
* Admin API draft-order - coverage
* Admin API draft-order create w/ discount in tax-inclusive
Resolves: CORE-771
Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>