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

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 +16 -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 +4 -4
  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 +1 -1
  45. package/dist/cjs/graphql/schema-utils/entry-reference-util.js +63 -16
  46. package/dist/cjs/graphql/schema-utils/entry-reference-util.js.map +1 -1
  47. package/dist/cjs/graphql/util.d.ts +2 -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 +4 -4
  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 +64 -17
  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 +1 -1
  113. package/dist/types/graphql/schema-utils/entry-reference-util.d.ts.map +1 -1
  114. package/dist/types/graphql/util.d.ts +3 -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 +17 -13
  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 +131 -24
  135. package/src/graphql/util.ts +13 -0
@@ -1,14 +1,13 @@
1
1
  import { EntryData } from '@commitspark/git-adapter'
2
2
  import { findByTypeId } from '../../../persistence/persistence.ts'
3
- import { GraphQLFieldResolver } from 'graphql'
4
- import { QueryMutationResolverContext } from '../types.ts'
3
+ import { QueryMutationResolver } from '../types.ts'
5
4
 
6
- export const queryByIdResolver: GraphQLFieldResolver<
7
- any,
8
- QueryMutationResolverContext,
9
- any,
10
- Promise<EntryData>
11
- > = async (_obj, args, context, info) => {
5
+ export const queryByIdResolver: QueryMutationResolver<EntryData> = async (
6
+ _source,
7
+ args,
8
+ context,
9
+ info,
10
+ ) => {
12
11
  void info
13
12
  const entry = await findByTypeId(context, context.type.name, args.id)
14
13
 
@@ -1,14 +1,13 @@
1
1
  import { EntryData } from '@commitspark/git-adapter'
2
2
  import { findByType } from '../../../persistence/persistence.ts'
3
- import { GraphQLFieldResolver } from 'graphql'
4
- import { QueryMutationResolverContext } from '../types.ts'
3
+ import { QueryMutationResolver } from '../types.ts'
5
4
 
6
- export const queryEveryResolver: GraphQLFieldResolver<
7
- any,
8
- QueryMutationResolverContext,
9
- any,
10
- Promise<EntryData[]>
11
- > = async (_obj, _args, context, info) => {
5
+ export const queryEveryResolver: QueryMutationResolver<EntryData[]> = async (
6
+ _source,
7
+ _args,
8
+ context,
9
+ info,
10
+ ) => {
12
11
  void info
13
12
  const entries = await findByType(context, context.type.name)
14
13
 
@@ -1,13 +1,12 @@
1
1
  import { getTypeById } from '../../../persistence/persistence.ts'
2
- import { GraphQLFieldResolver } from 'graphql'
3
- import { ApolloContext } from '../../../client.ts'
2
+ import { QueryMutationResolver } from '../types.ts'
4
3
 
5
- export const queryTypeByIdResolver: GraphQLFieldResolver<
6
- any,
7
- ApolloContext,
8
- any,
9
- Promise<string>
10
- > = async (_source, args, context, info) => {
4
+ export const queryTypeByIdResolver: QueryMutationResolver<string> = async (
5
+ _source,
6
+ args,
7
+ context,
8
+ info,
9
+ ) => {
11
10
  void info
12
11
  return getTypeById(context, args.id)
13
12
  }
@@ -1,18 +1,30 @@
1
- import { ApolloContext } from '../../../client.ts'
2
1
  import { getTypeById } from '../../../persistence/persistence.ts'
3
- import { GraphQLTypeResolver } from 'graphql'
4
2
  import { buildsOnTypeWithEntryDirective } from '../../schema-utils/entry-type-util.ts'
3
+ import { UnionTypeResolver } from '../types.ts'
4
+ import { createError, ErrorCode } from '../../errors.ts'
5
5
 
6
- export const unionTypeResolver: GraphQLTypeResolver<
7
- any,
8
- ApolloContext
9
- > = async (obj, context, info, abstractType) => {
6
+ export const unionTypeResolver: UnionTypeResolver = async (
7
+ source,
8
+ context,
9
+ info,
10
+ abstractType,
11
+ ) => {
10
12
  if (buildsOnTypeWithEntryDirective(abstractType)) {
11
- return getTypeById(context, obj.id)
13
+ if (!('id' in source) || typeof source.id !== 'string') {
14
+ throw createError(
15
+ `Expected key "id" of type string in data while resolving reference-based union type for field "${info.fieldName}".`,
16
+ ErrorCode.BAD_REPOSITORY_DATA,
17
+ {
18
+ typeName: abstractType.name,
19
+ fieldName: info.fieldName,
20
+ },
21
+ )
22
+ }
23
+ return getTypeById(context, source.id)
12
24
  } else {
13
25
  // We have injected an internal `__typename` field into the data of fields pointing to a non-entry union
14
26
  // in UnionValueResolver. This artificial field holds the type information we need here.
15
- return obj.__typename
27
+ return source.__typename
16
28
  }
17
29
 
18
30
  // TODO same for interface type: https://www.apollographql.com/docs/apollo-server/data/resolvers/#resolving-unions-and-interfaces
@@ -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 { isEntryData } from '../util.ts'
17
21
 
18
22
  function isPermittedReferenceType(
19
23
  referencedTypeName: string,
@@ -38,16 +42,18 @@ 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)
45
49
  return
46
- } else if (isListType(fieldType)) {
50
+ }
51
+
52
+ if (isListType(fieldType)) {
47
53
  if (!Array.isArray(fieldValue)) {
48
54
  throw createError(
49
55
  `Expected array while validation references for field "${fieldName}".`,
50
- ErrorCode.SCHEMA_DATA_MISMATCH,
56
+ ErrorCode.BAD_REPOSITORY_DATA,
51
57
  {
52
58
  fieldName: fieldName,
53
59
  fieldValue: fieldValue,
@@ -63,17 +69,24 @@ async function validateReference(
63
69
  )
64
70
  }
65
71
  return
66
- } else if (isUnionType(fieldType) || isObjectType(fieldType)) {
67
- if (!('id' in fieldValue)) {
72
+ }
73
+
74
+ if (isUnionType(fieldType) || isObjectType(fieldType)) {
75
+ if (
76
+ fieldValue === null ||
77
+ !('id' in fieldValue) ||
78
+ typeof fieldValue.id !== 'string'
79
+ ) {
68
80
  throw createError(
69
- `Expected key "id" in data while validating reference for field "${fieldName}".`,
70
- ErrorCode.SCHEMA_DATA_MISMATCH,
81
+ `Expected key "id" with value of type string in data while validating reference for field "${fieldName}".`,
82
+ ErrorCode.BAD_REPOSITORY_DATA,
71
83
  {
72
84
  fieldName: fieldName,
73
85
  fieldValue: fieldValue,
74
86
  },
75
87
  )
76
88
  }
89
+
77
90
  const referencedId = fieldValue.id
78
91
  let referencedTypeName
79
92
  try {
@@ -106,8 +119,12 @@ export async function getReferencedEntryIds(
106
119
  context: ApolloContext,
107
120
  fieldName: string | null,
108
121
  type: GraphQLNullableType,
109
- data: any,
122
+ data: unknown,
110
123
  ): Promise<string[]> {
124
+ if (data === null || data === undefined || isScalarType(type)) {
125
+ return []
126
+ }
127
+
111
128
  if (isNonNullType(type)) {
112
129
  return getReferencedEntryIds(
113
130
  rootType,
@@ -116,7 +133,20 @@ export async function getReferencedEntryIds(
116
133
  type.ofType,
117
134
  data,
118
135
  )
119
- } else if (isListType(type)) {
136
+ }
137
+
138
+ if (isListType(type)) {
139
+ if (!Array.isArray(data)) {
140
+ throw createError(
141
+ `Expected array as data for field "${fieldName}". `,
142
+ ErrorCode.BAD_REPOSITORY_DATA,
143
+ {
144
+ fieldName: fieldName ? fieldName : undefined,
145
+ fieldValue: data,
146
+ },
147
+ )
148
+ }
149
+
120
150
  let referencedEntryIds: string[] = []
121
151
  for (const element of data) {
122
152
  referencedEntryIds = [
@@ -133,10 +163,29 @@ export async function getReferencedEntryIds(
133
163
  // deduplicate
134
164
  referencedEntryIds = [...new Set(referencedEntryIds)]
135
165
  return referencedEntryIds
136
- } else if (isUnionType(type)) {
166
+ }
167
+
168
+ if (isUnionType(type)) {
169
+ if (!isEntryData(data)) {
170
+ throw createError(
171
+ `Expected object as data for type "${type.name}".`,
172
+ ErrorCode.BAD_REPOSITORY_DATA,
173
+ {
174
+ typeName: type.name,
175
+ fieldName: fieldName ? fieldName : undefined,
176
+ fieldValue: data,
177
+ },
178
+ )
179
+ }
180
+
137
181
  if (isUnionOfEntryTypes(type)) {
138
- await validateReference(context, '', type, data)
139
- return [data.id]
182
+ const referenceId = await getValidatedReferenceId(
183
+ context,
184
+ fieldName,
185
+ type,
186
+ data,
187
+ )
188
+ return [referenceId]
140
189
  }
141
190
 
142
191
  const requestedUnionTypeName = getUnionTypeNameFromFieldValue(data)
@@ -166,24 +215,41 @@ export async function getReferencedEntryIds(
166
215
  concreteFieldUnionType,
167
216
  unionValue,
168
217
  )
169
- } else if (isObjectType(type)) {
218
+ }
219
+
220
+ if (isObjectType(type)) {
170
221
  if (type.name !== rootType.name && hasEntryDirective(type)) {
171
- await validateReference(context, fieldName ?? '', type, data)
172
- return [data.id]
222
+ const referenceId = await getValidatedReferenceId(
223
+ context,
224
+ fieldName,
225
+ type,
226
+ data,
227
+ )
228
+ return [referenceId]
173
229
  } else {
174
230
  let referencedEntryIds: string[] = []
175
231
  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,
232
+ // expect our object type to hold EntryData (i.e. an object)
233
+ if (Array.isArray(data) || !isEntryData(data)) {
234
+ throw createError(
235
+ `Expected object as data for type "${type.name}".`,
236
+ ErrorCode.BAD_REPOSITORY_DATA,
237
+ {
238
+ typeName: type.name,
239
+ fieldName: field.name ? field.name : undefined,
240
+ },
184
241
  )
185
- referencedEntryIds = [...referencedEntryIds, ...nestedResult]
186
242
  }
243
+
244
+ // recursively get referenced IDs in nested data
245
+ const nestedResult = await getReferencedEntryIds(
246
+ rootType,
247
+ context,
248
+ fieldsKey,
249
+ field.type,
250
+ data[fieldsKey],
251
+ )
252
+ referencedEntryIds = [...referencedEntryIds, ...nestedResult]
187
253
  }
188
254
  // deduplicate
189
255
  referencedEntryIds = [...new Set(referencedEntryIds)]
@@ -193,3 +259,44 @@ export async function getReferencedEntryIds(
193
259
 
194
260
  return []
195
261
  }
262
+
263
+ async function getValidatedReferenceId(
264
+ context: ApolloContext,
265
+ fieldName: string | null,
266
+ type: GraphQLUnionType | GraphQLObjectType,
267
+ data: unknown,
268
+ ): Promise<string> {
269
+ if (
270
+ data === null ||
271
+ data === undefined ||
272
+ !isEntryData(data) ||
273
+ Array.isArray(data)
274
+ ) {
275
+ throw createError(
276
+ `Expected object as data for field "${fieldName}" of type "${type.name}".`,
277
+ ErrorCode.BAD_REPOSITORY_DATA,
278
+ {
279
+ typeName: type.name,
280
+ fieldName: fieldName ? fieldName : undefined,
281
+ fieldValue: data,
282
+ },
283
+ )
284
+ }
285
+ await validateReference(context, fieldName ? fieldName : '', type, data)
286
+
287
+ let referencedId = null
288
+ if (typeof (referencedId = data.id) !== 'string') {
289
+ throw createError(
290
+ `Expected a key "id" with value of type string in data of field "${fieldName}" of type "${type.name}"` +
291
+ ` after this reference was just verified to be valid.`,
292
+ ErrorCode.INTERNAL_ERROR,
293
+ {
294
+ typeName: type.name,
295
+ fieldName: fieldName ? fieldName : undefined,
296
+ fieldValue: data,
297
+ },
298
+ )
299
+ }
300
+
301
+ return referencedId
302
+ }
@@ -0,0 +1,13 @@
1
+ import { EntryData } from '@commitspark/git-adapter'
2
+
3
+ export function isEntryData(obj: unknown): obj is EntryData {
4
+ if (typeof obj !== 'object') {
5
+ return false
6
+ }
7
+
8
+ if (Array.isArray(obj)) {
9
+ return false
10
+ }
11
+
12
+ return Object.getOwnPropertySymbols(obj).length === 0
13
+ }