@executor-js/plugin-graphql 1.5.22 → 1.5.24
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/dist/{AddGraphqlSource-B7ZOZ7WM.js → AddGraphqlSource-WZIUR2NX.js} +4 -8
- package/dist/AddGraphqlSource-WZIUR2NX.js.map +1 -0
- package/dist/{GraphqlAccountsPanel-QGBVXP2A.js → GraphqlAccountsPanel-LUSTMA3K.js} +3 -3
- package/dist/{chunk-IUCH3RWQ.js → chunk-DQ3XWZ6J.js} +80 -23
- package/dist/chunk-DQ3XWZ6J.js.map +1 -0
- package/dist/{chunk-732HGFSH.js → chunk-JTWENVHO.js} +10 -2
- package/dist/chunk-JTWENVHO.js.map +1 -0
- package/dist/{chunk-VSLIDDNK.js → chunk-ZUGWBXOU.js} +2 -2
- package/dist/client.js +2 -2
- package/dist/core.js +2 -2
- package/dist/index.js +2 -2
- package/dist/sdk/invoke.d.ts +10 -0
- package/dist/sdk/types.d.ts +9 -1
- package/dist/sdk/validate-selection.d.ts +3 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing.js +64 -0
- package/dist/testing.js.map +1 -1
- package/package.json +3 -3
- package/dist/AddGraphqlSource-B7ZOZ7WM.js.map +0 -1
- package/dist/chunk-732HGFSH.js.map +0 -1
- package/dist/chunk-IUCH3RWQ.js.map +0 -1
- /package/dist/{GraphqlAccountsPanel-QGBVXP2A.js.map → GraphqlAccountsPanel-LUSTMA3K.js.map} +0 -0
- /package/dist/{chunk-VSLIDDNK.js.map → chunk-ZUGWBXOU.js.map} +0 -0
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
GraphqlAuthMethodInput,
|
|
4
4
|
GraphqlExtractionError,
|
|
5
5
|
GraphqlIntrospectionError
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JTWENVHO.js";
|
|
7
7
|
|
|
8
8
|
// src/react/atoms.ts
|
|
9
9
|
import * as Atom from "effect/unstable/reactivity/Atom";
|
|
@@ -166,4 +166,4 @@ export {
|
|
|
166
166
|
graphqlAuthMethodInputsFromPlacements,
|
|
167
167
|
graphqlWireAuthInput
|
|
168
168
|
};
|
|
169
|
-
//# sourceMappingURL=chunk-
|
|
169
|
+
//# sourceMappingURL=chunk-ZUGWBXOU.js.map
|
package/dist/client.js
CHANGED
|
@@ -7,8 +7,8 @@ import { defineClientPlugin } from "@executor-js/sdk/client";
|
|
|
7
7
|
|
|
8
8
|
// src/react/source-plugin.ts
|
|
9
9
|
import { lazy } from "react";
|
|
10
|
-
var importAdd = () => import("./AddGraphqlSource-
|
|
11
|
-
var importAccounts = () => import("./GraphqlAccountsPanel-
|
|
10
|
+
var importAdd = () => import("./AddGraphqlSource-WZIUR2NX.js");
|
|
11
|
+
var importAccounts = () => import("./GraphqlAccountsPanel-LUSTMA3K.js");
|
|
12
12
|
var graphqlIntegrationPlugin = {
|
|
13
13
|
key: "graphql",
|
|
14
14
|
label: "GraphQL",
|
package/dist/core.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
invokeWithLayer,
|
|
8
8
|
makeDefaultGraphqlStore,
|
|
9
9
|
parseIntrospectionJson
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-DQ3XWZ6J.js";
|
|
11
11
|
import "./chunk-QVJ2HNNZ.js";
|
|
12
12
|
import {
|
|
13
13
|
ExtractedField,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
decodeGraphqlIntegrationConfig,
|
|
28
28
|
decodeGraphqlIntegrationConfigOption,
|
|
29
29
|
normalizeGraphqlAuthMethods
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-JTWENVHO.js";
|
|
31
31
|
|
|
32
32
|
// src/sdk/migrate-config.ts
|
|
33
33
|
import { Option, Schema } from "effect";
|
package/dist/index.js
CHANGED
package/dist/sdk/invoke.d.ts
CHANGED
|
@@ -3,11 +3,21 @@ import { HttpClient } from "effect/unstable/http";
|
|
|
3
3
|
import { GraphqlInvocationError } from "./errors";
|
|
4
4
|
import { type OperationBinding } from "./types";
|
|
5
5
|
export declare const endpointForTelemetry: (endpoint: string) => string;
|
|
6
|
+
/** The operation string to send for a call. A caller-supplied `select` overrides
|
|
7
|
+
* the default scalar-leaf selection: it is spliced into the field's selection
|
|
8
|
+
* set (`field { <select> }`) so nested/list data can be requested per call. Falls
|
|
9
|
+
* back to the stored default operation when `select` is absent or the binding
|
|
10
|
+
* predates the prefix/suffix split. `select` is a control input, never a GraphQL
|
|
11
|
+
* variable. Shared with plugin.invokeTool so the validated string matches the
|
|
12
|
+
* sent string exactly. */
|
|
13
|
+
export declare const effectiveOperationString: (operation: OperationBinding, args: Record<string, unknown>) => string;
|
|
6
14
|
export declare const invoke: (operation: {
|
|
7
15
|
readonly kind: "query" | "mutation";
|
|
8
16
|
readonly fieldName: string;
|
|
9
17
|
readonly variableNames: readonly string[];
|
|
10
18
|
readonly operationString: string;
|
|
19
|
+
readonly operationPrefix?: string | undefined;
|
|
20
|
+
readonly operationSuffix?: string | undefined;
|
|
11
21
|
}, args: Record<string, unknown>, endpoint: string, resolvedHeaders: Record<string, string>, resolvedQueryParams?: Record<string, string> | undefined) => Effect.Effect<{
|
|
12
22
|
readonly data: unknown;
|
|
13
23
|
readonly status: number;
|
package/dist/sdk/types.d.ts
CHANGED
|
@@ -52,8 +52,16 @@ export type ExtractionResult = typeof ExtractionResult.Type;
|
|
|
52
52
|
export declare const OperationBinding: Schema.Struct<{
|
|
53
53
|
readonly kind: Schema.Literals<readonly ["query", "mutation"]>;
|
|
54
54
|
readonly fieldName: Schema.String;
|
|
55
|
-
/** The full GraphQL query/mutation string
|
|
55
|
+
/** The full GraphQL query/mutation string, with the default scalar-leaf
|
|
56
|
+
* selection. Sent when the caller does not supply a custom `select`. */
|
|
56
57
|
readonly operationString: Schema.String;
|
|
58
|
+
/** Operation text up to (not including) the field's selection set, e.g.
|
|
59
|
+
* `query Op($a: T) { field(a: $a)`. With `operationSuffix`, lets `invoke`
|
|
60
|
+
* splice a caller-supplied `select` as `{ <select> }` without re-introspecting.
|
|
61
|
+
* Optional so bindings persisted before this field still decode. */
|
|
62
|
+
readonly operationPrefix: Schema.optional<Schema.String>;
|
|
63
|
+
/** Closes the operation (` }`); pairs with `operationPrefix`. */
|
|
64
|
+
readonly operationSuffix: Schema.optional<Schema.String>;
|
|
57
65
|
/** Ordered variable names for mapping */
|
|
58
66
|
readonly variableNames: Schema.$Array<Schema.String>;
|
|
59
67
|
}>;
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -63,6 +63,7 @@ export declare class GraphqlTestServer extends GraphqlTestServer_base {
|
|
|
63
63
|
export declare const makeGreetingGraphqlSchema: (options?: {
|
|
64
64
|
readonly includeMutation?: boolean;
|
|
65
65
|
}) => GraphQLSchema;
|
|
66
|
+
export declare const makeGitlab1146Schema: () => GraphQLSchema;
|
|
66
67
|
export declare const TestLayers: {
|
|
67
68
|
greeting: () => Layer.Layer<GraphqlTestServer, GraphqlTestServerAddressError | GraphqlTestServerHandlerError, never>;
|
|
68
69
|
greetingWithOAuth: () => Layer.Layer<GraphqlTestServer, GraphqlTestServerAddressError | GraphqlTestServerHandlerError, OAuthTestServer>;
|
package/dist/testing.js
CHANGED
|
@@ -165,6 +165,69 @@ var makeGreetingGraphqlSchema = (options = {}) => {
|
|
|
165
165
|
}
|
|
166
166
|
});
|
|
167
167
|
};
|
|
168
|
+
var makeGitlab1146Schema = () => createSchema({
|
|
169
|
+
typeDefs: (
|
|
170
|
+
/* GraphQL */
|
|
171
|
+
`
|
|
172
|
+
type Query {
|
|
173
|
+
metadata: Metadata
|
|
174
|
+
currentUser: User
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
type Metadata {
|
|
178
|
+
version: String
|
|
179
|
+
revision: String
|
|
180
|
+
enterprise: Boolean
|
|
181
|
+
featureFlags(names: [String!]!): [FeatureFlag!]!
|
|
182
|
+
kas: Kas
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
type FeatureFlag {
|
|
186
|
+
name: String
|
|
187
|
+
enabled: Boolean
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
type Kas {
|
|
191
|
+
enabled: Boolean
|
|
192
|
+
externalUrl: String
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
type User {
|
|
196
|
+
active: Boolean
|
|
197
|
+
admin: Boolean
|
|
198
|
+
mergeRequests: MergeRequestConnection
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
type MergeRequestConnection {
|
|
202
|
+
count: Int
|
|
203
|
+
nodes: [MergeRequest!]
|
|
204
|
+
pageInfo: PageInfo
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
type PageInfo {
|
|
208
|
+
hasNextPage: Boolean
|
|
209
|
+
endCursor: String
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
type MergeRequest {
|
|
213
|
+
id: ID
|
|
214
|
+
title: String
|
|
215
|
+
author: Author
|
|
216
|
+
assignees: AssigneeConnection
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
type Author {
|
|
220
|
+
name: String
|
|
221
|
+
username: String
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
type AssigneeConnection {
|
|
225
|
+
count: Int
|
|
226
|
+
nodes: [Author!]
|
|
227
|
+
}
|
|
228
|
+
`
|
|
229
|
+
)
|
|
230
|
+
});
|
|
168
231
|
var TestLayers = {
|
|
169
232
|
greeting: () => GraphqlTestServer.layer({ schema: makeGreetingGraphqlSchema() }),
|
|
170
233
|
greetingWithOAuth: () => GraphqlTestServer.layerWithOAuth({ schema: makeGreetingGraphqlSchema() })
|
|
@@ -172,6 +235,7 @@ var TestLayers = {
|
|
|
172
235
|
export {
|
|
173
236
|
GraphqlTestServer,
|
|
174
237
|
TestLayers,
|
|
238
|
+
makeGitlab1146Schema,
|
|
175
239
|
makeGreetingGraphqlSchema,
|
|
176
240
|
serveGraphqlFailureTestServer,
|
|
177
241
|
serveGraphqlTestServer
|
package/dist/testing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/testing/index.ts"],"sourcesContent":["import {\n Context,\n Data,\n Effect,\n Layer,\n Predicate,\n Ref,\n Schema as EffectSchema,\n Scope,\n} from \"effect\";\nimport { HttpServerRequest, HttpServerResponse } from \"effect/unstable/http\";\nimport type { GraphQLSchema } from \"graphql\";\nimport {\n createSchema,\n createYoga,\n type GraphQLParams,\n type YogaInitialContext,\n} from \"graphql-yoga\";\nimport { OAuthTestServer, serveTestHttpApp } from \"@executor-js/sdk/testing\";\n\nconst GraphqlRequestPayload = EffectSchema.Struct({\n query: EffectSchema.optional(EffectSchema.String),\n variables: EffectSchema.optional(EffectSchema.Record(EffectSchema.String, EffectSchema.Unknown)),\n operationName: EffectSchema.optional(EffectSchema.NullOr(EffectSchema.String)),\n});\n\ntype GraphqlRequestPayload = typeof GraphqlRequestPayload.Type;\n\nexport interface GraphqlTestRequest {\n readonly url: string;\n readonly method: string;\n readonly path: string;\n readonly headers: Readonly<Record<string, string>>;\n readonly payload: GraphqlRequestPayload;\n}\n\nexport interface GraphqlTestContext {\n readonly request: GraphqlTestRequest;\n}\n\nexport interface GraphqlTestServerOptions {\n readonly schema: GraphQLSchema;\n readonly path?: string;\n readonly auth?: {\n readonly validateAuthorization: (authorization: string | null) => Effect.Effect<boolean>;\n readonly wwwAuthenticate?: string;\n };\n}\n\nexport interface GraphqlTestServerShape {\n readonly endpoint: string;\n readonly schema: GraphQLSchema;\n readonly requests: Effect.Effect<readonly GraphqlTestRequest[]>;\n readonly clearRequests: Effect.Effect<void>;\n}\n\nclass GraphqlTestServerAddressError extends Data.TaggedError(\"GraphqlTestServerAddressError\")<{\n readonly address: unknown;\n}> {}\n\nclass GraphqlTestServerHandlerError extends Data.TaggedError(\"GraphqlTestServerHandlerError\")<{\n readonly cause: unknown;\n}> {}\n\nconst headersFromRequest = (headers: Headers): Readonly<Record<string, string>> =>\n Object.fromEntries(headers.entries());\n\nconst payloadFromParams = (params: GraphQLParams): GraphqlRequestPayload => ({\n query: params.query,\n variables:\n typeof params.variables === \"object\" && params.variables !== null\n ? params.variables\n : undefined,\n operationName: params.operationName ?? null,\n});\n\nconst captureRequest = (\n initial: YogaInitialContext,\n requests: Ref.Ref<readonly GraphqlTestRequest[]>,\n) => {\n const url = new URL(initial.request.url);\n const captured: GraphqlTestRequest = {\n url: initial.request.url,\n method: initial.request.method,\n path: url.pathname,\n headers: headersFromRequest(initial.request.headers),\n payload: payloadFromParams(initial.params),\n };\n return Effect.runPromise(\n Ref.update(requests, (all) => [...all, captured]).pipe(Effect.as(captured)),\n );\n};\n\nexport const serveGraphqlTestServer = (\n options: GraphqlTestServerOptions,\n): Effect.Effect<\n GraphqlTestServerShape,\n GraphqlTestServerAddressError | GraphqlTestServerHandlerError,\n Scope.Scope\n> =>\n Effect.gen(function* () {\n const requests = yield* Ref.make<readonly GraphqlTestRequest[]>([]);\n const path = options.path ?? \"/graphql\";\n\n const yoga = createYoga<Record<string, never>, GraphqlTestContext>({\n schema: options.schema,\n graphqlEndpoint: path,\n graphiql: false,\n landingPage: false,\n logging: false,\n maskedErrors: false,\n context: (initial) =>\n captureRequest(initial, requests).then((request) => ({\n request,\n })),\n });\n\n const server = yield* serveTestHttpApp((request) =>\n Effect.gen(function* () {\n if (options.auth) {\n const accepted = yield* options.auth.validateAuthorization(\n request.headers.authorization ?? null,\n );\n if (!accepted) {\n const responseOptions = options.auth.wwwAuthenticate\n ? {\n status: 401,\n headers: { \"www-authenticate\": options.auth.wwwAuthenticate },\n }\n : { status: 401 };\n return HttpServerResponse.jsonUnsafe(\n { errors: [{ message: \"Unauthorized\" }] },\n responseOptions,\n );\n }\n }\n const webRequest = yield* HttpServerRequest.toWeb(request);\n const response = yield* Effect.promise(() => Promise.resolve(yoga.handle(webRequest, {})));\n return HttpServerResponse.fromWeb(response);\n }).pipe(\n Effect.catch(() =>\n Effect.succeed(\n HttpServerResponse.text(\"GraphQL test server failed\", {\n status: 500,\n contentType: \"text/plain\",\n }),\n ),\n ),\n ),\n ).pipe(\n Effect.mapError((error) =>\n Predicate.isTagged(error, \"TestHttpServerAddressError\")\n ? new GraphqlTestServerAddressError({ address: error.address })\n : new GraphqlTestServerHandlerError({ cause: error.cause }),\n ),\n );\n\n return {\n endpoint: server.url(path),\n schema: options.schema,\n requests: Ref.get(requests),\n clearRequests: Ref.set(requests, []),\n };\n });\n\nexport const serveGraphqlFailureTestServer = (options: {\n readonly status: number;\n readonly body: string;\n readonly contentType?: string;\n readonly path?: string;\n}) =>\n serveTestHttpApp(() =>\n Effect.succeed(\n HttpServerResponse.text(options.body, {\n status: options.status,\n contentType: options.contentType ?? \"text/plain\",\n }),\n ),\n ).pipe(\n Effect.map((server) => ({\n endpoint: server.url(options.path ?? \"/graphql\"),\n httpClientLayer: server.httpClientLayer,\n })),\n );\n\nexport class GraphqlTestServer extends Context.Service<GraphqlTestServer, GraphqlTestServerShape>()(\n \"@executor-js/plugin-graphql/testing/GraphqlTestServer\",\n) {\n static readonly layer = (options: GraphqlTestServerOptions) =>\n Layer.effect(GraphqlTestServer, serveGraphqlTestServer(options));\n\n static readonly layerWithOAuth = (options: Omit<GraphqlTestServerOptions, \"auth\">) =>\n Layer.effect(\n GraphqlTestServer,\n Effect.gen(function* () {\n const oauth = yield* OAuthTestServer;\n return yield* serveGraphqlTestServer({\n ...options,\n auth: {\n validateAuthorization: oauth.acceptsAuthorizationHeader,\n wwwAuthenticate: 'Bearer error=\"invalid_token\"',\n },\n });\n }),\n );\n}\n\nconst stringArgument = (\n args: Readonly<Record<string, unknown>>,\n key: string,\n fallback: string,\n): string => {\n const value = args[key];\n return typeof value === \"string\" ? value : fallback;\n};\n\nexport const makeGreetingGraphqlSchema = (\n options: { readonly includeMutation?: boolean } = {},\n): GraphQLSchema => {\n const includeMutation = options.includeMutation ?? true;\n return createSchema<GraphqlTestContext>({\n typeDefs: /* GraphQL */ `\n type Query {\n hello(name: String): String\n }\n\n ${\n includeMutation\n ? /* GraphQL */ `\n type Mutation {\n setGreeting(message: String!): String\n }\n `\n : \"\"\n }\n `,\n resolvers: {\n Query: {\n hello: (_source: unknown, args: Readonly<Record<string, unknown>>) =>\n `Hello ${stringArgument(args, \"name\", \"world\")}`,\n },\n ...(includeMutation\n ? {\n Mutation: {\n setGreeting: (_source: unknown, args: Readonly<Record<string, unknown>>) =>\n stringArgument(args, \"message\", \"\"),\n },\n }\n : {}),\n },\n });\n};\n\nexport const TestLayers = {\n greeting: () => GraphqlTestServer.layer({ schema: makeGreetingGraphqlSchema() }),\n greetingWithOAuth: () =>\n GraphqlTestServer.layerWithOAuth({ schema: makeGreetingGraphqlSchema() }),\n};\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,OAEL;AACP,SAAS,mBAAmB,0BAA0B;AAEtD;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP,SAAS,iBAAiB,wBAAwB;AAElD,IAAM,wBAAwB,aAAa,OAAO;AAAA,EAChD,OAAO,aAAa,SAAS,aAAa,MAAM;AAAA,EAChD,WAAW,aAAa,SAAS,aAAa,OAAO,aAAa,QAAQ,aAAa,OAAO,CAAC;AAAA,EAC/F,eAAe,aAAa,SAAS,aAAa,OAAO,aAAa,MAAM,CAAC;AAC/E,CAAC;AAgCD,IAAM,gCAAN,cAA4C,KAAK,YAAY,+BAA+B,EAEzF;AAAC;AAEJ,IAAM,gCAAN,cAA4C,KAAK,YAAY,+BAA+B,EAEzF;AAAC;AAEJ,IAAM,qBAAqB,CAAC,YAC1B,OAAO,YAAY,QAAQ,QAAQ,CAAC;AAEtC,IAAM,oBAAoB,CAAC,YAAkD;AAAA,EAC3E,OAAO,OAAO;AAAA,EACd,WACE,OAAO,OAAO,cAAc,YAAY,OAAO,cAAc,OACzD,OAAO,YACP;AAAA,EACN,eAAe,OAAO,iBAAiB;AACzC;AAEA,IAAM,iBAAiB,CACrB,SACA,aACG;AACH,QAAM,MAAM,IAAI,IAAI,QAAQ,QAAQ,GAAG;AACvC,QAAM,WAA+B;AAAA,IACnC,KAAK,QAAQ,QAAQ;AAAA,IACrB,QAAQ,QAAQ,QAAQ;AAAA,IACxB,MAAM,IAAI;AAAA,IACV,SAAS,mBAAmB,QAAQ,QAAQ,OAAO;AAAA,IACnD,SAAS,kBAAkB,QAAQ,MAAM;AAAA,EAC3C;AACA,SAAO,OAAO;AAAA,IACZ,IAAI,OAAO,UAAU,CAAC,QAAQ,CAAC,GAAG,KAAK,QAAQ,CAAC,EAAE,KAAK,OAAO,GAAG,QAAQ,CAAC;AAAA,EAC5E;AACF;AAEO,IAAM,yBAAyB,CACpC,YAMA,OAAO,IAAI,aAAa;AACtB,QAAM,WAAW,OAAO,IAAI,KAAoC,CAAC,CAAC;AAClE,QAAM,OAAO,QAAQ,QAAQ;AAE7B,QAAM,OAAO,WAAsD;AAAA,IACjE,QAAQ,QAAQ;AAAA,IAChB,iBAAiB;AAAA,IACjB,UAAU;AAAA,IACV,aAAa;AAAA,IACb,SAAS;AAAA,IACT,cAAc;AAAA,IACd,SAAS,CAAC,YACR,eAAe,SAAS,QAAQ,EAAE,KAAK,CAAC,aAAa;AAAA,MACnD;AAAA,IACF,EAAE;AAAA,EACN,CAAC;AAED,QAAM,SAAS,OAAO;AAAA,IAAiB,CAAC,YACtC,OAAO,IAAI,aAAa;AACtB,UAAI,QAAQ,MAAM;AAChB,cAAM,WAAW,OAAO,QAAQ,KAAK;AAAA,UACnC,QAAQ,QAAQ,iBAAiB;AAAA,QACnC;AACA,YAAI,CAAC,UAAU;AACb,gBAAM,kBAAkB,QAAQ,KAAK,kBACjC;AAAA,YACE,QAAQ;AAAA,YACR,SAAS,EAAE,oBAAoB,QAAQ,KAAK,gBAAgB;AAAA,UAC9D,IACA,EAAE,QAAQ,IAAI;AAClB,iBAAO,mBAAmB;AAAA,YACxB,EAAE,QAAQ,CAAC,EAAE,SAAS,eAAe,CAAC,EAAE;AAAA,YACxC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,YAAM,aAAa,OAAO,kBAAkB,MAAM,OAAO;AACzD,YAAM,WAAW,OAAO,OAAO,QAAQ,MAAM,QAAQ,QAAQ,KAAK,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC;AACzF,aAAO,mBAAmB,QAAQ,QAAQ;AAAA,IAC5C,CAAC,EAAE;AAAA,MACD,OAAO;AAAA,QAAM,MACX,OAAO;AAAA,UACL,mBAAmB,KAAK,8BAA8B;AAAA,YACpD,QAAQ;AAAA,YACR,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF,EAAE;AAAA,IACA,OAAO;AAAA,MAAS,CAAC,UACf,UAAU,SAAS,OAAO,4BAA4B,IAClD,IAAI,8BAA8B,EAAE,SAAS,MAAM,QAAQ,CAAC,IAC5D,IAAI,8BAA8B,EAAE,OAAO,MAAM,MAAM,CAAC;AAAA,IAC9D;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAU,OAAO,IAAI,IAAI;AAAA,IACzB,QAAQ,QAAQ;AAAA,IAChB,UAAU,IAAI,IAAI,QAAQ;AAAA,IAC1B,eAAe,IAAI,IAAI,UAAU,CAAC,CAAC;AAAA,EACrC;AACF,CAAC;AAEI,IAAM,gCAAgC,CAAC,YAM5C;AAAA,EAAiB,MACf,OAAO;AAAA,IACL,mBAAmB,KAAK,QAAQ,MAAM;AAAA,MACpC,QAAQ,QAAQ;AAAA,MAChB,aAAa,QAAQ,eAAe;AAAA,IACtC,CAAC;AAAA,EACH;AACF,EAAE;AAAA,EACA,OAAO,IAAI,CAAC,YAAY;AAAA,IACtB,UAAU,OAAO,IAAI,QAAQ,QAAQ,UAAU;AAAA,IAC/C,iBAAiB,OAAO;AAAA,EAC1B,EAAE;AACJ;AAEK,IAAM,oBAAN,MAAM,2BAA0B,QAAQ,QAAmD;AAAA,EAChG;AACF,EAAE;AAAA,EACA,OAAgB,QAAQ,CAAC,YACvB,MAAM,OAAO,oBAAmB,uBAAuB,OAAO,CAAC;AAAA,EAEjE,OAAgB,iBAAiB,CAAC,YAChC,MAAM;AAAA,IACJ;AAAA,IACA,OAAO,IAAI,aAAa;AACtB,YAAM,QAAQ,OAAO;AACrB,aAAO,OAAO,uBAAuB;AAAA,QACnC,GAAG;AAAA,QACH,MAAM;AAAA,UACJ,uBAAuB,MAAM;AAAA,UAC7B,iBAAiB;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACJ;AAEA,IAAM,iBAAiB,CACrB,MACA,KACA,aACW;AACX,QAAM,QAAQ,KAAK,GAAG;AACtB,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEO,IAAM,4BAA4B,CACvC,UAAkD,CAAC,MACjC;AAClB,QAAM,kBAAkB,QAAQ,mBAAmB;AACnD,SAAO,aAAiC;AAAA,IACtC;AAAA;AAAA,MAAwB;AAAA;AAAA;AAAA;AAAA;AAAA,QAMpB;AAAA;AAAA,QACkB;AAAA;AAAA;AAAA;AAAA;AAAA,UAKd,EACN;AAAA;AAAA;AAAA,IAEF,WAAW;AAAA,MACT,OAAO;AAAA,QACL,OAAO,CAAC,SAAkB,SACxB,SAAS,eAAe,MAAM,QAAQ,OAAO,CAAC;AAAA,MAClD;AAAA,MACA,GAAI,kBACA;AAAA,QACE,UAAU;AAAA,UACR,aAAa,CAAC,SAAkB,SAC9B,eAAe,MAAM,WAAW,EAAE;AAAA,QACtC;AAAA,MACF,IACA,CAAC;AAAA,IACP;AAAA,EACF,CAAC;AACH;AAEO,IAAM,aAAa;AAAA,EACxB,UAAU,MAAM,kBAAkB,MAAM,EAAE,QAAQ,0BAA0B,EAAE,CAAC;AAAA,EAC/E,mBAAmB,MACjB,kBAAkB,eAAe,EAAE,QAAQ,0BAA0B,EAAE,CAAC;AAC5E;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/testing/index.ts"],"sourcesContent":["import {\n Context,\n Data,\n Effect,\n Layer,\n Predicate,\n Ref,\n Schema as EffectSchema,\n Scope,\n} from \"effect\";\nimport { HttpServerRequest, HttpServerResponse } from \"effect/unstable/http\";\nimport type { GraphQLSchema } from \"graphql\";\nimport {\n createSchema,\n createYoga,\n type GraphQLParams,\n type YogaInitialContext,\n} from \"graphql-yoga\";\nimport { OAuthTestServer, serveTestHttpApp } from \"@executor-js/sdk/testing\";\n\nconst GraphqlRequestPayload = EffectSchema.Struct({\n query: EffectSchema.optional(EffectSchema.String),\n variables: EffectSchema.optional(EffectSchema.Record(EffectSchema.String, EffectSchema.Unknown)),\n operationName: EffectSchema.optional(EffectSchema.NullOr(EffectSchema.String)),\n});\n\ntype GraphqlRequestPayload = typeof GraphqlRequestPayload.Type;\n\nexport interface GraphqlTestRequest {\n readonly url: string;\n readonly method: string;\n readonly path: string;\n readonly headers: Readonly<Record<string, string>>;\n readonly payload: GraphqlRequestPayload;\n}\n\nexport interface GraphqlTestContext {\n readonly request: GraphqlTestRequest;\n}\n\nexport interface GraphqlTestServerOptions {\n readonly schema: GraphQLSchema;\n readonly path?: string;\n readonly auth?: {\n readonly validateAuthorization: (authorization: string | null) => Effect.Effect<boolean>;\n readonly wwwAuthenticate?: string;\n };\n}\n\nexport interface GraphqlTestServerShape {\n readonly endpoint: string;\n readonly schema: GraphQLSchema;\n readonly requests: Effect.Effect<readonly GraphqlTestRequest[]>;\n readonly clearRequests: Effect.Effect<void>;\n}\n\nclass GraphqlTestServerAddressError extends Data.TaggedError(\"GraphqlTestServerAddressError\")<{\n readonly address: unknown;\n}> {}\n\nclass GraphqlTestServerHandlerError extends Data.TaggedError(\"GraphqlTestServerHandlerError\")<{\n readonly cause: unknown;\n}> {}\n\nconst headersFromRequest = (headers: Headers): Readonly<Record<string, string>> =>\n Object.fromEntries(headers.entries());\n\nconst payloadFromParams = (params: GraphQLParams): GraphqlRequestPayload => ({\n query: params.query,\n variables:\n typeof params.variables === \"object\" && params.variables !== null\n ? params.variables\n : undefined,\n operationName: params.operationName ?? null,\n});\n\nconst captureRequest = (\n initial: YogaInitialContext,\n requests: Ref.Ref<readonly GraphqlTestRequest[]>,\n) => {\n const url = new URL(initial.request.url);\n const captured: GraphqlTestRequest = {\n url: initial.request.url,\n method: initial.request.method,\n path: url.pathname,\n headers: headersFromRequest(initial.request.headers),\n payload: payloadFromParams(initial.params),\n };\n return Effect.runPromise(\n Ref.update(requests, (all) => [...all, captured]).pipe(Effect.as(captured)),\n );\n};\n\nexport const serveGraphqlTestServer = (\n options: GraphqlTestServerOptions,\n): Effect.Effect<\n GraphqlTestServerShape,\n GraphqlTestServerAddressError | GraphqlTestServerHandlerError,\n Scope.Scope\n> =>\n Effect.gen(function* () {\n const requests = yield* Ref.make<readonly GraphqlTestRequest[]>([]);\n const path = options.path ?? \"/graphql\";\n\n const yoga = createYoga<Record<string, never>, GraphqlTestContext>({\n schema: options.schema,\n graphqlEndpoint: path,\n graphiql: false,\n landingPage: false,\n logging: false,\n maskedErrors: false,\n context: (initial) =>\n captureRequest(initial, requests).then((request) => ({\n request,\n })),\n });\n\n const server = yield* serveTestHttpApp((request) =>\n Effect.gen(function* () {\n if (options.auth) {\n const accepted = yield* options.auth.validateAuthorization(\n request.headers.authorization ?? null,\n );\n if (!accepted) {\n const responseOptions = options.auth.wwwAuthenticate\n ? {\n status: 401,\n headers: { \"www-authenticate\": options.auth.wwwAuthenticate },\n }\n : { status: 401 };\n return HttpServerResponse.jsonUnsafe(\n { errors: [{ message: \"Unauthorized\" }] },\n responseOptions,\n );\n }\n }\n const webRequest = yield* HttpServerRequest.toWeb(request);\n const response = yield* Effect.promise(() => Promise.resolve(yoga.handle(webRequest, {})));\n return HttpServerResponse.fromWeb(response);\n }).pipe(\n Effect.catch(() =>\n Effect.succeed(\n HttpServerResponse.text(\"GraphQL test server failed\", {\n status: 500,\n contentType: \"text/plain\",\n }),\n ),\n ),\n ),\n ).pipe(\n Effect.mapError((error) =>\n Predicate.isTagged(error, \"TestHttpServerAddressError\")\n ? new GraphqlTestServerAddressError({ address: error.address })\n : new GraphqlTestServerHandlerError({ cause: error.cause }),\n ),\n );\n\n return {\n endpoint: server.url(path),\n schema: options.schema,\n requests: Ref.get(requests),\n clearRequests: Ref.set(requests, []),\n };\n });\n\nexport const serveGraphqlFailureTestServer = (options: {\n readonly status: number;\n readonly body: string;\n readonly contentType?: string;\n readonly path?: string;\n}) =>\n serveTestHttpApp(() =>\n Effect.succeed(\n HttpServerResponse.text(options.body, {\n status: options.status,\n contentType: options.contentType ?? \"text/plain\",\n }),\n ),\n ).pipe(\n Effect.map((server) => ({\n endpoint: server.url(options.path ?? \"/graphql\"),\n httpClientLayer: server.httpClientLayer,\n })),\n );\n\nexport class GraphqlTestServer extends Context.Service<GraphqlTestServer, GraphqlTestServerShape>()(\n \"@executor-js/plugin-graphql/testing/GraphqlTestServer\",\n) {\n static readonly layer = (options: GraphqlTestServerOptions) =>\n Layer.effect(GraphqlTestServer, serveGraphqlTestServer(options));\n\n static readonly layerWithOAuth = (options: Omit<GraphqlTestServerOptions, \"auth\">) =>\n Layer.effect(\n GraphqlTestServer,\n Effect.gen(function* () {\n const oauth = yield* OAuthTestServer;\n return yield* serveGraphqlTestServer({\n ...options,\n auth: {\n validateAuthorization: oauth.acceptsAuthorizationHeader,\n wwwAuthenticate: 'Bearer error=\"invalid_token\"',\n },\n });\n }),\n );\n}\n\nconst stringArgument = (\n args: Readonly<Record<string, unknown>>,\n key: string,\n fallback: string,\n): string => {\n const value = args[key];\n return typeof value === \"string\" ? value : fallback;\n};\n\nexport const makeGreetingGraphqlSchema = (\n options: { readonly includeMutation?: boolean } = {},\n): GraphQLSchema => {\n const includeMutation = options.includeMutation ?? true;\n return createSchema<GraphqlTestContext>({\n typeDefs: /* GraphQL */ `\n type Query {\n hello(name: String): String\n }\n\n ${\n includeMutation\n ? /* GraphQL */ `\n type Mutation {\n setGreeting(message: String!): String\n }\n `\n : \"\"\n }\n `,\n resolvers: {\n Query: {\n hello: (_source: unknown, args: Readonly<Record<string, unknown>>) =>\n `Hello ${stringArgument(args, \"name\", \"world\")}`,\n },\n ...(includeMutation\n ? {\n Mutation: {\n setGreeting: (_source: unknown, args: Readonly<Record<string, unknown>>) =>\n stringArgument(args, \"message\", \"\"),\n },\n }\n : {}),\n },\n });\n};\n\n// A small GitLab-shaped schema that reproduces the two failure modes from issue\n// #1146 when the plugin auto-generates selection sets against it:\n// 1. `metadata.featureFlags(names: [String!]!)` has a REQUIRED nested argument\n// the generator cannot fill.\n// 2. `currentUser` nests connections deep enough that composite leaf fields\n// (`author`, `assignees`) sit past the recursion depth cap, so a naive\n// generator emits them with no sub-selection.\n// graphql-yoga validates with graphql-js, exactly like the @emulators/gitlab\n// surface, so a generated operation that validates clean here is valid GraphQL.\nexport const makeGitlab1146Schema = (): GraphQLSchema =>\n createSchema<GraphqlTestContext>({\n typeDefs: /* GraphQL */ `\n type Query {\n metadata: Metadata\n currentUser: User\n }\n\n type Metadata {\n version: String\n revision: String\n enterprise: Boolean\n featureFlags(names: [String!]!): [FeatureFlag!]!\n kas: Kas\n }\n\n type FeatureFlag {\n name: String\n enabled: Boolean\n }\n\n type Kas {\n enabled: Boolean\n externalUrl: String\n }\n\n type User {\n active: Boolean\n admin: Boolean\n mergeRequests: MergeRequestConnection\n }\n\n type MergeRequestConnection {\n count: Int\n nodes: [MergeRequest!]\n pageInfo: PageInfo\n }\n\n type PageInfo {\n hasNextPage: Boolean\n endCursor: String\n }\n\n type MergeRequest {\n id: ID\n title: String\n author: Author\n assignees: AssigneeConnection\n }\n\n type Author {\n name: String\n username: String\n }\n\n type AssigneeConnection {\n count: Int\n nodes: [Author!]\n }\n `,\n });\n\nexport const TestLayers = {\n greeting: () => GraphqlTestServer.layer({ schema: makeGreetingGraphqlSchema() }),\n greetingWithOAuth: () =>\n GraphqlTestServer.layerWithOAuth({ schema: makeGreetingGraphqlSchema() }),\n};\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@executor-js/plugin-graphql",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.24",
|
|
4
4
|
"homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/plugins/graphql",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/RhysSullivan/executor/issues"
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@effect/platform-node": "4.0.0-beta.59",
|
|
56
|
-
"@executor-js/config": "1.5.
|
|
57
|
-
"@executor-js/sdk": "1.5.
|
|
56
|
+
"@executor-js/config": "1.5.24",
|
|
57
|
+
"@executor-js/sdk": "1.5.24",
|
|
58
58
|
"graphql": "^16.12.0",
|
|
59
59
|
"graphql-yoga": "^5.17.0"
|
|
60
60
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/AddGraphqlSource.tsx","../src/react/GraphqlSourceFields.tsx"],"sourcesContent":["import { useCallback, useMemo, useState } from \"react\";\nimport { useAtomSet } from \"@effect/atom-react\";\nimport * as Exit from \"effect/Exit\";\n\nimport { integrationWriteKeys } from \"@executor-js/react/api/reactivity-keys\";\nimport {\n integrationDisplayNameFromUrl,\n slugifyNamespace,\n useIntegrationIdentity,\n} from \"@executor-js/react/plugins/integration-identity\";\nimport { Button } from \"@executor-js/react/components/button\";\nimport {\n AuthMethodListEditor,\n useAuthMethodList,\n type AuthMethodRow,\n type AuthMethodSeed,\n} from \"@executor-js/react/components/auth-method-list-editor\";\nimport { FloatActions } from \"@executor-js/react/components/float-actions\";\nimport { Spinner } from \"@executor-js/react/components/spinner\";\nimport {\n addIntegrationErrorMessage,\n FormErrorAlert,\n SlugCollisionAlert,\n useSlugAlreadyExists,\n} from \"@executor-js/react/lib/integration-add\";\n\nimport { addGraphqlIntegrationOptimistic } from \"./atoms\";\nimport { GraphqlSourceFields } from \"./GraphqlSourceFields\";\nimport { graphqlAuthMethodInputsFromPlacements } from \"./auth-method-config\";\nimport type { GraphqlAuthMethodInput } from \"../sdk/types\";\n\n// v2 GraphQL add flow: register the integration with its declared auth-method\n// LIST (the shared `AuthMethodListEditor` — GraphQL stays header/query apiKey;\n// OAuth is hidden), then route to the integration's detail hub. Connection\n// creation is no longer part of the add flow — accounts are added from the hub\n// (P6: add without auth, connect later).\n\n// GraphQL has no add-time detection, so the list starts empty (module constant\n// — a fresh [] every render would re-seed the list each render).\nconst NO_SEEDS: readonly AuthMethodSeed[] = [];\n\nexport default function AddGraphqlSource(props: {\n onComplete: (slug?: string) => void;\n onCancel: () => void;\n initialUrl?: string;\n}) {\n const [endpoint, setEndpoint] = useState(props.initialUrl ?? \"\");\n const [description, setDescription] = useState(\"\");\n const identity = useIntegrationIdentity({\n fallbackName: integrationDisplayNameFromUrl(endpoint, \"GraphQL\") ?? \"\",\n });\n const authMethodList = useAuthMethodList(NO_SEEDS);\n const [adding, setAdding] = useState(false);\n const [addError, setAddError] = useState<string | null>(null);\n\n const doAddIntegration = useAtomSet(addGraphqlIntegrationOptimistic, {\n mode: \"promiseExit\",\n });\n\n // The methods to register: each apikey row declares ONE method carrying\n // every named placement (header + query mix in a single method). Inputs\n // omit slugs — the backend assigns carrier-derived ones. `none` rows\n // register nothing.\n const authenticationTemplate = useMemo<readonly GraphqlAuthMethodInput[]>(\n () =>\n authMethodList.rows.flatMap((row: AuthMethodRow) =>\n row.value.kind === \"apikey\"\n ? graphqlAuthMethodInputsFromPlacements(row.value.placements)\n : [],\n ),\n [authMethodList.rows],\n );\n\n // Every apikey row needs at least one named placement; `none` rows are\n // always valid.\n const apiKeyComplete = authMethodList.rows.every(\n (row: AuthMethodRow) =>\n row.value.kind !== \"apikey\" ||\n row.value.placements.some((placement) => placement.name.trim().length > 0),\n );\n\n const resolvedSlug = useMemo(\n () =>\n slugifyNamespace(identity.namespace) ||\n slugifyNamespace(integrationDisplayNameFromUrl(endpoint.trim(), \"GraphQL\") ?? \"\") ||\n \"graphql\",\n [endpoint, identity.namespace],\n );\n\n // Pre-empt the API's `IntegrationAlreadyExistsError`: adding an integration\n // whose slug already exists clobbers the existing one's connections/policies,\n // so the API blocks it. Surface that here from the tenant-scoped catalog list.\n const slugAlreadyExists = useSlugAlreadyExists(resolvedSlug);\n\n const canAdd = endpoint.trim().length > 0 && apiKeyComplete && !adding && !slugAlreadyExists;\n\n const sourceIdentity = useCallback(() => {\n const trimmedEndpoint = endpoint.trim();\n const slug = resolvedSlug;\n const displayName =\n identity.name.trim() || integrationDisplayNameFromUrl(trimmedEndpoint, \"GraphQL\") || slug;\n return { trimmedEndpoint, slug, displayName };\n }, [endpoint, identity.name, resolvedSlug]);\n\n const handleAdd = async (): Promise<void> => {\n setAdding(true);\n setAddError(null);\n const { trimmedEndpoint, slug, displayName } = sourceIdentity();\n\n const integrationExit = await doAddIntegration({\n payload: {\n endpoint: trimmedEndpoint,\n slug,\n name: displayName,\n ...(description.trim().length > 0 ? { description: description.trim() } : {}),\n ...(authenticationTemplate.length > 0\n ? { authenticationTemplate: [...authenticationTemplate] }\n : {}),\n },\n reactivityKeys: integrationWriteKeys,\n });\n if (Exit.isFailure(integrationExit)) {\n setAddError(addIntegrationErrorMessage(integrationExit, slug, \"Failed to add source\"));\n setAdding(false);\n return;\n }\n const registeredSlug = integrationExit.value.slug;\n\n props.onComplete(String(registeredSlug));\n };\n\n return (\n <div className=\"flex flex-1 flex-col gap-6\">\n <h1 className=\"text-xl font-semibold text-foreground\">Add GraphQL Source</h1>\n\n <GraphqlSourceFields\n endpoint={endpoint}\n onEndpointChange={setEndpoint}\n identity={identity}\n description={description}\n onDescriptionChange={setDescription}\n />\n\n <AuthMethodListEditor\n list={authMethodList}\n allowedKinds={[\"none\", \"apikey\"]}\n emptyHint=\"No authentication declared. Add a method, or add the source without auth and connect an account from the integration page later.\"\n footerHint=\"Every method here is registered with the source. Connect an account from the integration page after adding.\"\n />\n\n {slugAlreadyExists && !adding && <SlugCollisionAlert slug={resolvedSlug} />}\n\n {addError && <FormErrorAlert message={addError} />}\n\n <FloatActions>\n <Button variant=\"ghost\" onClick={() => props.onCancel()} disabled={adding}>\n Cancel\n </Button>\n <Button onClick={() => void handleAdd()} disabled={!canAdd}>\n {adding && <Spinner className=\"size-3.5\" />}\n {adding ? \"Adding...\" : \"Add source\"}\n </Button>\n </FloatActions>\n </div>\n );\n}\n","import {\n CardStack,\n CardStackContent,\n CardStackEntryField,\n} from \"@executor-js/react/components/card-stack\";\nimport { Input } from \"@executor-js/react/components/input\";\nimport { Textarea } from \"@executor-js/react/components/textarea\";\nimport {\n IntegrationIdentityFieldRows,\n type IntegrationIdentity,\n} from \"@executor-js/react/plugins/integration-identity\";\n\nexport function GraphqlSourceFields(props: {\n readonly endpoint: string;\n readonly onEndpointChange: (endpoint: string) => void;\n readonly identity: IntegrationIdentity;\n /** The integration's agent-visible description. Blank = the backend falls\n * back to the introspected schema's own description, then the name. */\n readonly description?: string;\n readonly onDescriptionChange?: (value: string) => void;\n readonly endpointDisabled?: boolean;\n readonly namespaceReadOnly?: boolean;\n}) {\n return (\n <CardStack>\n <CardStackContent className=\"border-t-0\">\n <CardStackEntryField\n label=\"Endpoint\"\n hint=\"The endpoint will be introspected to discover available queries and mutations.\"\n >\n <Input\n value={props.endpoint}\n onChange={(e) => props.onEndpointChange((e.target as HTMLInputElement).value)}\n placeholder=\"https://api.example.com/graphql\"\n className=\"font-mono text-sm\"\n disabled={props.endpointDisabled}\n />\n </CardStackEntryField>\n <IntegrationIdentityFieldRows\n identity={props.identity}\n namePlaceholder=\"e.g. Shopify API\"\n namespaceReadOnly={props.namespaceReadOnly}\n />\n {props.onDescriptionChange && (\n <CardStackEntryField label=\"Description\">\n <Textarea\n value={props.description ?? \"\"}\n onChange={(e) => props.onDescriptionChange?.((e.target as HTMLTextAreaElement).value)}\n placeholder=\"What this API is and when to reach for it\"\n rows={2}\n maxRows={6}\n className=\"text-sm\"\n />\n <p className=\"text-[11px] text-muted-foreground\">\n Agent-visible. Leave blank to use the schema's own description when it has one.\n </p>\n </CardStackEntryField>\n )}\n </CardStackContent>\n </CardStack>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sdk/errors.ts","../src/sdk/types.ts"],"sourcesContent":["import { Data, Schema } from \"effect\";\nimport type { Option } from \"effect\";\nimport type { AuthToolFailureCode } from \"@executor-js/sdk/core\";\n\nexport class GraphqlIntrospectionError extends Schema.TaggedErrorClass<GraphqlIntrospectionError>()(\n \"GraphqlIntrospectionError\",\n {\n message: Schema.String,\n },\n) {}\n\nexport class GraphqlExtractionError extends Schema.TaggedErrorClass<GraphqlExtractionError>()(\n \"GraphqlExtractionError\",\n {\n message: Schema.String,\n },\n) {}\n\nexport class GraphqlInvocationError extends Data.TaggedError(\"GraphqlInvocationError\")<{\n readonly message: string;\n readonly statusCode: Option.Option<number>;\n readonly cause?: unknown;\n}> {}\n\n/** A tool invocation could not produce a usable credential. Re-keyed for v2:\n * references the connection by (owner, integration, name) instead of a v1\n * source id + scope. */\nexport class GraphqlAuthRequiredError extends Data.TaggedError(\"GraphqlAuthRequiredError\")<{\n readonly code: AuthToolFailureCode;\n readonly message: string;\n readonly owner: string;\n readonly integration: string;\n readonly connection: string;\n readonly credentialKind: \"secret\" | \"oauth\" | \"upstream\";\n readonly credentialLabel?: string;\n readonly template?: string;\n readonly status?: number;\n readonly details?: unknown;\n readonly cause?: unknown;\n}> {}\n","import { Schema } from \"effect\";\nimport {\n ApiKeyAuthTemplate,\n apiKeyMethodFromAuthTemplate,\n isApiKeyAuthTemplate,\n ApiKeyAuthMethod,\n NoneAuthMethod,\n normalizeAuthMethodSlugs,\n} from \"@executor-js/sdk/http-auth\";\n\n// ---------------------------------------------------------------------------\n// GraphQL operation kind\n// ---------------------------------------------------------------------------\n\nexport const GraphqlOperationKind = Schema.Literals([\"query\", \"mutation\"]);\nexport type GraphqlOperationKind = typeof GraphqlOperationKind.Type;\n\n// ---------------------------------------------------------------------------\n// Extracted field (becomes a tool)\n// ---------------------------------------------------------------------------\n\nexport const GraphqlArgument = Schema.Struct({\n name: Schema.String,\n typeName: Schema.String,\n required: Schema.Boolean,\n description: Schema.OptionFromOptional(Schema.String),\n});\nexport type GraphqlArgument = typeof GraphqlArgument.Type;\n\nexport const ExtractedField = Schema.Struct({\n /** e.g. \"user\", \"createUser\" */\n fieldName: Schema.String,\n /** \"query\" or \"mutation\" */\n kind: GraphqlOperationKind,\n description: Schema.OptionFromOptional(Schema.String),\n arguments: Schema.Array(GraphqlArgument),\n /** JSON Schema for the input (built from arguments) */\n inputSchema: Schema.OptionFromOptional(Schema.Unknown),\n /** The return type name for documentation */\n returnTypeName: Schema.String,\n});\nexport type ExtractedField = typeof ExtractedField.Type;\n\nexport const ExtractionResult = Schema.Struct({\n /** Schema name from introspection */\n schemaName: Schema.OptionFromOptional(Schema.String),\n fields: Schema.Array(ExtractedField),\n});\nexport type ExtractionResult = typeof ExtractionResult.Type;\n\n// ---------------------------------------------------------------------------\n// Operation binding — minimal data needed to invoke\n// ---------------------------------------------------------------------------\n\nexport const OperationBinding = Schema.Struct({\n kind: GraphqlOperationKind,\n fieldName: Schema.String,\n /** The full GraphQL query/mutation string */\n operationString: Schema.String,\n /** Ordered variable names for mapping */\n variableNames: Schema.Array(Schema.String),\n});\nexport type OperationBinding = typeof OperationBinding.Type;\n\n// ---------------------------------------------------------------------------\n// Auth methods — the shared placements vocabulary (`@executor-js/sdk/http-auth`)\n// plus GraphQL's own oauth variant. The integration's\n// `config.authenticationTemplate` declares zero or more methods, each with a\n// stable `slug` a connection binds against (`connection.template`). There are\n// no secret slots and no credential bindings — a connection IS the credential,\n// and the plugin renders its resolved values onto the request through the\n// bound method (D11).\n//\n// none — no credential (open endpoint)\n// apikey — render the connection's values through the method's header/query\n// placements (one credential input per distinct placement\n// `variable`; a method may mix carriers — e.g. a bearer header\n// plus a team-id query param)\n// oauth2 — the value is an OAuth access token, applied as a bearer header\n// (optionally overriding the header name / prefix). GraphQL oauth\n// stores no endpoints — only how the token is rendered.\n// ---------------------------------------------------------------------------\n\n/** An OAuth bearer method: write `<header>: <prefix><access-token>`. The\n * resolved (and refreshed) access token is the connection's `token` value. */\nexport const GraphqlOAuthMethod = Schema.Struct({\n kind: Schema.Literal(\"oauth2\"),\n slug: Schema.String,\n /** The header to write the bearer token to. Defaults to `Authorization`. */\n header: Schema.optional(Schema.String),\n /** The token prefix. Defaults to `Bearer `. */\n prefix: Schema.optional(Schema.String),\n});\nexport type GraphqlOAuthMethod = typeof GraphqlOAuthMethod.Type;\n\nexport const GraphqlAuthMethod = Schema.Union([\n NoneAuthMethod,\n ApiKeyAuthMethod,\n GraphqlOAuthMethod,\n]);\nexport type GraphqlAuthMethod = typeof GraphqlAuthMethod.Type;\n\n/** Input variant of `GraphqlAuthMethod` — callers (UI, agents) may omit the\n * slug; `normalizeGraphqlAuthMethods` backfills it. */\nexport const GraphqlAuthMethodInput = Schema.Union([\n Schema.Struct({ slug: Schema.optional(Schema.String), kind: Schema.Literal(\"none\") }),\n Schema.Struct({\n slug: Schema.optional(Schema.String),\n kind: Schema.Literal(\"oauth2\"),\n header: Schema.optional(Schema.String),\n prefix: Schema.optional(Schema.String),\n }),\n // Credential methods are authored request-shaped — the ONE apikey input\n // dialect: `{ type: \"apiKey\", headers: { Authorization: [\"Bearer \",\n // variable(\"token\")] }, queryParams: { … } }`. Stored configs and the\n // catalog read as canonical placements; `apiKeyAuthTemplateFromMethod`\n // serializes them back for read-modify-write flows.\n ApiKeyAuthTemplate,\n]);\nexport type GraphqlAuthMethodInput = typeof GraphqlAuthMethodInput.Type;\n\n/** The expansion target: input arms with the dialect resolved to canonical\n * placements (slug still optional — backfill is a separate pass). */\nexport type GraphqlCanonicalAuthMethodInput =\n | Exclude<GraphqlAuthMethodInput, ApiKeyAuthTemplate>\n | (Omit<ApiKeyAuthMethod, \"slug\"> & { readonly slug?: string });\n\n/** The default slug for a slug-less input method. Carrier-derived for the\n * single-placement apikey cases (`header` / `query`) so the UI, agent, and\n * migration paths all converge on the same names. */\nconst defaultGraphqlAuthSlug = (method: GraphqlCanonicalAuthMethodInput): string => {\n if (method.kind !== \"apikey\") return method.kind;\n if (method.placements.length === 1) {\n return method.placements[0]!.carrier === \"header\" ? \"header\" : \"query\";\n }\n return \"apikey\";\n};\n\n/** Expand request-shaped dialect entries into canonical placements; canonical\n * entries pass through. Slug backfill is the caller's concern\n * (`normalizeGraphqlAuthMethods` for declare flows, `mergeAuthTemplates` for\n * the custom-method merge). */\nexport const expandGraphqlAuthMethodInputs = (\n methods: readonly GraphqlAuthMethodInput[],\n): readonly GraphqlCanonicalAuthMethodInput[] =>\n methods.map(\n (method): GraphqlCanonicalAuthMethodInput =>\n isApiKeyAuthTemplate(method)\n ? (apiKeyMethodFromAuthTemplate(method) as GraphqlCanonicalAuthMethodInput)\n : (method as GraphqlCanonicalAuthMethodInput),\n );\n\n/** Assign each method a stable slug: a caller-provided one wins, otherwise a\n * kind/carrier-derived default, suffixed `_2`, `_3`, … on collision. The\n * request-shaped dialect is expanded to canonical placements first. */\nexport const normalizeGraphqlAuthMethods = (\n methods: readonly GraphqlAuthMethodInput[],\n): readonly GraphqlAuthMethod[] =>\n normalizeAuthMethodSlugs(\n expandGraphqlAuthMethodInputs(methods),\n defaultGraphqlAuthSlug,\n ) as readonly GraphqlAuthMethod[];\n\n// ---------------------------------------------------------------------------\n// Integration config — the opaque-to-core blob the graphql plugin stores on the\n// integration row. Holds everything `resolveTools` (introspection) and\n// `invokeTool` (request building + auth rendering) need.\n// ---------------------------------------------------------------------------\n\nexport const GraphqlIntegrationConfig = Schema.Struct({\n /** The GraphQL endpoint URL. */\n endpoint: Schema.String,\n /** Display name for the integration. */\n name: Schema.String,\n /** Hex SHA-256 of the introspection JSON snapshot — the content address of\n * the blob (`introspection/<hash>` in the plugin blob store). Rows that\n * predate the blob store (inline `introspectionJson` text) are rewritten\n * by the introspection-to-blob migrations before this schema sees them. */\n introspectionHash: Schema.optional(Schema.String),\n /** Static headers applied to every request (and to add-time introspection). */\n headers: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n /** Static query parameters applied to every request. */\n queryParams: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n /** Declared auth methods — how a connection's values are rendered onto\n * requests. A connection's `template` picks one by slug. */\n authenticationTemplate: Schema.Array(GraphqlAuthMethod),\n});\nexport type GraphqlIntegrationConfig = typeof GraphqlIntegrationConfig.Type;\n\n// Decodes ONLY the canonical shape. Pre-canonical stored shapes are rewritten\n// by the one-off config migration (`migrate-config.ts`), not decoded here —\n// runtime code knows only the canonical model.\nexport const decodeGraphqlIntegrationConfig = Schema.decodeUnknownEffect(GraphqlIntegrationConfig);\nexport const decodeGraphqlIntegrationConfigOption =\n Schema.decodeUnknownOption(GraphqlIntegrationConfig);\n\n// ---------------------------------------------------------------------------\n// Invocation\n// ---------------------------------------------------------------------------\n\nexport const InvocationResult = Schema.Struct({\n status: Schema.Number,\n data: Schema.NullOr(Schema.Unknown),\n errors: Schema.NullOr(Schema.Unknown),\n});\nexport type InvocationResult = typeof InvocationResult.Type;\n"],"mappings":"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","names":["Schema"]}
|