@openapi-qraft/tanstack-query-react-plugin 1.8.0 → 1.10.0

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/generateCode.d.ts +2 -1
  3. package/dist/generateCode.d.ts.map +1 -0
  4. package/dist/generateCode.js +10 -9
  5. package/dist/generateCode.js.map +1 -1
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/plugin.d.ts +1 -0
  9. package/dist/plugin.d.ts.map +1 -0
  10. package/dist/plugin.js +8 -6
  11. package/dist/plugin.js.map +1 -1
  12. package/dist/ts-factory/astToString.d.ts +1 -0
  13. package/dist/ts-factory/astToString.d.ts.map +1 -0
  14. package/dist/ts-factory/getClientFactory.d.ts +1 -0
  15. package/dist/ts-factory/getClientFactory.d.ts.map +1 -0
  16. package/dist/ts-factory/getIndexFactory.d.ts +12 -2
  17. package/dist/ts-factory/getIndexFactory.d.ts.map +1 -0
  18. package/dist/ts-factory/getIndexFactory.js +19 -1
  19. package/dist/ts-factory/getIndexFactory.js.map +1 -1
  20. package/dist/ts-factory/getServiceFactory.d.ts +1 -0
  21. package/dist/ts-factory/getServiceFactory.d.ts.map +1 -0
  22. package/dist/ts-factory/getServiceFactory.js +7 -0
  23. package/dist/ts-factory/getServiceFactory.js.map +1 -1
  24. package/dist/ts-factory/getServiceIndexFactory.d.ts +1 -0
  25. package/dist/ts-factory/getServiceIndexFactory.d.ts.map +1 -0
  26. package/package.json +8 -8
  27. package/src/__snapshots__/create-api-client.ts.snapshot.ts +80 -86
  28. package/src/__snapshots__/index.ts.snapshot.ts +8 -12
  29. package/src/__snapshots__/services/ApprovalPoliciesService.ts.snapshot.ts +67 -62
  30. package/src/__snapshots__/services/FilesService.ts.snapshot.ts +57 -55
  31. package/src/__snapshots__/services/index.ts.snapshot.ts +17 -23
  32. package/src/generateCode.ts +15 -12
  33. package/src/plugin.ts +13 -9
  34. package/src/ts-factory/getIndexFactory.ts +37 -1
  35. package/src/ts-factory/getServiceFactory.ts +35 -0
  36. package/dist/__snapshots__/create-api-client.ts.snapshot.d.ts +0 -1
  37. package/dist/__snapshots__/create-api-client.ts.snapshot.js +0 -88
  38. package/dist/__snapshots__/create-api-client.ts.snapshot.js.map +0 -1
  39. package/dist/__snapshots__/index.ts.snapshot.d.ts +0 -1
  40. package/dist/__snapshots__/index.ts.snapshot.js +0 -13
  41. package/dist/__snapshots__/index.ts.snapshot.js.map +0 -1
  42. package/dist/__snapshots__/services/ApprovalPoliciesService.ts.snapshot.d.ts +0 -1
  43. package/dist/__snapshots__/services/ApprovalPoliciesService.ts.snapshot.js +0 -62
  44. package/dist/__snapshots__/services/ApprovalPoliciesService.ts.snapshot.js.map +0 -1
  45. package/dist/__snapshots__/services/FilesService.ts.snapshot.d.ts +0 -1
  46. package/dist/__snapshots__/services/FilesService.ts.snapshot.js +0 -57
  47. package/dist/__snapshots__/services/FilesService.ts.snapshot.js.map +0 -1
  48. package/dist/__snapshots__/services/index.ts.snapshot.d.ts +0 -1
  49. package/dist/__snapshots__/services/index.ts.snapshot.js +0 -24
  50. package/dist/__snapshots__/services/index.ts.snapshot.js.map +0 -1
@@ -1,13 +1,9 @@
1
- import fs from 'node:fs';
2
- import { expect } from 'vitest';
1
+ /**
2
+ * This file was auto-generated by @openapi-qraft/cli.
3
+ * Do not make direct changes to the file.
4
+ */
3
5
 
4
- export default function () {
5
- expect(fs.readFileSync('/mock-fs/index.ts', 'utf-8')).toMatchInlineSnapshot(`
6
- "/* generated using @openapi-qraft/cli -- do no edit */
7
- /* istanbul ignore file */
8
- export { services } from "./services/index.js";
9
- export type { Services } from "./services/index.js";
10
- export { createAPIClient } from "./create-api-client.js";
11
- "
12
- `);
13
- }
6
+ export type * from "./../openapi.js";
7
+ export { services } from "./services/index.js";
8
+ export type { Services } from "./services/index.js";
9
+ export { createAPIClient } from "./create-api-client.js";
@@ -1,64 +1,69 @@
1
- import fs from 'node:fs';
2
- import { expect } from 'vitest';
1
+ /**
2
+ * This file was auto-generated by @openapi-qraft/cli.
3
+ * Do not make direct changes to the file.
4
+ */
3
5
 
4
- export default function () {
5
- expect(
6
- fs.readFileSync('/mock-fs/services/ApprovalPoliciesService.ts', 'utf-8')
7
- ).toMatchInlineSnapshot(`
8
- "/* generated using @openapi-qraft/cli -- do no edit */
9
- /* istanbul ignore file */
10
- import type { paths } from "../../openapi.js";
11
- import type { ServiceOperationQuery, ServiceOperationMutation } from "@openapi-qraft/react";
12
- export interface ApprovalPoliciesService {
13
- /**
14
- * @summary Get an approval policy by ID
15
- * @description Retrieve a specific approval policy.
16
- */
17
- getApprovalPoliciesId: ServiceOperationQuery<{
18
- method: "get";
19
- url: "/approval_policies/{approval_policy_id}";
20
- }, paths["/approval_policies/{approval_policy_id}"]["get"]["responses"]["200"]["content"]["application/json"], paths["/approval_policies/{approval_policy_id}"]["get"]["parameters"], paths["/approval_policies/{approval_policy_id}"]["get"]["responses"]["401"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["get"]["responses"]["422"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["get"]["responses"]["default"]["content"]["application/json"]>;
21
- /**
22
- * @summary Delete an approval policy
23
- * @description Delete an existing approval policy.
24
- */
25
- deleteApprovalPoliciesId: ServiceOperationMutation<{
26
- method: "delete";
27
- url: "/approval_policies/{approval_policy_id}";
28
- }, undefined, paths["/approval_policies/{approval_policy_id}"]["delete"]["responses"]["200"]["content"]["application/json"], paths["/approval_policies/{approval_policy_id}"]["delete"]["parameters"], paths["/approval_policies/{approval_policy_id}"]["delete"]["responses"]["401"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["delete"]["responses"]["422"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["delete"]["responses"]["default"]["content"]["application/json"]>;
29
- /**
30
- * @summary Update an approval policy
31
- * @description Update an existing approval policy.
32
- */
33
- patchApprovalPoliciesId: ServiceOperationMutation<{
34
- method: "patch";
35
- url: "/approval_policies/{approval_policy_id}";
36
- mediaType: "application/json";
37
- }, NonNullable<paths["/approval_policies/{approval_policy_id}"]["patch"]["requestBody"]>["content"]["application/json"], paths["/approval_policies/{approval_policy_id}"]["patch"]["responses"]["200"]["content"]["application/json"], paths["/approval_policies/{approval_policy_id}"]["patch"]["parameters"], paths["/approval_policies/{approval_policy_id}"]["patch"]["responses"]["401"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["patch"]["responses"]["422"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["patch"]["responses"]["default"]["content"]["application/json"]>;
38
- }
39
- export const approvalPoliciesService: {
40
- [key in keyof ApprovalPoliciesService]: Pick<ApprovalPoliciesService[key], "schema">;
41
- } = {
42
- getApprovalPoliciesId: {
43
- schema: {
44
- method: "get",
45
- url: "/approval_policies/{approval_policy_id}"
46
- }
47
- },
48
- deleteApprovalPoliciesId: {
49
- schema: {
50
- method: "delete",
51
- url: "/approval_policies/{approval_policy_id}"
52
- }
53
- },
54
- patchApprovalPoliciesId: {
55
- schema: {
56
- method: "patch",
57
- url: "/approval_policies/{approval_policy_id}",
58
- mediaType: "application/json"
59
- }
60
- }
61
- } as const;
62
- "
63
- `);
6
+ import type { paths } from "../../openapi.js";
7
+ import type { ServiceOperationQuery, ServiceOperationMutation } from "@openapi-qraft/react";
8
+ export interface ApprovalPoliciesService {
9
+ /**
10
+ * @summary Get an approval policy by ID
11
+ * @description Retrieve a specific approval policy.
12
+ */
13
+ getApprovalPoliciesId: ServiceOperationQuery<{
14
+ method: "get";
15
+ url: "/approval_policies/{approval_policy_id}";
16
+ security: [
17
+ "partnerToken"
18
+ ];
19
+ }, paths["/approval_policies/{approval_policy_id}"]["get"]["responses"]["200"]["content"]["application/json"], paths["/approval_policies/{approval_policy_id}"]["get"]["parameters"], paths["/approval_policies/{approval_policy_id}"]["get"]["responses"]["401"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["get"]["responses"]["422"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["get"]["responses"]["default"]["content"]["application/json"]>;
20
+ /**
21
+ * @summary Delete an approval policy
22
+ * @description Delete an existing approval policy.
23
+ */
24
+ deleteApprovalPoliciesId: ServiceOperationMutation<{
25
+ method: "delete";
26
+ url: "/approval_policies/{approval_policy_id}";
27
+ security: [
28
+ "HTTPBearer"
29
+ ];
30
+ }, undefined, paths["/approval_policies/{approval_policy_id}"]["delete"]["responses"]["200"]["content"]["application/json"], paths["/approval_policies/{approval_policy_id}"]["delete"]["parameters"], paths["/approval_policies/{approval_policy_id}"]["delete"]["responses"]["401"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["delete"]["responses"]["422"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["delete"]["responses"]["default"]["content"]["application/json"]>;
31
+ /**
32
+ * @summary Update an approval policy
33
+ * @description Update an existing approval policy.
34
+ */
35
+ patchApprovalPoliciesId: ServiceOperationMutation<{
36
+ method: "patch";
37
+ url: "/approval_policies/{approval_policy_id}";
38
+ mediaType: "application/json";
39
+ security: [
40
+ "HTTPBearer"
41
+ ];
42
+ }, NonNullable<paths["/approval_policies/{approval_policy_id}"]["patch"]["requestBody"]>["content"]["application/json"], paths["/approval_policies/{approval_policy_id}"]["patch"]["responses"]["200"]["content"]["application/json"], paths["/approval_policies/{approval_policy_id}"]["patch"]["parameters"], paths["/approval_policies/{approval_policy_id}"]["patch"]["responses"]["401"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["patch"]["responses"]["422"]["content"]["application/json"] | paths["/approval_policies/{approval_policy_id}"]["patch"]["responses"]["default"]["content"]["application/json"]>;
64
43
  }
44
+ export const approvalPoliciesService: {
45
+ [key in keyof ApprovalPoliciesService]: Pick<ApprovalPoliciesService[key], "schema">;
46
+ } = {
47
+ getApprovalPoliciesId: {
48
+ schema: {
49
+ method: "get",
50
+ url: "/approval_policies/{approval_policy_id}",
51
+ security: ["partnerToken"]
52
+ }
53
+ },
54
+ deleteApprovalPoliciesId: {
55
+ schema: {
56
+ method: "delete",
57
+ url: "/approval_policies/{approval_policy_id}",
58
+ security: ["HTTPBearer"]
59
+ }
60
+ },
61
+ patchApprovalPoliciesId: {
62
+ schema: {
63
+ method: "patch",
64
+ url: "/approval_policies/{approval_policy_id}",
65
+ mediaType: "application/json",
66
+ security: ["HTTPBearer"]
67
+ }
68
+ }
69
+ } as const;
@@ -1,57 +1,59 @@
1
- import fs from 'node:fs';
2
- import { expect } from 'vitest';
1
+ /**
2
+ * This file was auto-generated by @openapi-qraft/cli.
3
+ * Do not make direct changes to the file.
4
+ */
3
5
 
4
- export default function () {
5
- expect(fs.readFileSync('/mock-fs/services/FilesService.ts', 'utf-8'))
6
- .toMatchInlineSnapshot(`
7
- "/* generated using @openapi-qraft/cli -- do no edit */
8
- /* istanbul ignore file */
9
- import type { paths } from "../../openapi.js";
10
- import type { ServiceOperationQuery, ServiceOperationMutation } from "@openapi-qraft/react";
11
- export interface FilesService {
12
- /** @summary Get a files by ID */
13
- getFiles: ServiceOperationQuery<{
14
- method: "get";
15
- url: "/files";
16
- }, paths["/files"]["get"]["responses"]["200"]["content"]["application/json"], paths["/files"]["get"]["parameters"], paths["/files"]["get"]["responses"]["405"]["content"]["application/json"] | paths["/files"]["get"]["responses"]["422"]["content"]["application/json"] | paths["/files"]["get"]["responses"]["default"]["content"]["application/json"]>;
17
- /** @summary Upload a files by ID */
18
- postFiles: ServiceOperationMutation<{
19
- method: "post";
20
- url: "/files";
21
- mediaType: "multipart/form-data";
22
- }, NonNullable<paths["/files"]["post"]["requestBody"]>["content"]["multipart/form-data"], paths["/files"]["post"]["responses"]["200"]["content"]["application/json"], undefined, paths["/files"]["post"]["responses"]["default"]["content"]["application/json"]>;
23
- /**
24
- * @deprecated
25
- * @summary Get a file list
26
- */
27
- getFileList: ServiceOperationQuery<{
28
- method: "get";
29
- url: "/files/list";
30
- }, paths["/files/list"]["get"]["responses"]["200"]["content"]["application/json"], paths["/files/list"]["get"]["parameters"], paths["/files/list"]["get"]["responses"]["default"]["content"]["application/json"]>;
31
- }
32
- export const filesService: {
33
- [key in keyof FilesService]: Pick<FilesService[key], "schema">;
34
- } = {
35
- getFiles: {
36
- schema: {
37
- method: "get",
38
- url: "/files"
39
- }
40
- },
41
- postFiles: {
42
- schema: {
43
- method: "post",
44
- url: "/files",
45
- mediaType: "multipart/form-data"
46
- }
47
- },
48
- getFileList: {
49
- schema: {
50
- method: "get",
51
- url: "/files/list"
52
- }
53
- }
54
- } as const;
55
- "
56
- `);
6
+ import type { paths } from "../../openapi.js";
7
+ import type { ServiceOperationQuery, ServiceOperationMutation } from "@openapi-qraft/react";
8
+ export interface FilesService {
9
+ /** @summary Get a files by ID */
10
+ getFiles: ServiceOperationQuery<{
11
+ method: "get";
12
+ url: "/files";
13
+ security: [
14
+ "HTTPBearer"
15
+ ];
16
+ }, paths["/files"]["get"]["responses"]["200"]["content"]["application/json"], paths["/files"]["get"]["parameters"], paths["/files"]["get"]["responses"]["405"]["content"]["application/json"] | paths["/files"]["get"]["responses"]["422"]["content"]["application/json"] | paths["/files"]["get"]["responses"]["default"]["content"]["application/json"]>;
17
+ /** @summary Upload a files by ID */
18
+ postFiles: ServiceOperationMutation<{
19
+ method: "post";
20
+ url: "/files";
21
+ mediaType: "multipart/form-data";
22
+ }, NonNullable<paths["/files"]["post"]["requestBody"]>["content"]["multipart/form-data"], paths["/files"]["post"]["responses"]["200"]["content"]["application/json"], undefined, paths["/files"]["post"]["responses"]["default"]["content"]["application/json"]>;
23
+ /**
24
+ * @deprecated
25
+ * @summary Get a file list
26
+ */
27
+ getFileList: ServiceOperationQuery<{
28
+ method: "get";
29
+ url: "/files/list";
30
+ security: [
31
+ "HTTPBearer"
32
+ ];
33
+ }, paths["/files/list"]["get"]["responses"]["200"]["content"]["application/json"], paths["/files/list"]["get"]["parameters"], paths["/files/list"]["get"]["responses"]["default"]["content"]["application/json"]>;
57
34
  }
35
+ export const filesService: {
36
+ [key in keyof FilesService]: Pick<FilesService[key], "schema">;
37
+ } = {
38
+ getFiles: {
39
+ schema: {
40
+ method: "get",
41
+ url: "/files",
42
+ security: ["HTTPBearer"]
43
+ }
44
+ },
45
+ postFiles: {
46
+ schema: {
47
+ method: "post",
48
+ url: "/files",
49
+ mediaType: "multipart/form-data"
50
+ }
51
+ },
52
+ getFileList: {
53
+ schema: {
54
+ method: "get",
55
+ url: "/files/list",
56
+ security: ["HTTPBearer"]
57
+ }
58
+ }
59
+ } as const;
@@ -1,24 +1,18 @@
1
- import fs from 'node:fs';
2
- import { expect } from 'vitest';
1
+ /**
2
+ * This file was auto-generated by @openapi-qraft/cli.
3
+ * Do not make direct changes to the file.
4
+ */
3
5
 
4
- export default function () {
5
- expect(fs.readFileSync('/mock-fs/services/index.ts', 'utf-8'))
6
- .toMatchInlineSnapshot(`
7
- "/* generated using @openapi-qraft/cli -- do no edit */
8
- /* istanbul ignore file */
9
- import { EntitiesService, entitiesService } from "./EntitiesService.js";
10
- import { ApprovalPoliciesService, approvalPoliciesService } from "./ApprovalPoliciesService.js";
11
- import { FilesService, filesService } from "./FilesService.js";
12
- export type Services = {
13
- entities: EntitiesService;
14
- approvalPolicies: ApprovalPoliciesService;
15
- files: FilesService;
16
- };
17
- export const services = {
18
- entities: entitiesService,
19
- approvalPolicies: approvalPoliciesService,
20
- files: filesService
21
- } as const;
22
- "
23
- `);
24
- }
6
+ import { EntitiesService, entitiesService } from "./EntitiesService.js";
7
+ import { ApprovalPoliciesService, approvalPoliciesService } from "./ApprovalPoliciesService.js";
8
+ import { FilesService, filesService } from "./FilesService.js";
9
+ export type Services = {
10
+ entities: EntitiesService;
11
+ approvalPolicies: ApprovalPoliciesService;
12
+ files: FilesService;
13
+ };
14
+ export const services = {
15
+ entities: entitiesService,
16
+ approvalPolicies: approvalPoliciesService,
17
+ files: filesService
18
+ } as const;
@@ -1,3 +1,4 @@
1
+ import { formatFileHeader } from '@openapi-qraft/plugin/lib/formatFileHeader';
1
2
  import { GeneratorFile } from '@openapi-qraft/plugin/lib/GeneratorFile';
2
3
  import { Service } from '@openapi-qraft/plugin/lib/open-api/getServices';
3
4
  import { OutputOptions as OutputOptionsBase } from '@openapi-qraft/plugin/lib/OutputOptions';
@@ -19,6 +20,7 @@ interface OutputOptions extends OutputOptionsBase {
19
20
  fileHeader: string | undefined;
20
21
  servicesDirName: string;
21
22
  explicitImportExtensions: boolean;
23
+ exportSchemaTypes: boolean | undefined;
22
24
  }
23
25
 
24
26
  export const generateCode = async ({
@@ -36,7 +38,7 @@ export const generateCode = async ({
36
38
  ...(await generateServices(spinner, services, serviceImports, output)),
37
39
  ...(await generateServiceIndex(spinner, services, output)),
38
40
  ...(await generateClient(spinner, output)),
39
- ...(await generateIndex(spinner, output)),
41
+ ...(await generateIndex(spinner, serviceImports, output)),
40
42
  ];
41
43
  };
42
44
 
@@ -82,7 +84,7 @@ const generateServices = async (
82
84
 
83
85
  serviceFiles.push({
84
86
  file: new URL(`${fileBaseName}.ts`, servicesDir),
85
- code: getFileHeader(output) + code,
87
+ code: formatFileHeader(output.fileHeader) + code,
86
88
  });
87
89
  } catch (error) {
88
90
  spinner.fail(
@@ -123,7 +125,7 @@ const generateServiceIndex = async (
123
125
 
124
126
  serviceIndexFiles.push({
125
127
  file: new URL('index.ts', composeServicesDirPath(output)),
126
- code: getFileHeader(output) + code,
128
+ code: formatFileHeader(output.fileHeader) + code,
127
129
  });
128
130
  } catch (error) {
129
131
  spinner.fail(
@@ -153,7 +155,7 @@ const generateClient = async (spinner: Ora, output: OutputOptions) => {
153
155
 
154
156
  clientFiles.push({
155
157
  file: new URL('create-api-client.ts', output.dir),
156
- code: getFileHeader(output) + code,
158
+ code: formatFileHeader(output.fileHeader) + code,
157
159
  });
158
160
  } catch (error) {
159
161
  spinner.fail(c.redBright('Error occurred during client generation'));
@@ -166,7 +168,11 @@ const generateClient = async (spinner: Ora, output: OutputOptions) => {
166
168
  return clientFiles;
167
169
  };
168
170
 
169
- const generateIndex = async (spinner: Ora, output: OutputOptions) => {
171
+ const generateIndex = async (
172
+ spinner: Ora,
173
+ serviceImports: ServiceImportsFactoryOptions,
174
+ output: OutputOptions
175
+ ) => {
170
176
  spinner.start('Generating index');
171
177
 
172
178
  const indexFiles: GeneratorFile[] = [];
@@ -176,12 +182,15 @@ const generateIndex = async (spinner: Ora, output: OutputOptions) => {
176
182
  getIndexFactory({
177
183
  servicesDirName: output.servicesDirName,
178
184
  explicitImportExtensions: Boolean(output.explicitImportExtensions),
185
+ openapiTypesImportPath: output.exportSchemaTypes
186
+ ? serviceImports.openapiTypesImportPath
187
+ : undefined,
179
188
  })
180
189
  );
181
190
 
182
191
  indexFiles.push({
183
192
  file: new URL('index.ts', output.dir),
184
- code: getFileHeader(output) + code,
193
+ code: formatFileHeader(output.fileHeader) + code,
185
194
  });
186
195
  } catch (error) {
187
196
  spinner.fail(c.redBright('Error occurred during index generation'));
@@ -193,9 +202,3 @@ const generateIndex = async (spinner: Ora, output: OutputOptions) => {
193
202
 
194
203
  return indexFiles;
195
204
  };
196
-
197
- export const getFileHeader = ({
198
- fileHeader,
199
- }: Pick<OutputOptions, 'fileHeader'>) => {
200
- return fileHeader && `${fileHeader}\n`;
201
- };
package/src/plugin.ts CHANGED
@@ -9,24 +9,27 @@ export const plugin: QraftCommandPlugin = {
9
9
  command
10
10
  .description('Generate TanStack Query React client from OpenAPI Schema')
11
11
  .requiredOption(
12
- '--openapi-types-import-path <path>', // todo::specify better param name to avoid confusion with real path
13
- 'Path to schema types file (.d.ts), eg: "../openapi.d.ts"'
14
- )
15
- .option(
16
- '--file-header <string>',
17
- 'Header to be added to the generated file (eg: /* eslint-disable */)'
12
+ '--openapi-types-import-path <path>',
13
+ 'Path to schema types file (.d.ts), eg: "../schema.d.ts"'
18
14
  )
19
15
  .option(
20
16
  '--explicit-import-extensions',
21
17
  'All import statements will include explicit `.js` extensions. Ideal for projects using ECMAScript modules.'
22
18
  )
19
+ .option(
20
+ '--export-openapi-types [bool]',
21
+ 'Export the OpenAPI schema types from the generated `./index.ts` file',
22
+ (arg) => {
23
+ return arg?.toLowerCase() !== 'false';
24
+ }
25
+ )
23
26
  .option(
24
27
  '--operation-generics-import-path <path>',
25
28
  'Path to operation generics file',
26
29
  '@openapi-qraft/react'
27
30
  )
28
- .action(({ spinner, output, args, services }, resolve) => {
29
- return void generateCode({
31
+ .action(async ({ spinner, output, args, services }, resolve) => {
32
+ return void (await generateCode({
30
33
  spinner,
31
34
  services,
32
35
  serviceImports: {
@@ -38,8 +41,9 @@ export const plugin: QraftCommandPlugin = {
38
41
  fileHeader: args.fileHeader ?? fileHeader,
39
42
  explicitImportExtensions: args.explicitImportExtensions,
40
43
  servicesDirName: 'services',
44
+ exportSchemaTypes: args.exportOpenapiTypes,
41
45
  },
42
- }).then(resolve);
46
+ }).then(resolve));
43
47
  });
44
48
  },
45
49
  };
@@ -1,16 +1,32 @@
1
1
  import ts from 'typescript';
2
2
 
3
+ import type { ServiceImportsFactoryOptions } from './getServiceFactory.js';
4
+
3
5
  export const getIndexFactory = ({
6
+ openapiTypesImportPath,
4
7
  servicesDirName,
5
8
  explicitImportExtensions,
6
9
  }: {
7
10
  servicesDirName: string;
8
11
  explicitImportExtensions: boolean;
9
- }) => {
12
+ } & Partial<Pick<ServiceImportsFactoryOptions, 'openapiTypesImportPath'>>) => {
10
13
  const factory = ts.factory;
11
14
  const importExtension = explicitImportExtensions ? '.js' : '';
12
15
 
13
16
  return [
17
+ ...(openapiTypesImportPath
18
+ ? [
19
+ factory.createExportDeclaration(
20
+ undefined,
21
+ true,
22
+ undefined,
23
+ factory.createStringLiteral(
24
+ maybeResolveImport({ openapiTypesImportPath, servicesDirName })
25
+ ),
26
+ undefined
27
+ ),
28
+ ]
29
+ : []),
14
30
  factory.createExportDeclaration(
15
31
  undefined,
16
32
  false,
@@ -56,3 +72,23 @@ export const getIndexFactory = ({
56
72
  ),
57
73
  ];
58
74
  };
75
+
76
+ /**
77
+ * Resolve the import path if it's a relative path.
78
+ * Normally,`openapiTypesImportPath` is a relative path to services directory.
79
+ */
80
+ export function maybeResolveImport<T extends string | undefined>({
81
+ openapiTypesImportPath,
82
+ servicesDirName,
83
+ }: {
84
+ openapiTypesImportPath: T;
85
+ servicesDirName: string;
86
+ }) {
87
+ if (openapiTypesImportPath?.startsWith('../')) {
88
+ return `./${openapiTypesImportPath.slice(3)}`;
89
+ } else if (openapiTypesImportPath?.startsWith('./')) {
90
+ return `./${servicesDirName}/${openapiTypesImportPath.slice(2)}`;
91
+ }
92
+
93
+ return openapiTypesImportPath;
94
+ }
@@ -182,6 +182,22 @@ const getOperationSchemaFactory = (operation: ServiceOperation) => {
182
182
  )
183
183
  )
184
184
  : null,
185
+
186
+ operation.security
187
+ ? factory.createPropertySignature(
188
+ undefined,
189
+ factory.createIdentifier('security'),
190
+ undefined,
191
+ factory.createTupleTypeNode(
192
+ getOperationSecuritySchemas(operation.security).map(
193
+ (securitySchemaName) =>
194
+ factory.createLiteralTypeNode(
195
+ factory.createStringLiteral(securitySchemaName)
196
+ )
197
+ )
198
+ )
199
+ )
200
+ : null,
185
201
  ].filter((node): node is NonNullable<typeof node> => Boolean(node))
186
202
  );
187
203
  };
@@ -382,6 +398,18 @@ const getServiceVariablePropertyFactory = (operation: ServiceOperation) => {
382
398
  factory.createStringLiteral(operation.mediaType)
383
399
  )
384
400
  : null,
401
+
402
+ operation.security
403
+ ? factory.createPropertyAssignment(
404
+ factory.createIdentifier('security'),
405
+ factory.createArrayLiteralExpression(
406
+ getOperationSecuritySchemas(operation.security).map(
407
+ (securitySchemaName) =>
408
+ factory.createStringLiteral(securitySchemaName)
409
+ )
410
+ )
411
+ )
412
+ : null,
385
413
  ].filter((node): node is NonNullable<typeof node> => Boolean(node)),
386
414
  true
387
415
  )
@@ -408,3 +436,10 @@ const createMultilineComment = (comment: string[]) => {
408
436
 
409
437
  return '';
410
438
  };
439
+
440
+ const getOperationSecuritySchemas = (
441
+ security: NonNullable<ServiceOperation['security']>
442
+ ) =>
443
+ security.flatMap((security) =>
444
+ Object.keys(security).map((securitySchemaName) => securitySchemaName)
445
+ );
@@ -1 +0,0 @@
1
- export default function (): void;