@happyvertical/graphql 0.74.8

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/AGENT.md ADDED
@@ -0,0 +1,33 @@
1
+ # @happyvertical/graphql
2
+
3
+ <!-- BEGIN AGENT:GENERATED -->
4
+ ## Purpose
5
+ GitHub GraphQL client for SDK packages
6
+
7
+ ## Package Map
8
+ - Package: `@happyvertical/graphql`
9
+ - Hierarchy path: `@happyvertical/sdk > packages > graphql`
10
+ - Workspace position: `14 of 30` local packages
11
+ - Internal dependencies: none
12
+ - Internal dependents: `@happyvertical/projects`, `@happyvertical/repos`
13
+ - Knowledge graph files: `AGENT.md`, `metadata.json`, `ecosystem-manifest.json`
14
+
15
+ ## Build & Test
16
+ ```bash
17
+ pnpm --filter @happyvertical/graphql build
18
+ pnpm --filter @happyvertical/graphql test
19
+ pnpm --filter @happyvertical/graphql clean
20
+ ```
21
+
22
+ ## Agent Correction Loops
23
+ - If Vite or TypeScript reports missing packages, run `pnpm install` at the repo root and rerun `pnpm --filter @happyvertical/graphql build`.
24
+ - If tests or exports fail after API, type, or bundle changes, run `pnpm --filter @happyvertical/graphql clean` followed by `pnpm --filter @happyvertical/graphql build` and `pnpm --filter @happyvertical/graphql test`.
25
+ - If failures span multiple packages or Turborepo ordering looks wrong, run `pnpm build` and `pnpm typecheck` from the repo root before retrying package-scoped commands.
26
+
27
+ ## Ecosystem Relationships
28
+ - Provides: GitHub GraphQL client for SDK packages
29
+ - Implements: none
30
+ - Requires: none
31
+ - Stability: stable (Primary package surface is described as implemented and production-oriented.)
32
+ <!-- END AGENT:GENERATED -->
33
+
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright <2025> <Happy Vertical Corporation>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ export { }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=claude-context.d.ts.map
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, mkdirSync, copyFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ const Dirname = dirname(fileURLToPath(import.meta.url));
6
+ const pkgRoot = join(Dirname, "../..");
7
+ const targetDir = join(process.cwd(), ".claude");
8
+ if (!existsSync(targetDir)) {
9
+ mkdirSync(targetDir, { recursive: true });
10
+ }
11
+ const pkgName = "graphql";
12
+ const agentMdSrc = existsSync(join(pkgRoot, "AGENT.md")) ? join(pkgRoot, "AGENT.md") : join(pkgRoot, "CLAUDE.md");
13
+ const metaSrc = existsSync(join(pkgRoot, "metadata.json")) ? join(pkgRoot, "metadata.json") : join(pkgRoot, ".claude-meta.json");
14
+ if (existsSync(agentMdSrc)) {
15
+ copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));
16
+ }
17
+ if (existsSync(metaSrc)) {
18
+ copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));
19
+ }
20
+ console.log(`✓ Installed @happyvertical/${pkgName} context to .claude/`);
21
+ //# sourceMappingURL=claude-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-context.js","sources":["../../src/cli/claude-context.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI script to install agent context for @happyvertical/graphql\n * Run the published context installer binary for this package.\n */\nimport { copyFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst Dirname = dirname(fileURLToPath(import.meta.url));\nconst pkgRoot = join(Dirname, '../..');\nconst targetDir = join(process.cwd(), '.claude');\n\nif (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n}\n\nconst pkgName = 'graphql';\nconst agentMdSrc = existsSync(join(pkgRoot, 'AGENT.md'))\n ? join(pkgRoot, 'AGENT.md')\n : join(pkgRoot, 'CLAUDE.md');\nconst metaSrc = existsSync(join(pkgRoot, 'metadata.json'))\n ? join(pkgRoot, 'metadata.json')\n : join(pkgRoot, '.claude-meta.json');\n\nif (existsSync(agentMdSrc)) {\n copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));\n}\n\nif (existsSync(metaSrc)) {\n copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));\n}\n\nconsole.log(`✓ Installed @happyvertical/${pkgName} context to .claude/`);\n"],"names":[],"mappings":";;;;AASA,MAAM,UAAU,QAAQ,cAAc,YAAY,GAAG,CAAC;AACtD,MAAM,UAAU,KAAK,SAAS,OAAO;AACrC,MAAM,YAAY,KAAK,QAAQ,IAAA,GAAO,SAAS;AAE/C,IAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,YAAU,WAAW,EAAE,WAAW,KAAA,CAAM;AAC1C;AAEA,MAAM,UAAU;AAChB,MAAM,aAAa,WAAW,KAAK,SAAS,UAAU,CAAC,IACnD,KAAK,SAAS,UAAU,IACxB,KAAK,SAAS,WAAW;AAC7B,MAAM,UAAU,WAAW,KAAK,SAAS,eAAe,CAAC,IACrD,KAAK,SAAS,eAAe,IAC7B,KAAK,SAAS,mBAAmB;AAErC,IAAI,WAAW,UAAU,GAAG;AAC1B,eAAa,YAAY,KAAK,WAAW,QAAQ,OAAO,KAAK,CAAC;AAChE;AAEA,IAAI,WAAW,OAAO,GAAG;AACvB,eAAa,SAAS,KAAK,WAAW,QAAQ,OAAO,YAAY,CAAC;AACpE;AAEA,QAAQ,IAAI,8BAA8B,OAAO,sBAAsB;"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Get a GraphQL client instance
3
+ *
4
+ * This is the main entry point for creating GraphQL clients.
5
+ * It can accept either a configuration object or an existing client instance.
6
+ *
7
+ * @param options - GraphQL configuration or existing client instance
8
+ * @returns Promise resolving to GraphQL client interface
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { getGraphQLClient } from '@happyvertical/graphql';
13
+ *
14
+ * // Create a GitHub GraphQL client
15
+ * const github = await getGraphQLClient({
16
+ * endpoint: 'https://api.github.com/graphql',
17
+ * token: process.env.GITHUB_TOKEN
18
+ * });
19
+ *
20
+ * // Create a GitLab GraphQL client
21
+ * const gitlab = await getGraphQLClient({
22
+ * endpoint: 'https://gitlab.com/api/graphql',
23
+ * token: process.env.GITLAB_TOKEN
24
+ * });
25
+ *
26
+ * // Custom headers for other APIs
27
+ * const custom = await getGraphQLClient({
28
+ * endpoint: 'https://api.example.com/graphql',
29
+ * headers: {
30
+ * 'X-API-Key': 'my-api-key',
31
+ * 'X-Custom-Header': 'value'
32
+ * }
33
+ * });
34
+ *
35
+ * // Execute a query
36
+ * const result = await github.query<{ viewer: { login: string } }>(`
37
+ * query {
38
+ * viewer {
39
+ * login
40
+ * }
41
+ * }
42
+ * `);
43
+ *
44
+ * // Pass existing instance (returns it unchanged)
45
+ * const sameClient = await getGraphQLClient(github);
46
+ * ```
47
+ */
48
+ export declare function getGraphQLClient(options: GraphQLConfig | IGraphQLClient): Promise<IGraphQLClient>;
49
+
50
+ /**
51
+ * Generic GraphQL client implementation
52
+ *
53
+ * Works with any GraphQL endpoint - GitHub, GitLab, Shopify, custom APIs, etc.
54
+ */
55
+ export declare class GraphQLClient implements IGraphQLClient {
56
+ private readonly endpoint;
57
+ private readonly headers;
58
+ constructor(config: GraphQLConfig);
59
+ /**
60
+ * Execute a GraphQL query
61
+ */
62
+ query<T>(query: string, variables?: Record<string, unknown>): Promise<T>;
63
+ /**
64
+ * Execute a GraphQL mutation
65
+ */
66
+ mutate<T>(mutation: string, variables?: Record<string, unknown>): Promise<T>;
67
+ /**
68
+ * Execute GraphQL operation
69
+ */
70
+ private execute;
71
+ }
72
+
73
+ /**
74
+ * GraphQL client types
75
+ */
76
+ /**
77
+ * GraphQL client configuration
78
+ *
79
+ * Generic configuration for any GraphQL endpoint.
80
+ * GraphQL is a protocol, not a provider - the client
81
+ * works with any GraphQL API (GitHub, GitLab, Shopify, etc.)
82
+ */
83
+ export declare interface GraphQLConfig {
84
+ /** GraphQL endpoint URL */
85
+ endpoint: string;
86
+ /** Bearer token for Authorization header */
87
+ token?: string;
88
+ /** Custom headers (merged with defaults) */
89
+ headers?: Record<string, string>;
90
+ }
91
+
92
+ /**
93
+ * GraphQL error class
94
+ */
95
+ export declare class GraphQLError extends Error {
96
+ readonly code: GraphQLErrorCode;
97
+ readonly details?: GraphQLErrorDetail[];
98
+ readonly originalError?: unknown;
99
+ constructor(message: string, code: GraphQLErrorCode, details?: GraphQLErrorDetail[], originalError?: unknown);
100
+ /**
101
+ * Create error from HTTP status code
102
+ */
103
+ static fromHTTPStatus(status: number, message: string, originalError?: unknown): GraphQLError;
104
+ /**
105
+ * Create error from GraphQL response errors
106
+ */
107
+ static fromGraphQLErrors(errors: GraphQLErrorDetail[]): GraphQLError;
108
+ /**
109
+ * Create network error
110
+ */
111
+ static networkError(message: string, originalError?: unknown): GraphQLError;
112
+ /**
113
+ * Check if error is retryable
114
+ */
115
+ isRetryable(): boolean;
116
+ }
117
+
118
+ /**
119
+ * Error codes for GraphQL operations
120
+ */
121
+ export declare enum GraphQLErrorCode {
122
+ /** Authentication failed */
123
+ UNAUTHORIZED = "UNAUTHORIZED",
124
+ /** Resource not found */
125
+ NOT_FOUND = "NOT_FOUND",
126
+ /** Rate limit exceeded */
127
+ RATE_LIMITED = "RATE_LIMITED",
128
+ /** Network error */
129
+ NETWORK_ERROR = "NETWORK_ERROR",
130
+ /** Invalid query or mutation */
131
+ VALIDATION_ERROR = "VALIDATION_ERROR",
132
+ /** Unknown error */
133
+ UNKNOWN = "UNKNOWN"
134
+ }
135
+
136
+ /**
137
+ * GraphQL error detail from API response
138
+ */
139
+ export declare interface GraphQLErrorDetail {
140
+ message: string;
141
+ type?: string;
142
+ path?: string[];
143
+ locations?: Array<{
144
+ line: number;
145
+ column: number;
146
+ }>;
147
+ }
148
+
149
+ /**
150
+ * GraphQL response structure
151
+ */
152
+ export declare interface GraphQLResponse<T> {
153
+ data?: T;
154
+ errors?: GraphQLErrorDetail[];
155
+ }
156
+
157
+ /**
158
+ * GraphQL client interface
159
+ */
160
+ export declare interface IGraphQLClient {
161
+ /**
162
+ * Execute a GraphQL query
163
+ */
164
+ query<T>(query: string, variables?: Record<string, unknown>): Promise<T>;
165
+ /**
166
+ * Execute a GraphQL mutation
167
+ */
168
+ mutate<T>(mutation: string, variables?: Record<string, unknown>): Promise<T>;
169
+ }
170
+
171
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,166 @@
1
+ var GraphQLErrorCode = /* @__PURE__ */ ((GraphQLErrorCode2) => {
2
+ GraphQLErrorCode2["UNAUTHORIZED"] = "UNAUTHORIZED";
3
+ GraphQLErrorCode2["NOT_FOUND"] = "NOT_FOUND";
4
+ GraphQLErrorCode2["RATE_LIMITED"] = "RATE_LIMITED";
5
+ GraphQLErrorCode2["NETWORK_ERROR"] = "NETWORK_ERROR";
6
+ GraphQLErrorCode2["VALIDATION_ERROR"] = "VALIDATION_ERROR";
7
+ GraphQLErrorCode2["UNKNOWN"] = "UNKNOWN";
8
+ return GraphQLErrorCode2;
9
+ })(GraphQLErrorCode || {});
10
+ class GraphQLError extends Error {
11
+ code;
12
+ details;
13
+ originalError;
14
+ constructor(message, code, details, originalError) {
15
+ super(message);
16
+ this.name = "GraphQLError";
17
+ this.code = code;
18
+ this.details = details;
19
+ this.originalError = originalError;
20
+ }
21
+ /**
22
+ * Create error from HTTP status code
23
+ */
24
+ static fromHTTPStatus(status, message, originalError) {
25
+ let code;
26
+ switch (status) {
27
+ case 401:
28
+ code = "UNAUTHORIZED";
29
+ break;
30
+ case 403:
31
+ code = "RATE_LIMITED";
32
+ break;
33
+ case 404:
34
+ code = "NOT_FOUND";
35
+ break;
36
+ case 422:
37
+ code = "VALIDATION_ERROR";
38
+ break;
39
+ default:
40
+ code = "UNKNOWN";
41
+ }
42
+ return new GraphQLError(message, code, void 0, originalError);
43
+ }
44
+ /**
45
+ * Create error from GraphQL response errors
46
+ */
47
+ static fromGraphQLErrors(errors) {
48
+ const message = errors.map((e) => e.message).join("; ");
49
+ return new GraphQLError(
50
+ `GraphQL errors: ${message}`,
51
+ "VALIDATION_ERROR",
52
+ errors
53
+ );
54
+ }
55
+ /**
56
+ * Create network error
57
+ */
58
+ static networkError(message, originalError) {
59
+ return new GraphQLError(
60
+ message,
61
+ "NETWORK_ERROR",
62
+ void 0,
63
+ originalError
64
+ );
65
+ }
66
+ /**
67
+ * Check if error is retryable
68
+ */
69
+ isRetryable() {
70
+ return this.code === "RATE_LIMITED" || this.code === "NETWORK_ERROR";
71
+ }
72
+ }
73
+ class GraphQLClient {
74
+ endpoint;
75
+ headers;
76
+ constructor(config) {
77
+ if (!config.endpoint) {
78
+ throw new GraphQLError(
79
+ "GraphQL endpoint is required",
80
+ GraphQLError.fromHTTPStatus(400, "Missing endpoint").code
81
+ );
82
+ }
83
+ this.endpoint = config.endpoint;
84
+ this.headers = {
85
+ "Content-Type": "application/json"
86
+ };
87
+ if (config.token) {
88
+ this.headers.Authorization = `Bearer ${config.token}`;
89
+ }
90
+ if (config.headers) {
91
+ Object.assign(this.headers, config.headers);
92
+ }
93
+ }
94
+ /**
95
+ * Execute a GraphQL query
96
+ */
97
+ async query(query, variables) {
98
+ return this.execute(query, variables);
99
+ }
100
+ /**
101
+ * Execute a GraphQL mutation
102
+ */
103
+ async mutate(mutation, variables) {
104
+ return this.execute(mutation, variables);
105
+ }
106
+ /**
107
+ * Execute GraphQL operation
108
+ */
109
+ async execute(operation, variables) {
110
+ let response;
111
+ try {
112
+ response = await fetch(this.endpoint, {
113
+ method: "POST",
114
+ headers: this.headers,
115
+ body: JSON.stringify({ query: operation, variables })
116
+ });
117
+ } catch (error) {
118
+ throw GraphQLError.networkError(
119
+ `Failed to connect to GraphQL API: ${error instanceof Error ? error.message : "Unknown error"}`,
120
+ error
121
+ );
122
+ }
123
+ if (!response.ok) {
124
+ const errorText = await response.text();
125
+ throw GraphQLError.fromHTTPStatus(
126
+ response.status,
127
+ `GraphQL error: ${response.statusText}
128
+ ${errorText}`,
129
+ errorText
130
+ );
131
+ }
132
+ const result = await response.json();
133
+ if (result.errors && result.errors.length > 0) {
134
+ throw GraphQLError.fromGraphQLErrors(result.errors);
135
+ }
136
+ if (!result.data) {
137
+ throw new GraphQLError(
138
+ "GraphQL response contained no data",
139
+ GraphQLError.fromHTTPStatus(500, "No data").code
140
+ );
141
+ }
142
+ return result.data;
143
+ }
144
+ }
145
+ function isGraphQLClientInstance(value) {
146
+ return value !== null && typeof value === "object" && "query" in value && "mutate" in value && typeof value.query === "function" && typeof value.mutate === "function";
147
+ }
148
+ async function getGraphQLClient(options) {
149
+ if (isGraphQLClientInstance(options)) {
150
+ return options;
151
+ }
152
+ if (!options.endpoint) {
153
+ throw new GraphQLError(
154
+ "GraphQL endpoint is required",
155
+ GraphQLErrorCode.VALIDATION_ERROR
156
+ );
157
+ }
158
+ return new GraphQLClient(options);
159
+ }
160
+ export {
161
+ GraphQLClient,
162
+ GraphQLError,
163
+ GraphQLErrorCode,
164
+ getGraphQLClient
165
+ };
166
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/errors.ts","../src/client.ts","../src/factory.ts"],"sourcesContent":["/**\n * GraphQL error handling\n */\n\nimport type { GraphQLErrorDetail } from './types.js';\n\n/**\n * Error codes for GraphQL operations\n */\nexport enum GraphQLErrorCode {\n /** Authentication failed */\n UNAUTHORIZED = 'UNAUTHORIZED',\n /** Resource not found */\n NOT_FOUND = 'NOT_FOUND',\n /** Rate limit exceeded */\n RATE_LIMITED = 'RATE_LIMITED',\n /** Network error */\n NETWORK_ERROR = 'NETWORK_ERROR',\n /** Invalid query or mutation */\n VALIDATION_ERROR = 'VALIDATION_ERROR',\n /** Unknown error */\n UNKNOWN = 'UNKNOWN',\n}\n\n/**\n * GraphQL error class\n */\nexport class GraphQLError extends Error {\n readonly code: GraphQLErrorCode;\n readonly details?: GraphQLErrorDetail[];\n readonly originalError?: unknown;\n\n constructor(\n message: string,\n code: GraphQLErrorCode,\n details?: GraphQLErrorDetail[],\n originalError?: unknown,\n ) {\n super(message);\n this.name = 'GraphQLError';\n this.code = code;\n this.details = details;\n this.originalError = originalError;\n }\n\n /**\n * Create error from HTTP status code\n */\n static fromHTTPStatus(\n status: number,\n message: string,\n originalError?: unknown,\n ): GraphQLError {\n let code: GraphQLErrorCode;\n\n switch (status) {\n case 401:\n code = GraphQLErrorCode.UNAUTHORIZED;\n break;\n case 403:\n code = GraphQLErrorCode.RATE_LIMITED;\n break;\n case 404:\n code = GraphQLErrorCode.NOT_FOUND;\n break;\n case 422:\n code = GraphQLErrorCode.VALIDATION_ERROR;\n break;\n default:\n code = GraphQLErrorCode.UNKNOWN;\n }\n\n return new GraphQLError(message, code, undefined, originalError);\n }\n\n /**\n * Create error from GraphQL response errors\n */\n static fromGraphQLErrors(errors: GraphQLErrorDetail[]): GraphQLError {\n const message = errors.map((e) => e.message).join('; ');\n return new GraphQLError(\n `GraphQL errors: ${message}`,\n GraphQLErrorCode.VALIDATION_ERROR,\n errors,\n );\n }\n\n /**\n * Create network error\n */\n static networkError(message: string, originalError?: unknown): GraphQLError {\n return new GraphQLError(\n message,\n GraphQLErrorCode.NETWORK_ERROR,\n undefined,\n originalError,\n );\n }\n\n /**\n * Check if error is retryable\n */\n isRetryable(): boolean {\n return (\n this.code === GraphQLErrorCode.RATE_LIMITED ||\n this.code === GraphQLErrorCode.NETWORK_ERROR\n );\n }\n}\n","/**\n * Generic GraphQL client\n */\n\nimport { GraphQLError } from './errors.js';\nimport type {\n GraphQLConfig,\n GraphQLErrorDetail,\n IGraphQLClient,\n} from './types.js';\n\n/**\n * Generic GraphQL client implementation\n *\n * Works with any GraphQL endpoint - GitHub, GitLab, Shopify, custom APIs, etc.\n */\nexport class GraphQLClient implements IGraphQLClient {\n private readonly endpoint: string;\n private readonly headers: Record<string, string>;\n\n constructor(config: GraphQLConfig) {\n if (!config.endpoint) {\n throw new GraphQLError(\n 'GraphQL endpoint is required',\n GraphQLError.fromHTTPStatus(400, 'Missing endpoint').code,\n );\n }\n\n this.endpoint = config.endpoint;\n\n // Build headers - start with defaults\n this.headers = {\n 'Content-Type': 'application/json',\n };\n\n // Add Authorization if token provided\n if (config.token) {\n this.headers.Authorization = `Bearer ${config.token}`;\n }\n\n // Merge custom headers (can override defaults)\n if (config.headers) {\n Object.assign(this.headers, config.headers);\n }\n }\n\n /**\n * Execute a GraphQL query\n */\n async query<T>(\n query: string,\n variables?: Record<string, unknown>,\n ): Promise<T> {\n return this.execute<T>(query, variables);\n }\n\n /**\n * Execute a GraphQL mutation\n */\n async mutate<T>(\n mutation: string,\n variables?: Record<string, unknown>,\n ): Promise<T> {\n return this.execute<T>(mutation, variables);\n }\n\n /**\n * Execute GraphQL operation\n */\n private async execute<T>(\n operation: string,\n variables?: Record<string, unknown>,\n ): Promise<T> {\n let response: Response;\n\n try {\n response = await fetch(this.endpoint, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({ query: operation, variables }),\n });\n } catch (error) {\n throw GraphQLError.networkError(\n `Failed to connect to GraphQL API: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error,\n );\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n throw GraphQLError.fromHTTPStatus(\n response.status,\n `GraphQL error: ${response.statusText}\\n${errorText}`,\n errorText,\n );\n }\n\n const result = (await response.json()) as {\n data?: T;\n errors?: GraphQLErrorDetail[];\n };\n\n if (result.errors && result.errors.length > 0) {\n throw GraphQLError.fromGraphQLErrors(result.errors);\n }\n\n if (!result.data) {\n throw new GraphQLError(\n 'GraphQL response contained no data',\n GraphQLError.fromHTTPStatus(500, 'No data').code,\n );\n }\n\n return result.data;\n }\n}\n","/**\n * GraphQL client factory function\n */\n\nimport { GraphQLClient } from './client.js';\nimport { GraphQLError, GraphQLErrorCode } from './errors.js';\nimport type { GraphQLConfig, IGraphQLClient } from './types.js';\n\n/**\n * Check if value is already a GraphQL client instance\n */\nfunction isGraphQLClientInstance(value: unknown): value is IGraphQLClient {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'query' in value &&\n 'mutate' in value &&\n typeof (value as IGraphQLClient).query === 'function' &&\n typeof (value as IGraphQLClient).mutate === 'function'\n );\n}\n\n/**\n * Get a GraphQL client instance\n *\n * This is the main entry point for creating GraphQL clients.\n * It can accept either a configuration object or an existing client instance.\n *\n * @param options - GraphQL configuration or existing client instance\n * @returns Promise resolving to GraphQL client interface\n *\n * @example\n * ```typescript\n * import { getGraphQLClient } from '@happyvertical/graphql';\n *\n * // Create a GitHub GraphQL client\n * const github = await getGraphQLClient({\n * endpoint: 'https://api.github.com/graphql',\n * token: process.env.GITHUB_TOKEN\n * });\n *\n * // Create a GitLab GraphQL client\n * const gitlab = await getGraphQLClient({\n * endpoint: 'https://gitlab.com/api/graphql',\n * token: process.env.GITLAB_TOKEN\n * });\n *\n * // Custom headers for other APIs\n * const custom = await getGraphQLClient({\n * endpoint: 'https://api.example.com/graphql',\n * headers: {\n * 'X-API-Key': 'my-api-key',\n * 'X-Custom-Header': 'value'\n * }\n * });\n *\n * // Execute a query\n * const result = await github.query<{ viewer: { login: string } }>(`\n * query {\n * viewer {\n * login\n * }\n * }\n * `);\n *\n * // Pass existing instance (returns it unchanged)\n * const sameClient = await getGraphQLClient(github);\n * ```\n */\nexport async function getGraphQLClient(\n options: GraphQLConfig | IGraphQLClient,\n): Promise<IGraphQLClient> {\n // If already a client instance, return it\n if (isGraphQLClientInstance(options)) {\n return options;\n }\n\n // Validate configuration\n if (!options.endpoint) {\n throw new GraphQLError(\n 'GraphQL endpoint is required',\n GraphQLErrorCode.VALIDATION_ERROR,\n );\n }\n\n return new GraphQLClient(options);\n}\n"],"names":["GraphQLErrorCode"],"mappings":"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"}
package/metadata.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@happyvertical/graphql",
3
+ "path": "packages/graphql",
4
+ "position": {
5
+ "index": 14,
6
+ "count": 30
7
+ },
8
+ "description": "GitHub GraphQL client for SDK packages",
9
+ "provides": [
10
+ "GitHub GraphQL client for SDK packages"
11
+ ],
12
+ "implements": [],
13
+ "requires": {
14
+ "workspace": [],
15
+ "externalHappyVertical": [],
16
+ "external": []
17
+ },
18
+ "dependents": [
19
+ "@happyvertical/projects",
20
+ "@happyvertical/repos"
21
+ ],
22
+ "stability": {
23
+ "level": "stable",
24
+ "reason": "Primary package surface is described as implemented and production-oriented."
25
+ },
26
+ "keywords": [
27
+ "graphql"
28
+ ]
29
+ }
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@happyvertical/graphql",
3
+ "version": "0.74.8",
4
+ "description": "GitHub GraphQL client for SDK packages",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "bin": {
15
+ "have-graphql-context": "./dist/cli/claude-context.js"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "25.0.10",
19
+ "typescript": "^5.9.3",
20
+ "vite": "7.3.2",
21
+ "vite-plugin-dts": "4.5.4",
22
+ "vitest": "4.1.5"
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "README.md",
27
+ "LICENSE",
28
+ "AGENT.md",
29
+ "metadata.json"
30
+ ],
31
+ "publishConfig": {
32
+ "registry": "https://registry.npmjs.org",
33
+ "access": "public"
34
+ },
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/happyvertical/sdk.git",
38
+ "directory": "packages/graphql"
39
+ },
40
+ "bugs": {
41
+ "url": "https://github.com/happyvertical/sdk/issues"
42
+ },
43
+ "homepage": "https://github.com/happyvertical/sdk/tree/main/packages/graphql#readme",
44
+ "license": "MIT",
45
+ "scripts": {
46
+ "test": "npx vitest run --passWithNoTests",
47
+ "test:watch": "npx vitest",
48
+ "build": "vite build",
49
+ "build:watch": "vite build --watch",
50
+ "clean": "rm -rf dist",
51
+ "dev": "npm run build:watch & npm run test:watch"
52
+ }
53
+ }