@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
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
parser: '@typescript-eslint/parser',
|
|
3
|
+
parserOptions: {
|
|
4
|
+
project: 'tsconfig.json',
|
|
5
|
+
sourceType: 'module',
|
|
6
|
+
},
|
|
7
|
+
plugins: ['@typescript-eslint/eslint-plugin'],
|
|
8
|
+
extends: [
|
|
9
|
+
'plugin:@typescript-eslint/recommended',
|
|
10
|
+
'plugin:prettier/recommended',
|
|
11
|
+
],
|
|
12
|
+
root: true,
|
|
13
|
+
env: {
|
|
14
|
+
node: true,
|
|
15
|
+
jest: true,
|
|
16
|
+
},
|
|
17
|
+
ignorePatterns: ['.eslintrc.js'],
|
|
18
|
+
rules: {
|
|
19
|
+
'@typescript-eslint/interface-name-prefix': 'off',
|
|
20
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
21
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
22
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
23
|
+
},
|
|
24
|
+
};
|
package/.prettierrc
ADDED
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
3
|
+
|
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [0.7.0] - 2023-05-12
|
|
8
|
+
### Changed
|
|
9
|
+
- Rename organization
|
|
10
|
+
- Remove deprecated code
|
|
11
|
+
|
|
12
|
+
## [0.6.1] - 2023-05-07
|
|
13
|
+
### Changed
|
|
14
|
+
- Improve documentation
|
|
15
|
+
|
|
16
|
+
## [0.6.0] - 2023-04-27
|
|
17
|
+
### Changed
|
|
18
|
+
- Enable strict TypeScript for improved type safety
|
|
19
|
+
- Update packages to address NPM security audit
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- [#23](https://github.com/commitspark/graphql-api/issues/23) Data of unions with non-Entry members is
|
|
23
|
+
not discernible after serialization
|
|
24
|
+
|
|
25
|
+
## [0.5.4] - 2023-03-15
|
|
26
|
+
### Changed
|
|
27
|
+
- Remove dependency injection package to support bundling with webpack & co.
|
|
28
|
+
- Upgrade to Apollo Server 4.5
|
|
29
|
+
|
|
30
|
+
## [0.5.3] - 2023-03-12
|
|
31
|
+
### Changed
|
|
32
|
+
- Improve GraphQL endpoint type definition
|
|
33
|
+
|
|
34
|
+
## [0.5.2] - 2022-11-14
|
|
35
|
+
### Changed
|
|
36
|
+
- Update dependencies
|
|
37
|
+
- Upgrade to Apollo Server 4
|
|
38
|
+
|
|
39
|
+
## [0.5.1] - 2022-11-04
|
|
40
|
+
### Changed
|
|
41
|
+
- Clean up unused dependencies
|
|
42
|
+
- Extensive update of README
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
- Fix omission of providing preceding commit hash when requesting a new commit from Git adapter
|
|
46
|
+
|
|
47
|
+
## [0.5.0] - 2022-11-01
|
|
48
|
+
### Changed
|
|
49
|
+
- Move NPM package to organization namespace
|
|
50
|
+
- Update to organization-based `git-adapter`
|
|
51
|
+
|
|
52
|
+
## [0.4.1] - 2022-10-25
|
|
53
|
+
### Changed
|
|
54
|
+
- Update to Git Adapter interface 0.4.0
|
|
55
|
+
|
|
56
|
+
## [0.4.0] - 2022-10-25
|
|
57
|
+
### Changed
|
|
58
|
+
- Move responsibility for Git adapter lifecycle out of library
|
|
59
|
+
- Make type query use commit hash for better performance
|
|
60
|
+
|
|
61
|
+
## [0.3.0] - 2022-10-24
|
|
62
|
+
### Changed
|
|
63
|
+
- Drop NestJS in favor of awilix due to https://github.com/nestjs/nest/issues/9622
|
|
64
|
+
|
|
65
|
+
## [0.2.1] - 2022-10-11
|
|
66
|
+
### Fixed
|
|
67
|
+
- Export signature of `ApiService`
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
- Move example application into [separate repository](https://github.com/commitspark/example-code-serverless)
|
|
71
|
+
|
|
72
|
+
## [0.2.0] - 2022-10-07
|
|
73
|
+
### Changed
|
|
74
|
+
- Move GitLab (SaaS) implementation into [separate repository](https://github.com/commitspark/git-adapter-gitlab)
|
|
75
|
+
- Refactor code to be used as library
|
|
76
|
+
- Move application-specific code to example directory
|
|
77
|
+
- Upgrade to NestJS 9
|
|
78
|
+
- Refactor code to be truly stateless
|
|
79
|
+
|
|
80
|
+
## [0.1.0] - 2022-07-15
|
|
81
|
+
|
|
82
|
+
### Added
|
|
83
|
+
- Initial release
|
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Markus Weiland
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Introduction
|
|
2
|
+
|
|
3
|
+
**This library dynamically generates a GraphQL API that allows reading and writing structured text content to and from a
|
|
4
|
+
Git repository.**
|
|
5
|
+
|
|
6
|
+
Queries and mutations offered by the generated API are determined by a vanilla GraphQL type definition file inside the
|
|
7
|
+
Git repository.
|
|
8
|
+
|
|
9
|
+
Content is stored using plain YAML text files in the same Git repository. No other data store or configuration is
|
|
10
|
+
needed.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
*Commitspark is in tech-preview, i.e. it is not yet feature-complete, missing some error handling and tests, and may
|
|
15
|
+
implement breaking changes before a first production-ready release.*
|
|
16
|
+
|
|
17
|
+
# Usage
|
|
18
|
+
|
|
19
|
+
Use this library to query structured content from a Git repository via GraphQL e.g. in order to fill frontends such as a
|
|
20
|
+
Next.js-based website with content. The generated GraphQL API is similar to those offered by headless content management
|
|
21
|
+
systems (CMS), only that content comes from a Git repository and not a proprietary storage or API.
|
|
22
|
+
|
|
23
|
+
To edit content, either use the [Commitspark user interface](https://commitspark.com) or execute the library's generated
|
|
24
|
+
GraphQL mutations yourself. (Or if you know what you're doing, you could even edit the YAML content files directly in a
|
|
25
|
+
repository).
|
|
26
|
+
|
|
27
|
+
To change the content model, simply modify the GraphQL type definition (schema) file. For details, see below.
|
|
28
|
+
|
|
29
|
+
# Running the Commitspark library
|
|
30
|
+
|
|
31
|
+
There are two common ways to run this library:
|
|
32
|
+
|
|
33
|
+
1. By making GraphQL calls directly against the library as a code dependency in your own JavaScript / TypeScript /
|
|
34
|
+
NodeJS application (NPM package name `@commitspark/graphql-api`)
|
|
35
|
+
2. By making GraphQL calls over HTTP to the library wrapped in
|
|
36
|
+
a webserver or Lambda function of choice
|
|
37
|
+
([NodeJS Express server example](https://github.com/commitspark/example-http-express),
|
|
38
|
+
[Lambda function example](https://github.com/commitspark/example-code-serverless))
|
|
39
|
+
|
|
40
|
+
In both cases, it is recommended to use a dedicated Git repository for content and not use the same repository as used
|
|
41
|
+
for application code. See "Git repository hosting" below on where this content repository can be located.
|
|
42
|
+
|
|
43
|
+
# Getting started
|
|
44
|
+
|
|
45
|
+
If you're new to Commitspark, the quickest way to see Commitspark in action is as follows:
|
|
46
|
+
|
|
47
|
+
1. [Copy the example Git content repository](https://github.com/commitspark/example-content-website/generate)
|
|
48
|
+
2. [Copy the example Next.js application repository](https://github.com/commitspark/example-nextjs/generate)
|
|
49
|
+
3. In the application repository, follow the simple
|
|
50
|
+
[README](https://github.com/commitspark/example-nextjs/blob/main/README.md) steps to point Next.js to your content
|
|
51
|
+
repository
|
|
52
|
+
|
|
53
|
+
# Git repository hosting
|
|
54
|
+
|
|
55
|
+
Commitspark follows an adapter pattern, so it can read from and write to Git repositories in various places, either
|
|
56
|
+
hosted or locally. When using the library, pass an adapter instance as needed by your project.
|
|
57
|
+
|
|
58
|
+
The following adapters exist:
|
|
59
|
+
|
|
60
|
+
| Adapter | Description | NPM package name |
|
|
61
|
+
|---------------------------------------------------------------------|------------------------------------------------------------|---------------------------------------|
|
|
62
|
+
| [GitHub](https://github.com/commitspark/git-adapter-github) | Provides access to Git repositories hosted on github.com | `@commitspark/git-adapter-github` |
|
|
63
|
+
| [GitLab (SaaS)](https://github.com/commitspark/git-adapter-gitlab) | Provides access to Git repositories hosted on gitlab.com | `@commitspark/git-adapter-gitlab` |
|
|
64
|
+
| [Filesystem](https://github.com/commitspark/git-adapter-filesystem) | Provides read-only access to files on the filesystem level | `@commitspark/git-adapter-filesystem` |
|
|
65
|
+
|
|
66
|
+
In case you want to build your own adapter, implement the interfaces found
|
|
67
|
+
in [this repository](https://github.com/commitspark/git-adapter).
|
|
68
|
+
|
|
69
|
+
# Making GraphQL calls
|
|
70
|
+
|
|
71
|
+
## Picking from the Git tree
|
|
72
|
+
|
|
73
|
+
As Commitspark is Git-based, all queries and mutations support traversing the Git commit tree by setting the `ref`
|
|
74
|
+
argument in library calls to a
|
|
75
|
+
|
|
76
|
+
* ref (i.e. commit hash),
|
|
77
|
+
* branch name, or
|
|
78
|
+
* tag name (light or regular)
|
|
79
|
+
|
|
80
|
+
This enables great flexibility, e.g. to retrieve always the same content of a specific (historic) commit, to have
|
|
81
|
+
different branches with different content, or to retrieve content by tag such as reviewed content.
|
|
82
|
+
|
|
83
|
+
## Obtaining the generated GraphQL schema
|
|
84
|
+
|
|
85
|
+
Commitspark dynamically extends the GraphQL schema file's content model at runtime with additional types as well as
|
|
86
|
+
queries and mutations. This extended schema can be retrieved by calling `getSchema()`.
|
|
87
|
+
|
|
88
|
+
Compared to schema data obtained through GraphQL introspection, the schema returned here also includes directive
|
|
89
|
+
declarations and annotations, allowing for development of additional tools that require this information.
|
|
90
|
+
|
|
91
|
+
## Reading data
|
|
92
|
+
|
|
93
|
+
The `request` argument of `postGraphQL()` expects a conventional GraphQL query and supports query variables as well as
|
|
94
|
+
introspection. Commitspark also transparently resolves references between @Entry-annotated content entries (see below),
|
|
95
|
+
allowing for retrieval of complex data in a single query.
|
|
96
|
+
|
|
97
|
+
### Generated queries
|
|
98
|
+
|
|
99
|
+
For each content type annotated with `@Entry` in the content model (see below), the following queries are generated:
|
|
100
|
+
|
|
101
|
+
* Query a single entry of a type by ID, e.g. `MyType(id:"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"): MyType`
|
|
102
|
+
* Query all entries of a type, e.g. `allMyTypes: [MyType]`
|
|
103
|
+
|
|
104
|
+
## Writing data
|
|
105
|
+
|
|
106
|
+
The `request` argument of `postGraphQL()` expects a conventional GraphQL mutation and supports mutation variables as
|
|
107
|
+
well as introspection. Mutation operations work on branch names only and (when successful) each append a new commit on
|
|
108
|
+
HEAD in the given branch. To avoid race conditions, mutations in calls with multiple mutations are processed
|
|
109
|
+
sequentially (see the [GraphQL documentation](https://graphql.org/learn/queries/#multiple-fields-in-mutations)).
|
|
110
|
+
|
|
111
|
+
### Generated queries
|
|
112
|
+
|
|
113
|
+
For each content type annotated with `@Entry` (see below), the following mutations are generated:
|
|
114
|
+
|
|
115
|
+
* Create a single entry of a type, e.g.
|
|
116
|
+
`createMyType(message:"Commit message", data:{...}): MyType`
|
|
117
|
+
* Mutate a single entry of a type by ID, e.g.
|
|
118
|
+
`updateMyType(id:"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", message:"Commit message", data:{...}): MyType`
|
|
119
|
+
* Delete a single entry of a type by ID, e.g.
|
|
120
|
+
`deleteMyType(id:"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", message:"Commit message"): { id }`
|
|
121
|
+
|
|
122
|
+
## Authenticating with your repository
|
|
123
|
+
|
|
124
|
+
Depending on the Git adapter used (see above), an authentication token must be provided. See the corresponding adapter
|
|
125
|
+
README for details.
|
|
126
|
+
|
|
127
|
+
# Technical documentation
|
|
128
|
+
|
|
129
|
+
## Content model
|
|
130
|
+
|
|
131
|
+
The content model (i.e. schema) is defined in a single GraphQL type definition text file using the
|
|
132
|
+
[GraphQL type system](https://graphql.org/learn/schema/).
|
|
133
|
+
|
|
134
|
+
The schema file must be located at `schema/schema.graphql` inside the Git repository.
|
|
135
|
+
|
|
136
|
+
Commitspark currently supports the following data types:
|
|
137
|
+
|
|
138
|
+
* `type`
|
|
139
|
+
* `union`
|
|
140
|
+
* `enum`
|
|
141
|
+
|
|
142
|
+
### Content entries
|
|
143
|
+
|
|
144
|
+
To denote which content type instances are to be given a unique identity for referencing, a directive `@Entry` is
|
|
145
|
+
to be declared (this must be done right in the schema file so that the schema remains valid).
|
|
146
|
+
|
|
147
|
+
To define the `@Entry` directive, simply add this line to the schema file:
|
|
148
|
+
|
|
149
|
+
```graphql
|
|
150
|
+
directive @Entry on OBJECT
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
To promote a content type to Entry, annotate the type as follows:
|
|
154
|
+
|
|
155
|
+
```graphql
|
|
156
|
+
type MyType @Entry {
|
|
157
|
+
id: ID!
|
|
158
|
+
# ...
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Important:** Any type annotated with `@Entry` must have a field `id` of type `ID!`.
|
|
163
|
+
|
|
164
|
+
**Note:** Only apply `@Entry` to content types that you actually want to reference or link to from other entries. This
|
|
165
|
+
keeps the number of entries low and performance up.
|
|
166
|
+
|
|
167
|
+
## Content storage
|
|
168
|
+
|
|
169
|
+
Content entries, i.e. instances of content types annotated with `@Entry`, are stored as `.yaml` YAML text files inside
|
|
170
|
+
a folder `entries` in the repository.
|
|
171
|
+
|
|
172
|
+
The filename (excluding file extension) constitutes the entry ID and is generated as a UUID4 string by Commitspark.
|
|
173
|
+
|
|
174
|
+
Entry files have the following structure:
|
|
175
|
+
|
|
176
|
+
```yaml
|
|
177
|
+
metadata:
|
|
178
|
+
type: MyType # name of type as defined in your schema
|
|
179
|
+
data:
|
|
180
|
+
# ... fields of the type as defined in your schema
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Serialization
|
|
184
|
+
|
|
185
|
+
References to types annotated with `@Entry` are stored using a sub-field `id`.
|
|
186
|
+
|
|
187
|
+
For example, consider the following schema:
|
|
188
|
+
|
|
189
|
+
```graphql
|
|
190
|
+
type Page @Entry {
|
|
191
|
+
id: ID!
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
type Link @Entry {
|
|
195
|
+
target: Page
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
An entry for `Link` referencing a `Page` will look like this:
|
|
200
|
+
|
|
201
|
+
```yaml
|
|
202
|
+
metadata:
|
|
203
|
+
type: Link
|
|
204
|
+
data:
|
|
205
|
+
target:
|
|
206
|
+
id: aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa # ID of targeted Page
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
# FAQ
|
|
210
|
+
|
|
211
|
+
* Q: Do I need to run a web server or serverless function to use Commitspark?
|
|
212
|
+
|
|
213
|
+
A: No. You can pass a GraphQL request string directly to the Commitspark library without going through HTTP. This can
|
|
214
|
+
be useful e.g. in CI/CD pipelines where you might not want to bring up a server just to execute a GraphQL query.
|
|
215
|
+
|
|
216
|
+
* Q: Do I really need to have two separate repositories for application code and content?
|
|
217
|
+
|
|
218
|
+
A: No. You can have both in the same repository but depending on how your software and content workflows are
|
|
219
|
+
structured, you may have a hard time finding a workflow that works equally well for both domains.
|
|
220
|
+
|
|
221
|
+
# License
|
|
222
|
+
|
|
223
|
+
The code in this repository is licensed under the permissive ISC license (see [LICENSE](LICENSE)).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ApolloConfigFactoryService } from '../graphql/apollo-config-factory.service';
|
|
2
|
+
import { SchemaGeneratorService } from '../graphql/schema-generator.service';
|
|
3
|
+
import { GraphQLFormattedError } from 'graphql';
|
|
4
|
+
import { GitAdapter } from '@commitspark/git-adapter';
|
|
5
|
+
import { VariableValues } from '@apollo/server/src/externalTypes/graphql';
|
|
6
|
+
import { GraphQLRequest } from '@apollo/server/src/externalTypes';
|
|
7
|
+
import { DocumentNode, TypedQueryDocumentNode } from 'graphql/index';
|
|
8
|
+
export declare class ApiService {
|
|
9
|
+
private readonly apolloConfigFactory;
|
|
10
|
+
private readonly schemaGenerator;
|
|
11
|
+
constructor(apolloConfigFactory: ApolloConfigFactoryService, schemaGenerator: SchemaGeneratorService);
|
|
12
|
+
postGraphQL<TData = Record<string, unknown>, TVariables extends VariableValues = VariableValues>(gitAdapter: GitAdapter, ref: string, request: Omit<Omit<GraphQLRequest<TVariables>, 'query'>, 'http'> & {
|
|
13
|
+
query?: string | DocumentNode | TypedQueryDocumentNode<TData, TVariables>;
|
|
14
|
+
}): Promise<GraphQLResponse<TData | null>>;
|
|
15
|
+
getSchema(gitAdapter: GitAdapter, ref: string): Promise<SchemaResponse>;
|
|
16
|
+
}
|
|
17
|
+
export interface ApolloContext {
|
|
18
|
+
branch: string;
|
|
19
|
+
gitAdapter: GitAdapter;
|
|
20
|
+
getCurrentRef(): string;
|
|
21
|
+
setCurrentRef(sha: string): void;
|
|
22
|
+
}
|
|
23
|
+
export interface GraphQLResponse<TData> {
|
|
24
|
+
ref: string;
|
|
25
|
+
data?: TData;
|
|
26
|
+
errors: ReadonlyArray<GraphQLFormattedError> | undefined;
|
|
27
|
+
}
|
|
28
|
+
export interface SchemaResponse {
|
|
29
|
+
ref: string;
|
|
30
|
+
data: string;
|
|
31
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiService = void 0;
|
|
4
|
+
const server_1 = require("@apollo/server");
|
|
5
|
+
class ApiService {
|
|
6
|
+
constructor(apolloConfigFactory, schemaGenerator) {
|
|
7
|
+
this.apolloConfigFactory = apolloConfigFactory;
|
|
8
|
+
this.schemaGenerator = schemaGenerator;
|
|
9
|
+
}
|
|
10
|
+
async postGraphQL(gitAdapter, ref, request) {
|
|
11
|
+
let currentRef = await gitAdapter.getLatestCommitHash(ref);
|
|
12
|
+
const context = {
|
|
13
|
+
branch: ref,
|
|
14
|
+
gitAdapter: gitAdapter,
|
|
15
|
+
getCurrentRef() {
|
|
16
|
+
return currentRef;
|
|
17
|
+
},
|
|
18
|
+
setCurrentRef(refArg) {
|
|
19
|
+
currentRef = refArg;
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
const apolloDriverConfig = await this.apolloConfigFactory.createGqlOptions(context);
|
|
23
|
+
const apolloServer = new server_1.ApolloServer(Object.assign({}, apolloDriverConfig));
|
|
24
|
+
const result = await apolloServer.executeOperation(request, {
|
|
25
|
+
contextValue: context,
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
ref: context.getCurrentRef(),
|
|
29
|
+
data: result.body.kind === 'single'
|
|
30
|
+
? result.body.singleResult.data
|
|
31
|
+
: undefined,
|
|
32
|
+
errors: result.body.kind === 'single'
|
|
33
|
+
? result.body.singleResult.errors
|
|
34
|
+
: undefined,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async getSchema(gitAdapter, ref) {
|
|
38
|
+
let currentRef = await gitAdapter.getLatestCommitHash(ref);
|
|
39
|
+
const contextGenerator = () => ({
|
|
40
|
+
branch: ref,
|
|
41
|
+
gitAdapter: gitAdapter,
|
|
42
|
+
getCurrentRef() {
|
|
43
|
+
return currentRef;
|
|
44
|
+
},
|
|
45
|
+
setCurrentRef(refArg) {
|
|
46
|
+
currentRef = refArg;
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
const typeDefinitionStrings = (await this.schemaGenerator.generateSchema(contextGenerator())).typeDefs;
|
|
50
|
+
if (!Array.isArray(typeDefinitionStrings)) {
|
|
51
|
+
throw new Error('Unknown element');
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
ref: contextGenerator().getCurrentRef(),
|
|
55
|
+
data: typeDefinitionStrings.join('\n'),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.ApiService = ApiService;
|
|
60
|
+
//# sourceMappingURL=api.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.service.js","sourceRoot":"","sources":["../../src/app/api.service.ts"],"names":[],"mappings":";;;AAIA,2CAAkE;AAKlE,MAAa,UAAU;IACrB,YACmB,mBAA+C,EAC/C,eAAuC;QADvC,wBAAmB,GAAnB,mBAAmB,CAA4B;QAC/C,oBAAe,GAAf,eAAe,CAAwB;IACvD,CAAC;IAEJ,KAAK,CAAC,WAAW,CAIf,UAAsB,EACtB,GAAW,EAEX,OAEC;QAED,IAAI,UAAU,GAAG,MAAM,UAAU,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAA;QAC1D,MAAM,OAAO,GAAkB;YAC7B,MAAM,EAAE,GAAG;YACX,UAAU,EAAE,UAAU;YACtB,aAAa;gBACX,OAAO,UAAU,CAAA;YACnB,CAAC;YACD,aAAa,CAAC,MAAc;gBAC1B,UAAU,GAAG,MAAM,CAAA;YACrB,CAAC;SACF,CAAA;QAED,MAAM,kBAAkB,GACtB,MAAM,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAE1D,MAAM,YAAY,GAAG,IAAI,qBAAY,mBAChC,kBAAkB,EACrB,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,gBAAgB,CAChD,OAAO,EACP;YACE,YAAY,EAAE,OAAO;SACtB,CACF,CAAA;QAED,OAAO;YACL,GAAG,EAAE,OAAO,CAAC,aAAa,EAAE;YAC5B,IAAI,EACF,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ;gBAC3B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI;gBAC/B,CAAC,CAAC,SAAS;YACf,MAAM,EACJ,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ;gBAC3B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM;gBACjC,CAAC,CAAC,SAAS;SAChB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CACb,UAAsB,EACtB,GAAW;QAEX,IAAI,UAAU,GAAG,MAAM,UAAU,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAA;QAC1D,MAAM,gBAAgB,GAAG,GAAG,EAAE,CAC5B,CAAC;YACC,MAAM,EAAE,GAAG;YACX,UAAU,EAAE,UAAU;YACtB,aAAa;gBACX,OAAO,UAAU,CAAA;YACnB,CAAC;YACD,aAAa,CAAC,MAAc;gBAC1B,UAAU,GAAG,MAAM,CAAA;YACrB,CAAC;SACgB,CAAA,CAAA;QAErB,MAAM,qBAAqB,GAAG,CAC5B,MAAM,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,gBAAgB,EAAE,CAAC,CAC9D,CAAC,QAAQ,CAAA;QACV,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;SACnC;QAED,OAAO;YACL,GAAG,EAAE,gBAAgB,EAAE,CAAC,aAAa,EAAE;YACvC,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;SACvC,CAAA;IACH,CAAC;CACF;AArFD,gCAqFC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.apiService = void 0;
|
|
4
|
+
const api_service_1 = require("./app/api.service");
|
|
5
|
+
const apollo_config_factory_service_1 = require("./graphql/apollo-config-factory.service");
|
|
6
|
+
const entry_reference_resolver_generator_1 = require("./graphql/resolver-generators/entry-reference-resolver.generator");
|
|
7
|
+
const input_type_generator_service_1 = require("./graphql/input-type-generator.service");
|
|
8
|
+
const queries_mutations_generator_service_1 = require("./graphql/queries-mutations-generator.service");
|
|
9
|
+
const schema_analyzer_service_1 = require("./graphql/schema-analyzer.service");
|
|
10
|
+
const schema_root_type_generator_service_1 = require("./graphql/schema-root-type-generator.service");
|
|
11
|
+
const union_type_resolver_generator_1 = require("./graphql/resolver-generators/union-type-resolver-generator");
|
|
12
|
+
const persistence_service_1 = require("./persistence/persistence.service");
|
|
13
|
+
const schema_generator_service_1 = require("./graphql/schema-generator.service");
|
|
14
|
+
const mutation_create_resolver_generator_1 = require("./graphql/resolver-generators/mutation-create-resolver-generator");
|
|
15
|
+
const mutation_delete_resolver_generator_1 = require("./graphql/resolver-generators/mutation-delete-resolver-generator");
|
|
16
|
+
const mutation_update_resolver_generator_1 = require("./graphql/resolver-generators/mutation-update.resolver-generator");
|
|
17
|
+
const query_all_resolver_generator_1 = require("./graphql/resolver-generators/query-all-resolver-generator");
|
|
18
|
+
const query_by_id_resolver_generator_1 = require("./graphql/resolver-generators/query-by-id-resolver-generator");
|
|
19
|
+
const query_count_all_resolver_generator_1 = require("./graphql/resolver-generators/query-count-all-resolver-generator");
|
|
20
|
+
const query_type_by_id_resolver_generator_1 = require("./graphql/resolver-generators/query-type-by-id-resolver-generator");
|
|
21
|
+
const schema_validator_1 = require("./graphql/schema-validator");
|
|
22
|
+
const union_value_resolver_generator_1 = require("./graphql/resolver-generators/union-value-resolver-generator");
|
|
23
|
+
const entry_reference_util_1 = require("./graphql/schema-utils/entry-reference-util");
|
|
24
|
+
const entryReferenceUtil = new entry_reference_util_1.EntryReferenceUtil();
|
|
25
|
+
const schemaValidator = new schema_validator_1.SchemaValidator();
|
|
26
|
+
const persistenceService = new persistence_service_1.PersistenceService();
|
|
27
|
+
const schemaRootTypeGeneratorService = new schema_root_type_generator_service_1.SchemaRootTypeGeneratorService();
|
|
28
|
+
const inputTypeGeneratorService = new input_type_generator_service_1.InputTypeGeneratorService(entryReferenceUtil);
|
|
29
|
+
const schemaAnalyzerService = new schema_analyzer_service_1.SchemaAnalyzerService(entryReferenceUtil);
|
|
30
|
+
const entryReferenceResolverGeneratorService = new entry_reference_resolver_generator_1.EntryReferenceResolverGenerator(persistenceService);
|
|
31
|
+
const mutationCreateResolverGenerator = new mutation_create_resolver_generator_1.MutationCreateResolverGenerator(persistenceService);
|
|
32
|
+
const mutationDeleteResolverGenerator = new mutation_delete_resolver_generator_1.MutationDeleteResolverGenerator(persistenceService);
|
|
33
|
+
const mutationUpdateResolverGenerator = new mutation_update_resolver_generator_1.MutationUpdateResolverGenerator(persistenceService);
|
|
34
|
+
const queryAllResolverGenerator = new query_all_resolver_generator_1.QueryAllResolverGenerator(persistenceService);
|
|
35
|
+
const queryByIdResolverGenerator = new query_by_id_resolver_generator_1.QueryByIdResolverGenerator(persistenceService);
|
|
36
|
+
const queryCountAllResolverGenerator = new query_count_all_resolver_generator_1.QueryCountAllResolverGenerator(persistenceService);
|
|
37
|
+
const queryTypeByIdResolverGenerator = new query_type_by_id_resolver_generator_1.QueryTypeByIdResolverGenerator(persistenceService);
|
|
38
|
+
const unionTypeResolverGenerator = new union_type_resolver_generator_1.UnionTypeResolverGenerator(persistenceService, entryReferenceUtil);
|
|
39
|
+
const unionValueResolverGenerator = new union_value_resolver_generator_1.UnionValueResolverGenerator(entryReferenceUtil);
|
|
40
|
+
const queriesMutationsGeneratorService = new queries_mutations_generator_service_1.QueriesMutationsGeneratorService(queryAllResolverGenerator, queryByIdResolverGenerator, queryCountAllResolverGenerator, queryTypeByIdResolverGenerator, mutationCreateResolverGenerator, mutationUpdateResolverGenerator, mutationDeleteResolverGenerator);
|
|
41
|
+
const schemaGeneratorService = new schema_generator_service_1.SchemaGeneratorService(queriesMutationsGeneratorService, schemaAnalyzerService, inputTypeGeneratorService, schemaRootTypeGeneratorService, entryReferenceResolverGeneratorService, unionTypeResolverGenerator, unionValueResolverGenerator, schemaValidator);
|
|
42
|
+
const apolloConfigFactoryService = new apollo_config_factory_service_1.ApolloConfigFactoryService(schemaGeneratorService);
|
|
43
|
+
exports.apiService = new api_service_1.ApiService(apolloConfigFactoryService, schemaGeneratorService);
|
|
44
|
+
//# sourceMappingURL=container.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":";;;AAAA,mDAA8C;AAC9C,2FAAoF;AACpF,yHAAkH;AAClH,yFAAkF;AAClF,uGAAgG;AAChG,+EAAyE;AACzE,qGAA6F;AAC7F,+GAAwG;AACxG,2EAAsE;AACtE,iFAA2E;AAC3E,yHAAkH;AAClH,yHAAkH;AAClH,yHAAkH;AAClH,6GAAsG;AACtG,iHAAyG;AACzG,yHAAiH;AACjH,2HAAkH;AAClH,iEAA4D;AAC5D,iHAA0G;AAC1G,sFAAgF;AAIhF,MAAM,kBAAkB,GAAG,IAAI,yCAAkB,EAAE,CAAA;AACnD,MAAM,eAAe,GAAG,IAAI,kCAAe,EAAE,CAAA;AAC7C,MAAM,kBAAkB,GAAG,IAAI,wCAAkB,EAAE,CAAA;AACnD,MAAM,8BAA8B,GAAG,IAAI,mEAA8B,EAAE,CAAA;AAE3E,MAAM,yBAAyB,GAAG,IAAI,wDAAyB,CAC7D,kBAAkB,CACnB,CAAA;AACD,MAAM,qBAAqB,GAAG,IAAI,+CAAqB,CAAC,kBAAkB,CAAC,CAAA;AAC3E,MAAM,sCAAsC,GAC1C,IAAI,oEAA+B,CAAC,kBAAkB,CAAC,CAAA;AACzD,MAAM,+BAA+B,GAAG,IAAI,oEAA+B,CACzE,kBAAkB,CACnB,CAAA;AACD,MAAM,+BAA+B,GAAG,IAAI,oEAA+B,CACzE,kBAAkB,CACnB,CAAA;AACD,MAAM,+BAA+B,GAAG,IAAI,oEAA+B,CACzE,kBAAkB,CACnB,CAAA;AACD,MAAM,yBAAyB,GAAG,IAAI,wDAAyB,CAC7D,kBAAkB,CACnB,CAAA;AACD,MAAM,0BAA0B,GAAG,IAAI,2DAA0B,CAC/D,kBAAkB,CACnB,CAAA;AACD,MAAM,8BAA8B,GAAG,IAAI,mEAA8B,CACvE,kBAAkB,CACnB,CAAA;AACD,MAAM,8BAA8B,GAAG,IAAI,oEAA8B,CACvE,kBAAkB,CACnB,CAAA;AACD,MAAM,0BAA0B,GAAG,IAAI,0DAA0B,CAC/D,kBAAkB,EAClB,kBAAkB,CACnB,CAAA;AACD,MAAM,2BAA2B,GAAG,IAAI,4DAA2B,CACjE,kBAAkB,CACnB,CAAA;AAED,MAAM,gCAAgC,GAAG,IAAI,sEAAgC,CAC3E,yBAAyB,EACzB,0BAA0B,EAC1B,8BAA8B,EAC9B,8BAA8B,EAC9B,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,CAChC,CAAA;AAED,MAAM,sBAAsB,GAAG,IAAI,iDAAsB,CACvD,gCAAgC,EAChC,qBAAqB,EACrB,yBAAyB,EACzB,8BAA8B,EAC9B,sCAAsC,EACtC,0BAA0B,EAC1B,2BAA2B,EAC3B,eAAe,CAChB,CAAA;AAED,MAAM,0BAA0B,GAAG,IAAI,0DAA0B,CAC/D,sBAAsB,CACvB,CAAA;AAEY,QAAA,UAAU,GAAG,IAAI,wBAAU,CACtC,0BAA0B,EAC1B,sBAAsB,CACvB,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SchemaGeneratorService } from './schema-generator.service';
|
|
2
|
+
import { ApolloContext } from '../app/api.service';
|
|
3
|
+
import { ApolloServerOptions } from '@apollo/server';
|
|
4
|
+
export declare class ApolloConfigFactoryService {
|
|
5
|
+
private readonly schemaGenerator;
|
|
6
|
+
constructor(schemaGenerator: SchemaGeneratorService);
|
|
7
|
+
createGqlOptions(context: ApolloContext): Promise<ApolloServerOptions<ApolloContext>>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApolloConfigFactoryService = void 0;
|
|
4
|
+
const schema_1 = require("@graphql-tools/schema");
|
|
5
|
+
const disabled_1 = require("@apollo/server/plugin/disabled");
|
|
6
|
+
class ApolloConfigFactoryService {
|
|
7
|
+
constructor(schemaGenerator) {
|
|
8
|
+
this.schemaGenerator = schemaGenerator;
|
|
9
|
+
}
|
|
10
|
+
async createGqlOptions(context) {
|
|
11
|
+
const schemaDefinition = await this.schemaGenerator.generateSchema(context);
|
|
12
|
+
const schema = (0, schema_1.makeExecutableSchema)(schemaDefinition);
|
|
13
|
+
return {
|
|
14
|
+
schema: schema,
|
|
15
|
+
plugins: [(0, disabled_1.ApolloServerPluginUsageReportingDisabled)()],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.ApolloConfigFactoryService = ApolloConfigFactoryService;
|
|
20
|
+
//# sourceMappingURL=apollo-config-factory.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apollo-config-factory.service.js","sourceRoot":"","sources":["../../src/graphql/apollo-config-factory.service.ts"],"names":[],"mappings":";;;AAAA,kDAA4D;AAI5D,6DAAyF;AAEzF,MAAa,0BAA0B;IACrC,YAA6B,eAAuC;QAAvC,oBAAe,GAAf,eAAe,CAAwB;IAAG,CAAC;IAExE,KAAK,CAAC,gBAAgB,CACpB,OAAsB;QAEtB,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;QAC3E,MAAM,MAAM,GAAG,IAAA,6BAAoB,EAAC,gBAAgB,CAAC,CAAA;QAErD,OAAO;YACL,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,CAAC,IAAA,mDAAwC,GAAE,CAAC;SAChB,CAAA;IACzC,CAAC;CACF;AAdD,gEAcC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GraphQLNullableType, GraphQLUnionType } from 'graphql/type/definition';
|
|
2
|
+
import { GraphQLObjectType } from 'graphql';
|
|
3
|
+
import { ISchemaAnalyzerResult } from './schema-analyzer.service';
|
|
4
|
+
import { EntryReferenceUtil } from './schema-utils/entry-reference-util';
|
|
5
|
+
export declare class InputTypeGeneratorService {
|
|
6
|
+
private readonly entryReferenceUtil;
|
|
7
|
+
constructor(entryReferenceUtil: EntryReferenceUtil);
|
|
8
|
+
generateFieldInputTypeString(type: GraphQLNullableType): string;
|
|
9
|
+
generateIdInputTypeStrings(schemaAnalyzerResult: ISchemaAnalyzerResult): string[];
|
|
10
|
+
generateObjectInputTypeStrings(objectTypes: GraphQLObjectType[]): string[];
|
|
11
|
+
generateUnionInputTypeStrings(unionTypes: GraphQLUnionType[]): string[];
|
|
12
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InputTypeGeneratorService = void 0;
|
|
4
|
+
const definition_1 = require("graphql/type/definition");
|
|
5
|
+
const graphql_1 = require("graphql");
|
|
6
|
+
class InputTypeGeneratorService {
|
|
7
|
+
constructor(entryReferenceUtil) {
|
|
8
|
+
this.entryReferenceUtil = entryReferenceUtil;
|
|
9
|
+
}
|
|
10
|
+
generateFieldInputTypeString(type) {
|
|
11
|
+
if (type instanceof graphql_1.GraphQLList) {
|
|
12
|
+
return `[${this.generateFieldInputTypeString(type.ofType)}]`;
|
|
13
|
+
}
|
|
14
|
+
else if (type instanceof graphql_1.GraphQLNonNull) {
|
|
15
|
+
return `${this.generateFieldInputTypeString(type.ofType)}!`;
|
|
16
|
+
}
|
|
17
|
+
else if (type instanceof graphql_1.GraphQLObjectType) {
|
|
18
|
+
if (this.entryReferenceUtil.hasEntryDirective(type)) {
|
|
19
|
+
return `${type.name}IdInput`;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
return `${type.name}Input`;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else if (type instanceof definition_1.GraphQLInterfaceType) {
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
else if (type instanceof definition_1.GraphQLUnionType) {
|
|
29
|
+
if (this.entryReferenceUtil.buildsOnTypeWithEntryDirective(type)) {
|
|
30
|
+
return `${type.name}IdInput`;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
return `${type.name}Input`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
return type.name;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
generateIdInputTypeStrings(schemaAnalyzerResult) {
|
|
41
|
+
let typesWithIdField = [];
|
|
42
|
+
typesWithIdField = typesWithIdField.concat(schemaAnalyzerResult.entryDirectiveTypes);
|
|
43
|
+
typesWithIdField = typesWithIdField.concat(schemaAnalyzerResult.interfaceTypes);
|
|
44
|
+
typesWithIdField = typesWithIdField.concat(schemaAnalyzerResult.unionTypes);
|
|
45
|
+
return typesWithIdField.map((type) => {
|
|
46
|
+
return `input ${type.name}IdInput {\n` + ' id:ID!\n' + '}\n';
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
generateObjectInputTypeStrings(objectTypes) {
|
|
50
|
+
return objectTypes.map((objectType) => {
|
|
51
|
+
const name = objectType.name;
|
|
52
|
+
const inputTypeName = `${name}Input`;
|
|
53
|
+
let inputType = `input ${inputTypeName} {\n`;
|
|
54
|
+
for (const fieldsKey in objectType.getFields()) {
|
|
55
|
+
const field = objectType.getFields()[fieldsKey];
|
|
56
|
+
if (field.name === 'id') {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const inputTypeString = this.generateFieldInputTypeString(field.type);
|
|
60
|
+
inputType += ` ${field.name}: ${inputTypeString}\n`;
|
|
61
|
+
}
|
|
62
|
+
inputType += '}\n';
|
|
63
|
+
return inputType;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
generateUnionInputTypeStrings(unionTypes) {
|
|
67
|
+
const typeStrings = unionTypes.map((unionType) => {
|
|
68
|
+
if (this.entryReferenceUtil.buildsOnTypeWithEntryDirective(unionType)) {
|
|
69
|
+
return '';
|
|
70
|
+
}
|
|
71
|
+
let unionInputType = `input ${unionType.name}Input @oneOf {\n`;
|
|
72
|
+
for (const innerType of unionType.getTypes()) {
|
|
73
|
+
const fieldName = innerType.name.toLowerCase().at(0) + innerType.name.substring(1);
|
|
74
|
+
unionInputType += ` ${fieldName}: ${innerType.name}Input\n`;
|
|
75
|
+
}
|
|
76
|
+
unionInputType += '}\n';
|
|
77
|
+
return unionInputType;
|
|
78
|
+
});
|
|
79
|
+
if (typeStrings.join('').length > 0) {
|
|
80
|
+
typeStrings.push('directive @oneOf on INPUT_OBJECT\n');
|
|
81
|
+
}
|
|
82
|
+
return typeStrings;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.InputTypeGeneratorService = InputTypeGeneratorService;
|
|
86
|
+
//# sourceMappingURL=input-type-generator.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-type-generator.service.js","sourceRoot":"","sources":["../../src/graphql/input-type-generator.service.ts"],"names":[],"mappings":"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"}
|