feat(codegen): x-expanded-relations (#3442)

## What

Alter generated types base on `x-expanded-relations` OAS extension declared on schemaObjects.

## Why

Often, API endpoints will automatically expand a model relations by default. They can also decorate a model with calculated totals. In order to more accurately represent the API, we wish to alter the generated types based on the expanded relations information.

## How

- Follow the relation declaration signature as the backend controllers and the `expand` query param, i.e.: `items.variant.product`.
- Introduce a custom `x-expended-relations` OAS extension.
- Allow for organizing declared relations to help their maintenance.
- Use traversal algorithms in codegen to support deeply nested relationships.
- Use [type-fest](https://www.npmjs.com/package/type-fest)'s `Merge` and `SetRequired` to efficiently alter the types while enabling great intellisense for IDEs.

Extra scope: 
* Added convenience yarn script to interact with the `medisa-oas` CLI within the monorepo. 

## Test

Include in the PR are two implementations of the x-expanded-relations on OAS schema, a simple and a complex one.

### Step 1
* Run `yarn install`
* Run `yarn build`
* Run `yarn medusa-oas oas --type combined --out-dir ~/tmp/oas`
* Run `yarn medusa-oas client --type combined --component types --src-file ~/tmp/oas/combined.osa.json --out-dir ~/tmp/types`
* Open `~/tmp/types/models/StoreRegionsRes`
* Expect relations to be declared as required

### Step 2
* Open `~/tmp/types/models/StoreCartsRes`
* Expect relations to be declared as required
* Expect nested relations to have relations as required.

### Step 3 (optional)
* Open `~/tmp/types` in an intellisense capable IDE
* Within the `index.ts` file, attempt to declare a `const storeRegionRes: StoreRegionRes = {}`
* Expect IDE to highlight that `countries` is a required field of `StoreRegionRes`
This commit is contained in:
Patrick
2023-03-13 14:21:56 +00:00
committed by GitHub
parent c16f387d1c
commit 7b57695e00
17 changed files with 349 additions and 5 deletions
@@ -154,6 +154,52 @@ export const defaultStoreCartRelations = [
/**
* @schema StoreCartsRes
* type: object
* x-expanded-relations:
* field: cart
* relations:
* - billing_address
* - discounts
* - discounts.rule
* - gift_cards
* - items
* - items.adjustments
* - items.variant
* - payment
* - payment_sessions
* - region
* - region.countries
* - region.payment_providers
* - shipping_address
* - shipping_methods
* - shipping_methods.shipping_option
* implicit:
* - items.tax_lines
* - items.variant.product
* - region.fulfillment_providers
* - region.payment_providers
* - region.tax_rates
* - shipping_methods.shipping_option
* - shipping_methods.tax_lines
* totals:
* - discount_total
* - gift_card_tax_total
* - gift_card_total
* - item_tax_total
* - refundable_amount
* - refunded_total
* - shipping_tax_total
* - shipping_total
* - subtotal
* - tax_total
* - total
* - items.discount_total
* - items.gift_card_total
* - items.original_tax_total
* - items.original_total
* - items.refundable
* - items.subtotal
* - items.tax_total
* - items.total
* required:
* - cart
* properties:
@@ -16,6 +16,12 @@ export default (app) => {
/**
* @schema StoreRegionsListRes
* type: object
* x-expanded-relations:
* field: regions
* relations:
* - countries
* - payment_providers
* - fulfillment_providers
* required:
* - regions
* properties:
@@ -31,6 +37,12 @@ export type StoreRegionsListRes = {
/**
* @schema StoreRegionsRes
* type: object
* x-expanded-relations:
* field: region
* relations:
* - countries
* - payment_providers
* - fulfillment_providers
* required:
* - region
* properties: