From 66aaec9b48d9eee1a707b26c87eae844dec5d7b9 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 5 May 2023 16:30:30 -0700 Subject: [PATCH 1/2] fix: zod plugin issue with lower-case model names --- .../schema/src/plugins/zod/transformer.ts | 59 +++++++++++-------- .../tests/regression/issues.test.ts | 14 +++++ 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/packages/schema/src/plugins/zod/transformer.ts b/packages/schema/src/plugins/zod/transformer.ts index 087c7dc75..44e9cc9e3 100644 --- a/packages/schema/src/plugins/zod/transformer.ts +++ b/packages/schema/src/plugins/zod/transformer.ts @@ -3,6 +3,7 @@ import type { DMMF as PrismaDMMF } from '@prisma/generator-helper'; import { AUXILIARY_FIELDS } from '@zenstackhq/sdk'; import { checkModelHasModelRelation, findModelByName, isAggregateInputType } from '@zenstackhq/sdk/dmmf-helpers'; import indentString from '@zenstackhq/sdk/utils'; +import { pascalCase } from 'change-case'; import path from 'path'; import { Project } from 'ts-morph'; import { AggregateOperationSupport, TransformerParams } from './types'; @@ -425,9 +426,13 @@ export default class Transformer { `import { ${modelName}WhereInputObjectSchema } from './objects/${modelName}WhereInput.schema'`, `import { ${modelName}OrderByWithRelationInputObjectSchema } from './objects/${modelName}OrderByWithRelationInput.schema'`, `import { ${modelName}WhereUniqueInputObjectSchema } from './objects/${modelName}WhereUniqueInput.schema'`, - `import { ${modelName}ScalarFieldEnumSchema } from './enums/${modelName}ScalarFieldEnum.schema'` + `import { ${pascalCase(modelName)}ScalarFieldEnumSchema } from './enums/${pascalCase( + modelName + )}ScalarFieldEnum.schema'` ); - codeBody += `findFirst: z.object({ ${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithRelationInputObjectSchema, ${modelName}OrderByWithRelationInputObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), distinct: z.array(${modelName}ScalarFieldEnumSchema).optional() }),`; + codeBody += `findFirst: z.object({ ${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithRelationInputObjectSchema, ${modelName}OrderByWithRelationInputObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), distinct: z.array(${pascalCase( + modelName + )}ScalarFieldEnumSchema).optional() }),`; } if (findMany) { @@ -435,9 +440,13 @@ export default class Transformer { `import { ${modelName}WhereInputObjectSchema } from './objects/${modelName}WhereInput.schema'`, `import { ${modelName}OrderByWithRelationInputObjectSchema } from './objects/${modelName}OrderByWithRelationInput.schema'`, `import { ${modelName}WhereUniqueInputObjectSchema } from './objects/${modelName}WhereUniqueInput.schema'`, - `import { ${modelName}ScalarFieldEnumSchema } from './enums/${modelName}ScalarFieldEnum.schema'` + `import { ${pascalCase(modelName)}ScalarFieldEnumSchema } from './enums/${pascalCase( + modelName + )}ScalarFieldEnum.schema'` ); - codeBody += `findMany: z.object({ ${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithRelationInputObjectSchema, ${modelName}OrderByWithRelationInputObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), distinct: z.array(${modelName}ScalarFieldEnumSchema).optional() }),`; + codeBody += `findMany: z.object({ ${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithRelationInputObjectSchema, ${modelName}OrderByWithRelationInputObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), distinct: z.array(${pascalCase( + modelName + )}ScalarFieldEnumSchema).optional() }),`; } if (createOne) { @@ -494,37 +503,39 @@ export default class Transformer { } const aggregateOperations = []; - if (this.aggregateOperationSupport[modelName].count) { + // DMMF messed up the model name casing used in the aggregate operations, + const modelNameVar = pascalCase(modelName); + if (this.aggregateOperationSupport[modelNameVar]?.count) { imports.push( - `import { ${modelName}CountAggregateInputObjectSchema } from './objects/${modelName}CountAggregateInput.schema'` + `import { ${modelNameVar}CountAggregateInputObjectSchema } from './objects/${modelNameVar}CountAggregateInput.schema'` ); aggregateOperations.push( - `_count: z.union([ z.literal(true), ${modelName}CountAggregateInputObjectSchema ]).optional()` + `_count: z.union([ z.literal(true), ${modelNameVar}CountAggregateInputObjectSchema ]).optional()` ); } - if (this.aggregateOperationSupport[modelName].min) { + if (this.aggregateOperationSupport[modelNameVar]?.min) { imports.push( - `import { ${modelName}MinAggregateInputObjectSchema } from './objects/${modelName}MinAggregateInput.schema'` + `import { ${modelNameVar}MinAggregateInputObjectSchema } from './objects/${modelNameVar}MinAggregateInput.schema'` ); - aggregateOperations.push(`_min: ${modelName}MinAggregateInputObjectSchema.optional()`); + aggregateOperations.push(`_min: ${modelNameVar}MinAggregateInputObjectSchema.optional()`); } - if (this.aggregateOperationSupport[modelName].max) { + if (this.aggregateOperationSupport[modelNameVar]?.max) { imports.push( - `import { ${modelName}MaxAggregateInputObjectSchema } from './objects/${modelName}MaxAggregateInput.schema'` + `import { ${modelNameVar}MaxAggregateInputObjectSchema } from './objects/${modelNameVar}MaxAggregateInput.schema'` ); - aggregateOperations.push(`_max: ${modelName}MaxAggregateInputObjectSchema.optional()`); + aggregateOperations.push(`_max: ${modelNameVar}MaxAggregateInputObjectSchema.optional()`); } - if (this.aggregateOperationSupport[modelName].avg) { + if (this.aggregateOperationSupport[modelNameVar]?.avg) { imports.push( - `import { ${modelName}AvgAggregateInputObjectSchema } from './objects/${modelName}AvgAggregateInput.schema'` + `import { ${modelNameVar}AvgAggregateInputObjectSchema } from './objects/${modelNameVar}AvgAggregateInput.schema'` ); - aggregateOperations.push(`_avg: ${modelName}AvgAggregateInputObjectSchema.optional()`); + aggregateOperations.push(`_avg: ${modelNameVar}AvgAggregateInputObjectSchema.optional()`); } - if (this.aggregateOperationSupport[modelName].sum) { + if (this.aggregateOperationSupport[modelNameVar]?.sum) { imports.push( - `import { ${modelName}SumAggregateInputObjectSchema } from './objects/${modelName}SumAggregateInput.schema'` + `import { ${modelNameVar}SumAggregateInputObjectSchema } from './objects/${modelNameVar}SumAggregateInput.schema'` ); - aggregateOperations.push(`_sum: ${modelName}SumAggregateInputObjectSchema.optional()`); + aggregateOperations.push(`_sum: ${modelNameVar}SumAggregateInputObjectSchema.optional()`); } if (aggregate) { @@ -544,11 +555,13 @@ export default class Transformer { `import { ${modelName}WhereInputObjectSchema } from './objects/${modelName}WhereInput.schema'`, `import { ${modelName}OrderByWithAggregationInputObjectSchema } from './objects/${modelName}OrderByWithAggregationInput.schema'`, `import { ${modelName}ScalarWhereWithAggregatesInputObjectSchema } from './objects/${modelName}ScalarWhereWithAggregatesInput.schema'`, - `import { ${modelName}ScalarFieldEnumSchema } from './enums/${modelName}ScalarFieldEnum.schema'` + `import { ${pascalCase(modelName)}ScalarFieldEnumSchema } from './enums/${pascalCase( + modelName + )}ScalarFieldEnum.schema'` ); - codeBody += `groupBy: z.object({ where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithAggregationInputObjectSchema, ${modelName}OrderByWithAggregationInputObjectSchema.array()]).optional(), having: ${modelName}ScalarWhereWithAggregatesInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), by: z.array(${modelName}ScalarFieldEnumSchema), ${aggregateOperations.join( - ', ' - )} }),`; + codeBody += `groupBy: z.object({ where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithAggregationInputObjectSchema, ${modelName}OrderByWithAggregationInputObjectSchema.array()]).optional(), having: ${modelName}ScalarWhereWithAggregatesInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), by: z.array(${pascalCase( + modelName + )}ScalarFieldEnumSchema), ${aggregateOperations.join(', ')} }),`; } imports = [...new Set(imports)]; diff --git a/tests/integration/tests/regression/issues.test.ts b/tests/integration/tests/regression/issues.test.ts index 6683a9de2..4e33edc7c 100644 --- a/tests/integration/tests/regression/issues.test.ts +++ b/tests/integration/tests/regression/issues.test.ts @@ -54,4 +54,18 @@ describe('GitHub issues regression', () => { expect(queried.posts[0].zenstack_guard).toBeUndefined(); expect(queried.posts[0].zenstack_transaction).toBeUndefined(); }); + + it('issue 389', async () => { + const { withPolicy } = await loadSchema(` + model model { + id String @id @default(uuid()) + value Int + @@allow('read', true) + @@allow('create', value > 0) + } + `); + const db = withPolicy(); + await expect(db.model.create({ data: { value: 0 } })).toBeRejectedByPolicy(); + await expect(db.model.create({ data: { value: 1 } })).toResolveTruthy(); + }); }); From 5111da5e7b61c67e06de4850b5d4b4afdf1bcd2b Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Fri, 5 May 2023 17:19:10 -0700 Subject: [PATCH 2/2] fix name casing issues --- packages/plugins/openapi/package.json | 2 + packages/plugins/openapi/src/generator.ts | 8 +-- packages/plugins/react/package.json | 12 +++-- .../react/src/generator/react-query.ts | 12 +++-- packages/plugins/react/src/generator/swr.ts | 5 +- packages/plugins/trpc/package.json | 2 + packages/plugins/trpc/src/generator.ts | 4 +- packages/runtime/package.json | 2 + .../runtime/src/enhancements/model-meta.ts | 4 +- .../src/enhancements/policy/policy-utils.ts | 12 ++--- packages/schema/package.json | 4 ++ .../access-policy/policy-guard-generator.ts | 4 +- .../access-policy/zod-schema-generator.ts | 4 +- .../schema/src/plugins/model-meta/index.ts | 6 +-- .../schema/src/plugins/zod/transformer.ts | 16 +++--- packages/server/package.json | 2 + packages/server/src/openapi/index.ts | 6 +-- pnpm-lock.yaml | 52 ++++++++++++++++++- 18 files changed, 113 insertions(+), 44 deletions(-) diff --git a/packages/plugins/openapi/package.json b/packages/plugins/openapi/package.json index 3744c94fb..8174a1e69 100644 --- a/packages/plugins/openapi/package.json +++ b/packages/plugins/openapi/package.json @@ -28,6 +28,7 @@ "@zenstackhq/runtime": "workspace:*", "@zenstackhq/sdk": "workspace:*", "change-case": "^4.1.2", + "lower-case-first": "^2.0.2", "openapi-types": "^12.1.0", "tiny-invariant": "^1.3.1", "yaml": "^2.2.1", @@ -38,6 +39,7 @@ "@prisma/internals": "^4.7.1", "@readme/openapi-parser": "^2.4.0", "@types/jest": "^29.5.0", + "@types/lower-case-first": "^1.0.1", "@types/tmp": "^0.2.3", "@typescript-eslint/eslint-plugin": "^5.54.0", "@typescript-eslint/parser": "^5.54.0", diff --git a/packages/plugins/openapi/src/generator.ts b/packages/plugins/openapi/src/generator.ts index e29b4ee68..8e3dd43f0 100644 --- a/packages/plugins/openapi/src/generator.ts +++ b/packages/plugins/openapi/src/generator.ts @@ -18,7 +18,7 @@ import { AggregateOperationSupport, resolveAggregateOperationSupport, } from '@zenstackhq/sdk/dmmf-helpers'; -import { camelCase } from 'change-case'; +import { lowerCaseFirst } from 'lower-case-first'; import * as fs from 'fs'; import type { OpenAPIV3_1 as OAPI } from 'openapi-types'; import * as path from 'path'; @@ -84,7 +84,7 @@ export class OpenAPIGenerator { tags: this.includedModels.map((model) => { const meta = getModelResourceMeta(model); return { - name: camelCase(model.name), + name: lowerCaseFirst(model.name), description: meta?.tagDescription ?? `${model.name} operations`, }; }), @@ -533,7 +533,7 @@ export class OpenAPIGenerator { const def: OAPI.OperationObject = { operationId: `${operation}${model.name}`, description: meta?.description ?? description, - tags: meta?.tags || [camelCase(model.name)], + tags: meta?.tags || [lowerCaseFirst(model.name)], summary: meta?.summary, // security priority: operation-level > model-level > inferred security: meta?.security ?? resourceMeta?.security ?? security, @@ -581,7 +581,7 @@ export class OpenAPIGenerator { } } - result[`${prefix}/${camelCase(model.name)}/${resolvedPath}`] = { + result[`${prefix}/${lowerCaseFirst(model.name)}/${resolvedPath}`] = { [resolvedMethod]: def, }; } diff --git a/packages/plugins/react/package.json b/packages/plugins/react/package.json index 21cd12088..11fef22b7 100644 --- a/packages/plugins/react/package.json +++ b/packages/plugins/react/package.json @@ -28,26 +28,30 @@ "@zenstackhq/sdk": "workspace:*", "change-case": "^4.1.2", "decimal.js": "^10.4.2", + "lower-case-first": "^2.0.2", "superjson": "^1.11.0", - "ts-morph": "^16.0.0" + "ts-morph": "^16.0.0", + "upper-case-first": "^2.0.2" }, "peerDependencies": { + "@tanstack/react-query": "4.x", "react": "^17.0.2 || ^18", "react-dom": "^17.0.2 || ^18", - "swr": "2.x", - "@tanstack/react-query": "4.x" + "swr": "2.x" }, "devDependencies": { "@tanstack/react-query": "^4.28.0", "@types/jest": "^29.5.0", + "@types/lower-case-first": "^1.0.1", "@types/react": "^18.0.26", "@types/tmp": "^0.2.3", + "@types/upper-case-first": "^1.1.2", "@zenstackhq/testtools": "workspace:*", "copyfiles": "^2.4.1", "jest": "^29.5.0", - "rimraf": "^3.0.2", "react": "^17.0.2 || ^18", "react-dom": "^17.0.2 || ^18", + "rimraf": "^3.0.2", "swr": "^2.0.3", "ts-jest": "^29.0.5", "typescript": "^4.9.4" diff --git a/packages/plugins/react/src/generator/react-query.ts b/packages/plugins/react/src/generator/react-query.ts index ca2c379bd..c065e75d8 100644 --- a/packages/plugins/react/src/generator/react-query.ts +++ b/packages/plugins/react/src/generator/react-query.ts @@ -1,9 +1,11 @@ import { DMMF } from '@prisma/generator-helper'; import { PluginError, PluginOptions, createProject, getDataModels, saveProject } from '@zenstackhq/sdk'; import { DataModel, Model } from '@zenstackhq/sdk/ast'; -import { camelCase, paramCase, pascalCase } from 'change-case'; +import { paramCase } from 'change-case'; +import { lowerCaseFirst } from 'lower-case-first'; import * as path from 'path'; import { Project, SourceFile, VariableDeclarationKind } from 'ts-morph'; +import { upperCaseFirst } from 'upper-case-first'; export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.Document) { let outDir = options.output as string; @@ -45,7 +47,7 @@ function generateQueryHook( overrideInputType?: string, overrideTypeParameters?: string[] ) { - const capOperation = pascalCase(operation); + const capOperation = upperCaseFirst(operation); const argsType = overrideInputType ?? `Prisma.${model}${capOperation}Args`; const inputType = `Prisma.SelectSubset`; @@ -71,7 +73,7 @@ function generateQueryHook( func.addStatements([ 'const { endpoint } = useContext(RequestHandlerContext);', - `return request.query<${returnType}>('${model}', \`\${endpoint}/${camelCase( + `return request.query<${returnType}>('${model}', \`\${endpoint}/${lowerCaseFirst( model )}/${operation}\`, args, options);`, ]); @@ -84,7 +86,7 @@ function generateMutationHook( httpVerb: 'post' | 'put' | 'delete', overrideReturnType?: string ) { - const capOperation = pascalCase(operation); + const capOperation = upperCaseFirst(operation); const argsType = `Prisma.${model}${capOperation}Args`; const inputType = `Prisma.SelectSubset`; @@ -119,7 +121,7 @@ function generateMutationHook( initializer: ` request.${httpVerb}Mutation<${argsType}, ${ overrideReturnType ?? model - }>('${model}', \`\${endpoint}/${camelCase(model)}/${operation}\`, options, invalidateQueries) + }>('${model}', \`\${endpoint}/${lowerCaseFirst(model)}/${operation}\`, options, invalidateQueries) `, }, ], diff --git a/packages/plugins/react/src/generator/swr.ts b/packages/plugins/react/src/generator/swr.ts index 5ad536ae7..cd503b18f 100644 --- a/packages/plugins/react/src/generator/swr.ts +++ b/packages/plugins/react/src/generator/swr.ts @@ -8,7 +8,8 @@ import { saveProject, } from '@zenstackhq/sdk'; import { DataModel, Model } from '@zenstackhq/sdk/ast'; -import { camelCase, paramCase } from 'change-case'; +import { paramCase } from 'change-case'; +import { lowerCaseFirst } from 'lower-case-first'; import * as path from 'path'; import { Project } from 'ts-morph'; @@ -79,7 +80,7 @@ function generateModelHooks(project: Project, outDir: string, model: DataModel, }); const prefixesToMutate = ['find', 'aggregate', 'count', 'groupBy']; - const modelRouteName = camelCase(model.name); + const modelRouteName = lowerCaseFirst(model.name); useFunc.addStatements([ 'const { endpoint } = useContext(RequestHandlerContext);', diff --git a/packages/plugins/trpc/package.json b/packages/plugins/trpc/package.json index 45905e994..867830da2 100644 --- a/packages/plugins/trpc/package.json +++ b/packages/plugins/trpc/package.json @@ -28,6 +28,7 @@ "@prisma/internals": "^4.7.1", "@zenstackhq/sdk": "workspace:*", "change-case": "^4.1.2", + "lower-case-first": "^2.0.2", "prettier": "^2.8.3", "ts-morph": "^16.0.0", "tslib": "^2.4.1", @@ -35,6 +36,7 @@ }, "devDependencies": { "@types/jest": "^29.5.0", + "@types/lower-case-first": "^1.0.1", "@types/prettier": "^2.7.2", "@zenstackhq/testtools": "workspace:*", "copyfiles": "^2.4.1", diff --git a/packages/plugins/trpc/src/generator.ts b/packages/plugins/trpc/src/generator.ts index 29bf6c743..95c4d6f56 100644 --- a/packages/plugins/trpc/src/generator.ts +++ b/packages/plugins/trpc/src/generator.ts @@ -1,7 +1,7 @@ import { DMMF } from '@prisma/generator-helper'; import { CrudFailureReason, PluginError, PluginOptions, RUNTIME_PACKAGE, saveProject } from '@zenstackhq/sdk'; import { Model } from '@zenstackhq/sdk/ast'; -import { camelCase } from 'change-case'; +import { lowerCaseFirst } from 'lower-case-first'; import { promises as fs } from 'fs'; import path from 'path'; import { Project } from 'ts-morph'; @@ -116,7 +116,7 @@ function createAppRouter(outDir: string, modelOperations: DMMF.ModelMapping[], h moduleSpecifier: `./${model}.router`, }); - writer.writeLine(`${camelCase(model)}: create${model}Router(router, procedure),`); + writer.writeLine(`${lowerCaseFirst(model)}: create${model}Router(router, procedure),`); } }); writer.write(');'); diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 1b30261c4..217fb4b8b 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -28,6 +28,7 @@ "colors": "1.4.0", "decimal.js": "^10.4.2", "deepcopy": "^2.1.0", + "lower-case-first": "^2.0.2", "pluralize": "^8.0.0", "superjson": "^1.11.0", "tslib": "^2.4.1", @@ -45,6 +46,7 @@ "devDependencies": { "@types/bcryptjs": "^2.4.2", "@types/jest": "^29.5.0", + "@types/lower-case-first": "^1.0.1", "@types/node": "^14.18.29", "@types/pluralize": "^0.0.29", "copyfiles": "^2.4.1", diff --git a/packages/runtime/src/enhancements/model-meta.ts b/packages/runtime/src/enhancements/model-meta.ts index 719880f15..40ab077b6 100644 --- a/packages/runtime/src/enhancements/model-meta.ts +++ b/packages/runtime/src/enhancements/model-meta.ts @@ -1,4 +1,4 @@ -import { camelCase } from 'change-case'; +import { lowerCaseFirst } from 'lower-case-first'; import { ModelMeta } from './types'; /** @@ -17,5 +17,5 @@ export function getDefaultModelMeta(): ModelMeta { * Resolves a model field to its metadata. Returns undefined if not found. */ export function resolveField(modelMeta: ModelMeta, model: string, field: string) { - return modelMeta.fields[camelCase(model)][field]; + return modelMeta.fields[lowerCaseFirst(model)][field]; } diff --git a/packages/runtime/src/enhancements/policy/policy-utils.ts b/packages/runtime/src/enhancements/policy/policy-utils.ts index de5c9c721..734729fcb 100644 --- a/packages/runtime/src/enhancements/policy/policy-utils.ts +++ b/packages/runtime/src/enhancements/policy/policy-utils.ts @@ -3,7 +3,7 @@ import { createId } from '@paralleldrive/cuid2'; import { PrismaClientKnownRequestError, PrismaClientUnknownRequestError } from '@prisma/client/runtime'; import { AUXILIARY_FIELDS, CrudFailureReason, GUARD_FIELD_NAME, TRANSACTION_FIELD_NAME } from '@zenstackhq/sdk'; -import { camelCase } from 'change-case'; +import { lowerCaseFirst } from 'lower-case-first'; import deepcopy from 'deepcopy'; import pluralize from 'pluralize'; import { fromZodError } from 'zod-validation-error'; @@ -97,7 +97,7 @@ export class PolicyUtil { * otherwise returns a guard object */ async getAuthGuard(model: string, operation: PolicyOperationKind, preValue?: any): Promise { - const guard = this.policy.guard[camelCase(model)]; + const guard = this.policy.guard[lowerCaseFirst(model)]; if (!guard) { throw this.unknownError(`unable to load policy guard for ${model}`); } @@ -114,7 +114,7 @@ export class PolicyUtil { } private async getPreValueSelect(model: string): Promise { - const guard = this.policy.guard[camelCase(model)]; + const guard = this.policy.guard[lowerCaseFirst(model)]; if (!guard) { throw this.unknownError(`unable to load policy guard for ${model}`); } @@ -122,7 +122,7 @@ export class PolicyUtil { } private async getModelSchema(model: string) { - return this.policy.schema[camelCase(model)]; + return this.policy.schema[lowerCaseFirst(model)]; } /** @@ -255,7 +255,7 @@ export class PolicyUtil { // flatten unique constraint filters async flattenGeneratedUniqueField(model: string, args: any) { // e.g.: { a_b: { a: '1', b: '1' } } => { a: '1', b: '1' } - const uniqueConstraints = this.modelMeta.uniqueConstraints?.[camelCase(model)]; + const uniqueConstraints = this.modelMeta.uniqueConstraints?.[lowerCaseFirst(model)]; let flattened = false; if (uniqueConstraints) { for (const [field, value] of Object.entries(args)) { @@ -856,7 +856,7 @@ export class PolicyUtil { * Gets "id" field for a given model. */ getIdFields(model: string) { - const fields = this.modelMeta.fields[camelCase(model)]; + const fields = this.modelMeta.fields[lowerCaseFirst(model)]; if (!fields) { throw this.unknownError(`Unable to load fields for ${model}`); } diff --git a/packages/schema/package.json b/packages/schema/package.json index b46808e18..58cdef241 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -94,6 +94,7 @@ "commander": "^8.3.0", "get-latest-version": "^5.0.1", "langium": "1.1.0", + "lower-case-first": "^2.0.2", "mixpanel": "^0.17.0", "node-machine-id": "^1.1.12", "ora": "^5.4.1", @@ -102,6 +103,7 @@ "semver": "^7.3.8", "sleep-promise": "^9.1.0", "ts-morph": "^16.0.0", + "upper-case-first": "^2.0.2", "uuid": "^9.0.0", "vscode-jsonrpc": "^8.0.2", "vscode-languageclient": "^8.0.2", @@ -114,10 +116,12 @@ "devDependencies": { "@types/async-exit-hook": "^2.0.0", "@types/jest": "^29.5.0", + "@types/lower-case-first": "^1.0.1", "@types/node": "^14.18.32", "@types/pluralize": "^0.0.29", "@types/semver": "^7.3.13", "@types/tmp": "^0.2.3", + "@types/upper-case-first": "^1.1.2", "@types/uuid": "^8.3.4", "@types/vscode": "^1.56.0", "@typescript-eslint/eslint-plugin": "^5.42.0", diff --git a/packages/schema/src/plugins/access-policy/policy-guard-generator.ts b/packages/schema/src/plugins/access-policy/policy-guard-generator.ts index ac9e26e92..b77da8fed 100644 --- a/packages/schema/src/plugins/access-policy/policy-guard-generator.ts +++ b/packages/schema/src/plugins/access-policy/policy-guard-generator.ts @@ -28,7 +28,7 @@ import { RUNTIME_PACKAGE, saveProject, } from '@zenstackhq/sdk'; -import { camelCase } from 'change-case'; +import { lowerCaseFirst } from 'lower-case-first'; import { streamAllContents } from 'langium'; import path from 'path'; import { FunctionDeclaration, SourceFile, VariableDeclarationKind } from 'ts-morph'; @@ -90,7 +90,7 @@ export default class PolicyGenerator { writer.write('guard:'); writer.inlineBlock(() => { for (const [model, map] of Object.entries(policyMap)) { - writer.write(`${camelCase(model)}:`); + writer.write(`${lowerCaseFirst(model)}:`); writer.inlineBlock(() => { for (const [op, func] of Object.entries(map)) { if (typeof func === 'object') { diff --git a/packages/schema/src/plugins/access-policy/zod-schema-generator.ts b/packages/schema/src/plugins/access-policy/zod-schema-generator.ts index a6f94a19b..7e136051a 100644 --- a/packages/schema/src/plugins/access-policy/zod-schema-generator.ts +++ b/packages/schema/src/plugins/access-policy/zod-schema-generator.ts @@ -1,6 +1,6 @@ import { DataModel, DataModelField, DataModelFieldAttribute, isDataModelField } from '@zenstackhq/language/ast'; import { AUXILIARY_FIELDS, VALIDATION_ATTRIBUTES, getLiteral } from '@zenstackhq/sdk'; -import { camelCase } from 'change-case'; +import { lowerCaseFirst } from 'lower-case-first'; import { CodeBlockWriter } from 'ts-morph'; /** @@ -24,7 +24,7 @@ export class ZodSchemaGenerator { } generated = true; - writer.write(`${camelCase(model.name)}: z.object(`); + writer.write(`${lowerCaseFirst(model.name)}: z.object(`); writer.inlineBlock(() => { fields.forEach((field) => { writer.writeLine(`${field.name}: ${this.makeFieldValidator(field)},`); diff --git a/packages/schema/src/plugins/model-meta/index.ts b/packages/schema/src/plugins/model-meta/index.ts index 2d65224bf..86245eb4a 100644 --- a/packages/schema/src/plugins/model-meta/index.ts +++ b/packages/schema/src/plugins/model-meta/index.ts @@ -19,7 +19,7 @@ import { resolved, saveProject, } from '@zenstackhq/sdk'; -import { camelCase } from 'change-case'; +import { lowerCaseFirst } from 'lower-case-first'; import path from 'path'; import { CodeBlockWriter, VariableDeclarationKind } from 'ts-morph'; import { getIdFields } from '../../language-server/utils'; @@ -65,7 +65,7 @@ function generateModelMetadata(dataModels: DataModel[], writer: CodeBlockWriter) writer.write('fields:'); writer.block(() => { for (const model of dataModels) { - writer.write(`${camelCase(model.name)}:`); + writer.write(`${lowerCaseFirst(model.name)}:`); writer.block(() => { for (const f of model.fields) { const backlink = getBackLink(f); @@ -95,7 +95,7 @@ function generateModelMetadata(dataModels: DataModel[], writer: CodeBlockWriter) writer.write('uniqueConstraints:'); writer.block(() => { for (const model of dataModels) { - writer.write(`${camelCase(model.name)}:`); + writer.write(`${lowerCaseFirst(model.name)}:`); writer.block(() => { for (const constraint of getUniqueConstraints(model)) { writer.write(`${constraint.name}: { diff --git a/packages/schema/src/plugins/zod/transformer.ts b/packages/schema/src/plugins/zod/transformer.ts index 44e9cc9e3..325aba5b4 100644 --- a/packages/schema/src/plugins/zod/transformer.ts +++ b/packages/schema/src/plugins/zod/transformer.ts @@ -3,7 +3,7 @@ import type { DMMF as PrismaDMMF } from '@prisma/generator-helper'; import { AUXILIARY_FIELDS } from '@zenstackhq/sdk'; import { checkModelHasModelRelation, findModelByName, isAggregateInputType } from '@zenstackhq/sdk/dmmf-helpers'; import indentString from '@zenstackhq/sdk/utils'; -import { pascalCase } from 'change-case'; +import { upperCaseFirst } from 'upper-case-first'; import path from 'path'; import { Project } from 'ts-morph'; import { AggregateOperationSupport, TransformerParams } from './types'; @@ -426,11 +426,11 @@ export default class Transformer { `import { ${modelName}WhereInputObjectSchema } from './objects/${modelName}WhereInput.schema'`, `import { ${modelName}OrderByWithRelationInputObjectSchema } from './objects/${modelName}OrderByWithRelationInput.schema'`, `import { ${modelName}WhereUniqueInputObjectSchema } from './objects/${modelName}WhereUniqueInput.schema'`, - `import { ${pascalCase(modelName)}ScalarFieldEnumSchema } from './enums/${pascalCase( + `import { ${upperCaseFirst(modelName)}ScalarFieldEnumSchema } from './enums/${upperCaseFirst( modelName )}ScalarFieldEnum.schema'` ); - codeBody += `findFirst: z.object({ ${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithRelationInputObjectSchema, ${modelName}OrderByWithRelationInputObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), distinct: z.array(${pascalCase( + codeBody += `findFirst: z.object({ ${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithRelationInputObjectSchema, ${modelName}OrderByWithRelationInputObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), distinct: z.array(${upperCaseFirst( modelName )}ScalarFieldEnumSchema).optional() }),`; } @@ -440,11 +440,11 @@ export default class Transformer { `import { ${modelName}WhereInputObjectSchema } from './objects/${modelName}WhereInput.schema'`, `import { ${modelName}OrderByWithRelationInputObjectSchema } from './objects/${modelName}OrderByWithRelationInput.schema'`, `import { ${modelName}WhereUniqueInputObjectSchema } from './objects/${modelName}WhereUniqueInput.schema'`, - `import { ${pascalCase(modelName)}ScalarFieldEnumSchema } from './enums/${pascalCase( + `import { ${upperCaseFirst(modelName)}ScalarFieldEnumSchema } from './enums/${upperCaseFirst( modelName )}ScalarFieldEnum.schema'` ); - codeBody += `findMany: z.object({ ${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithRelationInputObjectSchema, ${modelName}OrderByWithRelationInputObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), distinct: z.array(${pascalCase( + codeBody += `findMany: z.object({ ${selectZodSchemaLineLazy} ${includeZodSchemaLineLazy} where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithRelationInputObjectSchema, ${modelName}OrderByWithRelationInputObjectSchema.array()]).optional(), cursor: ${modelName}WhereUniqueInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), distinct: z.array(${upperCaseFirst( modelName )}ScalarFieldEnumSchema).optional() }),`; } @@ -504,7 +504,7 @@ export default class Transformer { const aggregateOperations = []; // DMMF messed up the model name casing used in the aggregate operations, - const modelNameVar = pascalCase(modelName); + const modelNameVar = upperCaseFirst(modelName); if (this.aggregateOperationSupport[modelNameVar]?.count) { imports.push( `import { ${modelNameVar}CountAggregateInputObjectSchema } from './objects/${modelNameVar}CountAggregateInput.schema'` @@ -555,11 +555,11 @@ export default class Transformer { `import { ${modelName}WhereInputObjectSchema } from './objects/${modelName}WhereInput.schema'`, `import { ${modelName}OrderByWithAggregationInputObjectSchema } from './objects/${modelName}OrderByWithAggregationInput.schema'`, `import { ${modelName}ScalarWhereWithAggregatesInputObjectSchema } from './objects/${modelName}ScalarWhereWithAggregatesInput.schema'`, - `import { ${pascalCase(modelName)}ScalarFieldEnumSchema } from './enums/${pascalCase( + `import { ${upperCaseFirst(modelName)}ScalarFieldEnumSchema } from './enums/${upperCaseFirst( modelName )}ScalarFieldEnum.schema'` ); - codeBody += `groupBy: z.object({ where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithAggregationInputObjectSchema, ${modelName}OrderByWithAggregationInputObjectSchema.array()]).optional(), having: ${modelName}ScalarWhereWithAggregatesInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), by: z.array(${pascalCase( + codeBody += `groupBy: z.object({ where: ${modelName}WhereInputObjectSchema.optional(), orderBy: z.union([${modelName}OrderByWithAggregationInputObjectSchema, ${modelName}OrderByWithAggregationInputObjectSchema.array()]).optional(), having: ${modelName}ScalarWhereWithAggregatesInputObjectSchema.optional(), take: z.number().optional(), skip: z.number().optional(), by: z.array(${upperCaseFirst( modelName )}ScalarFieldEnumSchema), ${aggregateOperations.join(', ')} }),`; } diff --git a/packages/server/package.json b/packages/server/package.json index a1a9b09bc..60c1923ff 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -28,6 +28,7 @@ "@zenstackhq/sdk": "workspace:*", "change-case": "^4.1.2", "tiny-invariant": "^1.3.1", + "upper-case-first": "^2.0.2", "zod-validation-error": "^0.2.1" }, "devDependencies": { @@ -35,6 +36,7 @@ "@types/express": "^4.17.17", "@types/jest": "^29.5.0", "@types/supertest": "^2.0.12", + "@types/upper-case-first": "^1.1.2", "@zenstackhq/testtools": "workspace:*", "body-parser": "^1.20.2", "copyfiles": "^2.4.1", diff --git a/packages/server/src/openapi/index.ts b/packages/server/src/openapi/index.ts index 3ecfa1e5d..684257dfd 100644 --- a/packages/server/src/openapi/index.ts +++ b/packages/server/src/openapi/index.ts @@ -6,7 +6,7 @@ import { isPrismaClientValidationError, } from '@zenstackhq/runtime'; import type { ModelZodSchema } from '@zenstackhq/runtime/zod'; -import { pascalCase } from 'change-case'; +import { upperCaseFirst } from 'upper-case-first'; import { fromZodError } from 'zod-validation-error'; import { stripAuxFields } from './utils'; @@ -57,8 +57,8 @@ export type Response = { function getZodSchema(zodSchemas: ModelZodSchema, model: string, operation: keyof DbOperations) { if (zodSchemas[model]) { return zodSchemas[model][operation]; - } else if (zodSchemas[pascalCase(model)]) { - return zodSchemas[pascalCase(model)][operation]; + } else if (zodSchemas[upperCaseFirst(model)]) { + return zodSchemas[upperCaseFirst(model)][operation]; } else { return undefined; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7bacedc5b..b60762121 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -68,6 +68,7 @@ importers: '@prisma/internals': ^4.7.1 '@readme/openapi-parser': ^2.4.0 '@types/jest': ^29.5.0 + '@types/lower-case-first': ^1.0.1 '@types/tmp': ^0.2.3 '@typescript-eslint/eslint-plugin': ^5.54.0 '@typescript-eslint/parser': ^5.54.0 @@ -78,6 +79,7 @@ importers: copyfiles: ^2.4.1 eslint: ^8.35.0 jest: ^29.5.0 + lower-case-first: ^2.0.2 openapi-types: ^12.1.0 rimraf: ^3.0.2 tiny-invariant: ^1.3.1 @@ -93,6 +95,7 @@ importers: '@zenstackhq/runtime': link:../../runtime/dist '@zenstackhq/sdk': link:../../sdk/dist change-case: 4.1.2 + lower-case-first: 2.0.2 openapi-types: 12.1.0 tiny-invariant: 1.3.1 yaml: 2.2.1 @@ -102,6 +105,7 @@ importers: '@prisma/internals': 4.7.1 '@readme/openapi-parser': 2.4.0_openapi-types@12.1.0 '@types/jest': 29.5.0 + '@types/lower-case-first': 1.0.1 '@types/tmp': 0.2.3 '@typescript-eslint/eslint-plugin': 5.54.0_6mj2wypvdnknez7kws2nfdgupi '@typescript-eslint/parser': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu @@ -121,14 +125,17 @@ importers: '@prisma/generator-helper': ^4.7.1 '@tanstack/react-query': ^4.28.0 '@types/jest': ^29.5.0 + '@types/lower-case-first': ^1.0.1 '@types/react': ^18.0.26 '@types/tmp': ^0.2.3 + '@types/upper-case-first': ^1.1.2 '@zenstackhq/sdk': workspace:* '@zenstackhq/testtools': workspace:* change-case: ^4.1.2 copyfiles: ^2.4.1 decimal.js: ^10.4.2 jest: ^29.5.0 + lower-case-first: ^2.0.2 react: ^17.0.2 || ^18 react-dom: ^17.0.2 || ^18 rimraf: ^3.0.2 @@ -137,18 +144,23 @@ importers: ts-jest: ^29.0.5 ts-morph: ^16.0.0 typescript: ^4.9.4 + upper-case-first: ^2.0.2 dependencies: '@prisma/generator-helper': 4.7.1 '@zenstackhq/sdk': link:../../sdk/dist change-case: 4.1.2 decimal.js: 10.4.2 + lower-case-first: 2.0.2 superjson: 1.12.1 ts-morph: 16.0.0 + upper-case-first: 2.0.2 devDependencies: '@tanstack/react-query': 4.28.0_biqbaboplfbrettd7655fr4n2y '@types/jest': 29.5.0 + '@types/lower-case-first': 1.0.1 '@types/react': 18.0.26 '@types/tmp': 0.2.3 + '@types/upper-case-first': 1.1.2 '@zenstackhq/testtools': link:../../testtools/dist copyfiles: 2.4.1 jest: 29.5.0 @@ -165,12 +177,14 @@ importers: '@prisma/generator-helper': ^4.7.1 '@prisma/internals': ^4.7.1 '@types/jest': ^29.5.0 + '@types/lower-case-first': ^1.0.1 '@types/prettier': ^2.7.2 '@zenstackhq/sdk': workspace:* '@zenstackhq/testtools': workspace:* change-case: ^4.1.2 copyfiles: ^2.4.1 jest: ^29.5.0 + lower-case-first: ^2.0.2 prettier: ^2.8.3 rimraf: ^3.0.2 ts-jest: ^29.0.5 @@ -183,12 +197,14 @@ importers: '@prisma/internals': 4.7.1 '@zenstackhq/sdk': link:../../sdk/dist change-case: 4.1.2 + lower-case-first: 2.0.2 prettier: 2.8.3 ts-morph: 16.0.0 tslib: 2.4.1 zod: 3.21.1 devDependencies: '@types/jest': 29.5.0 + '@types/lower-case-first': 1.0.1 '@types/prettier': 2.7.2 '@zenstackhq/testtools': link:../../testtools/dist copyfiles: 2.4.1 @@ -204,6 +220,7 @@ importers: '@prisma/client': ^4.0.0 '@types/bcryptjs': ^2.4.2 '@types/jest': ^29.5.0 + '@types/lower-case-first': ^1.0.1 '@types/node': ^14.18.29 '@types/pluralize': ^0.0.29 '@zenstackhq/sdk': workspace:* @@ -213,6 +230,7 @@ importers: copyfiles: ^2.4.1 decimal.js: ^10.4.2 deepcopy: ^2.1.0 + lower-case-first: ^2.0.2 pluralize: ^8.0.0 rimraf: ^3.0.2 superjson: ^1.11.0 @@ -230,6 +248,7 @@ importers: colors: 1.4.0 decimal.js: 10.4.2 deepcopy: 2.1.0 + lower-case-first: 2.0.2 pluralize: 8.0.0 superjson: 1.11.0 tslib: 2.4.1 @@ -237,6 +256,7 @@ importers: zod-validation-error: 0.2.1_zod@3.21.1 devDependencies: '@types/jest': 29.5.0 + '@types/lower-case-first': 1.0.1 '@types/node': 14.18.32 '@types/pluralize': 0.0.29 copyfiles: 2.4.1 @@ -251,10 +271,12 @@ importers: '@prisma/internals': ^4.0.0 '@types/async-exit-hook': ^2.0.0 '@types/jest': ^29.5.0 + '@types/lower-case-first': ^1.0.1 '@types/node': ^14.18.32 '@types/pluralize': ^0.0.29 '@types/semver': ^7.3.13 '@types/tmp': ^0.2.3 + '@types/upper-case-first': ^1.1.2 '@types/uuid': ^8.3.4 '@types/vscode': ^1.56.0 '@typescript-eslint/eslint-plugin': ^5.42.0 @@ -278,6 +300,7 @@ importers: get-latest-version: ^5.0.1 jest: ^29.5.0 langium: 1.1.0 + lower-case-first: ^2.0.2 mixpanel: ^0.17.0 node-machine-id: ^1.1.12 ora: ^5.4.1 @@ -294,6 +317,7 @@ importers: ts-node: ^10.9.1 tsc-alias: ^1.7.0 typescript: ^4.8.4 + upper-case-first: ^2.0.2 uuid: ^9.0.0 vitest: ^0.29.7 vscode-jsonrpc: ^8.0.2 @@ -316,6 +340,7 @@ importers: commander: 8.3.0 get-latest-version: 5.0.1 langium: 1.1.0 + lower-case-first: 2.0.2 mixpanel: 0.17.0 node-machine-id: 1.1.12 ora: 5.4.1 @@ -324,6 +349,7 @@ importers: semver: 7.3.8 sleep-promise: 9.1.0 ts-morph: 16.0.0 + upper-case-first: 2.0.2 uuid: 9.0.0 vscode-jsonrpc: 8.0.2 vscode-languageclient: 8.0.2 @@ -335,10 +361,12 @@ importers: devDependencies: '@types/async-exit-hook': 2.0.0 '@types/jest': 29.5.0 + '@types/lower-case-first': 1.0.1 '@types/node': 14.18.32 '@types/pluralize': 0.0.29 '@types/semver': 7.3.13 '@types/tmp': 0.2.3 + '@types/upper-case-first': 1.1.2 '@types/uuid': 8.3.4 '@types/vscode': 1.72.0 '@typescript-eslint/eslint-plugin': 5.42.0_ofgjrzjuekeo7s3hdyz2yuzw34 @@ -390,6 +418,7 @@ importers: '@types/express': ^4.17.17 '@types/jest': ^29.5.0 '@types/supertest': ^2.0.12 + '@types/upper-case-first': ^1.1.2 '@zenstackhq/openapi': workspace:* '@zenstackhq/runtime': workspace:* '@zenstackhq/sdk': workspace:* @@ -406,6 +435,7 @@ importers: tiny-invariant: ^1.3.1 ts-jest: ^29.0.5 typescript: ^4.9.4 + upper-case-first: ^2.0.2 zod-validation-error: ^0.2.1 dependencies: '@zenstackhq/openapi': link:../plugins/openapi/dist @@ -413,12 +443,14 @@ importers: '@zenstackhq/sdk': link:../sdk/dist change-case: 4.1.2 tiny-invariant: 1.3.1 + upper-case-first: 2.0.2 zod-validation-error: 0.2.1_zod@3.21.1 devDependencies: '@types/body-parser': 1.19.2 '@types/express': 4.17.17 '@types/jest': 29.5.0 '@types/supertest': 2.0.12 + '@types/upper-case-first': 1.1.2 '@zenstackhq/testtools': link:../testtools/dist body-parser: 1.20.2 copyfiles: 2.4.1 @@ -2382,6 +2414,13 @@ packages: '@types/node': 18.14.2 dev: true + /@types/lower-case-first/1.0.1: + resolution: {integrity: sha512-Sko9LlGuUr1oqpqD2dTznreWYDWpt0OsgQxPEGudt41Rbp0iFTd3gkbo5j0MpeJCgp/Q2WRTd6MTjjZ9ax0USg==} + deprecated: This is a stub types definition for lower-case-first (https://github.com/blakeembrey/lower-case-first). lower-case-first provides its own type definitions, so you don't need @types/lower-case-first installed! + dependencies: + lower-case-first: 2.0.2 + dev: true + /@types/mime/3.0.1: resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} dev: true @@ -2481,6 +2520,13 @@ packages: resolution: {integrity: sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==} dev: true + /@types/upper-case-first/1.1.2: + resolution: {integrity: sha512-YOy6ArS6hUf7d/vzYcL78OBH7+l5t98Kpn0AHrgUnetgChU2r7ku1je12Ysqh0leOHbkz+y+6R8v5hzSDE9U7g==} + deprecated: This is a stub types definition for upper-case-first (https://github.com/blakeembrey/upper-case-first). upper-case-first provides its own type definitions, so you don't need @types/upper-case-first installed! + dependencies: + upper-case-first: 2.0.2 + dev: true + /@types/uuid/8.3.4: resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} dev: true @@ -6844,6 +6890,11 @@ packages: get-func-name: 2.0.0 dev: true + /lower-case-first/2.0.2: + resolution: {integrity: sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==} + dependencies: + tslib: 2.4.1 + /lower-case/2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} dependencies: @@ -9150,7 +9201,6 @@ packages: resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} dependencies: tslib: 2.4.1 - dev: false /upper-case/2.0.2: resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==}