feat(types): package scaffolding for generated types (#3452)

## What

Generated client types package based on the API's OpenApi Spec.

## Why

This package aims at replacing the need to import types directly from the core `@medusajs/medusa` package which can lead to side effects like importing backend dependencies into the client's realm.

## How

* The package contains a script that is invoked during the build step. 
* The script will use the `medusa-oas oas --type=combined` cli to generate a combined oas file. 
* Then, `medusa-oas client --component=types` uses the oas file to generate the types based on the OAS schema definitions. The result is outputted into `/src/lib`
* `prettier` is run on the `/src/lib` directory to ensure that the generated code follows the monorepo coding style.
* Finally, with `"emitDeclarationOnly": true`,  `tsc` compiles the src directory to only output types.

Until we update our CI pipeline, we will not commit the content `/src/lib`.

## Test

* Run `yarn install`
* Run `yarn build`
* Expect `packages/generated/client-types/dist/` to contain types generated from the OAS defined by `@medusajs/medusa`
This commit is contained in:
Patrick
2023-03-13 08:23:26 -04:00
committed by GitHub
parent 6d928628a9
commit 55febef7f1
10 changed files with 177 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
---
"@medusajs/client-types": patch
---
feat(types): package scaffolding for generated types

View File

@@ -4,6 +4,7 @@
"workspaces": {
"packages": [
"packages/*",
"packages/generated/*",
"packages/oas/*",
"integration-tests/**/*"
]

View File

@@ -0,0 +1,3 @@
node_modules
/dist
/src/lib

View File

@@ -0,0 +1,19 @@
# Medusa Client Types
TypeScript types derived from the OpenAPI Spec (OAS) to be used in API clients.
The source code is generated using the `medusa-oas` CLI tooling.
## Install
`yarn add --dev @medusa/client-types`
## How to use
Import in the client.
```typescript
import type { AdminCustomersRes } from "@medusajs/client-types"
import type { Customer } from "@medusajs/client-types"
import type { StoreGetProductCategoryParams } from "@medusajs/client-types"
```

View File

@@ -0,0 +1,35 @@
{
"name": "@medusajs/client-types",
"version": "0.1.0",
"description": "Client types for Medusa Commerce Rest API",
"main": "dist/index.js",
"files": [
"dist"
],
"scripts": {
"prepare": "cross-env NODE_ENV=production yarn run build",
"build": "yarn prebuild && tsc --build",
"prebuild": "ts-node ./scripts/build.ts && yarn prettier",
"prettier": "prettier --write --loglevel warn ./src/lib",
"test": "jest --passWithNoTests"
},
"author": "Medusa",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/medusajs/medusa",
"directory": "packages/generate/client-types"
},
"bugs": {
"url": "https://github.com/medusajs/medusa/issues"
},
"devDependencies": {
"@medusajs/medusa-oas-cli": "*",
"cross-env": "^7.0.3",
"execa": "^5.1.1",
"jest": "^27.4.7",
"prettier": "^2.7.1",
"ts-node": "^10.9.1",
"typescript": "^4.9.5"
}
}

View File

@@ -0,0 +1,59 @@
import execa from "execa"
import os from "os"
import fs from "fs/promises"
import path from "path"
const basePath = path.resolve(__dirname, `../`)
async function run() {
const tmpDirPath = await getTmpDirectory()
await generateOASSources(tmpDirPath)
const oasFilePath = path.resolve(tmpDirPath, `combined.oas.json`)
const outDirPath = path.resolve(basePath, "src/lib/")
await generateClientTypes(oasFilePath, outDirPath, true)
}
const generateOASSources = async (outDir: string) => {
const params = ["oas", `--out-dir=${outDir}`, "--type=combined"]
const { all: logs } = await execa("medusa-oas", params, {
cwd: basePath,
all: true,
})
console.log(logs)
}
const generateClientTypes = async (
srcFile: string,
outDir: string,
clean = false
) => {
const params = [
"client",
`--src-file=${srcFile}`,
`--out-dir=${outDir}`,
"--type=combined",
"--component=types",
]
if (clean) {
params.push("--clean")
}
const { all: logs } = await execa("medusa-oas", params, {
cwd: basePath,
all: true,
})
console.log(logs)
}
const getTmpDirectory = async () => {
/**
* RUNNER_TEMP: GitHub action, the path to a temporary directory on the runner.
*/
const tmpDir = process.env["RUNNER_TEMP"] ?? os.tmpdir()
return await fs.mkdtemp(tmpDir)
}
void (async () => {
await run()
})()

View File

@@ -0,0 +1,6 @@
{
"extends": "../tsconfig.json",
"include": [
"./**/*"
]
}

View File

@@ -0,0 +1 @@
export * from "./lib"

View File

@@ -0,0 +1,34 @@
{
"compilerOptions": {
"lib": [
"es2019"
],
"target": "es5",
"outDir": "./dist",
"esModuleInterop": true,
"declaration": true,
"module": "commonjs",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true,
"noImplicitReturns": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"allowJs": true,
"skipLibCheck": true,
"jsx": "react-jsx",
"emitDeclarationOnly": true
},
"include": [
"src"
],
"exclude": [
"node_modules",
"**/tests/*"
],
"ts-node": {
"transpileOnly": true
}
}

View File

@@ -5722,6 +5722,20 @@ __metadata:
languageName: unknown
linkType: soft
"@medusajs/client-types@workspace:packages/generated/client-types":
version: 0.0.0-use.local
resolution: "@medusajs/client-types@workspace:packages/generated/client-types"
dependencies:
"@medusajs/medusa-oas-cli": "*"
cross-env: ^7.0.3
execa: ^5.1.1
jest: ^27.4.7
prettier: ^2.7.1
ts-node: ^10.9.1
typescript: ^4.9.5
languageName: unknown
linkType: soft
"@medusajs/inventory@workspace:packages/inventory":
version: 0.0.0-use.local
resolution: "@medusajs/inventory@workspace:packages/inventory"