From bf1e52182b636cef8c2cd54bcb123baf47d2d624 Mon Sep 17 00:00:00 2001 From: Stijn Van Hulle Date: Sun, 21 Jan 2024 19:36:03 +0100 Subject: [PATCH] Correct import when refs are using . syntax(creating subfolders) (#796) * fix: remove use of ts namespace * chore: update examples * fix: A schema name with `pet.Pets` will be moved inside of the folder `src/gen/pet/pets/ts` instead of `src/gen/petPets.ts` * chore: update examples * chore: fix examples * chore: fix plugin zod --- .changeset/perfect-trees-juggle.md | 6 +++ examples/advanced/petStore.yaml | 6 +-- .../src/gen/mocks/createAddPetRequest.ts | 4 +- examples/advanced/src/gen/mocks/createPet.ts | 4 +- examples/advanced/src/gen/mocks/index.ts | 2 +- .../src/gen/mocks/{ => tag}/createTag.ts | 4 +- examples/advanced/src/gen/mocks/tag/index.ts | 1 + .../src/gen/models/ts/AddPetRequest.ts | 4 +- examples/advanced/src/gen/models/ts/Pet.ts | 4 +- examples/advanced/src/gen/models/ts/index.ts | 2 +- .../src/gen/models/ts/{ => tag}/Tag.ts | 2 +- .../advanced/src/gen/models/ts/tag/index.ts | 1 + .../src/gen/schemas/AddPetRequest.json | 2 +- examples/advanced/src/gen/schemas/Pet.json | 2 +- .../gen/schemas/{Tag.json => tag.Tag.json} | 2 +- .../src/gen/schemas2/AddPetRequest.json | 2 +- examples/advanced/src/gen/schemas2/Pet.json | 2 +- .../gen/schemas2/{Tag.json => tag.Tag.json} | 2 +- .../src/gen/zod/addPetRequestSchema.ts | 4 +- examples/advanced/src/gen/zod/index.ts | 2 +- examples/advanced/src/gen/zod/petSchema.ts | 4 +- examples/advanced/src/gen/zod/tag/index.ts | 1 + .../advanced/src/gen/zod/tag/tagSchema.ts | 4 ++ examples/advanced/src/gen/zod/tagSchema.ts | 4 -- packages/core/src/transformers/casing.test.ts | 26 ++++++++++ packages/core/src/transformers/casing.ts | 38 +++++++++++++-- packages/core/src/transformers/index.ts | 5 +- packages/swagger-client/src/plugin.ts | 2 +- packages/swagger-faker/src/FakerGenerator.ts | 31 +++++++----- packages/swagger-faker/src/plugin.ts | 2 +- packages/swagger-msw/src/components/Mock.tsx | 2 +- packages/swagger-msw/src/plugin.ts | 2 +- packages/swagger-swr/src/plugin.ts | 2 +- packages/swagger-tanstack-query/src/plugin.ts | 4 +- packages/swagger-ts/src/TypeGenerator.ts | 3 +- .../OperationGenerator.test.tsx.snap | 20 ++++---- packages/swagger-ts/src/plugin.ts | 2 +- packages/swagger-zod/src/ZodGenerator.ts | 47 ++++++++++--------- packages/swagger-zod/src/plugin.ts | 2 +- packages/swagger-zodios/src/plugin.ts | 4 +- packages/swagger/src/hooks/useOperation.ts | 2 +- packages/swagger/src/plugin.ts | 12 ++++- 42 files changed, 181 insertions(+), 96 deletions(-) create mode 100644 .changeset/perfect-trees-juggle.md rename examples/advanced/src/gen/mocks/{ => tag}/createTag.ts (51%) create mode 100644 examples/advanced/src/gen/mocks/tag/index.ts rename examples/advanced/src/gen/models/ts/{ => tag}/Tag.ts (84%) create mode 100644 examples/advanced/src/gen/models/ts/tag/index.ts rename examples/advanced/src/gen/schemas/{Tag.json => tag.Tag.json} (81%) rename examples/advanced/src/gen/schemas2/{Tag.json => tag.Tag.json} (81%) create mode 100644 examples/advanced/src/gen/zod/tag/index.ts create mode 100644 examples/advanced/src/gen/zod/tag/tagSchema.ts delete mode 100644 examples/advanced/src/gen/zod/tagSchema.ts create mode 100644 packages/core/src/transformers/casing.test.ts diff --git a/.changeset/perfect-trees-juggle.md b/.changeset/perfect-trees-juggle.md new file mode 100644 index 000000000..b7c9d9a47 --- /dev/null +++ b/.changeset/perfect-trees-juggle.md @@ -0,0 +1,6 @@ +--- +"@kubb/swagger-ts": patch +"@kubb/core": patch +--- + +A schema name with `pet.Pets` will be moved inside of the folder `src/gen/pet/pets/ts` instead of `src/gen/petPets.ts` diff --git a/examples/advanced/petStore.yaml b/examples/advanced/petStore.yaml index 214067980..57f92a090 100644 --- a/examples/advanced/petStore.yaml +++ b/examples/advanced/petStore.yaml @@ -810,7 +810,7 @@ components: example: 1 xml: name: user - Tag: + tag.Tag: type: object properties: id: @@ -851,7 +851,7 @@ components: xml: wrapped: true items: - $ref: "#/components/schemas/Tag" + $ref: "#/components/schemas/tag.Tag" status: type: string description: pet status in the store @@ -889,7 +889,7 @@ components: xml: wrapped: true items: - $ref: "#/components/schemas/Tag" + $ref: "#/components/schemas/tag.Tag" status: type: string description: pet status in the store diff --git a/examples/advanced/src/gen/mocks/createAddPetRequest.ts b/examples/advanced/src/gen/mocks/createAddPetRequest.ts index b6155abe1..46fa0bcc7 100644 --- a/examples/advanced/src/gen/mocks/createAddPetRequest.ts +++ b/examples/advanced/src/gen/mocks/createAddPetRequest.ts @@ -1,5 +1,5 @@ import { createCategory } from './createCategory' -import { createTag } from './createTag' +import { createTagTag } from './tag/createTag' import { faker } from '@faker-js/faker' import type { AddPetRequest } from '../models/ts/AddPetRequest' @@ -9,7 +9,7 @@ export function createAddPetRequest(): NonNullable { 'name': faker.string.alpha(), 'category': createCategory(), 'photoUrls': faker.helpers.arrayElements([faker.string.alpha()]) as any, - 'tags': faker.helpers.arrayElements([createTag()]) as any, + 'tags': faker.helpers.arrayElements([createTagTag()]) as any, 'status': faker.helpers.arrayElement([`available`, `pending`, `sold`]), } } diff --git a/examples/advanced/src/gen/mocks/createPet.ts b/examples/advanced/src/gen/mocks/createPet.ts index 7aeee5d29..0e4335869 100644 --- a/examples/advanced/src/gen/mocks/createPet.ts +++ b/examples/advanced/src/gen/mocks/createPet.ts @@ -1,5 +1,5 @@ import { createCategory } from './createCategory' -import { createTag } from './createTag' +import { createTagTag } from './tag/createTag' import { faker } from '@faker-js/faker' import type { Pet } from '../models/ts/Pet' @@ -9,7 +9,7 @@ export function createPet(): NonNullable { 'name': faker.string.alpha(), 'category': createCategory(), 'photoUrls': faker.helpers.arrayElements([faker.string.alpha()]) as any, - 'tags': faker.helpers.arrayElements([createTag()]) as any, + 'tags': faker.helpers.arrayElements([createTagTag()]) as any, 'status': faker.helpers.arrayElement([`available`, `pending`, `sold`]), } } diff --git a/examples/advanced/src/gen/mocks/index.ts b/examples/advanced/src/gen/mocks/index.ts index 991e8f571..e0d89ec0a 100644 --- a/examples/advanced/src/gen/mocks/index.ts +++ b/examples/advanced/src/gen/mocks/index.ts @@ -6,9 +6,9 @@ export * from './createCustomer' export * from './createOrder' export * from './createPet' export * from './createPetNotFound' -export * from './createTag' export * from './createUser' export * from './createUserArray' +export * from './tag/index' export * as petsMocks from './petsController/index' export * as petMocks from './petController/index' export * as userMocks from './userController/index' diff --git a/examples/advanced/src/gen/mocks/createTag.ts b/examples/advanced/src/gen/mocks/tag/createTag.ts similarity index 51% rename from examples/advanced/src/gen/mocks/createTag.ts rename to examples/advanced/src/gen/mocks/tag/createTag.ts index d5d5736d9..887a2b193 100644 --- a/examples/advanced/src/gen/mocks/createTag.ts +++ b/examples/advanced/src/gen/mocks/tag/createTag.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker' -import type { Tag } from '../models/ts/Tag' +import type { TagTag } from '../../models/ts/tag/Tag' -export function createTag(): NonNullable { +export function createTagTag(): NonNullable { return { 'id': faker.number.float({}), 'name': faker.string.alpha() } } diff --git a/examples/advanced/src/gen/mocks/tag/index.ts b/examples/advanced/src/gen/mocks/tag/index.ts new file mode 100644 index 000000000..0e9c9fc81 --- /dev/null +++ b/examples/advanced/src/gen/mocks/tag/index.ts @@ -0,0 +1 @@ +export * from './createTag' diff --git a/examples/advanced/src/gen/models/ts/AddPetRequest.ts b/examples/advanced/src/gen/models/ts/AddPetRequest.ts index 0fb07cfa9..e2874133e 100644 --- a/examples/advanced/src/gen/models/ts/AddPetRequest.ts +++ b/examples/advanced/src/gen/models/ts/AddPetRequest.ts @@ -1,5 +1,5 @@ import type { Category } from './Category' -import type { Tag } from './Tag' +import type { TagTag } from './tag/Tag' export const AddPetRequestStatus = { 'available': 'available', @@ -26,7 +26,7 @@ export type AddPetRequest = { /** * @type array | undefined */ - tags?: Tag[] + tags?: TagTag[] /** * @description pet status in the store * @type string | undefined diff --git a/examples/advanced/src/gen/models/ts/Pet.ts b/examples/advanced/src/gen/models/ts/Pet.ts index 9cbdc42e2..67c515d37 100644 --- a/examples/advanced/src/gen/models/ts/Pet.ts +++ b/examples/advanced/src/gen/models/ts/Pet.ts @@ -1,5 +1,5 @@ import type { Category } from './Category' -import type { Tag } from './Tag' +import type { TagTag } from './tag/Tag' export const PetStatus = { 'available': 'available', @@ -26,7 +26,7 @@ export type Pet = { /** * @type array | undefined */ - tags?: Tag[] + tags?: TagTag[] /** * @description pet status in the store * @type string | undefined diff --git a/examples/advanced/src/gen/models/ts/index.ts b/examples/advanced/src/gen/models/ts/index.ts index 0ac662d13..1251cd573 100644 --- a/examples/advanced/src/gen/models/ts/index.ts +++ b/examples/advanced/src/gen/models/ts/index.ts @@ -9,7 +9,7 @@ export * from './petController/index.js' export * from './PetNotFound.js' export * from './petsController/index.js' export * from './storeController/index.js' -export * from './Tag.js' +export * from './tag/index.js' export * from './User.js' export * from './UserArray.js' export * from './userController/index.js' diff --git a/examples/advanced/src/gen/models/ts/Tag.ts b/examples/advanced/src/gen/models/ts/tag/Tag.ts similarity index 84% rename from examples/advanced/src/gen/models/ts/Tag.ts rename to examples/advanced/src/gen/models/ts/tag/Tag.ts index 5145ac12c..4d03c8601 100644 --- a/examples/advanced/src/gen/models/ts/Tag.ts +++ b/examples/advanced/src/gen/models/ts/tag/Tag.ts @@ -1,4 +1,4 @@ -export type Tag = { +export type TagTag = { /** * @type integer | undefined int64 */ diff --git a/examples/advanced/src/gen/models/ts/tag/index.ts b/examples/advanced/src/gen/models/ts/tag/index.ts new file mode 100644 index 000000000..bdf170b8f --- /dev/null +++ b/examples/advanced/src/gen/models/ts/tag/index.ts @@ -0,0 +1 @@ +export * from './Tag.js' diff --git a/examples/advanced/src/gen/schemas/AddPetRequest.json b/examples/advanced/src/gen/schemas/AddPetRequest.json index c25915adc..324697512 100644 --- a/examples/advanced/src/gen/schemas/AddPetRequest.json +++ b/examples/advanced/src/gen/schemas/AddPetRequest.json @@ -18,7 +18,7 @@ "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" } }, "xml": { "name": "tag" }, - "x-readme-ref-name": "Tag" + "x-readme-ref-name": "tag.Tag" } }, "status": { "type": "string", "description": "pet status in the store", "enum": ["available", "pending", "sold"] } diff --git a/examples/advanced/src/gen/schemas/Pet.json b/examples/advanced/src/gen/schemas/Pet.json index 61744e162..039034944 100644 --- a/examples/advanced/src/gen/schemas/Pet.json +++ b/examples/advanced/src/gen/schemas/Pet.json @@ -18,7 +18,7 @@ "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" } }, "xml": { "name": "tag" }, - "x-readme-ref-name": "Tag" + "x-readme-ref-name": "tag.Tag" } }, "status": { "type": "string", "description": "pet status in the store", "enum": ["available", "pending", "sold"] } diff --git a/examples/advanced/src/gen/schemas/Tag.json b/examples/advanced/src/gen/schemas/tag.Tag.json similarity index 81% rename from examples/advanced/src/gen/schemas/Tag.json rename to examples/advanced/src/gen/schemas/tag.Tag.json index 7ae9c9e7d..97ab1f7b3 100644 --- a/examples/advanced/src/gen/schemas/Tag.json +++ b/examples/advanced/src/gen/schemas/tag.Tag.json @@ -2,5 +2,5 @@ "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" } }, "xml": { "name": "tag" }, - "x-readme-ref-name": "Tag" + "x-readme-ref-name": "tag.Tag" } diff --git a/examples/advanced/src/gen/schemas2/AddPetRequest.json b/examples/advanced/src/gen/schemas2/AddPetRequest.json index c25915adc..324697512 100644 --- a/examples/advanced/src/gen/schemas2/AddPetRequest.json +++ b/examples/advanced/src/gen/schemas2/AddPetRequest.json @@ -18,7 +18,7 @@ "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" } }, "xml": { "name": "tag" }, - "x-readme-ref-name": "Tag" + "x-readme-ref-name": "tag.Tag" } }, "status": { "type": "string", "description": "pet status in the store", "enum": ["available", "pending", "sold"] } diff --git a/examples/advanced/src/gen/schemas2/Pet.json b/examples/advanced/src/gen/schemas2/Pet.json index 61744e162..039034944 100644 --- a/examples/advanced/src/gen/schemas2/Pet.json +++ b/examples/advanced/src/gen/schemas2/Pet.json @@ -18,7 +18,7 @@ "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" } }, "xml": { "name": "tag" }, - "x-readme-ref-name": "Tag" + "x-readme-ref-name": "tag.Tag" } }, "status": { "type": "string", "description": "pet status in the store", "enum": ["available", "pending", "sold"] } diff --git a/examples/advanced/src/gen/schemas2/Tag.json b/examples/advanced/src/gen/schemas2/tag.Tag.json similarity index 81% rename from examples/advanced/src/gen/schemas2/Tag.json rename to examples/advanced/src/gen/schemas2/tag.Tag.json index 7ae9c9e7d..97ab1f7b3 100644 --- a/examples/advanced/src/gen/schemas2/Tag.json +++ b/examples/advanced/src/gen/schemas2/tag.Tag.json @@ -2,5 +2,5 @@ "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" } }, "xml": { "name": "tag" }, - "x-readme-ref-name": "Tag" + "x-readme-ref-name": "tag.Tag" } diff --git a/examples/advanced/src/gen/zod/addPetRequestSchema.ts b/examples/advanced/src/gen/zod/addPetRequestSchema.ts index 5b2e6d7d7..aa77cf922 100644 --- a/examples/advanced/src/gen/zod/addPetRequestSchema.ts +++ b/examples/advanced/src/gen/zod/addPetRequestSchema.ts @@ -1,5 +1,5 @@ import { categorySchema } from './categorySchema' -import { tagSchema } from './tagSchema' +import { tagTagSchema } from './tag/tagSchema' import { z } from 'zod' import type { AddPetRequest } from '../models/ts/AddPetRequest' @@ -8,6 +8,6 @@ export const addPetRequestSchema: z.ZodType = z.object({ 'name': z.string(), 'category': z.lazy(() => categorySchema).optional(), 'photoUrls': z.array(z.string()), - 'tags': z.array(z.lazy(() => tagSchema)).optional(), + 'tags': z.array(z.lazy(() => tagTagSchema)).optional(), 'status': z.enum([`available`, `pending`, `sold`]).describe(`pet status in the store`).optional(), }) diff --git a/examples/advanced/src/gen/zod/index.ts b/examples/advanced/src/gen/zod/index.ts index 46c453a44..f09682b9d 100644 --- a/examples/advanced/src/gen/zod/index.ts +++ b/examples/advanced/src/gen/zod/index.ts @@ -8,7 +8,7 @@ export * as petSchemas from './petController/index' export * from './petNotFoundSchema' export * from './petSchema' export * as petsSchemas from './petsController/index' -export * from './tagSchema' +export * from './tag/index' export * from './userArraySchema' export * as userSchemas from './userController/index' export * from './userSchema' diff --git a/examples/advanced/src/gen/zod/petSchema.ts b/examples/advanced/src/gen/zod/petSchema.ts index d496ea5b7..71149f07a 100644 --- a/examples/advanced/src/gen/zod/petSchema.ts +++ b/examples/advanced/src/gen/zod/petSchema.ts @@ -1,5 +1,5 @@ import { categorySchema } from './categorySchema' -import { tagSchema } from './tagSchema' +import { tagTagSchema } from './tag/tagSchema' import { z } from 'zod' import type { Pet } from '../models/ts/Pet' @@ -8,6 +8,6 @@ export const petSchema: z.ZodType = z.object({ 'name': z.string(), 'category': z.lazy(() => categorySchema).optional(), 'photoUrls': z.array(z.string()), - 'tags': z.array(z.lazy(() => tagSchema)).optional(), + 'tags': z.array(z.lazy(() => tagTagSchema)).optional(), 'status': z.enum([`available`, `pending`, `sold`]).describe(`pet status in the store`).optional(), }) diff --git a/examples/advanced/src/gen/zod/tag/index.ts b/examples/advanced/src/gen/zod/tag/index.ts new file mode 100644 index 000000000..829f2ec12 --- /dev/null +++ b/examples/advanced/src/gen/zod/tag/index.ts @@ -0,0 +1 @@ +export * from './tagSchema' diff --git a/examples/advanced/src/gen/zod/tag/tagSchema.ts b/examples/advanced/src/gen/zod/tag/tagSchema.ts new file mode 100644 index 000000000..7380033c0 --- /dev/null +++ b/examples/advanced/src/gen/zod/tag/tagSchema.ts @@ -0,0 +1,4 @@ +import { z } from 'zod' +import type { TagTag } from '../../models/ts/tag/Tag' + +export const tagTagSchema: z.ZodType = z.object({ 'id': z.number().optional(), 'name': z.string().optional() }) diff --git a/examples/advanced/src/gen/zod/tagSchema.ts b/examples/advanced/src/gen/zod/tagSchema.ts deleted file mode 100644 index d8a4b5c18..000000000 --- a/examples/advanced/src/gen/zod/tagSchema.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { z } from 'zod' -import type { Tag } from '../models/ts/Tag' - -export const tagSchema: z.ZodType = z.object({ 'id': z.number().optional(), 'name': z.string().optional() }) diff --git a/packages/core/src/transformers/casing.test.ts b/packages/core/src/transformers/casing.test.ts new file mode 100644 index 000000000..b5b51b46c --- /dev/null +++ b/packages/core/src/transformers/casing.test.ts @@ -0,0 +1,26 @@ +import { camelCase, pascalCase, pathCase } from './casing.ts' + +describe('casing', () => { + test('camelCase', () => { + expect(camelCase('pet pet')).toBe('petPet') + expect(camelCase('pet.Pet', { isFile: true })).toBe('pet/pet') + expect(camelCase('create tag.tag', { isFile: true })).toBe('createTag/tag') + expect(camelCase('tag.tag', { isFile: true, prefix: 'create' })).toBe('tag/createTag') + expect(camelCase('tag.tag', { isFile: true, suffix: 'schema' })).toBe('tag/tagSchema') + }) + test('pascalCase', () => { + expect(pascalCase('pet pet')).toBe('PetPet') + expect(pascalCase('pet.Pet', { isFile: true })).toBe('pet/Pet') + expect(pascalCase('create tag.tag', { isFile: true })).toBe('createTag/Tag') + expect(pascalCase('tag.tag', { isFile: true, prefix: 'create' })).toBe('tag/CreateTag') + expect(pascalCase('tag.tag', { isFile: true, suffix: 'schema' })).toBe('tag/TagSchema') + }) + + test('pathCase', () => { + expect(pathCase('pet pet')).toBe('petpet') + expect(pathCase('pet.Pet', { isFile: true })).toBe('pet/pet') + expect(pathCase('create tag.tag', { isFile: true })).toBe('createTag/tag') + expect(pathCase('tag.tag', { isFile: true, prefix: 'create' })).toBe('tag/createtag') + expect(pathCase('tag.tag', { isFile: true, suffix: 'schema' })).toBe('tag/tagschema') + }) +}) diff --git a/packages/core/src/transformers/casing.ts b/packages/core/src/transformers/casing.ts index bb96386fd..1c30e6be0 100644 --- a/packages/core/src/transformers/casing.ts +++ b/packages/core/src/transformers/casing.ts @@ -1,9 +1,37 @@ -import { camelCase as changeCaseCamel, pascalCase as changePascalCase } from 'change-case' +import { camelCase as changeCamelCase, pascalCase as changePascalCase, pathCase as changePathCase } from 'change-case' -export function camelCase(text: string): string { - return changeCaseCamel(text, { delimiter: '', mergeAmbiguousCharacters: true }) +type Options = { + /** + * When set it will replace all `.` with `/`. + */ + isFile?: boolean + prefix?: string + suffix?: string } -export function pascalCase(text: string): string { - return changePascalCase(text, { delimiter: '', mergeAmbiguousCharacters: true }) +export function camelCase(text: string, { isFile, prefix = '', suffix = '' }: Options = {}): string { + if (isFile) { + const splitArray = text.split('.') + return splitArray.map((item, i) => i === splitArray.length - 1 ? camelCase(item, { prefix, suffix }) : camelCase(item)).join('/') + } + + return changeCamelCase(`${prefix} ${text} ${suffix}`, { delimiter: '', mergeAmbiguousCharacters: true }) +} + +export function pascalCase(text: string, { isFile, prefix = '', suffix = '' }: Options = {}): string { + if (isFile) { + const splitArray = text.split('.') + return splitArray.map((item, i) => i === splitArray.length - 1 ? pascalCase(item, { prefix, suffix }) : camelCase(item)).join('/') + } + + return changePascalCase(`${prefix} ${text} ${suffix}`, { delimiter: '', mergeAmbiguousCharacters: true }) +} + +export function pathCase(text: string, { isFile, prefix = '', suffix = '' }: Options = {}): string { + if (isFile) { + const splitArray = text.split('.') + return splitArray.map((item, i) => i === splitArray.length - 1 ? pathCase(item, { prefix, suffix }) : camelCase(item)).join('/') + } + + return changePathCase(`${prefix} ${text} ${suffix}`, { delimiter: '' }) } diff --git a/packages/core/src/transformers/index.ts b/packages/core/src/transformers/index.ts index ad4b5ffa1..42f9463e5 100644 --- a/packages/core/src/transformers/index.ts +++ b/packages/core/src/transformers/index.ts @@ -1,4 +1,4 @@ -import { camelCase, pascalCase } from './casing.ts' +import { camelCase, pascalCase, pathCase } from './casing.ts' import { combineCodes } from './combineCodes.ts' import { createJSDocBlockText } from './createJSDocBlockText.ts' import { escape, jsStringEscape } from './escape.ts' @@ -8,7 +8,7 @@ import { searchAndReplace } from './searchAndReplace.ts' import { transformReservedWord } from './transformReservedWord.ts' import { trim, trimExtName } from './trim.ts' -export { camelCase, pascalCase } from './casing.ts' +export { camelCase, pascalCase, pathCase } from './casing.ts' export { combineCodes } from './combineCodes.ts' export { createJSDocBlockText } from './createJSDocBlockText.ts' export { escape, jsStringEscape } from './escape.ts' @@ -33,4 +33,5 @@ export default { }, camelCase, pascalCase, + pathCase, } as const diff --git a/packages/swagger-client/src/plugin.ts b/packages/swagger-client/src/plugin.ts index 5cb6d18a8..c4534ff3a 100644 --- a/packages/swagger-client/src/plugin.ts +++ b/packages/swagger-client/src/plugin.ts @@ -68,7 +68,7 @@ export const definePlugin = createPlugin((options) => { return path.resolve(root, output.path, baseName) }, resolveName(name, type) { - const resolvedName = camelCase(name) + const resolvedName = camelCase(name, { isFile: type === 'file' }) if (type) { return transformers?.name?.(resolvedName, type) || resolvedName diff --git a/packages/swagger-faker/src/FakerGenerator.ts b/packages/swagger-faker/src/FakerGenerator.ts index 3c73f7570..8309fad5a 100644 --- a/packages/swagger-faker/src/FakerGenerator.ts +++ b/packages/swagger-faker/src/FakerGenerator.ts @@ -62,21 +62,25 @@ export class FakerGenerator extends Generator((options) => { return path.resolve(root, output.path, baseName) }, resolveName(name, type) { - const resolvedName = camelCase(`create ${name}`) + const resolvedName = camelCase(name, { prefix: type ? 'create' : undefined, isFile: type === 'file' }) if (type) { return transformers?.name?.(resolvedName, type) || resolvedName diff --git a/packages/swagger-msw/src/components/Mock.tsx b/packages/swagger-msw/src/components/Mock.tsx index 59fef71a3..5ee5c4804 100644 --- a/packages/swagger-msw/src/components/Mock.tsx +++ b/packages/swagger-msw/src/components/Mock.tsx @@ -102,7 +102,7 @@ Mock.File = function({ templates = defaultTemplates }: FileProps): ReactNode { const schemas = useSchemas() const file = useOperationFile() const fileFaker = useOperationFile({ pluginKey: fakerPluginKey }) - const responseName = useResolveName({ pluginKey: fakerPluginKey, name: schemas.response.name, type: 'type' }) + const responseName = useResolveName({ pluginKey: fakerPluginKey, name: schemas.response.name, type: 'function' }) const isV2 = new PackageManager().isValidSync('msw', '>=2') diff --git a/packages/swagger-msw/src/plugin.ts b/packages/swagger-msw/src/plugin.ts index 58aeaa9c3..c95ad463a 100644 --- a/packages/swagger-msw/src/plugin.ts +++ b/packages/swagger-msw/src/plugin.ts @@ -53,7 +53,7 @@ export const definePlugin = createPlugin((options) => { return path.resolve(root, output.path, baseName) }, resolveName(name, type) { - const resolvedName = camelCase(`${name} Handler`) + const resolvedName = camelCase(name, { suffix: type ? 'handler' : undefined, isFile: type === 'file' }) if (type) { return transformers?.name?.(resolvedName, type) || resolvedName } diff --git a/packages/swagger-swr/src/plugin.ts b/packages/swagger-swr/src/plugin.ts index 737dcde94..9f6f78698 100644 --- a/packages/swagger-swr/src/plugin.ts +++ b/packages/swagger-swr/src/plugin.ts @@ -69,7 +69,7 @@ export const definePlugin = createPlugin((options) => { let resolvedName = camelCase(name) if (type === 'file' || type === 'function') { - resolvedName = camelCase(`use ${name}`) + resolvedName = camelCase(name, { prefix: 'use', isFile: type === 'file' }) } if (type === 'type') { diff --git a/packages/swagger-tanstack-query/src/plugin.ts b/packages/swagger-tanstack-query/src/plugin.ts index e555da9ce..4999d7b18 100644 --- a/packages/swagger-tanstack-query/src/plugin.ts +++ b/packages/swagger-tanstack-query/src/plugin.ts @@ -88,11 +88,11 @@ export const definePlugin = createPlugin((options) => { if (type === 'file' || type === 'function') { if (framework === 'react' || framework === 'vue') { - resolvedName = camelCase(`use ${name}`) + resolvedName = camelCase(name, { prefix: 'use', isFile: type === 'file' }) } if (framework === 'svelte' || framework === 'solid') { - resolvedName = camelCase(`${name} query`) + resolvedName = camelCase(name, { suffix: 'query', isFile: type === 'file' }) } } if (type === 'type') { diff --git a/packages/swagger-ts/src/TypeGenerator.ts b/packages/swagger-ts/src/TypeGenerator.ts index 99ee96e1d..bb655fc92 100644 --- a/packages/swagger-ts/src/TypeGenerator.ts +++ b/packages/swagger-ts/src/TypeGenerator.ts @@ -174,7 +174,8 @@ export class TypeGenerator extends Generator((options) => { return path.resolve(root, output.path, baseName) }, resolveName(name, type) { - const resolvedName = pascalCase(name) + const resolvedName = pascalCase(name, { isFile: type === 'file' }) if (type) { return transformers?.name?.(resolvedName, type) || resolvedName diff --git a/packages/swagger-zod/src/ZodGenerator.ts b/packages/swagger-zod/src/ZodGenerator.ts index 6ea03a6a9..cd61d4a9a 100644 --- a/packages/swagger-zod/src/ZodGenerator.ts +++ b/packages/swagger-zod/src/ZodGenerator.ts @@ -63,31 +63,32 @@ export class ZodGenerator extends Generator((options) => { return path.resolve(root, output.path, baseName) }, resolveName(name, type) { - const resolvedName = camelCase(`${name}Schema`) + const resolvedName = camelCase(name, { suffix: type ? 'schema' : undefined, isFile: type === 'file' }) if (type) { return transformers?.name?.(resolvedName, type) || resolvedName diff --git a/packages/swagger-zodios/src/plugin.ts b/packages/swagger-zodios/src/plugin.ts index 9e59e6017..2fe7aad10 100644 --- a/packages/swagger-zodios/src/plugin.ts +++ b/packages/swagger-zodios/src/plugin.ts @@ -30,8 +30,8 @@ export const definePlugin = createPlugin((options) => { return path.resolve(root, baseName) }, - resolveName(name) { - return camelCase(name) + resolveName(name, type) { + return camelCase(name, { isFile: type === 'file' }) }, async writeFile(source, writePath) { if (!writePath.endsWith('.ts') || !source) { diff --git a/packages/swagger/src/hooks/useOperation.ts b/packages/swagger/src/hooks/useOperation.ts index e03349a24..0a788364e 100644 --- a/packages/swagger/src/hooks/useOperation.ts +++ b/packages/swagger/src/hooks/useOperation.ts @@ -11,7 +11,7 @@ export function useOperation(): Operation { } type UseOperationNameProps = { - type: NonNullable + type: ResolveNameParams['type'] pluginKey?: KubbPlugin['key'] } diff --git a/packages/swagger/src/plugin.ts b/packages/swagger/src/plugin.ts index ee840c3a4..4290153fa 100644 --- a/packages/swagger/src/plugin.ts +++ b/packages/swagger/src/plugin.ts @@ -1,6 +1,7 @@ import path from 'node:path' import { createPlugin } from '@kubb/core' +import { camelCase } from '@kubb/core/transformers' import { getSchemas } from './utils/getSchemas.ts' import { OasManager } from './OasManager.ts' @@ -62,6 +63,9 @@ export const definePlugin = createPlugin((options) => { return path.resolve(root, output.path, baseName) }, + resolveName(name, type) { + return camelCase(name, { isFile: type === 'file' }) + }, async writeFile(source, writePath) { if (!writePath.endsWith('.json') || !source) { return @@ -84,13 +88,19 @@ export const definePlugin = createPlugin((options) => { pluginKey: this.plugin.key, }) + const resvoledFileName = this.resolveName({ + name: `${name}.json`, + pluginKey, + type: 'file', + }) as `${string}.json` + if (!resolvedPath) { return } await this.addFile({ path: resolvedPath, - baseName: `${name}.json`, + baseName: resvoledFileName, source: JSON.stringify(schema), meta: { pluginKey: this.plugin.key,