@ttoss/graphql-api 0.1.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/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # @ttoss/graphql-api
2
+
3
+ This package provides an opinionated way to create an GraphQL API using ttoss ecosystem modules. The main goal of this package is to provide a resilient way to create a complex GraphQL API to meet the following goals:
4
+
5
+ 1. **Modular**: you can create your GraphQL API using modules, so you can reduce the complexity of a big GraphQL API.
6
+ 1. **Relay**: ttoss uses Relay as the main GraphQL client, so this package implements the [Relay Server Specification](https://relay.dev/docs/guides/graphql-server-specification/).
7
+ 1. **Build Schema**: as Relay needs an introspection query to work, this package provides a way to build the GraphQL schema by running `ttoss-graphl-api build-schema`.
8
+ 1. **AppSync Support**: this package provides a way to create a GraphQL API that works with AWS AppSync, besides you can also create a local GraphQL API server.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ pnpm add @ttoss/graphql-api graphql
14
+ ```
15
+
16
+ ## Getting Started
17
+
18
+ This library uses [`graphql-compose`](https://graphql-compose.github.io/) to create the GraphQL schema. It re-export all the [`graphql-compose`](https://graphql-compose.github.io/) types and methods, so you can use it directly from this package.
19
+
20
+ ### Type Creation
21
+
22
+ For more examples about how to create types, check the [`graphql-compose`](https://graphql-compose.github.io/docs/basics/understanding-types.html) documentation.
23
+
24
+ ```ts
25
+ import { schemaComposer } from '@ttoss/graphql-api';
26
+
27
+ const UserTC = schemaComposer.createObjectTC({
28
+ name: 'User',
29
+ fields: {
30
+ id: 'ID!',
31
+ name: 'String!',
32
+ },
33
+ });
34
+ ```
35
+
36
+ ### Resolvers
37
+
38
+ ### Integrate All Modules
39
+
40
+ Once you've created all your types and resolvers, you can integrate all the modules to create the GraphQL schema.
41
+
42
+ ```ts title="src/schemaComposer.ts"
43
+ // scr/schemaComposer.ts
44
+ import { schemaComposer } from '@ttoss/graphql-api';
45
+ import './modules/Module1/composer';
46
+ import './modules/Module3/composer';
47
+ import './modules/User/composer';
48
+
49
+ export { schemaComposer };
50
+ ```
51
+
52
+ ## Relay Server Specification
53
+
54
+ As ttoss uses Relay as the main GraphQL client, this library implements the [Relay Server Specification](https://relay.dev/docs/guides/graphql-server-specification/).
55
+
56
+ ### Object Identification
57
+
58
+ Method `composeWithRelay` will handle the object identification for your `ObjectTypeComposer`, it will return a globally unique ID among all types in the following format `base64(TypeName + ':' + recordId)`.
59
+
60
+ Method `composeWithRelay` only works if `ObjectTypeComposer` meets the following requirements:
61
+
62
+ 1. Has defined `recordIdFn`: returns the id for the globalId construction. For example, if you use DynamoDB, you could create id from hash and range keys:
63
+
64
+ ```ts
65
+ UserTC.setRecordIdFn((source) => {
66
+ return `${source.hashKey}:${source.rangeKey}`;
67
+ });
68
+ ```
69
+
70
+ 2. Have `findById` resolver: this resolver will be used by `RootQuery.node` to resolve the object by globalId. For example:
71
+
72
+ ```ts
73
+ UserTC.addResolver({
74
+ name: 'findById',
75
+ type: UserTC,
76
+ args: {
77
+ id: 'String!',
78
+ },
79
+ resolve: ({ args }) => {
80
+ const { type, recordId } = fromGlobalId(args.id);
81
+ // find object
82
+ },
83
+ });
84
+ ```
85
+
86
+ #### Example
87
+
88
+ ```ts
89
+ import {
90
+ composeWithRelay,
91
+ schemaComposer,
92
+ fromGlobalId,
93
+ } from '@ttoss/graphql-api';
94
+
95
+ const UserTC = schemaComposer.createObjectTC({
96
+ name: 'User',
97
+ fields: {
98
+ id: 'ID!',
99
+ name: 'String!',
100
+ },
101
+ });
102
+
103
+ /**
104
+ * 1. Returns you id for the globalId construction.
105
+ */
106
+ UserTC.setRecordIdFn((source) => {
107
+ /**
108
+ * If you use DynamoDB, you could create id from hash and range keys:
109
+ * return `${source.hashKey}:${source.rangeKey}`;
110
+ */
111
+ return source.id;
112
+ });
113
+
114
+ /**
115
+ * 2. Define `findById` resolver (that will be used by `RootQuery.node`).
116
+ */
117
+ UserTC.addResolver({
118
+ name: 'findById',
119
+ type: UserTC,
120
+ args: {
121
+ id: 'String!',
122
+ },
123
+ resolve: ({ args }) => {
124
+ const { type, recordId } = fromGlobalId(args.id);
125
+ // find object
126
+ },
127
+ });
128
+
129
+ /**
130
+ * 3. This will add the `id` field and the `node` query.
131
+ */
132
+ composeWithRelay(UserTC);
133
+ ```
134
+
135
+ _We inspired ourselves on [graphql-compose-relay](https://graphql-compose.github.io/docs/plugins/plugin-relay.html) to create `composeWithRelay`._
136
+
137
+ ## Building Schema
138
+
139
+ As Relay needs an introspection query to work, this package provides a way to build the GraphQL schema by running `ttoss-graphl-api build-schema`.
140
+
141
+ ```bash
142
+ ttoss-graphl-api build-schema
143
+ ```
144
+
145
+ ## Server
146
+
147
+ This package provides a Koa server to run your GraphQL API. You can use the `createServer` method to create the server.
148
+
149
+ ```ts
150
+ import { createServer } from '@ttoss/graphql-api/server';
151
+
152
+ const server = createServer({
153
+ schemaComposer,
154
+ graphiql: true,
155
+ });
156
+
157
+ server.listen(3000, () => {
158
+ console.log('Server listening on port 3000');
159
+ });
160
+ ```
package/bin/cli.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require('../dist/cli.js');
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/cli.js ADDED
@@ -0,0 +1,51 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ "use strict";
3
+
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: () => from[key],
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
25
+ value: mod,
26
+ enumerable: true
27
+ }) : target, mod));
28
+
29
+ // src/cli.ts
30
+ var fs = __toESM(require("fs"));
31
+ var path = __toESM(require("path"));
32
+ var import_ts_node = require("ts-node");
33
+ var import_npmlog = __toESM(require("npmlog"));
34
+ var import_yargs = __toESM(require("yargs"));
35
+ var logPrefix = "graphql-api";
36
+ (0, import_ts_node.register)({
37
+ transpileOnly: true
38
+ });
39
+ var argv = (0, import_yargs.default)(process.argv.slice(2)).argv;
40
+ if (argv._.includes("build-schema")) {
41
+ import_npmlog.default.info(logPrefix, "Building schema...");
42
+ const {
43
+ schemaComposer
44
+ } = require(path.resolve(process.cwd(), "src", "schemaComposer.ts"));
45
+ const sdl = schemaComposer.toSDL();
46
+ fs.mkdirSync("schema", {
47
+ recursive: true
48
+ });
49
+ fs.writeFileSync("schema/schema.graphql", sdl);
50
+ import_npmlog.default.info(logPrefix, "Schema built.");
51
+ }
@@ -0,0 +1,8 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ var __require = /* @__PURE__ */(x => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function (x) {
5
+ if (typeof require !== "undefined") return require.apply(this, arguments);
6
+ throw new Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+ export { __require };
@@ -0,0 +1,26 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ import { __require } from "./chunk-SAO2ACBY.js";
3
+
4
+ // src/cli.ts
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import { register } from "ts-node";
8
+ import log from "npmlog";
9
+ import yargs from "yargs";
10
+ var logPrefix = "graphql-api";
11
+ register({
12
+ transpileOnly: true
13
+ });
14
+ var argv = yargs(process.argv.slice(2)).argv;
15
+ if (argv._.includes("build-schema")) {
16
+ log.info(logPrefix, "Building schema...");
17
+ const {
18
+ schemaComposer
19
+ } = __require(path.resolve(process.cwd(), "src", "schemaComposer.ts"));
20
+ const sdl = schemaComposer.toSDL();
21
+ fs.mkdirSync("schema", {
22
+ recursive: true
23
+ });
24
+ fs.writeFileSync("schema/schema.graphql", sdl);
25
+ log.info(logPrefix, "Schema built.");
26
+ }
@@ -0,0 +1,156 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ import "./chunk-SAO2ACBY.js";
3
+
4
+ // src/composeWithRelay/composeWithRelay.ts
5
+ import { ObjectTypeComposer } from "graphql-compose";
6
+
7
+ // src/composeWithRelay/nodeFieldConfig.ts
8
+ import { getProjectionFromAST } from "graphql-compose";
9
+
10
+ // src/composeWithRelay/globalId.ts
11
+ var base64 = i => {
12
+ return Buffer.from(i, "ascii").toString("base64");
13
+ };
14
+ var unbase64 = i => {
15
+ return Buffer.from(i, "base64").toString("ascii");
16
+ };
17
+ var toGlobalId = (type, recordId) => {
18
+ return base64([type, recordId].join(":"));
19
+ };
20
+ var fromGlobalId = globalId => {
21
+ const unbasedGlobalId = unbase64(globalId);
22
+ const [type, recordId] = unbasedGlobalId.split(":");
23
+ return {
24
+ type,
25
+ recordId
26
+ };
27
+ };
28
+
29
+ // src/composeWithRelay/nodeFieldConfig.ts
30
+ var getNodeFieldConfig = (typeMapForRelayNode, nodeInterface) => {
31
+ return {
32
+ description: "Fetches an object that has globally unique ID among all types",
33
+ type: nodeInterface,
34
+ args: {
35
+ id: {
36
+ type: "ID!",
37
+ description: "The globally unique ID among all types"
38
+ }
39
+ },
40
+ resolve: (source, args, context, info) => {
41
+ if (!args.id || !(typeof args.id === "string")) {
42
+ return null;
43
+ }
44
+ const {
45
+ type
46
+ } = fromGlobalId(args.id);
47
+ if (!typeMapForRelayNode[type]) {
48
+ return null;
49
+ }
50
+ const {
51
+ tc,
52
+ resolver: findById
53
+ } = typeMapForRelayNode[type];
54
+ if (findById && findById.resolve && tc) {
55
+ const graphqlType = tc.getType();
56
+ let projection;
57
+ if (info) {
58
+ projection = getProjectionFromAST({
59
+ ...info,
60
+ returnType: graphqlType
61
+ });
62
+ } else {
63
+ projection = {};
64
+ }
65
+ const idArgName = Object.keys(findById.args)[0];
66
+ return findById.resolve({
67
+ source,
68
+ args: {
69
+ [idArgName]: args.id
70
+ },
71
+ // eg. mongoose has _id fieldname, so should map
72
+ context,
73
+ info,
74
+ projection
75
+ }).then(res => {
76
+ if (!res) return res;
77
+ res.__nodeType = graphqlType;
78
+ return res;
79
+ });
80
+ }
81
+ return null;
82
+ }
83
+ };
84
+ };
85
+
86
+ // src/composeWithRelay/nodeInterface.ts
87
+ import { InterfaceTypeComposer } from "graphql-compose";
88
+ var NodeTC = InterfaceTypeComposer.createTemp({
89
+ name: "Node",
90
+ description: "An object, that can be fetched by the globally unique ID among all types.",
91
+ fields: {
92
+ id: {
93
+ type: "ID!",
94
+ description: "The globally unique ID among all types."
95
+ }
96
+ },
97
+ resolveType: payload => {
98
+ return payload.__nodeType.name ? payload.__nodeType.name : null;
99
+ }
100
+ });
101
+ var NodeInterface = NodeTC.getType();
102
+ var getNodeInterface = sc => {
103
+ if (sc.hasInstance("Node", InterfaceTypeComposer)) {
104
+ return sc.get("Node");
105
+ }
106
+ sc.set("Node", NodeTC);
107
+ return NodeTC;
108
+ };
109
+
110
+ // src/composeWithRelay/composeWithRelay.ts
111
+ var TypeMapForRelayNode = {};
112
+ var composeWithRelay = tc => {
113
+ if (!(tc instanceof ObjectTypeComposer)) {
114
+ throw new Error("You should provide ObjectTypeComposer instance to composeWithRelay method");
115
+ }
116
+ const nodeInterface = getNodeInterface(tc.schemaComposer);
117
+ const nodeFieldConfig = getNodeFieldConfig(TypeMapForRelayNode, nodeInterface);
118
+ if (tc.getTypeName() === "Query" || tc.getTypeName() === "RootQuery") {
119
+ tc.setField("node", nodeFieldConfig);
120
+ return tc;
121
+ }
122
+ if (tc.getTypeName() === "Mutation" || tc.getTypeName() === "RootMutation") {
123
+ return tc;
124
+ }
125
+ if (!tc.hasRecordIdFn()) {
126
+ throw new Error(`ObjectTypeComposer(${tc.getTypeName()}) should have recordIdFn. This function returns ID from provided object.`);
127
+ }
128
+ const findById = tc.getResolver("findById");
129
+ if (!findById) {
130
+ throw new Error(`ObjectTypeComposer(${tc.getTypeName()}) provided to composeWithRelay should have findById resolver.`);
131
+ }
132
+ TypeMapForRelayNode[tc.getTypeName()] = {
133
+ resolver: findById,
134
+ tc
135
+ };
136
+ tc.addFields({
137
+ id: {
138
+ type: "ID!",
139
+ description: "The globally unique ID among all types",
140
+ resolve: source => {
141
+ return toGlobalId(tc.getTypeName(), tc.getRecordId(source));
142
+ }
143
+ }
144
+ });
145
+ tc.addInterface(nodeInterface);
146
+ return tc;
147
+ };
148
+
149
+ // src/composeWithRelay/index.ts
150
+ import { schemaComposer } from "graphql-compose";
151
+ composeWithRelay(schemaComposer.Query);
152
+
153
+ // src/index.ts
154
+ import { default as default2 } from "graphql-compose-connection";
155
+ export * from "graphql-compose";
156
+ export { default2 as composeWithConnection, composeWithRelay, fromGlobalId, toGlobalId };
@@ -0,0 +1,46 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ import "./chunk-SAO2ACBY.js";
3
+
4
+ // src/server.ts
5
+ import { getGraphQLParameters, processRequest, renderGraphiQL, sendResult, shouldRenderGraphiQL } from "graphql-helix";
6
+ import Koa from "koa";
7
+ import Router from "@koa/router";
8
+ import bodyParser from "koa-bodyparser";
9
+ var createServer = ({
10
+ schemaComposer,
11
+ graphiql = false
12
+ }) => {
13
+ const server = new Koa();
14
+ const router = new Router();
15
+ server.use(bodyParser());
16
+ router.all("/graphql", async ctx => {
17
+ const request = {
18
+ body: ctx.request.body,
19
+ headers: ctx.headers,
20
+ method: ctx.method,
21
+ query: ctx.request.query
22
+ };
23
+ if (shouldRenderGraphiQL(request)) {
24
+ if (graphiql) {
25
+ ctx.body = renderGraphiQL({});
26
+ }
27
+ return;
28
+ }
29
+ const {
30
+ operationName,
31
+ query,
32
+ variables
33
+ } = getGraphQLParameters(request);
34
+ const result = await processRequest({
35
+ operationName,
36
+ query,
37
+ variables,
38
+ request,
39
+ schema: schemaComposer.buildSchema()
40
+ });
41
+ sendResult(result, ctx.res);
42
+ });
43
+ server.use(router.routes()).use(router.allowedMethods());
44
+ return server;
45
+ };
46
+ export { Router, createServer };
@@ -0,0 +1,22 @@
1
+ import { ObjectTypeComposer } from 'graphql-compose';
2
+ export * from 'graphql-compose';
3
+ export { default as composeWithConnection } from 'graphql-compose-connection';
4
+
5
+ declare const composeWithRelay: <TContext>(tc: ObjectTypeComposer<any, TContext>) => ObjectTypeComposer<any, TContext>;
6
+
7
+ type ResolvedGlobalId = {
8
+ type: string;
9
+ recordId: string;
10
+ };
11
+ /**
12
+ * Takes a type name and an ID specific to that type name, and returns a
13
+ * "global ID" that is unique among all types.
14
+ */
15
+ declare const toGlobalId: (type: string, recordId: string | number) => string;
16
+ /**
17
+ * Takes the "global ID" created by toGlobalID, and returns the type name and ID
18
+ * used to create it.
19
+ */
20
+ declare const fromGlobalId: (globalId: string) => ResolvedGlobalId;
21
+
22
+ export { composeWithRelay, fromGlobalId, toGlobalId };
package/dist/index.js ADDED
@@ -0,0 +1,207 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ "use strict";
3
+
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __export = (target, all) => {
11
+ for (var name in all) __defProp(target, name, {
12
+ get: all[name],
13
+ enumerable: true
14
+ });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
19
+ get: () => from[key],
20
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
21
+ });
22
+ }
23
+ return to;
24
+ };
25
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
26
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
27
+ // If the importer is in node compatibility mode or this is not an ESM
28
+ // file that has been converted to a CommonJS file using a Babel-
29
+ // compatible transform (i.e. "__esModule" has not been set), then set
30
+ // "default" to the CommonJS "module.exports" for node compatibility.
31
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
32
+ value: mod,
33
+ enumerable: true
34
+ }) : target, mod));
35
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
36
+ value: true
37
+ }), mod);
38
+
39
+ // src/index.ts
40
+ var src_exports = {};
41
+ __export(src_exports, {
42
+ composeWithConnection: () => import_graphql_compose_connection.default,
43
+ composeWithRelay: () => composeWithRelay,
44
+ fromGlobalId: () => fromGlobalId,
45
+ toGlobalId: () => toGlobalId
46
+ });
47
+ module.exports = __toCommonJS(src_exports);
48
+
49
+ // src/composeWithRelay/composeWithRelay.ts
50
+ var import_graphql_compose3 = require("graphql-compose");
51
+
52
+ // src/composeWithRelay/nodeFieldConfig.ts
53
+ var import_graphql_compose = require("graphql-compose");
54
+
55
+ // src/composeWithRelay/globalId.ts
56
+ var base64 = i => {
57
+ return Buffer.from(i, "ascii").toString("base64");
58
+ };
59
+ var unbase64 = i => {
60
+ return Buffer.from(i, "base64").toString("ascii");
61
+ };
62
+ var toGlobalId = (type, recordId) => {
63
+ return base64([type, recordId].join(":"));
64
+ };
65
+ var fromGlobalId = globalId => {
66
+ const unbasedGlobalId = unbase64(globalId);
67
+ const [type, recordId] = unbasedGlobalId.split(":");
68
+ return {
69
+ type,
70
+ recordId
71
+ };
72
+ };
73
+
74
+ // src/composeWithRelay/nodeFieldConfig.ts
75
+ var getNodeFieldConfig = (typeMapForRelayNode, nodeInterface) => {
76
+ return {
77
+ description: "Fetches an object that has globally unique ID among all types",
78
+ type: nodeInterface,
79
+ args: {
80
+ id: {
81
+ type: "ID!",
82
+ description: "The globally unique ID among all types"
83
+ }
84
+ },
85
+ resolve: (source, args, context, info) => {
86
+ if (!args.id || !(typeof args.id === "string")) {
87
+ return null;
88
+ }
89
+ const {
90
+ type
91
+ } = fromGlobalId(args.id);
92
+ if (!typeMapForRelayNode[type]) {
93
+ return null;
94
+ }
95
+ const {
96
+ tc,
97
+ resolver: findById
98
+ } = typeMapForRelayNode[type];
99
+ if (findById && findById.resolve && tc) {
100
+ const graphqlType = tc.getType();
101
+ let projection;
102
+ if (info) {
103
+ projection = (0, import_graphql_compose.getProjectionFromAST)({
104
+ ...info,
105
+ returnType: graphqlType
106
+ });
107
+ } else {
108
+ projection = {};
109
+ }
110
+ const idArgName = Object.keys(findById.args)[0];
111
+ return findById.resolve({
112
+ source,
113
+ args: {
114
+ [idArgName]: args.id
115
+ },
116
+ // eg. mongoose has _id fieldname, so should map
117
+ context,
118
+ info,
119
+ projection
120
+ }).then(res => {
121
+ if (!res) return res;
122
+ res.__nodeType = graphqlType;
123
+ return res;
124
+ });
125
+ }
126
+ return null;
127
+ }
128
+ };
129
+ };
130
+
131
+ // src/composeWithRelay/nodeInterface.ts
132
+ var import_graphql_compose2 = require("graphql-compose");
133
+ var NodeTC = import_graphql_compose2.InterfaceTypeComposer.createTemp({
134
+ name: "Node",
135
+ description: "An object, that can be fetched by the globally unique ID among all types.",
136
+ fields: {
137
+ id: {
138
+ type: "ID!",
139
+ description: "The globally unique ID among all types."
140
+ }
141
+ },
142
+ resolveType: payload => {
143
+ return payload.__nodeType.name ? payload.__nodeType.name : null;
144
+ }
145
+ });
146
+ var NodeInterface = NodeTC.getType();
147
+ var getNodeInterface = sc => {
148
+ if (sc.hasInstance("Node", import_graphql_compose2.InterfaceTypeComposer)) {
149
+ return sc.get("Node");
150
+ }
151
+ sc.set("Node", NodeTC);
152
+ return NodeTC;
153
+ };
154
+
155
+ // src/composeWithRelay/composeWithRelay.ts
156
+ var TypeMapForRelayNode = {};
157
+ var composeWithRelay = tc => {
158
+ if (!(tc instanceof import_graphql_compose3.ObjectTypeComposer)) {
159
+ throw new Error("You should provide ObjectTypeComposer instance to composeWithRelay method");
160
+ }
161
+ const nodeInterface = getNodeInterface(tc.schemaComposer);
162
+ const nodeFieldConfig = getNodeFieldConfig(TypeMapForRelayNode, nodeInterface);
163
+ if (tc.getTypeName() === "Query" || tc.getTypeName() === "RootQuery") {
164
+ tc.setField("node", nodeFieldConfig);
165
+ return tc;
166
+ }
167
+ if (tc.getTypeName() === "Mutation" || tc.getTypeName() === "RootMutation") {
168
+ return tc;
169
+ }
170
+ if (!tc.hasRecordIdFn()) {
171
+ throw new Error(`ObjectTypeComposer(${tc.getTypeName()}) should have recordIdFn. This function returns ID from provided object.`);
172
+ }
173
+ const findById = tc.getResolver("findById");
174
+ if (!findById) {
175
+ throw new Error(`ObjectTypeComposer(${tc.getTypeName()}) provided to composeWithRelay should have findById resolver.`);
176
+ }
177
+ TypeMapForRelayNode[tc.getTypeName()] = {
178
+ resolver: findById,
179
+ tc
180
+ };
181
+ tc.addFields({
182
+ id: {
183
+ type: "ID!",
184
+ description: "The globally unique ID among all types",
185
+ resolve: source => {
186
+ return toGlobalId(tc.getTypeName(), tc.getRecordId(source));
187
+ }
188
+ }
189
+ });
190
+ tc.addInterface(nodeInterface);
191
+ return tc;
192
+ };
193
+
194
+ // src/composeWithRelay/index.ts
195
+ var import_graphql_compose4 = require("graphql-compose");
196
+ composeWithRelay(import_graphql_compose4.schemaComposer.Query);
197
+
198
+ // src/index.ts
199
+ var import_graphql_compose_connection = __toESM(require("graphql-compose-connection"));
200
+ __reExport(src_exports, require("graphql-compose"), module.exports);
201
+ // Annotate the CommonJS export names for ESM import in node:
202
+ 0 && (module.exports = {
203
+ composeWithConnection,
204
+ composeWithRelay,
205
+ fromGlobalId,
206
+ toGlobalId
207
+ });