Skip to content

Feature/codegen script #78

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,75 @@ npx @rtk-incubator/rtk-query-codegen-openapi --file generated.api.ts --baseQuery
- `--hooks` - include React Hooks in the output (ex: `export const { useGetModelQuery, useUpdateModelMutation } = api`)
- `--file <filename>` - specify a filename to output to (ex: `./generated.api.ts`)

<br/>

### Script Usage

---

Step 1: Create codegen config script

```js
// rtk-codgen.config.js
const { generateEndpoints } = require('@rtk-incubator/rtk-query-codegen-openapi');

// Comes from .env.local config - accepts urls or relative paths
// ex. https://your.custom.domain/api/v1/swagger.json
const {
parsed: { OPENAPI_DOCS },
} = require('dotenv').config({ path: './.env.local' });

const simpleUsageExample = generateEndpoints({
apiFile: 'api.ts',
schemaFile: 'openapi.json',
outputFile: 'enhancedApi.ts',
});

const multiOutputConfig = {
apiFile: 'api.ts',
schemaFile: 'openapi.json',
hooks: true,
outputFiles: {
'posts.ts': {
filterEndpoints: /post/i,
},
'users.ts': {
filterEndpoints: /user/i,
endpointOverrides: [{ pattern: 'filterUsers', type: 'query' }],
},
},
};

generateEndpoints({
schemaFile: OPENAPI_DOCS,
outputFile: './src/app/api.generated.ts',
hooks: true,
baseQuery: './src/app/apiBaseQuery.ts:apiBaseQuery',
});
```

Step 2: Add package.json script

```json
"scripts": {
"rtk-codegen": "node rtk-codegen.config.js"
}
```

Step 3: Run script to update api as needed

with npm:

```bash
npm run rtk-codegen
```

or with yarn:

```bash
yarn rtk-codegen
```

### Documentation

[View the RTK Query Code Generation docs](https://redux-toolkit.js.org/rtk-query/usage/code-generation)
37 changes: 37 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env node

import * as path from 'path';
import * as fs from 'fs';
import { generateApi } from './generate';
import { isValidUrl, MESSAGES, prettify } from './utils';
import type { CommonOptions, OutputFileOptions } from './types';
import { getCompilerOptions } from './utils/getTsConfig';

export async function generateEndpoints({
schemaFile,
outputFile,
tsConfigFilePath,
...options
}: CommonOptions & OutputFileOptions) {
try {
const schemaAbsPath = isValidUrl(schemaFile) ? schemaFile : path.resolve(process.cwd(), schemaFile);
if (tsConfigFilePath) {
tsConfigFilePath = path.resolve(tsConfigFilePath);
if (!fs.existsSync(tsConfigFilePath)) {
throw Error(MESSAGES.TSCONFIG_FILE_NOT_FOUND);
}
}

const compilerOptions = getCompilerOptions(tsConfigFilePath);
const generateApiOptions = { ...options, outputFile, compilerOptions };

var sourceCode = await generateApi(schemaAbsPath, generateApiOptions);
if (outputFile) {
fs.writeFileSync(path.resolve(process.cwd(), outputFile), await prettify(outputFile, sourceCode));
} else {
console.log(await prettify(null, sourceCode));
}
} catch (error) {
console.error(error);
}
}
24 changes: 24 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,27 @@ export type GenerationOptions = {
compilerOptions?: ts.CompilerOptions;
isDataResponse?(code: string, response: OpenAPIV3.ResponseObject, allResponses: OpenAPIV3.ResponsesObject): boolean;
};

export interface CommonOptions extends GenerationOptions {
//apiFile: string;
schemaFile: string; // filename or url
apiImport?: string; // defaults to "api"
tsConfigFilePath?: string;
}

export interface OutputFileOptions extends Partial<GenerationOptions> {
outputFile: string;
filterEndpoints?: string | string[] | RegExp | RegExp[];
endpointOverrides?: EndpointOverrides[];
}

export interface EndpointOverrides {
pattern: string | string[] | RegExp | RegExp[];
type: 'mutation' | 'query';
}

export type ConfigFile =
| (CommonOptions & OutputFileOptions)
| (Omit<CommonOptions, 'outputFile'> & {
outputFiles: { [outputFile: string]: Omit<OutputFileOptions, 'outputFile'> };
});
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es2019" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
"target": "es2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
Expand Down