@commitspark/graphql-api 0.7.0
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.
- package/.eslintrc.js +24 -0
- package/.prettierrc +6 -0
- package/CHANGELOG.md +83 -0
- package/LICENSE +15 -0
- package/README.md +223 -0
- package/dist/app/api.service.d.ts +31 -0
- package/dist/app/api.service.js +60 -0
- package/dist/app/api.service.js.map +1 -0
- package/dist/container.d.ts +2 -0
- package/dist/container.js +44 -0
- package/dist/container.js.map +1 -0
- package/dist/graphql/apollo-config-factory.service.d.ts +8 -0
- package/dist/graphql/apollo-config-factory.service.js +20 -0
- package/dist/graphql/apollo-config-factory.service.js.map +1 -0
- package/dist/graphql/input-type-generator.service.d.ts +12 -0
- package/dist/graphql/input-type-generator.service.js +86 -0
- package/dist/graphql/input-type-generator.service.js.map +1 -0
- package/dist/graphql/queries-mutations-generator.service.d.ts +39 -0
- package/dist/graphql/queries-mutations-generator.service.js +82 -0
- package/dist/graphql/queries-mutations-generator.service.js.map +1 -0
- package/dist/graphql/resolver-generators/entry-reference-resolver.generator.d.ts +12 -0
- package/dist/graphql/resolver-generators/entry-reference-resolver.generator.js +29 -0
- package/dist/graphql/resolver-generators/entry-reference-resolver.generator.js.map +1 -0
- package/dist/graphql/resolver-generators/mutation-create-resolver-generator.d.ts +8 -0
- package/dist/graphql/resolver-generators/mutation-create-resolver-generator.js +17 -0
- package/dist/graphql/resolver-generators/mutation-create-resolver-generator.js.map +1 -0
- package/dist/graphql/resolver-generators/mutation-delete-resolver-generator.d.ts +8 -0
- package/dist/graphql/resolver-generators/mutation-delete-resolver-generator.js +19 -0
- package/dist/graphql/resolver-generators/mutation-delete-resolver-generator.js.map +1 -0
- package/dist/graphql/resolver-generators/mutation-update.resolver-generator.d.ts +8 -0
- package/dist/graphql/resolver-generators/mutation-update.resolver-generator.js +17 -0
- package/dist/graphql/resolver-generators/mutation-update.resolver-generator.js.map +1 -0
- package/dist/graphql/resolver-generators/query-all-resolver-generator.d.ts +8 -0
- package/dist/graphql/resolver-generators/query-all-resolver-generator.js +15 -0
- package/dist/graphql/resolver-generators/query-all-resolver-generator.js.map +1 -0
- package/dist/graphql/resolver-generators/query-by-id-resolver-generator.d.ts +8 -0
- package/dist/graphql/resolver-generators/query-by-id-resolver-generator.js +15 -0
- package/dist/graphql/resolver-generators/query-by-id-resolver-generator.js.map +1 -0
- package/dist/graphql/resolver-generators/query-count-all-resolver-generator.d.ts +9 -0
- package/dist/graphql/resolver-generators/query-count-all-resolver-generator.js +17 -0
- package/dist/graphql/resolver-generators/query-count-all-resolver-generator.js.map +1 -0
- package/dist/graphql/resolver-generators/query-type-by-id-resolver-generator.d.ts +8 -0
- package/dist/graphql/resolver-generators/query-type-by-id-resolver-generator.js +15 -0
- package/dist/graphql/resolver-generators/query-type-by-id-resolver-generator.js.map +1 -0
- package/dist/graphql/resolver-generators/union-type-resolver-generator.d.ts +10 -0
- package/dist/graphql/resolver-generators/union-type-resolver-generator.js +21 -0
- package/dist/graphql/resolver-generators/union-type-resolver-generator.js.map +1 -0
- package/dist/graphql/resolver-generators/union-value-resolver-generator.d.ts +13 -0
- package/dist/graphql/resolver-generators/union-value-resolver-generator.js +80 -0
- package/dist/graphql/resolver-generators/union-value-resolver-generator.js.map +1 -0
- package/dist/graphql/schema-analyzer.service.d.ts +19 -0
- package/dist/graphql/schema-analyzer.service.js +52 -0
- package/dist/graphql/schema-analyzer.service.js.map +1 -0
- package/dist/graphql/schema-generator.service.d.ts +22 -0
- package/dist/graphql/schema-generator.service.js +99 -0
- package/dist/graphql/schema-generator.service.js.map +1 -0
- package/dist/graphql/schema-root-type-generator.service.d.ts +4 -0
- package/dist/graphql/schema-root-type-generator.service.js +37 -0
- package/dist/graphql/schema-root-type-generator.service.js.map +1 -0
- package/dist/graphql/schema-utils/entry-reference-util.d.ts +7 -0
- package/dist/graphql/schema-utils/entry-reference-util.js +42 -0
- package/dist/graphql/schema-utils/entry-reference-util.js.map +1 -0
- package/dist/graphql/schema-validator.d.ts +5 -0
- package/dist/graphql/schema-validator.js +33 -0
- package/dist/graphql/schema-validator.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/persistence/persistence.service.d.ts +17 -0
- package/dist/persistence/persistence.service.js +110 -0
- package/dist/persistence/persistence.service.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +34 -0
- package/src/app/api.service.ts +113 -0
- package/src/container.ts +92 -0
- package/src/graphql/apollo-config-factory.service.ts +21 -0
- package/src/graphql/input-type-generator.service.ts +114 -0
- package/src/graphql/queries-mutations-generator.service.ts +155 -0
- package/src/graphql/resolver-generators/entry-reference-resolver.generator.ts +71 -0
- package/src/graphql/resolver-generators/mutation-create-resolver-generator.ts +38 -0
- package/src/graphql/resolver-generators/mutation-delete-resolver-generator.ts +35 -0
- package/src/graphql/resolver-generators/mutation-update.resolver-generator.ts +39 -0
- package/src/graphql/resolver-generators/query-all-resolver-generator.ts +27 -0
- package/src/graphql/resolver-generators/query-by-id-resolver-generator.ts +23 -0
- package/src/graphql/resolver-generators/query-count-all-resolver-generator.ts +29 -0
- package/src/graphql/resolver-generators/query-type-by-id-resolver-generator.ts +27 -0
- package/src/graphql/resolver-generators/union-type-resolver-generator.ts +40 -0
- package/src/graphql/resolver-generators/union-value-resolver-generator.ts +116 -0
- package/src/graphql/schema-analyzer.service.ts +70 -0
- package/src/graphql/schema-generator.service.ts +190 -0
- package/src/graphql/schema-root-type-generator.service.ts +42 -0
- package/src/graphql/schema-utils/entry-reference-util.ts +49 -0
- package/src/graphql/schema-validator.ts +41 -0
- package/src/index.ts +8 -0
- package/src/persistence/persistence.service.ts +183 -0
- package/tsconfig.build.json +10 -0
- package/tsconfig.json +18 -0
- package/webpack.config.js +25 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import {
|
|
2
|
+
IGeneratedSchema,
|
|
3
|
+
QueriesMutationsGeneratorService,
|
|
4
|
+
} from './queries-mutations-generator.service'
|
|
5
|
+
import {
|
|
6
|
+
IExecutableSchemaDefinition,
|
|
7
|
+
makeExecutableSchema,
|
|
8
|
+
} from '@graphql-tools/schema'
|
|
9
|
+
import { SchemaAnalyzerService } from './schema-analyzer.service'
|
|
10
|
+
import { InputTypeGeneratorService } from './input-type-generator.service'
|
|
11
|
+
import { SchemaRootTypeGeneratorService } from './schema-root-type-generator.service'
|
|
12
|
+
import { printSchemaWithDirectives } from '@graphql-tools/utils'
|
|
13
|
+
import { EntryReferenceResolverGenerator } from './resolver-generators/entry-reference-resolver.generator'
|
|
14
|
+
import { UnionTypeResolverGenerator } from './resolver-generators/union-type-resolver-generator'
|
|
15
|
+
import { ApolloContext } from '../app/api.service'
|
|
16
|
+
import {
|
|
17
|
+
GraphQLFieldResolver,
|
|
18
|
+
GraphQLTypeResolver,
|
|
19
|
+
} from 'graphql/type/definition'
|
|
20
|
+
import { SchemaValidator } from './schema-validator'
|
|
21
|
+
import { Entry } from '../persistence/persistence.service'
|
|
22
|
+
import { UnionValueResolverGenerator } from './resolver-generators/union-value-resolver-generator'
|
|
23
|
+
|
|
24
|
+
export class SchemaGeneratorService {
|
|
25
|
+
constructor(
|
|
26
|
+
private readonly queriesMutationsGenerator: QueriesMutationsGeneratorService,
|
|
27
|
+
private readonly schemaAnalyzer: SchemaAnalyzerService,
|
|
28
|
+
private readonly inputTypeGenerator: InputTypeGeneratorService,
|
|
29
|
+
private readonly schemaRootTypeGenerator: SchemaRootTypeGeneratorService,
|
|
30
|
+
private readonly entryReferenceResolverGenerator: EntryReferenceResolverGenerator,
|
|
31
|
+
private readonly unionTypeResolverGenerator: UnionTypeResolverGenerator,
|
|
32
|
+
private readonly unionValueResolverGenerator: UnionValueResolverGenerator,
|
|
33
|
+
private readonly schemaValidator: SchemaValidator,
|
|
34
|
+
) {}
|
|
35
|
+
|
|
36
|
+
public async generateSchema(
|
|
37
|
+
context: ApolloContext,
|
|
38
|
+
): Promise<IExecutableSchemaDefinition> {
|
|
39
|
+
const originalSchemaString = await context.gitAdapter.getSchema(
|
|
40
|
+
context.getCurrentRef(),
|
|
41
|
+
)
|
|
42
|
+
const schema = makeExecutableSchema({
|
|
43
|
+
typeDefs: originalSchemaString,
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const validationResult = this.schemaValidator.getValidationResult(schema)
|
|
47
|
+
if (validationResult.length > 0) {
|
|
48
|
+
throw new Error(validationResult.join('\n'))
|
|
49
|
+
}
|
|
50
|
+
const schemaAnalyzerResult = this.schemaAnalyzer.analyzeSchema(schema)
|
|
51
|
+
|
|
52
|
+
const filteredOriginalSchemaString = printSchemaWithDirectives(schema)
|
|
53
|
+
|
|
54
|
+
const generatedIdInputTypeStrings =
|
|
55
|
+
this.inputTypeGenerator.generateIdInputTypeStrings(schemaAnalyzerResult)
|
|
56
|
+
|
|
57
|
+
const generatedQueriesMutations =
|
|
58
|
+
this.queriesMutationsGenerator.generateFromAnalyzedSchema(
|
|
59
|
+
schemaAnalyzerResult.entryDirectiveTypes,
|
|
60
|
+
)
|
|
61
|
+
const generatedTypeNameQuery =
|
|
62
|
+
this.queriesMutationsGenerator.generateTypeNameQuery()
|
|
63
|
+
|
|
64
|
+
let generatedEntryReferenceResolvers: Record<
|
|
65
|
+
string,
|
|
66
|
+
Record<
|
|
67
|
+
string,
|
|
68
|
+
GraphQLFieldResolver<
|
|
69
|
+
Record<string, any>,
|
|
70
|
+
ApolloContext,
|
|
71
|
+
any,
|
|
72
|
+
Promise<Entry | Entry[] | undefined>
|
|
73
|
+
>
|
|
74
|
+
>
|
|
75
|
+
> = {}
|
|
76
|
+
for (const type of schemaAnalyzerResult.typesWithEntryReferences) {
|
|
77
|
+
generatedEntryReferenceResolvers[type.type.name] =
|
|
78
|
+
this.entryReferenceResolverGenerator.createResolver(context, type)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const generatedObjectInputTypeStrings =
|
|
82
|
+
this.inputTypeGenerator.generateObjectInputTypeStrings(
|
|
83
|
+
schemaAnalyzerResult.objectTypes,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
const generatedUnionInputTypeStrings =
|
|
87
|
+
this.inputTypeGenerator.generateUnionInputTypeStrings(
|
|
88
|
+
schemaAnalyzerResult.unionTypes,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
const generatedSchemaRootTypeStrings =
|
|
92
|
+
this.schemaRootTypeGenerator.generateSchemaRootTypeStrings(
|
|
93
|
+
generatedQueriesMutations,
|
|
94
|
+
generatedTypeNameQuery,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
const generatedSchemaString =
|
|
98
|
+
'schema {\n query: Query\n mutation: Mutation\n}\n\n' +
|
|
99
|
+
generatedSchemaRootTypeStrings +
|
|
100
|
+
'\n' +
|
|
101
|
+
'type ListMetadata {\n' +
|
|
102
|
+
' count: Int!\n' +
|
|
103
|
+
'}\n\n' +
|
|
104
|
+
'type DeletionResult {\n' +
|
|
105
|
+
' id: ID\n' +
|
|
106
|
+
'}\n'
|
|
107
|
+
|
|
108
|
+
const generatedUnionTypeResolvers: Record<string, UnionTypeResolver> = {}
|
|
109
|
+
for (const unionType of schemaAnalyzerResult.unionTypes) {
|
|
110
|
+
generatedUnionTypeResolvers[unionType.name] = {
|
|
111
|
+
__resolveType: this.unionTypeResolverGenerator.createResolver(),
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const generatedUnionValueResolvers =
|
|
115
|
+
this.unionValueResolverGenerator.createResolver(schema)
|
|
116
|
+
|
|
117
|
+
const generatedQueryResolvers: Record<
|
|
118
|
+
string,
|
|
119
|
+
GraphQLFieldResolver<any, ApolloContext>
|
|
120
|
+
> = {}
|
|
121
|
+
const generatedMutationResolvers: Record<
|
|
122
|
+
string,
|
|
123
|
+
GraphQLFieldResolver<any, ApolloContext>
|
|
124
|
+
> = {}
|
|
125
|
+
|
|
126
|
+
generatedQueriesMutations.forEach(function (
|
|
127
|
+
element: IGeneratedSchema,
|
|
128
|
+
): void {
|
|
129
|
+
generatedQueryResolvers[element.queryAll.name] = element.queryAll.resolver
|
|
130
|
+
generatedQueryResolvers[element.queryAllMeta.name] =
|
|
131
|
+
element.queryAllMeta.resolver
|
|
132
|
+
generatedQueryResolvers[element.queryById.name] =
|
|
133
|
+
element.queryById.resolver
|
|
134
|
+
generatedMutationResolvers[element.createMutation.name] =
|
|
135
|
+
element.createMutation.resolver
|
|
136
|
+
generatedMutationResolvers[element.updateMutation.name] =
|
|
137
|
+
element.updateMutation.resolver
|
|
138
|
+
generatedMutationResolvers[element.deleteMutation.name] =
|
|
139
|
+
element.deleteMutation.resolver
|
|
140
|
+
})
|
|
141
|
+
generatedQueryResolvers[generatedTypeNameQuery.name] =
|
|
142
|
+
generatedTypeNameQuery.resolver
|
|
143
|
+
|
|
144
|
+
const allGeneratedResolvers: Record<
|
|
145
|
+
string,
|
|
146
|
+
Record<
|
|
147
|
+
string,
|
|
148
|
+
| GraphQLFieldResolver<any, ApolloContext>
|
|
149
|
+
| GraphQLTypeResolver<any, ApolloContext>
|
|
150
|
+
>
|
|
151
|
+
> = {
|
|
152
|
+
Query: generatedQueryResolvers,
|
|
153
|
+
Mutation: generatedMutationResolvers,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
for (const typeName of Object.keys(generatedUnionTypeResolvers)) {
|
|
157
|
+
allGeneratedResolvers[typeName] = {
|
|
158
|
+
...(allGeneratedResolvers[typeName] ?? {}),
|
|
159
|
+
...generatedUnionTypeResolvers[typeName],
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
for (const typeName of Object.keys(generatedUnionValueResolvers)) {
|
|
163
|
+
allGeneratedResolvers[typeName] = {
|
|
164
|
+
...(allGeneratedResolvers[typeName] ?? {}),
|
|
165
|
+
...generatedUnionValueResolvers[typeName],
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
for (const typeName of Object.keys(generatedEntryReferenceResolvers)) {
|
|
169
|
+
allGeneratedResolvers[typeName] = {
|
|
170
|
+
...(allGeneratedResolvers[typeName] ?? {}),
|
|
171
|
+
...generatedEntryReferenceResolvers[typeName],
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
typeDefs: [
|
|
177
|
+
filteredOriginalSchemaString,
|
|
178
|
+
generatedSchemaString,
|
|
179
|
+
generatedIdInputTypeStrings.join('\n'),
|
|
180
|
+
generatedObjectInputTypeStrings.join('\n'),
|
|
181
|
+
generatedUnionInputTypeStrings.join('\n'),
|
|
182
|
+
],
|
|
183
|
+
resolvers: allGeneratedResolvers,
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
interface UnionTypeResolver {
|
|
189
|
+
__resolveType: GraphQLTypeResolver<any, ApolloContext>
|
|
190
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
IGeneratedQuery,
|
|
3
|
+
IGeneratedSchema,
|
|
4
|
+
} from './queries-mutations-generator.service'
|
|
5
|
+
|
|
6
|
+
export class SchemaRootTypeGeneratorService {
|
|
7
|
+
public generateSchemaRootTypeStrings(
|
|
8
|
+
generatedSchemas: IGeneratedSchema[],
|
|
9
|
+
typeQuery: IGeneratedQuery<Promise<string>>,
|
|
10
|
+
): string {
|
|
11
|
+
return (
|
|
12
|
+
`type Query {\n` +
|
|
13
|
+
generatedSchemas
|
|
14
|
+
.map((generated) => ' ' + generated.queryAll.schemaString)
|
|
15
|
+
.join('\n') +
|
|
16
|
+
generatedSchemas
|
|
17
|
+
.map((generated) => ' ' + generated.queryAllMeta.schemaString)
|
|
18
|
+
.join('\n') +
|
|
19
|
+
generatedSchemas
|
|
20
|
+
.map((generated) => ' ' + generated.queryById.schemaString)
|
|
21
|
+
.join('\n') +
|
|
22
|
+
'\n' +
|
|
23
|
+
` ${typeQuery.schemaString}` +
|
|
24
|
+
'\n' +
|
|
25
|
+
'}\n' +
|
|
26
|
+
'type Mutation {\n' +
|
|
27
|
+
generatedSchemas
|
|
28
|
+
.map((generated) => ' ' + generated.createMutation.schemaString)
|
|
29
|
+
.join('\n') +
|
|
30
|
+
'\n' +
|
|
31
|
+
generatedSchemas
|
|
32
|
+
.map((generated) => ' ' + generated.updateMutation.schemaString)
|
|
33
|
+
.join('\n') +
|
|
34
|
+
'\n' +
|
|
35
|
+
generatedSchemas
|
|
36
|
+
.map((generated) => ' ' + generated.deleteMutation.schemaString)
|
|
37
|
+
.join('\n') +
|
|
38
|
+
'\n' +
|
|
39
|
+
'}\n'
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GraphQLField,
|
|
3
|
+
GraphQLList,
|
|
4
|
+
GraphQLNonNull,
|
|
5
|
+
GraphQLObjectType,
|
|
6
|
+
} from 'graphql/type'
|
|
7
|
+
import { GraphQLNullableType, GraphQLUnionType } from 'graphql/type/definition'
|
|
8
|
+
|
|
9
|
+
export class EntryReferenceUtil {
|
|
10
|
+
public getFieldsWithReferenceToTypeWithEntryDirective(
|
|
11
|
+
objectType: GraphQLObjectType,
|
|
12
|
+
): GraphQLField<any, any>[] {
|
|
13
|
+
const fields = []
|
|
14
|
+
for (const fieldsKey in objectType.getFields()) {
|
|
15
|
+
const field: GraphQLField<any, any> = objectType.getFields()[fieldsKey]
|
|
16
|
+
if (this.buildsOnTypeWithEntryDirective(field.type)) {
|
|
17
|
+
fields.push(field)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return fields
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public buildsOnTypeWithEntryDirective(type: GraphQLNullableType): boolean {
|
|
24
|
+
if (type instanceof GraphQLNonNull) {
|
|
25
|
+
return this.buildsOnTypeWithEntryDirective(type.ofType)
|
|
26
|
+
} else if (type instanceof GraphQLList) {
|
|
27
|
+
return this.buildsOnTypeWithEntryDirective(type.ofType)
|
|
28
|
+
} else if (type instanceof GraphQLUnionType) {
|
|
29
|
+
return (
|
|
30
|
+
type
|
|
31
|
+
.getTypes()
|
|
32
|
+
.filter((unionType) => this.buildsOnTypeWithEntryDirective(unionType))
|
|
33
|
+
.length > 0
|
|
34
|
+
)
|
|
35
|
+
} else if (type instanceof GraphQLObjectType) {
|
|
36
|
+
return this.hasEntryDirective(type)
|
|
37
|
+
}
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public hasEntryDirective(type: GraphQLObjectType): boolean {
|
|
42
|
+
return (
|
|
43
|
+
!!type.astNode &&
|
|
44
|
+
type.astNode.directives?.find(
|
|
45
|
+
(directive) => directive.name.value === 'Entry',
|
|
46
|
+
) !== undefined
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { GraphQLSchema } from 'graphql'
|
|
2
|
+
import { Kind } from 'graphql/language/kinds'
|
|
3
|
+
import { GraphQLUnionType } from 'graphql/type/definition'
|
|
4
|
+
|
|
5
|
+
export class SchemaValidator {
|
|
6
|
+
public getValidationResult(schema: GraphQLSchema): string[] {
|
|
7
|
+
const results = []
|
|
8
|
+
results.push(this.checkUnionMembersConsistentUseOfEntryDirective(schema))
|
|
9
|
+
return results.filter((result) => result !== '')
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
private checkUnionMembersConsistentUseOfEntryDirective(
|
|
13
|
+
schema: GraphQLSchema,
|
|
14
|
+
): string {
|
|
15
|
+
const typeMap = schema.getTypeMap()
|
|
16
|
+
|
|
17
|
+
for (const [key, type] of Object.entries(typeMap)) {
|
|
18
|
+
if (type.astNode?.kind !== Kind.UNION_TYPE_DEFINITION) {
|
|
19
|
+
continue
|
|
20
|
+
}
|
|
21
|
+
const innerTypes = (type as GraphQLUnionType).getTypes()
|
|
22
|
+
|
|
23
|
+
const numberUnionMembersWithEntryDirective = innerTypes.filter(
|
|
24
|
+
(innerType) =>
|
|
25
|
+
!!innerType.astNode &&
|
|
26
|
+
innerType.astNode.directives?.find(
|
|
27
|
+
(directive) => directive.name.value === 'Entry',
|
|
28
|
+
) !== undefined,
|
|
29
|
+
).length
|
|
30
|
+
|
|
31
|
+
if (
|
|
32
|
+
numberUnionMembersWithEntryDirective !== 0 &&
|
|
33
|
+
numberUnionMembersWithEntryDirective !== innerTypes.length
|
|
34
|
+
) {
|
|
35
|
+
return `Either all union members of "${type.name}" must have "@Entry" directive or none.`
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return ''
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid'
|
|
2
|
+
import { ContentEntry, GitAdapter } from '@commitspark/git-adapter'
|
|
3
|
+
|
|
4
|
+
export class PersistenceService {
|
|
5
|
+
constructor() {}
|
|
6
|
+
|
|
7
|
+
public async getTypeById(
|
|
8
|
+
gitAdapter: GitAdapter,
|
|
9
|
+
commitHash: string,
|
|
10
|
+
id: ID,
|
|
11
|
+
): Promise<string> {
|
|
12
|
+
const allEntries = await gitAdapter.getContentEntries(commitHash)
|
|
13
|
+
const requestedEntry = allEntries.filter(
|
|
14
|
+
(contentEntry: ContentEntry) => contentEntry.id === (id as string),
|
|
15
|
+
)[0]
|
|
16
|
+
if (requestedEntry === undefined) {
|
|
17
|
+
throw new Error(`Not found: ${id}`)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return requestedEntry.metadata.type
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public async findById(
|
|
24
|
+
gitAdapter: GitAdapter,
|
|
25
|
+
commitHash: string,
|
|
26
|
+
id: ID,
|
|
27
|
+
): Promise<Entry> {
|
|
28
|
+
const allEntries = await gitAdapter.getContentEntries(commitHash)
|
|
29
|
+
const requestedEntry = allEntries.filter(
|
|
30
|
+
(contentEntry: ContentEntry) => contentEntry.id === (id as string),
|
|
31
|
+
)[0]
|
|
32
|
+
if (requestedEntry === undefined) {
|
|
33
|
+
throw new Error(`Not found: ${id}`)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return { ...requestedEntry.data, id: id }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public async findByType(
|
|
40
|
+
gitAdapter: GitAdapter,
|
|
41
|
+
commitHash: string,
|
|
42
|
+
type: string,
|
|
43
|
+
): Promise<Entry[]> {
|
|
44
|
+
const allEntries = await gitAdapter.getContentEntries(commitHash)
|
|
45
|
+
return allEntries
|
|
46
|
+
.filter(
|
|
47
|
+
(contentEntry: ContentEntry) => contentEntry.metadata.type === type,
|
|
48
|
+
)
|
|
49
|
+
.map((value) => ({ ...value.data, id: value.id }))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public async findByTypeId(
|
|
53
|
+
gitAdapter: GitAdapter,
|
|
54
|
+
commitHash: string,
|
|
55
|
+
type: string,
|
|
56
|
+
id: ID,
|
|
57
|
+
): Promise<Entry> {
|
|
58
|
+
const allEntries = await gitAdapter.getContentEntries(commitHash)
|
|
59
|
+
const requestedEntry = allEntries.filter(
|
|
60
|
+
(contentEntry: ContentEntry) => contentEntry.id === (id as string),
|
|
61
|
+
)[0]
|
|
62
|
+
if (requestedEntry === undefined || requestedEntry.metadata.type !== type) {
|
|
63
|
+
throw new Error(`Not found: ${type}, ${id}`)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return { ...requestedEntry.data, id: id }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public async createType(
|
|
70
|
+
gitAdapter: GitAdapter,
|
|
71
|
+
branch: string,
|
|
72
|
+
commitHash: string,
|
|
73
|
+
type: string,
|
|
74
|
+
data: Entry,
|
|
75
|
+
message: string,
|
|
76
|
+
): Promise<CommitResult> {
|
|
77
|
+
const id = uuidv4()
|
|
78
|
+
const commit = await gitAdapter.createCommit({
|
|
79
|
+
ref: branch,
|
|
80
|
+
parentSha: commitHash,
|
|
81
|
+
contentEntries: [
|
|
82
|
+
{
|
|
83
|
+
id: id,
|
|
84
|
+
data: data,
|
|
85
|
+
metadata: {
|
|
86
|
+
type: type,
|
|
87
|
+
},
|
|
88
|
+
deletion: false,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
message: message,
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
id,
|
|
96
|
+
ref: commit.ref,
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public async updateByTypeId(
|
|
101
|
+
gitAdapter: GitAdapter,
|
|
102
|
+
branch: string,
|
|
103
|
+
commitHash: string,
|
|
104
|
+
type: string,
|
|
105
|
+
id: ID,
|
|
106
|
+
data: Entry,
|
|
107
|
+
message: string,
|
|
108
|
+
): Promise<CommitResult> {
|
|
109
|
+
const allEntries = await gitAdapter.getContentEntries(commitHash)
|
|
110
|
+
const requestedEntry = allEntries.filter(
|
|
111
|
+
(contentEntry: ContentEntry) => contentEntry.id === (id as string),
|
|
112
|
+
)[0]
|
|
113
|
+
if (requestedEntry === undefined || requestedEntry.metadata.type !== type) {
|
|
114
|
+
throw new Error(`Not found: ${type}, ${id}`)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const newData: Entry = { ...requestedEntry.data, ...data }
|
|
118
|
+
|
|
119
|
+
const commit = await gitAdapter.createCommit({
|
|
120
|
+
ref: branch,
|
|
121
|
+
parentSha: commitHash,
|
|
122
|
+
contentEntries: [
|
|
123
|
+
{
|
|
124
|
+
id: id,
|
|
125
|
+
data: newData,
|
|
126
|
+
metadata: requestedEntry.metadata,
|
|
127
|
+
deletion: false,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
message: message,
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
id,
|
|
135
|
+
ref: commit.ref,
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public async deleteByTypeId(
|
|
140
|
+
gitAdapter: GitAdapter,
|
|
141
|
+
branch: string,
|
|
142
|
+
commitHash: string,
|
|
143
|
+
type: string,
|
|
144
|
+
id: ID,
|
|
145
|
+
message: string,
|
|
146
|
+
): Promise<CommitResult> {
|
|
147
|
+
const allEntries = await gitAdapter.getContentEntries(commitHash)
|
|
148
|
+
const requestedEntry = allEntries.filter(
|
|
149
|
+
(contentEntry: ContentEntry) => contentEntry.id === (id as string),
|
|
150
|
+
)[0]
|
|
151
|
+
if (requestedEntry === undefined || requestedEntry.metadata.type !== type) {
|
|
152
|
+
throw new Error(`Not found: ${type}, ${id}`)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const commit = await gitAdapter.createCommit({
|
|
156
|
+
ref: branch,
|
|
157
|
+
parentSha: commitHash,
|
|
158
|
+
contentEntries: [
|
|
159
|
+
{
|
|
160
|
+
id: id,
|
|
161
|
+
data: {},
|
|
162
|
+
metadata: requestedEntry.metadata,
|
|
163
|
+
deletion: true,
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
message: message,
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
id,
|
|
171
|
+
ref: commit.ref,
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface CommitResult {
|
|
177
|
+
id: ID
|
|
178
|
+
ref: string // commit sha
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export type ID = string
|
|
182
|
+
|
|
183
|
+
export type Entry = Record<string, unknown>
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "commonjs",
|
|
4
|
+
"declaration": true,
|
|
5
|
+
"removeComments": true,
|
|
6
|
+
"emitDecoratorMetadata": true,
|
|
7
|
+
"experimentalDecorators": true,
|
|
8
|
+
"allowSyntheticDefaultImports": true,
|
|
9
|
+
"target": "es2017",
|
|
10
|
+
"sourceMap": true,
|
|
11
|
+
"outDir": "./dist",
|
|
12
|
+
"baseUrl": "./",
|
|
13
|
+
"incremental": true,
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"esModuleInterop": true,
|
|
16
|
+
"strict": true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const path = require('node:path')
|
|
2
|
+
module.exports = (options, webpack) => {
|
|
3
|
+
return {
|
|
4
|
+
...options,
|
|
5
|
+
devtool: 'source-map', // create source map for debugging
|
|
6
|
+
externals: [],
|
|
7
|
+
entry: {
|
|
8
|
+
main: './src/index.ts',
|
|
9
|
+
},
|
|
10
|
+
output: {
|
|
11
|
+
...options.output,
|
|
12
|
+
libraryTarget: 'commonjs2',
|
|
13
|
+
},
|
|
14
|
+
plugins: [
|
|
15
|
+
...options.plugins,
|
|
16
|
+
],
|
|
17
|
+
resolve: {
|
|
18
|
+
// @see https://github.com/apollographql/apollo-server/issues/4983
|
|
19
|
+
extensions: ['.ts', '.js'],
|
|
20
|
+
alias: {
|
|
21
|
+
graphql$: path.resolve(__dirname, 'node_modules/graphql/index.js'),
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
}
|