@kollors/react-codegen 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 kollors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # React Codegen
2
+
3
+ [Русский](README.ru.md)
4
+
5
+ Generate one self-contained TypeScript client file from an OpenAPI schema, GraphQL schema and operations, or both.
6
+
7
+ Requires Node.js 22 or newer and TanStack Query 5 in the consuming application.
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ npm install -D @kollors/react-codegen@alpha
13
+ ```
14
+
15
+ ## Configuration
16
+
17
+ Create `codegen.config.js`:
18
+
19
+ ```js
20
+ export default {
21
+ openapi: {
22
+ schema: './openapi.yaml',
23
+ output: './src/api/openapi.ts',
24
+ },
25
+ graphql: {
26
+ schema: './schema.graphql',
27
+ documents: './src/graphql',
28
+ output: './src/api/graphql.ts',
29
+ },
30
+ };
31
+ ```
32
+
33
+ Run both configured generators with:
34
+
35
+ ```sh
36
+ npx react-codegen codegen.config.js
37
+ ```
38
+
39
+ Paths are resolved relative to the config file. A configured `openapi` section enables OpenAPI generation; a configured `graphql` section enables GraphQL generation. Omit a section to skip it. At least one section is required. Each section writes one TypeScript file. `documents` is a directory; all `.graphql` files under it, including nested directories, are included.
40
+
41
+ Schema values may be local paths or URLs. `output` directories are created when needed.
42
+
43
+ ## Programmatic API
44
+
45
+ ```ts
46
+ import { generate, type CodegenConfig } from '@kollors/react-codegen';
47
+
48
+ const config: CodegenConfig = {
49
+ graphql: {
50
+ schema: './schema.graphql',
51
+ documents: './src/graphql',
52
+ output: './src/api/graphql.ts',
53
+ },
54
+ };
55
+
56
+ const result = await generate(config);
57
+ console.log(result.outputs);
58
+ ```
59
+
60
+ Programmatic relative paths resolve from the current working directory. `generate` returns the generated output paths.
61
+
62
+ ## Development
63
+
64
+ ```sh
65
+ npm ci
66
+ npm run verify
67
+ ```
68
+
69
+ ## License
70
+
71
+ [MIT](LICENSE)
package/README.ru.md ADDED
@@ -0,0 +1,71 @@
1
+ # React Codegen
2
+
3
+ [English](README.md)
4
+
5
+ Генерация одного самодостаточного TypeScript-клиента из OpenAPI-схемы, GraphQL-схемы и операций либо сразу из обеих схем.
6
+
7
+ Требуются Node.js 22 или новее и TanStack Query 5 в подключающем приложении.
8
+
9
+ ## Установка
10
+
11
+ ```sh
12
+ npm install -D @kollors/react-codegen@alpha
13
+ ```
14
+
15
+ ## Конфигурация
16
+
17
+ Создайте `codegen.config.js`:
18
+
19
+ ```js
20
+ export default {
21
+ openapi: {
22
+ schema: './openapi.yaml',
23
+ output: './src/api/openapi.ts',
24
+ },
25
+ graphql: {
26
+ schema: './schema.graphql',
27
+ documents: './src/graphql',
28
+ output: './src/api/graphql.ts',
29
+ },
30
+ };
31
+ ```
32
+
33
+ Запуск:
34
+
35
+ ```sh
36
+ npx react-codegen codegen.config.js
37
+ ```
38
+
39
+ Пути разрешаются относительно файла конфигурации. Наличие секции `openapi` запускает генерацию OpenAPI, наличие `graphql` — GraphQL. Отсутствующую секцию можно опустить; нужна хотя бы одна. Каждая секция создаёт один TypeScript-файл. `documents` — каталог: в нём и всех подпапках рекурсивно ищутся файлы `.graphql`.
40
+
41
+ В `schema` можно передавать локальный путь или URL. Каталоги для `output` создаются автоматически.
42
+
43
+ ## Программный API
44
+
45
+ ```ts
46
+ import { generate, type CodegenConfig } from '@kollors/react-codegen';
47
+
48
+ const config: CodegenConfig = {
49
+ graphql: {
50
+ schema: './schema.graphql',
51
+ documents: './src/graphql',
52
+ output: './src/api/graphql.ts',
53
+ },
54
+ };
55
+
56
+ const result = await generate(config);
57
+ console.log(result.outputs);
58
+ ```
59
+
60
+ В программном API относительные пути считаются от текущей рабочей директории. `generate` возвращает пути созданных файлов.
61
+
62
+ ## Разработка
63
+
64
+ ```sh
65
+ npm ci
66
+ npm run verify
67
+ ```
68
+
69
+ ## Лицензия
70
+
71
+ [MIT](LICENSE)
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from 'node:fs/promises';
3
+ import { dirname, isAbsolute, resolve } from 'node:path';
4
+ import { pathToFileURL } from 'node:url';
5
+ import { generate } from './generate.js';
6
+ const help = `Usage: react-codegen <codegen.config.js>
7
+
8
+ Generate configured OpenAPI and GraphQL clients.
9
+
10
+ Options:
11
+ -h, --help Show this help message
12
+ -v, --version Show version
13
+ `;
14
+ function resolvePath(value, directory) {
15
+ return isAbsolute(value) ? value : resolve(directory, value);
16
+ }
17
+ function resolveSchema(value, directory) {
18
+ return /^[a-z][a-z\d+.-]*:\/\//i.test(value) ? value : resolvePath(value, directory);
19
+ }
20
+ async function main(args) {
21
+ if (args.includes('--help') || args.includes('-h')) {
22
+ process.stdout.write(help);
23
+ return;
24
+ }
25
+ if (args.includes('--version') || args.includes('-v')) {
26
+ const packageJson = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
27
+ process.stdout.write(`${packageJson.version}\n`);
28
+ return;
29
+ }
30
+ if (args.length !== 1 || args[0]?.startsWith('-')) {
31
+ throw new Error('Usage: react-codegen <codegen.config.js>');
32
+ }
33
+ const configPath = resolve(args[0]);
34
+ const configModule = (await import(pathToFileURL(configPath).href));
35
+ if (!configModule.default || typeof configModule.default !== 'object') {
36
+ throw new TypeError(`${configPath} must export a configuration object as default.`);
37
+ }
38
+ const directory = dirname(configPath);
39
+ const config = {
40
+ ...configModule.default,
41
+ ...(configModule.default.openapi && {
42
+ openapi: {
43
+ ...configModule.default.openapi,
44
+ schema: resolveSchema(configModule.default.openapi.schema, directory),
45
+ output: resolvePath(configModule.default.openapi.output, directory),
46
+ },
47
+ }),
48
+ ...(configModule.default.graphql && {
49
+ graphql: {
50
+ ...configModule.default.graphql,
51
+ schema: resolveSchema(configModule.default.graphql.schema, directory),
52
+ documents: resolvePath(configModule.default.graphql.documents, directory),
53
+ output: resolvePath(configModule.default.graphql.output, directory),
54
+ },
55
+ }),
56
+ };
57
+ const result = await generate(config);
58
+ for (const output of result.outputs)
59
+ process.stdout.write(`Generated: ${output}\n`);
60
+ }
61
+ try {
62
+ await main(process.argv.slice(2));
63
+ }
64
+ catch (error) {
65
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
66
+ process.exitCode = 1;
67
+ }
68
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CodegenConfig, CodegenResult } from './types.js';
2
+ /** Generate configured OpenAPI and GraphQL clients into one TypeScript file per enabled section. */
3
+ export declare function generate(config: CodegenConfig): Promise<CodegenResult>;
@@ -0,0 +1,119 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ const packageDirectory = dirname(dirname(fileURLToPath(import.meta.url)));
6
+ const templatesDirectory = join(packageDirectory, 'templates');
7
+ function outputPath(path, cwd) {
8
+ return isAbsolute(path) ? path : resolve(cwd, path);
9
+ }
10
+ function schemaValue(schema, cwd) {
11
+ return /^[a-z][a-z\d+.-]*:\/\//i.test(schema) ? schema : outputPath(schema, cwd);
12
+ }
13
+ function openapiSource(schema, cwd) {
14
+ if (/^[a-z][a-z\d+.-]*:\/\//i.test(schema))
15
+ return { source: 'url', url: schema };
16
+ return { source: 'file', relativePath: relative(packageDirectory, schemaValue(schema, cwd)) };
17
+ }
18
+ function run(command, args, cwd) {
19
+ execFileSync(command, args, { cwd, stdio: 'inherit' });
20
+ }
21
+ function createProjectTempDirectory(cwd, prefix) {
22
+ const baseDirectory = join(cwd, '.react-codegen-temp');
23
+ mkdirSync(baseDirectory, { recursive: true });
24
+ return mkdtempSync(join(baseDirectory, prefix));
25
+ }
26
+ function generateOpenapi(config, cwd) {
27
+ const tempDirectory = createProjectTempDirectory(packageDirectory, 'openapi-');
28
+ const output = outputPath(config.output, cwd);
29
+ try {
30
+ mkdirSync(dirname(output), { recursive: true });
31
+ const fetcherPath = join(tempDirectory, 'openapi-fetcher.ts');
32
+ const fetcher = readFileSync(join(packageDirectory, 'dist', 'openapi-fetcher.js'), 'utf8')
33
+ .replace(/\n?\/\/# sourceMappingURL=.*$/, '')
34
+ .replaceAll('export ', '');
35
+ writeFileSync(fetcherPath, fetcher);
36
+ const template = readFileSync(join(templatesDirectory, 'openapi.template'), 'utf8');
37
+ const configText = template
38
+ .replaceAll('%OPENAPI_SOURCE%', JSON.stringify(openapiSource(config.schema, cwd)))
39
+ .replaceAll('%FILENAME%', JSON.stringify(output))
40
+ .replaceAll('%OUTPUT_DIR%', JSON.stringify(relative(packageDirectory, join(tempDirectory, 'output'))))
41
+ .replaceAll('%FETCHER_PATH%', JSON.stringify(fetcherPath));
42
+ const configPath = join(tempDirectory, 'openapi.codegen.ts');
43
+ writeFileSync(configPath, configText);
44
+ run('openapi-codegen', ['gen', 'openapi', '-c', relative(packageDirectory, configPath)], packageDirectory);
45
+ return output;
46
+ }
47
+ finally {
48
+ rmSync(tempDirectory, { force: true, recursive: true });
49
+ }
50
+ }
51
+ function generateGraphql(config, cwd) {
52
+ const tempDirectory = createProjectTempDirectory(packageDirectory, 'graphql-');
53
+ const output = outputPath(config.output, cwd);
54
+ try {
55
+ mkdirSync(dirname(output), { recursive: true });
56
+ const template = readFileSync(join(templatesDirectory, 'graphql.template'), 'utf8');
57
+ const configText = template
58
+ .replaceAll('%SCHEMA%', JSON.stringify(schemaValue(config.schema, cwd)))
59
+ .replaceAll('%DOCUMENTS%', JSON.stringify(`${outputPath(config.documents, cwd).replace(/\/$/, '')}/**/*.graphql`))
60
+ .replaceAll('%FILENAME%', JSON.stringify(output));
61
+ const configPath = join(tempDirectory, 'graphql.codegen.ts');
62
+ writeFileSync(configPath, configText);
63
+ run('graphql-codegen', ['--config', relative(packageDirectory, configPath)], packageDirectory);
64
+ const generatedFile = readFileSync(output, 'utf8');
65
+ const fetcher = readFileSync(join(packageDirectory, 'dist', 'graphql-fetcher.js'), 'utf8').replace(/\n?\/\/# sourceMappingURL=.*$/, '');
66
+ const importLine = "import { graphqlFetcher } from '@kollors/react-codegen/graphql-fetcher';";
67
+ if (!generatedFile.includes(importLine)) {
68
+ throw new Error('Generated GraphQL client does not contain the expected fetcher import.');
69
+ }
70
+ writeFileSync(output, `// @ts-nocheck\n/* eslint-disable */\n${generatedFile.replace(importLine, `${fetcher}\n`)}`);
71
+ return output;
72
+ }
73
+ finally {
74
+ rmSync(tempDirectory, { force: true, recursive: true });
75
+ }
76
+ }
77
+ function validateConfig(config) {
78
+ if (config === null || typeof config !== 'object' || Array.isArray(config)) {
79
+ throw new TypeError('Codegen config must be an object.');
80
+ }
81
+ const keys = Object.keys(config);
82
+ if (keys.some((key) => key !== 'openapi' && key !== 'graphql')) {
83
+ throw new Error(`Unknown codegen config section: ${keys.find((key) => key !== 'openapi' && key !== 'graphql')}`);
84
+ }
85
+ if (!config.openapi && !config.graphql) {
86
+ throw new Error('Codegen config must contain an openapi or graphql section.');
87
+ }
88
+ for (const [kind, section] of Object.entries(config)) {
89
+ if (!section || typeof section !== 'object' || Array.isArray(section)) {
90
+ throw new TypeError(`config.${kind} must be an object.`);
91
+ }
92
+ const expectedKeys = kind === 'openapi' ? ['schema', 'output'] : ['schema', 'documents', 'output'];
93
+ for (const key of Object.keys(section)) {
94
+ if (!expectedKeys.includes(key))
95
+ throw new Error(`Unknown config.${kind} option: ${key}`);
96
+ }
97
+ for (const key of expectedKeys) {
98
+ const value = section[key];
99
+ if (typeof value !== 'string' || !value.trim())
100
+ throw new TypeError(`config.${kind}.${key} must be a non-empty string.`);
101
+ }
102
+ }
103
+ const outputs = [config.openapi?.output, config.graphql?.output].filter((value) => Boolean(value));
104
+ if (new Set(outputs.map((value) => resolve(value))).size !== outputs.length) {
105
+ throw new Error('OpenAPI and GraphQL outputs must use different files.');
106
+ }
107
+ }
108
+ /** Generate configured OpenAPI and GraphQL clients into one TypeScript file per enabled section. */
109
+ export async function generate(config) {
110
+ validateConfig(config);
111
+ const cwd = process.cwd();
112
+ const outputs = [];
113
+ if (config.openapi)
114
+ outputs.push(generateOpenapi(config.openapi, cwd));
115
+ if (config.graphql)
116
+ outputs.push(generateGraphql(config.graphql, cwd));
117
+ return { outputs };
118
+ }
119
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface GraphqlFetcherConfiguration {
2
+ endpoint?: string;
3
+ getToken?: () => string | null | undefined;
4
+ headers?: HeadersInit;
5
+ }
6
+ export declare function createGraphqlFetcher(configuration?: GraphqlFetcherConfiguration): <TData, TVariables>(query: string, variables?: TVariables) => Promise<TData>;
7
+ export declare const graphqlFetcher: <TData, TVariables>(query: string, variables?: TVariables) => Promise<TData>;
@@ -0,0 +1,33 @@
1
+ function defaultGetToken() {
2
+ return typeof localStorage === 'undefined' ? '' : (localStorage.getItem('token') ?? '');
3
+ }
4
+ export function createGraphqlFetcher(configuration = {}) {
5
+ const endpoint = configuration.endpoint ?? '/api/graphql';
6
+ const getToken = configuration.getToken ?? defaultGetToken;
7
+ return async function graphqlFetcher(query, variables) {
8
+ const headers = new Headers({ authorization: getToken() ?? '', 'content-type': 'application/json' });
9
+ new Headers(configuration.headers).forEach((value, key) => {
10
+ headers.set(key, value);
11
+ });
12
+ try {
13
+ const response = await fetch(endpoint, {
14
+ body: JSON.stringify({ query, variables }),
15
+ headers,
16
+ method: 'POST',
17
+ });
18
+ const result = (await response.json());
19
+ if (!response.ok || result.errors?.length) {
20
+ throw new Error(result.errors?.[0]?.message ?? `GraphQL request failed with status ${response.status}.`);
21
+ }
22
+ if (result.data === undefined) {
23
+ throw new Error('GraphQL response does not contain data.');
24
+ }
25
+ return result.data;
26
+ }
27
+ catch (error) {
28
+ throw error instanceof Error ? error : new Error(String(error));
29
+ }
30
+ };
31
+ }
32
+ export const graphqlFetcher = createGraphqlFetcher();
33
+ //# sourceMappingURL=graphql-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql-fetcher.js","sourceRoot":"","sources":["../src/graphql-fetcher.ts"],"names":[],"mappings":"AAMA,SAAS,eAAe;IACtB,OAAO,OAAO,YAAY,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,gBAA6C,EAAE;IAClF,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,IAAI,cAAc,CAAC;IAC1D,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,IAAI,eAAe,CAAC;IAE3D,OAAO,KAAK,UAAU,cAAc,CAAoB,KAAa,EAAE,SAAsB;QAC3F,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACrG,IAAI,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACxD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;gBACrC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;gBAC1C,OAAO;gBACP,MAAM,EAAE,MAAM;aACf,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA0D,CAAC;YAEhG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,sCAAsC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;YAC3G,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAC7D,CAAC;YAED,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { generate } from './generate.js';
2
+ export type { GraphqlFetcherConfiguration } from './graphql-fetcher.js';
3
+ export { createGraphqlFetcher, graphqlFetcher } from './graphql-fetcher.js';
4
+ export type { OpenapiFetcherConfiguration, OpenapiFetcherOptions } from './openapi-fetcher.js';
5
+ export { createOpenapiFetcher, openapiFetcher } from './openapi-fetcher.js';
6
+ export type { CodegenConfig, CodegenResult } from './types.js';
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { generate } from './generate.js';
2
+ export { createGraphqlFetcher, graphqlFetcher } from './graphql-fetcher.js';
3
+ export { createOpenapiFetcher, openapiFetcher } from './openapi-fetcher.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,14 @@
1
+ export interface OpenapiFetcherOptions<TBody, THeaders, TQueryParams, TPathParams> {
2
+ body?: TBody;
3
+ headers?: THeaders;
4
+ method: string;
5
+ pathParams?: TPathParams;
6
+ queryParams?: TQueryParams;
7
+ signal?: AbortSignal;
8
+ url: string;
9
+ }
10
+ export interface OpenapiFetcherConfiguration {
11
+ getToken?: () => string | null | undefined;
12
+ }
13
+ export declare function createOpenapiFetcher(configuration?: OpenapiFetcherConfiguration): <TData, TError, TBody, THeaders, TQueryParams, TPathParams>(options: OpenapiFetcherOptions<TBody, THeaders, TQueryParams, TPathParams>) => Promise<TData>;
14
+ export declare const openapiFetcher: <TData, TError, TBody, THeaders, TQueryParams, TPathParams>(options: OpenapiFetcherOptions<TBody, THeaders, TQueryParams, TPathParams>) => Promise<TData>;
@@ -0,0 +1,37 @@
1
+ function defaultGetToken() {
2
+ return typeof localStorage === 'undefined' ? '' : (localStorage.getItem('token') ?? '');
3
+ }
4
+ export function createOpenapiFetcher(configuration = {}) {
5
+ const getToken = configuration.getToken ?? defaultGetToken;
6
+ return async function openapiFetcher(options) {
7
+ const headers = new Headers({ authorization: getToken() ?? '', 'content-type': 'application/json' });
8
+ new Headers(options.headers).forEach((value, key) => {
9
+ headers.set(key, value);
10
+ });
11
+ if (headers.get('content-type')?.toLowerCase().includes('multipart/form-data')) {
12
+ headers.delete('content-type');
13
+ }
14
+ const queryParams = new URLSearchParams(options.queryParams).toString();
15
+ const pathParams = options.pathParams;
16
+ const url = options.url.replace(/\{\w*}/g, (key) => String(pathParams?.[key.slice(1, -1)] ?? ''));
17
+ const body = options.body instanceof FormData ? options.body : options.body == null ? undefined : JSON.stringify(options.body);
18
+ try {
19
+ const response = await fetch(`${url}${queryParams ? `?${queryParams}` : ''}`, {
20
+ body,
21
+ headers,
22
+ method: options.method.toUpperCase(),
23
+ signal: options.signal,
24
+ });
25
+ const result = (response.headers.get('content-type')?.includes('json') ? await response.json() : await response.blob());
26
+ if (!response.ok) {
27
+ return Promise.reject(result);
28
+ }
29
+ return result;
30
+ }
31
+ catch (error) {
32
+ throw error instanceof Error ? error : new Error(String(error));
33
+ }
34
+ };
35
+ }
36
+ export const openapiFetcher = createOpenapiFetcher();
37
+ //# sourceMappingURL=openapi-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-fetcher.js","sourceRoot":"","sources":["../src/openapi-fetcher.ts"],"names":[],"mappings":"AAcA,SAAS,eAAe;IACtB,OAAO,OAAO,YAAY,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,gBAA6C,EAAE;IAClF,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,IAAI,eAAe,CAAC;IAE3D,OAAO,KAAK,UAAU,cAAc,CAClC,OAA0E;QAE1E,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACrG,IAAI,OAAO,CAAC,OAAO,CAAC,OAAkC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YAC7E,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;YAC/E,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACjC,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,WAAiD,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC9G,MAAM,UAAU,GAAG,OAAO,CAAC,UAAyD,CAAC;QACrF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAClG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,YAAY,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAE/H,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE;gBAC5E,IAAI;gBACJ,OAAO;gBACP,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE;gBACpC,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAU,CAAC;YAEjI,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,OAAO,CAAC,MAAM,CAAC,MAA2B,CAAC,CAAC;YACrD,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ export interface CodegenConfig {
2
+ openapi?: {
3
+ schema: string;
4
+ output: string;
5
+ };
6
+ graphql?: {
7
+ schema: string;
8
+ documents: string;
9
+ output: string;
10
+ };
11
+ }
12
+ export interface CodegenResult {
13
+ outputs: string[];
14
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@kollors/react-codegen",
3
+ "version": "2.0.0-alpha.1",
4
+ "description": "Generate TanStack Query clients from OpenAPI and GraphQL schemas",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ },
11
+ "./graphql-fetcher": {
12
+ "types": "./dist/graphql-fetcher.d.ts",
13
+ "import": "./dist/graphql-fetcher.js"
14
+ },
15
+ "./openapi-fetcher": {
16
+ "types": "./dist/openapi-fetcher.d.ts",
17
+ "import": "./dist/openapi-fetcher.js"
18
+ }
19
+ },
20
+ "bin": {
21
+ "react-codegen": "dist/cli.js"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "templates",
26
+ "LICENSE",
27
+ "README.md",
28
+ "README.ru.md"
29
+ ],
30
+ "scripts": {
31
+ "build": "node scripts/clean-dist.js && tsc",
32
+ "lint": "biome check . --error-on-warnings",
33
+ "lint:fix": "biome check --write .",
34
+ "pack:check": "npm pack --dry-run",
35
+ "prepack": "npm run build",
36
+ "prepublishOnly": "npm run verify",
37
+ "test": "npm run build && node --test",
38
+ "typecheck": "tsc --noEmit",
39
+ "verify": "npm run typecheck && npm run lint && npm run test && npm run pack:check"
40
+ },
41
+ "engines": {
42
+ "node": ">=22"
43
+ },
44
+ "dependencies": {
45
+ "@graphql-codegen/cli": "^7.4.2",
46
+ "@graphql-codegen/typescript": "^6.1.0",
47
+ "@graphql-codegen/typescript-operations": "^6.1.7",
48
+ "@graphql-codegen/typescript-react-query": "^7.0.5",
49
+ "@openapi-codegen/cli": "^3.1.0",
50
+ "@openapi-codegen/typescript": "^11.1.0"
51
+ },
52
+ "peerDependencies": {
53
+ "@tanstack/react-query": "^5.103.2"
54
+ },
55
+ "devDependencies": {
56
+ "@biomejs/biome": "^2.5.12",
57
+ "@types/node": "^26.6.2",
58
+ "typescript": "^5.7.3"
59
+ },
60
+ "repository": {
61
+ "type": "git",
62
+ "url": "git+https://github.com/kollors/react-codegen.git"
63
+ },
64
+ "homepage": "https://github.com/kollors/react-codegen#readme",
65
+ "bugs": {
66
+ "url": "https://github.com/kollors/react-codegen/issues"
67
+ },
68
+ "keywords": [
69
+ "codegen",
70
+ "graphql",
71
+ "openapi",
72
+ "react",
73
+ "react-query",
74
+ "tanstack-query",
75
+ "typescript"
76
+ ],
77
+ "author": "kollors",
78
+ "license": "MIT",
79
+ "publishConfig": {
80
+ "access": "public"
81
+ },
82
+ "overrides": {
83
+ "lodash": "^4.18.1"
84
+ }
85
+ }
@@ -0,0 +1,26 @@
1
+ import type { CodegenConfig } from '@graphql-codegen/cli';
2
+ const config: CodegenConfig = {
3
+ schema: %SCHEMA%,
4
+ documents: %DOCUMENTS%,
5
+ ignoreNoDocuments: true,
6
+ generates: {
7
+ [%FILENAME%]: {
8
+ plugins: [
9
+ 'typescript',
10
+ 'typescript-operations',
11
+ 'typescript-react-query',
12
+ ],
13
+ config: {
14
+ maybeValue: 'T | undefined',
15
+ scalars: { ID: 'number' },
16
+
17
+ fetcher: '@kollors/react-codegen/graphql-fetcher#graphqlFetcher',
18
+ legacyMode: false,
19
+ omitOperationSuffix: true,
20
+ reactQueryVersion: 5,
21
+ },
22
+ },
23
+ },
24
+ };
25
+
26
+ export default config;
@@ -0,0 +1,45 @@
1
+ import { defineConfig } from '@openapi-codegen/cli';
2
+ import { generateReactQueryComponents, generateSchemaTypes } from '@openapi-codegen/typescript';
3
+ import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+
6
+ const tempDir = %OUTPUT_DIR%;
7
+ const readGeneratedFile = (filename) => {
8
+ const path = join(tempDir, filename);
9
+ return existsSync(path) ? readFileSync(path, 'utf-8') : '';
10
+ };
11
+
12
+ const config = defineConfig({
13
+ openapi: {
14
+ from: %OPENAPI_SOURCE%,
15
+ outputDir: tempDir,
16
+ to: async(context) => {
17
+ const { schemasFiles } = await generateSchemaTypes(context, { filenamePrefix: '' });
18
+ await generateReactQueryComponents(context, { filenamePrefix: '', schemasFiles });
19
+
20
+ const contextStr = readFileSync(join(tempDir, 'context.ts'), 'utf-8').replace('import { QueryOperation } from "./components";', '');
21
+ const utilsStr = readFileSync(join(tempDir, 'utils.ts'), 'utf-8');
22
+ const schemasStr = readFileSync(join(tempDir, 'schemas.ts'), 'utf-8');
23
+ const parametersStr = readGeneratedFile('parameters.ts');
24
+ const openapiFetcherStr = readFileSync(%FETCHER_PATH%, 'utf-8').replace('export ', '');
25
+
26
+ const componentsStr = readFileSync(join(tempDir, 'components.ts'), 'utf-8')
27
+ .replace(/import\s+\*\s+as\s+reactQuery\s+from\s+"@tanstack\/react-query";/g, 'import * as reactQuery from "@tanstack/react-query";')
28
+ .replace(/import\s+\{\s*useContext,\s*Context,\s*queryKeyFn\s*}\s+from\s+"\.\/context";/g, '')
29
+ .replace(/import\s+\{\s*deepMerge\s*}\s+from\s+"\.\/utils";/g, '')
30
+ .replace(/import\s+type\s+\*\s+as\s+Schemas\s+from\s+"\.\/schemas";/g, '')
31
+ .replace(/import\s+type\s+\*\s+as\s+Fetcher\s+from\s+"\.\/fetcher";/g, '')
32
+ .replace(/import\s+\{\s*fetch\s*}\s+from\s+"\.\/fetcher";/g, '')
33
+ .replace(/Schemas\./g, '')
34
+ .replace(/Fetcher\./g, '')
35
+ .replace(/fetch\s*</g, 'openapiFetcher<');
36
+
37
+ const result = ['// @ts-nocheck', '/* eslint-disable */', parametersStr, schemasStr, openapiFetcherStr, contextStr, utilsStr, componentsStr].join('\n\n');
38
+
39
+ writeFileSync(%FILENAME%, result, 'utf-8');
40
+ rmSync(tempDir, { recursive: true });
41
+ },
42
+ },
43
+ });
44
+
45
+ export default config;