@flightdev/graphql 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Flight Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # @flight-framework/graphql
2
+
3
+ GraphQL adapter for Flight Framework. Optional, non-imposing - use it only if you need GraphQL.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @flight-framework/graphql graphql graphql-yoga
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ Create a GraphQL endpoint in your Flight app:
14
+
15
+ ```typescript
16
+ // src/routes/api/graphql.ts
17
+ import { createGraphQLHandler } from '@flight-framework/graphql';
18
+ import { yogaAdapter } from '@flight-framework/graphql/yoga';
19
+ import { schema } from '../../graphql/schema';
20
+
21
+ const handler = createGraphQLHandler({
22
+ adapter: yogaAdapter(),
23
+ schema,
24
+ });
25
+
26
+ export const GET = handler;
27
+ export const POST = handler;
28
+ ```
29
+
30
+ ## Creating a Schema
31
+
32
+ ### Code-First (Recommended)
33
+
34
+ ```typescript
35
+ // src/graphql/schema.ts
36
+ import { createSchema } from 'graphql-yoga';
37
+
38
+ export const schema = createSchema({
39
+ typeDefs: /* GraphQL */ `
40
+ type Query {
41
+ hello(name: String): String!
42
+ users: [User!]!
43
+ }
44
+
45
+ type User {
46
+ id: ID!
47
+ name: String!
48
+ email: String!
49
+ }
50
+ `,
51
+ resolvers: {
52
+ Query: {
53
+ hello: (_, { name }) => `Hello ${name || 'World'}`,
54
+ users: () => db.users.findMany(),
55
+ },
56
+ },
57
+ });
58
+ ```
59
+
60
+ ### Schema-First
61
+
62
+ ```typescript
63
+ import { buildSchema } from 'graphql';
64
+ import { createGraphQLHandler } from '@flight-framework/graphql';
65
+ import { yogaAdapter } from '@flight-framework/graphql/yoga';
66
+
67
+ const schema = buildSchema(/* GraphQL */ `
68
+ type Query {
69
+ hello: String
70
+ }
71
+ `);
72
+
73
+ const rootValue = {
74
+ hello: () => 'Hello World',
75
+ };
76
+
77
+ export const POST = createGraphQLHandler({
78
+ adapter: yogaAdapter({ rootValue }),
79
+ schema,
80
+ });
81
+ ```
82
+
83
+ ## Context
84
+
85
+ Pass request context to resolvers:
86
+
87
+ ```typescript
88
+ const handler = createGraphQLHandler({
89
+ adapter: yogaAdapter(),
90
+ schema,
91
+ context: async (req) => {
92
+ const token = req.headers.get('Authorization');
93
+ const user = token ? await verifyToken(token) : null;
94
+ return { user, db };
95
+ },
96
+ });
97
+ ```
98
+
99
+ Access in resolvers:
100
+
101
+ ```typescript
102
+ const resolvers = {
103
+ Query: {
104
+ me: (_, __, ctx) => ctx.user,
105
+ posts: (_, __, ctx) => ctx.db.posts.findMany(),
106
+ },
107
+ };
108
+ ```
109
+
110
+ ## GraphiQL
111
+
112
+ GraphiQL is enabled by default in development. Access it at your endpoint URL.
113
+
114
+ To disable:
115
+
116
+ ```typescript
117
+ const handler = createGraphQLHandler({
118
+ adapter: yogaAdapter({ graphiql: false }),
119
+ schema,
120
+ });
121
+ ```
122
+
123
+ ## Adapters
124
+
125
+ ### GraphQL Yoga (Default)
126
+
127
+ ```typescript
128
+ import { yogaAdapter } from '@flight-framework/graphql/yoga';
129
+ ```
130
+
131
+ Yoga is the recommended adapter - modern, lightweight, full fetch API support.
132
+
133
+ ### Apollo (Coming Soon)
134
+
135
+ ```typescript
136
+ import { apolloAdapter } from '@flight-framework/graphql/apollo';
137
+ ```
138
+
139
+ ## TypeScript
140
+
141
+ Full TypeScript support with type inference:
142
+
143
+ ```typescript
144
+ import type { GraphQLContext, GraphQLAdapter } from '@flight-framework/graphql';
145
+ ```
146
+
147
+ ## License
148
+
149
+ MIT
@@ -0,0 +1,93 @@
1
+ import { GraphQLSchema } from 'graphql';
2
+ export { ExecutionResult, GraphQLSchema } from 'graphql';
3
+
4
+ /**
5
+ * @flightdev/graphql
6
+ *
7
+ * GraphQL adapter for Flight Framework.
8
+ * Optional, non-imposing - use it only if you need GraphQL.
9
+ */
10
+
11
+ /**
12
+ * Context factory function type
13
+ */
14
+ type ContextFactory<TContext = Record<string, unknown>> = (request: Request) => TContext | Promise<TContext>;
15
+ /**
16
+ * Configuration for GraphQL adapters
17
+ */
18
+ interface GraphQLAdapterConfig<TContext = Record<string, unknown>> {
19
+ /** GraphQL schema */
20
+ schema: GraphQLSchema;
21
+ /** Context factory for resolvers */
22
+ context?: ContextFactory<TContext>;
23
+ /** Root value for schema-first approach */
24
+ rootValue?: unknown;
25
+ }
26
+ /**
27
+ * GraphQL handler function type
28
+ *
29
+ * Uses rest parameters with `any[]` to accommodate different GraphQL server
30
+ * implementations with varying signatures:
31
+ * - GraphQL Yoga: `fetch(request, serverContext?)` with overloaded variants
32
+ * - Apollo: `executeHTTPGraphQLRequest(request)`
33
+ * - Other implementations may differ
34
+ *
35
+ * This is an intentional TypeScript escape hatch - the adapter pattern provides
36
+ * type safety at the public API boundaries (createGraphQLHandler), while allowing
37
+ * internal flexibility for wrapping third-party libraries.
38
+ *
39
+ * @see https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any
40
+ */
41
+ type GraphQLHandler = (request: Request, ...serverContext: any[]) => Response | Promise<Response>;
42
+ /**
43
+ * GraphQL adapter interface
44
+ *
45
+ * Implement this interface to add support for different GraphQL servers.
46
+ */
47
+ interface GraphQLAdapter {
48
+ /** Adapter name for debugging */
49
+ readonly name: string;
50
+ /**
51
+ * Create a request handler from the adapter config
52
+ */
53
+ createHandler<TContext = Record<string, unknown>>(config: GraphQLAdapterConfig<TContext>): GraphQLHandler;
54
+ }
55
+ /**
56
+ * Options for createGraphQLHandler
57
+ */
58
+ interface CreateGraphQLHandlerOptions<TContext = Record<string, unknown>> {
59
+ /** The GraphQL adapter to use */
60
+ adapter: GraphQLAdapter;
61
+ /** GraphQL schema */
62
+ schema: GraphQLSchema;
63
+ /** Context factory for resolvers */
64
+ context?: ContextFactory<TContext>;
65
+ /** Root value for schema-first approach */
66
+ rootValue?: unknown;
67
+ }
68
+ /**
69
+ * Create a GraphQL request handler
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * import { createGraphQLHandler } from '@flightdev/graphql';
74
+ * import { yogaAdapter } from '@flightdev/graphql/yoga';
75
+ * import { schema } from './schema';
76
+ *
77
+ * const handler = createGraphQLHandler({
78
+ * adapter: yogaAdapter(),
79
+ * schema,
80
+ * context: (req) => ({ user: getUser(req) }),
81
+ * });
82
+ *
83
+ * export const GET = handler;
84
+ * export const POST = handler;
85
+ * ```
86
+ */
87
+ declare function createGraphQLHandler<TContext = Record<string, unknown>>(options: CreateGraphQLHandlerOptions<TContext>): GraphQLHandler;
88
+ /**
89
+ * Type helper for GraphQL context
90
+ */
91
+ type GraphQLContext<T = Record<string, unknown>> = T;
92
+
93
+ export { type ContextFactory, type CreateGraphQLHandlerOptions, type GraphQLAdapter, type GraphQLAdapterConfig, type GraphQLContext, type GraphQLHandler, createGraphQLHandler };
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ // src/index.ts
2
+ function createGraphQLHandler(options) {
3
+ const { adapter, schema, context, rootValue } = options;
4
+ return adapter.createHandler({
5
+ schema,
6
+ context,
7
+ rootValue
8
+ });
9
+ }
10
+
11
+ export { createGraphQLHandler };
package/dist/yoga.d.ts ADDED
@@ -0,0 +1,66 @@
1
+ import { YogaServerOptions } from 'graphql-yoga';
2
+ export { createSchema } from 'graphql-yoga';
3
+ import { GraphQLAdapter } from './index.js';
4
+ import 'graphql';
5
+
6
+ /**
7
+ * GraphQL Yoga Adapter for Flight Framework
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { createGraphQLHandler } from '@flightdev/graphql';
12
+ * import { yogaAdapter } from '@flightdev/graphql/yoga';
13
+ *
14
+ * const handler = createGraphQLHandler({
15
+ * adapter: yogaAdapter(),
16
+ * schema,
17
+ * });
18
+ * ```
19
+ */
20
+
21
+ /**
22
+ * Options specific to the Yoga adapter
23
+ */
24
+ interface YogaAdapterOptions {
25
+ /** Enable/disable GraphiQL interface (default: true in development) */
26
+ graphiql?: boolean | {
27
+ title?: string;
28
+ defaultQuery?: string;
29
+ };
30
+ /** CORS configuration (passed directly to Yoga) */
31
+ cors?: boolean | Record<string, unknown>;
32
+ /** Enable/disable logging */
33
+ logging?: boolean;
34
+ /** Mask errors in production */
35
+ maskedErrors?: boolean;
36
+ /** Custom plugins */
37
+ plugins?: YogaServerOptions<Record<string, unknown>, Record<string, unknown>>['plugins'];
38
+ }
39
+ /**
40
+ * Create a GraphQL Yoga adapter
41
+ *
42
+ * Yoga is the recommended GraphQL server for Flight:
43
+ * - Modern, lightweight, full fetch API support
44
+ * - Built-in GraphiQL, CORS, file uploads
45
+ * - Excellent TypeScript support
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * // Basic usage
50
+ * yogaAdapter()
51
+ *
52
+ * // With options
53
+ * yogaAdapter({
54
+ * graphiql: { title: 'My API' },
55
+ * cors: { origin: 'https://myapp.com' },
56
+ * })
57
+ *
58
+ * // Disable GraphiQL in production
59
+ * yogaAdapter({
60
+ * graphiql: process.env.NODE_ENV !== 'production',
61
+ * })
62
+ * ```
63
+ */
64
+ declare function yogaAdapter(options?: YogaAdapterOptions): GraphQLAdapter;
65
+
66
+ export { type YogaAdapterOptions, yogaAdapter };
package/dist/yoga.js ADDED
@@ -0,0 +1,39 @@
1
+ import { createYoga } from 'graphql-yoga';
2
+ export { createSchema } from 'graphql-yoga';
3
+
4
+ // src/yoga.ts
5
+ function yogaAdapter(options = {}) {
6
+ const {
7
+ graphiql = true,
8
+ cors,
9
+ logging = false,
10
+ maskedErrors = true,
11
+ plugins = []
12
+ } = options;
13
+ return {
14
+ name: "graphql-yoga",
15
+ createHandler(config) {
16
+ const yoga = createYoga({
17
+ schema: config.schema,
18
+ // Context factory
19
+ context: config.context ? async ({ request }) => {
20
+ const ctx = await config.context(request);
21
+ return ctx;
22
+ } : void 0,
23
+ // GraphiQL configuration
24
+ graphiql: graphiql === true ? { title: "Flight GraphQL" } : graphiql === false ? false : graphiql,
25
+ // CORS - use simple default
26
+ cors: cors ?? true,
27
+ // Logging
28
+ logging,
29
+ // Error masking
30
+ maskedErrors,
31
+ // Plugins
32
+ plugins
33
+ });
34
+ return yoga.fetch.bind(yoga);
35
+ }
36
+ };
37
+ }
38
+
39
+ export { yogaAdapter };
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@flightdev/graphql",
3
+ "version": "0.1.0",
4
+ "description": "GraphQL adapter for Flight Framework - optional, non-imposing",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ },
11
+ "./yoga": {
12
+ "types": "./dist/yoga.d.ts",
13
+ "import": "./dist/yoga.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "dependencies": {},
20
+ "peerDependencies": {
21
+ "graphql": "^16.0.0",
22
+ "graphql-yoga": "^5.0.0"
23
+ },
24
+ "peerDependenciesMeta": {
25
+ "graphql-yoga": {
26
+ "optional": true
27
+ }
28
+ },
29
+ "devDependencies": {
30
+ "graphql": "^16.9.0",
31
+ "graphql-yoga": "^5.10.0",
32
+ "tsup": "^8.0.0",
33
+ "typescript": "^5.7.0",
34
+ "vitest": "^3.0.0"
35
+ },
36
+ "keywords": [
37
+ "flight",
38
+ "graphql",
39
+ "yoga",
40
+ "adapter"
41
+ ],
42
+ "license": "MIT",
43
+ "scripts": {
44
+ "build": "tsup",
45
+ "dev": "tsup --watch",
46
+ "test": "vitest",
47
+ "typecheck": "tsc --noEmit"
48
+ }
49
+ }