refactor(schema): reorganize IndexField and related types (#22439)
## Summary
Querying `indexMetadatas { indexFieldMetadatas { ... } }` on the
`/metadata` GraphQL endpoint fails with a 500:
> Nest could not find IndexFieldMetadataDTOAuthorizer element (this
provider does not
> exist in the current context)
The `@CursorConnection('indexFieldMetadatas', ...)` decorator on
`IndexMetadataDTO` makes nestjs-query auto-generate a relation resolver
that injects an authorizer for `IndexFieldMetadataDTO`. That authorizer
is never provided, because the DTO was never registered as a resolver in
`IndexMetadataModule` — so the field has been broken since it was
introduced in #7162.
Since the working, DataLoader-backed `indexFieldMetadataList` field
already exposes the same data (and is what the frontend uses), this PR
removes the dead connection instead of wiring up the authorizer.
## Changes
- Remove `@CursorConnection('indexFieldMetadatas', ...)` from
`IndexMetadataDTO`
- Regenerate frontend metadata GraphQL types
(`twenty-front/src/generated-metadata`)
- Regenerate client SDK metadata schema/types
(`twenty-client-sdk/src/metadata/generated`)
## Notes
- Not a breaking change in practice: the removed field always threw, so
no consumer can have been relying on it. Callers now get a standard
GraphQL validation error suggesting `indexFieldMetadataList` instead of
an internal server error.
- Verified locally: the failing query now returns `Cannot query field
"indexFieldMetadatas" on type "Index". Did you mean
"indexFieldMetadataList"?` and `indexFieldMetadataList` continues to
work.
Fixes [sonarly issue #54098](https://sonarly.com/issue/54098?type=bug)
<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22439?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
@@ -529,15 +529,6 @@ enum FieldMetadataType {
|
||||
UUID
|
||||
}
|
||||
|
||||
type IndexField {
|
||||
id: UUID!
|
||||
fieldMetadataId: UUID!
|
||||
order: Float!
|
||||
subFieldName: String
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
}
|
||||
|
||||
type Index {
|
||||
id: UUID!
|
||||
name: String!
|
||||
@@ -555,13 +546,6 @@ type Index {
|
||||
"""Specify to filter the records returned."""
|
||||
filter: ObjectFilter! = {}
|
||||
): IndexObjectMetadataConnection!
|
||||
indexFieldMetadatas(
|
||||
"""Limit or page results."""
|
||||
paging: CursorPaging! = {first: 10}
|
||||
|
||||
"""Specify to filter the records returned."""
|
||||
filter: IndexFieldFilter! = {}
|
||||
): IndexIndexFieldMetadatasConnection!
|
||||
}
|
||||
|
||||
"""Type of the index"""
|
||||
@@ -622,13 +606,6 @@ input BooleanFieldComparison {
|
||||
isNot: Boolean
|
||||
}
|
||||
|
||||
input IndexFieldFilter {
|
||||
and: [IndexFieldFilter!]
|
||||
or: [IndexFieldFilter!]
|
||||
id: UUIDFilterComparison
|
||||
fieldMetadataId: UUIDFilterComparison
|
||||
}
|
||||
|
||||
type ObjectStandardOverrides {
|
||||
labelSingular: String
|
||||
labelPlural: String
|
||||
@@ -2021,6 +1998,15 @@ enum RelationType {
|
||||
MANY_TO_ONE
|
||||
}
|
||||
|
||||
type IndexField {
|
||||
id: UUID!
|
||||
fieldMetadataId: UUID!
|
||||
order: Float!
|
||||
subFieldName: String
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
}
|
||||
|
||||
type IndexEdge {
|
||||
"""The node containing the Index"""
|
||||
node: Index!
|
||||
@@ -2051,22 +2037,6 @@ type IndexConnection {
|
||||
edges: [IndexEdge!]!
|
||||
}
|
||||
|
||||
type IndexFieldEdge {
|
||||
"""The node containing the IndexField"""
|
||||
node: IndexField!
|
||||
|
||||
"""Cursor for this node."""
|
||||
cursor: ConnectionCursor!
|
||||
}
|
||||
|
||||
type IndexIndexFieldMetadatasConnection {
|
||||
"""Paging information"""
|
||||
pageInfo: PageInfo!
|
||||
|
||||
"""Array of edges."""
|
||||
edges: [IndexFieldEdge!]!
|
||||
}
|
||||
|
||||
type ObjectEdge {
|
||||
"""The node containing the Object"""
|
||||
node: Object!
|
||||
|
||||
@@ -387,16 +387,6 @@ export interface Field {
|
||||
/** Type of the field */
|
||||
export type FieldMetadataType = 'ACTOR' | 'ADDRESS' | 'ARRAY' | 'BOOLEAN' | 'CURRENCY' | 'DATE' | 'DATE_TIME' | 'EMAILS' | 'FILES' | 'FULL_NAME' | 'LINKS' | 'MORPH_RELATION' | 'MULTI_SELECT' | 'NUMBER' | 'NUMERIC' | 'PHONES' | 'POSITION' | 'RATING' | 'RAW_JSON' | 'RELATION' | 'RICH_TEXT' | 'SELECT' | 'TEXT' | 'TS_VECTOR' | 'UUID'
|
||||
|
||||
export interface IndexField {
|
||||
id: Scalars['UUID']
|
||||
fieldMetadataId: Scalars['UUID']
|
||||
order: Scalars['Float']
|
||||
subFieldName?: Scalars['String']
|
||||
createdAt: Scalars['DateTime']
|
||||
updatedAt: Scalars['DateTime']
|
||||
__typename: 'IndexField'
|
||||
}
|
||||
|
||||
export interface Index {
|
||||
id: Scalars['UUID']
|
||||
name: Scalars['String']
|
||||
@@ -408,7 +398,6 @@ export interface Index {
|
||||
updatedAt: Scalars['DateTime']
|
||||
indexFieldMetadataList: IndexField[]
|
||||
objectMetadata: IndexObjectMetadataConnection
|
||||
indexFieldMetadatas: IndexIndexFieldMetadatasConnection
|
||||
__typename: 'Index'
|
||||
}
|
||||
|
||||
@@ -1655,6 +1644,16 @@ export interface Relation {
|
||||
/** Relation type */
|
||||
export type RelationType = 'ONE_TO_MANY' | 'MANY_TO_ONE'
|
||||
|
||||
export interface IndexField {
|
||||
id: Scalars['UUID']
|
||||
fieldMetadataId: Scalars['UUID']
|
||||
order: Scalars['Float']
|
||||
subFieldName?: Scalars['String']
|
||||
createdAt: Scalars['DateTime']
|
||||
updatedAt: Scalars['DateTime']
|
||||
__typename: 'IndexField'
|
||||
}
|
||||
|
||||
export interface IndexEdge {
|
||||
/** The node containing the Index */
|
||||
node: Index
|
||||
@@ -1683,22 +1682,6 @@ export interface IndexConnection {
|
||||
__typename: 'IndexConnection'
|
||||
}
|
||||
|
||||
export interface IndexFieldEdge {
|
||||
/** The node containing the IndexField */
|
||||
node: IndexField
|
||||
/** Cursor for this node. */
|
||||
cursor: Scalars['ConnectionCursor']
|
||||
__typename: 'IndexFieldEdge'
|
||||
}
|
||||
|
||||
export interface IndexIndexFieldMetadatasConnection {
|
||||
/** Paging information */
|
||||
pageInfo: PageInfo
|
||||
/** Array of edges. */
|
||||
edges: IndexFieldEdge[]
|
||||
__typename: 'IndexIndexFieldMetadatasConnection'
|
||||
}
|
||||
|
||||
export interface ObjectEdge {
|
||||
/** The node containing the Object */
|
||||
node: Object
|
||||
@@ -3408,17 +3391,6 @@ export interface FieldGenqlSelection{
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface IndexFieldGenqlSelection{
|
||||
id?: boolean | number
|
||||
fieldMetadataId?: boolean | number
|
||||
order?: boolean | number
|
||||
subFieldName?: boolean | number
|
||||
createdAt?: boolean | number
|
||||
updatedAt?: boolean | number
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface IndexGenqlSelection{
|
||||
id?: boolean | number
|
||||
name?: boolean | number
|
||||
@@ -3434,11 +3406,6 @@ export interface IndexGenqlSelection{
|
||||
paging: CursorPaging,
|
||||
/** Specify to filter the records returned. */
|
||||
filter: ObjectFilter} })
|
||||
indexFieldMetadatas?: (IndexIndexFieldMetadatasConnectionGenqlSelection & { __args: {
|
||||
/** Limit or page results. */
|
||||
paging: CursorPaging,
|
||||
/** Specify to filter the records returned. */
|
||||
filter: IndexFieldFilter} })
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
@@ -3459,8 +3426,6 @@ export interface UUIDFilterComparison {is?: (Scalars['Boolean'] | null),isNot?:
|
||||
|
||||
export interface BooleanFieldComparison {is?: (Scalars['Boolean'] | null),isNot?: (Scalars['Boolean'] | null)}
|
||||
|
||||
export interface IndexFieldFilter {and?: (IndexFieldFilter[] | null),or?: (IndexFieldFilter[] | null),id?: (UUIDFilterComparison | null),fieldMetadataId?: (UUIDFilterComparison | null)}
|
||||
|
||||
export interface ObjectStandardOverridesGenqlSelection{
|
||||
labelSingular?: boolean | number
|
||||
labelPlural?: boolean | number
|
||||
@@ -4744,6 +4709,17 @@ export interface RelationGenqlSelection{
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface IndexFieldGenqlSelection{
|
||||
id?: boolean | number
|
||||
fieldMetadataId?: boolean | number
|
||||
order?: boolean | number
|
||||
subFieldName?: boolean | number
|
||||
createdAt?: boolean | number
|
||||
updatedAt?: boolean | number
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface IndexEdgeGenqlSelection{
|
||||
/** The node containing the Index */
|
||||
node?: IndexGenqlSelection
|
||||
@@ -4775,24 +4751,6 @@ export interface IndexConnectionGenqlSelection{
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface IndexFieldEdgeGenqlSelection{
|
||||
/** The node containing the IndexField */
|
||||
node?: IndexFieldGenqlSelection
|
||||
/** Cursor for this node. */
|
||||
cursor?: boolean | number
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface IndexIndexFieldMetadatasConnectionGenqlSelection{
|
||||
/** Paging information */
|
||||
pageInfo?: PageInfoGenqlSelection
|
||||
/** Array of edges. */
|
||||
edges?: IndexFieldEdgeGenqlSelection
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface ObjectEdgeGenqlSelection{
|
||||
/** The node containing the Object */
|
||||
node?: ObjectGenqlSelection
|
||||
@@ -6848,14 +6806,6 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
|
||||
|
||||
|
||||
|
||||
const IndexField_possibleTypes: string[] = ['IndexField']
|
||||
export const isIndexField = (obj?: { __typename?: any } | null): obj is IndexField => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isIndexField"')
|
||||
return IndexField_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const Index_possibleTypes: string[] = ['Index']
|
||||
export const isIndex = (obj?: { __typename?: any } | null): obj is Index => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isIndex"')
|
||||
@@ -7736,6 +7686,14 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
|
||||
|
||||
|
||||
|
||||
const IndexField_possibleTypes: string[] = ['IndexField']
|
||||
export const isIndexField = (obj?: { __typename?: any } | null): obj is IndexField => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isIndexField"')
|
||||
return IndexField_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const IndexEdge_possibleTypes: string[] = ['IndexEdge']
|
||||
export const isIndexEdge = (obj?: { __typename?: any } | null): obj is IndexEdge => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isIndexEdge"')
|
||||
@@ -7760,22 +7718,6 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
|
||||
|
||||
|
||||
|
||||
const IndexFieldEdge_possibleTypes: string[] = ['IndexFieldEdge']
|
||||
export const isIndexFieldEdge = (obj?: { __typename?: any } | null): obj is IndexFieldEdge => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isIndexFieldEdge"')
|
||||
return IndexFieldEdge_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const IndexIndexFieldMetadatasConnection_possibleTypes: string[] = ['IndexIndexFieldMetadatasConnection']
|
||||
export const isIndexIndexFieldMetadatasConnection = (obj?: { __typename?: any } | null): obj is IndexIndexFieldMetadatasConnection => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isIndexIndexFieldMetadatasConnection"')
|
||||
return IndexIndexFieldMetadatasConnection_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const ObjectEdge_possibleTypes: string[] = ['ObjectEdge']
|
||||
export const isObjectEdge = (obj?: { __typename?: any } | null): obj is ObjectEdge => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isObjectEdge"')
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2050,7 +2050,6 @@ export type Index = {
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
id: Scalars['UUID']['output'];
|
||||
indexFieldMetadataList: Array<IndexField>;
|
||||
indexFieldMetadatas: IndexIndexFieldMetadatasConnection;
|
||||
indexType: IndexType;
|
||||
indexWhereClause?: Maybe<Scalars['String']['output']>;
|
||||
isCustom?: Maybe<Scalars['Boolean']['output']>;
|
||||
@@ -2061,12 +2060,6 @@ export type Index = {
|
||||
};
|
||||
|
||||
|
||||
export type IndexIndexFieldMetadatasArgs = {
|
||||
filter?: IndexFieldFilter;
|
||||
paging?: CursorPaging;
|
||||
};
|
||||
|
||||
|
||||
export type IndexObjectMetadataArgs = {
|
||||
filter?: ObjectFilter;
|
||||
paging?: CursorPaging;
|
||||
@@ -2098,21 +2091,6 @@ export type IndexField = {
|
||||
updatedAt: Scalars['DateTime']['output'];
|
||||
};
|
||||
|
||||
export type IndexFieldEdge = {
|
||||
__typename?: 'IndexFieldEdge';
|
||||
/** Cursor for this node. */
|
||||
cursor: Scalars['ConnectionCursor']['output'];
|
||||
/** The node containing the IndexField */
|
||||
node: IndexField;
|
||||
};
|
||||
|
||||
export type IndexFieldFilter = {
|
||||
and?: InputMaybe<Array<IndexFieldFilter>>;
|
||||
fieldMetadataId?: InputMaybe<UuidFilterComparison>;
|
||||
id?: InputMaybe<UuidFilterComparison>;
|
||||
or?: InputMaybe<Array<IndexFieldFilter>>;
|
||||
};
|
||||
|
||||
export type IndexFilter = {
|
||||
and?: InputMaybe<Array<IndexFilter>>;
|
||||
id?: InputMaybe<UuidFilterComparison>;
|
||||
@@ -2120,14 +2098,6 @@ export type IndexFilter = {
|
||||
or?: InputMaybe<Array<IndexFilter>>;
|
||||
};
|
||||
|
||||
export type IndexIndexFieldMetadatasConnection = {
|
||||
__typename?: 'IndexIndexFieldMetadatasConnection';
|
||||
/** Array of edges. */
|
||||
edges: Array<IndexFieldEdge>;
|
||||
/** Paging information */
|
||||
pageInfo: PageInfo;
|
||||
};
|
||||
|
||||
export type IndexObjectMetadataConnection = {
|
||||
__typename?: 'IndexObjectMetadataConnection';
|
||||
/** Array of edges. */
|
||||
|
||||
-2
@@ -24,7 +24,6 @@ import {
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { IsValidMetadataName } from 'src/engine/decorators/metadata/is-valid-metadata-name.decorator';
|
||||
import { IndexFieldMetadataDTO } from 'src/engine/metadata-modules/index-metadata/dtos/index-field-metadata.dto';
|
||||
import { IndexType } from 'src/engine/metadata-modules/index-metadata/types/indexType.types';
|
||||
import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto';
|
||||
|
||||
@@ -46,7 +45,6 @@ registerEnumType(IndexType, {
|
||||
maxResultsSize: 1000,
|
||||
})
|
||||
@CursorConnection('objectMetadata', () => ObjectMetadataDTO)
|
||||
@CursorConnection('indexFieldMetadatas', () => IndexFieldMetadataDTO)
|
||||
export class IndexMetadataDTO {
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
|
||||
Reference in New Issue
Block a user