diff --git a/package.json b/package.json index ee7762c45..8354081fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-monorepo", - "version": "2.6.2", + "version": "2.7.0", "description": "", "scripts": { "build": "pnpm -r build", diff --git a/packages/ide/jetbrains/build.gradle.kts b/packages/ide/jetbrains/build.gradle.kts index d05aa39a0..d5f344268 100644 --- a/packages/ide/jetbrains/build.gradle.kts +++ b/packages/ide/jetbrains/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } group = "dev.zenstack" -version = "2.6.2" +version = "2.7.0" repositories { mavenCentral() diff --git a/packages/ide/jetbrains/package.json b/packages/ide/jetbrains/package.json index 6722a7668..0c4304700 100644 --- a/packages/ide/jetbrains/package.json +++ b/packages/ide/jetbrains/package.json @@ -1,6 +1,6 @@ { "name": "jetbrains", - "version": "2.6.2", + "version": "2.7.0", "displayName": "ZenStack JetBrains IDE Plugin", "description": "ZenStack JetBrains IDE plugin", "homepage": "https://zenstack.dev", diff --git a/packages/language/package.json b/packages/language/package.json index 8156be8c6..116189e9a 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/language", - "version": "2.6.2", + "version": "2.7.0", "displayName": "ZenStack modeling language compiler", "description": "ZenStack modeling language compiler", "homepage": "https://zenstack.dev", diff --git a/packages/misc/redwood/package.json b/packages/misc/redwood/package.json index 3de99248a..38af66c2b 100644 --- a/packages/misc/redwood/package.json +++ b/packages/misc/redwood/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/redwood", "displayName": "ZenStack RedwoodJS Integration", - "version": "2.6.2", + "version": "2.7.0", "description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.", "repository": { "type": "git", diff --git a/packages/plugins/openapi/package.json b/packages/plugins/openapi/package.json index 83e875ddf..8d55327e7 100644 --- a/packages/plugins/openapi/package.json +++ b/packages/plugins/openapi/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/openapi", "displayName": "ZenStack Plugin and Runtime for OpenAPI", - "version": "2.6.2", + "version": "2.7.0", "description": "ZenStack plugin and runtime supporting OpenAPI", "main": "index.js", "repository": { diff --git a/packages/plugins/openapi/src/rest-generator.ts b/packages/plugins/openapi/src/rest-generator.ts index 90383f8f9..7cf465d9e 100644 --- a/packages/plugins/openapi/src/rest-generator.ts +++ b/packages/plugins/openapi/src/rest-generator.ts @@ -409,6 +409,8 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { private generateFilterParameters(model: DataModel) { const result: OAPI.ParameterObject[] = []; + const hasMultipleIds = model.fields.filter((f) => isIdField(f)).length > 1; + for (const field of model.fields) { if (isForeignKeyField(field)) { // no filtering with foreign keys because one can filter @@ -416,7 +418,8 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { continue; } - if (isIdField(field)) { + // For multiple ids, make each id field filterable like a regular field + if (isIdField(field) && !hasMultipleIds) { // id filter result.push(this.makeFilterParameter(field, 'id', 'Id filter')); continue; @@ -843,7 +846,9 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { } private generateModelEntity(model: DataModel, mode: 'read' | 'create' | 'update'): OAPI.SchemaObject { - const fields = model.fields.filter((f) => !isIdField(f)); + const idFields = model.fields.filter((f) => isIdField(f)); + // For compound ids, each component is also exposed as a separate field + const fields = idFields.length > 1 ? model.fields : model.fields.filter((f) => !isIdField(f)); const attributes: Record = {}; const relationships: Record = {}; @@ -869,6 +874,9 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { !(isDataModel(field.$resolvedType?.decl) && field.type.array) ) { required.push(field.name); + } else if (mode === 'read') { + // Until we support sparse fieldsets, all fields are required for read operations + required.push(field.name); } } } @@ -886,8 +894,8 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { if (mode === 'create') { // 'id' is required if there's no default value - const idField = model.fields.find((f) => isIdField(f)); - if (idField && !hasAttribute(idField, '@default')) { + const idFields = model.fields.filter((f) => isIdField(f)); + if (idFields.length && idFields.every((f) => !hasAttribute(f, '@default'))) { properties = { id: { type: 'string' }, ...properties }; toplevelRequired.unshift('id'); } diff --git a/packages/plugins/openapi/tests/baseline/rest-3.0.0.baseline.yaml b/packages/plugins/openapi/tests/baseline/rest-3.0.0.baseline.yaml index 263624c66..96f80d81a 100644 --- a/packages/plugins/openapi/tests/baseline/rest-3.0.0.baseline.yaml +++ b/packages/plugins/openapi/tests/baseline/rest-3.0.0.baseline.yaml @@ -9,6 +9,8 @@ tags: description: Profile operations - name: post_Item description: Post-related operations + - name: postLike + description: PostLike operations paths: /user: get: @@ -193,6 +195,16 @@ paths: explode: false schema: type: string + - name: filter[likes] + required: false + description: Equality filter for "likes" + in: query + style: form + explode: false + schema: + type: array + items: + type: string responses: '200': description: Successful operation @@ -543,6 +555,16 @@ paths: explode: false schema: type: string + - name: filter[likes] + required: false + description: Equality filter for "likes" + in: query + style: form + explode: false + schema: + type: array + items: + type: string responses: '200': description: Successful operation @@ -745,6 +767,16 @@ paths: explode: false schema: type: string + - name: filter[likes] + required: false + description: Equality filter for "likes" + in: query + style: form + explode: false + schema: + type: array + items: + type: string responses: '200': description: Successful operation @@ -1593,6 +1625,16 @@ paths: explode: false schema: type: string + - name: filter[likes] + required: false + description: Equality filter for "likes" + in: query + style: form + explode: false + schema: + type: array + items: + type: string responses: '200': description: Successful operation @@ -1876,230 +1918,657 @@ paths: application/vnd.api+json: schema: $ref: '#/components/schemas/_errorResponse' -components: - schemas: - _jsonapi: - type: object - description: An object describing the server’s implementation - required: - - version - properties: - version: - type: string - _meta: - type: object - description: Meta information about the request or response - properties: - serialization: - description: Superjson serialization metadata - additionalProperties: true - _resourceIdentifier: - type: object - description: Identifier for a resource - required: - - type - - id - properties: - type: - type: string - description: Resource type - id: - type: string - description: Resource id - _resource: - allOf: - - $ref: '#/components/schemas/_resourceIdentifier' - - type: object - description: A resource with attributes and relationships - properties: - attributes: - type: object - description: Resource attributes - relationships: - type: object - description: Resource relationships - _links: - type: object - required: - - self - description: Links related to the resource - properties: - self: - type: string - description: Link for refetching the curent results - _pagination: - type: object - description: Pagination information - required: - - first - - last - - prev - - next - properties: - first: - type: string - description: Link to the first page - nullable: true - last: - type: string - description: Link to the last page - nullable: true - prev: - type: string - description: Link to the previous page - nullable: true - next: - type: string - description: Link to the next page - nullable: true - _errors: - type: array - description: An array of error objects - items: - type: object - required: - - status - - code - properties: - status: - type: string - description: HTTP status - code: - type: string - description: Error code - prismaCode: - type: string - description: Prisma error code if the error is thrown by Prisma - title: - type: string - description: Error title - detail: - type: string - description: Error detail - reason: - type: string - description: Detailed error reason - zodErrors: - type: object - additionalProperties: true - description: Zod validation errors if the error is due to data validation - failure - _errorResponse: - type: object - required: - - errors - description: An error response - properties: - jsonapi: - $ref: '#/components/schemas/_jsonapi' - errors: - $ref: '#/components/schemas/_errors' - _relationLinks: - type: object - required: - - self - - related - description: Links related to a relationship - properties: - self: - type: string - description: Link for fetching this relationship - related: - type: string - description: Link for fetching the resource represented by this relationship - _toOneRelationship: - type: object - description: A to-one relationship - properties: - data: - allOf: - - $ref: '#/components/schemas/_resourceIdentifier' - nullable: true - _toOneRelationshipWithLinks: - type: object - required: - - links - - data - description: A to-one relationship with links - properties: - links: - $ref: '#/components/schemas/_relationLinks' - data: - allOf: - - $ref: '#/components/schemas/_resourceIdentifier' - nullable: true - _toManyRelationship: - type: object - required: - - data - description: A to-many relationship - properties: - data: - type: array - items: - $ref: '#/components/schemas/_resourceIdentifier' - _toManyRelationshipWithLinks: - type: object - required: - - links - - data - description: A to-many relationship with links - properties: - links: - $ref: '#/components/schemas/_pagedRelationLinks' - data: - type: array - items: - $ref: '#/components/schemas/_resourceIdentifier' - _pagedRelationLinks: - description: Relationship links with pagination information - allOf: - - $ref: '#/components/schemas/_pagination' - - $ref: '#/components/schemas/_relationLinks' - _toManyRelationshipRequest: - type: object - required: - - data - description: Input for manipulating a to-many relationship - properties: - data: - type: array - items: - $ref: '#/components/schemas/_resourceIdentifier' - _toOneRelationshipRequest: - description: Input for manipulating a to-one relationship - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/_resourceIdentifier' - nullable: true - _toManyRelationshipResponse: - description: Response for a to-many relationship - allOf: - - $ref: '#/components/schemas/_toManyRelationshipWithLinks' - - type: object - properties: - jsonapi: - $ref: '#/components/schemas/_jsonapi' - _toOneRelationshipResponse: - description: Response for a to-one relationship - allOf: - - $ref: '#/components/schemas/_toOneRelationshipWithLinks' - - type: object - properties: - jsonapi: - $ref: '#/components/schemas/_jsonapi' - role: - type: string - description: The "role" Enum - enum: - - USER - - ADMIN - User: - type: object - description: The "User" model + /postLike: + get: + operationId: list-PostLike + description: List "PostLike" resources + tags: + - postLike + parameters: + - $ref: '#/components/parameters/include' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/page-offset' + - $ref: '#/components/parameters/page-limit' + - name: filter[post] + required: false + description: Equality filter for "post" + in: query + style: form + explode: false + schema: + type: string + - name: filter[user] + required: false + description: Equality filter for "user" + in: query + style: form + explode: false + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeListResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + post: + operationId: create-PostLike + description: Create a "PostLike" resource + tags: + - postLike + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeCreateRequest' + responses: + '201': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '422': + description: Request is unprocessable due to validation errors + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /postLike/{id}: + get: + operationId: fetch-PostLike + description: Fetch a "PostLike" resource + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-PostLike-put + description: Update a "PostLike" resource + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '422': + description: Request is unprocessable due to validation errors + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-PostLike-patch + description: Update a "PostLike" resource + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '422': + description: Request is unprocessable due to validation errors + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + delete: + operationId: delete-PostLike + description: Delete a "PostLike" resource + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /postLike/{id}/post: + get: + operationId: fetch-PostLike-related-post + description: Fetch the related "post" resource for "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/post_ItemResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /postLike/{id}/relationships/post: + get: + operationId: fetch-PostLike-relationship-post + description: Fetch the "post" relationships for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-PostLike-relationship-post-put + description: Update "post" relationship for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-PostLike-relationship-post-patch + description: Update "post" relationship for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /postLike/{id}/user: + get: + operationId: fetch-PostLike-related-user + description: Fetch the related "user" resource for "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /postLike/{id}/relationships/user: + get: + operationId: fetch-PostLike-relationship-user + description: Fetch the "user" relationships for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-PostLike-relationship-user-put + description: Update "user" relationship for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-PostLike-relationship-user-patch + description: Update "user" relationship for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' +components: + schemas: + _jsonapi: + type: object + description: An object describing the server’s implementation + required: + - version + properties: + version: + type: string + _meta: + type: object + description: Meta information about the request or response + properties: + serialization: + description: Superjson serialization metadata + additionalProperties: true + _resourceIdentifier: + type: object + description: Identifier for a resource + required: + - type + - id + properties: + type: + type: string + description: Resource type + id: + type: string + description: Resource id + _resource: + allOf: + - $ref: '#/components/schemas/_resourceIdentifier' + - type: object + description: A resource with attributes and relationships + properties: + attributes: + type: object + description: Resource attributes + relationships: + type: object + description: Resource relationships + _links: + type: object + required: + - self + description: Links related to the resource + properties: + self: + type: string + description: Link for refetching the curent results + _pagination: + type: object + description: Pagination information + required: + - first + - last + - prev + - next + properties: + first: + type: string + description: Link to the first page + nullable: true + last: + type: string + description: Link to the last page + nullable: true + prev: + type: string + description: Link to the previous page + nullable: true + next: + type: string + description: Link to the next page + nullable: true + _errors: + type: array + description: An array of error objects + items: + type: object + required: + - status + - code + properties: + status: + type: string + description: HTTP status + code: + type: string + description: Error code + prismaCode: + type: string + description: Prisma error code if the error is thrown by Prisma + title: + type: string + description: Error title + detail: + type: string + description: Error detail + reason: + type: string + description: Detailed error reason + zodErrors: + type: object + additionalProperties: true + description: Zod validation errors if the error is due to data validation + failure + _errorResponse: + type: object + required: + - errors + description: An error response + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + errors: + $ref: '#/components/schemas/_errors' + _relationLinks: + type: object + required: + - self + - related + description: Links related to a relationship + properties: + self: + type: string + description: Link for fetching this relationship + related: + type: string + description: Link for fetching the resource represented by this relationship + _toOneRelationship: + type: object + description: A to-one relationship + properties: + data: + allOf: + - $ref: '#/components/schemas/_resourceIdentifier' + nullable: true + _toOneRelationshipWithLinks: + type: object + required: + - links + - data + description: A to-one relationship with links + properties: + links: + $ref: '#/components/schemas/_relationLinks' + data: + allOf: + - $ref: '#/components/schemas/_resourceIdentifier' + nullable: true + _toManyRelationship: + type: object + required: + - data + description: A to-many relationship + properties: + data: + type: array + items: + $ref: '#/components/schemas/_resourceIdentifier' + _toManyRelationshipWithLinks: + type: object + required: + - links + - data + description: A to-many relationship with links + properties: + links: + $ref: '#/components/schemas/_pagedRelationLinks' + data: + type: array + items: + $ref: '#/components/schemas/_resourceIdentifier' + _pagedRelationLinks: + description: Relationship links with pagination information + allOf: + - $ref: '#/components/schemas/_pagination' + - $ref: '#/components/schemas/_relationLinks' + _toManyRelationshipRequest: + type: object + required: + - data + description: Input for manipulating a to-many relationship + properties: + data: + type: array + items: + $ref: '#/components/schemas/_resourceIdentifier' + _toOneRelationshipRequest: + description: Input for manipulating a to-one relationship + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/_resourceIdentifier' + nullable: true + _toManyRelationshipResponse: + description: Response for a to-many relationship + allOf: + - $ref: '#/components/schemas/_toManyRelationshipWithLinks' + - type: object + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + _toOneRelationshipResponse: + description: Response for a to-one relationship + allOf: + - $ref: '#/components/schemas/_toOneRelationshipWithLinks' + - type: object + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + role: + type: string + description: The "role" Enum + enum: + - USER + - ADMIN + User: + type: object + description: The "User" model required: - id - type @@ -2122,6 +2591,11 @@ components: type: string role: $ref: '#/components/schemas/role' + required: + - createdAt + - updatedAt + - email + - role relationships: type: object properties: @@ -2292,6 +2766,9 @@ components: nullable: true userId: type: string + required: + - image + - userId relationships: type: object properties: @@ -2450,6 +2927,14 @@ components: notes: type: string nullable: true + required: + - createdAt + - updatedAt + - title + - authorId + - published + - viewCount + - notes relationships: type: object properties: @@ -2611,6 +3096,165 @@ components: allOf: - $ref: '#/components/schemas/_links' - $ref: '#/components/schemas/_pagination' + PostLike: + type: object + description: The "PostLike" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + postId: + type: string + userId: + type: string + required: + - postId + - userId + relationships: + type: object + properties: + post: + $ref: '#/components/schemas/_toOneRelationshipWithLinks' + user: + $ref: '#/components/schemas/_toOneRelationshipWithLinks' + PostLikeCreateRequest: + type: object + description: Input for creating a "PostLike" + required: + - data + properties: + data: + type: object + description: The "PostLike" model + required: + - id + - type + - attributes + properties: + type: + type: string + attributes: + type: object + required: + - postId + - userId + properties: + postId: + type: string + userId: + type: string + relationships: + type: object + properties: + post: + $ref: '#/components/schemas/_toOneRelationship' + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + PostLikeUpdateRequest: + type: object + description: Input for updating a "PostLike" + required: + - data + properties: + data: + type: object + description: The "PostLike" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + postId: + type: string + userId: + type: string + relationships: + type: object + properties: + post: + $ref: '#/components/schemas/_toOneRelationship' + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + PostLikeResponse: + type: object + description: Response for a "PostLike" + required: + - data + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + allOf: + - $ref: '#/components/schemas/PostLike' + - type: object + properties: + relationships: + type: object + properties: + post: + $ref: '#/components/schemas/_toOneRelationship' + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + $ref: '#/components/schemas/_links' + PostLikeListResponse: + type: object + description: Response for a list of "PostLike" + required: + - data + - links + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + type: array + items: + allOf: + - $ref: '#/components/schemas/PostLike' + - type: object + properties: + relationships: + type: object + properties: + post: + $ref: '#/components/schemas/_toOneRelationship' + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + allOf: + - $ref: '#/components/schemas/_links' + - $ref: '#/components/schemas/_pagination' parameters: id: name: id diff --git a/packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml b/packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml index e0c7cce3d..e3f2d6821 100644 --- a/packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml +++ b/packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml @@ -9,6 +9,8 @@ tags: description: Profile operations - name: post_Item description: Post-related operations + - name: postLike + description: PostLike operations paths: /user: get: @@ -193,6 +195,16 @@ paths: explode: false schema: type: string + - name: filter[likes] + required: false + description: Equality filter for "likes" + in: query + style: form + explode: false + schema: + type: array + items: + type: string responses: '200': description: Successful operation @@ -543,6 +555,16 @@ paths: explode: false schema: type: string + - name: filter[likes] + required: false + description: Equality filter for "likes" + in: query + style: form + explode: false + schema: + type: array + items: + type: string responses: '200': description: Successful operation @@ -745,6 +767,16 @@ paths: explode: false schema: type: string + - name: filter[likes] + required: false + description: Equality filter for "likes" + in: query + style: form + explode: false + schema: + type: array + items: + type: string responses: '200': description: Successful operation @@ -1593,6 +1625,16 @@ paths: explode: false schema: type: string + - name: filter[likes] + required: false + description: Equality filter for "likes" + in: query + style: form + explode: false + schema: + type: array + items: + type: string responses: '200': description: Successful operation @@ -1876,230 +1918,657 @@ paths: application/vnd.api+json: schema: $ref: '#/components/schemas/_errorResponse' -components: - schemas: - _jsonapi: - type: object - description: An object describing the server’s implementation - required: - - version - properties: - version: - type: string - _meta: - type: object - description: Meta information about the request or response - properties: - serialization: - description: Superjson serialization metadata - additionalProperties: true - _resourceIdentifier: - type: object - description: Identifier for a resource - required: - - type - - id - properties: - type: - type: string - description: Resource type - id: - type: string - description: Resource id - _resource: - allOf: - - $ref: '#/components/schemas/_resourceIdentifier' - - type: object - description: A resource with attributes and relationships - properties: - attributes: - type: object - description: Resource attributes - relationships: - type: object - description: Resource relationships - _links: - type: object - required: - - self - description: Links related to the resource - properties: - self: - type: string - description: Link for refetching the curent results - _pagination: - type: object - description: Pagination information - required: - - first - - last - - prev - - next - properties: - first: - oneOf: - - type: 'null' - - type: string - description: Link to the first page - last: - oneOf: - - type: 'null' - - type: string - description: Link to the last page - prev: - oneOf: - - type: 'null' - - type: string - description: Link to the previous page - next: - oneOf: - - type: 'null' - - type: string - description: Link to the next page - _errors: - type: array - description: An array of error objects - items: - type: object - required: - - status - - code - properties: - status: - type: string - description: HTTP status - code: - type: string - description: Error code - prismaCode: - type: string - description: Prisma error code if the error is thrown by Prisma - title: - type: string - description: Error title - detail: - type: string - description: Error detail - reason: - type: string - description: Detailed error reason - zodErrors: - type: object - additionalProperties: true - description: Zod validation errors if the error is due to data validation - failure - _errorResponse: - type: object - required: - - errors - description: An error response - properties: - jsonapi: - $ref: '#/components/schemas/_jsonapi' - errors: - $ref: '#/components/schemas/_errors' - _relationLinks: - type: object - required: - - self - - related - description: Links related to a relationship - properties: - self: - type: string - description: Link for fetching this relationship - related: - type: string - description: Link for fetching the resource represented by this relationship - _toOneRelationship: - type: object - description: A to-one relationship - properties: - data: - oneOf: - - type: 'null' - - $ref: '#/components/schemas/_resourceIdentifier' - _toOneRelationshipWithLinks: - type: object - required: - - links - - data - description: A to-one relationship with links - properties: - links: - $ref: '#/components/schemas/_relationLinks' - data: - oneOf: - - type: 'null' - - $ref: '#/components/schemas/_resourceIdentifier' - _toManyRelationship: - type: object - required: - - data - description: A to-many relationship - properties: - data: - type: array - items: - $ref: '#/components/schemas/_resourceIdentifier' - _toManyRelationshipWithLinks: - type: object - required: - - links - - data - description: A to-many relationship with links - properties: - links: - $ref: '#/components/schemas/_pagedRelationLinks' - data: - type: array - items: - $ref: '#/components/schemas/_resourceIdentifier' - _pagedRelationLinks: - description: Relationship links with pagination information - allOf: - - $ref: '#/components/schemas/_pagination' - - $ref: '#/components/schemas/_relationLinks' - _toManyRelationshipRequest: - type: object - required: - - data - description: Input for manipulating a to-many relationship - properties: - data: - type: array - items: - $ref: '#/components/schemas/_resourceIdentifier' - _toOneRelationshipRequest: - description: Input for manipulating a to-one relationship - oneOf: - - type: 'null' - - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/_resourceIdentifier' - _toManyRelationshipResponse: - description: Response for a to-many relationship - allOf: - - $ref: '#/components/schemas/_toManyRelationshipWithLinks' - - type: object - properties: - jsonapi: - $ref: '#/components/schemas/_jsonapi' - _toOneRelationshipResponse: - description: Response for a to-one relationship - allOf: - - $ref: '#/components/schemas/_toOneRelationshipWithLinks' - - type: object - properties: - jsonapi: - $ref: '#/components/schemas/_jsonapi' - role: - type: string - description: The "role" Enum - enum: + /postLike: + get: + operationId: list-PostLike + description: List "PostLike" resources + tags: + - postLike + parameters: + - $ref: '#/components/parameters/include' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/page-offset' + - $ref: '#/components/parameters/page-limit' + - name: filter[post] + required: false + description: Equality filter for "post" + in: query + style: form + explode: false + schema: + type: string + - name: filter[user] + required: false + description: Equality filter for "user" + in: query + style: form + explode: false + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeListResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + post: + operationId: create-PostLike + description: Create a "PostLike" resource + tags: + - postLike + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeCreateRequest' + responses: + '201': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '422': + description: Request is unprocessable due to validation errors + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /postLike/{id}: + get: + operationId: fetch-PostLike + description: Fetch a "PostLike" resource + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-PostLike-put + description: Update a "PostLike" resource + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '422': + description: Request is unprocessable due to validation errors + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-PostLike-patch + description: Update a "PostLike" resource + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/PostLikeResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '422': + description: Request is unprocessable due to validation errors + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + delete: + operationId: delete-PostLike + description: Delete a "PostLike" resource + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /postLike/{id}/post: + get: + operationId: fetch-PostLike-related-post + description: Fetch the related "post" resource for "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/post_ItemResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /postLike/{id}/relationships/post: + get: + operationId: fetch-PostLike-relationship-post + description: Fetch the "post" relationships for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-PostLike-relationship-post-put + description: Update "post" relationship for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-PostLike-relationship-post-patch + description: Update "post" relationship for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /postLike/{id}/user: + get: + operationId: fetch-PostLike-related-user + description: Fetch the related "user" resource for "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /postLike/{id}/relationships/user: + get: + operationId: fetch-PostLike-relationship-user + description: Fetch the "user" relationships for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-PostLike-relationship-user-put + description: Update "user" relationship for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-PostLike-relationship-user-patch + description: Update "user" relationship for a "PostLike" + tags: + - postLike + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' +components: + schemas: + _jsonapi: + type: object + description: An object describing the server’s implementation + required: + - version + properties: + version: + type: string + _meta: + type: object + description: Meta information about the request or response + properties: + serialization: + description: Superjson serialization metadata + additionalProperties: true + _resourceIdentifier: + type: object + description: Identifier for a resource + required: + - type + - id + properties: + type: + type: string + description: Resource type + id: + type: string + description: Resource id + _resource: + allOf: + - $ref: '#/components/schemas/_resourceIdentifier' + - type: object + description: A resource with attributes and relationships + properties: + attributes: + type: object + description: Resource attributes + relationships: + type: object + description: Resource relationships + _links: + type: object + required: + - self + description: Links related to the resource + properties: + self: + type: string + description: Link for refetching the curent results + _pagination: + type: object + description: Pagination information + required: + - first + - last + - prev + - next + properties: + first: + oneOf: + - type: 'null' + - type: string + description: Link to the first page + last: + oneOf: + - type: 'null' + - type: string + description: Link to the last page + prev: + oneOf: + - type: 'null' + - type: string + description: Link to the previous page + next: + oneOf: + - type: 'null' + - type: string + description: Link to the next page + _errors: + type: array + description: An array of error objects + items: + type: object + required: + - status + - code + properties: + status: + type: string + description: HTTP status + code: + type: string + description: Error code + prismaCode: + type: string + description: Prisma error code if the error is thrown by Prisma + title: + type: string + description: Error title + detail: + type: string + description: Error detail + reason: + type: string + description: Detailed error reason + zodErrors: + type: object + additionalProperties: true + description: Zod validation errors if the error is due to data validation + failure + _errorResponse: + type: object + required: + - errors + description: An error response + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + errors: + $ref: '#/components/schemas/_errors' + _relationLinks: + type: object + required: + - self + - related + description: Links related to a relationship + properties: + self: + type: string + description: Link for fetching this relationship + related: + type: string + description: Link for fetching the resource represented by this relationship + _toOneRelationship: + type: object + description: A to-one relationship + properties: + data: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/_resourceIdentifier' + _toOneRelationshipWithLinks: + type: object + required: + - links + - data + description: A to-one relationship with links + properties: + links: + $ref: '#/components/schemas/_relationLinks' + data: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/_resourceIdentifier' + _toManyRelationship: + type: object + required: + - data + description: A to-many relationship + properties: + data: + type: array + items: + $ref: '#/components/schemas/_resourceIdentifier' + _toManyRelationshipWithLinks: + type: object + required: + - links + - data + description: A to-many relationship with links + properties: + links: + $ref: '#/components/schemas/_pagedRelationLinks' + data: + type: array + items: + $ref: '#/components/schemas/_resourceIdentifier' + _pagedRelationLinks: + description: Relationship links with pagination information + allOf: + - $ref: '#/components/schemas/_pagination' + - $ref: '#/components/schemas/_relationLinks' + _toManyRelationshipRequest: + type: object + required: + - data + description: Input for manipulating a to-many relationship + properties: + data: + type: array + items: + $ref: '#/components/schemas/_resourceIdentifier' + _toOneRelationshipRequest: + description: Input for manipulating a to-one relationship + oneOf: + - type: 'null' + - type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/_resourceIdentifier' + _toManyRelationshipResponse: + description: Response for a to-many relationship + allOf: + - $ref: '#/components/schemas/_toManyRelationshipWithLinks' + - type: object + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + _toOneRelationshipResponse: + description: Response for a to-one relationship + allOf: + - $ref: '#/components/schemas/_toOneRelationshipWithLinks' + - type: object + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + role: + type: string + description: The "role" Enum + enum: - USER - ADMIN User: @@ -2127,6 +2596,11 @@ components: type: string role: $ref: '#/components/schemas/role' + required: + - createdAt + - updatedAt + - email + - role relationships: type: object properties: @@ -2298,6 +2772,9 @@ components: - type: string userId: type: string + required: + - image + - userId relationships: type: object properties: @@ -2460,6 +2937,14 @@ components: oneOf: - type: 'null' - type: string + required: + - createdAt + - updatedAt + - title + - authorId + - published + - viewCount + - notes relationships: type: object properties: @@ -2625,6 +3110,165 @@ components: allOf: - $ref: '#/components/schemas/_links' - $ref: '#/components/schemas/_pagination' + PostLike: + type: object + description: The "PostLike" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + postId: + type: string + userId: + type: string + required: + - postId + - userId + relationships: + type: object + properties: + post: + $ref: '#/components/schemas/_toOneRelationshipWithLinks' + user: + $ref: '#/components/schemas/_toOneRelationshipWithLinks' + PostLikeCreateRequest: + type: object + description: Input for creating a "PostLike" + required: + - data + properties: + data: + type: object + description: The "PostLike" model + required: + - id + - type + - attributes + properties: + type: + type: string + attributes: + type: object + required: + - postId + - userId + properties: + postId: + type: string + userId: + type: string + relationships: + type: object + properties: + post: + $ref: '#/components/schemas/_toOneRelationship' + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + PostLikeUpdateRequest: + type: object + description: Input for updating a "PostLike" + required: + - data + properties: + data: + type: object + description: The "PostLike" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + postId: + type: string + userId: + type: string + relationships: + type: object + properties: + post: + $ref: '#/components/schemas/_toOneRelationship' + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + PostLikeResponse: + type: object + description: Response for a "PostLike" + required: + - data + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + allOf: + - $ref: '#/components/schemas/PostLike' + - type: object + properties: + relationships: + type: object + properties: + post: + $ref: '#/components/schemas/_toOneRelationship' + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + $ref: '#/components/schemas/_links' + PostLikeListResponse: + type: object + description: Response for a list of "PostLike" + required: + - data + - links + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + type: array + items: + allOf: + - $ref: '#/components/schemas/PostLike' + - type: object + properties: + relationships: + type: object + properties: + post: + $ref: '#/components/schemas/_toOneRelationship' + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + allOf: + - $ref: '#/components/schemas/_links' + - $ref: '#/components/schemas/_pagination' parameters: id: name: id diff --git a/packages/plugins/openapi/tests/openapi-restful.test.ts b/packages/plugins/openapi/tests/openapi-restful.test.ts index 9997dd540..8fd0880ff 100644 --- a/packages/plugins/openapi/tests/openapi-restful.test.ts +++ b/packages/plugins/openapi/tests/openapi-restful.test.ts @@ -35,6 +35,7 @@ model User { role role @default(USER) posts post_Item[] profile Profile? + likes PostLike[] } model Profile { @@ -55,12 +56,21 @@ model post_Item { published Boolean @default(false) viewCount Int @default(0) notes String? + likes PostLike[] @@openapi.meta({ tagDescription: 'Post-related operations' }) } +model PostLike { + post post_Item @relation(fields: [postId], references: [id]) + postId String + user User @relation(fields: [userId], references: [id]) + userId String + @@id([postId, userId]) +} + model Foo { id String @id @@openapi.ignore @@ -98,9 +108,15 @@ model Bar { expect(api.paths?.['/user/{id}/relationships/posts']?.['get']).toBeTruthy(); expect(api.paths?.['/user/{id}/relationships/posts']?.['post']).toBeTruthy(); expect(api.paths?.['/user/{id}/relationships/posts']?.['patch']).toBeTruthy(); + expect(api.paths?.['/user/{id}/relationships/likes']?.['get']).toBeTruthy(); + expect(api.paths?.['/user/{id}/relationships/likes']?.['post']).toBeTruthy(); + expect(api.paths?.['/user/{id}/relationships/likes']?.['patch']).toBeTruthy(); expect(api.paths?.['/post_Item/{id}/relationships/author']?.['get']).toBeTruthy(); expect(api.paths?.['/post_Item/{id}/relationships/author']?.['post']).toBeUndefined(); expect(api.paths?.['/post_Item/{id}/relationships/author']?.['patch']).toBeTruthy(); + expect(api.paths?.['/post_Item/{id}/relationships/likes']?.['get']).toBeTruthy(); + expect(api.paths?.['/post_Item/{id}/relationships/likes']?.['post']).toBeTruthy(); + expect(api.paths?.['/post_Item/{id}/relationships/likes']?.['patch']).toBeTruthy(); expect(api.paths?.['/foo']).toBeUndefined(); expect(api.paths?.['/bar']).toBeUndefined(); @@ -323,6 +339,35 @@ model Foo { expect(parsed).toMatchObject(baseline); } }); + + it('exposes individual fields from a compound id as attributes', async () => { + const { model, dmmf, modelFile } = await loadZModelAndDmmf(` +plugin openapi { + provider = '${normalizePath(path.resolve(__dirname, '../dist'))}' +} + +model User { + email String + role String + company String + @@id([role, company]) +} + `); + + const { name: output } = tmp.fileSync({ postfix: '.yaml' }); + + const options = buildOptions(model, modelFile, output, '3.1.0'); + await generate(model, options, dmmf); + + await OpenAPIParser.validate(output); + + const parsed = YAML.parse(fs.readFileSync(output, 'utf-8')); + expect(parsed.openapi).toBe('3.1.0'); + + expect(Object.keys(parsed.components.schemas.User.properties.attributes.properties)).toEqual( + expect.arrayContaining(['role', 'company']) + ); + }); }); function buildOptions(model: Model, modelFile: string, output: string, specVersion = '3.0.0') { diff --git a/packages/plugins/swr/package.json b/packages/plugins/swr/package.json index 82139bf43..c98ab6c24 100644 --- a/packages/plugins/swr/package.json +++ b/packages/plugins/swr/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/swr", "displayName": "ZenStack plugin for generating SWR hooks", - "version": "2.6.2", + "version": "2.7.0", "description": "ZenStack plugin for generating SWR hooks", "main": "index.js", "repository": { diff --git a/packages/plugins/tanstack-query/package.json b/packages/plugins/tanstack-query/package.json index ed1f76527..7448796bd 100644 --- a/packages/plugins/tanstack-query/package.json +++ b/packages/plugins/tanstack-query/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/tanstack-query", "displayName": "ZenStack plugin for generating tanstack-query hooks", - "version": "2.6.2", + "version": "2.7.0", "description": "ZenStack plugin for generating tanstack-query hooks", "main": "index.js", "exports": { @@ -92,7 +92,7 @@ }, "devDependencies": { "@tanstack/react-query": "^4.29.7", - "@tanstack/react-query-v5": "npm:@tanstack/react-query@^5.0.0", + "@tanstack/react-query-v5": "npm:@tanstack/react-query@5.56.x", "@tanstack/svelte-query": "^4.29.7", "@tanstack/svelte-query-v5": "npm:@tanstack/svelte-query@^5.0.0", "@tanstack/vue-query": "^4.37.0", diff --git a/packages/plugins/tanstack-query/src/runtime/common.ts b/packages/plugins/tanstack-query/src/runtime/common.ts index 40830b3ee..2d6793c8a 100644 --- a/packages/plugins/tanstack-query/src/runtime/common.ts +++ b/packages/plugins/tanstack-query/src/runtime/common.ts @@ -385,6 +385,11 @@ async function optimisticUpdate( state: { data, error }, } = cacheItem; + if (!isZenStackQueryKey(queryKey)) { + // skip non-zenstack queries + continue; + } + if (error) { if (logging) { console.warn(`Skipping optimistic update for ${JSON.stringify(queryKey)} due to error:`, error); @@ -392,8 +397,8 @@ async function optimisticUpdate( continue; } - const [_, queryModel, queryOperation, queryArgs, { optimisticUpdate }] = queryKey as QueryKey; - if (!optimisticUpdate) { + const [_, queryModel, queryOperation, queryArgs, queryOptions] = queryKey; + if (!queryOptions?.optimisticUpdate) { if (logging) { console.log(`Skipping optimistic update for ${JSON.stringify(queryKey)} due to opt-out`); } @@ -450,3 +455,15 @@ async function optimisticUpdate( } } } + +function isZenStackQueryKey(queryKey: readonly unknown[]): queryKey is QueryKey { + if (queryKey.length < 5) { + return false; + } + + if (queryKey[0] !== QUERY_KEY_PREFIX) { + return false; + } + + return true; +} diff --git a/packages/plugins/tanstack-query/tests/plugin.test.ts b/packages/plugins/tanstack-query/tests/plugin.test.ts index 42cb3da29..7fc7a18b3 100644 --- a/packages/plugins/tanstack-query/tests/plugin.test.ts +++ b/packages/plugins/tanstack-query/tests/plugin.test.ts @@ -113,7 +113,7 @@ ${sharedModel} { provider: 'postgresql', pushDb: false, - extraDependencies: ['react@18.2.0', '@types/react@18.2.0', '@tanstack/react-query@^5.0.0'], + extraDependencies: ['react@18.2.0', '@types/react@18.2.0', '@tanstack/react-query@5.56.x'], copyDependencies: [path.resolve(__dirname, '../dist')], compile: true, extraSourceFiles: [ diff --git a/packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx b/packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx index a52da3316..51f7de64f 100644 --- a/packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx +++ b/packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx @@ -1,7 +1,9 @@ /** * @jest-environment jsdom */ -import { QueryClient, QueryClientProvider } from '@tanstack/react-query-v5'; +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query-v5'; import { act, renderHook, waitFor } from '@testing-library/react'; import nock from 'nock'; import React from 'react'; @@ -470,6 +472,118 @@ describe('Tanstack Query React Hooks V5 Test', () => { }); }); + it('optimistic upsert - create', async () => { + const { queryClient, wrapper } = createWrapper(); + + const data: any[] = []; + + nock(makeUrl('User', 'findMany')) + .get(/.*/) + .reply(200, () => { + console.log('Querying data:', JSON.stringify(data)); + return { data }; + }) + .persist(); + + const { result } = renderHook( + () => useModelQuery('User', makeUrl('User', 'findMany'), undefined, { optimisticUpdate: true }), + { + wrapper, + } + ); + await waitFor(() => { + expect(result.current.data).toHaveLength(0); + }); + + nock(makeUrl('User', 'upsert')) + .post(/.*/) + .reply(200, () => { + console.log('Not mutating data'); + return { data: null }; + }); + + const { result: mutationResult } = renderHook( + () => + useModelMutation('User', 'POST', makeUrl('User', 'upsert'), modelMeta, { + optimisticUpdate: true, + invalidateQueries: false, + }), + { + wrapper, + } + ); + + act(() => + mutationResult.current.mutate({ + where: { id: '1' }, + create: { id: '1', name: 'foo' }, + update: { name: 'bar' }, + }) + ); + + await waitFor(() => { + const cacheData: any = queryClient.getQueryData( + getQueryKey('User', 'findMany', undefined, { infinite: false, optimisticUpdate: true }) + ); + expect(cacheData).toHaveLength(1); + expect(cacheData[0].$optimistic).toBe(true); + expect(cacheData[0].id).toBeTruthy(); + expect(cacheData[0].name).toBe('foo'); + }); + }); + + it('optimistic upsert - update', async () => { + const { queryClient, wrapper } = createWrapper(); + + const queryArgs = { where: { id: '1' } }; + const data = { id: '1', name: 'foo' }; + + nock(makeUrl('User', 'findUnique', queryArgs)) + .get(/.*/) + .reply(200, () => { + console.log('Querying data:', JSON.stringify(data)); + return { data }; + }) + .persist(); + + const { result } = renderHook( + () => useModelQuery('User', makeUrl('User', 'findUnique'), queryArgs, { optimisticUpdate: true }), + { + wrapper, + } + ); + await waitFor(() => { + expect(result.current.data).toMatchObject({ name: 'foo' }); + }); + + nock(makeUrl('User', 'upsert')) + .post(/.*/) + .reply(200, () => { + console.log('Not mutating data'); + return data; + }); + + const { result: mutationResult } = renderHook( + () => + useModelMutation('User', 'POST', makeUrl('User', 'upsert'), modelMeta, { + optimisticUpdate: true, + invalidateQueries: false, + }), + { + wrapper, + } + ); + + act(() => mutationResult.current.mutate({ ...queryArgs, update: { name: 'bar' }, create: { name: 'zee' } })); + + await waitFor(() => { + const cacheData = queryClient.getQueryData( + getQueryKey('User', 'findUnique', queryArgs, { infinite: false, optimisticUpdate: true }) + ); + expect(cacheData).toMatchObject({ name: 'bar', $optimistic: true }); + }); + }); + it('delete and invalidation', async () => { const { queryClient, wrapper } = createWrapper(); @@ -749,4 +863,69 @@ describe('Tanstack Query React Hooks V5 Test', () => { expect(cacheData[0].name).toBe('foohooray'); }); }); + + it('optimistic update mixed with non-zenstack queries', async () => { + const { queryClient, wrapper } = createWrapper(); + + // non-zenstack query + const { result: myQueryResult } = renderHook( + () => useQuery({ queryKey: ['myQuery'], queryFn: () => ({ data: 'myData' }) }), + { + wrapper, + } + ); + await waitFor(() => { + expect(myQueryResult.current.data).toEqual({ data: 'myData' }); + }); + + const data: any[] = []; + + nock(makeUrl('User', 'findMany')) + .get(/.*/) + .reply(200, () => { + console.log('Querying data:', JSON.stringify(data)); + return { data }; + }) + .persist(); + + const { result } = renderHook( + () => useModelQuery('User', makeUrl('User', 'findMany'), undefined, { optimisticUpdate: true }), + { + wrapper, + } + ); + await waitFor(() => { + expect(result.current.data).toHaveLength(0); + }); + + nock(makeUrl('User', 'create')) + .post(/.*/) + .reply(200, () => { + console.log('Not mutating data'); + return { data: null }; + }); + + const { result: mutationResult } = renderHook( + () => + useModelMutation('User', 'POST', makeUrl('User', 'create'), modelMeta, { + optimisticUpdate: true, + invalidateQueries: false, + }), + { + wrapper, + } + ); + + act(() => mutationResult.current.mutate({ data: { name: 'foo' } })); + + await waitFor(() => { + const cacheData: any = queryClient.getQueryData( + getQueryKey('User', 'findMany', undefined, { infinite: false, optimisticUpdate: true }) + ); + expect(cacheData).toHaveLength(1); + expect(cacheData[0].$optimistic).toBe(true); + expect(cacheData[0].id).toBeTruthy(); + expect(cacheData[0].name).toBe('foo'); + }); + }); }); diff --git a/packages/plugins/tanstack-query/tests/react-hooks.test.tsx b/packages/plugins/tanstack-query/tests/react-hooks.test.tsx index c788988de..48ff6b650 100644 --- a/packages/plugins/tanstack-query/tests/react-hooks.test.tsx +++ b/packages/plugins/tanstack-query/tests/react-hooks.test.tsx @@ -1,6 +1,8 @@ /** * @jest-environment jsdom */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { act, renderHook, waitFor } from '@testing-library/react'; import nock from 'nock'; @@ -389,6 +391,122 @@ describe('Tanstack Query React Hooks V4 Test', () => { }); }); + it('optimistic upsert - create', async () => { + const { queryClient, wrapper } = createWrapper(); + + const data: any[] = []; + + nock(makeUrl('User', 'findMany')) + .get(/.*/) + .reply(200, () => { + console.log('Querying data:', JSON.stringify(data)); + return { data }; + }) + .persist(); + + const { result } = renderHook( + () => useModelQuery('User', makeUrl('User', 'findMany'), undefined, { optimisticUpdate: true }), + { + wrapper, + } + ); + await waitFor(() => { + expect(result.current.data).toHaveLength(0); + }); + + nock(makeUrl('User', 'upsert')) + .post(/.*/) + .reply(200, () => { + console.log('Not mutating data'); + return { data: null }; + }); + + const { result: mutationResult } = renderHook( + () => + useModelMutation( + 'User', + 'POST', + makeUrl('User', 'upsert'), + modelMeta, + { optimisticUpdate: true, invalidateQueries: false }, + undefined + ), + { + wrapper, + } + ); + + act(() => + mutationResult.current.mutate({ + where: { id: '1' }, + create: { id: '1', name: 'foo' }, + update: { name: 'bar' }, + }) + ); + + await waitFor(() => { + const cacheData: any = queryClient.getQueryData(getQueryKey('User', 'findMany', undefined)); + expect(cacheData).toHaveLength(1); + expect(cacheData[0].$optimistic).toBe(true); + expect(cacheData[0].id).toBeTruthy(); + expect(cacheData[0].name).toBe('foo'); + }); + }); + + it('optimistic upsert - update', async () => { + const { queryClient, wrapper } = createWrapper(); + + const queryArgs = { where: { id: '1' } }; + const data = { id: '1', name: 'foo' }; + + nock(makeUrl('User', 'findUnique', queryArgs)) + .get(/.*/) + .reply(200, () => { + console.log('Querying data:', JSON.stringify(data)); + return { data }; + }) + .persist(); + + const { result } = renderHook( + () => useModelQuery('User', makeUrl('User', 'findUnique'), queryArgs, { optimisticUpdate: true }), + { + wrapper, + } + ); + await waitFor(() => { + expect(result.current.data).toMatchObject({ name: 'foo' }); + }); + + nock(makeUrl('User', 'upsert')) + .post(/.*/) + .reply(200, () => { + console.log('Not mutating data'); + return data; + }); + + const { result: mutationResult } = renderHook( + () => + useModelMutation( + 'User', + 'POST', + makeUrl('User', 'upsert'), + modelMeta, + { optimisticUpdate: true, invalidateQueries: false }, + undefined + ), + { + wrapper, + } + ); + + act(() => mutationResult.current.mutate({ ...queryArgs, update: { name: 'bar' }, create: { name: 'zee' } })); + + await waitFor(() => { + const cacheData = queryClient.getQueryData(getQueryKey('User', 'findUnique', queryArgs)); + expect(cacheData).toMatchObject({ name: 'bar', $optimistic: true }); + }); + }); + it('delete and invalidation', async () => { const { queryClient, wrapper } = createWrapper(); diff --git a/packages/plugins/trpc/package.json b/packages/plugins/trpc/package.json index 149d5d01f..040767fdb 100644 --- a/packages/plugins/trpc/package.json +++ b/packages/plugins/trpc/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/trpc", "displayName": "ZenStack plugin for tRPC", - "version": "2.6.2", + "version": "2.7.0", "description": "ZenStack plugin for tRPC", "main": "index.js", "repository": { diff --git a/packages/plugins/trpc/res/client/v10/next.ts b/packages/plugins/trpc/res/client/v10/next.ts index fecac441c..6e7db4142 100644 --- a/packages/plugins/trpc/res/client/v10/next.ts +++ b/packages/plugins/trpc/res/client/v10/next.ts @@ -4,7 +4,6 @@ import type { AnyRouter } from '@trpc/server'; import type { NextPageContext } from 'next'; import { type CreateTRPCNext, createTRPCNext as _createTRPCNext } from '@trpc/next'; import type { DeepOverrideAtPath } from './utils'; -import type { ClientType } from '../routers'; export function createTRPCNext< TRouter extends AnyRouter, diff --git a/packages/plugins/trpc/res/client/v10/nuxt.ts b/packages/plugins/trpc/res/client/v10/nuxt.ts new file mode 100644 index 000000000..5fe0591c8 --- /dev/null +++ b/packages/plugins/trpc/res/client/v10/nuxt.ts @@ -0,0 +1,12 @@ +/* eslint-disable */ + +import type { AnyRouter } from '@trpc/server'; +import { createTRPCNuxtClient as _createTRPCNuxtClient } from 'trpc-nuxt/client'; +import type { DeepOverrideAtPath } from './utils'; + +export function createTRPCNuxtClient( + opts: Parameters>[0] +) { + const r = _createTRPCNuxtClient(opts); + return r as DeepOverrideAtPath, TPath>; +} diff --git a/packages/plugins/trpc/res/client/v10/react.ts b/packages/plugins/trpc/res/client/v10/react.ts index e4c67e3c5..5b204819c 100644 --- a/packages/plugins/trpc/res/client/v10/react.ts +++ b/packages/plugins/trpc/res/client/v10/react.ts @@ -4,7 +4,6 @@ import type { AnyRouter } from '@trpc/server'; import type { CreateTRPCReactOptions } from '@trpc/react-query/shared'; import { type CreateTRPCReact, createTRPCReact as _createTRPCReact } from '@trpc/react-query'; import type { DeepOverrideAtPath } from './utils'; -import type { ClientType } from '../routers'; export function createTRPCReact< TRouter extends AnyRouter, diff --git a/packages/plugins/trpc/res/client/v10/utils.ts b/packages/plugins/trpc/res/client/v10/utils.ts index 223fde54d..9b0daacdb 100644 --- a/packages/plugins/trpc/res/client/v10/utils.ts +++ b/packages/plugins/trpc/res/client/v10/utils.ts @@ -30,3 +30,17 @@ export type DeepOverrideAtPath & Record> : never; + +// Utility type from 'trpc-nuxt' +export type KeysOf = Array; + +// Utility type from 'trpc-nuxt' +export type PickFrom> = T extends Array + ? T + : T extends Record + ? keyof T extends K[number] + ? T + : K[number] extends never + ? T + : Pick + : T; diff --git a/packages/plugins/trpc/res/client/v11/next.ts b/packages/plugins/trpc/res/client/v11/next.ts index 659d657a7..edd0072b2 100644 --- a/packages/plugins/trpc/res/client/v11/next.ts +++ b/packages/plugins/trpc/res/client/v11/next.ts @@ -4,7 +4,6 @@ import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; import type { NextPageContext } from 'next'; import { type CreateTRPCNext, createTRPCNext as _createTRPCNext } from '@trpc/next'; import type { DeepOverrideAtPath } from './utils'; -import type { ClientType } from '../routers'; export function createTRPCNext< TRouter extends AnyRouter, diff --git a/packages/plugins/trpc/res/client/v11/nuxt.ts b/packages/plugins/trpc/res/client/v11/nuxt.ts new file mode 100644 index 000000000..b107fdf0b --- /dev/null +++ b/packages/plugins/trpc/res/client/v11/nuxt.ts @@ -0,0 +1,12 @@ +/* eslint-disable */ + +import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; +import { createTRPCNuxtClient as _createTRPCNuxtClient } from 'trpc-nuxt/client'; +import type { DeepOverrideAtPath } from './utils'; + +export function createTRPCNuxtClient( + opts: Parameters>[0] +) { + const r = _createTRPCNuxtClient(opts); + return r as DeepOverrideAtPath, TPath>; +} diff --git a/packages/plugins/trpc/res/client/v11/react.ts b/packages/plugins/trpc/res/client/v11/react.ts index be69328fe..43a1f33eb 100644 --- a/packages/plugins/trpc/res/client/v11/react.ts +++ b/packages/plugins/trpc/res/client/v11/react.ts @@ -4,7 +4,6 @@ import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; import type { CreateTRPCReactOptions } from '@trpc/react-query/shared'; import { type CreateTRPCReact, createTRPCReact as _createTRPCReact } from '@trpc/react-query'; import type { DeepOverrideAtPath } from './utils'; -import type { ClientType } from '../routers'; export function createTRPCReact< TRouter extends AnyRouter, diff --git a/packages/plugins/trpc/res/client/v11/utils.ts b/packages/plugins/trpc/res/client/v11/utils.ts deleted file mode 100644 index 223fde54d..000000000 --- a/packages/plugins/trpc/res/client/v11/utils.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-disable */ - -// inspired by: https://stackoverflow.com/questions/70632026/generic-to-recursively-modify-a-given-type-interface-in-typescript - -type Primitive = string | Function | number | boolean | Symbol | undefined | null; - -/** - * Recursively merges `T` and `R`. If there's a shared key, use `R`'s field type to overwrite `T`. - */ -export type DeepOverride = T extends Primitive - ? R - : R extends Primitive - ? R - : { - [K in keyof T]: K extends keyof R ? DeepOverride : T[K]; - } & { - [K in Exclude]: R[K]; - }; - -/** - * Traverse to `Path` (denoted by dot separated string literal type) in `T`, and starting from there, - * recursively merge with `R`. - */ -export type DeepOverrideAtPath = Path extends undefined - ? DeepOverride - : Path extends `${infer P1}.${infer P2}` - ? P1 extends keyof T - ? Omit & Record>> - : never - : Path extends keyof T - ? Omit & Record> - : never; diff --git a/packages/plugins/trpc/res/client/v11/utils.ts b/packages/plugins/trpc/res/client/v11/utils.ts new file mode 120000 index 000000000..45919501d --- /dev/null +++ b/packages/plugins/trpc/res/client/v11/utils.ts @@ -0,0 +1 @@ +../v10/utils.ts \ No newline at end of file diff --git a/packages/plugins/trpc/src/client-helper/index.ts b/packages/plugins/trpc/src/client-helper/index.ts new file mode 100644 index 000000000..f296ca1ab --- /dev/null +++ b/packages/plugins/trpc/src/client-helper/index.ts @@ -0,0 +1,289 @@ +import { PluginError, type PluginOptions } from '@zenstackhq/sdk'; +import { getPrismaClientImportSpec } from '@zenstackhq/sdk/prisma'; +import fs from 'fs'; +import { lowerCaseFirst } from 'lower-case-first'; +import path from 'path'; +import { + InterfaceDeclarationStructure, + Project, + PropertySignatureStructure, + SourceFile, + StructureKind, +} from 'ts-morph'; +import { upperCaseFirst } from 'upper-case-first'; +import { name } from '..'; +import { SupportedClientHelpers } from '../utils'; +import * as NextHelpers from './next'; +import * as NuxtHelpers from './nuxt'; +import * as ReactHelpers from './react'; + +const helpers = { + react: ReactHelpers, + next: NextHelpers, + nuxt: NuxtHelpers, +}; + +export function generateClientTypingForModel( + project: Project, + generateClientHelpers: SupportedClientHelpers[], + model: string, + options: PluginOptions, + generateOperations: Array<{ name: string; baseType: string }>, + version: string, + outDir: string +) { + for (const clientType of generateClientHelpers) { + const sf = project.createSourceFile( + path.resolve(outDir, `client/${upperCaseFirst(model)}.${clientType}.type.ts`), + undefined, + { + overwrite: true, + } + ); + + sf.addStatements([`/* eslint-disable */`]); + + generateImports(clientType, sf, options, version); + + // generate a `ClientType` interface that contains typing for query/mutation operations + const routerTypingStructure: InterfaceDeclarationStructure = { + kind: StructureKind.Interface, + name: 'ClientType', + isExported: true, + typeParameters: ['AppRouter extends AnyRouter', `Context = AppRouter['_def']['_config']['$types']['ctx']`], + properties: [] as PropertySignatureStructure[], + }; + + for (const { name: generateOpName, baseType: baseOpType } of generateOperations) { + routerTypingStructure.properties?.push({ + kind: StructureKind.PropertySignature, + name: generateOpName, + type: (writer) => { + helpers[clientType].generateProcedureTyping(writer, generateOpName, model, baseOpType, version); + }, + }); + } + + sf.addInterface(routerTypingStructure); + } +} + +function generateImports( + clientHelperType: SupportedClientHelpers, + sourceFile: SourceFile, + options: PluginOptions, + version: string +) { + const importingDir = sourceFile.getDirectoryPath(); + const prismaImport = getPrismaClientImportSpec(importingDir, options); + sourceFile.addStatements([ + `import type { Prisma } from '${prismaImport}';`, + `import type { TRPCClientErrorLike, TRPCRequestOptions } from '@trpc/client';`, + ]); + + // generate framework-specific imports + helpers[clientHelperType].generateRouterTypingImports(sourceFile, version); +} + +export function createClientHelperEntries( + project: Project, + outputDir: string, + generateClientHelpers: SupportedClientHelpers[], + models: string[], + version: string +) { + // generate utils + const content = fs.readFileSync(path.join(__dirname, `../res/client/${version}/utils.ts`), 'utf-8'); + project.createSourceFile(path.resolve(outputDir, 'client', `utils.ts`), content, { + overwrite: true, + }); + + for (const client of generateClientHelpers) { + createClientHelperEntryForType(project, client, models, version, outputDir); + } +} + +function createClientHelperEntryForType( + project: Project, + clientHelperType: SupportedClientHelpers, + models: string[], + version: string, + outputDir: string +) { + const content = fs.readFileSync(path.join(__dirname, `../res/client/${version}/${clientHelperType}.ts`), 'utf-8'); + const sf = project.createSourceFile(path.resolve(outputDir, 'client', `${clientHelperType}.ts`), content, { + overwrite: true, + }); + + sf.addInterface({ + name: 'ClientType', + typeParameters: ['AppRouter extends AnyRouter'], + isExported: true, + properties: models.map((model) => { + sf.addImportDeclaration({ + namedImports: [{ name: 'ClientType', alias: `${upperCaseFirst(model)}ClientType` }], + moduleSpecifier: `./${upperCaseFirst(model)}.${clientHelperType}.type`, + }); + return { + name: lowerCaseFirst(model), + type: `${upperCaseFirst(model)}ClientType`, + } as PropertySignatureStructure; + }), + }); +} + +/** + * Given a model and Prisma operation, returns related TS types. + */ +export function getPrismaOperationTypes(model: string, operation: string) { + // TODO: find a way to derive from Prisma Client API's generic types + // instead of duplicating them + + const capModel = upperCaseFirst(model); + const capOperation = upperCaseFirst(operation); + + let genericBase = `Prisma.${capModel}${capOperation}Args`; + const getPayload = `Prisma.${capModel}GetPayload`; + const selectSubset = `Prisma.SelectSubset`; + + let argsType: string; + let resultType: string; + const argsOptional = ['findMany', 'findFirst', 'findFirstOrThrow', 'createMany', 'deleteMany', 'count'].includes( + operation + ); + + switch (operation) { + case 'findUnique': + case 'findFirst': + argsType = selectSubset; + resultType = `${getPayload} | null`; + break; + + case 'findUniqueOrThrow': + case 'findFirstOrThrow': + argsType = selectSubset; + resultType = getPayload; + break; + + case 'findMany': + argsType = selectSubset; + resultType = `Array<${getPayload}>`; + break; + + case 'create': + argsType = selectSubset; + resultType = getPayload; + break; + + case 'createMany': + argsType = selectSubset; + resultType = `Prisma.BatchPayload`; + break; + + case 'update': + argsType = selectSubset; + resultType = getPayload; + break; + + case 'updateMany': + argsType = selectSubset; + resultType = `Prisma.BatchPayload`; + break; + + case 'upsert': + argsType = selectSubset; + resultType = getPayload; + break; + + case 'delete': + argsType = selectSubset; + resultType = getPayload; + break; + + case 'deleteMany': + argsType = selectSubset; + resultType = `Prisma.BatchPayload`; + break; + + case 'count': + argsType = `Prisma.Subset`; + resultType = `'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number`; + break; + + case 'aggregate': + argsType = `Prisma.Subset`; + resultType = `Prisma.Get${capModel}AggregateType`; + break; + + case 'groupBy': + genericBase = `Prisma.${capModel}GroupByArgs, + HasSelectOrTake extends Prisma.Or< + Prisma.Extends<'skip', Prisma.Keys>, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.${capModel}GroupByArgs['orderBy'] } + : { orderBy?: Prisma.${capModel}GroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? \`Error: "by" must not be empty.\` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? \`Error: Field "\${P}" used in "having" needs to be provided in "by".\` + : [ + Error, + 'Field ', + P, + \` in "having" needs to be provided in "by"\`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : \`Error: Field "\${P}" in "orderBy" needs to be provided in "by"\` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : \`Error: Field "\${P}" in "orderBy" needs to be provided in "by"\` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : \`Error: Field "\${P}" in "orderBy" needs to be provided in "by"\` + }[OrderFields] + `; + argsType = `Prisma.SubsetIntersection & InputErrors`; + resultType = `{} extends InputErrors ? Prisma.Get${capModel}GroupByPayload : InputErrors`; + break; + + default: + throw new PluginError(name, `Unsupported operation: "${operation}"`); + } + + return { genericBase, argsType, resultType, argsOptional }; +} diff --git a/packages/plugins/trpc/src/client-helper/next.ts b/packages/plugins/trpc/src/client-helper/next.ts new file mode 100644 index 000000000..d71b66e76 --- /dev/null +++ b/packages/plugins/trpc/src/client-helper/next.ts @@ -0,0 +1,21 @@ +import { CodeBlockWriter, SourceFile } from 'ts-morph'; +import { + generateProcedureTyping as generateProcedureTypingForReact, + generateRouterTypingImports as generateRouterTypingImportsForReact, +} from './react'; + +export function generateRouterTypingImports(sourceFile: SourceFile, version: string) { + // next shares the same typing imports as react + generateRouterTypingImportsForReact(sourceFile, version); +} + +export function generateProcedureTyping( + writer: CodeBlockWriter, + opType: string, + modelName: string, + baseOpType: string, + version: string +) { + // next shares the same procedure typing as react + generateProcedureTypingForReact(writer, opType, modelName, baseOpType, version); +} diff --git a/packages/plugins/trpc/src/client-helper/nuxt.ts b/packages/plugins/trpc/src/client-helper/nuxt.ts new file mode 100644 index 000000000..abd8a69c0 --- /dev/null +++ b/packages/plugins/trpc/src/client-helper/nuxt.ts @@ -0,0 +1,57 @@ +import { CodeBlockWriter, SourceFile } from 'ts-morph'; +import { getProcedureTypeByOpName } from '../utils'; +import { getPrismaOperationTypes } from '.'; + +export function generateRouterTypingImports(sourceFile: SourceFile, version: string) { + sourceFile.addStatements([ + `import type { MaybeRefOrGetter, UnwrapRef } from 'vue';`, + `import type { AsyncData, AsyncDataOptions } from 'nuxt/app';`, + `import type { KeysOf, PickFrom } from './utils';`, + ]); + + if (version === 'v10') { + sourceFile.addStatements([`import type { AnyRouter } from '@trpc/server';`]); + } else { + sourceFile.addStatements([`import type { AnyTRPCRouter as AnyRouter } from '@trpc/server';`]); + } +} + +export function generateProcedureTyping( + writer: CodeBlockWriter, + opType: string, + modelName: string, + baseOpType: string, + _version: string +) { + const procType = getProcedureTypeByOpName(baseOpType); + const { genericBase, argsType, argsOptional, resultType } = getPrismaOperationTypes(modelName, opType); + const errorType = `TRPCClientErrorLike`; + const inputOptional = argsOptional ? '?' : ''; + + writer.block(() => { + if (procType === 'query') { + writer.writeLine(` + query: (input${inputOptional}: ${argsType}) => Promise<${resultType}>; + useQuery: = KeysOf, DefaultT = null>(input${inputOptional}: MaybeRefOrGetter<${argsType}>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: = KeysOf, DefaultT = null>(input${inputOptional}: MaybeRefOrGetter<${argsType}>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + `); + } else if (procType === 'mutation') { + writer.writeLine(` + mutate: (input${inputOptional}: ${argsType}) => Promise<${resultType}>; + useMutation: = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: = KeysOf>(input${inputOptional}: ${argsType}) => Promise | null, DataE>['data']>>; + }; + `); + } + }); +} diff --git a/packages/plugins/trpc/src/client-helper/react.ts b/packages/plugins/trpc/src/client-helper/react.ts new file mode 100644 index 000000000..9708ab24f --- /dev/null +++ b/packages/plugins/trpc/src/client-helper/react.ts @@ -0,0 +1,92 @@ +import { CodeBlockWriter, SourceFile } from 'ts-morph'; +import { getProcedureTypeByOpName } from '../utils'; +import { getPrismaOperationTypes } from '.'; + +export function generateRouterTypingImports(sourceFile: SourceFile, version: string) { + sourceFile.addStatements([ + `import type { UseTRPCMutationOptions, UseTRPCMutationResult, UseTRPCQueryOptions, UseTRPCQueryResult, UseTRPCInfiniteQueryOptions, UseTRPCInfiniteQueryResult } from '@trpc/react-query/shared';`, + ]); + if (version === 'v10') { + sourceFile.addStatements([`import type { AnyRouter } from '@trpc/server';`]); + } else { + sourceFile.addStatements([ + `import type { AnyTRPCRouter as AnyRouter } from '@trpc/server';`, + `import type { UseTRPCSuspenseQueryOptions, UseTRPCSuspenseQueryResult, UseTRPCSuspenseInfiniteQueryOptions, UseTRPCSuspenseInfiniteQueryResult } from '@trpc/react-query/shared';`, + ]); + } +} + +export function generateProcedureTyping( + writer: CodeBlockWriter, + opType: string, + modelName: string, + baseOpType: string, + version: string +) { + const procType = getProcedureTypeByOpName(baseOpType); + const { genericBase, argsType, argsOptional, resultType } = getPrismaOperationTypes(modelName, opType); + const errorType = `TRPCClientErrorLike`; + const inputOptional = argsOptional ? '?' : ''; + + writer.block(() => { + if (procType === 'query') { + if (version === 'v10') { + writer.writeLine(` + useQuery: ( + input${inputOptional}: ${argsType}, + opts?: UseTRPCQueryOptions + ) => UseTRPCQueryResult< + TData, + ${errorType} + >; + useInfiniteQuery: ( + input${inputOptional}: Omit<${argsType}, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions + ) => UseTRPCInfiniteQueryResult< + ${resultType}, + ${errorType} + >; + `); + } else { + writer.writeLine(` + useQuery: ( + input${inputOptional}: ${argsType}, + opts?: UseTRPCQueryOptions<${resultType}, TData, Error> + ) => UseTRPCQueryResult< + TData, + ${errorType} + >; + useInfiniteQuery: ( + input${inputOptional}: Omit<${argsType}, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions + ) => UseTRPCInfiniteQueryResult< + ${resultType}, + ${errorType}, + T + >; + useSuspenseQuery: ( + input${inputOptional}: ${argsType}, + opts?: UseTRPCSuspenseQueryOptions<${resultType}, TData, Error> + ) => UseTRPCSuspenseQueryResult; + useSuspenseInfiniteQuery: ( + input${inputOptional}: Omit<${argsType}, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions + ) => UseTRPCSuspenseInfiniteQueryResult<${resultType}, ${errorType}, T>; + `); + } + } else if (procType === 'mutation') { + writer.writeLine(` + useMutation: (opts?: UseTRPCMutationOptions< + ${genericBase}, + ${errorType}, + ${resultType}, + Context + >) => + Omit, 'mutateAsync'> & { + mutateAsync: + (variables${inputOptional}: T, opts?: UseTRPCMutationOptions) => Promise<${resultType}> + }; + `); + } + }); +} diff --git a/packages/plugins/trpc/src/generator.ts b/packages/plugins/trpc/src/generator.ts index b8ae9ec37..6574069f8 100644 --- a/packages/plugins/trpc/src/generator.ts +++ b/packages/plugins/trpc/src/generator.ts @@ -12,22 +12,22 @@ import { } from '@zenstackhq/sdk'; import { DataModel, isDataModel, Model } from '@zenstackhq/sdk/ast'; import { getPrismaClientImportSpec, supportCreateMany, type DMMF } from '@zenstackhq/sdk/prisma'; -import fs from 'fs'; import { lowerCaseFirst } from 'lower-case-first'; import path from 'path'; -import { InterfaceDeclarationStructure, Project, PropertySignatureStructure, StructureKind } from 'ts-morph'; +import { Project } from 'ts-morph'; import { upperCaseFirst } from 'upper-case-first'; import { name } from '.'; +import { createClientHelperEntries, generateClientTypingForModel } from './client-helper'; +import { project } from './project'; import { + AllSupportedClientHelpers, generateHelperImport, generateProcedure, generateRouterSchemaImport, - generateRouterTyping, - generateRouterTypingImports, getInputSchemaByOpName, resolveModelsComments, -} from './helpers'; -import { project } from './project'; + SupportedClientHelpers, +} from './utils'; export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.Document) { // resolve "generateModels" option @@ -38,8 +38,16 @@ export async function generate(model: Model, options: PluginOptions, dmmf: DMMF. // resolve "generateClientHelpers" option const generateClientHelpers = parseOptionAsStrings(options, 'generateClientHelpers', name); - if (generateClientHelpers && !generateClientHelpers.every((v) => ['react', 'next'].includes(v))) { - throw new PluginError(name, `Option "generateClientHelpers" only support values "react" and "next"`); + if ( + generateClientHelpers && + !generateClientHelpers.every((v) => AllSupportedClientHelpers.includes(v as SupportedClientHelpers)) + ) { + throw new PluginError( + name, + `Option "generateClientHelpers" only supports the following values: ${AllSupportedClientHelpers.map( + (n) => '"' + n + '"' + ).join(', ')}.` + ); } if (options.zodSchemasImport && typeof options.zodSchemasImport !== 'string') { @@ -86,7 +94,7 @@ export async function generate(model: Model, options: PluginOptions, dmmf: DMMF. modelOperations, hiddenModels, generateModelActions, - generateClientHelpers, + generateClientHelpers as SupportedClientHelpers[] | undefined, model, zodSchemasImport, options, @@ -103,7 +111,7 @@ function createAppRouter( modelOperations: readonly DMMF.ModelMapping[], hiddenModels: string[], generateModelActions: string[] | undefined, - generateClientHelpers: string[] | undefined, + generateClientHelpers: SupportedClientHelpers[] | undefined, zmodel: Model, zodSchemasImport: string, options: PluginOptions, @@ -238,60 +246,25 @@ function createAppRouter( }); if (generateClientHelpers) { - appRouter.addInterface({ - name: 'ClientType', - typeParameters: ['AppRouter extends AnyRouter'], - isExported: true, - properties: filteredModelOperations.map(({ model }) => { - appRouter.addImportDeclaration({ - namedImports: [{ name: 'ClientType', alias: `${upperCaseFirst(model)}ClientType` }], - moduleSpecifier: `./${model}.router`, - }); - return { - name: lowerCaseFirst(model), - type: `${upperCaseFirst(model)}ClientType`, - } as PropertySignatureStructure; - }), - }); - - createClientHelpers(outDir, generateClientHelpers, version); + createClientHelperEntries( + project, + outDir, + generateClientHelpers, + filteredModelOperations.map(({ model }) => model), + version + ); } appRouter.formatText(); } -function createClientHelpers(outputDir: string, generateClientHelpers: string[], version: string) { - const utils = project.createSourceFile(path.resolve(outputDir, 'client', `utils.ts`), undefined, { - overwrite: true, - }); - utils.replaceWithText(fs.readFileSync(path.join(__dirname, `./res/client/${version}/utils.ts`), 'utf-8')); - - for (const client of generateClientHelpers) { - switch (client) { - case 'react': { - const content = fs.readFileSync(path.join(__dirname, `./res/client/${version}/react.ts`), 'utf-8'); - project.createSourceFile(path.resolve(outputDir, 'client', 'react.ts'), content, { - overwrite: true, - }); - break; - } - - case 'next': { - const content = fs.readFileSync(path.join(__dirname, `./res/client/${version}/next.ts`), 'utf-8'); - project.createSourceFile(path.resolve(outputDir, 'client', 'next.ts'), content, { overwrite: true }); - break; - } - } - } -} - function generateModelCreateRouter( project: Project, model: string, operations: Record, outputDir: string, generateModelActions: string[] | undefined, - generateClientHelpers: string[] | undefined, + generateClientHelpers: SupportedClientHelpers[] | undefined, zodSchemasImport: string, options: PluginOptions, zmodel: Model, @@ -339,11 +312,6 @@ function generateModelCreateRouter( // runtime helpers generateHelperImport(modelRouter); - // client helper imports - if (generateClientHelpers) { - generateRouterTypingImports(modelRouter, options, version); - } - const createRouterFunc = version === 'v10' ? modelRouter.addFunction({ @@ -361,24 +329,13 @@ function generateModelCreateRouter( isDefaultExport: true, }); - let routerTypingStructure: InterfaceDeclarationStructure | undefined = undefined; - if (generateClientHelpers) { - // generate an interface for precise Prisma-like typing for the router procedures - // which will be used to correct tRPC's typing on the client side - routerTypingStructure = { - kind: StructureKind.Interface, - name: 'ClientType', - isExported: true, - typeParameters: ['AppRouter extends AnyRouter', `Context = AppRouter['_def']['_config']['$types']['ctx']`], - properties: [] as PropertySignatureStructure[], - }; - } - const dataModel = zmodel.declarations.find((d): d is DataModel => isDataModel(d) && d.name === model); if (!dataModel) { throw new Error(`Data model "${model}" not found`); } + const generateOperations: Array<{ name: string; baseType: string }> = []; + createRouterFunc.setBodyText((funcWriter) => { funcWriter.write(`return ${version === 'v10' ? 'router' : 'createTRPCRouter'}(`); funcWriter.block(() => { @@ -402,24 +359,23 @@ function generateModelCreateRouter( } generateProcedure(funcWriter, generateOpName, upperCaseFirst(inputType), model, baseOpType); - - if (routerTypingStructure) { - routerTypingStructure.properties?.push({ - kind: StructureKind.PropertySignature, - name: generateOpName, - type: (writer) => { - generateRouterTyping(writer, generateOpName, model, baseOpType, version); - }, - }); - } + generateOperations.push({ name: generateOpName, baseType: baseOpType }); } } }); funcWriter.write(');'); }); - if (routerTypingStructure) { - modelRouter.addInterface(routerTypingStructure); + if (generateClientHelpers) { + generateClientTypingForModel( + project, + generateClientHelpers, + model, + options, + generateOperations, + version, + outputDir + ); } modelRouter.formatText(); diff --git a/packages/plugins/trpc/src/helpers.ts b/packages/plugins/trpc/src/helpers.ts deleted file mode 100644 index 35ee14686..000000000 --- a/packages/plugins/trpc/src/helpers.ts +++ /dev/null @@ -1,412 +0,0 @@ -import { PluginError, type PluginOptions } from '@zenstackhq/sdk'; -import { getPrismaClientImportSpec, type DMMF } from '@zenstackhq/sdk/prisma'; -import { lowerCaseFirst } from 'lower-case-first'; -import { CodeBlockWriter, SourceFile } from 'ts-morph'; -import { upperCaseFirst } from 'upper-case-first'; -import { name } from '.'; - -export function generateProcedure( - writer: CodeBlockWriter, - opType: string, - typeName: string, - modelName: string, - baseOpType: string -) { - const procType = getProcedureTypeByOpName(baseOpType); - const prismaMethod = opType.replace('One', ''); - - if (procType === 'query') { - // the cast "as any" is to circumvent a TS compiler misfired error in certain cases - writer.write(` - ${opType}: procedure.input(${typeName}).query(({ctx, input}) => checkRead(db(ctx).${lowerCaseFirst( - modelName - )}.${prismaMethod}(input as any))), - `); - } else if (procType === 'mutation') { - // the cast "as any" is to circumvent a TS compiler misfired error in certain cases - writer.write(` - ${opType}: procedure.input(${typeName}).mutation(async ({ctx, input}) => checkMutate(db(ctx).${lowerCaseFirst( - modelName - )}.${prismaMethod}(input as any))), - `); - } -} - -/** - * Given a model and Prisma operation, returns related TS types. - */ -function getPrismaOperationTypes(model: string, operation: string) { - // TODO: find a way to derive from Prisma Client API's generic types - // instead of duplicating them - - const capModel = upperCaseFirst(model); - const capOperation = upperCaseFirst(operation); - - let genericBase = `Prisma.${capModel}${capOperation}Args`; - const getPayload = `Prisma.${capModel}GetPayload`; - const selectSubset = `Prisma.SelectSubset`; - - let argsType: string; - let resultType: string; - const argsOptional = ['findMany', 'findFirst', 'findFirstOrThrow', 'createMany', 'deleteMany', 'count'].includes( - operation - ); - - switch (operation) { - case 'findUnique': - case 'findUniqueOrThrow': - case 'findFirst': - case 'findFirstOrThrow': - argsType = selectSubset; - resultType = getPayload; - break; - - case 'findMany': - argsType = selectSubset; - resultType = `Array<${getPayload}>`; - break; - - case 'create': - argsType = selectSubset; - resultType = getPayload; - break; - - case 'createMany': - argsType = selectSubset; - resultType = `Prisma.BatchPayload`; - break; - - case 'update': - argsType = selectSubset; - resultType = getPayload; - break; - - case 'updateMany': - argsType = selectSubset; - resultType = `Prisma.BatchPayload`; - break; - - case 'upsert': - argsType = selectSubset; - resultType = getPayload; - break; - - case 'delete': - argsType = selectSubset; - resultType = getPayload; - break; - - case 'deleteMany': - argsType = selectSubset; - resultType = `Prisma.BatchPayload`; - break; - - case 'count': - argsType = `Prisma.Subset`; - resultType = `'select' extends keyof T - ? T['select'] extends true - ? number - : Prisma.GetScalarType - : number`; - break; - - case 'aggregate': - argsType = `Prisma.Subset`; - resultType = `Prisma.Get${capModel}AggregateType`; - break; - - case 'groupBy': - genericBase = `Prisma.${capModel}GroupByArgs, - HasSelectOrTake extends Prisma.Or< - Prisma.Extends<'skip', Prisma.Keys>, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.${capModel}GroupByArgs['orderBy'] } - : { orderBy?: Prisma.${capModel}GroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? \`Error: "by" must not be empty.\` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? \`Error: Field "\${P}" used in "having" needs to be provided in "by".\` - : [ - Error, - 'Field ', - P, - \` in "having" needs to be provided in "by"\`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : \`Error: Field "\${P}" in "orderBy" needs to be provided in "by"\` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : \`Error: Field "\${P}" in "orderBy" needs to be provided in "by"\` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : \`Error: Field "\${P}" in "orderBy" needs to be provided in "by"\` - }[OrderFields] - `; - argsType = `Prisma.SubsetIntersection & InputErrors`; - resultType = `{} extends InputErrors ? Prisma.Get${capModel}GroupByPayload : InputErrors`; - break; - - default: - throw new PluginError(name, `Unsupported operation: "${operation}"`); - } - - return { genericBase, argsType, resultType, argsOptional }; -} - -/** - * Generate precise Prisma-like typing for router procedures. - */ -export function generateRouterTyping( - writer: CodeBlockWriter, - opType: string, - modelName: string, - baseOpType: string, - version: string -) { - const procType = getProcedureTypeByOpName(baseOpType); - const { genericBase, argsType, argsOptional, resultType } = getPrismaOperationTypes(modelName, opType); - const errorType = `TRPCClientErrorLike`; - const inputOptional = argsOptional ? '?' : ''; - - writer.block(() => { - if (procType === 'query') { - if (version === 'v10') { - writer.writeLine(` - useQuery: ( - input${inputOptional}: ${argsType}, - opts?: UseTRPCQueryOptions - ) => UseTRPCQueryResult< - TData, - ${errorType} - >; - useInfiniteQuery: ( - input${inputOptional}: Omit<${argsType}, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions - ) => UseTRPCInfiniteQueryResult< - ${resultType}, - ${errorType} - >; - `); - } else { - writer.writeLine(` - useQuery: ( - input${inputOptional}: ${argsType}, - opts?: UseTRPCQueryOptions<${resultType}, TData, Error> - ) => UseTRPCQueryResult< - TData, - ${errorType} - >; - useInfiniteQuery: ( - input${inputOptional}: Omit<${argsType}, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions - ) => UseTRPCInfiniteQueryResult< - ${resultType}, - ${errorType}, - T - >; - useSuspenseQuery: ( - input${inputOptional}: ${argsType}, - opts?: UseTRPCSuspenseQueryOptions<${resultType}, TData, Error> - ) => UseTRPCSuspenseQueryResult; - useSuspenseInfiniteQuery: ( - input${inputOptional}: Omit<${argsType}, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions - ) => UseTRPCSuspenseInfiniteQueryResult<${resultType}, ${errorType}, T>; - `); - } - } else if (procType === 'mutation') { - writer.writeLine(` - useMutation: (opts?: UseTRPCMutationOptions< - ${genericBase}, - ${errorType}, - ${resultType}, - Context - >,) => - Omit, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions) => Promise<${resultType}> - }; - `); - } - }); -} - -export function generateRouterTypingImports(sourceFile: SourceFile, options: PluginOptions, version: string) { - const importingDir = sourceFile.getDirectoryPath(); - const prismaImport = getPrismaClientImportSpec(importingDir, options); - sourceFile.addStatements([ - `import type { Prisma } from '${prismaImport}';`, - `import type { UseTRPCMutationOptions, UseTRPCMutationResult, UseTRPCQueryOptions, UseTRPCQueryResult, UseTRPCInfiniteQueryOptions, UseTRPCInfiniteQueryResult } from '@trpc/react-query/shared';`, - `import type { TRPCClientErrorLike } from '@trpc/client';`, - ]); - if (version === 'v10') { - sourceFile.addStatements([`import type { AnyRouter } from '@trpc/server';`]); - } else { - sourceFile.addStatements([ - `import type { AnyTRPCRouter as AnyRouter } from '@trpc/server';`, - `import type { UseTRPCSuspenseQueryOptions, UseTRPCSuspenseQueryResult, UseTRPCSuspenseInfiniteQueryOptions, UseTRPCSuspenseInfiniteQueryResult } from '@trpc/react-query/shared';`, - ]); - } -} - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export function generateRouterSchemaImport(sourceFile: SourceFile, zodSchemasImport: string) { - sourceFile.addStatements([ - `import * as _Schema from '${zodSchemasImport}/input';`, - // temporary solution for dealing with the issue that Node.js wraps named exports under a `default` - // key when importing from a CJS module - `const $Schema: typeof _Schema = (_Schema as any).default ?? _Schema;`, - ]); -} - -export function generateHelperImport(sourceFile: SourceFile) { - sourceFile.addStatements(`import { checkRead, checkMutate } from '../helper';`); -} - -export const getInputSchemaByOpName = (opName: string, modelName: string) => { - let inputType; - const capModelName = upperCaseFirst(modelName); - switch (opName) { - case 'findUnique': - inputType = `$Schema.${capModelName}InputSchema.findUnique`; - break; - case 'findFirst': - inputType = `$Schema.${capModelName}InputSchema.findFirst.optional()`; - break; - case 'findMany': - inputType = `$Schema.${capModelName}InputSchema.findMany.optional()`; - break; - case 'findRaw': - inputType = `$Schema.${capModelName}InputSchema.findRawObject`; - break; - case 'createOne': - inputType = `$Schema.${capModelName}InputSchema.create`; - break; - case 'createMany': - inputType = `$Schema.${capModelName}InputSchema.createMany.optional()`; - break; - case 'deleteOne': - inputType = `$Schema.${capModelName}InputSchema.delete`; - break; - case 'updateOne': - inputType = `$Schema.${capModelName}InputSchema.update`; - break; - case 'deleteMany': - inputType = `$Schema.${capModelName}InputSchema.deleteMany.optional()`; - break; - case 'updateMany': - inputType = `$Schema.${capModelName}InputSchema.updateMany`; - break; - case 'upsertOne': - inputType = `$Schema.${capModelName}InputSchema.upsert`; - break; - case 'aggregate': - inputType = `$Schema.${capModelName}InputSchema.aggregate`; - break; - case 'aggregateRaw': - inputType = `$Schema.${capModelName}InputSchema.aggregateRawObject`; - break; - case 'groupBy': - inputType = `$Schema.${capModelName}InputSchema.groupBy`; - break; - case 'count': - inputType = `$Schema.${capModelName}InputSchema.count.optional()`; - break; - default: - break; - } - return inputType; -}; - -export const getProcedureTypeByOpName = (opName: string) => { - let procType; - switch (opName) { - case 'findUnique': - case 'findFirst': - case 'findMany': - case 'findRaw': - case 'aggregate': - case 'aggregateRaw': - case 'groupBy': - case 'count': - procType = 'query'; - break; - case 'createOne': - case 'createMany': - case 'deleteOne': - case 'updateOne': - case 'deleteMany': - case 'updateMany': - case 'upsertOne': - procType = 'mutation'; - break; - default: - console.log('getProcedureTypeByOpName: ', { opName }); - } - return procType; -}; - -export function resolveModelsComments(models: readonly DMMF.Model[], hiddenModels: string[]) { - const modelAttributeRegex = /(@@Gen\.)+([A-z])+(\()+(.+)+(\))+/; - const attributeNameRegex = /(?:\.)+([A-Za-z])+(?:\()+/; - const attributeArgsRegex = /(?:\()+([A-Za-z])+:+(.+)+(?:\))+/; - - for (const model of models) { - if (model.documentation) { - const attribute = model.documentation?.match(modelAttributeRegex)?.[0]; - const attributeName = attribute?.match(attributeNameRegex)?.[0]?.slice(1, -1); - if (attributeName !== 'model') continue; - const rawAttributeArgs = attribute?.match(attributeArgsRegex)?.[0]?.slice(1, -1); - - const parsedAttributeArgs: Record = {}; - if (rawAttributeArgs) { - const rawAttributeArgsParts = rawAttributeArgs - .split(':') - .map((it) => it.trim()) - .map((part) => (part.startsWith('[') ? part : part.split(','))) - .flat() - .map((it) => it.trim()); - - for (let i = 0; i < rawAttributeArgsParts.length; i += 2) { - const key = rawAttributeArgsParts[i]; - const value = rawAttributeArgsParts[i + 1]; - parsedAttributeArgs[key] = JSON.parse(value); - } - } - if (parsedAttributeArgs.hide) { - hiddenModels.push(model.name); - } - } - } -} diff --git a/packages/plugins/trpc/src/utils.ts b/packages/plugins/trpc/src/utils.ts new file mode 100644 index 000000000..258f697ff --- /dev/null +++ b/packages/plugins/trpc/src/utils.ts @@ -0,0 +1,172 @@ +import { type DMMF } from '@zenstackhq/sdk/prisma'; +import { lowerCaseFirst } from 'lower-case-first'; +import { CodeBlockWriter, SourceFile } from 'ts-morph'; +import { upperCaseFirst } from 'upper-case-first'; + +/** + * Supported client helper types + */ +export type SupportedClientHelpers = 'react' | 'next' | 'nuxt'; + +/** + * All supported client helper types + */ +export const AllSupportedClientHelpers: SupportedClientHelpers[] = ['react', 'next', 'nuxt']; + +export function generateProcedure( + writer: CodeBlockWriter, + opType: string, + typeName: string, + modelName: string, + baseOpType: string +) { + const procType = getProcedureTypeByOpName(baseOpType); + const prismaMethod = opType.replace('One', ''); + + if (procType === 'query') { + // the cast "as any" is to circumvent a TS compiler misfired error in certain cases + writer.write(` + ${opType}: procedure.input(${typeName}).query(({ctx, input}) => checkRead(db(ctx).${lowerCaseFirst( + modelName + )}.${prismaMethod}(input as any))), + `); + } else if (procType === 'mutation') { + // the cast "as any" is to circumvent a TS compiler misfired error in certain cases + writer.write(` + ${opType}: procedure.input(${typeName}).mutation(async ({ctx, input}) => checkMutate(db(ctx).${lowerCaseFirst( + modelName + )}.${prismaMethod}(input as any))), + `); + } +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function generateRouterSchemaImport(sourceFile: SourceFile, zodSchemasImport: string) { + sourceFile.addStatements([ + `import * as _Schema from '${zodSchemasImport}/input';`, + // temporary solution for dealing with the issue that Node.js wraps named exports under a `default` + // key when importing from a CJS module + `const $Schema: typeof _Schema = (_Schema as any).default ?? _Schema;`, + ]); +} + +export function generateHelperImport(sourceFile: SourceFile) { + sourceFile.addStatements(`import { checkRead, checkMutate } from '../helper';`); +} + +export const getInputSchemaByOpName = (opName: string, modelName: string) => { + let inputType; + const capModelName = upperCaseFirst(modelName); + switch (opName) { + case 'findUnique': + inputType = `$Schema.${capModelName}InputSchema.findUnique`; + break; + case 'findFirst': + inputType = `$Schema.${capModelName}InputSchema.findFirst.optional()`; + break; + case 'findMany': + inputType = `$Schema.${capModelName}InputSchema.findMany.optional()`; + break; + case 'findRaw': + inputType = `$Schema.${capModelName}InputSchema.findRawObject`; + break; + case 'createOne': + inputType = `$Schema.${capModelName}InputSchema.create`; + break; + case 'createMany': + inputType = `$Schema.${capModelName}InputSchema.createMany.optional()`; + break; + case 'deleteOne': + inputType = `$Schema.${capModelName}InputSchema.delete`; + break; + case 'updateOne': + inputType = `$Schema.${capModelName}InputSchema.update`; + break; + case 'deleteMany': + inputType = `$Schema.${capModelName}InputSchema.deleteMany.optional()`; + break; + case 'updateMany': + inputType = `$Schema.${capModelName}InputSchema.updateMany`; + break; + case 'upsertOne': + inputType = `$Schema.${capModelName}InputSchema.upsert`; + break; + case 'aggregate': + inputType = `$Schema.${capModelName}InputSchema.aggregate`; + break; + case 'aggregateRaw': + inputType = `$Schema.${capModelName}InputSchema.aggregateRawObject`; + break; + case 'groupBy': + inputType = `$Schema.${capModelName}InputSchema.groupBy`; + break; + case 'count': + inputType = `$Schema.${capModelName}InputSchema.count.optional()`; + break; + default: + break; + } + return inputType; +}; + +export const getProcedureTypeByOpName = (opName: string) => { + let procType: string | undefined; + switch (opName) { + case 'findUnique': + case 'findFirst': + case 'findMany': + case 'findRaw': + case 'aggregate': + case 'aggregateRaw': + case 'groupBy': + case 'count': + procType = 'query'; + break; + case 'createOne': + case 'createMany': + case 'deleteOne': + case 'updateOne': + case 'deleteMany': + case 'updateMany': + case 'upsertOne': + procType = 'mutation'; + break; + default: + break; + } + return procType; +}; + +export function resolveModelsComments(models: readonly DMMF.Model[], hiddenModels: string[]) { + const modelAttributeRegex = /(@@Gen\.)+([A-z])+(\()+(.+)+(\))+/; + const attributeNameRegex = /(?:\.)+([A-Za-z])+(?:\()+/; + const attributeArgsRegex = /(?:\()+([A-Za-z])+:+(.+)+(?:\))+/; + + for (const model of models) { + if (model.documentation) { + const attribute = model.documentation?.match(modelAttributeRegex)?.[0]; + const attributeName = attribute?.match(attributeNameRegex)?.[0]?.slice(1, -1); + if (attributeName !== 'model') continue; + const rawAttributeArgs = attribute?.match(attributeArgsRegex)?.[0]?.slice(1, -1); + + const parsedAttributeArgs: Record = {}; + if (rawAttributeArgs) { + const rawAttributeArgsParts = rawAttributeArgs + .split(':') + .map((it) => it.trim()) + .map((part) => (part.startsWith('[') ? part : part.split(','))) + .flat() + .map((it) => it.trim()); + + for (let i = 0; i < rawAttributeArgsParts.length; i += 2) { + const key = rawAttributeArgsParts[i]; + const value = rawAttributeArgsParts[i + 1]; + parsedAttributeArgs[key] = JSON.parse(value); + } + } + if (parsedAttributeArgs.hide) { + hiddenModels.push(model.name); + } + } + } +} diff --git a/packages/plugins/trpc/tests/nuxt.test.ts b/packages/plugins/trpc/tests/nuxt.test.ts new file mode 100644 index 000000000..03471c5aa --- /dev/null +++ b/packages/plugins/trpc/tests/nuxt.test.ts @@ -0,0 +1,43 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +import { run } from '@zenstackhq/testtools'; +import path from 'path'; + +describe('tRPC plugin tests with nuxt', () => { + let origDir: string | undefined; + + beforeEach(() => { + origDir = process.cwd(); + }); + + afterEach(() => { + if (origDir) { + process.chdir(origDir); + } + }); + + it('project test trpc v10', () => { + const ver = require(path.join(__dirname, '../package.json')).version; + process.chdir(path.join(__dirname, './projects/nuxt-trpc-v10')); + + const deps = ['zenstackhq-language', 'zenstackhq-runtime', 'zenstackhq-sdk', 'zenstack']; + for (const dep of deps) { + run(`npm install ${path.join(__dirname, '../../../../.build/') + dep + '-' + ver + '.tgz'}`); + } + + run('npx zenstack generate'); + run('npm run build'); + }); + + it('project test trpc v11', () => { + const ver = require(path.join(__dirname, '../package.json')).version; + process.chdir(path.join(__dirname, './projects/nuxt-trpc-v11')); + + const deps = ['zenstackhq-language', 'zenstackhq-runtime', 'zenstackhq-sdk', 'zenstack']; + for (const dep of deps) { + run(`npm install ${path.join(__dirname, '../../../../.build/') + dep + '-' + ver + '.tgz'}`); + } + + run('npx zenstack generate'); + run('npm run build'); + }); +}); diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/.gitignore b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/.gitignore new file mode 100644 index 000000000..cdb506446 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/.gitignore @@ -0,0 +1,26 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example + +*.db diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/README.md b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/README.md new file mode 100644 index 000000000..f5db2a2db --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/README.md @@ -0,0 +1,75 @@ +# Nuxt 3 Minimal Starter + +Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. + +## Setup + +Make sure to install the dependencies: + +```bash +# npm +npm install + +# pnpm +pnpm install + +# yarn +yarn install + +# bun +bun install +``` + +## Development Server + +Start the development server on `http://localhost:3000`: + +```bash +# npm +npm run dev + +# pnpm +pnpm run dev + +# yarn +yarn dev + +# bun +bun run dev +``` + +## Production + +Build the application for production: + +```bash +# npm +npm run build + +# pnpm +pnpm run build + +# yarn +yarn build + +# bun +bun run build +``` + +Locally preview production build: + +```bash +# npm +npm run preview + +# pnpm +pnpm run preview + +# yarn +yarn preview + +# bun +bun run preview +``` + +Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/app.vue b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/app.vue new file mode 100644 index 000000000..01a7fa6f7 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/app.vue @@ -0,0 +1,52 @@ + + + diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/nuxt.config.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/nuxt.config.ts new file mode 100644 index 000000000..897b1221c --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/nuxt.config.ts @@ -0,0 +1,8 @@ +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + compatibilityDate: '2024-04-03', + devtools: { enabled: true }, + build: { + transpile: ['trpc-nuxt'], + }, +}); diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package-lock.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package-lock.json new file mode 100644 index 000000000..df371c9bb --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package-lock.json @@ -0,0 +1,8936 @@ +{ + "name": "nuxt-app", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nuxt-app", + "hasInstallScript": true, + "dependencies": { + "@prisma/client": "^5.19.1", + "@trpc/client": "^10.45.2", + "@trpc/server": "^10.45.2", + "nuxt": "^3.13.0", + "trpc-nuxt": "^0.10.22", + "vue": "latest", + "vue-router": "latest", + "zod": "^3.23.8" + }, + "devDependencies": { + "esbuild": "^0.24.0", + "prisma": "^5.19.1", + "typescript": "^5.6.2" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@antfu/utils": { + "version": "0.7.10", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.25.4", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.25.2", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.25.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.2", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.4", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.4", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.8", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.2", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.8", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.0", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.8", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.6", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.24.7", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-decorators": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.24.7", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.25.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.25.2", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-typescript": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/standalone": { + "version": "7.25.6", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.0", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.6", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.6", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cloudflare/kv-asset-handler": { + "version": "0.3.4", + "license": "MIT OR Apache-2.0", + "dependencies": { + "mime": "^3.0.0" + }, + "engines": { + "node": ">=16.13" + } + }, + "node_modules/@cloudflare/kv-asset-handler/node_modules/mime": { + "version": "3.0.0", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "license": "MIT" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "license": "BSD-3-Clause", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@netlify/functions": { + "version": "2.8.1", + "license": "MIT", + "dependencies": { + "@netlify/serverless-functions-api": "1.19.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@netlify/node-cookies": { + "version": "0.1.0", + "license": "MIT", + "engines": { + "node": "^14.16.0 || >=16.0.0" + } + }, + "node_modules/@netlify/serverless-functions-api": { + "version": "1.19.1", + "license": "MIT", + "dependencies": { + "@netlify/node-cookies": "^0.1.0", + "urlpattern-polyfill": "8.0.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nuxt/devalue": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/@nuxt/devtools": { + "version": "1.5.1", + "license": "MIT", + "dependencies": { + "@antfu/utils": "^0.7.10", + "@nuxt/devtools-kit": "1.5.1", + "@nuxt/devtools-wizard": "1.5.1", + "@nuxt/kit": "^3.13.2", + "@vue/devtools-core": "7.4.4", + "@vue/devtools-kit": "7.4.4", + "birpc": "^0.2.17", + "consola": "^3.2.3", + "cronstrue": "^2.50.0", + "destr": "^2.0.3", + "error-stack-parser-es": "^0.1.5", + "execa": "^7.2.0", + "fast-npm-meta": "^0.2.2", + "flatted": "^3.3.1", + "get-port-please": "^3.1.2", + "hookable": "^5.5.3", + "image-meta": "^0.2.1", + "is-installed-globally": "^1.0.0", + "launch-editor": "^2.9.1", + "local-pkg": "^0.5.0", + "magicast": "^0.3.5", + "nypm": "^0.3.11", + "ohash": "^1.1.4", + "pathe": "^1.1.2", + "perfect-debounce": "^1.0.0", + "pkg-types": "^1.2.0", + "rc9": "^2.1.2", + "scule": "^1.3.0", + "semver": "^7.6.3", + "simple-git": "^3.27.0", + "sirv": "^2.0.4", + "tinyglobby": "^0.2.6", + "unimport": "^3.12.0", + "vite-plugin-inspect": "^0.8.7", + "vite-plugin-vue-inspector": "^5.2.0", + "which": "^3.0.1", + "ws": "^8.18.0" + }, + "bin": { + "devtools": "cli.mjs" + }, + "peerDependencies": { + "vite": "*" + } + }, + "node_modules/@nuxt/devtools-kit": { + "version": "1.5.1", + "license": "MIT", + "dependencies": { + "@nuxt/kit": "^3.13.2", + "@nuxt/schema": "^3.13.2", + "execa": "^7.2.0" + }, + "peerDependencies": { + "vite": "*" + } + }, + "node_modules/@nuxt/devtools-wizard": { + "version": "1.5.1", + "license": "MIT", + "dependencies": { + "consola": "^3.2.3", + "diff": "^7.0.0", + "execa": "^7.2.0", + "global-directory": "^4.0.1", + "magicast": "^0.3.5", + "pathe": "^1.1.2", + "pkg-types": "^1.2.0", + "prompts": "^2.4.2", + "rc9": "^2.1.2", + "semver": "^7.6.3" + }, + "bin": { + "devtools-wizard": "cli.mjs" + } + }, + "node_modules/@nuxt/kit": { + "version": "3.13.2", + "license": "MIT", + "dependencies": { + "@nuxt/schema": "3.13.2", + "c12": "^1.11.2", + "consola": "^3.2.3", + "defu": "^6.1.4", + "destr": "^2.0.3", + "globby": "^14.0.2", + "hash-sum": "^2.0.0", + "ignore": "^5.3.2", + "jiti": "^1.21.6", + "klona": "^2.0.6", + "knitwork": "^1.1.0", + "mlly": "^1.7.1", + "pathe": "^1.1.2", + "pkg-types": "^1.2.0", + "scule": "^1.3.0", + "semver": "^7.6.3", + "ufo": "^1.5.4", + "unctx": "^2.3.1", + "unimport": "^3.12.0", + "untyped": "^1.4.2" + }, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/@nuxt/schema": { + "version": "3.13.2", + "license": "MIT", + "dependencies": { + "compatx": "^0.1.8", + "consola": "^3.2.3", + "defu": "^6.1.4", + "hookable": "^5.5.3", + "pathe": "^1.1.2", + "pkg-types": "^1.2.0", + "scule": "^1.3.0", + "std-env": "^3.7.0", + "ufo": "^1.5.4", + "uncrypto": "^0.1.3", + "unimport": "^3.12.0", + "untyped": "^1.4.2" + }, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/@nuxt/telemetry": { + "version": "2.6.0", + "license": "MIT", + "dependencies": { + "@nuxt/kit": "^3.13.1", + "ci-info": "^4.0.0", + "consola": "^3.2.3", + "create-require": "^1.1.1", + "defu": "^6.1.4", + "destr": "^2.0.3", + "dotenv": "^16.4.5", + "git-url-parse": "^15.0.0", + "is-docker": "^3.0.0", + "jiti": "^1.21.6", + "mri": "^1.2.0", + "nanoid": "^5.0.7", + "ofetch": "^1.3.4", + "package-manager-detector": "^0.2.0", + "parse-git-config": "^3.0.0", + "pathe": "^1.1.2", + "rc9": "^2.1.2", + "std-env": "^3.7.0" + }, + "bin": { + "nuxt-telemetry": "bin/nuxt-telemetry.mjs" + } + }, + "node_modules/@nuxt/vite-builder": { + "version": "3.13.2", + "license": "MIT", + "dependencies": { + "@nuxt/kit": "3.13.2", + "@rollup/plugin-replace": "^5.0.7", + "@vitejs/plugin-vue": "^5.1.3", + "@vitejs/plugin-vue-jsx": "^4.0.1", + "autoprefixer": "^10.4.20", + "clear": "^0.1.0", + "consola": "^3.2.3", + "cssnano": "^7.0.6", + "defu": "^6.1.4", + "esbuild": "^0.23.1", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "externality": "^1.0.2", + "get-port-please": "^3.1.2", + "h3": "^1.12.0", + "knitwork": "^1.1.0", + "magic-string": "^0.30.11", + "mlly": "^1.7.1", + "ohash": "^1.1.4", + "pathe": "^1.1.2", + "perfect-debounce": "^1.0.0", + "pkg-types": "^1.2.0", + "postcss": "^8.4.47", + "rollup-plugin-visualizer": "^5.12.0", + "std-env": "^3.7.0", + "strip-literal": "^2.1.0", + "ufo": "^1.5.4", + "unenv": "^1.10.0", + "unplugin": "^1.14.1", + "vite": "^5.4.5", + "vite-node": "^2.1.1", + "vite-plugin-checker": "^0.8.0", + "vue-bundle-renderer": "^2.1.0" + }, + "engines": { + "node": "^14.18.0 || >=16.10.0" + }, + "peerDependencies": { + "vue": "^3.3.4" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/aix-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/android-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/android-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/android-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/darwin-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/darwin-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/freebsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/linux-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/linux-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/linux-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/linux-loong64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/linux-mips64el": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/linux-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/linux-riscv64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@nuxt/vite-builder/node_modules/esbuild": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.4.1", + "@parcel/watcher-darwin-arm64": "2.4.1", + "@parcel/watcher-darwin-x64": "2.4.1", + "@parcel/watcher-freebsd-x64": "2.4.1", + "@parcel/watcher-linux-arm-glibc": "2.4.1", + "@parcel/watcher-linux-arm64-glibc": "2.4.1", + "@parcel/watcher-linux-arm64-musl": "2.4.1", + "@parcel/watcher-linux-x64-glibc": "2.4.1", + "@parcel/watcher-linux-x64-musl": "2.4.1", + "@parcel/watcher-win32-arm64": "2.4.1", + "@parcel/watcher-win32-ia32": "2.4.1", + "@parcel/watcher-win32-x64": "2.4.1" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.4.1", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-wasm": { + "version": "2.4.1", + "bundleDependencies": [ + "napi-wasm" + ], + "license": "MIT", + "dependencies": { + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "napi-wasm": "^1.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-wasm/node_modules/napi-wasm": { + "version": "1.1.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "license": "MIT" + }, + "node_modules/@prisma/client": { + "version": "5.19.1", + "hasInstallScript": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.13" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/debug": { + "version": "5.19.1", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/engines": { + "version": "5.19.1", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.19.1", + "@prisma/engines-version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3", + "@prisma/fetch-engine": "5.19.1", + "@prisma/get-platform": "5.19.1" + } + }, + "node_modules/@prisma/engines-version": { + "version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/fetch-engine": { + "version": "5.19.1", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.19.1", + "@prisma/engines-version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3", + "@prisma/get-platform": "5.19.1" + } + }, + "node_modules/@prisma/get-platform": { + "version": "5.19.1", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.19.1" + } + }, + "node_modules/@rollup/plugin-alias": { + "version": "5.1.1", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "25.0.8", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "glob": "^8.0.3", + "is-reference": "1.2.1", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/estree-walker": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/@rollup/plugin-inject": { + "version": "5.0.5", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-inject/node_modules/estree-walker": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/@rollup/plugin-json": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.3.0", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "5.0.7", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.22.4", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@trpc/client": { + "version": "10.45.2", + "funding": [ + "https://trpc.io/sponsor" + ], + "license": "MIT", + "peerDependencies": { + "@trpc/server": "10.45.2" + } + }, + "node_modules/@trpc/server": { + "version": "10.45.2", + "funding": [ + "https://trpc.io/sponsor" + ], + "license": "MIT" + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.6.1", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "license": "MIT" + }, + "node_modules/@unhead/dom": { + "version": "1.11.6", + "license": "MIT", + "dependencies": { + "@unhead/schema": "1.11.6", + "@unhead/shared": "1.11.6" + }, + "funding": { + "url": "https://github.com/sponsors/harlan-zw" + } + }, + "node_modules/@unhead/schema": { + "version": "1.11.6", + "license": "MIT", + "dependencies": { + "hookable": "^5.5.3", + "zhead": "^2.2.4" + }, + "funding": { + "url": "https://github.com/sponsors/harlan-zw" + } + }, + "node_modules/@unhead/shared": { + "version": "1.11.6", + "license": "MIT", + "dependencies": { + "@unhead/schema": "1.11.6" + }, + "funding": { + "url": "https://github.com/sponsors/harlan-zw" + } + }, + "node_modules/@unhead/ssr": { + "version": "1.11.6", + "license": "MIT", + "dependencies": { + "@unhead/schema": "1.11.6", + "@unhead/shared": "1.11.6" + }, + "funding": { + "url": "https://github.com/sponsors/harlan-zw" + } + }, + "node_modules/@unhead/vue": { + "version": "1.11.6", + "license": "MIT", + "dependencies": { + "@unhead/schema": "1.11.6", + "@unhead/shared": "1.11.6", + "defu": "^6.1.4", + "hookable": "^5.5.3", + "unhead": "1.11.6" + }, + "funding": { + "url": "https://github.com/sponsors/harlan-zw" + }, + "peerDependencies": { + "vue": ">=2.7 || >=3" + } + }, + "node_modules/@vercel/nft": { + "version": "0.26.5", + "license": "MIT", + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.5", + "@rollup/pluginutils": "^4.0.0", + "acorn": "^8.6.0", + "acorn-import-attributes": "^1.9.2", + "async-sema": "^3.1.1", + "bindings": "^1.4.0", + "estree-walker": "2.0.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.2", + "node-gyp-build": "^4.2.2", + "resolve-from": "^5.0.0" + }, + "bin": { + "nft": "out/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@vercel/nft/node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "license": "MIT", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@vercel/nft/node_modules/brace-expansion": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@vercel/nft/node_modules/estree-walker": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/@vercel/nft/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vercel/nft/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.1.4", + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vitejs/plugin-vue-jsx": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.24.7", + "@vue/babel-plugin-jsx": "^1.2.2" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0", + "vue": "^3.0.0" + } + }, + "node_modules/@vue-macros/common": { + "version": "1.14.0", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6", + "@rollup/pluginutils": "^5.1.0", + "@vue/compiler-sfc": "^3.5.4", + "ast-kit": "^1.1.0", + "local-pkg": "^0.5.0", + "magic-string-ast": "^0.6.2" + }, + "engines": { + "node": ">=16.14.0" + }, + "peerDependencies": { + "vue": "^2.7.0 || ^3.2.25" + }, + "peerDependenciesMeta": { + "vue": { + "optional": true + } + } + }, + "node_modules/@vue/babel-helper-vue-transform-on": { + "version": "1.2.5", + "license": "MIT" + }, + "node_modules/@vue/babel-plugin-jsx": { + "version": "1.2.5", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.6", + "@babel/types": "^7.25.6", + "@vue/babel-helper-vue-transform-on": "1.2.5", + "@vue/babel-plugin-resolve-type": "1.2.5", + "html-tags": "^3.3.1", + "svg-tags": "^1.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + } + } + }, + "node_modules/@vue/babel-plugin-resolve-type": { + "version": "1.2.5", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/parser": "^7.25.6", + "@vue/compiler-sfc": "^3.5.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.11.tgz", + "integrity": "sha512-PwAdxs7/9Hc3ieBO12tXzmTD+Ln4qhT/56S+8DvrrZ4kLDn4Z/AMUr8tXJD0axiJBS0RKIoNaR0yMuQB9v9Udg==", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.11", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-core/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.11.tgz", + "integrity": "sha512-pyGf8zdbDDRkBrEzf8p7BQlMKNNF5Fk/Cf/fQ6PiUz9at4OaUfyXW0dGJTo2Vl1f5U9jSLCNf0EZJEogLXoeew==", + "dependencies": { + "@vue/compiler-core": "3.5.11", + "@vue/shared": "3.5.11" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.11.tgz", + "integrity": "sha512-gsbBtT4N9ANXXepprle+X9YLg2htQk1sqH/qGJ/EApl+dgpUBdTv3yP7YlR535uHZY3n6XaR0/bKo0BgwwDniw==", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.11", + "@vue/compiler-dom": "3.5.11", + "@vue/compiler-ssr": "3.5.11", + "@vue/shared": "3.5.11", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.11", + "postcss": "^8.4.47", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/estree-walker": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.11.tgz", + "integrity": "sha512-P4+GPjOuC2aFTk1Z4WANvEhyOykcvEd5bIj2KVNGKGfM745LaXGr++5njpdBTzVz5pZifdlR1kpYSJJpIlSePA==", + "dependencies": { + "@vue/compiler-dom": "3.5.11", + "@vue/shared": "3.5.11" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "license": "MIT" + }, + "node_modules/@vue/devtools-core": { + "version": "7.4.4", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.4.4", + "@vue/devtools-shared": "^7.4.4", + "mitt": "^3.0.1", + "nanoid": "^3.3.4", + "pathe": "^1.1.2", + "vite-hot-client": "^0.2.3" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@vue/devtools-core/node_modules/nanoid": { + "version": "3.3.7", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.4.4", + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.4.4", + "birpc": "^0.2.17", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.1" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.4.6", + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.11.tgz", + "integrity": "sha512-Nqo5VZEn8MJWlCce8XoyVqHZbd5P2NH+yuAaFzuNSR96I+y1cnuUiq7xfSG+kyvLSiWmaHTKP1r3OZY4mMD50w==", + "dependencies": { + "@vue/shared": "3.5.11" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.11.tgz", + "integrity": "sha512-7PsxFGqwfDhfhh0OcDWBG1DaIQIVOLgkwA5q6MtkPiDFjp5gohVnJEahSktwSFLq7R5PtxDKy6WKURVN1UDbzA==", + "dependencies": { + "@vue/reactivity": "3.5.11", + "@vue/shared": "3.5.11" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.11.tgz", + "integrity": "sha512-GNghjecT6IrGf0UhuYmpgaOlN7kxzQBhxWEn08c/SQDxv1yy4IXI1bn81JgEpQ4IXjRxWtPyI8x0/7TF5rPfYQ==", + "dependencies": { + "@vue/reactivity": "3.5.11", + "@vue/runtime-core": "3.5.11", + "@vue/shared": "3.5.11", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.11.tgz", + "integrity": "sha512-cVOwYBxR7Wb1B1FoxYvtjJD8X/9E5nlH4VSkJy2uMA1MzYNdzAAB//l8nrmN9py/4aP+3NjWukf9PZ3TeWULaA==", + "dependencies": { + "@vue/compiler-ssr": "3.5.11", + "@vue/shared": "3.5.11" + }, + "peerDependencies": { + "vue": "3.5.11" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.11.tgz", + "integrity": "sha512-W8GgysJVnFo81FthhzurdRAWP/byq3q2qIw70e0JWblzVhjgOMiC2GyovXrZTFQJnFVryYaKGP3Tc9vYzYm6PQ==" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/archiver": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.2", + "async": "^3.2.4", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^6.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils": { + "version": "5.0.2", + "license": "MIT", + "dependencies": { + "glob": "^10.0.0", + "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils/node_modules/glob": { + "version": "10.4.5", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/archiver-utils/node_modules/is-stream": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/archiver-utils/node_modules/minimatch": { + "version": "9.0.5", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/archiver-utils/node_modules/minipass": { + "version": "7.1.2", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.2", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "license": "Python-2.0" + }, + "node_modules/ast-kit": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.6", + "pathe": "^1.1.2" + }, + "engines": { + "node": ">=16.14.0" + } + }, + "node_modules/ast-walker-scope": { + "version": "0.6.2", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "ast-kit": "^1.0.1" + }, + "engines": { + "node": ">=16.14.0" + } + }, + "node_modules/async": { + "version": "3.2.6", + "license": "MIT" + }, + "node_modules/async-sema": { + "version": "3.1.1", + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/b4a": { + "version": "1.6.6", + "license": "Apache-2.0" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.4.2", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/birpc": { + "version": "0.2.17", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.3", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-crc32": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/c12": { + "version": "1.11.2", + "license": "MIT", + "dependencies": { + "chokidar": "^3.6.0", + "confbox": "^0.1.7", + "defu": "^6.1.4", + "dotenv": "^16.4.5", + "giget": "^1.2.3", + "jiti": "^1.21.6", + "mlly": "^1.7.1", + "ohash": "^1.1.3", + "pathe": "^1.1.2", + "perfect-debounce": "^1.0.0", + "pkg-types": "^1.2.0", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.4" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, + "node_modules/cac": { + "version": "6.7.14", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001663", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "2.4.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "4.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/citty": { + "version": "0.1.6", + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + } + }, + "node_modules/clear": { + "version": "0.1.0", + "engines": { + "node": "*" + } + }, + "node_modules/clipboardy": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "execa": "^8.0.1", + "is-wsl": "^3.1.0", + "is64bit": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clipboardy/node_modules/execa": { + "version": "8.0.1", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/clipboardy/node_modules/get-stream": { + "version": "8.0.1", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clipboardy/node_modules/human-signals": { + "version": "5.0.0", + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/clipboardy/node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/color-support": { + "version": "1.1.3", + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colord": { + "version": "2.9.3", + "license": "MIT" + }, + "node_modules/commander": { + "version": "7.2.0", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/compatx": { + "version": "0.1.8", + "license": "MIT" + }, + "node_modules/compress-commons": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/compress-commons/node_modules/is-stream": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.1.7", + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.2.3", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "license": "ISC" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/cookie-es": { + "version": "1.2.2", + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "3.0.5", + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/crc-32": { + "version": "1.2.2", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/croner": { + "version": "8.1.1", + "license": "MIT", + "engines": { + "node": ">=18.0" + } + }, + "node_modules/cronstrue": { + "version": "2.50.0", + "license": "MIT", + "bin": { + "cronstrue": "bin/cli.js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crossws": { + "version": "0.2.4", + "license": "MIT", + "peerDependencies": { + "uWebSockets.js": "*" + }, + "peerDependenciesMeta": { + "uWebSockets.js": { + "optional": true + } + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.2.0", + "license": "ISC", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "7.0.6", + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^7.0.6", + "lilconfig": "^3.1.2" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "7.0.6", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^5.0.0", + "postcss-calc": "^10.0.2", + "postcss-colormin": "^7.0.2", + "postcss-convert-values": "^7.0.4", + "postcss-discard-comments": "^7.0.3", + "postcss-discard-duplicates": "^7.0.1", + "postcss-discard-empty": "^7.0.0", + "postcss-discard-overridden": "^7.0.0", + "postcss-merge-longhand": "^7.0.4", + "postcss-merge-rules": "^7.0.4", + "postcss-minify-font-values": "^7.0.0", + "postcss-minify-gradients": "^7.0.0", + "postcss-minify-params": "^7.0.2", + "postcss-minify-selectors": "^7.0.4", + "postcss-normalize-charset": "^7.0.0", + "postcss-normalize-display-values": "^7.0.0", + "postcss-normalize-positions": "^7.0.0", + "postcss-normalize-repeat-style": "^7.0.0", + "postcss-normalize-string": "^7.0.0", + "postcss-normalize-timing-functions": "^7.0.0", + "postcss-normalize-unicode": "^7.0.2", + "postcss-normalize-url": "^7.0.0", + "postcss-normalize-whitespace": "^7.0.0", + "postcss-ordered-values": "^7.0.1", + "postcss-reduce-initial": "^7.0.2", + "postcss-reduce-transforms": "^7.0.0", + "postcss-svgo": "^7.0.1", + "postcss-unique-selectors": "^7.0.3" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/db0": { + "version": "0.1.4", + "license": "MIT", + "peerDependencies": { + "@libsql/client": "^0.5.2", + "better-sqlite3": "^9.4.3", + "drizzle-orm": "^0.29.4" + }, + "peerDependenciesMeta": { + "@libsql/client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "drizzle-orm": { + "optional": true + } + } + }, + "node_modules/debug": { + "version": "4.3.7", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "license": "MIT" + }, + "node_modules/delegates": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/denque": { + "version": "2.1.0", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destr": { + "version": "2.0.3", + "license": "MIT" + }, + "node_modules/destroy": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "5.0.0", + "license": "MIT" + }, + "node_modules/diff": { + "version": "7.0.0", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "8.0.2", + "license": "MIT", + "dependencies": { + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.27", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-stack-parser-es": { + "version": "0.1.5", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/errx": { + "version": "0.1.0", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/externality": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "enhanced-resolve": "^5.14.1", + "mlly": "^1.3.0", + "pathe": "^1.1.1", + "ufo": "^1.1.2" + } + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-npm-meta": { + "version": "0.2.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "3.0.2", + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-port-please": { + "version": "3.1.2", + "license": "MIT" + }, + "node_modules/get-stream": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/giget": { + "version": "1.2.3", + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.2.3", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.3", + "nypm": "^0.3.8", + "ohash": "^1.1.3", + "pathe": "^1.1.2", + "tar": "^6.2.0" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, + "node_modules/git-config-path": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/git-up": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "is-ssh": "^1.4.0", + "parse-url": "^8.1.0" + } + }, + "node_modules/git-url-parse": { + "version": "15.0.0", + "license": "MIT", + "dependencies": { + "git-up": "^7.0.0" + } + }, + "node_modules/glob": { + "version": "8.1.0", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-directory": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "14.0.2", + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "license": "ISC" + }, + "node_modules/gzip-size": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/h3": { + "version": "1.12.0", + "license": "MIT", + "dependencies": { + "cookie-es": "^1.1.0", + "crossws": "^0.2.4", + "defu": "^6.1.4", + "destr": "^2.0.3", + "iron-webcrypto": "^1.1.1", + "ohash": "^1.1.3", + "radix3": "^1.1.2", + "ufo": "^1.5.3", + "uncrypto": "^0.1.3", + "unenv": "^1.9.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "license": "ISC" + }, + "node_modules/hash-sum": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/hasown": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "license": "MIT" + }, + "node_modules/html-tags": { + "version": "3.3.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-shutdown": { + "version": "1.2.2", + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/httpxy": { + "version": "0.1.5", + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "4.3.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-meta": { + "version": "0.2.1", + "license": "MIT" + }, + "node_modules/impound": { + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0", + "mlly": "^1.7.1", + "pathe": "^1.1.2", + "unenv": "^1.10.0", + "unplugin": "^1.12.2" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/ini": { + "version": "4.1.1", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ioredis": { + "version": "5.4.1", + "license": "MIT", + "dependencies": { + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-installed-globally": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "global-directory": "^4.0.1", + "is-path-inside": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/is-number": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-ssh": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "protocols": "^2.0.1" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "4.1.16", + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is64bit": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "system-architecture": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/knitwork": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/kolorist": { + "version": "1.8.0", + "license": "MIT" + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/listhen": { + "version": "1.7.2", + "license": "MIT", + "dependencies": { + "@parcel/watcher": "^2.4.1", + "@parcel/watcher-wasm": "^2.4.1", + "citty": "^0.1.6", + "clipboardy": "^4.0.0", + "consola": "^3.2.3", + "crossws": "^0.2.0", + "defu": "^6.1.4", + "get-port-please": "^3.1.2", + "h3": "^1.10.2", + "http-shutdown": "^1.2.2", + "jiti": "^1.21.0", + "mlly": "^1.6.1", + "node-forge": "^1.3.1", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "ufo": "^1.4.0", + "untun": "^0.1.3", + "uqr": "^0.1.2" + }, + "bin": { + "listen": "bin/listhen.mjs", + "listhen": "bin/listhen.mjs" + } + }, + "node_modules/local-pkg": { + "version": "0.5.0", + "license": "MIT", + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "license": "MIT" + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.11", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/magic-string-ast": { + "version": "0.6.2", + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.10" + }, + "engines": { + "node": ">=16.14.0" + } + }, + "node_modules/magicast": { + "version": "0.3.5", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "license": "CC0-1.0" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "4.0.4", + "funding": [ + "https://github.com/sponsors/broofa" + ], + "license": "MIT", + "bin": { + "mime": "bin/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "5.1.6", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + }, + "node_modules/mitt": { + "version": "3.0.1", + "license": "MIT" + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mlly": { + "version": "1.7.1", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.1.1", + "ufo": "^1.5.3" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "5.0.7", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/nanotar": { + "version": "0.1.1", + "license": "MIT" + }, + "node_modules/nitropack": { + "version": "2.9.7", + "license": "MIT", + "dependencies": { + "@cloudflare/kv-asset-handler": "^0.3.4", + "@netlify/functions": "^2.8.0", + "@rollup/plugin-alias": "^5.1.0", + "@rollup/plugin-commonjs": "^25.0.8", + "@rollup/plugin-inject": "^5.0.5", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^5.0.7", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/pluginutils": "^5.1.0", + "@types/http-proxy": "^1.17.14", + "@vercel/nft": "^0.26.5", + "archiver": "^7.0.1", + "c12": "^1.11.1", + "chalk": "^5.3.0", + "chokidar": "^3.6.0", + "citty": "^0.1.6", + "consola": "^3.2.3", + "cookie-es": "^1.1.0", + "croner": "^8.0.2", + "crossws": "^0.2.4", + "db0": "^0.1.4", + "defu": "^6.1.4", + "destr": "^2.0.3", + "dot-prop": "^8.0.2", + "esbuild": "^0.20.2", + "escape-string-regexp": "^5.0.0", + "etag": "^1.8.1", + "fs-extra": "^11.2.0", + "globby": "^14.0.1", + "gzip-size": "^7.0.0", + "h3": "^1.12.0", + "hookable": "^5.5.3", + "httpxy": "^0.1.5", + "ioredis": "^5.4.1", + "jiti": "^1.21.6", + "klona": "^2.0.6", + "knitwork": "^1.1.0", + "listhen": "^1.7.2", + "magic-string": "^0.30.10", + "mime": "^4.0.3", + "mlly": "^1.7.1", + "mri": "^1.2.0", + "node-fetch-native": "^1.6.4", + "ofetch": "^1.3.4", + "ohash": "^1.1.3", + "openapi-typescript": "^6.7.6", + "pathe": "^1.1.2", + "perfect-debounce": "^1.0.0", + "pkg-types": "^1.1.1", + "pretty-bytes": "^6.1.1", + "radix3": "^1.1.2", + "rollup": "^4.18.0", + "rollup-plugin-visualizer": "^5.12.0", + "scule": "^1.3.0", + "semver": "^7.6.2", + "serve-placeholder": "^2.0.2", + "serve-static": "^1.15.0", + "std-env": "^3.7.0", + "ufo": "^1.5.3", + "uncrypto": "^0.1.3", + "unctx": "^2.3.1", + "unenv": "^1.9.0", + "unimport": "^3.7.2", + "unstorage": "^1.10.2", + "unwasm": "^0.3.9" + }, + "bin": { + "nitro": "dist/cli/index.mjs", + "nitropack": "dist/cli/index.mjs" + }, + "engines": { + "node": "^16.11.0 || >=17.0.0" + }, + "peerDependencies": { + "xml2js": "^0.6.2" + }, + "peerDependenciesMeta": { + "xml2js": { + "optional": true + } + } + }, + "node_modules/nitropack/node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/nitropack/node_modules/chalk": { + "version": "5.3.0", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/nitropack/node_modules/esbuild": { + "version": "0.20.2", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.4", + "license": "MIT" + }, + "node_modules/node-forge": { + "version": "1.3.1", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.2", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "license": "MIT" + }, + "node_modules/nopt": { + "version": "5.0.0", + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nuxi": { + "version": "3.13.2", + "license": "MIT", + "bin": { + "nuxi": "bin/nuxi.mjs", + "nuxi-ng": "bin/nuxi.mjs", + "nuxt": "bin/nuxi.mjs", + "nuxt-cli": "bin/nuxi.mjs" + }, + "engines": { + "node": "^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/nuxt": { + "version": "3.13.2", + "license": "MIT", + "dependencies": { + "@nuxt/devalue": "^2.0.2", + "@nuxt/devtools": "^1.4.2", + "@nuxt/kit": "3.13.2", + "@nuxt/schema": "3.13.2", + "@nuxt/telemetry": "^2.6.0", + "@nuxt/vite-builder": "3.13.2", + "@unhead/dom": "^1.11.5", + "@unhead/shared": "^1.11.5", + "@unhead/ssr": "^1.11.5", + "@unhead/vue": "^1.11.5", + "@vue/shared": "^3.5.5", + "acorn": "8.12.1", + "c12": "^1.11.2", + "chokidar": "^3.6.0", + "compatx": "^0.1.8", + "consola": "^3.2.3", + "cookie-es": "^1.2.2", + "defu": "^6.1.4", + "destr": "^2.0.3", + "devalue": "^5.0.0", + "errx": "^0.1.0", + "esbuild": "^0.23.1", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "globby": "^14.0.2", + "h3": "^1.12.0", + "hookable": "^5.5.3", + "ignore": "^5.3.2", + "impound": "^0.1.0", + "jiti": "^1.21.6", + "klona": "^2.0.6", + "knitwork": "^1.1.0", + "magic-string": "^0.30.11", + "mlly": "^1.7.1", + "nanotar": "^0.1.1", + "nitropack": "^2.9.7", + "nuxi": "^3.13.2", + "nypm": "^0.3.11", + "ofetch": "^1.3.4", + "ohash": "^1.1.4", + "pathe": "^1.1.2", + "perfect-debounce": "^1.0.0", + "pkg-types": "^1.2.0", + "radix3": "^1.1.2", + "scule": "^1.3.0", + "semver": "^7.6.3", + "std-env": "^3.7.0", + "strip-literal": "^2.1.0", + "tinyglobby": "0.2.6", + "ufo": "^1.5.4", + "ultrahtml": "^1.5.3", + "uncrypto": "^0.1.3", + "unctx": "^2.3.1", + "unenv": "^1.10.0", + "unhead": "^1.11.5", + "unimport": "^3.12.0", + "unplugin": "^1.14.1", + "unplugin-vue-router": "^0.10.8", + "unstorage": "^1.12.0", + "untyped": "^1.4.2", + "vue": "^3.5.5", + "vue-bundle-renderer": "^2.1.0", + "vue-devtools-stub": "^0.1.0", + "vue-router": "^4.4.5" + }, + "bin": { + "nuxi": "bin/nuxt.mjs", + "nuxt": "bin/nuxt.mjs" + }, + "engines": { + "node": "^14.18.0 || >=16.10.0" + }, + "peerDependencies": { + "@parcel/watcher": "^2.1.0", + "@types/node": "^14.18.0 || >=16.10.0" + }, + "peerDependenciesMeta": { + "@parcel/watcher": { + "optional": true + }, + "@types/node": { + "optional": true + } + } + }, + "node_modules/nuxt/node_modules/@esbuild/aix-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/android-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/android-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/android-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/darwin-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/darwin-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/freebsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/linux-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/linux-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/linux-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/linux-loong64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/linux-mips64el": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/linux-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/linux-riscv64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/nuxt/node_modules/esbuild": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" + } + }, + "node_modules/nypm": { + "version": "0.3.11", + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.2.3", + "execa": "^8.0.1", + "pathe": "^1.1.2", + "pkg-types": "^1.2.0", + "ufo": "^1.5.4" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": "^14.16.0 || >=16.10.0" + } + }, + "node_modules/nypm/node_modules/execa": { + "version": "8.0.1", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/nypm/node_modules/get-stream": { + "version": "8.0.1", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nypm/node_modules/human-signals": { + "version": "5.0.0", + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/nypm/node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ofetch": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "destr": "^2.0.3", + "node-fetch-native": "^1.6.4", + "ufo": "^1.5.4" + } + }, + "node_modules/ohash": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open/node_modules/is-docker": { + "version": "2.2.1", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open/node_modules/is-wsl": { + "version": "2.2.0", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/openapi-typescript": { + "version": "6.7.6", + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "fast-glob": "^3.3.2", + "js-yaml": "^4.1.0", + "supports-color": "^9.4.0", + "undici": "^5.28.4", + "yargs-parser": "^21.1.1" + }, + "bin": { + "openapi-typescript": "bin/cli.js" + } + }, + "node_modules/openapi-typescript/node_modules/supports-color": { + "version": "9.4.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "license": "BlueOak-1.0.0" + }, + "node_modules/package-manager-detector": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/parse-git-config": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "git-config-path": "^2.0.0", + "ini": "^1.3.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parse-git-config/node_modules/ini": { + "version": "1.3.8", + "license": "ISC" + }, + "node_modules/parse-path": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "protocols": "^2.0.0" + } + }, + "node_modules/parse-url": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "parse-path": "^7.0.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "license": "ISC" + }, + "node_modules/path-type": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.0", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-types": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.7", + "mlly": "^1.7.1", + "pathe": "^1.1.2" + } + }, + "node_modules/postcss": { + "version": "8.4.47", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "10.0.2", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12 || ^20.9 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.38" + } + }, + "node_modules/postcss-colormin": { + "version": "7.0.2", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "7.0.4", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-comments": { + "version": "7.0.3", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.2" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "7.0.1", + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "7.0.4", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^7.0.4" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "7.0.4", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^5.0.0", + "postcss-selector-parser": "^6.1.2" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^5.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "7.0.2", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "cssnano-utils": "^5.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "7.0.4", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "postcss-selector-parser": "^6.1.2" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "7.0.2", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-ordered-values": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^5.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "7.0.2", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.3.2" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "7.0.3", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.2" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.7", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/pretty-bytes": { + "version": "6.1.1", + "license": "MIT", + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prisma": { + "version": "5.19.1", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/engines": "5.19.1" + }, + "bin": { + "prisma": "build/index.js" + }, + "engines": { + "node": ">=16.13" + }, + "optionalDependencies": { + "fsevents": "2.3.3" + } + }, + "node_modules/process": { + "version": "0.11.10", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/prompts": { + "version": "2.4.2", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/protocols": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/radix3": { + "version": "1.1.2", + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rc9": { + "version": "2.1.2", + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "destr": "^2.0.3" + } + }, + "node_modules/readable-stream": { + "version": "4.5.2", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/rollup": { + "version": "4.22.4", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-visualizer": { + "version": "5.12.0", + "license": "MIT", + "dependencies": { + "open": "^8.4.0", + "picomatch": "^2.3.1", + "source-map": "^0.7.4", + "yargs": "^17.5.1" + }, + "bin": { + "rollup-plugin-visualizer": "dist/bin/cli.js" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "rollup": "2.x || 3.x || 4.x" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/rollup/node_modules/@types/estree": { + "version": "1.0.5", + "license": "MIT" + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/scule": { + "version": "1.3.0", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.6.3", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-placeholder": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "defu": "^6.1.4" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "license": "ISC" + }, + "node_modules/simple-git": { + "version": "3.27.0", + "license": "MIT", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, + "node_modules/sirv": { + "version": "2.0.4", + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "license": "MIT" + }, + "node_modules/slash": { + "version": "5.1.0", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/smob": { + "version": "1.5.0", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.7.4", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.7.0", + "license": "MIT" + }, + "node_modules/streamx": { + "version": "2.20.1", + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.0", + "license": "MIT" + }, + "node_modules/stylehacks": { + "version": "7.0.4", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "postcss-selector-parser": "^6.1.2" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/superjson": { + "version": "2.2.1", + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0" + }, + "node_modules/svgo": { + "version": "3.3.2", + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/system-architecture": { + "version": "0.1.0", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + }, + "node_modules/terser": { + "version": "5.33.0", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "license": "MIT" + }, + "node_modules/text-decoder": { + "version": "1.2.0", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.6", + "license": "ISC", + "dependencies": { + "fdir": "^6.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.3.0", + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "license": "MIT" + }, + "node_modules/trpc-nuxt": { + "version": "0.10.22", + "license": "MIT", + "dependencies": { + "h3": "^1.11.1", + "ohash": "^1.1.3" + }, + "peerDependencies": { + "@trpc/client": "^10.38.1 <11", + "@trpc/server": "^10.38.1 <11", + "ofetch": "^1.3.3" + } + }, + "node_modules/type-fest": { + "version": "3.13.1", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.6.2", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.5.4", + "license": "MIT" + }, + "node_modules/ultrahtml": { + "version": "1.5.3", + "license": "MIT" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "license": "MIT" + }, + "node_modules/unctx": { + "version": "2.3.1", + "license": "MIT", + "dependencies": { + "acorn": "^8.8.2", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.0", + "unplugin": "^1.3.1" + } + }, + "node_modules/undici": { + "version": "5.28.4", + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "license": "MIT" + }, + "node_modules/unenv": { + "version": "1.10.0", + "license": "MIT", + "dependencies": { + "consola": "^3.2.3", + "defu": "^6.1.4", + "mime": "^3.0.0", + "node-fetch-native": "^1.6.4", + "pathe": "^1.1.2" + } + }, + "node_modules/unenv/node_modules/mime": { + "version": "3.0.0", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/unhead": { + "version": "1.11.6", + "license": "MIT", + "dependencies": { + "@unhead/dom": "1.11.6", + "@unhead/schema": "1.11.6", + "@unhead/shared": "1.11.6", + "hookable": "^5.5.3" + }, + "funding": { + "url": "https://github.com/sponsors/harlan-zw" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unimport": { + "version": "3.12.0", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0", + "acorn": "^8.12.1", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "fast-glob": "^3.3.2", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.11", + "mlly": "^1.7.1", + "pathe": "^1.1.2", + "pkg-types": "^1.2.0", + "scule": "^1.3.0", + "strip-literal": "^2.1.0", + "unplugin": "^1.14.1" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unplugin": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "acorn": "^8.12.1", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "webpack-sources": "^3" + }, + "peerDependenciesMeta": { + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/unplugin-vue-router": { + "version": "0.10.8", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.4", + "@rollup/pluginutils": "^5.1.0", + "@vue-macros/common": "^1.12.2", + "ast-walker-scope": "^0.6.2", + "chokidar": "^3.6.0", + "fast-glob": "^3.3.2", + "json5": "^2.2.3", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.11", + "mlly": "^1.7.1", + "pathe": "^1.1.2", + "scule": "^1.3.0", + "unplugin": "^1.12.2", + "yaml": "^2.5.0" + }, + "peerDependencies": { + "vue-router": "^4.4.0" + }, + "peerDependenciesMeta": { + "vue-router": { + "optional": true + } + } + }, + "node_modules/unstorage": { + "version": "1.12.0", + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^3.6.0", + "destr": "^2.0.3", + "h3": "^1.12.0", + "listhen": "^1.7.2", + "lru-cache": "^10.4.3", + "mri": "^1.2.0", + "node-fetch-native": "^1.6.4", + "ofetch": "^1.3.4", + "ufo": "^1.5.4" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.7.0", + "@azure/cosmos": "^4.1.1", + "@azure/data-tables": "^13.2.2", + "@azure/identity": "^4.4.1", + "@azure/keyvault-secrets": "^4.8.0", + "@azure/storage-blob": "^12.24.0", + "@capacitor/preferences": "^6.0.2", + "@netlify/blobs": "^6.5.0 || ^7.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.0", + "@vercel/kv": "^1.0.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.1" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + } + } + }, + "node_modules/unstorage/node_modules/lru-cache": { + "version": "10.4.3", + "license": "ISC" + }, + "node_modules/untun": { + "version": "0.1.3", + "license": "MIT", + "dependencies": { + "citty": "^0.1.5", + "consola": "^3.2.3", + "pathe": "^1.1.1" + }, + "bin": { + "untun": "bin/untun.mjs" + } + }, + "node_modules/untyped": { + "version": "1.4.2", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.7", + "@babel/standalone": "^7.23.8", + "@babel/types": "^7.23.6", + "defu": "^6.1.4", + "jiti": "^1.21.0", + "mri": "^1.2.0", + "scule": "^1.2.0" + }, + "bin": { + "untyped": "dist/cli.mjs" + } + }, + "node_modules/unwasm": { + "version": "0.3.9", + "license": "MIT", + "dependencies": { + "knitwork": "^1.0.0", + "magic-string": "^0.30.8", + "mlly": "^1.6.1", + "pathe": "^1.1.2", + "pkg-types": "^1.0.3", + "unplugin": "^1.10.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uqr": { + "version": "0.1.2", + "license": "MIT" + }, + "node_modules/urlpattern-polyfill": { + "version": "8.0.2", + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/vite": { + "version": "5.4.7", + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-hot-client": { + "version": "0.2.3", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0" + } + }, + "node_modules/vite-node": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.6", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-plugin-checker": { + "version": "0.8.0", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "ansi-escapes": "^4.3.0", + "chalk": "^4.1.1", + "chokidar": "^3.5.1", + "commander": "^8.0.0", + "fast-glob": "^3.2.7", + "fs-extra": "^11.1.0", + "npm-run-path": "^4.0.1", + "strip-ansi": "^6.0.0", + "tiny-invariant": "^1.1.0", + "vscode-languageclient": "^7.0.0", + "vscode-languageserver": "^7.0.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-uri": "^3.0.2" + }, + "engines": { + "node": ">=14.16" + }, + "peerDependencies": { + "@biomejs/biome": ">=1.7", + "eslint": ">=7", + "meow": "^9.0.0", + "optionator": "^0.9.1", + "stylelint": ">=13", + "typescript": "*", + "vite": ">=2.0.0", + "vls": "*", + "vti": "*", + "vue-tsc": "~2.1.6" + }, + "peerDependenciesMeta": { + "@biomejs/biome": { + "optional": true + }, + "eslint": { + "optional": true + }, + "meow": { + "optional": true + }, + "optionator": { + "optional": true + }, + "stylelint": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vls": { + "optional": true + }, + "vti": { + "optional": true + }, + "vue-tsc": { + "optional": true + } + } + }, + "node_modules/vite-plugin-checker/node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/vite-plugin-checker/node_modules/chalk": { + "version": "4.1.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/vite-plugin-checker/node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/vite-plugin-checker/node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/vite-plugin-checker/node_modules/commander": { + "version": "8.3.0", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/vite-plugin-checker/node_modules/has-flag": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/vite-plugin-checker/node_modules/npm-run-path": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vite-plugin-checker/node_modules/supports-color": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vite-plugin-inspect": { + "version": "0.8.7", + "license": "MIT", + "dependencies": { + "@antfu/utils": "^0.7.10", + "@rollup/pluginutils": "^5.1.0", + "debug": "^4.3.6", + "error-stack-parser-es": "^0.1.5", + "fs-extra": "^11.2.0", + "open": "^10.1.0", + "perfect-debounce": "^1.0.0", + "picocolors": "^1.0.1", + "sirv": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/vite-plugin-inspect/node_modules/define-lazy-prop": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vite-plugin-inspect/node_modules/open": { + "version": "10.1.0", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vite-plugin-vue-inspector": { + "version": "5.2.0", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.0", + "@babel/plugin-proposal-decorators": "^7.23.0", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.22.15", + "@vue/babel-plugin-jsx": "^1.1.5", + "@vue/compiler-dom": "^3.3.4", + "kolorist": "^1.8.0", + "magic-string": "^0.30.4" + }, + "peerDependencies": { + "vite": "^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0" + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vscode-jsonrpc": { + "version": "6.0.0", + "license": "MIT", + "engines": { + "node": ">=8.0.0 || >=10.0.0" + } + }, + "node_modules/vscode-languageclient": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.4", + "semver": "^7.3.4", + "vscode-languageserver-protocol": "3.16.0" + }, + "engines": { + "vscode": "^1.52.0" + } + }, + "node_modules/vscode-languageclient/node_modules/brace-expansion": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/vscode-languageclient/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/vscode-languageserver": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.16.0" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.16.0", + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "6.0.0", + "vscode-languageserver-types": "3.16.0" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.16.0", + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.11.tgz", + "integrity": "sha512-/8Wurrd9J3lb72FTQS7gRMNQD4nztTtKPmuDuPuhqXmmpD6+skVjAeahNpVzsuky6Sy9gy7wn8UadqPtt9SQIg==", + "dependencies": { + "@vue/compiler-dom": "3.5.11", + "@vue/compiler-sfc": "3.5.11", + "@vue/runtime-dom": "3.5.11", + "@vue/server-renderer": "3.5.11", + "@vue/shared": "3.5.11" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-bundle-renderer": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "ufo": "^1.5.3" + } + }, + "node_modules/vue-devtools-stub": { + "version": "0.1.0", + "license": "MIT" + }, + "node_modules/vue-router": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz", + "integrity": "sha512-4fKZygS8cH1yCyuabAXGUAsyi1b2/o/OKgu/RUb+znIYOxPRxdkytJEx+0wGcpBE1pX6vUgh5jwWOKRGvuA/7Q==", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "license": "BSD-2-Clause" + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "license": "MIT" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "3.0.1", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.18.0", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.5.1", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/zhead": { + "version": "2.2.4", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/harlan-zw" + } + }, + "node_modules/zip-stream": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/zod": { + "version": "3.23.8", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json new file mode 100644 index 000000000..e20211c8d --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json @@ -0,0 +1,27 @@ +{ + "name": "nuxt-app", + "private": true, + "type": "module", + "scripts": { + "build": "nuxt typecheck && nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare" + }, + "dependencies": { + "@prisma/client": "^5.19.1", + "@trpc/client": "^10.45.2", + "@trpc/server": "^10.45.2", + "nuxt": "^3.13.0", + "trpc-nuxt": "^0.10.22", + "vue": "latest", + "vue-router": "latest", + "zod": "^3.23.8" + }, + "devDependencies": { + "esbuild": "^0.24.0", + "prisma": "^5.19.1", + "typescript": "^5.6.2" + } +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/plugins/client.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/plugins/client.ts new file mode 100644 index 000000000..9493be346 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/plugins/client.ts @@ -0,0 +1,23 @@ +import { httpBatchLink } from 'trpc-nuxt/client'; +import type { AppRouter } from '~/server/trpc/routers'; +import { createTRPCNuxtClient } from '~/server/trpc/routers/generated/client/nuxt'; + +export default defineNuxtPlugin(() => { + /** + * createTRPCNuxtClient adds a `useQuery` composable + * built on top of `useAsyncData`. + */ + const client = createTRPCNuxtClient({ + links: [ + httpBatchLink({ + url: '/api/trpc', + }), + ], + }); + + return { + provide: { + client, + }, + }; +}); diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/prisma/schema.prisma b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/prisma/schema.prisma new file mode 100644 index 000000000..e83468bb0 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/prisma/schema.prisma @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////////////////////////// +// DO NOT MODIFY THIS FILE // +// This file is automatically generated by ZenStack CLI and should not be manually updated. // +////////////////////////////////////////////////////////////////////////////////////////////// + +datasource db { + provider = "sqlite" + url = "file:./dev.db" +} + +generator client { + provider = "prisma-client-js" +} + +/// @@allow('create', true) +/// @@allow('all', auth() == this) +model User { + id String @id() @default(cuid()) + /// @email + /// @length(6, 32) + email String @unique() + /// @password + /// @omit + password String + posts Post[] +} + +/// @@allow('read', auth() != null && published) +/// @@allow('all', author == auth()) +model Post { + id String @id() @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt() + /// @length(1, 256) + title String + content String + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId String +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/public/favicon.ico b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/public/favicon.ico new file mode 100644 index 000000000..18993ad91 Binary files /dev/null and b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/public/favicon.ico differ diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/schema.zmodel b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/schema.zmodel new file mode 100644 index 000000000..c68fcdd19 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/schema.zmodel @@ -0,0 +1,55 @@ +// This is a sample model to get you started. + +/** + * A sample data source using local sqlite db. + */ +datasource db { + provider = 'sqlite' + url = 'file:./dev.db' +} + +generator client { + provider = "prisma-client-js" +} + +plugin trpc { + provider = "../../../dist" + output = './server/trpc/routers/generated' + generateClientHelpers = 'nuxt' +} + +/** + * User model + */ +model User { + id String @id @default(cuid()) + email String @unique @email @length(6, 32) + password String @password @omit + posts Post[] + + // everybody can signup + @@allow('create', true) + + // full access by self + @@allow('all', auth() == this) +} + +/** + * Post model + */ +model Post { + id String @id @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String @length(1, 256) + content String + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId String + + // allow read for all signin users + @@allow('read', auth() != null && published) + + // full access by author + @@allow('all', author == auth()) +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/api/trpc/[trpc].ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/api/trpc/[trpc].ts new file mode 100644 index 000000000..1f1e2154a --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/api/trpc/[trpc].ts @@ -0,0 +1,9 @@ +import { createNuxtApiHandler } from 'trpc-nuxt'; +import { appRouter } from '../../trpc/routers'; +import { createContext } from '../../trpc/context'; + +// export API handler +export default createNuxtApiHandler({ + router: appRouter, + createContext, +}); diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/db.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/db.ts new file mode 100644 index 000000000..9b6c4ce30 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/db.ts @@ -0,0 +1,3 @@ +import { PrismaClient } from '@prisma/client'; + +export const prisma = new PrismaClient(); diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/context.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/context.ts new file mode 100644 index 000000000..46a2ffa74 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/context.ts @@ -0,0 +1,12 @@ +import { inferAsyncReturnType } from '@trpc/server'; +import { prisma } from '../db'; + +/** + * Creates context for an incoming request + * @link https://trpc.io/docs/context + */ +export const createContext = () => ({ + prisma, +}); + +export type Context = inferAsyncReturnType; diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/Post.nuxt.type.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/Post.nuxt.type.ts new file mode 100644 index 000000000..118da4be5 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/Post.nuxt.type.ts @@ -0,0 +1,380 @@ +/* eslint-disable */ +import type { Prisma } from '@prisma/client'; +import type { TRPCClientErrorLike, TRPCRequestOptions } from '@trpc/client'; +import type { MaybeRefOrGetter, UnwrapRef } from 'vue'; +import type { AsyncData, AsyncDataOptions } from 'nuxt/app'; +import type { KeysOf, PickFrom } from './utils'; +import type { AnyRouter } from '@trpc/server'; + +export interface ClientType { + aggregate: { + + query: (input: Prisma.Subset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + createMany: { + + mutate: (input?: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input?: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + create: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + deleteMany: { + + mutate: (input?: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input?: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + delete: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + findFirst: { + + query: (input?: Prisma.SelectSubset) => Promise | null>; + useQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findFirstOrThrow: { + + query: (input?: Prisma.SelectSubset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findMany: { + + query: (input?: Prisma.SelectSubset) => Promise>>; + useQuery: >, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: >, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findUnique: { + + query: (input: Prisma.SelectSubset) => Promise | null>; + useQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findUniqueOrThrow: { + + query: (input: Prisma.SelectSubset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + groupBy: { + + query: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >(input: Prisma.SubsetIntersection & InputErrors) => Promise<{} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors>; + useQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , ResT = {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter & InputErrors>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , ResT = {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter & InputErrors>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + updateMany: { + + mutate: (input: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + update: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + upsert: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + count: { + + query: (input?: Prisma.Subset) => Promise<'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number>; + useQuery: + : number, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: + : number, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/User.nuxt.type.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/User.nuxt.type.ts new file mode 100644 index 000000000..fb4d90c74 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/User.nuxt.type.ts @@ -0,0 +1,380 @@ +/* eslint-disable */ +import type { Prisma } from '@prisma/client'; +import type { TRPCClientErrorLike, TRPCRequestOptions } from '@trpc/client'; +import type { MaybeRefOrGetter, UnwrapRef } from 'vue'; +import type { AsyncData, AsyncDataOptions } from 'nuxt/app'; +import type { KeysOf, PickFrom } from './utils'; +import type { AnyRouter } from '@trpc/server'; + +export interface ClientType { + aggregate: { + + query: (input: Prisma.Subset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + createMany: { + + mutate: (input?: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input?: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + create: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + deleteMany: { + + mutate: (input?: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input?: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + delete: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + findFirst: { + + query: (input?: Prisma.SelectSubset) => Promise | null>; + useQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findFirstOrThrow: { + + query: (input?: Prisma.SelectSubset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findMany: { + + query: (input?: Prisma.SelectSubset) => Promise>>; + useQuery: >, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: >, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findUnique: { + + query: (input: Prisma.SelectSubset) => Promise | null>; + useQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findUniqueOrThrow: { + + query: (input: Prisma.SelectSubset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + groupBy: { + + query: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >(input: Prisma.SubsetIntersection & InputErrors) => Promise<{} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors>; + useQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , ResT = {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter & InputErrors>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , ResT = {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter & InputErrors>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + updateMany: { + + mutate: (input: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + update: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + upsert: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + count: { + + query: (input?: Prisma.Subset) => Promise<'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number>; + useQuery: + : number, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: + : number, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/nuxt.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/nuxt.ts new file mode 100644 index 000000000..8bffd4a5b --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/nuxt.ts @@ -0,0 +1,19 @@ +/* eslint-disable */ + +import type { AnyRouter } from '@trpc/server'; +import { createTRPCNuxtClient as _createTRPCNuxtClient } from 'trpc-nuxt/client'; +import type { DeepOverrideAtPath } from './utils'; +import { ClientType as UserClientType } from "./User.nuxt.type"; +import { ClientType as PostClientType } from "./Post.nuxt.type"; + +export function createTRPCNuxtClient( + opts: Parameters>[0] +) { + const r = _createTRPCNuxtClient(opts); + return r as DeepOverrideAtPath, TPath>; +} + +export interface ClientType { + user: UserClientType; + post: PostClientType; +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/utils.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/utils.ts new file mode 100644 index 000000000..8173ebbc0 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/utils.ts @@ -0,0 +1,46 @@ +/* eslint-disable */ + +// inspired by: https://stackoverflow.com/questions/70632026/generic-to-recursively-modify-a-given-type-interface-in-typescript + +type Primitive = string | Function | number | boolean | Symbol | undefined | null; + +/** + * Recursively merges `T` and `R`. If there's a shared key, use `R`'s field type to overwrite `T`. + */ +export type DeepOverride = T extends Primitive + ? R + : R extends Primitive + ? R + : { + [K in keyof T]: K extends keyof R ? DeepOverride : T[K]; + } & { + [K in Exclude]: R[K]; + }; + +/** + * Traverse to `Path` (denoted by dot separated string literal type) in `T`, and starting from there, + * recursively merge with `R`. + */ +export type DeepOverrideAtPath = Path extends undefined + ? DeepOverride + : Path extends `${infer P1}.${infer P2}` + ? P1 extends keyof T + ? Omit & Record>> + : never + : Path extends keyof T + ? Omit & Record> + : never; + +// Utility type from 'trpc-nuxt' +export type KeysOf = Array; + +// Utility type from 'trpc-nuxt' +export type PickFrom> = T extends Array + ? T + : T extends Record + ? keyof T extends K[number] + ? T + : K[number] extends never + ? T + : Pick + : T; diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/helper.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/helper.ts new file mode 100644 index 000000000..7f292fff2 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/helper.ts @@ -0,0 +1,69 @@ +/* eslint-disable */ +import { TRPCError } from '@trpc/server'; +import { isPrismaClientKnownRequestError } from '@zenstackhq/runtime'; + +export async function checkMutate(promise: Promise): Promise { + try { + return await promise; + } catch (err: any) { + if (isPrismaClientKnownRequestError(err)) { + if (err.code === 'P2004') { + if (err.meta?.reason === 'RESULT_NOT_READABLE') { + // unable to readback data + return undefined; + } else { + // rejected by policy + throw new TRPCError({ + code: 'FORBIDDEN', + message: err.message, + cause: err, + }); + } + } else { + // request error + throw new TRPCError({ + code: 'BAD_REQUEST', + message: err.message, + cause: err, + }); + } + } else { + throw err; + } + } + +} + +export async function checkRead(promise: Promise): Promise { + try { + return await promise; + } catch (err: any) { + if (isPrismaClientKnownRequestError(err)) { + if (err.code === 'P2004') { + // rejected by policy + throw new TRPCError({ + code: 'FORBIDDEN', + message: err.message, + cause: err, + }); + } else if (err.code === 'P2025') { + // not found + throw new TRPCError({ + code: 'NOT_FOUND', + message: err.message, + cause: err, + }); + } else { + // request error + throw new TRPCError({ + code: 'BAD_REQUEST', + message: err.message, + cause: err, + }) + } + } else { + throw err; + } + } + +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/routers/Post.router.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/routers/Post.router.ts new file mode 100644 index 000000000..1733631f2 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/routers/Post.router.ts @@ -0,0 +1,42 @@ +/* eslint-disable */ +import { type RouterFactory, type ProcBuilder, type BaseConfig, db } from "."; +import * as _Schema from '@zenstackhq/runtime/zod/input'; +const $Schema: typeof _Schema = (_Schema as any).default ?? _Schema; +import { checkRead, checkMutate } from '../helper'; + +export default function createRouter(router: RouterFactory, procedure: ProcBuilder) { + return router({ + + aggregate: procedure.input($Schema.PostInputSchema.aggregate).query(({ ctx, input }) => checkRead(db(ctx).post.aggregate(input as any))), + + createMany: procedure.input($Schema.PostInputSchema.createMany.optional()).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.createMany(input as any))), + + create: procedure.input($Schema.PostInputSchema.create).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.create(input as any))), + + deleteMany: procedure.input($Schema.PostInputSchema.deleteMany.optional()).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.deleteMany(input as any))), + + delete: procedure.input($Schema.PostInputSchema.delete).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.delete(input as any))), + + findFirst: procedure.input($Schema.PostInputSchema.findFirst.optional()).query(({ ctx, input }) => checkRead(db(ctx).post.findFirst(input as any))), + + findFirstOrThrow: procedure.input($Schema.PostInputSchema.findFirst.optional()).query(({ ctx, input }) => checkRead(db(ctx).post.findFirstOrThrow(input as any))), + + findMany: procedure.input($Schema.PostInputSchema.findMany.optional()).query(({ ctx, input }) => checkRead(db(ctx).post.findMany(input as any))), + + findUnique: procedure.input($Schema.PostInputSchema.findUnique).query(({ ctx, input }) => checkRead(db(ctx).post.findUnique(input as any))), + + findUniqueOrThrow: procedure.input($Schema.PostInputSchema.findUnique).query(({ ctx, input }) => checkRead(db(ctx).post.findUniqueOrThrow(input as any))), + + groupBy: procedure.input($Schema.PostInputSchema.groupBy).query(({ ctx, input }) => checkRead(db(ctx).post.groupBy(input as any))), + + updateMany: procedure.input($Schema.PostInputSchema.updateMany).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.updateMany(input as any))), + + update: procedure.input($Schema.PostInputSchema.update).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.update(input as any))), + + upsert: procedure.input($Schema.PostInputSchema.upsert).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.upsert(input as any))), + + count: procedure.input($Schema.PostInputSchema.count.optional()).query(({ ctx, input }) => checkRead(db(ctx).post.count(input as any))), + + } + ); +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/routers/User.router.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/routers/User.router.ts new file mode 100644 index 000000000..da606d2da --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/routers/User.router.ts @@ -0,0 +1,42 @@ +/* eslint-disable */ +import { type RouterFactory, type ProcBuilder, type BaseConfig, db } from "."; +import * as _Schema from '@zenstackhq/runtime/zod/input'; +const $Schema: typeof _Schema = (_Schema as any).default ?? _Schema; +import { checkRead, checkMutate } from '../helper'; + +export default function createRouter(router: RouterFactory, procedure: ProcBuilder) { + return router({ + + aggregate: procedure.input($Schema.UserInputSchema.aggregate).query(({ ctx, input }) => checkRead(db(ctx).user.aggregate(input as any))), + + createMany: procedure.input($Schema.UserInputSchema.createMany.optional()).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.createMany(input as any))), + + create: procedure.input($Schema.UserInputSchema.create).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.create(input as any))), + + deleteMany: procedure.input($Schema.UserInputSchema.deleteMany.optional()).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.deleteMany(input as any))), + + delete: procedure.input($Schema.UserInputSchema.delete).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.delete(input as any))), + + findFirst: procedure.input($Schema.UserInputSchema.findFirst.optional()).query(({ ctx, input }) => checkRead(db(ctx).user.findFirst(input as any))), + + findFirstOrThrow: procedure.input($Schema.UserInputSchema.findFirst.optional()).query(({ ctx, input }) => checkRead(db(ctx).user.findFirstOrThrow(input as any))), + + findMany: procedure.input($Schema.UserInputSchema.findMany.optional()).query(({ ctx, input }) => checkRead(db(ctx).user.findMany(input as any))), + + findUnique: procedure.input($Schema.UserInputSchema.findUnique).query(({ ctx, input }) => checkRead(db(ctx).user.findUnique(input as any))), + + findUniqueOrThrow: procedure.input($Schema.UserInputSchema.findUnique).query(({ ctx, input }) => checkRead(db(ctx).user.findUniqueOrThrow(input as any))), + + groupBy: procedure.input($Schema.UserInputSchema.groupBy).query(({ ctx, input }) => checkRead(db(ctx).user.groupBy(input as any))), + + updateMany: procedure.input($Schema.UserInputSchema.updateMany).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.updateMany(input as any))), + + update: procedure.input($Schema.UserInputSchema.update).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.update(input as any))), + + upsert: procedure.input($Schema.UserInputSchema.upsert).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.upsert(input as any))), + + count: procedure.input($Schema.UserInputSchema.count.optional()).query(({ ctx, input }) => checkRead(db(ctx).user.count(input as any))), + + } + ); +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/routers/index.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/routers/index.ts new file mode 100644 index 000000000..076308882 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/routers/index.ts @@ -0,0 +1,34 @@ +/* eslint-disable */ +import type { unsetMarker, AnyRouter, AnyRootConfig, CreateRouterInner, Procedure, ProcedureBuilder, ProcedureParams, ProcedureRouterRecord, ProcedureType } from "@trpc/server"; +import type { PrismaClient } from "@prisma/client"; +import createUserRouter from "./User.router"; +import createPostRouter from "./Post.router"; + +export type BaseConfig = AnyRootConfig; + +export type RouterFactory = < + ProcRouterRecord extends ProcedureRouterRecord +>( + procedures: ProcRouterRecord +) => CreateRouterInner; + +export type UnsetMarker = typeof unsetMarker; + +export type ProcBuilder = ProcedureBuilder< + ProcedureParams +>; + +export function db(ctx: any) { + if (!ctx.prisma) { + throw new Error('Missing "prisma" field in trpc context'); + } + return ctx.prisma as PrismaClient; +} + +export function createRouter(router: RouterFactory, procedure: ProcBuilder) { + return router({ + user: createUserRouter(router, procedure), + post: createPostRouter(router, procedure), + } + ); +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/index.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/index.ts new file mode 100644 index 000000000..a73321b66 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/index.ts @@ -0,0 +1,7 @@ +import { publicProcedure, router } from '../trpc'; +import { createRouter as createCRUDRouter } from './generated/routers'; + +export const appRouter = createCRUDRouter(router, publicProcedure); + +// export type definition of API +export type AppRouter = typeof appRouter; diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/trpc.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/trpc.ts new file mode 100644 index 000000000..0b93ecda7 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/trpc.ts @@ -0,0 +1,20 @@ +/** + * This is your entry point to setup the root configuration for tRPC on the server. + * - `initTRPC` should only be used once per app. + * - We export only the functionality that we use so we can enforce which base procedures should be used + * + * Learn how to create protected base procedures and other things below: + * @see https://trpc.io/docs/v10/router + * @see https://trpc.io/docs/v10/procedures + */ +import { initTRPC } from '@trpc/server'; +import { Context } from './context'; + +const t = initTRPC.context().create(); + +/** + * Unprotected procedure + **/ +export const publicProcedure = t.procedure; +export const router = t.router; +export const middleware = t.middleware; diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/tsconfig.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/tsconfig.json new file mode 100644 index 000000000..b9ed69c19 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/tsconfig.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/tsconfig.json new file mode 100644 index 000000000..f80f43a36 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/tsconfig.json @@ -0,0 +1,7 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json", + "compilerOptions": { + "verbatimModuleSyntax": false + } +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/.gitignore b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/.gitignore new file mode 100644 index 000000000..cdb506446 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/.gitignore @@ -0,0 +1,26 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example + +*.db diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/README.md b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/README.md new file mode 100644 index 000000000..f5db2a2db --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/README.md @@ -0,0 +1,75 @@ +# Nuxt 3 Minimal Starter + +Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. + +## Setup + +Make sure to install the dependencies: + +```bash +# npm +npm install + +# pnpm +pnpm install + +# yarn +yarn install + +# bun +bun install +``` + +## Development Server + +Start the development server on `http://localhost:3000`: + +```bash +# npm +npm run dev + +# pnpm +pnpm run dev + +# yarn +yarn dev + +# bun +bun run dev +``` + +## Production + +Build the application for production: + +```bash +# npm +npm run build + +# pnpm +pnpm run build + +# yarn +yarn build + +# bun +bun run build +``` + +Locally preview production build: + +```bash +# npm +npm run preview + +# pnpm +pnpm run preview + +# yarn +yarn preview + +# bun +bun run preview +``` + +Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/app.vue b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/app.vue new file mode 100644 index 000000000..8b526f9ed --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/app.vue @@ -0,0 +1,50 @@ + + + diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/nuxt.config.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/nuxt.config.ts new file mode 100644 index 000000000..897b1221c --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/nuxt.config.ts @@ -0,0 +1,8 @@ +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + compatibilityDate: '2024-04-03', + devtools: { enabled: true }, + build: { + transpile: ['trpc-nuxt'], + }, +}); diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package-lock.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package-lock.json new file mode 100644 index 000000000..8bbbdd208 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package-lock.json @@ -0,0 +1,968 @@ +{ + "name": "nuxt-app", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nuxt-app", + "hasInstallScript": true, + "dependencies": { + "@prisma/client": "^5.19.1", + "@trpc/client": "^11.0.0-rc.563", + "@trpc/server": "^11.0.0-rc.563", + "trpc-nuxt": "^0.11.0-beta.1", + "vue": "latest", + "vue-router": "latest", + "zod": "^3.23.8" + }, + "devDependencies": { + "esbuild": "^0.24.0", + "prisma": "^5.19.1", + "typescript": "^5.6.2" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.6", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "license": "MIT" + }, + "node_modules/@prisma/client": { + "version": "5.19.1", + "hasInstallScript": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.13" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/debug": { + "version": "5.19.1", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/engines": { + "version": "5.19.1", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.19.1", + "@prisma/engines-version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3", + "@prisma/fetch-engine": "5.19.1", + "@prisma/get-platform": "5.19.1" + } + }, + "node_modules/@prisma/engines-version": { + "version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/fetch-engine": { + "version": "5.19.1", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.19.1", + "@prisma/engines-version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3", + "@prisma/get-platform": "5.19.1" + } + }, + "node_modules/@prisma/get-platform": { + "version": "5.19.1", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.19.1" + } + }, + "node_modules/@trpc/client": { + "version": "11.0.0-rc.563", + "resolved": "https://registry.npmjs.org/@trpc/client/-/client-11.0.0-rc.563.tgz", + "integrity": "sha512-N1ldp7NGduuWoj/cuAQXvKkp/2MM3eVteRGLxuOgD5HzCKoDaJRSR/7EUm0qz8o51TW1LMbdoiYsM5Ip1lmXdA==", + "funding": [ + "https://trpc.io/sponsor" + ], + "peerDependencies": { + "@trpc/server": "11.0.0-rc.563+e5ae464b2" + } + }, + "node_modules/@trpc/server": { + "version": "11.0.0-rc.563", + "resolved": "https://registry.npmjs.org/@trpc/server/-/server-11.0.0-rc.563.tgz", + "integrity": "sha512-yB7oNWIIrZTavlETrQeijo+JUh6CTeQTrqlMCJ7qHfqyadrfxa7O4JJ5pk9J5nur0sxiACwFi0RiQxSlrOVb2A==", + "funding": [ + "https://trpc.io/sponsor" + ] + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.11.tgz", + "integrity": "sha512-PwAdxs7/9Hc3ieBO12tXzmTD+Ln4qhT/56S+8DvrrZ4kLDn4Z/AMUr8tXJD0axiJBS0RKIoNaR0yMuQB9v9Udg==", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.11", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-core/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.11.tgz", + "integrity": "sha512-pyGf8zdbDDRkBrEzf8p7BQlMKNNF5Fk/Cf/fQ6PiUz9at4OaUfyXW0dGJTo2Vl1f5U9jSLCNf0EZJEogLXoeew==", + "dependencies": { + "@vue/compiler-core": "3.5.11", + "@vue/shared": "3.5.11" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.11.tgz", + "integrity": "sha512-gsbBtT4N9ANXXepprle+X9YLg2htQk1sqH/qGJ/EApl+dgpUBdTv3yP7YlR535uHZY3n6XaR0/bKo0BgwwDniw==", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.11", + "@vue/compiler-dom": "3.5.11", + "@vue/compiler-ssr": "3.5.11", + "@vue/shared": "3.5.11", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.11", + "postcss": "^8.4.47", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/estree-walker": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.11.tgz", + "integrity": "sha512-P4+GPjOuC2aFTk1Z4WANvEhyOykcvEd5bIj2KVNGKGfM745LaXGr++5njpdBTzVz5pZifdlR1kpYSJJpIlSePA==", + "dependencies": { + "@vue/compiler-dom": "3.5.11", + "@vue/shared": "3.5.11" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "license": "MIT" + }, + "node_modules/@vue/reactivity": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.11.tgz", + "integrity": "sha512-Nqo5VZEn8MJWlCce8XoyVqHZbd5P2NH+yuAaFzuNSR96I+y1cnuUiq7xfSG+kyvLSiWmaHTKP1r3OZY4mMD50w==", + "dependencies": { + "@vue/shared": "3.5.11" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.11.tgz", + "integrity": "sha512-7PsxFGqwfDhfhh0OcDWBG1DaIQIVOLgkwA5q6MtkPiDFjp5gohVnJEahSktwSFLq7R5PtxDKy6WKURVN1UDbzA==", + "dependencies": { + "@vue/reactivity": "3.5.11", + "@vue/shared": "3.5.11" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.11.tgz", + "integrity": "sha512-GNghjecT6IrGf0UhuYmpgaOlN7kxzQBhxWEn08c/SQDxv1yy4IXI1bn81JgEpQ4IXjRxWtPyI8x0/7TF5rPfYQ==", + "dependencies": { + "@vue/reactivity": "3.5.11", + "@vue/runtime-core": "3.5.11", + "@vue/shared": "3.5.11", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.11.tgz", + "integrity": "sha512-cVOwYBxR7Wb1B1FoxYvtjJD8X/9E5nlH4VSkJy2uMA1MzYNdzAAB//l8nrmN9py/4aP+3NjWukf9PZ3TeWULaA==", + "dependencies": { + "@vue/compiler-ssr": "3.5.11", + "@vue/shared": "3.5.11" + }, + "peerDependencies": { + "vue": "3.5.11" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.11.tgz", + "integrity": "sha512-W8GgysJVnFo81FthhzurdRAWP/byq3q2qIw70e0JWblzVhjgOMiC2GyovXrZTFQJnFVryYaKGP3Tc9vYzYm6PQ==" + }, + "node_modules/consola": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", + "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/cookie-es": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz", + "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==" + }, + "node_modules/crossws": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.1.tgz", + "integrity": "sha512-HsZgeVYaG+b5zA+9PbIPGq4+J/CJynJuearykPsXx4V/eMhyQ5EDVg3Ak2FBZtVXCiOLu/U7IiwDHTr9MA+IKw==", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==" + }, + "node_modules/destr": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.3.tgz", + "integrity": "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==" + }, + "node_modules/entities": { + "version": "4.5.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/h3": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.13.0.tgz", + "integrity": "sha512-vFEAu/yf8UMUcB4s43OaDaigcqpQd14yanmOsn+NcRX3/guSKncyE2rOYhq8RIchgJrPSs/QiIddnTTR1ddiAg==", + "dependencies": { + "cookie-es": "^1.2.2", + "crossws": ">=0.2.0 <0.4.0", + "defu": "^6.1.4", + "destr": "^2.0.3", + "iron-webcrypto": "^1.2.1", + "ohash": "^1.1.4", + "radix3": "^1.1.2", + "ufo": "^1.5.4", + "uncrypto": "^0.1.3", + "unenv": "^1.10.0" + } + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/magic-string": { + "version": "0.30.11", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz", + "integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==" + }, + "node_modules/ofetch": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.4.0.tgz", + "integrity": "sha512-MuHgsEhU6zGeX+EMh+8mSMrYTnsqJQQrpM00Q6QHMKNqQ0bKy0B43tk8tL1wg+CnsSTy1kg4Ir2T5Ig6rD+dfQ==", + "dependencies": { + "destr": "^2.0.3", + "node-fetch-native": "^1.6.4", + "ufo": "^1.5.4" + } + }, + "node_modules/ohash": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz", + "integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==" + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==" + }, + "node_modules/picocolors": { + "version": "1.1.0", + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.4.47", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.7", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/prisma": { + "version": "5.19.1", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/engines": "5.19.1" + }, + "bin": { + "prisma": "build/index.js" + }, + "engines": { + "node": ">=16.13" + }, + "optionalDependencies": { + "fsevents": "2.3.3" + } + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/trpc-nuxt": { + "version": "0.11.0-beta.1", + "resolved": "https://registry.npmjs.org/trpc-nuxt/-/trpc-nuxt-0.11.0-beta.1.tgz", + "integrity": "sha512-8RvTkHsRKXtyo9LLjZe3yilHif2vKtoDsQH6oZI7FI7a08Yguk9ln6hwPEWLaZcnzvrKotzXxSnhFMqjmZi7rg==", + "dependencies": { + "h3": "^1.11.1", + "ofetch": "^1.3.4", + "ohash": "^1.1.3" + }, + "peerDependencies": { + "@trpc/client": "^11.0.0-rc.1", + "@trpc/server": "^11.0.0-rc.1" + } + }, + "node_modules/typescript": { + "version": "5.6.2", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==" + }, + "node_modules/unenv": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-1.10.0.tgz", + "integrity": "sha512-wY5bskBQFL9n3Eca5XnhH6KbUo/tfvkwm9OpcdCvLaeA7piBNbavbOKJySEwQ1V0RH6HvNlSAFRTpvTqgKRQXQ==", + "dependencies": { + "consola": "^3.2.3", + "defu": "^6.1.4", + "mime": "^3.0.0", + "node-fetch-native": "^1.6.4", + "pathe": "^1.1.2" + } + }, + "node_modules/vue": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.11.tgz", + "integrity": "sha512-/8Wurrd9J3lb72FTQS7gRMNQD4nztTtKPmuDuPuhqXmmpD6+skVjAeahNpVzsuky6Sy9gy7wn8UadqPtt9SQIg==", + "dependencies": { + "@vue/compiler-dom": "3.5.11", + "@vue/compiler-sfc": "3.5.11", + "@vue/runtime-dom": "3.5.11", + "@vue/server-renderer": "3.5.11", + "@vue/shared": "3.5.11" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-router": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz", + "integrity": "sha512-4fKZygS8cH1yCyuabAXGUAsyi1b2/o/OKgu/RUb+znIYOxPRxdkytJEx+0wGcpBE1pX6vUgh5jwWOKRGvuA/7Q==", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/zod": { + "version": "3.23.8", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json new file mode 100644 index 000000000..54acb8a0c --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json @@ -0,0 +1,26 @@ +{ + "name": "nuxt-app", + "private": true, + "type": "module", + "scripts": { + "build": "nuxt typecheck && nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare" + }, + "dependencies": { + "@prisma/client": "^5.19.1", + "@trpc/client": "^11.0.0-rc.563", + "@trpc/server": "^11.0.0-rc.563", + "trpc-nuxt": "^0.11.0-beta.1", + "vue": "latest", + "vue-router": "latest", + "zod": "^3.23.8" + }, + "devDependencies": { + "esbuild": "^0.24.0", + "prisma": "^5.19.1", + "typescript": "^5.6.2" + } +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/plugins/client.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/plugins/client.ts new file mode 100644 index 000000000..9493be346 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/plugins/client.ts @@ -0,0 +1,23 @@ +import { httpBatchLink } from 'trpc-nuxt/client'; +import type { AppRouter } from '~/server/trpc/routers'; +import { createTRPCNuxtClient } from '~/server/trpc/routers/generated/client/nuxt'; + +export default defineNuxtPlugin(() => { + /** + * createTRPCNuxtClient adds a `useQuery` composable + * built on top of `useAsyncData`. + */ + const client = createTRPCNuxtClient({ + links: [ + httpBatchLink({ + url: '/api/trpc', + }), + ], + }); + + return { + provide: { + client, + }, + }; +}); diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/prisma/schema.prisma b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/prisma/schema.prisma new file mode 100644 index 000000000..e83468bb0 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/prisma/schema.prisma @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////////////////////////// +// DO NOT MODIFY THIS FILE // +// This file is automatically generated by ZenStack CLI and should not be manually updated. // +////////////////////////////////////////////////////////////////////////////////////////////// + +datasource db { + provider = "sqlite" + url = "file:./dev.db" +} + +generator client { + provider = "prisma-client-js" +} + +/// @@allow('create', true) +/// @@allow('all', auth() == this) +model User { + id String @id() @default(cuid()) + /// @email + /// @length(6, 32) + email String @unique() + /// @password + /// @omit + password String + posts Post[] +} + +/// @@allow('read', auth() != null && published) +/// @@allow('all', author == auth()) +model Post { + id String @id() @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt() + /// @length(1, 256) + title String + content String + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId String +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/public/favicon.ico b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/public/favicon.ico new file mode 100644 index 000000000..18993ad91 Binary files /dev/null and b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/public/favicon.ico differ diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/schema.zmodel b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/schema.zmodel new file mode 100644 index 000000000..6bda37a9b --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/schema.zmodel @@ -0,0 +1,58 @@ +// This is a sample model to get you started. + +/** + * A sample data source using local sqlite db. + */ +datasource db { + provider = 'sqlite' + url = 'file:./dev.db' +} + +generator client { + provider = "prisma-client-js" +} + +plugin trpc { + provider = "../../../dist" + version = "v11" + importCreateRouter = "../../generated-router-helper" + importProcedure = "../../generated-router-helper" + output = './server/trpc/routers/generated' + generateClientHelpers = 'nuxt' +} + +/** + * User model + */ +model User { + id String @id @default(cuid()) + email String @unique @email @length(6, 32) + password String @password @omit + posts Post[] + + // everybody can signup + @@allow('create', true) + + // full access by self + @@allow('all', auth() == this) +} + +/** + * Post model + */ +model Post { + id String @id @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String @length(1, 256) + content String + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId String + + // allow read for all signin users + @@allow('read', auth() != null && published) + + // full access by author + @@allow('all', author == auth()) +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/api/trpc/[trpc].ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/api/trpc/[trpc].ts new file mode 100644 index 000000000..1f1e2154a --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/api/trpc/[trpc].ts @@ -0,0 +1,9 @@ +import { createNuxtApiHandler } from 'trpc-nuxt'; +import { appRouter } from '../../trpc/routers'; +import { createContext } from '../../trpc/context'; + +// export API handler +export default createNuxtApiHandler({ + router: appRouter, + createContext, +}); diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/db.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/db.ts new file mode 100644 index 000000000..9b6c4ce30 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/db.ts @@ -0,0 +1,3 @@ +import { PrismaClient } from '@prisma/client'; + +export const prisma = new PrismaClient(); diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/context.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/context.ts new file mode 100644 index 000000000..46a2ffa74 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/context.ts @@ -0,0 +1,12 @@ +import { inferAsyncReturnType } from '@trpc/server'; +import { prisma } from '../db'; + +/** + * Creates context for an incoming request + * @link https://trpc.io/docs/context + */ +export const createContext = () => ({ + prisma, +}); + +export type Context = inferAsyncReturnType; diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated-router-helper.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated-router-helper.ts new file mode 100644 index 000000000..c0226d129 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated-router-helper.ts @@ -0,0 +1,2 @@ +export { router as createTRPCRouter } from '../trpc'; +export { publicProcedure as procedure } from '../trpc'; diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/Post.nuxt.type.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/Post.nuxt.type.ts new file mode 100644 index 000000000..bf6e93498 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/Post.nuxt.type.ts @@ -0,0 +1,380 @@ +/* eslint-disable */ +import type { Prisma } from '@prisma/client'; +import type { TRPCClientErrorLike, TRPCRequestOptions } from '@trpc/client'; +import type { MaybeRefOrGetter, UnwrapRef } from 'vue'; +import type { AsyncData, AsyncDataOptions } from 'nuxt/app'; +import type { KeysOf, PickFrom } from './utils'; +import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; + +export interface ClientType { + aggregate: { + + query: (input: Prisma.Subset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + createMany: { + + mutate: (input?: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input?: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + create: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + deleteMany: { + + mutate: (input?: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input?: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + delete: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + findFirst: { + + query: (input?: Prisma.SelectSubset) => Promise | null>; + useQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findFirstOrThrow: { + + query: (input?: Prisma.SelectSubset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findMany: { + + query: (input?: Prisma.SelectSubset) => Promise>>; + useQuery: >, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: >, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findUnique: { + + query: (input: Prisma.SelectSubset) => Promise | null>; + useQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findUniqueOrThrow: { + + query: (input: Prisma.SelectSubset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + groupBy: { + + query: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >(input: Prisma.SubsetIntersection & InputErrors) => Promise<{} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors>; + useQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , ResT = {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter & InputErrors>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , ResT = {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter & InputErrors>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + updateMany: { + + mutate: (input: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + update: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + upsert: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + count: { + + query: (input?: Prisma.Subset) => Promise<'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number>; + useQuery: + : number, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: + : number, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/User.nuxt.type.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/User.nuxt.type.ts new file mode 100644 index 000000000..f78f3a5ed --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/User.nuxt.type.ts @@ -0,0 +1,380 @@ +/* eslint-disable */ +import type { Prisma } from '@prisma/client'; +import type { TRPCClientErrorLike, TRPCRequestOptions } from '@trpc/client'; +import type { MaybeRefOrGetter, UnwrapRef } from 'vue'; +import type { AsyncData, AsyncDataOptions } from 'nuxt/app'; +import type { KeysOf, PickFrom } from './utils'; +import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; + +export interface ClientType { + aggregate: { + + query: (input: Prisma.Subset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + createMany: { + + mutate: (input?: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input?: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + create: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + deleteMany: { + + mutate: (input?: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input?: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + delete: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + findFirst: { + + query: (input?: Prisma.SelectSubset) => Promise | null>; + useQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findFirstOrThrow: { + + query: (input?: Prisma.SelectSubset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findMany: { + + query: (input?: Prisma.SelectSubset) => Promise>>; + useQuery: >, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: >, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findUnique: { + + query: (input: Prisma.SelectSubset) => Promise | null>; + useQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: | null, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + findUniqueOrThrow: { + + query: (input: Prisma.SelectSubset) => Promise>; + useQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + groupBy: { + + query: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >(input: Prisma.SubsetIntersection & InputErrors) => Promise<{} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors>; + useQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , ResT = {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter & InputErrors>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , ResT = {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input: MaybeRefOrGetter & InputErrors>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; + updateMany: { + + mutate: (input: Prisma.SelectSubset) => Promise; + useMutation: , DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + update: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + upsert: { + + mutate: (input: Prisma.SelectSubset) => Promise>; + useMutation: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(opts?: Omit, 'lazy'> & { + trpc?: TRPCRequestOptions; + }) => AsyncData | DefaultT, DataE> & { + mutate: , DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf>(input: Prisma.SelectSubset) => Promise | null, DataE>['data']>>; + }; + + }; + count: { + + query: (input?: Prisma.Subset) => Promise<'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number>; + useQuery: + : number, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + useLazyQuery: + : number, DataE = TRPCClientErrorLike, DataT = ResT, PickKeys extends KeysOf = KeysOf, DefaultT = null>(input?: MaybeRefOrGetter>, opts?: Omit, 'lazy' | 'watch'> & { + trpc?: TRPCRequestOptions; + queryKey?: string; + watch?: AsyncDataOptions['watch'] | false; + }) => AsyncData | DefaultT, DataE>; + + }; +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/nuxt.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/nuxt.ts new file mode 100644 index 000000000..37d06435b --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/nuxt.ts @@ -0,0 +1,19 @@ +/* eslint-disable */ + +import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; +import { createTRPCNuxtClient as _createTRPCNuxtClient } from 'trpc-nuxt/client'; +import type { DeepOverrideAtPath } from './utils'; +import { ClientType as UserClientType } from "./User.nuxt.type"; +import { ClientType as PostClientType } from "./Post.nuxt.type"; + +export function createTRPCNuxtClient( + opts: Parameters>[0] +) { + const r = _createTRPCNuxtClient(opts); + return r as DeepOverrideAtPath, TPath>; +} + +export interface ClientType { + user: UserClientType; + post: PostClientType; +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/utils.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/utils.ts new file mode 100644 index 000000000..8173ebbc0 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/client/utils.ts @@ -0,0 +1,46 @@ +/* eslint-disable */ + +// inspired by: https://stackoverflow.com/questions/70632026/generic-to-recursively-modify-a-given-type-interface-in-typescript + +type Primitive = string | Function | number | boolean | Symbol | undefined | null; + +/** + * Recursively merges `T` and `R`. If there's a shared key, use `R`'s field type to overwrite `T`. + */ +export type DeepOverride = T extends Primitive + ? R + : R extends Primitive + ? R + : { + [K in keyof T]: K extends keyof R ? DeepOverride : T[K]; + } & { + [K in Exclude]: R[K]; + }; + +/** + * Traverse to `Path` (denoted by dot separated string literal type) in `T`, and starting from there, + * recursively merge with `R`. + */ +export type DeepOverrideAtPath = Path extends undefined + ? DeepOverride + : Path extends `${infer P1}.${infer P2}` + ? P1 extends keyof T + ? Omit & Record>> + : never + : Path extends keyof T + ? Omit & Record> + : never; + +// Utility type from 'trpc-nuxt' +export type KeysOf = Array; + +// Utility type from 'trpc-nuxt' +export type PickFrom> = T extends Array + ? T + : T extends Record + ? keyof T extends K[number] + ? T + : K[number] extends never + ? T + : Pick + : T; diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/helper.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/helper.ts new file mode 100644 index 000000000..7f292fff2 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/helper.ts @@ -0,0 +1,69 @@ +/* eslint-disable */ +import { TRPCError } from '@trpc/server'; +import { isPrismaClientKnownRequestError } from '@zenstackhq/runtime'; + +export async function checkMutate(promise: Promise): Promise { + try { + return await promise; + } catch (err: any) { + if (isPrismaClientKnownRequestError(err)) { + if (err.code === 'P2004') { + if (err.meta?.reason === 'RESULT_NOT_READABLE') { + // unable to readback data + return undefined; + } else { + // rejected by policy + throw new TRPCError({ + code: 'FORBIDDEN', + message: err.message, + cause: err, + }); + } + } else { + // request error + throw new TRPCError({ + code: 'BAD_REQUEST', + message: err.message, + cause: err, + }); + } + } else { + throw err; + } + } + +} + +export async function checkRead(promise: Promise): Promise { + try { + return await promise; + } catch (err: any) { + if (isPrismaClientKnownRequestError(err)) { + if (err.code === 'P2004') { + // rejected by policy + throw new TRPCError({ + code: 'FORBIDDEN', + message: err.message, + cause: err, + }); + } else if (err.code === 'P2025') { + // not found + throw new TRPCError({ + code: 'NOT_FOUND', + message: err.message, + cause: err, + }); + } else { + // request error + throw new TRPCError({ + code: 'BAD_REQUEST', + message: err.message, + cause: err, + }) + } + } else { + throw err; + } + } + +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/routers/Post.router.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/routers/Post.router.ts new file mode 100644 index 000000000..435b12d83 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/routers/Post.router.ts @@ -0,0 +1,44 @@ +/* eslint-disable */ +import { db } from "."; +import { createTRPCRouter } from "../../generated-router-helper"; +import { procedure } from "../../generated-router-helper"; +import * as _Schema from '@zenstackhq/runtime/zod/input'; +const $Schema: typeof _Schema = (_Schema as any).default ?? _Schema; +import { checkRead, checkMutate } from '../helper'; + +export default function createRouter() { + return createTRPCRouter({ + + aggregate: procedure.input($Schema.PostInputSchema.aggregate).query(({ ctx, input }) => checkRead(db(ctx).post.aggregate(input as any))), + + createMany: procedure.input($Schema.PostInputSchema.createMany.optional()).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.createMany(input as any))), + + create: procedure.input($Schema.PostInputSchema.create).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.create(input as any))), + + deleteMany: procedure.input($Schema.PostInputSchema.deleteMany.optional()).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.deleteMany(input as any))), + + delete: procedure.input($Schema.PostInputSchema.delete).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.delete(input as any))), + + findFirst: procedure.input($Schema.PostInputSchema.findFirst.optional()).query(({ ctx, input }) => checkRead(db(ctx).post.findFirst(input as any))), + + findFirstOrThrow: procedure.input($Schema.PostInputSchema.findFirst.optional()).query(({ ctx, input }) => checkRead(db(ctx).post.findFirstOrThrow(input as any))), + + findMany: procedure.input($Schema.PostInputSchema.findMany.optional()).query(({ ctx, input }) => checkRead(db(ctx).post.findMany(input as any))), + + findUnique: procedure.input($Schema.PostInputSchema.findUnique).query(({ ctx, input }) => checkRead(db(ctx).post.findUnique(input as any))), + + findUniqueOrThrow: procedure.input($Schema.PostInputSchema.findUnique).query(({ ctx, input }) => checkRead(db(ctx).post.findUniqueOrThrow(input as any))), + + groupBy: procedure.input($Schema.PostInputSchema.groupBy).query(({ ctx, input }) => checkRead(db(ctx).post.groupBy(input as any))), + + updateMany: procedure.input($Schema.PostInputSchema.updateMany).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.updateMany(input as any))), + + update: procedure.input($Schema.PostInputSchema.update).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.update(input as any))), + + upsert: procedure.input($Schema.PostInputSchema.upsert).mutation(async ({ ctx, input }) => checkMutate(db(ctx).post.upsert(input as any))), + + count: procedure.input($Schema.PostInputSchema.count.optional()).query(({ ctx, input }) => checkRead(db(ctx).post.count(input as any))), + + } + ); +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/routers/User.router.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/routers/User.router.ts new file mode 100644 index 000000000..9cba05d4c --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/routers/User.router.ts @@ -0,0 +1,44 @@ +/* eslint-disable */ +import { db } from "."; +import { createTRPCRouter } from "../../generated-router-helper"; +import { procedure } from "../../generated-router-helper"; +import * as _Schema from '@zenstackhq/runtime/zod/input'; +const $Schema: typeof _Schema = (_Schema as any).default ?? _Schema; +import { checkRead, checkMutate } from '../helper'; + +export default function createRouter() { + return createTRPCRouter({ + + aggregate: procedure.input($Schema.UserInputSchema.aggregate).query(({ ctx, input }) => checkRead(db(ctx).user.aggregate(input as any))), + + createMany: procedure.input($Schema.UserInputSchema.createMany.optional()).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.createMany(input as any))), + + create: procedure.input($Schema.UserInputSchema.create).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.create(input as any))), + + deleteMany: procedure.input($Schema.UserInputSchema.deleteMany.optional()).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.deleteMany(input as any))), + + delete: procedure.input($Schema.UserInputSchema.delete).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.delete(input as any))), + + findFirst: procedure.input($Schema.UserInputSchema.findFirst.optional()).query(({ ctx, input }) => checkRead(db(ctx).user.findFirst(input as any))), + + findFirstOrThrow: procedure.input($Schema.UserInputSchema.findFirst.optional()).query(({ ctx, input }) => checkRead(db(ctx).user.findFirstOrThrow(input as any))), + + findMany: procedure.input($Schema.UserInputSchema.findMany.optional()).query(({ ctx, input }) => checkRead(db(ctx).user.findMany(input as any))), + + findUnique: procedure.input($Schema.UserInputSchema.findUnique).query(({ ctx, input }) => checkRead(db(ctx).user.findUnique(input as any))), + + findUniqueOrThrow: procedure.input($Schema.UserInputSchema.findUnique).query(({ ctx, input }) => checkRead(db(ctx).user.findUniqueOrThrow(input as any))), + + groupBy: procedure.input($Schema.UserInputSchema.groupBy).query(({ ctx, input }) => checkRead(db(ctx).user.groupBy(input as any))), + + updateMany: procedure.input($Schema.UserInputSchema.updateMany).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.updateMany(input as any))), + + update: procedure.input($Schema.UserInputSchema.update).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.update(input as any))), + + upsert: procedure.input($Schema.UserInputSchema.upsert).mutation(async ({ ctx, input }) => checkMutate(db(ctx).user.upsert(input as any))), + + count: procedure.input($Schema.UserInputSchema.count.optional()).query(({ ctx, input }) => checkRead(db(ctx).user.count(input as any))), + + } + ); +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/routers/index.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/routers/index.ts new file mode 100644 index 000000000..949b84f3d --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/routers/index.ts @@ -0,0 +1,21 @@ +/* eslint-disable */ +import type { AnyTRPCRouter as AnyRouter } from "@trpc/server"; +import type { PrismaClient } from "@prisma/client"; +import { createTRPCRouter } from "../../generated-router-helper"; +import createUserRouter from "./User.router"; +import createPostRouter from "./Post.router"; + +export function db(ctx: any) { + if (!ctx.prisma) { + throw new Error('Missing "prisma" field in trpc context'); + } + return ctx.prisma as PrismaClient; +} + +export function createRouter() { + return createTRPCRouter({ + user: createUserRouter(), + post: createPostRouter(), + } + ); +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/index.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/index.ts new file mode 100644 index 000000000..731355810 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/index.ts @@ -0,0 +1,6 @@ +import { createRouter as createCRUDRouter } from './generated/routers'; + +export const appRouter = createCRUDRouter(); + +// export type definition of API +export type AppRouter = typeof appRouter; diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/trpc.ts b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/trpc.ts new file mode 100644 index 000000000..0b93ecda7 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/trpc.ts @@ -0,0 +1,20 @@ +/** + * This is your entry point to setup the root configuration for tRPC on the server. + * - `initTRPC` should only be used once per app. + * - We export only the functionality that we use so we can enforce which base procedures should be used + * + * Learn how to create protected base procedures and other things below: + * @see https://trpc.io/docs/v10/router + * @see https://trpc.io/docs/v10/procedures + */ +import { initTRPC } from '@trpc/server'; +import { Context } from './context'; + +const t = initTRPC.context().create(); + +/** + * Unprotected procedure + **/ +export const publicProcedure = t.procedure; +export const router = t.router; +export const middleware = t.middleware; diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/tsconfig.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/tsconfig.json new file mode 100644 index 000000000..b9ed69c19 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/tsconfig.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/tsconfig.json new file mode 100644 index 000000000..f80f43a36 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/tsconfig.json @@ -0,0 +1,7 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json", + "compilerOptions": { + "verbatimModuleSyntax": false + } +} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/pages/index.tsx b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/pages/index.tsx index 4e575b4c3..e8e910ced 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/pages/index.tsx +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/pages/index.tsx @@ -9,16 +9,30 @@ export default function Home() { { select: (data) => data.map((p) => ({ id: p.id, title: p.name })) } ); + const { mutateAsync: createPost } = api.post.post.create.useMutation(); + + const mutation = async () => { + const created = await createPost({ + data: { name: 'New post', published: true, authorId: 1 }, + include: { author: true }, + }); + console.log(created.author.email); + }; + return ( <>
{hello.data &&

{hello.data.greeting}

} {posts.data?.map((post) => ( -

{post.name}

+

+ {post.name} by {post.author.email} +

))} {postsTransformed.data?.map((post) => (

{post.title}

))} + +
); diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/Post.next.type.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/Post.next.type.ts new file mode 100644 index 000000000..c73627928 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/Post.next.type.ts @@ -0,0 +1,378 @@ +/* eslint-disable */ +import type { Prisma } from '@prisma/client'; +import type { TRPCClientErrorLike, TRPCRequestOptions } from '@trpc/client'; +import type { UseTRPCMutationOptions, UseTRPCMutationResult, UseTRPCQueryOptions, UseTRPCQueryResult, UseTRPCInfiniteQueryOptions, UseTRPCInfiniteQueryResult } from '@trpc/react-query/shared'; +import type { AnyRouter } from '@trpc/server'; + +export interface ClientType { + aggregate: { + + useQuery: >( + input: Prisma.Subset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.GetPostAggregateType, + TRPCClientErrorLike + >; + + }; + createMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostCreateManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables?: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + create: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostCreateArgs, + TRPCClientErrorLike, + Prisma.PostGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> + }; + + }; + deleteMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostDeleteManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables?: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + delete: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostDeleteArgs, + TRPCClientErrorLike, + Prisma.PostGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> + }; + + }; + findFirst: { + + useQuery: | null>( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions | null, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions | null, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.PostGetPayload | null, + TRPCClientErrorLike + >; + + }; + findFirstOrThrow: { + + useQuery: >( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.PostGetPayload, + TRPCClientErrorLike + >; + + }; + findMany: { + + useQuery: >>( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions>, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions>, Error> + ) => UseTRPCInfiniteQueryResult< + Array>, + TRPCClientErrorLike + >; + + }; + findUnique: { + + useQuery: | null>( + input: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions | null, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions | null, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.PostGetPayload | null, + TRPCClientErrorLike + >; + + }; + findUniqueOrThrow: { + + useQuery: >( + input: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.PostGetPayload, + TRPCClientErrorLike + >; + + }; + groupBy: { + + useQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , TData = {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors>( + input: Prisma.SubsetIntersection & InputErrors, + opts?: UseTRPCQueryOptions : InputErrors, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >( + input: Omit & InputErrors, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions : InputErrors, Error> + ) => UseTRPCInfiniteQueryResult< + {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, + TRPCClientErrorLike + >; + + }; + updateMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostUpdateManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + update: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostUpdateArgs, + TRPCClientErrorLike, + Prisma.PostGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> + }; + + }; + upsert: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostUpsertArgs, + TRPCClientErrorLike, + Prisma.PostGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> + }; + + }; + count: { + + useQuery: + : number>( + input?: Prisma.Subset, + opts?: UseTRPCQueryOptions + : number, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions + : number, Error> + ) => UseTRPCInfiniteQueryResult< + 'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number, + TRPCClientErrorLike + >; + + }; +} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/User.next.type.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/User.next.type.ts new file mode 100644 index 000000000..bd0617535 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/User.next.type.ts @@ -0,0 +1,378 @@ +/* eslint-disable */ +import type { Prisma } from '@prisma/client'; +import type { TRPCClientErrorLike, TRPCRequestOptions } from '@trpc/client'; +import type { UseTRPCMutationOptions, UseTRPCMutationResult, UseTRPCQueryOptions, UseTRPCQueryResult, UseTRPCInfiniteQueryOptions, UseTRPCInfiniteQueryResult } from '@trpc/react-query/shared'; +import type { AnyRouter } from '@trpc/server'; + +export interface ClientType { + aggregate: { + + useQuery: >( + input: Prisma.Subset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.GetUserAggregateType, + TRPCClientErrorLike + >; + + }; + createMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserCreateManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables?: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + create: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserCreateArgs, + TRPCClientErrorLike, + Prisma.UserGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> + }; + + }; + deleteMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserDeleteManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables?: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + delete: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserDeleteArgs, + TRPCClientErrorLike, + Prisma.UserGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> + }; + + }; + findFirst: { + + useQuery: | null>( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions | null, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions | null, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.UserGetPayload | null, + TRPCClientErrorLike + >; + + }; + findFirstOrThrow: { + + useQuery: >( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.UserGetPayload, + TRPCClientErrorLike + >; + + }; + findMany: { + + useQuery: >>( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions>, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions>, Error> + ) => UseTRPCInfiniteQueryResult< + Array>, + TRPCClientErrorLike + >; + + }; + findUnique: { + + useQuery: | null>( + input: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions | null, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions | null, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.UserGetPayload | null, + TRPCClientErrorLike + >; + + }; + findUniqueOrThrow: { + + useQuery: >( + input: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.UserGetPayload, + TRPCClientErrorLike + >; + + }; + groupBy: { + + useQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , TData = {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors>( + input: Prisma.SubsetIntersection & InputErrors, + opts?: UseTRPCQueryOptions : InputErrors, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >( + input: Omit & InputErrors, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions : InputErrors, Error> + ) => UseTRPCInfiniteQueryResult< + {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, + TRPCClientErrorLike + >; + + }; + updateMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserUpdateManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + update: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserUpdateArgs, + TRPCClientErrorLike, + Prisma.UserGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> + }; + + }; + upsert: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserUpsertArgs, + TRPCClientErrorLike, + Prisma.UserGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> + }; + + }; + count: { + + useQuery: + : number>( + input?: Prisma.Subset, + opts?: UseTRPCQueryOptions + : number, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions + : number, Error> + ) => UseTRPCInfiniteQueryResult< + 'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number, + TRPCClientErrorLike + >; + + }; +} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/next.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/next.ts index fecac441c..3b2c10686 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/next.ts +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/next.ts @@ -4,7 +4,8 @@ import type { AnyRouter } from '@trpc/server'; import type { NextPageContext } from 'next'; import { type CreateTRPCNext, createTRPCNext as _createTRPCNext } from '@trpc/next'; import type { DeepOverrideAtPath } from './utils'; -import type { ClientType } from '../routers'; +import { ClientType as UserClientType } from "./User.next.type"; +import { ClientType as PostClientType } from "./Post.next.type"; export function createTRPCNext< TRouter extends AnyRouter, @@ -15,3 +16,8 @@ export function createTRPCNext< const r: CreateTRPCNext = _createTRPCNext(opts); return r as DeepOverrideAtPath, ClientType, TPath>; } + +export interface ClientType { + user: UserClientType; + post: PostClientType; +} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/utils.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/utils.ts index 45a0df890..8173ebbc0 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/utils.ts +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/client/utils.ts @@ -30,3 +30,17 @@ export type DeepOverrideAtPath & Record> : never; + +// Utility type from 'trpc-nuxt' +export type KeysOf = Array; + +// Utility type from 'trpc-nuxt' +export type PickFrom> = T extends Array + ? T + : T extends Record + ? keyof T extends K[number] + ? T + : K[number] extends never + ? T + : Pick + : T; diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/Post.router.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/Post.router.ts index 27b10efdf..1733631f2 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/Post.router.ts +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/Post.router.ts @@ -3,10 +3,6 @@ import { type RouterFactory, type ProcBuilder, type BaseConfig, db } from "."; import * as _Schema from '@zenstackhq/runtime/zod/input'; const $Schema: typeof _Schema = (_Schema as any).default ?? _Schema; import { checkRead, checkMutate } from '../helper'; -import type { Prisma } from '@prisma/client'; -import type { UseTRPCMutationOptions, UseTRPCMutationResult, UseTRPCQueryOptions, UseTRPCQueryResult, UseTRPCInfiniteQueryOptions, UseTRPCInfiniteQueryResult } from '@trpc/react-query/shared'; -import type { TRPCClientErrorLike } from '@trpc/client'; -import type { AnyRouter } from '@trpc/server'; export default function createRouter(router: RouterFactory, procedure: ProcBuilder) { return router({ @@ -44,376 +40,3 @@ export default function createRouter(router: RouterFa } ); } - -export interface ClientType { - aggregate: { - - useQuery: >( - input: Prisma.Subset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.GetPostAggregateType, - TRPCClientErrorLike - >; - - }; - createMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostCreateManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - create: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostCreateArgs, - TRPCClientErrorLike, - Prisma.PostGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> - }; - - }; - deleteMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostDeleteManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - delete: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostDeleteArgs, - TRPCClientErrorLike, - Prisma.PostGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> - }; - - }; - findFirst: { - - useQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.PostGetPayload, - TRPCClientErrorLike - >; - - }; - findFirstOrThrow: { - - useQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.PostGetPayload, - TRPCClientErrorLike - >; - - }; - findMany: { - - useQuery: >>( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions>, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions>, Error> - ) => UseTRPCInfiniteQueryResult< - Array>, - TRPCClientErrorLike - >; - - }; - findUnique: { - - useQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.PostGetPayload, - TRPCClientErrorLike - >; - - }; - findUniqueOrThrow: { - - useQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.PostGetPayload, - TRPCClientErrorLike - >; - - }; - groupBy: { - - useQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } - : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - , TData = {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors>( - input: Prisma.SubsetIntersection & InputErrors, - opts?: UseTRPCQueryOptions : InputErrors, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } - : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - >( - input: Omit & InputErrors, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions : InputErrors, Error> - ) => UseTRPCInfiniteQueryResult< - {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, - TRPCClientErrorLike - >; - - }; - updateMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostUpdateManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - update: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostUpdateArgs, - TRPCClientErrorLike, - Prisma.PostGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> - }; - - }; - upsert: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostUpsertArgs, - TRPCClientErrorLike, - Prisma.PostGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> - }; - - }; - count: { - - useQuery: - : number>( - input?: Prisma.Subset, - opts?: UseTRPCQueryOptions - : number, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions - : number, Error> - ) => UseTRPCInfiniteQueryResult< - 'select' extends keyof T - ? T['select'] extends true - ? number - : Prisma.GetScalarType - : number, - TRPCClientErrorLike - >; - - }; -} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/User.router.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/User.router.ts index b3a4178e4..da606d2da 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/User.router.ts +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/User.router.ts @@ -3,10 +3,6 @@ import { type RouterFactory, type ProcBuilder, type BaseConfig, db } from "."; import * as _Schema from '@zenstackhq/runtime/zod/input'; const $Schema: typeof _Schema = (_Schema as any).default ?? _Schema; import { checkRead, checkMutate } from '../helper'; -import type { Prisma } from '@prisma/client'; -import type { UseTRPCMutationOptions, UseTRPCMutationResult, UseTRPCQueryOptions, UseTRPCQueryResult, UseTRPCInfiniteQueryOptions, UseTRPCInfiniteQueryResult } from '@trpc/react-query/shared'; -import type { TRPCClientErrorLike } from '@trpc/client'; -import type { AnyRouter } from '@trpc/server'; export default function createRouter(router: RouterFactory, procedure: ProcBuilder) { return router({ @@ -44,376 +40,3 @@ export default function createRouter(router: RouterFa } ); } - -export interface ClientType { - aggregate: { - - useQuery: >( - input: Prisma.Subset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.GetUserAggregateType, - TRPCClientErrorLike - >; - - }; - createMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserCreateManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - create: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserCreateArgs, - TRPCClientErrorLike, - Prisma.UserGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> - }; - - }; - deleteMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserDeleteManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - delete: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserDeleteArgs, - TRPCClientErrorLike, - Prisma.UserGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> - }; - - }; - findFirst: { - - useQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.UserGetPayload, - TRPCClientErrorLike - >; - - }; - findFirstOrThrow: { - - useQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.UserGetPayload, - TRPCClientErrorLike - >; - - }; - findMany: { - - useQuery: >>( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions>, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions>, Error> - ) => UseTRPCInfiniteQueryResult< - Array>, - TRPCClientErrorLike - >; - - }; - findUnique: { - - useQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.UserGetPayload, - TRPCClientErrorLike - >; - - }; - findUniqueOrThrow: { - - useQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.UserGetPayload, - TRPCClientErrorLike - >; - - }; - groupBy: { - - useQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } - : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - , TData = {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors>( - input: Prisma.SubsetIntersection & InputErrors, - opts?: UseTRPCQueryOptions : InputErrors, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } - : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - >( - input: Omit & InputErrors, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions : InputErrors, Error> - ) => UseTRPCInfiniteQueryResult< - {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, - TRPCClientErrorLike - >; - - }; - updateMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserUpdateManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - update: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserUpdateArgs, - TRPCClientErrorLike, - Prisma.UserGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> - }; - - }; - upsert: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserUpsertArgs, - TRPCClientErrorLike, - Prisma.UserGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> - }; - - }; - count: { - - useQuery: - : number>( - input?: Prisma.Subset, - opts?: UseTRPCQueryOptions - : number, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions - : number, Error> - ) => UseTRPCInfiniteQueryResult< - 'select' extends keyof T - ? T['select'] extends true - ? number - : Prisma.GetScalarType - : number, - TRPCClientErrorLike - >; - - }; -} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/index.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/index.ts index 523f4b645..076308882 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/index.ts +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/generated/routers/index.ts @@ -3,8 +3,6 @@ import type { unsetMarker, AnyRouter, AnyRootConfig, CreateRouterInner, Procedur import type { PrismaClient } from "@prisma/client"; import createUserRouter from "./User.router"; import createPostRouter from "./Post.router"; -import { ClientType as UserClientType } from "./User.router"; -import { ClientType as PostClientType } from "./Post.router"; export type BaseConfig = AnyRootConfig; @@ -34,8 +32,3 @@ export function createRouter(router: RouterFactory { - user: UserClientType; - post: PostClientType; -} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/app/_components/post.tsx b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/app/_components/post.tsx index 6acb6600c..8455c4a53 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/app/_components/post.tsx +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/app/_components/post.tsx @@ -21,7 +21,7 @@ export function LatestPost() { }, { staleTime: 1000 * 60 } ); - console.log(latestPost1.author.email); + console.log(latestPost1?.author.email); api.post.findMany.useInfiniteQuery( { diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/Post.react.type.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/Post.react.type.ts new file mode 100644 index 000000000..82b8da078 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/Post.react.type.ts @@ -0,0 +1,579 @@ +/* eslint-disable */ +import type { Prisma } from '@prisma/client'; +import type { TRPCClientErrorLike, TRPCRequestOptions } from '@trpc/client'; +import type { UseTRPCMutationOptions, UseTRPCMutationResult, UseTRPCQueryOptions, UseTRPCQueryResult, UseTRPCInfiniteQueryOptions, UseTRPCInfiniteQueryResult } from '@trpc/react-query/shared'; +import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; +import type { UseTRPCSuspenseQueryOptions, UseTRPCSuspenseQueryResult, UseTRPCSuspenseInfiniteQueryOptions, UseTRPCSuspenseInfiniteQueryResult } from '@trpc/react-query/shared'; + +export interface ClientType { + aggregate: { + + useQuery: >( + input: Prisma.Subset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.GetPostAggregateType, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: >( + input: Prisma.Subset, + opts?: UseTRPCSuspenseQueryOptions, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> + ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; + + }; + createMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostCreateManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables?: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + create: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostCreateArgs, + TRPCClientErrorLike, + Prisma.PostGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> + }; + + }; + deleteMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostDeleteManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables?: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + delete: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostDeleteArgs, + TRPCClientErrorLike, + Prisma.PostGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> + }; + + }; + findFirst: { + + useQuery: | null>( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions | null, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions | null, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.PostGetPayload | null, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: | null>( + input?: Prisma.SelectSubset, + opts?: UseTRPCSuspenseQueryOptions | null, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions | null, Error> + ) => UseTRPCSuspenseInfiniteQueryResult | null, TRPCClientErrorLike, T>; + + }; + findFirstOrThrow: { + + useQuery: >( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.PostGetPayload, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: >( + input?: Prisma.SelectSubset, + opts?: UseTRPCSuspenseQueryOptions, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> + ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; + + }; + findMany: { + + useQuery: >>( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions>, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions>, Error> + ) => UseTRPCInfiniteQueryResult< + Array>, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: >>( + input?: Prisma.SelectSubset, + opts?: UseTRPCSuspenseQueryOptions>, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions>, Error> + ) => UseTRPCSuspenseInfiniteQueryResult>, TRPCClientErrorLike, T>; + + }; + findUnique: { + + useQuery: | null>( + input: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions | null, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions | null, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.PostGetPayload | null, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: | null>( + input: Prisma.SelectSubset, + opts?: UseTRPCSuspenseQueryOptions | null, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions | null, Error> + ) => UseTRPCSuspenseInfiniteQueryResult | null, TRPCClientErrorLike, T>; + + }; + findUniqueOrThrow: { + + useQuery: >( + input: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.PostGetPayload, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: >( + input: Prisma.SelectSubset, + opts?: UseTRPCSuspenseQueryOptions, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> + ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; + + }; + groupBy: { + + useQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , TData = {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors>( + input: Prisma.SubsetIntersection & InputErrors, + opts?: UseTRPCQueryOptions<{} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >( + input: Omit & InputErrors, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions : InputErrors, Error> + ) => UseTRPCInfiniteQueryResult< + {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , TData = {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors>( + input: Prisma.SubsetIntersection & InputErrors, + opts?: UseTRPCSuspenseQueryOptions<{} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } + : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >( + input: Omit & InputErrors, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions : InputErrors, Error> + ) => UseTRPCSuspenseInfiniteQueryResult<{} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, TRPCClientErrorLike, T>; + + }; + updateMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostUpdateManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + update: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostUpdateArgs, + TRPCClientErrorLike, + Prisma.PostGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> + }; + + }; + upsert: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.PostUpsertArgs, + TRPCClientErrorLike, + Prisma.PostGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> + }; + + }; + count: { + + useQuery: + : number>( + input?: Prisma.Subset, + opts?: UseTRPCQueryOptions<'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions + : number, Error> + ) => UseTRPCInfiniteQueryResult< + 'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: + : number>( + input?: Prisma.Subset, + opts?: UseTRPCSuspenseQueryOptions<'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions + : number, Error> + ) => UseTRPCSuspenseInfiniteQueryResult<'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number, TRPCClientErrorLike, T>; + + }; +} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/User.react.type.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/User.react.type.ts new file mode 100644 index 000000000..e04628191 --- /dev/null +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/User.react.type.ts @@ -0,0 +1,579 @@ +/* eslint-disable */ +import type { Prisma } from '@prisma/client'; +import type { TRPCClientErrorLike, TRPCRequestOptions } from '@trpc/client'; +import type { UseTRPCMutationOptions, UseTRPCMutationResult, UseTRPCQueryOptions, UseTRPCQueryResult, UseTRPCInfiniteQueryOptions, UseTRPCInfiniteQueryResult } from '@trpc/react-query/shared'; +import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; +import type { UseTRPCSuspenseQueryOptions, UseTRPCSuspenseQueryResult, UseTRPCSuspenseInfiniteQueryOptions, UseTRPCSuspenseInfiniteQueryResult } from '@trpc/react-query/shared'; + +export interface ClientType { + aggregate: { + + useQuery: >( + input: Prisma.Subset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.GetUserAggregateType, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: >( + input: Prisma.Subset, + opts?: UseTRPCSuspenseQueryOptions, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> + ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; + + }; + createMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserCreateManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables?: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + create: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserCreateArgs, + TRPCClientErrorLike, + Prisma.UserGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> + }; + + }; + deleteMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserDeleteManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables?: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + delete: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserDeleteArgs, + TRPCClientErrorLike, + Prisma.UserGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> + }; + + }; + findFirst: { + + useQuery: | null>( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions | null, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions | null, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.UserGetPayload | null, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: | null>( + input?: Prisma.SelectSubset, + opts?: UseTRPCSuspenseQueryOptions | null, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions | null, Error> + ) => UseTRPCSuspenseInfiniteQueryResult | null, TRPCClientErrorLike, T>; + + }; + findFirstOrThrow: { + + useQuery: >( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.UserGetPayload, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: >( + input?: Prisma.SelectSubset, + opts?: UseTRPCSuspenseQueryOptions, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> + ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; + + }; + findMany: { + + useQuery: >>( + input?: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions>, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions>, Error> + ) => UseTRPCInfiniteQueryResult< + Array>, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: >>( + input?: Prisma.SelectSubset, + opts?: UseTRPCSuspenseQueryOptions>, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions>, Error> + ) => UseTRPCSuspenseInfiniteQueryResult>, TRPCClientErrorLike, T>; + + }; + findUnique: { + + useQuery: | null>( + input: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions | null, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions | null, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.UserGetPayload | null, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: | null>( + input: Prisma.SelectSubset, + opts?: UseTRPCSuspenseQueryOptions | null, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions | null, Error> + ) => UseTRPCSuspenseInfiniteQueryResult | null, TRPCClientErrorLike, T>; + + }; + findUniqueOrThrow: { + + useQuery: >( + input: Prisma.SelectSubset, + opts?: UseTRPCQueryOptions, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions, Error> + ) => UseTRPCInfiniteQueryResult< + Prisma.UserGetPayload, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: >( + input: Prisma.SelectSubset, + opts?: UseTRPCSuspenseQueryOptions, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> + ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; + + }; + groupBy: { + + useQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , TData = {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors>( + input: Prisma.SubsetIntersection & InputErrors, + opts?: UseTRPCQueryOptions<{} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >( + input: Omit & InputErrors, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions : InputErrors, Error> + ) => UseTRPCInfiniteQueryResult< + {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + , TData = {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors>( + input: Prisma.SubsetIntersection & InputErrors, + opts?: UseTRPCSuspenseQueryOptions<{} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: >, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } + : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >( + input: Omit & InputErrors, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions : InputErrors, Error> + ) => UseTRPCSuspenseInfiniteQueryResult<{} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, TRPCClientErrorLike, T>; + + }; + updateMany: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserUpdateManyArgs, + TRPCClientErrorLike, + Prisma.BatchPayload, + Context + >) => + Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise + }; + + }; + update: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserUpdateArgs, + TRPCClientErrorLike, + Prisma.UserGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> + }; + + }; + upsert: { + + useMutation: (opts?: UseTRPCMutationOptions< + Prisma.UserUpsertArgs, + TRPCClientErrorLike, + Prisma.UserGetPayload, + Context + >) => + Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { + mutateAsync: + (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> + }; + + }; + count: { + + useQuery: + : number>( + input?: Prisma.Subset, + opts?: UseTRPCQueryOptions<'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number, TData, Error> + ) => UseTRPCQueryResult< + TData, + TRPCClientErrorLike + >; + useInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCInfiniteQueryOptions + : number, Error> + ) => UseTRPCInfiniteQueryResult< + 'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number, + TRPCClientErrorLike, + T + >; + useSuspenseQuery: + : number>( + input?: Prisma.Subset, + opts?: UseTRPCSuspenseQueryOptions<'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number, TData, Error> + ) => UseTRPCSuspenseQueryResult>; + useSuspenseInfiniteQuery: ( + input?: Omit, 'cursor'>, + opts?: UseTRPCSuspenseInfiniteQueryOptions + : number, Error> + ) => UseTRPCSuspenseInfiniteQueryResult<'select' extends keyof T + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number, TRPCClientErrorLike, T>; + + }; +} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/react.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/react.ts index be69328fe..b3b2b2009 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/react.ts +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/react.ts @@ -4,7 +4,8 @@ import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; import type { CreateTRPCReactOptions } from '@trpc/react-query/shared'; import { type CreateTRPCReact, createTRPCReact as _createTRPCReact } from '@trpc/react-query'; import type { DeepOverrideAtPath } from './utils'; -import type { ClientType } from '../routers'; +import { ClientType as UserClientType } from "./User.react.type"; +import { ClientType as PostClientType } from "./Post.react.type"; export function createTRPCReact< TRouter extends AnyRouter, @@ -14,3 +15,8 @@ export function createTRPCReact< const r: CreateTRPCReact = _createTRPCReact(opts); return r as DeepOverrideAtPath, ClientType, TPath>; } + +export interface ClientType { + user: UserClientType; + post: PostClientType; +} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/utils.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/utils.ts index 45a0df890..8173ebbc0 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/utils.ts +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/client/utils.ts @@ -30,3 +30,17 @@ export type DeepOverrideAtPath & Record> : never; + +// Utility type from 'trpc-nuxt' +export type KeysOf = Array; + +// Utility type from 'trpc-nuxt' +export type PickFrom> = T extends Array + ? T + : T extends Record + ? keyof T extends K[number] + ? T + : K[number] extends never + ? T + : Pick + : T; diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/Post.router.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/Post.router.ts index 15c2f4bf0..435b12d83 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/Post.router.ts +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/Post.router.ts @@ -5,11 +5,6 @@ import { procedure } from "../../generated-router-helper"; import * as _Schema from '@zenstackhq/runtime/zod/input'; const $Schema: typeof _Schema = (_Schema as any).default ?? _Schema; import { checkRead, checkMutate } from '../helper'; -import type { Prisma } from '@prisma/client'; -import type { UseTRPCMutationOptions, UseTRPCMutationResult, UseTRPCQueryOptions, UseTRPCQueryResult, UseTRPCInfiniteQueryOptions, UseTRPCInfiniteQueryResult } from '@trpc/react-query/shared'; -import type { TRPCClientErrorLike } from '@trpc/client'; -import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; -import type { UseTRPCSuspenseQueryOptions, UseTRPCSuspenseQueryResult, UseTRPCSuspenseInfiniteQueryOptions, UseTRPCSuspenseInfiniteQueryResult } from '@trpc/react-query/shared'; export default function createRouter() { return createTRPCRouter({ @@ -47,576 +42,3 @@ export default function createRouter() { } ); } - -export interface ClientType { - aggregate: { - - useQuery: >( - input: Prisma.Subset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.GetPostAggregateType, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >( - input: Prisma.Subset, - opts?: UseTRPCSuspenseQueryOptions, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> - ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; - - }; - createMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostCreateManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - create: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostCreateArgs, - TRPCClientErrorLike, - Prisma.PostGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> - }; - - }; - deleteMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostDeleteManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - delete: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostDeleteArgs, - TRPCClientErrorLike, - Prisma.PostGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> - }; - - }; - findFirst: { - - useQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.PostGetPayload, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCSuspenseQueryOptions, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> - ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; - - }; - findFirstOrThrow: { - - useQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.PostGetPayload, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCSuspenseQueryOptions, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> - ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; - - }; - findMany: { - - useQuery: >>( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions>, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions>, Error> - ) => UseTRPCInfiniteQueryResult< - Array>, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >>( - input?: Prisma.SelectSubset, - opts?: UseTRPCSuspenseQueryOptions>, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions>, Error> - ) => UseTRPCSuspenseInfiniteQueryResult>, TRPCClientErrorLike, T>; - - }; - findUnique: { - - useQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.PostGetPayload, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCSuspenseQueryOptions, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> - ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; - - }; - findUniqueOrThrow: { - - useQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.PostGetPayload, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCSuspenseQueryOptions, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> - ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; - - }; - groupBy: { - - useQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } - : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - , TData = {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors>( - input: Prisma.SubsetIntersection & InputErrors, - opts?: UseTRPCQueryOptions<{} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } - : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - >( - input: Omit & InputErrors, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions : InputErrors, Error> - ) => UseTRPCInfiniteQueryResult< - {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } - : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - , TData = {} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors>( - input: Prisma.SubsetIntersection & InputErrors, - opts?: UseTRPCSuspenseQueryOptions<{} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.PostGroupByArgs['orderBy'] } - : { orderBy?: Prisma.PostGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - >( - input: Omit & InputErrors, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions : InputErrors, Error> - ) => UseTRPCSuspenseInfiniteQueryResult<{} extends InputErrors ? Prisma.GetPostGroupByPayload : InputErrors, TRPCClientErrorLike, T>; - - }; - updateMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostUpdateManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - update: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostUpdateArgs, - TRPCClientErrorLike, - Prisma.PostGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> - }; - - }; - upsert: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.PostUpsertArgs, - TRPCClientErrorLike, - Prisma.PostGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.PostGetPayload, Context>) => Promise> - }; - - }; - count: { - - useQuery: - : number>( - input?: Prisma.Subset, - opts?: UseTRPCQueryOptions<'select' extends keyof T - ? T['select'] extends true - ? number - : Prisma.GetScalarType - : number, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions - : number, Error> - ) => UseTRPCInfiniteQueryResult< - 'select' extends keyof T - ? T['select'] extends true - ? number - : Prisma.GetScalarType - : number, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: - : number>( - input?: Prisma.Subset, - opts?: UseTRPCSuspenseQueryOptions<'select' extends keyof T - ? T['select'] extends true - ? number - : Prisma.GetScalarType - : number, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions - : number, Error> - ) => UseTRPCSuspenseInfiniteQueryResult<'select' extends keyof T - ? T['select'] extends true - ? number - : Prisma.GetScalarType - : number, TRPCClientErrorLike, T>; - - }; -} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/User.router.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/User.router.ts index efcad4c16..9cba05d4c 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/User.router.ts +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/User.router.ts @@ -5,11 +5,6 @@ import { procedure } from "../../generated-router-helper"; import * as _Schema from '@zenstackhq/runtime/zod/input'; const $Schema: typeof _Schema = (_Schema as any).default ?? _Schema; import { checkRead, checkMutate } from '../helper'; -import type { Prisma } from '@prisma/client'; -import type { UseTRPCMutationOptions, UseTRPCMutationResult, UseTRPCQueryOptions, UseTRPCQueryResult, UseTRPCInfiniteQueryOptions, UseTRPCInfiniteQueryResult } from '@trpc/react-query/shared'; -import type { TRPCClientErrorLike } from '@trpc/client'; -import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; -import type { UseTRPCSuspenseQueryOptions, UseTRPCSuspenseQueryResult, UseTRPCSuspenseInfiniteQueryOptions, UseTRPCSuspenseInfiniteQueryResult } from '@trpc/react-query/shared'; export default function createRouter() { return createTRPCRouter({ @@ -47,576 +42,3 @@ export default function createRouter() { } ); } - -export interface ClientType { - aggregate: { - - useQuery: >( - input: Prisma.Subset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.GetUserAggregateType, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >( - input: Prisma.Subset, - opts?: UseTRPCSuspenseQueryOptions, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> - ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; - - }; - createMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserCreateManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - create: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserCreateArgs, - TRPCClientErrorLike, - Prisma.UserGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> - }; - - }; - deleteMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserDeleteManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - delete: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserDeleteArgs, - TRPCClientErrorLike, - Prisma.UserGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> - }; - - }; - findFirst: { - - useQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.UserGetPayload, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCSuspenseQueryOptions, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> - ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; - - }; - findFirstOrThrow: { - - useQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.UserGetPayload, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >( - input?: Prisma.SelectSubset, - opts?: UseTRPCSuspenseQueryOptions, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> - ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; - - }; - findMany: { - - useQuery: >>( - input?: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions>, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions>, Error> - ) => UseTRPCInfiniteQueryResult< - Array>, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >>( - input?: Prisma.SelectSubset, - opts?: UseTRPCSuspenseQueryOptions>, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions>, Error> - ) => UseTRPCSuspenseInfiniteQueryResult>, TRPCClientErrorLike, T>; - - }; - findUnique: { - - useQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.UserGetPayload, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCSuspenseQueryOptions, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> - ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; - - }; - findUniqueOrThrow: { - - useQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCQueryOptions, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions, Error> - ) => UseTRPCInfiniteQueryResult< - Prisma.UserGetPayload, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >( - input: Prisma.SelectSubset, - opts?: UseTRPCSuspenseQueryOptions, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions, Error> - ) => UseTRPCSuspenseInfiniteQueryResult, TRPCClientErrorLike, T>; - - }; - groupBy: { - - useQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } - : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - , TData = {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors>( - input: Prisma.SubsetIntersection & InputErrors, - opts?: UseTRPCQueryOptions<{} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } - : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - >( - input: Omit & InputErrors, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions : InputErrors, Error> - ) => UseTRPCInfiniteQueryResult< - {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } - : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - , TData = {} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors>( - input: Prisma.SubsetIntersection & InputErrors, - opts?: UseTRPCSuspenseQueryOptions<{} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: >, - Prisma.Extends<'take', Prisma.Keys> - >, - OrderByArg extends Prisma.True extends HasSelectOrTake - ? { orderBy: Prisma.UserGroupByArgs['orderBy'] } - : { orderBy?: Prisma.UserGroupByArgs['orderBy'] }, - OrderFields extends Prisma.ExcludeUnderscoreKeys>>, - ByFields extends Prisma.MaybeTupleToUnion, - ByValid extends Prisma.Has, - HavingFields extends Prisma.GetHavingFields, - HavingValid extends Prisma.Has, - ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, - InputErrors extends ByEmpty extends Prisma.True - ? `Error: "by" must not be empty.` - : HavingValid extends Prisma.False - ? { - [P in HavingFields]: P extends ByFields - ? never - : P extends string - ? `Error: Field "${P}" used in "having" needs to be provided in "by".` - : [ - Error, - 'Field ', - P, - ` in "having" needs to be provided in "by"`, - ] - }[HavingFields] - : 'take' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "take", you also need to provide "orderBy"' - : 'skip' extends Prisma.Keys - ? 'orderBy' extends Prisma.Keys - ? ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - : 'Error: If you provide "skip", you also need to provide "orderBy"' - : ByValid extends Prisma.True - ? {} - : { - [P in OrderFields]: P extends ByFields - ? never - : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` - }[OrderFields] - >( - input: Omit & InputErrors, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions : InputErrors, Error> - ) => UseTRPCSuspenseInfiniteQueryResult<{} extends InputErrors ? Prisma.GetUserGroupByPayload : InputErrors, TRPCClientErrorLike, T>; - - }; - updateMany: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserUpdateManyArgs, - TRPCClientErrorLike, - Prisma.BatchPayload, - Context - >,) => - Omit, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.BatchPayload, Context>) => Promise - }; - - }; - update: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserUpdateArgs, - TRPCClientErrorLike, - Prisma.UserGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> - }; - - }; - upsert: { - - useMutation: (opts?: UseTRPCMutationOptions< - Prisma.UserUpsertArgs, - TRPCClientErrorLike, - Prisma.UserGetPayload, - Context - >,) => - Omit, TRPCClientErrorLike, Prisma.SelectSubset, Context>, 'mutateAsync'> & { - mutateAsync: - (variables: T, opts?: UseTRPCMutationOptions, Prisma.UserGetPayload, Context>) => Promise> - }; - - }; - count: { - - useQuery: - : number>( - input?: Prisma.Subset, - opts?: UseTRPCQueryOptions<'select' extends keyof T - ? T['select'] extends true - ? number - : Prisma.GetScalarType - : number, TData, Error> - ) => UseTRPCQueryResult< - TData, - TRPCClientErrorLike - >; - useInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCInfiniteQueryOptions - : number, Error> - ) => UseTRPCInfiniteQueryResult< - 'select' extends keyof T - ? T['select'] extends true - ? number - : Prisma.GetScalarType - : number, - TRPCClientErrorLike, - T - >; - useSuspenseQuery: - : number>( - input?: Prisma.Subset, - opts?: UseTRPCSuspenseQueryOptions<'select' extends keyof T - ? T['select'] extends true - ? number - : Prisma.GetScalarType - : number, TData, Error> - ) => UseTRPCSuspenseQueryResult>; - useSuspenseInfiniteQuery: ( - input?: Omit, 'cursor'>, - opts?: UseTRPCSuspenseInfiniteQueryOptions - : number, Error> - ) => UseTRPCSuspenseInfiniteQueryResult<'select' extends keyof T - ? T['select'] extends true - ? number - : Prisma.GetScalarType - : number, TRPCClientErrorLike, T>; - - }; -} diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/index.ts b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/index.ts index f44daeffc..949b84f3d 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/index.ts +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/index.ts @@ -4,8 +4,6 @@ import type { PrismaClient } from "@prisma/client"; import { createTRPCRouter } from "../../generated-router-helper"; import createUserRouter from "./User.router"; import createPostRouter from "./Post.router"; -import { ClientType as UserClientType } from "./User.router"; -import { ClientType as PostClientType } from "./Post.router"; export function db(ctx: any) { if (!ctx.prisma) { @@ -21,8 +19,3 @@ export function createRouter() { } ); } - -export interface ClientType { - user: UserClientType; - post: PostClientType; -} diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 51540d2fe..a82ef0f54 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/runtime", "displayName": "ZenStack Runtime Library", - "version": "2.6.2", + "version": "2.7.0", "description": "Runtime of ZenStack for both client-side and server-side environments.", "repository": { "type": "git", @@ -111,7 +111,7 @@ "zod-validation-error": "^1.5.0" }, "peerDependencies": { - "@prisma/client": "5.0.0 - 5.20.x" + "@prisma/client": "5.0.0 - 5.21.x" }, "author": { "name": "ZenStack Team" diff --git a/packages/runtime/src/cross/mutator.ts b/packages/runtime/src/cross/mutator.ts index 874689c2d..e38570399 100644 --- a/packages/runtime/src/cross/mutator.ts +++ b/packages/runtime/src/cross/mutator.ts @@ -75,6 +75,31 @@ export async function applyMutation( } }, + upsert: (model, args) => { + if (model === queryModel && args?.where && args?.create && args?.update) { + // first see if a matching update can be applied + const updateResult = updateMutate( + queryModel, + resultData, + model, + { where: args.where, data: args.update }, + modelMeta, + logging + ); + if (updateResult) { + resultData = updateResult; + updated = true; + } else { + // if not, try to apply a create + const createResult = createMutate(queryModel, queryOp, resultData, args.create, modelMeta, logging); + if (createResult) { + resultData = createResult; + updated = true; + } + } + } + }, + delete: (model, args) => { if (model === queryModel) { const r = deleteMutate(queryModel, resultData, model, args, modelMeta, logging); diff --git a/packages/runtime/src/enhancements/node/delegate.ts b/packages/runtime/src/enhancements/node/delegate.ts index 5a9ff162c..8a7d613a1 100644 --- a/packages/runtime/src/enhancements/node/delegate.ts +++ b/packages/runtime/src/enhancements/node/delegate.ts @@ -365,12 +365,14 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler { if (this.options.processIncludeRelationPayload) { // use the callback in options to process the include payload, so enhancements // like 'policy' can do extra work (e.g., inject policy rules) + + // TODO: this causes both delegate base's policy rules and concrete model's rules to be injected, + // which is not wrong but redundant + await this.options.processIncludeRelationPayload(this.prisma, model, result, this.options, this.context); - // the callback may directly reference fields from polymorphic bases, we need to fix it - // into a proper hierarchy by moving base field references to the base layer relations - const properHierarchy = await this.buildSelectIncludeHierarchy(model, result, false); - result = { ...result, ...properHierarchy }; + const properSelectIncludeHierarchy = await this.buildSelectIncludeHierarchy(model, result, false); + result = { ...result, ...properSelectIncludeHierarchy }; } return result; diff --git a/packages/schema/package.json b/packages/schema/package.json index d950484b1..06f8fb652 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack Language Tools", "description": "FullStack enhancement for Prisma ORM: seamless integration from database to UI", - "version": "2.6.2", + "version": "2.7.0", "author": { "name": "ZenStack Team" }, @@ -123,10 +123,10 @@ "zod-validation-error": "^1.5.0" }, "peerDependencies": { - "prisma": "5.0.0 - 5.20.x" + "prisma": "5.0.0 - 5.21.x" }, "devDependencies": { - "@prisma/client": "5.20.x", + "@prisma/client": "5.21.x", "@types/async-exit-hook": "^2.0.0", "@types/pluralize": "^0.0.29", "@types/semver": "^7.3.13", diff --git a/packages/schema/src/language-server/validator/attribute-application-validator.ts b/packages/schema/src/language-server/validator/attribute-application-validator.ts index 0de3a5854..9ec2074be 100644 --- a/packages/schema/src/language-server/validator/attribute-application-validator.ts +++ b/packages/schema/src/language-server/validator/attribute-application-validator.ts @@ -15,7 +15,13 @@ import { isEnum, isReferenceExpr, } from '@zenstackhq/language/ast'; -import { isDataModelFieldReference, isFutureExpr, isRelationshipField, resolved } from '@zenstackhq/sdk'; +import { + isDataModelFieldReference, + isDelegateModel, + isFutureExpr, + isRelationshipField, + resolved, +} from '@zenstackhq/sdk'; import { ValidationAcceptor, streamAst } from 'langium'; import pluralize from 'pluralize'; import { AstValidator } from '../types'; @@ -164,6 +170,31 @@ export default class AttributeApplicationValidator implements AstValidator { + if (!isReferenceExpr(item)) { + accept('error', `Expecting a field reference`, { node: item }); + return; + } + if (!isDataModelField(item.target.ref)) { + accept('error', `Expecting a field reference`, { node: item }); + return; + } + + if (item.target.ref.$container !== attr.$container && isDelegateModel(item.target.ref.$container)) { + accept('error', `Cannot use fields inherited from a polymorphic base model in \`@@unique\``, { + node: item, + }); + } + }); + } else { + accept('error', `Expected an array of field references`, { node: fields }); + } + } + private validatePolicyKinds( kind: string, candidates: string[], diff --git a/packages/schema/src/language-server/validator/expression-validator.ts b/packages/schema/src/language-server/validator/expression-validator.ts index e6eb18c29..d5a11c7b7 100644 --- a/packages/schema/src/language-server/validator/expression-validator.ts +++ b/packages/schema/src/language-server/validator/expression-validator.ts @@ -24,7 +24,7 @@ import { import { ValidationAcceptor, streamAst } from 'langium'; import { findUpAst, getContainingDataModel } from '../../utils/ast-utils'; import { AstValidator } from '../types'; -import { typeAssignable } from './utils'; +import { isAuthOrAuthMemberAccess, typeAssignable } from './utils'; /** * Validates expressions. @@ -296,13 +296,9 @@ export default class ExpressionValidator implements AstValidator { // null isNullExpr(expr) || // `auth()` access - this.isAuthOrAuthMemberAccess(expr) || + isAuthOrAuthMemberAccess(expr) || // array (isArrayExpr(expr) && expr.items.every((item) => this.isNotModelFieldExpr(item))) ); } - - private isAuthOrAuthMemberAccess(expr: Expression) { - return isAuthInvocation(expr) || (isMemberAccessExpr(expr) && isAuthInvocation(expr.operand)); - } } diff --git a/packages/schema/src/language-server/validator/function-invocation-validator.ts b/packages/schema/src/language-server/validator/function-invocation-validator.ts index 79b2b1a6b..f37886c93 100644 --- a/packages/schema/src/language-server/validator/function-invocation-validator.ts +++ b/packages/schema/src/language-server/validator/function-invocation-validator.ts @@ -26,7 +26,7 @@ import { AstNode, streamAst, ValidationAcceptor } from 'langium'; import { match, P } from 'ts-pattern'; import { isCheckInvocation } from '../../utils/ast-utils'; import { AstValidator } from '../types'; -import { typeAssignable } from './utils'; +import { isAuthOrAuthMemberAccess, typeAssignable } from './utils'; // a registry of function handlers marked with @func const invocationCheckers = new Map(); @@ -109,15 +109,24 @@ export default class FunctionInvocationValidator implements AstValidator isLiteralExpr(item) || isEnumFieldReference(item)) + secondArg.items.every( + (item) => + isLiteralExpr(item) || isEnumFieldReference(item) || isAuthOrAuthMemberAccess(item) + ) ) ) { - accept('error', 'second argument must be a literal, an enum, or an array of them', { - node: secondArg, - }); + accept( + 'error', + 'second argument must be a literal, an enum, an expression starting with `auth().`, or an array of them', + { + node: secondArg, + } + ); } } } diff --git a/packages/schema/src/language-server/validator/utils.ts b/packages/schema/src/language-server/validator/utils.ts index 6a1a44336..3dd5b537b 100644 --- a/packages/schema/src/language-server/validator/utils.ts +++ b/packages/schema/src/language-server/validator/utils.ts @@ -10,10 +10,11 @@ import { isArrayExpr, isDataModelField, isEnum, + isMemberAccessExpr, isReferenceExpr, isStringLiteral, } from '@zenstackhq/language/ast'; -import { resolved } from '@zenstackhq/sdk'; +import { isAuthInvocation, resolved } from '@zenstackhq/sdk'; import { AstNode, ValidationAcceptor } from 'langium'; /** @@ -181,3 +182,7 @@ export function assignableToAttributeParam( return (dstRef?.ref === argResolvedType.decl || dstType === 'Any') && dstIsArray === argResolvedType.array; } } + +export function isAuthOrAuthMemberAccess(expr: Expression): boolean { + return isAuthInvocation(expr) || (isMemberAccessExpr(expr) && isAuthOrAuthMemberAccess(expr.operand)); +} diff --git a/packages/schema/src/plugins/enhancer/enhance/index.ts b/packages/schema/src/plugins/enhancer/enhance/index.ts index 8d411eb19..ff2e00b6a 100644 --- a/packages/schema/src/plugins/enhancer/enhance/index.ts +++ b/packages/schema/src/plugins/enhancer/enhance/index.ts @@ -8,6 +8,7 @@ import { getLiteral, isDelegateModel, isDiscriminatorField, + normalizedRelative, type PluginOptions, } from '@zenstackhq/sdk'; import { @@ -159,7 +160,7 @@ ${ const zodAbsPath = path.isAbsolute(zodCustomOutput) ? zodCustomOutput : path.resolve(schemaDir, zodCustomOutput); - return path.relative(this.outDir, zodAbsPath) || '.'; + return normalizedRelative(this.outDir, zodAbsPath); } private createSimplePrismaImports(prismaImport: string) { @@ -465,7 +466,9 @@ export function enhance(prisma: any, context?: EnhancementContext<${authTypePara if (delegateInfo.some(([delegate]) => `${delegate.name}Delegate` === iface.getName())) { // delegate models cannot be created directly, remove create/createMany/upsert - structure.methods = structure.methods?.filter((m) => !['create', 'createMany', 'upsert'].includes(m.name)); + structure.methods = structure.methods?.filter( + (m) => !['create', 'createMany', 'createManyAndReturn', 'upsert'].includes(m.name) + ); } return structure; diff --git a/packages/schema/src/plugins/enhancer/index.ts b/packages/schema/src/plugins/enhancer/index.ts index 8d05c50f4..c0cd7e13d 100644 --- a/packages/schema/src/plugins/enhancer/index.ts +++ b/packages/schema/src/plugins/enhancer/index.ts @@ -1,4 +1,11 @@ -import { PluginError, RUNTIME_PACKAGE, createProject, resolvePath, type PluginFunction } from '@zenstackhq/sdk'; +import { + PluginError, + RUNTIME_PACKAGE, + createProject, + normalizedRelative, + resolvePath, + type PluginFunction, +} from '@zenstackhq/sdk'; import path from 'path'; import { getDefaultOutputFolder } from '../plugin-utils'; import { EnhancerGenerator } from './enhance'; @@ -31,7 +38,7 @@ const run: PluginFunction = async (model, options, _dmmf, globalOptions) => { const prismaClientPathAbs = path.resolve(outDir, 'models'); // resolve it relative to the schema path - prismaClientPath = path.relative(path.dirname(options.schemaPath), prismaClientPathAbs); + prismaClientPath = normalizedRelative(path.dirname(options.schemaPath), prismaClientPathAbs); } else { prismaClientPath = `${RUNTIME_PACKAGE}/models`; } diff --git a/packages/schema/src/plugins/prisma/index.ts b/packages/schema/src/plugins/prisma/index.ts index d3a9c120a..7fa94cd92 100644 --- a/packages/schema/src/plugins/prisma/index.ts +++ b/packages/schema/src/plugins/prisma/index.ts @@ -1,4 +1,11 @@ -import { PluginError, type PluginFunction, type PluginOptions, getLiteral, resolvePath } from '@zenstackhq/sdk'; +import { + PluginError, + type PluginFunction, + type PluginOptions, + getLiteral, + normalizedRelative, + resolvePath, +} from '@zenstackhq/sdk'; import { GeneratorDecl, isGeneratorDecl } from '@zenstackhq/sdk/ast'; import { getDMMF } from '@zenstackhq/sdk/prisma'; import colors from 'colors'; @@ -59,7 +66,7 @@ const run: PluginFunction = async (model, options, _dmmf, _globalOptions) => { const absPath = path.resolve(path.dirname(output), clientOutput); // then make it relative to the zmodel schema location - prismaClientPath = path.relative(path.dirname(options.schemaPath), absPath); + prismaClientPath = normalizedRelative(path.dirname(options.schemaPath), absPath); } } } else { diff --git a/packages/schema/src/plugins/zod/utils/schema-gen.ts b/packages/schema/src/plugins/zod/utils/schema-gen.ts index 6d96087d0..ee46390ff 100644 --- a/packages/schema/src/plugins/zod/utils/schema-gen.ts +++ b/packages/schema/src/plugins/zod/utils/schema-gen.ts @@ -20,6 +20,7 @@ import { isInvocationExpr, isNumberLiteral, isStringLiteral, + isBooleanLiteral } from '@zenstackhq/sdk/ast'; import { upperCaseFirst } from 'upper-case-first'; import { name } from '..'; @@ -282,6 +283,8 @@ export function getFieldSchemaDefault(field: DataModelField) { return JSON.stringify(arg.value.value); } else if (isNumberLiteral(arg.value)) { return arg.value.value; + } else if (isBooleanLiteral(arg.value)) { + return arg.value.value; } else if ( isInvocationExpr(arg.value) && isFromStdlib(arg.value.function.ref!) && diff --git a/packages/schema/src/utils/ast-utils.ts b/packages/schema/src/utils/ast-utils.ts index bf935ce20..2ab474801 100644 --- a/packages/schema/src/utils/ast-utils.ts +++ b/packages/schema/src/utils/ast-utils.ts @@ -30,7 +30,7 @@ import { Mutable, Reference, } from 'langium'; -import { isAbsolute } from 'node:path'; +import path from 'node:path'; import { URI, Utils } from 'vscode-uri'; import { findNodeModulesFile } from './pkg-utils'; @@ -116,7 +116,17 @@ function cloneAst( ): Mutable { const clone = copyAstNode(node, buildReference) as Mutable; clone.$container = newContainer; - clone.$inheritedFrom = node.$inheritedFrom ?? getContainerOfType(node, isDataModel); + + if (isDataModel(newContainer) && isDataModelField(node)) { + // walk up the hierarchy to find the upper-most delegate ancestor that defines the field + const delegateBases = getRecursiveBases(newContainer).filter(isDelegateModel); + clone.$inheritedFrom = delegateBases.findLast((base) => base.fields.some((f) => f.name === node.name)); + } + + if (!clone.$inheritedFrom) { + clone.$inheritedFrom = node.$inheritedFrom ?? getContainerOfType(node, isDataModel); + } + return clone; } @@ -174,9 +184,16 @@ export function resolveImportUri(imp: ModelImport): URI | undefined { if ( !imp.path.startsWith('.') && // Respect relative paths - !isAbsolute(imp.path) // Respect Absolute paths + !path.isAbsolute(imp.path) // Respect Absolute paths ) { - imp.path = findNodeModulesFile(imp.path) ?? imp.path; + // use the current model's path as the search context + const contextPath = imp.$container.$document + ? path.dirname(imp.$container.$document.uri.fsPath) + : process.cwd(); + imp.path = findNodeModulesFile(imp.path, contextPath) ?? imp.path; + if (imp.path) { + console.log('Loaded import from:', imp.path); + } } const dirUri = Utils.dirname(getDocument(imp).uri); diff --git a/packages/schema/tests/schema/validation/attribute-validation.test.ts b/packages/schema/tests/schema/validation/attribute-validation.test.ts index 778f37d7a..0c89c61ae 100644 --- a/packages/schema/tests/schema/validation/attribute-validation.test.ts +++ b/packages/schema/tests/schema/validation/attribute-validation.test.ts @@ -816,6 +816,11 @@ describe('Attribute tests', () => { E2 } + model User { + id String @id + e E + } + model N { id String @id e E @@ -840,6 +845,7 @@ describe('Attribute tests', () => { @@allow('all', startsWith(s, 'a')) @@allow('all', endsWith(s, 'a')) @@allow('all', has(es, E1)) + @@allow('all', has(es, auth().e)) @@allow('all', hasSome(es, [E1])) @@allow('all', hasEvery(es, [E1])) @@allow('all', isEmpty(es)) @@ -890,7 +896,9 @@ describe('Attribute tests', () => { @@allow('all', contains(s, s1)) } `) - ).toContain('second argument must be a literal, an enum, or an array of them'); + ).toContain( + 'second argument must be a literal, an enum, an expression starting with `auth().`, or an array of them' + ); expect( await loadModelWithError(` @@ -1022,7 +1030,9 @@ describe('Attribute tests', () => { @@validate(contains(s, s1)) } `) - ).toContain('second argument must be a literal, an enum, or an array of them'); + ).toContain( + 'second argument must be a literal, an enum, an expression starting with `auth().`, or an array of them' + ); expect( await loadModelWithError(` diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 876f19907..ae64196a0 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "2.6.2", + "version": "2.7.0", "description": "ZenStack plugin development SDK", "main": "index.js", "scripts": { @@ -18,8 +18,8 @@ "author": "", "license": "MIT", "dependencies": { - "@prisma/generator-helper": "5.20.x", - "@prisma/internals": "5.20.x", + "@prisma/generator-helper": "5.21.x", + "@prisma/internals": "5.21.x", "@zenstackhq/language": "workspace:*", "@zenstackhq/runtime": "workspace:*", "langium": "1.3.1", diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 27198da28..d7ee364af 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -2,6 +2,7 @@ export * from './code-gen'; export * from './constants'; export { generate as generateModelMeta } from './model-meta-generator'; export * from './names'; +export * from './path'; export * from './policy'; export * from './types'; export * from './typescript-expression-transformer'; diff --git a/packages/sdk/src/path.ts b/packages/sdk/src/path.ts new file mode 100644 index 000000000..618abb751 --- /dev/null +++ b/packages/sdk/src/path.ts @@ -0,0 +1,9 @@ +import path from 'path'; + +/** + * Gets the relative path from `from` to `to` and normalizes it to start it with `./` + */ +export function normalizedRelative(from: string, to: string) { + const result = path.relative(from, to); + return result.startsWith('.') ? result : `./${result}`; +} diff --git a/packages/sdk/src/prisma.ts b/packages/sdk/src/prisma.ts index 1edab3c3d..6688bd691 100644 --- a/packages/sdk/src/prisma.ts +++ b/packages/sdk/src/prisma.ts @@ -9,6 +9,7 @@ import { Model } from './ast'; import { RUNTIME_PACKAGE } from './constants'; import type { PluginOptions } from './types'; import { getDataSourceProvider } from './utils'; +import { normalizedRelative } from './path'; /** * Given an import context directory and plugin options, compute the import spec for the Prisma Client. @@ -34,12 +35,11 @@ export function getPrismaClientImportSpec(importingFromDir: string, options: Plu const resolvedPrismaClientOutput = path.resolve(path.dirname(options.schemaPath), options.prismaClientPath); // translate to path relative to the importing context directory - let result = path.relative(importingFromDir, resolvedPrismaClientOutput); + let result = normalizedRelative(importingFromDir, resolvedPrismaClientOutput); // remove leading `node_modules` (which may be provided by the user) result = result.replace(/^([./\\]*)?node_modules\//, ''); - // compute prisma client absolute output dir relative to the importing file return normalizePath(result); } diff --git a/packages/server/package.json b/packages/server/package.json index 6f35baad3..fd1bc0f22 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/server", - "version": "2.6.2", + "version": "2.7.0", "displayName": "ZenStack Server-side Adapters", "description": "ZenStack server-side adapters", "homepage": "https://zenstack.dev", @@ -52,6 +52,7 @@ "fastify": "^4.14.1", "fastify-plugin": "^4.5.0", "h3": "^1.8.2", + "hono": "^4.6.3", "isomorphic-fetch": "^3.0.0", "next": "14.2.4", "nuxt": "^3.7.4", @@ -71,6 +72,7 @@ "./sveltekit": "./sveltekit/index.js", "./nuxt": "./nuxt/index.js", "./nestjs": "./nestjs/index.js", + "./hono": "./hono/index.js", "./types": "./types.js" } } diff --git a/packages/server/src/api/rest/index.ts b/packages/server/src/api/rest/index.ts index 75b2f738b..32367df44 100644 --- a/packages/server/src/api/rest/index.ts +++ b/packages/server/src/api/rest/index.ts @@ -5,6 +5,7 @@ import { DbClientContract, FieldInfo, PrismaErrorCode, + clone, enumerate, getIdFields, isPrismaClientKnownRequestError, @@ -32,6 +33,8 @@ const urlPatterns = { relationship: new UrlPattern('/:type/:id/relationships/:relationship'), }; +export const idDivider = '_'; + /** * Request handler options */ @@ -53,15 +56,13 @@ export type Options = { type RelationshipInfo = { type: string; - idField: string; - idFieldType: string; + idFields: FieldInfo[]; isCollection: boolean; isOptional: boolean; }; type ModelInfo = { - idField: string; - idFieldType: string; + idFields: FieldInfo[]; fields: Record; relationships: Record; }; @@ -129,10 +130,6 @@ class RequestHandler extends APIHandlerBase { status: 400, title: 'Model without an ID field is not supported', }, - multiId: { - status: 400, - title: 'Model with multiple ID fields is not supported', - }, invalidId: { status: 400, title: 'Resource ID is invalid', @@ -268,8 +265,7 @@ class RequestHandler extends APIHandlerBase { match.type, match.id, match.relationship, - query, - modelMeta + query ); } @@ -290,7 +286,7 @@ class RequestHandler extends APIHandlerBase { let match = urlPatterns.collection.match(path); if (match) { // resource creation - return await this.processCreate(prisma, match.type, query, requestBody, zodSchemas); + return await this.processCreate(prisma, match.type, query, requestBody, modelMeta, zodSchemas); } match = urlPatterns.relationship.match(path); @@ -320,7 +316,15 @@ class RequestHandler extends APIHandlerBase { let match = urlPatterns.single.match(path); if (match) { // resource update - return await this.processUpdate(prisma, match.type, match.id, query, requestBody, zodSchemas); + return await this.processUpdate( + prisma, + match.type, + match.id, + query, + requestBody, + modelMeta, + zodSchemas + ); } match = urlPatterns.relationship.match(path); @@ -387,7 +391,7 @@ class RequestHandler extends APIHandlerBase { return this.makeUnsupportedModelError(type); } - const args: any = { where: this.makeIdFilter(typeInfo.idField, typeInfo.idFieldType, resourceId) }; + const args: any = { where: this.makeIdFilter(typeInfo.idFields, resourceId) }; // include IDs of relation fields so that they can be serialized this.includeRelationshipIds(type, args, 'include'); @@ -406,6 +410,7 @@ class RequestHandler extends APIHandlerBase { } const entity = await prisma[type].findUnique(args); + if (entity) { return { status: 200, @@ -451,7 +456,7 @@ class RequestHandler extends APIHandlerBase { select = select ?? { [relationship]: true }; const args: any = { - where: this.makeIdFilter(typeInfo.idField, typeInfo.idFieldType, resourceId), + where: this.makeIdFilter(typeInfo.idFields, resourceId), select, }; @@ -496,8 +501,7 @@ class RequestHandler extends APIHandlerBase { type: string, resourceId: string, relationship: string, - query: Record | undefined, - modelMeta: ModelMeta + query: Record | undefined ): Promise { const typeInfo = this.typeMap[type]; if (!typeInfo) { @@ -510,13 +514,12 @@ class RequestHandler extends APIHandlerBase { } const args: any = { - where: this.makeIdFilter(typeInfo.idField, typeInfo.idFieldType, resourceId), - select: this.makeIdSelect(type, modelMeta), + where: this.makeIdFilter(typeInfo.idFields, resourceId), + select: this.makeIdSelect(typeInfo.idFields), }; // include IDs of relation fields so that they can be serialized - // this.includeRelationshipIds(type, args, 'select'); - args.select = { ...args.select, [relationship]: { select: this.makeIdSelect(relationInfo.type, modelMeta) } }; + args.select = { ...args.select, [relationship]: { select: this.makeIdSelect(relationInfo.idFields) } }; let paginator: Paginator | undefined; @@ -720,6 +723,7 @@ class RequestHandler extends APIHandlerBase { type: string, _query: Record | undefined, requestBody: unknown, + modelMeta: ModelMeta, zodSchemas?: ZodSchemas ): Promise { const typeInfo = this.typeMap[type]; @@ -749,7 +753,7 @@ class RequestHandler extends APIHandlerBase { if (relationInfo.isCollection) { createPayload.data[key] = { connect: enumerate(data.data).map((item: any) => ({ - [relationInfo.idField]: this.coerce(relationInfo.idFieldType, item.id), + [this.makeIdKey(relationInfo.idFields)]: item.id, })), }; } else { @@ -757,14 +761,16 @@ class RequestHandler extends APIHandlerBase { return this.makeError('invalidRelationData'); } createPayload.data[key] = { - connect: { [relationInfo.idField]: this.coerce(relationInfo.idFieldType, data.data.id) }, + connect: { + [this.makeIdKey(relationInfo.idFields)]: data.data.id, + }, }; } // make sure ID fields are included for result serialization createPayload.include = { ...createPayload.include, - [key]: { select: { [relationInfo.idField]: true } }, + [key]: { select: { [this.makeIdKey(relationInfo.idFields)]: true } }, }; } } @@ -801,8 +807,11 @@ class RequestHandler extends APIHandlerBase { } const updateArgs: any = { - where: this.makeIdFilter(typeInfo.idField, typeInfo.idFieldType, resourceId), - select: { [typeInfo.idField]: true, [relationship]: { select: { [relationInfo.idField]: true } } }, + where: this.makeIdFilter(typeInfo.idFields, resourceId), + select: { + ...typeInfo.idFields.reduce((acc, field) => ({ ...acc, [field.name]: true }), {}), + [relationship]: { select: this.makeIdSelect(relationInfo.idFields) }, + }, }; if (!relationInfo.isCollection) { @@ -833,7 +842,7 @@ class RequestHandler extends APIHandlerBase { updateArgs.data = { [relationship]: { connect: { - [relationInfo.idField]: this.coerce(relationInfo.idFieldType, parsed.data.data.id), + [this.makeIdKey(relationInfo.idFields)]: parsed.data.data.id, }, }, }; @@ -856,9 +865,9 @@ class RequestHandler extends APIHandlerBase { updateArgs.data = { [relationship]: { - [relationVerb]: enumerate(parsed.data.data).map((item: any) => ({ - [relationInfo.idField]: this.coerce(relationInfo.idFieldType, item.id), - })), + [relationVerb]: enumerate(parsed.data.data).map((item: any) => + this.makeIdFilter(relationInfo.idFields, item.id) + ), }, }; } @@ -884,6 +893,7 @@ class RequestHandler extends APIHandlerBase { resourceId: string, _query: Record | undefined, requestBody: unknown, + modelMeta: ModelMeta, zodSchemas?: ZodSchemas ): Promise { const typeInfo = this.typeMap[type]; @@ -897,7 +907,7 @@ class RequestHandler extends APIHandlerBase { } const updatePayload: any = { - where: this.makeIdFilter(typeInfo.idField, typeInfo.idFieldType, resourceId), + where: this.makeIdFilter(typeInfo.idFields, resourceId), data: { ...attributes }, }; @@ -916,7 +926,7 @@ class RequestHandler extends APIHandlerBase { if (relationInfo.isCollection) { updatePayload.data[key] = { set: enumerate(data.data).map((item: any) => ({ - [relationInfo.idField]: this.coerce(relationInfo.idFieldType, item.id), + [this.makeIdKey(relationInfo.idFields)]: item.id, })), }; } else { @@ -924,12 +934,14 @@ class RequestHandler extends APIHandlerBase { return this.makeError('invalidRelationData'); } updatePayload.data[key] = { - set: { [relationInfo.idField]: this.coerce(relationInfo.idFieldType, data.data.id) }, + set: { + [this.makeIdKey(relationInfo.idFields)]: data.data.id, + }, }; } updatePayload.include = { ...updatePayload.include, - [key]: { select: { [relationInfo.idField]: true } }, + [key]: { select: { [this.makeIdKey(relationInfo.idFields)]: true } }, }; } } @@ -948,7 +960,7 @@ class RequestHandler extends APIHandlerBase { } await prisma[type].delete({ - where: this.makeIdFilter(typeInfo.idField, typeInfo.idFieldType, resourceId), + where: this.makeIdFilter(typeInfo.idFields, resourceId), }); return { status: 204, @@ -966,14 +978,9 @@ class RequestHandler extends APIHandlerBase { logWarning(logger, `Not including model ${model} in the API because it has no ID field`); continue; } - if (idFields.length > 1) { - logWarning(logger, `Not including model ${model} in the API because it has multiple ID fields`); - continue; - } this.typeMap[model] = { - idField: idFields[0].name, - idFieldType: idFields[0].type, + idFields, relationships: {}, fields, }; @@ -990,18 +997,10 @@ class RequestHandler extends APIHandlerBase { ); continue; } - if (fieldTypeIdFields.length > 1) { - logWarning( - logger, - `Not including relation ${model}.${field} in the API because it has multiple ID fields` - ); - continue; - } this.typeMap[model].relationships[field] = { type: fieldInfo.type, - idField: fieldTypeIdFields[0].name, - idFieldType: fieldTypeIdFields[0].type, + idFields: fieldTypeIdFields, isCollection: !!fieldInfo.isArray, isOptional: !!fieldInfo.isOptional, }; @@ -1019,7 +1018,8 @@ class RequestHandler extends APIHandlerBase { for (const model of Object.keys(modelMeta.models)) { const ids = getIdFields(modelMeta, model); - if (ids.length !== 1) { + + if (ids.length < 1) { continue; } @@ -1042,7 +1042,7 @@ class RequestHandler extends APIHandlerBase { const serializer = new Serializer(model, { version: '1.1', - idKey: ids[0].name, + idKey: this.makeIdKey(ids), linkers: { resource: linker, document: linker, @@ -1069,7 +1069,7 @@ class RequestHandler extends APIHandlerBase { continue; } const fieldIds = getIdFields(modelMeta, fieldMeta.type); - if (fieldIds.length === 1) { + if (fieldIds.length > 0) { const relator = new Relator( async (data) => { return (data as any)[field]; @@ -1107,10 +1107,10 @@ class RequestHandler extends APIHandlerBase { return undefined; } const ids = getIdFields(modelMeta, model); - if (ids.length === 1) { - return data[ids[0].name]; - } else { + if (ids.length === 0) { return undefined; + } else { + return data[ids.map((id) => id.name).join(idDivider)]; } } @@ -1121,8 +1121,11 @@ class RequestHandler extends APIHandlerBase { throw new Error(`serializer not found for model ${model}`); } + const itemsWithId = clone(items); + this.injectCompoundId(model, itemsWithId); + // serialize to JSON:API structure - const serialized = await serializer.serialize(items, options); + const serialized = await serializer.serialize(itemsWithId, options); // convert the serialization result to plain object otherwise SuperJSON won't work const plainResult = this.toPlainObject(serialized); @@ -1138,6 +1141,31 @@ class RequestHandler extends APIHandlerBase { return result; } + private injectCompoundId(model: string, items: unknown) { + const typeInfo = this.typeMap[lowerCaseFirst(model)]; + if (!typeInfo) { + return; + } + + // recursively traverse the entity to create synthetic ID field for models with compound ID + enumerate(items).forEach((item: any) => { + if (!item) { + return; + } + + if (typeInfo.idFields.length > 1) { + item[this.makeIdKey(typeInfo.idFields)] = this.makeCompoundId(typeInfo.idFields, item); + } + + for (const [key, value] of Object.entries(item)) { + if (typeInfo.relationships[key]) { + // field is a relationship, recurse + this.injectCompoundId(typeInfo.relationships[key].type, value); + } + } + }); + } + private toPlainObject(data: any): any { if (data === undefined || data === null) { return data; @@ -1178,18 +1206,35 @@ class RequestHandler extends APIHandlerBase { return r.toString(); } - private makeIdFilter(idField: string, idFieldType: string, resourceId: string) { - return { [idField]: this.coerce(idFieldType, resourceId) }; + private makeIdFilter(idFields: FieldInfo[], resourceId: string) { + if (idFields.length === 1) { + return { [idFields[0].name]: this.coerce(idFields[0].type, resourceId) }; + } else { + return { + [idFields.map((idf) => idf.name).join(idDivider)]: idFields.reduce( + (acc, curr, idx) => ({ + ...acc, + [curr.name]: this.coerce(curr.type, resourceId.split(idDivider)[idx]), + }), + {} + ), + }; + } } - private makeIdSelect(model: string, modelMeta: ModelMeta) { - const idFields = getIdFields(modelMeta, model); + private makeIdSelect(idFields: FieldInfo[]) { if (idFields.length === 0) { throw this.errors.noId; - } else if (idFields.length > 1) { - throw this.errors.multiId; } - return { [idFields[0].name]: true }; + return idFields.reduce((acc, curr) => ({ ...acc, [curr.name]: true }), {}); + } + + private makeIdKey(idFields: FieldInfo[]) { + return idFields.map((idf) => idf.name).join(idDivider); + } + + private makeCompoundId(idFields: FieldInfo[], item: any) { + return idFields.map((idf) => item[idf.name]).join(idDivider); } private includeRelationshipIds(model: string, args: any, mode: 'select' | 'include') { @@ -1198,7 +1243,7 @@ class RequestHandler extends APIHandlerBase { return; } for (const [relation, relationInfo] of Object.entries(typeInfo.relationships)) { - args[mode] = { ...args[mode], [relation]: { select: { [relationInfo.idField]: true } } }; + args[mode] = { ...args[mode], [relation]: { select: this.makeIdSelect(relationInfo.idFields) } }; } } @@ -1425,7 +1470,10 @@ class RequestHandler extends APIHandlerBase { if (!relationType) { return { sort: undefined, error: this.makeUnsupportedModelError(fieldInfo.type) }; } - curr[fieldInfo.name] = { [relationType.idField]: dir }; + curr[fieldInfo.name] = relationType.idFields.reduce((acc: any, idField: FieldInfo) => { + acc[idField.name] = dir; + return acc; + }, {}); } else { // regular field curr[fieldInfo.name] = dir; @@ -1509,11 +1557,11 @@ class RequestHandler extends APIHandlerBase { const values = value.split(',').filter((i) => i); const filterValue = values.length > 1 - ? { OR: values.map((v) => this.makeIdFilter(info.idField, info.idFieldType, v)) } - : this.makeIdFilter(info.idField, info.idFieldType, value); + ? { OR: values.map((v) => this.makeIdFilter(info.idFields, v)) } + : this.makeIdFilter(info.idFields, value); return { some: filterValue }; } else { - return { is: this.makeIdFilter(info.idField, info.idFieldType, value) }; + return { is: this.makeIdFilter(info.idFields, value) }; } } else { const coerced = this.coerce(fieldInfo.type, value); diff --git a/packages/server/src/hono/handler.ts b/packages/server/src/hono/handler.ts new file mode 100644 index 000000000..45c104197 --- /dev/null +++ b/packages/server/src/hono/handler.ts @@ -0,0 +1,62 @@ +import { DbClientContract } from '@zenstackhq/runtime'; +import { Context, MiddlewareHandler } from 'hono'; +import { StatusCode } from 'hono/utils/http-status'; +import { RPCApiHandler } from '../api'; +import { loadAssets } from '../shared'; +import { AdapterBaseOptions } from '../types'; + +/** + * Options for initializing a Hono middleware. + */ +export interface HonoOptions extends AdapterBaseOptions { + /** + * Callback method for getting a Prisma instance for the given request. + */ + getPrisma: (ctx: Context) => Promise | unknown; +} + +export function createHonoHandler(options: HonoOptions): MiddlewareHandler { + const { modelMeta, zodSchemas } = loadAssets(options); + const requestHandler = options.handler ?? RPCApiHandler(); + + return async (ctx) => { + const prisma = (await options.getPrisma(ctx)) as DbClientContract; + if (!prisma) { + return ctx.json({ message: 'unable to get prisma from request context' }, 500); + } + + const url = new URL(ctx.req.url); + const query = Object.fromEntries(url.searchParams); + + const path = ctx.req.path.substring(ctx.req.routePath.length - 1); + + if (!path) { + return ctx.json({ message: 'missing path parameter' }, 400); + } + + let requestBody: unknown; + if (ctx.req.raw.body) { + try { + requestBody = await ctx.req.json(); + } catch { + // noop + } + } + + try { + const r = await requestHandler({ + method: ctx.req.method, + path, + query, + requestBody, + prisma, + modelMeta, + zodSchemas, + logger: options.logger, + }); + return ctx.json(r.body as object, r.status as StatusCode); + } catch (err) { + return ctx.json({ message: `An unhandled error occurred: ${err}` }, 500); + } + }; +} diff --git a/packages/server/src/hono/index.ts b/packages/server/src/hono/index.ts new file mode 100644 index 000000000..68ae53f6c --- /dev/null +++ b/packages/server/src/hono/index.ts @@ -0,0 +1 @@ +export * from './handler'; diff --git a/packages/server/src/nuxt/handler.ts b/packages/server/src/nuxt/handler.ts index 97c0626d4..c9f5042ff 100644 --- a/packages/server/src/nuxt/handler.ts +++ b/packages/server/src/nuxt/handler.ts @@ -50,6 +50,7 @@ export function createEventHandler(options: HandlerOptions) { prisma, modelMeta, zodSchemas, + logger: options.logger, }); setResponseStatus(event, status); diff --git a/packages/server/src/sveltekit/handler.ts b/packages/server/src/sveltekit/handler.ts index f5d1b7995..0721c1f86 100644 --- a/packages/server/src/sveltekit/handler.ts +++ b/packages/server/src/sveltekit/handler.ts @@ -62,6 +62,7 @@ export default function createHandler(options: HandlerOptions): Handle { prisma, modelMeta, zodSchemas, + logger: options.logger, }); return new Response(JSON.stringify(r.body), { diff --git a/packages/server/tests/adapter/hono.test.ts b/packages/server/tests/adapter/hono.test.ts new file mode 100644 index 000000000..3fc1bb9da --- /dev/null +++ b/packages/server/tests/adapter/hono.test.ts @@ -0,0 +1,191 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/// +import { loadSchema } from '@zenstackhq/testtools'; +import 'isomorphic-fetch'; +import path from 'path'; +import superjson from 'superjson'; +import Rest from '../../src/api/rest'; +import { createHonoHandler } from '../../src/hono'; +import { makeUrl, schema } from '../utils'; +import { Hono, MiddlewareHandler } from 'hono'; + +describe('Hono adapter tests - rpc handler', () => { + it('run hooks regular json', async () => { + const { prisma, zodSchemas } = await loadSchema(schema); + + const handler = await createHonoApp(createHonoHandler({ getPrisma: () => prisma, zodSchemas })); + + let r = await handler(makeRequest('GET', makeUrl('/api/post/findMany', { where: { id: { equals: '1' } } }))); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data).toHaveLength(0); + + r = await handler( + makeRequest('POST', '/api/user/create', { + include: { posts: true }, + data: { + id: 'user1', + email: 'user1@abc.com', + posts: { + create: [ + { title: 'post1', published: true, viewCount: 1 }, + { title: 'post2', published: false, viewCount: 2 }, + ], + }, + }, + }) + ); + expect(r.status).toBe(201); + expect((await unmarshal(r)).data).toMatchObject({ + email: 'user1@abc.com', + posts: expect.arrayContaining([ + expect.objectContaining({ title: 'post1' }), + expect.objectContaining({ title: 'post2' }), + ]), + }); + + r = await handler(makeRequest('GET', makeUrl('/api/post/findMany'))); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data).toHaveLength(2); + + r = await handler(makeRequest('GET', makeUrl('/api/post/findMany', { where: { viewCount: { gt: 1 } } }))); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data).toHaveLength(1); + + r = await handler( + makeRequest('PUT', '/api/user/update', { where: { id: 'user1' }, data: { email: 'user1@def.com' } }) + ); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data.email).toBe('user1@def.com'); + + r = await handler(makeRequest('GET', makeUrl('/api/post/count', { where: { viewCount: { gt: 1 } } }))); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data).toBe(1); + + r = await handler(makeRequest('GET', makeUrl('/api/post/aggregate', { _sum: { viewCount: true } }))); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data._sum.viewCount).toBe(3); + + r = await handler( + makeRequest('GET', makeUrl('/api/post/groupBy', { by: ['published'], _sum: { viewCount: true } })) + ); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ published: true, _sum: { viewCount: 1 } }), + expect.objectContaining({ published: false, _sum: { viewCount: 2 } }), + ]) + ); + + r = await handler(makeRequest('DELETE', makeUrl('/api/user/deleteMany', { where: { id: 'user1' } }))); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data.count).toBe(1); + }); + + it('custom load path', async () => { + const { prisma, projectDir } = await loadSchema(schema, { output: './zen' }); + + const handler = await createHonoApp( + createHonoHandler({ + getPrisma: () => prisma, + modelMeta: require(path.join(projectDir, './zen/model-meta')).default, + zodSchemas: require(path.join(projectDir, './zen/zod')), + }) + ); + + const r = await handler( + makeRequest('POST', '/api/user/create', { + include: { posts: true }, + data: { + id: 'user1', + email: 'user1@abc.com', + posts: { + create: [ + { title: 'post1', published: true, viewCount: 1 }, + { title: 'post2', published: false, viewCount: 2 }, + ], + }, + }, + }) + ); + expect(r.status).toBe(201); + }); +}); + +describe('Hono adapter tests - rest handler', () => { + it('run hooks', async () => { + const { prisma, modelMeta, zodSchemas } = await loadSchema(schema); + + const handler = await createHonoApp( + createHonoHandler({ + getPrisma: () => prisma, + handler: Rest({ endpoint: 'http://localhost/api' }), + modelMeta, + zodSchemas, + }) + ); + + let r = await handler(makeRequest('GET', makeUrl('/api/post/1'))); + expect(r.status).toBe(404); + + r = await handler( + makeRequest('POST', '/api/user', { + data: { + type: 'user', + attributes: { id: 'user1', email: 'user1@abc.com' }, + }, + }) + ); + expect(r.status).toBe(201); + expect(await unmarshal(r)).toMatchObject({ + data: { + id: 'user1', + attributes: { + email: 'user1@abc.com', + }, + }, + }); + + r = await handler(makeRequest('GET', makeUrl('/api/user?filter[id]=user1'))); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data).toHaveLength(1); + + r = await handler(makeRequest('GET', makeUrl('/api/user?filter[id]=user2'))); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data).toHaveLength(0); + + r = await handler(makeRequest('GET', makeUrl('/api/user?filter[id]=user1&filter[email]=xyz'))); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data).toHaveLength(0); + + r = await handler( + makeRequest('PUT', makeUrl('/api/user/user1'), { + data: { type: 'user', attributes: { email: 'user1@def.com' } }, + }) + ); + expect(r.status).toBe(200); + expect((await unmarshal(r)).data.attributes.email).toBe('user1@def.com'); + + r = await handler(makeRequest('DELETE', makeUrl(makeUrl('/api/user/user1')))); + expect(r.status).toBe(204); + expect(await prisma.user.findMany()).toHaveLength(0); + }); +}); + +function makeRequest(method: string, path: string, body?: any) { + const payload = body ? JSON.stringify(body) : undefined; + return new Request(`http://localhost${path}`, { method, body: payload }); +} + +async function unmarshal(r: Response, useSuperJson = false) { + const text = await r.text(); + return (useSuperJson ? superjson.parse(text) : JSON.parse(text)) as any; +} + +async function createHonoApp(middleware: MiddlewareHandler) { + const app = new Hono(); + + app.use('/api/*', middleware); + + return app.fetch; +} diff --git a/packages/server/tests/api/rest.test.ts b/packages/server/tests/api/rest.test.ts index a587678c3..fa7d0cfb8 100644 --- a/packages/server/tests/api/rest.test.ts +++ b/packages/server/tests/api/rest.test.ts @@ -5,7 +5,7 @@ import { CrudFailureReason, type ModelMeta } from '@zenstackhq/runtime'; import { loadSchema, run } from '@zenstackhq/testtools'; import { Decimal } from 'decimal.js'; import SuperJSON from 'superjson'; -import makeHandler from '../../src/api/rest'; +import makeHandler, { idDivider } from '../../src/api/rest'; describe('REST server tests', () => { let prisma: any; @@ -26,6 +26,7 @@ describe('REST server tests', () => { updatedAt DateTime @updatedAt email String @unique @email posts Post[] + likes PostLike[] profile Profile? } @@ -47,6 +48,7 @@ describe('REST server tests', () => { publishedAt DateTime? viewCount Int @default(0) comments Comment[] + likes PostLike[] setting Setting? } @@ -63,6 +65,15 @@ describe('REST server tests', () => { post Post @relation(fields: [postId], references: [id]) postId Int @unique } + + model PostLike { + postId Int + userId String + superLike Boolean + post Post @relation(fields: [postId], references: [id]) + user User @relation(fields: [userId], references: [myId]) + @@id([postId, userId]) + } `; beforeAll(async () => { @@ -125,6 +136,7 @@ describe('REST server tests', () => { path: '/user', prisma, }); + expect(r.status).toBe(200); expect(r.body).toMatchObject({ data: [], @@ -291,6 +303,35 @@ describe('REST server tests', () => { }); }); + it('fetches a related resource with a compound ID', async () => { + await prisma.user.create({ + data: { + myId: 'user1', + email: 'user1@abc.com', + posts: { + create: { id: 1, title: 'Post1' }, + }, + }, + }); + await prisma.postLike.create({ + data: { postId: 1, userId: 'user1', superLike: true }, + }); + + const r = await handler({ + method: 'get', + path: '/post/1/relationships/likes', + prisma, + }); + + expect(r.status).toBe(200); + expect(r.body).toMatchObject({ + links: { + self: 'http://localhost/api/post/1/relationships/likes', + }, + data: [{ type: 'postLike', id: `1${idDivider}user1` }], + }); + }); + it('fetch a relationship', async () => { // Create a user first await prisma.user.create({ @@ -1283,6 +1324,90 @@ describe('REST server tests', () => { next: null, }); }); + + describe('compound id', () => { + beforeEach(async () => { + await prisma.user.create({ + data: { myId: 'user1', email: 'user1@abc.com', posts: { create: { title: 'Post1' } } }, + }); + await prisma.user.create({ + data: { myId: 'user2', email: 'user2@abc.com' }, + }); + await prisma.postLike.create({ + data: { userId: 'user2', postId: 1, superLike: false }, + }); + }); + + it('get all', async () => { + const r = await handler({ + method: 'get', + path: '/postLike', + prisma, + }); + + expect(r.status).toBe(200); + expect(r.body).toMatchObject({ + data: [ + { + type: 'postLike', + id: `1${idDivider}user2`, + attributes: { userId: 'user2', postId: 1, superLike: false }, + }, + ], + }); + }); + + it('get single', async () => { + const r = await handler({ + method: 'get', + path: `/postLike/1${idDivider}user2`, // Order of ids is same as in the model @@id + prisma, + }); + + expect(r.status).toBe(200); + expect(r.body).toMatchObject({ + data: { + type: 'postLike', + id: `1${idDivider}user2`, + attributes: { userId: 'user2', postId: 1, superLike: false }, + }, + }); + }); + + it('get as relationship', async () => { + const r = await handler({ + method: 'get', + path: `/post/1`, + query: { include: 'likes' }, + prisma, + }); + + expect(r.status).toBe(200); + expect(r.body).toMatchObject({ + data: { + relationships: { + likes: { + data: [{ type: 'postLike', id: `1${idDivider}user2` }], + }, + }, + }, + included: [ + expect.objectContaining({ + type: 'postLike', + id: '1_user2', + attributes: { + postId: 1, + userId: 'user2', + superLike: false, + }, + links: { + self: 'http://localhost/api/postLike/1_user2', + }, + }), + ], + }); + }); + }); }); describe('POST', () => { @@ -1546,6 +1671,50 @@ describe('REST server tests', () => { expect(r.status).toBe(404); }); + + it('create relation with compound id', async () => { + await prisma.user.create({ data: { myId: 'user1', email: 'user1@abc.com' } }); + await prisma.post.create({ data: { id: 1, title: 'Post1' } }); + + const r = await handler({ + method: 'post', + path: '/postLike', + query: {}, + requestBody: { + data: { + type: 'postLike', + id: `1${idDivider}user1`, + attributes: { userId: 'user1', postId: 1, superLike: false }, + }, + }, + prisma, + }); + + expect(r.status).toBe(201); + }); + + it('compound id create single', async () => { + await prisma.user.create({ data: { myId: 'user1', email: 'user1@abc.com' } }); + await prisma.post.create({ + data: { id: 1, title: 'Post1' }, + }); + + const r = await handler({ + method: 'post', + path: '/postLike', + query: {}, + requestBody: { + data: { + type: 'postLike', + id: `1${idDivider}user1`, + attributes: { userId: 'user1', postId: 1, superLike: false }, + }, + }, + prisma, + }); + + expect(r.status).toBe(201); + }); }); describe('PUT', () => { @@ -1684,6 +1853,27 @@ describe('REST server tests', () => { expect(r.body.errors[0].code).toBe('invalid-payload'); }); + it('update item with compound id', async () => { + await prisma.user.create({ data: { myId: 'user1', email: 'user1@abc.com' } }); + await prisma.post.create({ data: { id: 1, title: 'Post1' } }); + await prisma.postLike.create({ data: { userId: 'user1', postId: 1, superLike: false } }); + + const r = await handler({ + method: 'put', + path: `/postLike/1${idDivider}user1`, + query: {}, + requestBody: { + data: { + type: 'postLike', + attributes: { superLike: true }, + }, + }, + prisma, + }); + + expect(r.status).toBe(200); + }); + it('update a single relation', async () => { await prisma.user.create({ data: { myId: 'user1', email: 'user1@abc.com' } }); await prisma.post.create({ @@ -1767,6 +1957,24 @@ describe('REST server tests', () => { }); }); + it('update a collection of relations with compound id', async () => { + await prisma.user.create({ data: { myId: 'user1', email: 'user1@abc.com' } }); + await prisma.post.create({ data: { id: 1, title: 'Post1' } }); + await prisma.postLike.create({ data: { userId: 'user1', postId: 1, superLike: false } }); + + const r = await handler({ + method: 'patch', + path: '/post/1/relationships/likes', + query: {}, + requestBody: { + data: [{ type: 'postLike', id: `1${idDivider}user1`, attributes: { superLike: true } }], + }, + prisma, + }); + + expect(r.status).toBe(200); + }); + it('update a collection of relations to empty', async () => { await prisma.user.create({ data: { myId: 'user1', email: 'user1@abc.com', posts: { create: { id: 1, title: 'Post1' } } }, @@ -1845,6 +2053,21 @@ describe('REST server tests', () => { expect(r.body).toBeUndefined(); }); + it('deletes an item with compound id', async () => { + await prisma.user.create({ + data: { myId: 'user1', email: 'user1@abc.com', posts: { create: { id: 1, title: 'Post1' } } }, + }); + await prisma.postLike.create({ data: { userId: 'user1', postId: 1, superLike: false } }); + + const r = await handler({ + method: 'delete', + path: `/postLike/1${idDivider}user1`, + prisma, + }); + expect(r.status).toBe(204); + expect(r.body).toBeUndefined(); + }); + it('returns 404 if the user does not exist', async () => { const r = await handler({ method: 'delete', diff --git a/packages/testtools/package.json b/packages/testtools/package.json index e45a93f4f..1c0a832a5 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/testtools", - "version": "2.6.2", + "version": "2.7.0", "description": "ZenStack Test Tools", "main": "index.js", "private": true, diff --git a/packages/testtools/src/schema.ts b/packages/testtools/src/schema.ts index 7cce9bd36..4a7b575bd 100644 --- a/packages/testtools/src/schema.ts +++ b/packages/testtools/src/schema.ts @@ -134,6 +134,7 @@ export type SchemaLoadOptions = { preserveTsFiles?: boolean; generatePermissionChecker?: boolean; previewFeatures?: string[]; + prismaLoadPath?: string; prismaClientOptions?: object; generateNoCompile?: boolean; }; @@ -263,7 +264,13 @@ export async function loadSchema(schema: string, options?: SchemaLoadOptions) { fs.cpSync(dep, path.join(projectDir, 'node_modules', pkgJson.name), { recursive: true, force: true }); }); - const PrismaClient = require(path.join(projectDir, 'node_modules/.prisma/client')).PrismaClient; + const prismaLoadPath = options?.prismaLoadPath + ? path.isAbsolute(options.prismaLoadPath) + ? options.prismaLoadPath + : path.join(projectDir, options.prismaLoadPath) + : path.join(projectDir, 'node_modules/.prisma/client'); + const prismaModule = require(prismaLoadPath); + const PrismaClient = prismaModule.PrismaClient; let clientOptions: object = { log: ['info', 'warn', 'error'] }; if (options?.prismaClientOptions) { @@ -273,8 +280,6 @@ export async function loadSchema(schema: string, options?: SchemaLoadOptions) { // https://github.com/prisma/prisma/issues/18292 prisma[Symbol.for('nodejs.util.inspect.custom')] = 'PrismaClient'; - const prismaModule = loadModule('@prisma/client', projectDir).Prisma; - if (opt.pulseApiKey) { const withPulse = loadModule('@prisma/extension-pulse/node', projectDir).withPulse; prisma = prisma.$extends(withPulse({ apiKey: opt.pulseApiKey })); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4d95f0b79..a0da7754f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -284,8 +284,8 @@ importers: specifier: ^4.29.7 version: 4.36.1(react-dom@18.3.1(react@18.2.0))(react@18.2.0) '@tanstack/react-query-v5': - specifier: npm:@tanstack/react-query@^5.0.0 - version: '@tanstack/react-query@5.48.0(react@18.2.0)' + specifier: npm:@tanstack/react-query@5.56.x + version: '@tanstack/react-query@5.56.2(react@18.2.0)' '@tanstack/svelte-query': specifier: ^4.29.7 version: 4.36.1(svelte@4.2.18) @@ -365,10 +365,10 @@ importers: devDependencies: '@trpc/next': specifier: ^10.32.0 - version: 10.45.2(@tanstack/react-query@5.48.0(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@5.48.0(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.3.1(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.2.0))(react@18.2.0))(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + version: 10.45.2(@tanstack/react-query@5.56.2(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@5.56.2(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.3.1(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.2.0))(react@18.2.0))(react-dom@18.3.1(react@18.2.0))(react@18.2.0) '@trpc/react-query': specifier: ^10.32.0 - version: 10.45.2(@tanstack/react-query@5.48.0(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + version: 10.45.2(@tanstack/react-query@5.56.2(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) '@trpc/server': specifier: ^10.32.0 version: 10.45.2 @@ -392,8 +392,8 @@ importers: packages/runtime: dependencies: '@prisma/client': - specifier: 5.0.0 - 5.20.x - version: 5.20.0(prisma@5.16.1) + specifier: 5.0.0 - 5.21.x + version: 5.21.0(prisma@5.16.1) bcryptjs: specifier: ^2.4.3 version: 2.4.3 @@ -523,7 +523,7 @@ importers: specifier: ^4.0.0 version: 4.0.1 prisma: - specifier: 5.0.0 - 5.20.x + specifier: 5.0.0 - 5.21.x version: 5.16.1 semver: specifier: ^7.5.2 @@ -575,8 +575,8 @@ importers: version: 1.5.0(zod@3.23.8) devDependencies: '@prisma/client': - specifier: 5.20.x - version: 5.20.0(prisma@5.16.1) + specifier: 5.21.x + version: 5.21.0(prisma@5.16.1) '@types/async-exit-hook': specifier: ^2.0.0 version: 2.0.2 @@ -627,11 +627,11 @@ importers: packages/sdk: dependencies: '@prisma/generator-helper': - specifier: 5.20.x - version: 5.20.0 + specifier: 5.21.x + version: 5.21.0 '@prisma/internals': - specifier: 5.20.x - version: 5.20.0 + specifier: 5.21.x + version: 5.21.0 '@zenstackhq/language': specifier: workspace:* version: link:../language/dist @@ -737,6 +737,9 @@ importers: h3: specifier: ^1.8.2 version: 1.12.0 + hono: + specifier: ^4.6.3 + version: 4.6.3 isomorphic-fetch: specifier: ^3.0.0 version: 3.0.0(encoding@0.1.13) @@ -2439,8 +2442,8 @@ packages: prisma: optional: true - '@prisma/client@5.20.0': - resolution: {integrity: sha512-CLv55ZuMuUawMsxoqxGtLT3bEZoa2W8L3Qnp6rDIFWy+ZBrUcOFKdoeGPSnbBqxc3SkdxJrF+D1veN/WNynZYA==} + '@prisma/client@5.21.0': + resolution: {integrity: sha512-Qf2YleB3dsCRXiKSQZ+j0aF5E+ojpfqF8ExXaNAWBbAhKapMduwNvgo13K2pEuTiQq8voG2aQPQnxjsO9fOpTQ==} engines: {node: '>=16.13'} peerDependencies: prisma: '*' @@ -2454,8 +2457,8 @@ packages: '@prisma/debug@5.16.1': resolution: {integrity: sha512-JsNgZAg6BD9RInLSrg7ZYzo11N7cVvYArq3fHGSD89HSgtN0VDdjV6bib7YddbcO6snzjchTiLfjeTqBjtArVQ==} - '@prisma/debug@5.20.0': - resolution: {integrity: sha512-oCx79MJ4HSujokA8S1g0xgZUGybD4SyIOydoHMngFYiwEwYDQ5tBQkK5XoEHuwOYDKUOKRn/J0MEymckc4IgsQ==} + '@prisma/debug@5.21.0': + resolution: {integrity: sha512-8gX68E36OKImh7LBz5fFIuTRLZgM1ObnDA8ukhC1kZvTK7k7Unti6pJe3ZiudzuFAxae06PV1rhq1u9DZbXVnQ==} '@prisma/engines-version@5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48': resolution: {integrity: sha512-ip6pNkRo1UxWv+6toxNcYvItNYaqQjXdFNGJ+Nuk2eYtRoEdoF13wxo7/jsClJFFenMPVNVqXQDV0oveXnR1cA==} @@ -2463,8 +2466,8 @@ packages: '@prisma/engines-version@5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303': resolution: {integrity: sha512-HkT2WbfmFZ9WUPyuJHhkiADxazHg8Y4gByrTSVeb3OikP6tjQ7txtSUGu9OBOBH0C13dPKN2qqH12xKtHu/Hiw==} - '@prisma/engines-version@5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284': - resolution: {integrity: sha512-Lg8AS5lpi0auZe2Mn4gjuCg081UZf88k3cn0RCwHgR+6cyHHpttPZBElJTHf83ZGsRNAmVCZCfUGA57WB4u4JA==} + '@prisma/engines-version@5.21.0-36.08713a93b99d58f31485621c634b04983ae01d95': + resolution: {integrity: sha512-hfq7c8MnkhcZTY0bGXG6bV5Cr7OsnHLERNy4xkZy6rbpWnhtfjuj3yUVM4u1GKXd6uWmFbg0+HDw8KXTgTVepQ==} '@prisma/engines@5.14.0': resolution: {integrity: sha512-lgxkKZ6IEygVcw6IZZUlPIfLQ9hjSYAtHjZ5r64sCLDgVzsPFCi2XBBJgzPMkOQ5RHzUD4E/dVdpn9+ez8tk1A==} @@ -2472,8 +2475,8 @@ packages: '@prisma/engines@5.16.1': resolution: {integrity: sha512-KkyF3eIUtBIyp5A/rJHCtwQO18OjpGgx18PzjyGcJDY/+vNgaVyuVd+TgwBgeq6NLdd1XMwRCI+58vinHsAdfA==} - '@prisma/engines@5.20.0': - resolution: {integrity: sha512-DtqkP+hcZvPEbj8t8dK5df2b7d3B8GNauKqaddRRqQBBlgkbdhJkxhoJTrOowlS3vaRt2iMCkU0+CSNn0KhqAQ==} + '@prisma/engines@5.21.0': + resolution: {integrity: sha512-IBewQJiDnFiz39pl8kEIzmzV4RAoBPBD2DoLDntMMXObg1an90Dp+xeb1mmwrTgRDE3elu/LYxyVPEkKw9LZ7A==} '@prisma/fetch-engine@5.14.0': resolution: {integrity: sha512-VrheA9y9DMURK5vu8OJoOgQpxOhas3qF0IBHJ8G/0X44k82kc8E0w98HCn2nhnbOOMwbWsJWXfLC2/F8n5u0gQ==} @@ -2481,14 +2484,14 @@ packages: '@prisma/fetch-engine@5.16.1': resolution: {integrity: sha512-oOkjaPU1lhcA/Rvr4GVfd1NLJBwExgNBE36Ueq7dr71kTMwy++a3U3oLd2ZwrV9dj9xoP6LjCcky799D9nEt4w==} - '@prisma/fetch-engine@5.20.0': - resolution: {integrity: sha512-JVcaPXC940wOGpCOwuqQRTz6I9SaBK0c1BAyC1pcz9xBi+dzFgUu3G/p9GV1FhFs9OKpfSpIhQfUJE9y00zhqw==} + '@prisma/fetch-engine@5.21.0': + resolution: {integrity: sha512-nXKJrsxVKng6yjJzl7vBjrr3S34cOmWQ9SiGTo9xidVTmVSgg5GCTwDL4r2be8DE3RntqK5BW2LWQ1gF80eINw==} '@prisma/generator-helper@5.14.0': resolution: {integrity: sha512-xVc71cmTnPZ0lnSs4FAY6Ta72vFJ3webrQwKMQ2ujr6hDG1VPIEf820T1TOS3ZZQd/OKigNKXnq3co8biz9/qw==} - '@prisma/generator-helper@5.20.0': - resolution: {integrity: sha512-37Aibw0wVRQgQVtCdNAIN71YFnSQfvetok7vd95KKkYkQRbEx94gsvPDpyN9Mw7p3IwA3nFgPfLc3jBRztUkKw==} + '@prisma/generator-helper@5.21.0': + resolution: {integrity: sha512-+DnQBW6LwsDIpj6hDAPbWoQBwU5MP+qrDt/d5wFAhsMNqg56XgSj6ZbHEkaej58xIuae5Pg6XmzwRdBPg7f/jA==} '@prisma/get-platform@5.14.0': resolution: {integrity: sha512-/yAyBvcEjRv41ynZrhdrPtHgk47xLRRq/o5eWGcUpBJ1YrUZTYB8EoPiopnP7iQrMATK8stXQdPOoVlrzuTQZw==} @@ -2496,14 +2499,14 @@ packages: '@prisma/get-platform@5.16.1': resolution: {integrity: sha512-R4IKnWnMkR2nUAbU5gjrPehdQYUUd7RENFD2/D+xXTNhcqczp0N+WEGQ3ViyI3+6mtVcjjNIMdnUTNyu3GxIgA==} - '@prisma/get-platform@5.20.0': - resolution: {integrity: sha512-8/+CehTZZNzJlvuryRgc77hZCWrUDYd/PmlZ7p2yNXtmf2Una4BWnTbak3us6WVdqoz5wmptk6IhsXdG2v5fmA==} + '@prisma/get-platform@5.21.0': + resolution: {integrity: sha512-NAyaAcHJhs0IysGYJtM6Fm3ccEs/LkCZqz/8riVkkJswFrRtFV93jAUIVKWO/wj1Ca1gO7HaMd/tr6e/9Xmvww==} '@prisma/internals@5.14.0': resolution: {integrity: sha512-s0JRNDmR2bvcyy0toz89jy7SbbjANAs4e9KCReNvSm5czctIaZzDf68tcOXdtH0G7m9mKhVhNPdS9lMky0DhWA==} - '@prisma/internals@5.20.0': - resolution: {integrity: sha512-n8ceNIpQbrLHNDcqsfmxtktpGrGNDKaGe9WNSz5B8J5ayQqarC6K/l9C3jCMNBjj8ZRI8nGN/B2yczdvEugs0w==} + '@prisma/internals@5.21.0': + resolution: {integrity: sha512-sfMmfp9qke/imXNAL0z2gvHUZ7jPX19w7Nh4TVcvKqbTpgTk1iM1uIPQM8CIPOBEV09UwipHe3ln9yxWYqJ6gw==} '@prisma/prisma-schema-wasm@5.14.0-17.56ca112d5a19c9925b53af75c3c6b7ada97f9f85': resolution: {integrity: sha512-SX9vE9dGYBap6xsfJuDE5b2eoA6w1vKsx8QpLUHZR+kIV6GQVUYUboEfkvYYoBVen3s9LqxJ1+LjHL/1MqBZag==} @@ -2511,14 +2514,14 @@ packages: '@prisma/prisma-schema-wasm@5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48': resolution: {integrity: sha512-WeTmJ0mK8ALoKJUQFO+465k9lm1JWS4ODUg7akJq1wjgyDU1RTAzDFli8ESmNJlMVgJgoAd6jXmzcnoA0HT9Lg==} - '@prisma/prisma-schema-wasm@5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284': - resolution: {integrity: sha512-tE5ZxPwI381Mrzgd1/GLJFusD1SfVXGzOWRU2P9c9zk25nlfa6GkyaqCtSTIaINexPAAy4npsCoAFt2Hc4rqYQ==} + '@prisma/prisma-schema-wasm@5.21.0-36.08713a93b99d58f31485621c634b04983ae01d95': + resolution: {integrity: sha512-JrZMlaWugM4JW6uiB4WirFmfMMnHnCN3LGWVTb32x2R23jPB2IBYDT61BnW8PlackUZE635IDBT8mrZ7bRy1KQ==} '@prisma/schema-files-loader@5.14.0': resolution: {integrity: sha512-n1QHR2C63dARKPZe0WPn7biybcBHzXe+BEmiHC5Drq9KPWnpmQtIfGpqm1ZKdvCZfcA5FF3wgpSMPK4LnB0obQ==} - '@prisma/schema-files-loader@5.20.0': - resolution: {integrity: sha512-Mq4an/vxzdjL+e1GZIw93xTDaU6Gq+2RMuW6NEs+XHAhmiOaBrw9QARZhc+QURY3wwAdj2dUSpoy4xaWON9JTg==} + '@prisma/schema-files-loader@5.21.0': + resolution: {integrity: sha512-snwMUFvyC+ukJWGU6xp9aGK2mXQDu8Zn6N3CB/2O73+qYfTaTvN91z0/Pk7xrUV8tdKihRk6XCyzNEODs4YfhQ==} '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -2810,6 +2813,9 @@ packages: '@tanstack/query-core@5.48.0': resolution: {integrity: sha512-lZAfPPeVIqXCswE9SSbG33B6/91XOWt/Iq41bFeWb/mnHwQSIfFRbkS4bfs+WhIk9abRArF9Id2fp0Mgo+hq6Q==} + '@tanstack/query-core@5.56.2': + resolution: {integrity: sha512-gor0RI3/R5rVV3gXfddh1MM+hgl0Z4G7tj6Xxpq6p2I03NGPaJ8dITY9Gz05zYYb/EJq9vPas/T4wn9EaDPd4Q==} + '@tanstack/react-query@4.36.1': resolution: {integrity: sha512-y7ySVHFyyQblPl3J3eQBWpXZkliroki3ARnBKsdJchlgt7yJLRDUcf4B8soufgiYt3pEQIkBWBx1N9/ZPIeUWw==} peerDependencies: @@ -2822,10 +2828,10 @@ packages: react-native: optional: true - '@tanstack/react-query@5.48.0': - resolution: {integrity: sha512-GDExbjYWzvDokyRqMSWXdrPiYpp95Aig0oeMIrxTaruOJJgWiWfUP//OAaowm2RrRkGVsavSZdko/XmIrrV2Nw==} + '@tanstack/react-query@5.56.2': + resolution: {integrity: sha512-SR0GzHVo6yzhN72pnRhkEFRAHMsUo5ZPzAxfTMvUxFIDVS6W9LYUp6nXW3fcHVdg0ZJl8opSH85jqahvm6DSVg==} peerDependencies: - react: ^18.0.0 + react: ^18 || ^19 '@tanstack/svelte-query@4.36.1': resolution: {integrity: sha512-5fj79QuAu5HuS6G/fairU6ywgILXfs4TGl3+Xc9+MBlmB1aPoQBvGsgJrNyhqvXQcnxro8wDNyZOH8S+Qitycw==} @@ -5173,6 +5179,10 @@ packages: highlight.js@10.4.1: resolution: {integrity: sha512-yR5lWvNz7c85OhVAEAeFhVCc/GV4C30Fjzc/rCP0aCWzc1UUOPUk55dK/qdwTZHBvMZo+eZ2jpk62ndX/xMFlg==} + hono@4.6.3: + resolution: {integrity: sha512-0LeEuBNFeSHGqZ9sNVVgZjB1V5fmhkBSB0hZrpqStSMLOWgfLy0dHOvrjbJh0H2khsjet6rbHfWTHY0kpYThKQ==} + engines: {node: '>=16.9.0'} + hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} @@ -10598,7 +10608,7 @@ snapshots: optionalDependencies: prisma: 5.16.1 - '@prisma/client@5.20.0(prisma@5.16.1)': + '@prisma/client@5.21.0(prisma@5.16.1)': optionalDependencies: prisma: 5.16.1 @@ -10606,13 +10616,13 @@ snapshots: '@prisma/debug@5.16.1': {} - '@prisma/debug@5.20.0': {} + '@prisma/debug@5.21.0': {} '@prisma/engines-version@5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48': {} '@prisma/engines-version@5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303': {} - '@prisma/engines-version@5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284': {} + '@prisma/engines-version@5.21.0-36.08713a93b99d58f31485621c634b04983ae01d95': {} '@prisma/engines@5.14.0': dependencies: @@ -10628,12 +10638,12 @@ snapshots: '@prisma/fetch-engine': 5.16.1 '@prisma/get-platform': 5.16.1 - '@prisma/engines@5.20.0': + '@prisma/engines@5.21.0': dependencies: - '@prisma/debug': 5.20.0 - '@prisma/engines-version': 5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284 - '@prisma/fetch-engine': 5.20.0 - '@prisma/get-platform': 5.20.0 + '@prisma/debug': 5.21.0 + '@prisma/engines-version': 5.21.0-36.08713a93b99d58f31485621c634b04983ae01d95 + '@prisma/fetch-engine': 5.21.0 + '@prisma/get-platform': 5.21.0 '@prisma/fetch-engine@5.14.0': dependencies: @@ -10647,19 +10657,19 @@ snapshots: '@prisma/engines-version': 5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303 '@prisma/get-platform': 5.16.1 - '@prisma/fetch-engine@5.20.0': + '@prisma/fetch-engine@5.21.0': dependencies: - '@prisma/debug': 5.20.0 - '@prisma/engines-version': 5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284 - '@prisma/get-platform': 5.20.0 + '@prisma/debug': 5.21.0 + '@prisma/engines-version': 5.21.0-36.08713a93b99d58f31485621c634b04983ae01d95 + '@prisma/get-platform': 5.21.0 '@prisma/generator-helper@5.14.0': dependencies: '@prisma/debug': 5.14.0 - '@prisma/generator-helper@5.20.0': + '@prisma/generator-helper@5.21.0': dependencies: - '@prisma/debug': 5.20.0 + '@prisma/debug': 5.21.0 '@prisma/get-platform@5.14.0': dependencies: @@ -10669,9 +10679,9 @@ snapshots: dependencies: '@prisma/debug': 5.16.1 - '@prisma/get-platform@5.20.0': + '@prisma/get-platform@5.21.0': dependencies: - '@prisma/debug': 5.20.0 + '@prisma/debug': 5.21.0 '@prisma/internals@5.14.0': dependencies: @@ -10685,15 +10695,15 @@ snapshots: arg: 5.0.2 prompts: 2.4.2 - '@prisma/internals@5.20.0': + '@prisma/internals@5.21.0': dependencies: - '@prisma/debug': 5.20.0 - '@prisma/engines': 5.20.0 - '@prisma/fetch-engine': 5.20.0 - '@prisma/generator-helper': 5.20.0 - '@prisma/get-platform': 5.20.0 - '@prisma/prisma-schema-wasm': 5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284 - '@prisma/schema-files-loader': 5.20.0 + '@prisma/debug': 5.21.0 + '@prisma/engines': 5.21.0 + '@prisma/fetch-engine': 5.21.0 + '@prisma/generator-helper': 5.21.0 + '@prisma/get-platform': 5.21.0 + '@prisma/prisma-schema-wasm': 5.21.0-36.08713a93b99d58f31485621c634b04983ae01d95 + '@prisma/schema-files-loader': 5.21.0 arg: 5.0.2 prompts: 2.4.2 @@ -10701,16 +10711,16 @@ snapshots: '@prisma/prisma-schema-wasm@5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48': {} - '@prisma/prisma-schema-wasm@5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284': {} + '@prisma/prisma-schema-wasm@5.21.0-36.08713a93b99d58f31485621c634b04983ae01d95': {} '@prisma/schema-files-loader@5.14.0': dependencies: '@prisma/prisma-schema-wasm': 5.14.0-17.56ca112d5a19c9925b53af75c3c6b7ada97f9f85 fs-extra: 11.1.1 - '@prisma/schema-files-loader@5.20.0': + '@prisma/schema-files-loader@5.21.0': dependencies: - '@prisma/prisma-schema-wasm': 5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284 + '@prisma/prisma-schema-wasm': 5.21.0-36.08713a93b99d58f31485621c634b04983ae01d95 fs-extra: 11.1.1 '@protobufjs/aspromise@1.1.2': {} @@ -11068,6 +11078,8 @@ snapshots: '@tanstack/query-core@5.48.0': {} + '@tanstack/query-core@5.56.2': {} + '@tanstack/react-query@4.36.1(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': dependencies: '@tanstack/query-core': 4.36.1 @@ -11076,9 +11088,9 @@ snapshots: optionalDependencies: react-dom: 18.3.1(react@18.2.0) - '@tanstack/react-query@5.48.0(react@18.2.0)': + '@tanstack/react-query@5.56.2(react@18.2.0)': dependencies: - '@tanstack/query-core': 5.48.0 + '@tanstack/query-core': 5.56.2 react: 18.2.0 '@tanstack/svelte-query@4.36.1(svelte@4.2.18)': @@ -11132,19 +11144,19 @@ snapshots: dependencies: '@trpc/server': 10.45.2 - '@trpc/next@10.45.2(@tanstack/react-query@5.48.0(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@5.48.0(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.3.1(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.2.0))(react@18.2.0))(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': + '@trpc/next@10.45.2(@tanstack/react-query@5.56.2(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@5.56.2(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.3.1(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.2.0))(react@18.2.0))(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': dependencies: - '@tanstack/react-query': 5.48.0(react@18.2.0) + '@tanstack/react-query': 5.56.2(react@18.2.0) '@trpc/client': 10.45.2(@trpc/server@10.45.2) - '@trpc/react-query': 10.45.2(@tanstack/react-query@5.48.0(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@trpc/react-query': 10.45.2(@tanstack/react-query@5.56.2(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) '@trpc/server': 10.45.2 next: 14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.3.1(react@18.2.0) - '@trpc/react-query@10.45.2(@tanstack/react-query@5.48.0(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': + '@trpc/react-query@10.45.2(@tanstack/react-query@5.56.2(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': dependencies: - '@tanstack/react-query': 5.48.0(react@18.2.0) + '@tanstack/react-query': 5.56.2(react@18.2.0) '@trpc/client': 10.45.2(@trpc/server@10.45.2) '@trpc/server': 10.45.2 react: 18.2.0 @@ -13891,6 +13903,8 @@ snapshots: highlight.js@10.4.1: {} + hono@4.6.3: {} + hookable@5.5.3: {} hosted-git-info@4.1.0: diff --git a/script/test-scaffold.ts b/script/test-scaffold.ts index ae54ea33b..a4cf21968 100644 --- a/script/test-scaffold.ts +++ b/script/test-scaffold.ts @@ -19,6 +19,6 @@ function run(cmd: string) { } run('npm init -y'); -run('npm i --no-audit --no-fund typescript prisma@5.20.x @prisma/client@5.20.x zod decimal.js @types/node'); +run('npm i --no-audit --no-fund typescript prisma@5.21.x @prisma/client@5.21.x zod decimal.js @types/node'); console.log('Test scaffold setup complete.'); diff --git a/tests/integration/test-run/package.json b/tests/integration/test-run/package.json index c32307b31..fa113f1e8 100644 --- a/tests/integration/test-run/package.json +++ b/tests/integration/test-run/package.json @@ -10,9 +10,9 @@ "author": "", "license": "ISC", "dependencies": { - "@prisma/client": "5.20.x", + "@prisma/client": "5.21.x", "@zenstackhq/runtime": "file:../../../packages/runtime/dist", - "prisma": "5.20.x", + "prisma": "5.21.x", "react": "^18.2.0", "swr": "^1.3.0", "typescript": "^4.9.3", diff --git a/tests/integration/tests/cli/plugins.test.ts b/tests/integration/tests/cli/plugins.test.ts index 4bacf425c..8c04eb67e 100644 --- a/tests/integration/tests/cli/plugins.test.ts +++ b/tests/integration/tests/cli/plugins.test.ts @@ -73,9 +73,9 @@ describe('CLI Plugins Tests', () => { 'zod@3.21.1', 'react', 'swr', - '@tanstack/react-query@^5.0.0', + '@tanstack/react-query@5.56.x', '@trpc/server', - '@prisma/client@5.20.x', + '@prisma/client@5.21.x', `${path.join(__dirname, '../../../../.build/zenstackhq-language-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-sdk-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-runtime-' + ver + '.tgz')}`, @@ -85,7 +85,7 @@ describe('CLI Plugins Tests', () => { const devDepPkgs = [ 'typescript', '@types/react', - 'prisma@5.20.x', + 'prisma@5.21.x', `${path.join(__dirname, '../../../../.build/zenstack-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-tanstack-query-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-swr-' + ver + '.tgz')}`, diff --git a/tests/integration/tests/e2e/filter-function-coverage.test.ts b/tests/integration/tests/e2e/filter-function-coverage.test.ts index 13564095c..04724578b 100644 --- a/tests/integration/tests/e2e/filter-function-coverage.test.ts +++ b/tests/integration/tests/e2e/filter-function-coverage.test.ts @@ -36,6 +36,28 @@ describe('Filter Function Coverage Tests', () => { await expect(enhance({ id: 'user1', name: 'bac' }).foo.create({ data: {} })).toResolveTruthy(); }); + it('contains with auth()', async () => { + const { enhance } = await loadSchema( + ` + model User { + id String @id + name String + } + + model Foo { + id String @id @default(cuid()) + string String + @@allow('all', contains(string, auth().name)) + } + ` + ); + + await expect(enhance().foo.create({ data: { string: 'abc' } })).toBeRejectedByPolicy(); + const db = enhance({ id: '1', name: 'a' }); + await expect(db.foo.create({ data: { string: 'bcd' } })).toBeRejectedByPolicy(); + await expect(db.foo.create({ data: { string: 'bac' } })).toResolveTruthy(); + }); + it('startsWith field', async () => { const { enhance } = await loadSchema( ` diff --git a/tests/integration/tests/enhancements/with-delegate/plugin-interaction.test.ts b/tests/integration/tests/enhancements/with-delegate/plugin-interaction.test.ts index b0fb0d343..8247c2e45 100644 --- a/tests/integration/tests/enhancements/with-delegate/plugin-interaction.test.ts +++ b/tests/integration/tests/enhancements/with-delegate/plugin-interaction.test.ts @@ -19,7 +19,7 @@ describe('Polymorphic Plugin Interaction Test', () => { await loadSchema(schema, { compile: true, copyDependencies: [tanstackPlugin], - extraDependencies: ['@tanstack/react-query'], + extraDependencies: ['@tanstack/react-query@5.56.x'], }); }); diff --git a/tests/integration/tests/enhancements/with-delegate/policy-interaction.test.ts b/tests/integration/tests/enhancements/with-delegate/policy-interaction.test.ts index ff791beb1..d149a6392 100644 --- a/tests/integration/tests/enhancements/with-delegate/policy-interaction.test.ts +++ b/tests/integration/tests/enhancements/with-delegate/policy-interaction.test.ts @@ -484,6 +484,53 @@ describe('Polymorphic Policy Test', () => { await expect(prisma.post.findUnique({ where: { id: post.id } })).toResolveFalsy(); }); + it('respects sub model policies when queried from a base: case 3', async () => { + const { enhance } = await loadSchema( + ` + model User { + id Int @id @default(autoincrement()) + assets Asset[] + @@allow('all', true) + } + + model Asset { + id Int @id @default(autoincrement()) + user User @relation(fields: [userId], references: [id]) + userId Int + value Int @default(0) + type String + @@delegate(type) + @@allow('all', value > 0) + } + + model Post extends Asset { + title String + deleted Boolean @default(false) + @@deny('read', deleted) + } + ` + ); + + const db = enhance(); + const user = await db.user.create({ data: { id: 1 } }); + + // can't create + await expect( + db.post.create({ data: { id: 1, title: 'Post1', userId: user.id, value: 0 } }) + ).toBeRejectedByPolicy(); + + // can't read back + await expect( + db.post.create({ data: { id: 1, title: 'Post1', userId: user.id, value: 1, deleted: true } }) + ).toBeRejectedByPolicy(); + + await expect( + db.post.create({ data: { id: 2, title: 'Post1', userId: user.id, value: 1, deleted: false } }) + ).toResolveTruthy(); + + await expect(db.asset.findMany()).resolves.toHaveLength(2); + }); + it('respects field-level policies', async () => { const { enhance } = await loadSchema(` model User { diff --git a/tests/integration/tests/frameworks/nextjs/test-project/package.json b/tests/integration/tests/frameworks/nextjs/test-project/package.json index 6f68beae0..8ead9a366 100644 --- a/tests/integration/tests/frameworks/nextjs/test-project/package.json +++ b/tests/integration/tests/frameworks/nextjs/test-project/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@prisma/client": "5.20.x", + "@prisma/client": "5.21.x", "@types/node": "18.11.18", "@types/react": "18.0.27", "@types/react-dom": "18.0.10", @@ -26,6 +26,6 @@ "@zenstackhq/swr": "../../../../../../../packages/plugins/swr/dist" }, "devDependencies": { - "prisma": "5.20.x" + "prisma": "5.21.x" } } diff --git a/tests/integration/tests/frameworks/trpc/test-project/package.json b/tests/integration/tests/frameworks/trpc/test-project/package.json index 3ba6a5023..a23a84e24 100644 --- a/tests/integration/tests/frameworks/trpc/test-project/package.json +++ b/tests/integration/tests/frameworks/trpc/test-project/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@prisma/client": "5.20.x", + "@prisma/client": "5.21.x", "@tanstack/react-query": "^4.22.4", "@trpc/client": "^10.34.0", "@trpc/next": "^10.34.0", @@ -31,6 +31,6 @@ "@zenstackhq/trpc": "../../../../../../../packages/plugins/trpc/dist" }, "devDependencies": { - "prisma": "5.20.x" + "prisma": "5.21.x" } } diff --git a/tests/regression/tests/issue-1743.test.ts b/tests/regression/tests/issue-1743.test.ts new file mode 100644 index 000000000..1c379ae44 --- /dev/null +++ b/tests/regression/tests/issue-1743.test.ts @@ -0,0 +1,34 @@ +import { loadSchema } from '@zenstackhq/testtools'; +describe('issue 1743', () => { + it('regression', async () => { + await loadSchema( + ` + generator client { + provider = "prisma-client-js" + output = '../lib/zenstack/prisma' + } + + datasource db { + provider = "sqlite" + url = "file:./dev.db" + } + + plugin enhancer { + provider = '@core/enhancer' + output = './lib/zenstack' + compile = false + } + + model User { + id Int @id + } + `, + { + addPrelude: false, + compile: true, + output: './lib/zenstack', + prismaLoadPath: './lib/zenstack/prisma', + } + ); + }); +}); diff --git a/tests/regression/tests/issue-1745.test.ts b/tests/regression/tests/issue-1745.test.ts new file mode 100644 index 000000000..ece70d6ee --- /dev/null +++ b/tests/regression/tests/issue-1745.test.ts @@ -0,0 +1,98 @@ +import { createPostgresDb, dropPostgresDb, loadSchema } from '@zenstackhq/testtools'; + +describe('issue 1745', () => { + it('regression', async () => { + const dbUrl = await createPostgresDb('issue-1745'); + + try { + await loadSchema( + ` + enum BuyerType { + STORE + RESTAURANT + WHOLESALER + } + + enum ChainStore { + ALL + CHAINSTORE_1 + CHAINSTORE_2 + CHAINSTORE_3 + } + + abstract model Id { + id String @id @default(cuid()) + } + + abstract model Base extends Id { + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + } + + model Ad extends Base { + serial Int @unique @default(autoincrement()) + buyerTypes BuyerType[] + chainStores ChainStore[] + listPrice Float + isSold Boolean @default(false) + + supplier Supplier @relation(fields: [supplierId], references: [id]) + supplierId String @default(auth().companyId) + + @@allow('all', auth().company.companyType == 'Buyer' && has(buyerTypes, auth().company.buyerType)) + @@allow('all', auth().company.companyType == 'Supplier' && auth().companyId == supplierId) + @@allow('all', auth().isAdmin) + } + + model Company extends Base { + name String @unique + organizationNumber String @unique + users User[] + buyerType BuyerType + + companyType String + @@delegate(companyType) + + @@allow('read, update', auth().companyId == id) + @@allow('all', auth().isAdmin) + } + + model Buyer extends Company { + storeName String + type String + chainStore ChainStore @default(ALL) + + @@allow('read, update', auth().company.companyType == 'Buyer' && auth().companyId == id) + @@allow('all', auth().isAdmin) + } + + model Supplier extends Company { + ads Ad[] + + @@allow('all', auth().company.companyType == 'Supplier' && auth().companyId == id) + @@allow('all', auth().isAdmin) + } + + model User extends Base { + firstName String + lastName String + email String @unique + username String @unique + password String @password @omit + isAdmin Boolean @default(false) + + company Company? @relation(fields: [companyId], references: [id]) + companyId String? + + @@allow('read', auth().id == id) + @@allow('read', auth().companyId == companyId) + @@allow('all', auth().isAdmin) + } + `, + { provider: 'postgresql', dbUrl, pushDb: false } + ); + } finally { + dropPostgresDb('issue-1745'); + } + }); +}); diff --git a/tests/regression/tests/issue-1758.test.ts b/tests/regression/tests/issue-1758.test.ts new file mode 100644 index 000000000..f07428e8e --- /dev/null +++ b/tests/regression/tests/issue-1758.test.ts @@ -0,0 +1,29 @@ +import { loadModelWithError } from '@zenstackhq/testtools'; + +describe('issue 1758', () => { + it('regression', async () => { + await expect( + loadModelWithError( + ` + model Organization { + id String @id @default(cuid()) + contents Content[] @relation("OrganizationContents") + } + + model Content { + id String @id @default(cuid()) + contentType String + organization Organization @relation("OrganizationContents", fields: [organizationId], references: [id]) + organizationId String + @@delegate(contentType) + } + + model Store extends Content { + name String + @@unique([organizationId, name]) + } + ` + ) + ).resolves.toContain('Cannot use fields inherited from a polymorphic base model in `@@unique`'); + }); +}); diff --git a/tests/regression/tests/issue-1770.test.ts b/tests/regression/tests/issue-1770.test.ts new file mode 100644 index 000000000..03af5cd19 --- /dev/null +++ b/tests/regression/tests/issue-1770.test.ts @@ -0,0 +1,49 @@ +import { loadSchema } from '@zenstackhq/testtools'; + +describe('issue 1770', () => { + it('regression', async () => { + const { enhance } = await loadSchema( + ` + model User { + id String @id @default(cuid()) + orgs OrgUser[] + } + + model OrgUser { + id String @id @default(cuid()) + user User @relation(fields: [userId], references: [id]) + userId String + org Organization @relation(fields: [orgId], references: [id]) + orgId String + } + + model Organization { + id String @id @default(uuid()) + users OrgUser[] + resources Resource[] @relation("organization") + } + + abstract model BaseAuth { + id String @id @default(uuid()) + organizationId String? + organization Organization? @relation(fields: [organizationId], references: [id], name: "organization") + + @@allow('all', organization.users?[user == auth()]) + } + + model Resource extends BaseAuth { + name String? + type String? + + @@delegate(type) + } + + model Personnel extends Resource { + } + ` + ); + + const db = enhance(); + await expect(db.resource.findMany()).toResolveTruthy(); + }); +});