Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added rtkquery codegen package #99

Merged
merged 2 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 14 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,29 @@

The Sistent Design System from Layer5 provides the open source building blocks to design and implement consistent, accessible, and delightful product experiences.

### Packages

- Design System components in React.js
- npm package:

`@layer5/sistent-components`
`@layer5/sistent-svg`

### Brand
## Brand

- Layer5 Brand Guide ([PDF](https://layer5.io/brand/brand-guide.pdf))
- [Layer5 Logos](https://layer5.io/company/brand) (more assets available in shared Community drive).

## Packages

- Design System components in React.js

### How to get started

1. Install `yarn@1.22.19`
2. Use `yarn` to install dependencies

### NPM Packages
- `@layer5/sistent-components`
- `@layer5/sistent-svg`

### Redux Toolkit Query

- [Readme](packages/rtk-query-codegen/README.md)


<div>&nbsp;</div>

## Join the Layer5 community!
Expand Down
60 changes: 60 additions & 0 deletions packages/rtk-query-codegen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# OpenAPI API Client Generation and Compilation

Generate an API client from an OpenAPI schema in YAML format and create a rtk-query api client. The provided Bash script streamlines this process and ensures a smooth workflow.

## Dependencies

Before proceeding, ensure you have the following dependencies installed:

1. **Node.js and npm:** Ensure you have Node.js and npm installed on your system. You can download them from [nodejs.org](https://nodejs.org/).

2. **redocly CLI (required):** If you prefer to use `swagger-cli` for schema conversion, you can install it globally using npm:

```bash
npm i -g @redocly/cli@latest
```

3 **TypeScript:**

```bash
npm i -g typescript
```

## Usage

1. **Execute the Cli:**

- Run the script using the following command:

```bash
rtk-query-codegen -i /path/to/schema.yml -o /path/to/generated-api.js
```

The script will execute the following steps:

a. Convert the YAML schema (at `../../../models/openapi-schema/schema.yml`) to JSON schema at using `redocly` and save it as `openapi.json`.

b. Generate the API client code using `@rtk-query/codegen-openapi` based on the JSON schema.

c. Compile the TypeScript code to JavaScript using the TypeScript Compiler (`tsc`).

d. Move the generated `api.js` to the output and remove the `dist` folder.

2. **Verification:** After executing the script, check your project directory for the compiled `api.js` file. You can use this file as your API client in your project.

## The Api.js file

The api.js file contains the generated api endpoints , it injects them into the base rtk client . And then exports all the hooks to use them .
If we need to override an api endpoint we can injectEnpoints in a separate file .

## Troubleshooting

- If any of the steps fail, the script will exit with a non-zero status code, indicating a failure. Review the error messages to diagnose and resolve any issues.

- Ensure that the Bash script is executable by running `chmod +x generate-api.sh`.

## Important Notes

- Make sure the OpenAPI schema (`schema.yml`) is updated with latest changes and doesnt contain any breaking changes .

- Always validate and test the generated API client to ensure it functions as expected.
65 changes: 65 additions & 0 deletions packages/rtk-query-codegen/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const { program } = require('commander');
const { exec } = require('child_process');
const { renameSync, rmdirSync, unlinkSync } = require('fs');
const { dirname, basename, join } = require('path');

program
.option('-i, --input <input>', 'Input YAML schema file path')
.option('-o, --output <output>', 'Output path including the filename (e.g., /output/api.js)')
.parse(process.argv);

// Function to run a command and handle success or failure
function runCommand(command, successMessage, failureMessage) {
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
console.error(failureMessage);
console.error(stderr);
reject(error);
} else {
console.log(successMessage);
resolve();
}
});
});
}

async function generateAPI(inputFilePath, outputFilePath) {
try {
// Convert YAML schema to JSON schema
const yamlToJSONCommand = `redocly bundle ${inputFilePath} -o ./openapi.json --ext json`;
await runCommand(yamlToJSONCommand, 'JSON bundle generation successful', 'JSON bundle generation failed');

// Run OpenAPI generator
const openApiGeneratorCommand = 'npx @rtk-query/codegen-openapi openapi-config.ts';
await runCommand(openApiGeneratorCommand, 'OpenAPI generation successful', 'OpenAPI generation failed');

// Run TypeScript compilation
const tscCommand = 'tsc --build tsconfig.json';
await runCommand(tscCommand, 'TypeScript compilation successful', 'TypeScript compilation failed');

// Move api.js from the generated folder to the output path
console.log('Removing Build Artifacts');
const outputPath = dirname(outputFilePath);
const outputFilename = basename(outputFilePath);
renameSync('./dist/api.js', join(outputPath, outputFilename));
rmdirSync('./dist', { recursive: true });
unlinkSync('./openapi.json');
unlinkSync('./api.ts');

console.log('API generation successful');
process.exit(0);
} catch (error) {
console.error('API generation failed');
process.exit(1);
}
}

const { input, output } = program.opts();

if (!input || !output) {
console.error('Please provide both input and output options.');
process.exit(1);
}

generateAPI(input, output);
8 changes: 8 additions & 0 deletions packages/rtk-query-codegen/empty-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

// initialize an empty api service that we'll inject endpoints into later as needed
// the name should be same as the of the api in ../index.js
export const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: () => ({})
});
12 changes: 12 additions & 0 deletions packages/rtk-query-codegen/openapi-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ConfigFile } from '@rtk-query/codegen-openapi';
const config: ConfigFile = {
schemaFile: './openapi.json',
apiFile: './empty-api.ts',
apiImport: 'api',
exportName: 'api',
hooks: true,
tag: true,
outputFile: './api.ts'
};

export default config;