@commitspark/graphql-api 1.0.0-beta.7 → 1.0.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +75 -28
  3. package/dist/cjs/graphql/errors.d.ts +0 -1
  4. package/dist/cjs/graphql/errors.js.map +1 -1
  5. package/dist/cjs/graphql/queries-mutations-generator.d.ts +10 -10
  6. package/dist/cjs/graphql/queries-mutations-generator.js.map +1 -1
  7. package/dist/cjs/graphql/resolvers/field-resolvers/entry-reference-resolver.d.ts +1 -1
  8. package/dist/cjs/graphql/resolvers/field-resolvers/entry-reference-resolver.js +8 -0
  9. package/dist/cjs/graphql/resolvers/field-resolvers/entry-reference-resolver.js.map +1 -1
  10. package/dist/cjs/graphql/resolvers/field-resolvers/field-default-value-resolver.d.ts +1 -1
  11. package/dist/cjs/graphql/resolvers/field-resolvers/field-default-value-resolver.js +1 -1
  12. package/dist/cjs/graphql/resolvers/field-resolvers/field-default-value-resolver.js.map +1 -1
  13. package/dist/cjs/graphql/resolvers/field-resolvers/types.d.ts +5 -3
  14. package/dist/cjs/graphql/resolvers/field-resolvers/union-value-resolver.d.ts +1 -1
  15. package/dist/cjs/graphql/resolvers/field-resolvers/union-value-resolver.js.map +1 -1
  16. package/dist/cjs/graphql/resolvers/object-type-field-default-value-resolver-generator.d.ts +4 -6
  17. package/dist/cjs/graphql/resolvers/object-type-field-default-value-resolver-generator.js +24 -7
  18. package/dist/cjs/graphql/resolvers/object-type-field-default-value-resolver-generator.js.map +1 -1
  19. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.d.ts +2 -3
  20. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.js +3 -3
  21. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.js.map +1 -1
  22. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.d.ts +2 -4
  23. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.js +2 -2
  24. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.js.map +1 -1
  25. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.d.ts +2 -3
  26. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.js +7 -6
  27. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.js.map +1 -1
  28. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.d.ts +2 -3
  29. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.js +1 -1
  30. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.js.map +1 -1
  31. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-every-resolver.d.ts +2 -3
  32. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-every-resolver.js +1 -1
  33. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-every-resolver.js.map +1 -1
  34. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.d.ts +2 -3
  35. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.js.map +1 -1
  36. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/union-type-resolver.d.ts +2 -3
  37. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/union-type-resolver.js +10 -3
  38. package/dist/cjs/graphql/resolvers/query-mutation-resolvers/union-type-resolver.js.map +1 -1
  39. package/dist/cjs/graphql/resolvers/types.d.ts +15 -2
  40. package/dist/cjs/graphql/schema-generator.js +0 -7
  41. package/dist/cjs/graphql/schema-generator.js.map +1 -1
  42. package/dist/cjs/graphql/schema-root-type-generator.d.ts +1 -1
  43. package/dist/cjs/graphql/schema-root-type-generator.js.map +1 -1
  44. package/dist/cjs/graphql/schema-utils/entry-reference-util.d.ts +2 -1
  45. package/dist/cjs/graphql/schema-utils/entry-reference-util.js +60 -11
  46. package/dist/cjs/graphql/schema-utils/entry-reference-util.js.map +1 -1
  47. package/dist/cjs/graphql/util.d.ts +1 -0
  48. package/dist/cjs/graphql/util.js +13 -0
  49. package/dist/cjs/graphql/util.js.map +1 -0
  50. package/dist/esm/graphql/errors.js.map +1 -1
  51. package/dist/esm/graphql/queries-mutations-generator.js.map +1 -1
  52. package/dist/esm/graphql/resolvers/field-resolvers/entry-reference-resolver.js +8 -0
  53. package/dist/esm/graphql/resolvers/field-resolvers/entry-reference-resolver.js.map +1 -1
  54. package/dist/esm/graphql/resolvers/field-resolvers/field-default-value-resolver.js +1 -1
  55. package/dist/esm/graphql/resolvers/field-resolvers/field-default-value-resolver.js.map +1 -1
  56. package/dist/esm/graphql/resolvers/field-resolvers/union-value-resolver.js.map +1 -1
  57. package/dist/esm/graphql/resolvers/object-type-field-default-value-resolver-generator.js +24 -7
  58. package/dist/esm/graphql/resolvers/object-type-field-default-value-resolver-generator.js.map +1 -1
  59. package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.js +3 -3
  60. package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.js.map +1 -1
  61. package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.js +2 -2
  62. package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.js.map +1 -1
  63. package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.js +7 -6
  64. package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.js.map +1 -1
  65. package/dist/esm/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.js +1 -1
  66. package/dist/esm/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.js.map +1 -1
  67. package/dist/esm/graphql/resolvers/query-mutation-resolvers/query-every-resolver.js +1 -1
  68. package/dist/esm/graphql/resolvers/query-mutation-resolvers/query-every-resolver.js.map +1 -1
  69. package/dist/esm/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.js.map +1 -1
  70. package/dist/esm/graphql/resolvers/query-mutation-resolvers/union-type-resolver.js +10 -3
  71. package/dist/esm/graphql/resolvers/query-mutation-resolvers/union-type-resolver.js.map +1 -1
  72. package/dist/esm/graphql/schema-generator.js +0 -7
  73. package/dist/esm/graphql/schema-generator.js.map +1 -1
  74. package/dist/esm/graphql/schema-root-type-generator.js.map +1 -1
  75. package/dist/esm/graphql/schema-utils/entry-reference-util.js +61 -12
  76. package/dist/esm/graphql/schema-utils/entry-reference-util.js.map +1 -1
  77. package/dist/esm/graphql/util.js +10 -0
  78. package/dist/esm/graphql/util.js.map +1 -0
  79. package/dist/types/graphql/errors.d.ts +0 -1
  80. package/dist/types/graphql/errors.d.ts.map +1 -1
  81. package/dist/types/graphql/queries-mutations-generator.d.ts +10 -10
  82. package/dist/types/graphql/queries-mutations-generator.d.ts.map +1 -1
  83. package/dist/types/graphql/resolvers/field-resolvers/entry-reference-resolver.d.ts +1 -1
  84. package/dist/types/graphql/resolvers/field-resolvers/entry-reference-resolver.d.ts.map +1 -1
  85. package/dist/types/graphql/resolvers/field-resolvers/field-default-value-resolver.d.ts +1 -1
  86. package/dist/types/graphql/resolvers/field-resolvers/field-default-value-resolver.d.ts.map +1 -1
  87. package/dist/types/graphql/resolvers/field-resolvers/types.d.ts +5 -3
  88. package/dist/types/graphql/resolvers/field-resolvers/types.d.ts.map +1 -1
  89. package/dist/types/graphql/resolvers/field-resolvers/union-value-resolver.d.ts +1 -1
  90. package/dist/types/graphql/resolvers/field-resolvers/union-value-resolver.d.ts.map +1 -1
  91. package/dist/types/graphql/resolvers/object-type-field-default-value-resolver-generator.d.ts +4 -6
  92. package/dist/types/graphql/resolvers/object-type-field-default-value-resolver-generator.d.ts.map +1 -1
  93. package/dist/types/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.d.ts +2 -3
  94. package/dist/types/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.d.ts.map +1 -1
  95. package/dist/types/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.d.ts +2 -4
  96. package/dist/types/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.d.ts.map +1 -1
  97. package/dist/types/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.d.ts +2 -3
  98. package/dist/types/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.d.ts.map +1 -1
  99. package/dist/types/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.d.ts +2 -3
  100. package/dist/types/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.d.ts.map +1 -1
  101. package/dist/types/graphql/resolvers/query-mutation-resolvers/query-every-resolver.d.ts +2 -3
  102. package/dist/types/graphql/resolvers/query-mutation-resolvers/query-every-resolver.d.ts.map +1 -1
  103. package/dist/types/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.d.ts +2 -3
  104. package/dist/types/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.d.ts.map +1 -1
  105. package/dist/types/graphql/resolvers/query-mutation-resolvers/union-type-resolver.d.ts +2 -3
  106. package/dist/types/graphql/resolvers/query-mutation-resolvers/union-type-resolver.d.ts.map +1 -1
  107. package/dist/types/graphql/resolvers/types.d.ts +15 -2
  108. package/dist/types/graphql/resolvers/types.d.ts.map +1 -1
  109. package/dist/types/graphql/schema-generator.d.ts.map +1 -1
  110. package/dist/types/graphql/schema-root-type-generator.d.ts +1 -1
  111. package/dist/types/graphql/schema-root-type-generator.d.ts.map +1 -1
  112. package/dist/types/graphql/schema-utils/entry-reference-util.d.ts +2 -1
  113. package/dist/types/graphql/schema-utils/entry-reference-util.d.ts.map +1 -1
  114. package/dist/types/graphql/util.d.ts +2 -0
  115. package/dist/types/graphql/util.d.ts.map +1 -0
  116. package/package.json +2 -2
  117. package/src/graphql/errors.ts +0 -1
  118. package/src/graphql/queries-mutations-generator.ts +16 -17
  119. package/src/graphql/resolvers/field-resolvers/entry-reference-resolver.ts +22 -7
  120. package/src/graphql/resolvers/field-resolvers/field-default-value-resolver.ts +8 -10
  121. package/src/graphql/resolvers/field-resolvers/types.ts +7 -5
  122. package/src/graphql/resolvers/field-resolvers/union-value-resolver.ts +2 -4
  123. package/src/graphql/resolvers/object-type-field-default-value-resolver-generator.ts +43 -26
  124. package/src/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.ts +11 -11
  125. package/src/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.ts +11 -11
  126. package/src/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.ts +15 -15
  127. package/src/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.ts +7 -8
  128. package/src/graphql/resolvers/query-mutation-resolvers/query-every-resolver.ts +7 -8
  129. package/src/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.ts +7 -8
  130. package/src/graphql/resolvers/query-mutation-resolvers/union-type-resolver.ts +20 -8
  131. package/src/graphql/resolvers/types.ts +27 -4
  132. package/src/graphql/schema-generator.ts +24 -31
  133. package/src/graphql/schema-root-type-generator.ts +5 -2
  134. package/src/graphql/schema-utils/entry-reference-util.ts +118 -19
  135. package/src/graphql/util.ts +11 -0
@@ -1,13 +1,36 @@
1
1
  import { ApolloContext } from '../../client.ts'
2
- import { GraphQLFieldResolver, GraphQLNamedType } from 'graphql'
2
+ import {
3
+ GraphQLFieldResolver,
4
+ GraphQLNamedType,
5
+ GraphQLTypeResolver,
6
+ } from 'graphql'
7
+ import { EntryData } from '@commitspark/git-adapter'
8
+ import { RecursiveArray } from './field-resolvers/types.ts'
3
9
 
4
10
  export interface QueryMutationResolverContext extends ApolloContext {
5
11
  type: GraphQLNamedType
6
12
  }
7
13
 
8
14
  export type QueryMutationResolver<ResultType> = GraphQLFieldResolver<
9
- any,
10
- ApolloContext,
11
- any,
15
+ unknown,
16
+ QueryMutationResolverContext,
17
+ { id: string; data?: EntryData; commitMessage: string },
12
18
  Promise<ResultType>
13
19
  >
20
+
21
+ export type UnionTypeResolver = GraphQLTypeResolver<
22
+ UnionTypeResolverSourceData,
23
+ ApolloContext
24
+ >
25
+
26
+ type UnionTypeResolverSourceData = EntryData & {
27
+ id?: string
28
+ __typename: string
29
+ }
30
+
31
+ export type ContextInjectionResolver = GraphQLFieldResolver<
32
+ EntryData,
33
+ ApolloContext,
34
+ Record<string, unknown>,
35
+ Promise<RecursiveArray<EntryData>>
36
+ >
@@ -16,11 +16,17 @@ import { generateSchemaRootTypeStrings } from './schema-root-type-generator.ts'
16
16
  import { printSchemaWithDirectives } from '@graphql-tools/utils'
17
17
  import { unionTypeResolver } from './resolvers/query-mutation-resolvers/union-type-resolver.ts'
18
18
  import { ApolloContext } from '../client.ts'
19
- import { GraphQLFieldResolver, GraphQLTypeResolver } from 'graphql'
19
+ import { GraphQLTypeResolver } from 'graphql'
20
20
  import { getValidationResult } from './schema-validator.ts'
21
- import { EntryData } from '@commitspark/git-adapter'
22
21
  import { createObjectTypeFieldResolvers } from './resolvers/object-type-field-default-value-resolver-generator.ts'
23
22
  import { createError, ErrorCode } from './errors.ts'
23
+ import { FieldResolver } from './resolvers/field-resolvers/types.ts'
24
+ import {
25
+ ContextInjectionResolver,
26
+ QueryMutationResolver,
27
+ UnionTypeResolver,
28
+ } from './resolvers/types.ts'
29
+ import { EntryData } from '@commitspark/git-adapter'
24
30
 
25
31
  export async function generateSchema(
26
32
  context: ApolloContext,
@@ -52,19 +58,6 @@ export async function generateSchema(
52
58
  )
53
59
  const generatedTypeNameQuery = generateTypeNameQuery()
54
60
 
55
- const generatedEntryReferenceResolvers: Record<
56
- string,
57
- Record<
58
- string,
59
- GraphQLFieldResolver<
60
- Record<string, any>,
61
- ApolloContext,
62
- any,
63
- Promise<EntryData | EntryData[] | null>
64
- >
65
- >
66
- > = {}
67
-
68
61
  const generatedObjectInputTypeStrings = generateObjectInputTypeStrings(
69
62
  schemaAnalyzerResult.objectTypes,
70
63
  )
@@ -85,7 +78,10 @@ export async function generateSchema(
85
78
 
86
79
  ${generatedSchemaRootTypeStrings}`
87
80
 
88
- const generatedUnionTypeResolvers: Record<string, UnionTypeResolver> = {}
81
+ const generatedUnionTypeResolvers: Record<
82
+ string,
83
+ { __resolveType: UnionTypeResolver }
84
+ > = {}
89
85
  for (const unionType of schemaAnalyzerResult.unionTypes) {
90
86
  generatedUnionTypeResolvers[unionType.name] = {
91
87
  __resolveType: unionTypeResolver,
@@ -96,11 +92,11 @@ ${generatedSchemaRootTypeStrings}`
96
92
 
97
93
  const generatedQueryResolvers: Record<
98
94
  string,
99
- GraphQLFieldResolver<any, ApolloContext>
95
+ QueryMutationResolver<EntryData | EntryData[] | string>
100
96
  > = {}
101
97
  const generatedMutationResolvers: Record<
102
98
  string,
103
- GraphQLFieldResolver<any, ApolloContext>
99
+ QueryMutationResolver<EntryData | EntryData[] | string>
104
100
  > = {}
105
101
 
106
102
  for (const element of generatedQueriesMutations) {
@@ -119,11 +115,14 @@ ${generatedSchemaRootTypeStrings}`
119
115
 
120
116
  const allGeneratedResolvers: Record<
121
117
  string,
122
- Record<
123
- string,
124
- | GraphQLFieldResolver<any, ApolloContext>
125
- | GraphQLTypeResolver<any, ApolloContext>
126
- >
118
+ | Record<
119
+ string,
120
+ | QueryMutationResolver<EntryData | EntryData[] | string>
121
+ | GraphQLTypeResolver<unknown, ApolloContext>
122
+ | ContextInjectionResolver
123
+ | FieldResolver
124
+ >
125
+ | UnionTypeResolverRecord
127
126
  > = {
128
127
  Query: generatedQueryResolvers,
129
128
  Mutation: generatedMutationResolvers,
@@ -141,12 +140,6 @@ ${generatedSchemaRootTypeStrings}`
141
140
  ...generatedObjectTypeFieldResolvers[typeName],
142
141
  }
143
142
  }
144
- for (const typeName of Object.keys(generatedEntryReferenceResolvers)) {
145
- allGeneratedResolvers[typeName] = {
146
- ...(allGeneratedResolvers[typeName] ?? {}),
147
- ...generatedEntryReferenceResolvers[typeName],
148
- }
149
- }
150
143
 
151
144
  const typeDefs = [
152
145
  filteredOriginalSchemaString,
@@ -162,6 +155,6 @@ ${generatedSchemaRootTypeStrings}`
162
155
  }
163
156
  }
164
157
 
165
- interface UnionTypeResolver {
166
- __resolveType: GraphQLTypeResolver<any, ApolloContext>
158
+ interface UnionTypeResolverRecord {
159
+ __resolveType: UnionTypeResolver
167
160
  }
@@ -1,8 +1,11 @@
1
- import { GeneratedQuery, GeneratedSchema } from './queries-mutations-generator.ts'
1
+ import {
2
+ GeneratedQuery,
3
+ GeneratedSchema,
4
+ } from './queries-mutations-generator.ts'
2
5
 
3
6
  export function generateSchemaRootTypeStrings(
4
7
  generatedSchemas: GeneratedSchema[],
5
- typeQuery: GeneratedQuery<Promise<string>>,
8
+ typeQuery: GeneratedQuery,
6
9
  ): string {
7
10
  return (
8
11
  `type Query {\n` +
@@ -1,9 +1,11 @@
1
1
  import {
2
2
  GraphQLNullableType,
3
3
  GraphQLObjectType,
4
+ GraphQLUnionType,
4
5
  isListType,
5
6
  isNonNullType,
6
7
  isObjectType,
8
+ isScalarType,
7
9
  isUnionType,
8
10
  } from 'graphql'
9
11
  import { ApolloContext } from '../../client.ts'
@@ -14,6 +16,8 @@ import {
14
16
  } from './union-type-util.ts'
15
17
  import { hasEntryDirective, isUnionOfEntryTypes } from './entry-type-util.ts'
16
18
  import { createError, ErrorCode } from '../errors.ts'
19
+ import { EntryData } from '@commitspark/git-adapter'
20
+ import { isRecord } from '../util.ts'
17
21
 
18
22
  function isPermittedReferenceType(
19
23
  referencedTypeName: string,
@@ -38,7 +42,7 @@ async function validateReference(
38
42
  context: ApolloContext,
39
43
  fieldName: string,
40
44
  fieldType: GraphQLNullableType,
41
- fieldValue: any,
45
+ fieldValue: EntryData,
42
46
  ): Promise<void> {
43
47
  if (isNonNullType(fieldType)) {
44
48
  await validateReference(context, fieldName, fieldType.ofType, fieldValue)
@@ -47,7 +51,7 @@ async function validateReference(
47
51
  if (!Array.isArray(fieldValue)) {
48
52
  throw createError(
49
53
  `Expected array while validation references for field "${fieldName}".`,
50
- ErrorCode.SCHEMA_DATA_MISMATCH,
54
+ ErrorCode.BAD_REPOSITORY_DATA,
51
55
  {
52
56
  fieldName: fieldName,
53
57
  fieldValue: fieldValue,
@@ -64,16 +68,21 @@ async function validateReference(
64
68
  }
65
69
  return
66
70
  } else if (isUnionType(fieldType) || isObjectType(fieldType)) {
67
- if (!('id' in fieldValue)) {
71
+ if (
72
+ fieldValue === null ||
73
+ !('id' in fieldValue) ||
74
+ typeof fieldValue.id !== 'string'
75
+ ) {
68
76
  throw createError(
69
- `Expected key "id" in data while validating reference for field "${fieldName}".`,
70
- ErrorCode.SCHEMA_DATA_MISMATCH,
77
+ `Expected key "id" with value of type string in data while validating reference for field "${fieldName}".`,
78
+ ErrorCode.BAD_REPOSITORY_DATA,
71
79
  {
72
80
  fieldName: fieldName,
73
81
  fieldValue: fieldValue,
74
82
  },
75
83
  )
76
84
  }
85
+
77
86
  const referencedId = fieldValue.id
78
87
  let referencedTypeName
79
88
  try {
@@ -106,8 +115,12 @@ export async function getReferencedEntryIds(
106
115
  context: ApolloContext,
107
116
  fieldName: string | null,
108
117
  type: GraphQLNullableType,
109
- data: any,
118
+ data: EntryData | EntryData[],
110
119
  ): Promise<string[]> {
120
+ if (data === null || isScalarType(type)) {
121
+ return []
122
+ }
123
+
111
124
  if (isNonNullType(type)) {
112
125
  return getReferencedEntryIds(
113
126
  rootType,
@@ -117,6 +130,17 @@ export async function getReferencedEntryIds(
117
130
  data,
118
131
  )
119
132
  } else if (isListType(type)) {
133
+ if (!Array.isArray(data)) {
134
+ throw createError(
135
+ `Expected array as data for field "${fieldName}". `,
136
+ ErrorCode.BAD_REPOSITORY_DATA,
137
+ {
138
+ fieldName: fieldName ? fieldName : undefined,
139
+ fieldValue: data,
140
+ },
141
+ )
142
+ }
143
+
120
144
  let referencedEntryIds: string[] = []
121
145
  for (const element of data) {
122
146
  referencedEntryIds = [
@@ -135,8 +159,13 @@ export async function getReferencedEntryIds(
135
159
  return referencedEntryIds
136
160
  } else if (isUnionType(type)) {
137
161
  if (isUnionOfEntryTypes(type)) {
138
- await validateReference(context, '', type, data)
139
- return [data.id]
162
+ const referenceId = await getValidatedReferenceId(
163
+ context,
164
+ fieldName,
165
+ type,
166
+ data,
167
+ )
168
+ return [referenceId]
140
169
  }
141
170
 
142
171
  const requestedUnionTypeName = getUnionTypeNameFromFieldValue(data)
@@ -168,22 +197,56 @@ export async function getReferencedEntryIds(
168
197
  )
169
198
  } else if (isObjectType(type)) {
170
199
  if (type.name !== rootType.name && hasEntryDirective(type)) {
171
- await validateReference(context, fieldName ?? '', type, data)
172
- return [data.id]
200
+ const referenceId = await getValidatedReferenceId(
201
+ context,
202
+ fieldName,
203
+ type,
204
+ data,
205
+ )
206
+ return [referenceId]
173
207
  } else {
174
208
  let referencedEntryIds: string[] = []
175
209
  for (const [fieldsKey, field] of Object.entries(type.getFields())) {
176
- const fieldValue = data[fieldsKey] ?? undefined
177
- if (fieldValue !== undefined) {
178
- const nestedResult = await getReferencedEntryIds(
179
- rootType,
180
- context,
181
- fieldsKey,
182
- field.type,
183
- fieldValue,
210
+ if (Array.isArray(data)) {
211
+ throw createError(
212
+ `Expected object as data for type "${type.name}".`,
213
+ ErrorCode.BAD_REPOSITORY_DATA,
214
+ {
215
+ typeName: type.name,
216
+ fieldName: field.name ? field.name : undefined,
217
+ },
184
218
  )
185
- referencedEntryIds = [...referencedEntryIds, ...nestedResult]
186
219
  }
220
+
221
+ const fieldValue = data[fieldsKey]
222
+ if (
223
+ fieldValue === undefined ||
224
+ fieldValue === null ||
225
+ isScalarType(field.type)
226
+ ) {
227
+ continue
228
+ }
229
+
230
+ if (!(Array.isArray(fieldValue) || isRecord(fieldValue))) {
231
+ throw createError(
232
+ `Expected object or array as data for field "${field.name}" of type "${type.name}".`,
233
+ ErrorCode.BAD_REPOSITORY_DATA,
234
+ {
235
+ typeName: type.name,
236
+ fieldName: field.name ? field.name : undefined,
237
+ fieldValue: fieldValue,
238
+ },
239
+ )
240
+ }
241
+ // recursively get referenced IDs in nested data
242
+ const nestedResult = await getReferencedEntryIds(
243
+ rootType,
244
+ context,
245
+ fieldsKey,
246
+ field.type,
247
+ fieldValue,
248
+ )
249
+ referencedEntryIds = [...referencedEntryIds, ...nestedResult]
187
250
  }
188
251
  // deduplicate
189
252
  referencedEntryIds = [...new Set(referencedEntryIds)]
@@ -193,3 +256,39 @@ export async function getReferencedEntryIds(
193
256
 
194
257
  return []
195
258
  }
259
+
260
+ async function getValidatedReferenceId(
261
+ context: ApolloContext,
262
+ fieldName: string | null,
263
+ type: GraphQLUnionType | GraphQLObjectType,
264
+ data: EntryData | EntryData[],
265
+ ): Promise<string> {
266
+ if (data === null || typeof data !== 'object' || Array.isArray(data)) {
267
+ throw createError(
268
+ `Expected object as data for field "${fieldName}" of type "${type.name}".`,
269
+ ErrorCode.BAD_REPOSITORY_DATA,
270
+ {
271
+ typeName: type.name,
272
+ fieldName: fieldName ? fieldName : undefined,
273
+ fieldValue: data,
274
+ },
275
+ )
276
+ }
277
+ await validateReference(context, fieldName ? fieldName : '', type, data)
278
+
279
+ let referencedId = null
280
+ if (typeof (referencedId = data.id) !== 'string') {
281
+ throw createError(
282
+ `Expected a key "id" with value of type string in data of field "${fieldName}" of type "${type.name}"` +
283
+ ` after this reference was just verified to be valid.`,
284
+ ErrorCode.INTERNAL_ERROR,
285
+ {
286
+ typeName: type.name,
287
+ fieldName: fieldName ? fieldName : undefined,
288
+ fieldValue: data,
289
+ },
290
+ )
291
+ }
292
+
293
+ return referencedId
294
+ }
@@ -0,0 +1,11 @@
1
+ export function isRecord(obj: unknown): obj is Record<string, unknown> {
2
+ if (typeof obj !== 'object') {
3
+ return false
4
+ }
5
+
6
+ if (Array.isArray(obj)) {
7
+ return false
8
+ }
9
+
10
+ return Object.getOwnPropertySymbols(obj).length === 0
11
+ }