@executor-js/plugin-graphql 1.5.5 → 1.5.7

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.
Files changed (38) hide show
  1. package/dist/{AddGraphqlSource-P3D3UXRJ.js → AddGraphqlSource-FGT7DNXV.js} +39 -64
  2. package/dist/AddGraphqlSource-FGT7DNXV.js.map +1 -0
  3. package/dist/{EditGraphqlSource-FVF67CTP.js → EditGraphqlSource-QELISUYT.js} +4 -4
  4. package/dist/GraphqlAccountsPanel-U62WSGHR.js +9 -0
  5. package/dist/api/group.d.ts +54 -21
  6. package/dist/api/handlers.d.ts +1 -1
  7. package/dist/api/index.d.ts +55 -22
  8. package/dist/{chunk-N5GJE7R6.js → chunk-732HGFSH.js} +57 -21
  9. package/dist/chunk-732HGFSH.js.map +1 -0
  10. package/dist/{chunk-2Y3J3CVO.js → chunk-HN5FB4DO.js} +35 -55
  11. package/dist/chunk-HN5FB4DO.js.map +1 -0
  12. package/dist/{chunk-VCYDSSIK.js → chunk-OGNJZCEF.js} +27 -28
  13. package/dist/chunk-OGNJZCEF.js.map +1 -0
  14. package/dist/{chunk-ADQTI2OK.js → chunk-OUZI3QNC.js} +119 -124
  15. package/dist/chunk-OUZI3QNC.js.map +1 -0
  16. package/dist/client.js +3 -3
  17. package/dist/core.js +124 -10
  18. package/dist/core.js.map +1 -1
  19. package/dist/index.js +2 -2
  20. package/dist/react/atoms.d.ts +83 -29
  21. package/dist/react/auth-method-config.d.ts +21 -8
  22. package/dist/react/client.d.ts +54 -21
  23. package/dist/react/defaults.d.ts +0 -11
  24. package/dist/sdk/index.d.ts +4 -1
  25. package/dist/sdk/introspection-blob-migration.d.ts +7 -0
  26. package/dist/sdk/migrate-config.d.ts +6 -0
  27. package/dist/sdk/plugin.d.ts +49 -22
  28. package/dist/sdk/store.d.ts +11 -1
  29. package/dist/sdk/types.d.ts +102 -47
  30. package/package.json +3 -3
  31. package/dist/AddGraphqlSource-P3D3UXRJ.js.map +0 -1
  32. package/dist/GraphqlAccountsPanel-GBNFHLFH.js +0 -9
  33. package/dist/chunk-2Y3J3CVO.js.map +0 -1
  34. package/dist/chunk-ADQTI2OK.js.map +0 -1
  35. package/dist/chunk-N5GJE7R6.js.map +0 -1
  36. package/dist/chunk-VCYDSSIK.js.map +0 -1
  37. /package/dist/{EditGraphqlSource-FVF67CTP.js.map → EditGraphqlSource-QELISUYT.js.map} +0 -0
  38. /package/dist/{GraphqlAccountsPanel-GBNFHLFH.js.map → GraphqlAccountsPanel-U62WSGHR.js.map} +0 -0
@@ -0,0 +1 @@
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"]}
@@ -1,8 +1,9 @@
1
1
  import {
2
- AuthTemplate,
2
+ GraphqlAuthMethod,
3
+ GraphqlAuthMethodInput,
3
4
  GraphqlExtractionError,
4
5
  GraphqlIntrospectionError
5
- } from "./chunk-N5GJE7R6.js";
6
+ } from "./chunk-732HGFSH.js";
6
7
 
7
8
  // src/react/atoms.ts
8
9
  import * as Atom from "effect/unstable/reactivity/Atom";
@@ -31,10 +32,10 @@ var AddIntegrationPayload = Schema.Struct({
31
32
  introspectionJson: Schema.optional(Schema.String),
32
33
  headers: Schema.optional(Schema.Record(Schema.String, Schema.String)),
33
34
  queryParams: Schema.optional(Schema.Record(Schema.String, Schema.String)),
34
- authenticationTemplate: Schema.optional(Schema.Array(AuthTemplate))
35
+ authenticationTemplate: Schema.optional(Schema.Array(GraphqlAuthMethodInput))
35
36
  });
36
37
  var ConfigurePayload = Schema.Struct({
37
- authenticationTemplate: Schema.Array(AuthTemplate),
38
+ authenticationTemplate: Schema.Array(GraphqlAuthMethodInput),
38
39
  mode: Schema.optional(Schema.Literals(["merge", "replace"]))
39
40
  });
40
41
  var AddIntegrationResponse = Schema.Struct({
@@ -44,13 +45,12 @@ var AddIntegrationResponse = Schema.Struct({
44
45
  var GraphqlConfigView = Schema.Struct({
45
46
  endpoint: Schema.String,
46
47
  name: Schema.String,
47
- introspectionJson: Schema.optional(Schema.String),
48
48
  headers: Schema.optional(Schema.Record(Schema.String, Schema.String)),
49
49
  queryParams: Schema.optional(Schema.Record(Schema.String, Schema.String)),
50
- authenticationTemplate: Schema.Array(AuthTemplate)
50
+ authenticationTemplate: Schema.Array(GraphqlAuthMethod)
51
51
  });
52
52
  var ConfigureResponse = Schema.Struct({
53
- authenticationTemplate: Schema.Array(AuthTemplate)
53
+ authenticationTemplate: Schema.Array(GraphqlAuthMethod)
54
54
  });
55
55
  var IntrospectionError = GraphqlIntrospectionError.annotate({
56
56
  httpApiStatus: 400
@@ -130,55 +130,34 @@ var addGraphqlIntegrationOptimistic = integrationsOptimisticAtom.pipe(
130
130
 
131
131
  // src/react/auth-method-config.ts
132
132
  import { AuthTemplateSlug } from "@executor-js/sdk/shared";
133
-
134
- // src/react/defaults.ts
135
- import { connectionIdentifier } from "@executor-js/react/lib/connection-name";
136
- var GRAPHQL_APIKEY_TEMPLATE = "apiKey";
137
-
138
- // src/react/auth-method-config.ts
139
- var labelForApiKey = (slug, name) => `API key (${name || slug})`;
140
- function authMethodsFromConfig(templates) {
141
- return templates.map((template) => {
142
- const slug = String(template.slug);
143
- const source = slug.startsWith("custom_") ? "custom" : "spec";
144
- if (template.kind === "oauth2") {
145
- return {
146
- id: slug,
147
- label: "OAuth2",
148
- kind: "oauth",
149
- source,
150
- template: AuthTemplateSlug.make(slug),
151
- placements: [],
152
- oauth: {}
153
- };
154
- }
155
- const placement = {
156
- carrier: template.in,
157
- name: template.name,
158
- prefix: template.prefix ?? ""
159
- };
160
- return {
161
- id: slug,
162
- label: labelForApiKey(slug, template.name),
163
- kind: "apikey",
164
- source,
165
- template: AuthTemplateSlug.make(slug),
166
- placements: [placement]
167
- };
133
+ import {
134
+ wireAuthInputFromShared,
135
+ authMethodFromSharedTemplate,
136
+ editorValueFromSharedMethod,
137
+ sharedMethodInputFromEditorValue,
138
+ wirePlacementsFromEditor
139
+ } from "@executor-js/react/lib/shared-auth-method-codec";
140
+ var oauthAuthMethod = (slug) => ({
141
+ id: slug,
142
+ label: "OAuth",
143
+ kind: "oauth",
144
+ source: slug.startsWith("custom_") ? "custom" : "spec",
145
+ template: AuthTemplateSlug.make(slug),
146
+ placements: [],
147
+ oauth: {}
148
+ });
149
+ function authMethodsFromConfig(methods) {
150
+ return methods.map((method) => {
151
+ if (method.kind === "oauth2") return oauthAuthMethod(method.slug);
152
+ return authMethodFromSharedTemplate(method);
168
153
  });
169
154
  }
170
- function graphqlTemplatesFromPlacements(placements, slug) {
171
- const named = placements.filter((placement) => placement.name.trim().length > 0);
172
- return named.map(
173
- (placement, index) => ({
174
- kind: "apiKey",
175
- slug: index === 0 ? slug ?? GRAPHQL_APIKEY_TEMPLATE : "",
176
- in: placement.carrier,
177
- name: placement.name,
178
- ...placement.prefix ? { prefix: placement.prefix } : {}
179
- })
180
- );
155
+ function graphqlAuthMethodInputsFromPlacements(placements) {
156
+ const wire = wirePlacementsFromEditor(placements);
157
+ if (wire.length === 0) return [];
158
+ return [graphqlWireAuthInput({ kind: "apikey", placements: wire })];
181
159
  }
160
+ var graphqlWireAuthInput = (method) => wireAuthInputFromShared(method);
182
161
 
183
162
  export {
184
163
  graphqlIntegrationConfigAtom,
@@ -186,6 +165,7 @@ export {
186
165
  graphqlConfigure,
187
166
  addGraphqlIntegrationOptimistic,
188
167
  authMethodsFromConfig,
189
- graphqlTemplatesFromPlacements
168
+ graphqlAuthMethodInputsFromPlacements,
169
+ graphqlWireAuthInput
190
170
  };
191
- //# sourceMappingURL=chunk-2Y3J3CVO.js.map
171
+ //# sourceMappingURL=chunk-HN5FB4DO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/atoms.ts","../src/react/client.ts","../src/api/group.ts","../src/react/auth-method-config.ts"],"sourcesContent":["import type { IntegrationSlug } from \"@executor-js/sdk/shared\";\nimport * as Atom from \"effect/unstable/reactivity/Atom\";\nimport * as AsyncResult from \"effect/unstable/reactivity/AsyncResult\";\nimport { integrationsOptimisticAtom } from \"@executor-js/react/api/atoms\";\nimport { ReactivityKey } from \"@executor-js/react/api/reactivity-keys\";\nimport { GraphqlClient } from \"./client\";\n\n// ---------------------------------------------------------------------------\n// Query atoms — v2 is integration-centric. The graphql HTTP surface exposes\n// only the catalog integration (`getIntegration` → its stored config, which\n// carries the `authenticationTemplate[]`). Connections are created through the\n// core API (`createConnection` / `oauth.start`), not through this plugin's\n// surface.\n// ---------------------------------------------------------------------------\n\nexport const graphqlIntegrationConfigAtom = (slug: IntegrationSlug) =>\n GraphqlClient.query(\"graphql\", \"getIntegration\", {\n params: { slug: String(slug) },\n timeToLive: \"15 seconds\",\n reactivityKeys: [ReactivityKey.integrations, ReactivityKey.tools],\n });\n\n// The full opaque config (including `authenticationTemplate`), used by the\n// configure UX to render existing auth methods and add custom ones.\nexport const graphqlConfigAtom = (slug: IntegrationSlug) =>\n GraphqlClient.query(\"graphql\", \"getConfig\", {\n params: { slug: String(slug) },\n timeToLive: \"15 seconds\",\n reactivityKeys: [ReactivityKey.integrations, ReactivityKey.tools],\n });\n\n// ---------------------------------------------------------------------------\n// Mutation atoms\n// ---------------------------------------------------------------------------\n\nexport const addGraphqlIntegration = GraphqlClient.mutation(\"graphql\", \"addIntegration\");\n\n// Merge-append custom auth methods onto an integration's `authenticationTemplate`.\nexport const graphqlConfigure = GraphqlClient.mutation(\"graphql\", \"configure\");\n\n// Optimistically slot a pending row into the shared integration catalog so the\n// integrations list reflects the new GraphQL integration before the server\n// round-trips. The reducer mirrors the catalog `Integration` shape.\nexport const addGraphqlIntegrationOptimistic = integrationsOptimisticAtom.pipe(\n Atom.optimisticFn({\n reducer: (\n current,\n arg: {\n readonly payload: {\n readonly endpoint: string;\n readonly slug?: string;\n readonly name?: string;\n };\n },\n ) =>\n AsyncResult.map(current, (rows) => {\n const slug = (arg.payload.slug ??\n `pending-${Math.random().toString(36).slice(2)}`) as IntegrationSlug;\n const integration = {\n slug,\n kind: \"graphql\",\n description: arg.payload.name ?? arg.payload.endpoint,\n canRemove: false,\n canRefresh: false,\n authMethods: [],\n };\n return [integration, ...rows.filter((row) => row.slug !== slug)].sort((a, b) =>\n a.description.localeCompare(b.description),\n );\n }),\n fn: addGraphqlIntegration,\n }),\n);\n","import { createPluginAtomClient } from \"@executor-js/sdk/client\";\nimport {\n getExecutorApiBaseUrl,\n getExecutorServerAuthorizationHeader,\n} from \"@executor-js/react/api/server-connection\";\nimport { GraphqlGroup } from \"../api/group\";\n\nexport const GraphqlClient = createPluginAtomClient(GraphqlGroup, {\n baseUrl: getExecutorApiBaseUrl,\n authorizationHeader: getExecutorServerAuthorizationHeader,\n});\n","import { HttpApiEndpoint, HttpApiGroup } from \"effect/unstable/httpapi\";\nimport { Schema } from \"effect\";\nimport { InternalError, IntegrationAlreadyExistsError } from \"@executor-js/sdk/shared\";\n\nimport { GraphqlIntrospectionError, GraphqlExtractionError } from \"../sdk/errors\";\nimport { GraphqlAuthMethod, GraphqlAuthMethodInput } from \"../sdk/types\";\n\n// ---------------------------------------------------------------------------\n// Params\n// ---------------------------------------------------------------------------\n\nconst IntegrationParams = {\n slug: Schema.String,\n};\n\n// ---------------------------------------------------------------------------\n// Payloads\n// ---------------------------------------------------------------------------\n\nconst AddIntegrationPayload = Schema.Struct({\n endpoint: Schema.String,\n slug: Schema.optional(Schema.String),\n name: Schema.optional(Schema.String),\n introspectionJson: Schema.optional(Schema.String),\n headers: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n queryParams: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n authenticationTemplate: Schema.optional(Schema.Array(GraphqlAuthMethodInput)),\n});\n\n// The `configure` payload — the custom auth methods to merge-append onto the\n// integration's `authenticationTemplate`. Reuses the same input schema as\n// `addIntegration` (slug optional — the backend backfills it) so a custom\n// apikey method round-trips identically.\nconst ConfigurePayload = Schema.Struct({\n authenticationTemplate: Schema.Array(GraphqlAuthMethodInput),\n mode: Schema.optional(Schema.Literals([\"merge\", \"replace\"])),\n});\n\n// ---------------------------------------------------------------------------\n// Responses\n// ---------------------------------------------------------------------------\n\nconst AddIntegrationResponse = Schema.Struct({\n slug: Schema.String,\n name: Schema.String,\n});\n\n// The integration config surfaced for the configure UX. Carries the\n// `authenticationTemplate` the configure / custom-method flow reads/writes.\n// The introspection snapshot is deliberately NOT served: it's a multi-MB\n// build artifact in the plugin blob store, and no client reads it.\nconst GraphqlConfigView = Schema.Struct({\n endpoint: Schema.String,\n name: Schema.String,\n headers: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n queryParams: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n authenticationTemplate: Schema.Array(GraphqlAuthMethod),\n});\n\n// The configure result — the merged `authenticationTemplate` after the new\n// custom methods were appended/replaced.\nconst ConfigureResponse = Schema.Struct({\n authenticationTemplate: Schema.Array(GraphqlAuthMethod),\n});\n\n// ---------------------------------------------------------------------------\n// Errors with HTTP status\n// ---------------------------------------------------------------------------\n\nconst IntrospectionError = GraphqlIntrospectionError.annotate({\n httpApiStatus: 400,\n});\nconst ExtractionError = GraphqlExtractionError.annotate({ httpApiStatus: 400 });\n\n// ---------------------------------------------------------------------------\n// Group — the GraphQL HTTP surface over integrations.\n//\n// Plugin SDK errors (GraphqlIntrospectionError etc.) are declared once at the\n// group level via `.addError(...)`. `InternalError` is the shared opaque-by-\n// schema 500 surface translated from `StorageError` by `withCapture` at the\n// HTTP edge.\n// ---------------------------------------------------------------------------\n\nconst GraphqlErrors = [\n InternalError,\n IntrospectionError,\n ExtractionError,\n IntegrationAlreadyExistsError,\n] as const;\n\nexport const GraphqlGroup = HttpApiGroup.make(\"graphql\")\n .add(\n HttpApiEndpoint.post(\"addIntegration\", \"/graphql/integrations\", {\n payload: AddIntegrationPayload,\n success: AddIntegrationResponse,\n error: GraphqlErrors,\n }),\n )\n .add(\n HttpApiEndpoint.get(\"getIntegration\", \"/graphql/integrations/:slug\", {\n params: IntegrationParams,\n success: Schema.NullOr(Schema.Unknown),\n error: GraphqlErrors,\n }),\n )\n .add(\n HttpApiEndpoint.get(\"getConfig\", \"/graphql/integrations/:slug/config\", {\n params: IntegrationParams,\n success: Schema.NullOr(GraphqlConfigView),\n error: GraphqlErrors,\n }),\n )\n .add(\n HttpApiEndpoint.post(\"configure\", \"/graphql/integrations/:slug/config\", {\n params: IntegrationParams,\n payload: ConfigurePayload,\n success: ConfigureResponse,\n error: GraphqlErrors,\n }),\n );\n","// ---------------------------------------------------------------------------\n// GraphQL ↔ generic auth-method converters — a thin oauth adapter over the\n// shared codec (`@executor-js/react/lib/shared-auth-method-codec`). The\n// apikey/none paths (multi-placement, multi-variable) live in the shared\n// codec; GraphQL only contributes its oauth flavor: endpoint-less methods that\n// render the connection's access token as a bearer header at invoke time\n// (optionally overriding the header name / prefix).\n// ---------------------------------------------------------------------------\n\nimport { AuthTemplateSlug } from \"@executor-js/sdk/shared\";\nimport type { AuthTemplateEditorValue } from \"@executor-js/react/components/auth-template-editor\";\nimport type { AuthMethod, Placement } from \"@executor-js/react/lib/auth-placements\";\nimport {\n wireAuthInputFromShared,\n authMethodFromSharedTemplate,\n editorValueFromSharedMethod,\n sharedMethodInputFromEditorValue,\n wirePlacementsFromEditor,\n} from \"@executor-js/react/lib/shared-auth-method-codec\";\n\nimport type {\n GraphqlAuthMethod,\n GraphqlAuthMethodInput,\n GraphqlCanonicalAuthMethodInput,\n} from \"../sdk/types\";\n\nconst oauthAuthMethod = (slug: string): AuthMethod => ({\n id: slug,\n label: \"OAuth\",\n kind: \"oauth\",\n source: slug.startsWith(\"custom_\") ? \"custom\" : \"spec\",\n template: AuthTemplateSlug.make(slug),\n placements: [],\n oauth: {},\n});\n\n/** Convert a generic editor value into one GraphQL auth-method input (no slug\n * — the backend assigns carrier-derived slugs). An apikey value keeps every\n * named placement (headers and query params mix freely); one with no usable\n * placement falls back to `none`. */\nexport function graphqlAuthMethodInputFromEditorValue(\n value: AuthTemplateEditorValue,\n): GraphqlAuthMethodInput {\n if (value.kind === \"oauth\") return { kind: \"oauth2\" };\n return (sharedMethodInputFromEditorValue(value) ?? { kind: \"none\" }) as GraphqlAuthMethodInput;\n}\n\n/** Convert one stored GraphQL method into the generic editor value. */\nexport function editorValueFromGraphqlAuthMethod(\n method: GraphqlAuthMethod,\n): AuthTemplateEditorValue {\n if (method.kind === \"oauth2\") {\n // GraphQL oauth methods store no endpoints — only the bearer rendering.\n return { kind: \"oauth\", authorizationUrl: \"\", tokenUrl: \"\", scopes: [] };\n }\n return editorValueFromSharedMethod(method);\n}\n\n/** Project the stored methods into the generic `AuthMethod[]` the hub renders.\n * Mirrors the server's `describeGraphqlAuthMethods`; `custom_` slugs mark\n * user-created methods (removable from the hub). */\nexport function authMethodsFromConfig(methods: readonly GraphqlAuthMethod[]): AuthMethod[] {\n return methods.map((method: GraphqlAuthMethod): AuthMethod => {\n if (method.kind === \"oauth2\") return oauthAuthMethod(method.slug);\n return authMethodFromSharedTemplate(method);\n });\n}\n\n/** Build the GraphQL method input for a custom method from generic placements\n * — ONE method carrying every named placement (header + query mix in a single\n * method; each placement renders from its own input variable, or shares one).\n * Empty when no placement is usable. */\nexport function graphqlAuthMethodInputsFromPlacements(\n placements: readonly Placement[],\n): GraphqlAuthMethodInput[] {\n const wire = wirePlacementsFromEditor(placements);\n if (wire.length === 0) return [];\n return [graphqlWireAuthInput({ kind: \"apikey\", placements: wire })];\n}\n\n/** Serialize a canonical method into the wire input union (apikey → the\n * request-shaped dialect; none/oauth2 pass through). */\nexport const graphqlWireAuthInput = (\n method: GraphqlAuthMethod | GraphqlCanonicalAuthMethodInput,\n): GraphqlAuthMethodInput => wireAuthInputFromShared(method) as GraphqlAuthMethodInput;\n"],"mappings":"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","names":[]}
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  authMethodsFromConfig,
3
+ graphqlAuthMethodInputsFromPlacements,
3
4
  graphqlConfigAtom,
4
5
  graphqlConfigure,
5
- graphqlTemplatesFromPlacements
6
- } from "./chunk-2Y3J3CVO.js";
6
+ graphqlWireAuthInput
7
+ } from "./chunk-HN5FB4DO.js";
7
8
 
8
9
  // src/react/GraphqlAccountsPanel.tsx
9
10
  import { useCallback, useMemo } from "react";
@@ -13,6 +14,9 @@ import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
13
14
  import { IntegrationSlug } from "@executor-js/sdk/shared";
14
15
  import { AccountsSection } from "@executor-js/react/components/accounts-section";
15
16
  import { integrationWriteKeys } from "@executor-js/react/api/reactivity-keys";
17
+ import {
18
+ useCustomMethodActions
19
+ } from "@executor-js/react/lib/custom-auth-methods";
16
20
  import { jsx } from "react/jsx-runtime";
17
21
  function GraphqlAccountsPanel(props) {
18
22
  const { sourceId, integrationName, accountHandoff } = props;
@@ -27,39 +31,34 @@ function GraphqlAccountsPanel(props) {
27
31
  () => authMethodsFromConfig(existingTemplate),
28
32
  [existingTemplate]
29
33
  );
30
- const createCustomMethod = useCallback(
34
+ const configure = useCallback(
31
35
  async (input) => {
32
- const templates = graphqlTemplatesFromPlacements(input.placements, "");
33
- if (templates.length === 0) return null;
34
36
  const exit = await doConfigure({
35
37
  params: { slug: String(slug) },
36
- payload: { authenticationTemplate: templates },
38
+ payload: {
39
+ authenticationTemplate: input.authenticationTemplate.map(graphqlWireAuthInput),
40
+ ...input.mode ? { mode: input.mode } : {}
41
+ },
37
42
  reactivityKeys: integrationWriteKeys
38
43
  });
39
- if (Exit.isFailure(exit)) return null;
40
- const before = new Set(existingTemplate.map((template) => template.slug));
41
- const created = authMethodsFromConfig(exit.value.authenticationTemplate).find(
42
- (candidate) => !before.has(String(candidate.template))
43
- );
44
- return created ?? null;
44
+ return Exit.map(exit, (result) => result.authenticationTemplate);
45
45
  },
46
- [doConfigure, existingTemplate, slug]
46
+ [doConfigure, slug]
47
47
  );
48
- const removeCustomMethod = useCallback(
49
- async (method) => {
50
- if (method.source !== "custom") return false;
51
- const next = existingTemplate.filter(
52
- (template) => template.slug !== String(method.template)
53
- );
54
- const exit = await doConfigure({
55
- params: { slug: String(slug) },
56
- payload: { authenticationTemplate: next, mode: "replace" },
57
- reactivityKeys: integrationWriteKeys
58
- });
59
- return Exit.isSuccess(exit);
60
- },
61
- [doConfigure, existingTemplate, slug]
48
+ const codec = useMemo(
49
+ () => ({
50
+ toAuthMethods: authMethodsFromConfig,
51
+ // Inputs omit slugs — the backend merge backfills `custom_<id>`.
52
+ templatesFromPlacements: (placements) => graphqlAuthMethodInputsFromPlacements(placements),
53
+ slugOf: (template) => template.slug
54
+ }),
55
+ []
62
56
  );
57
+ const { createCustomMethod, removeCustomMethod } = useCustomMethodActions({
58
+ existing: existingTemplate,
59
+ codec,
60
+ configure
61
+ });
63
62
  return /* @__PURE__ */ jsx("div", { className: "mx-auto max-w-3xl space-y-8 px-6 py-8", children: /* @__PURE__ */ jsx(
64
63
  AccountsSection,
65
64
  {
@@ -76,4 +75,4 @@ function GraphqlAccountsPanel(props) {
76
75
  export {
77
76
  GraphqlAccountsPanel
78
77
  };
79
- //# sourceMappingURL=chunk-VCYDSSIK.js.map
78
+ //# sourceMappingURL=chunk-OGNJZCEF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/GraphqlAccountsPanel.tsx"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport { useAtomValue, useAtomSet } from \"@effect/atom-react\";\nimport * as Exit from \"effect/Exit\";\nimport * as AsyncResult from \"effect/unstable/reactivity/AsyncResult\";\nimport { IntegrationSlug } from \"@executor-js/sdk/shared\";\nimport type { IntegrationAccountHandoff } from \"@executor-js/sdk/client\";\n\nimport { AccountsSection } from \"@executor-js/react/components/accounts-section\";\nimport { integrationWriteKeys } from \"@executor-js/react/api/reactivity-keys\";\nimport type { AuthMethod, Placement } from \"@executor-js/react/lib/auth-placements\";\nimport {\n useCustomMethodActions,\n type AuthMethodsCodec,\n type ConfigureAuthMethods,\n} from \"@executor-js/react/lib/custom-auth-methods\";\n\nimport { graphqlConfigAtom, graphqlConfigure } from \"./atoms\";\nimport {\n authMethodsFromConfig,\n graphqlAuthMethodInputsFromPlacements,\n graphqlWireAuthInput,\n} from \"./auth-method-config\";\nimport type { GraphqlAuthMethod } from \"../sdk/types\";\n\n// ---------------------------------------------------------------------------\n// GraphQL Accounts hub — fills the generic detail page's `accounts` slot.\n//\n// Reads the integration's real `authenticationTemplate` (via `getConfig`),\n// converts it to generic `AuthMethod[]`, and composes the generic\n// `AccountsSection` — whose Add-account offers those methods plus a \"+ Custom\n// method\" row (apikey-only). The custom-method create is INJECTED here\n// (`createCustomMethod`): generic placements → ONE apikey method\n// (`graphqlAuthMethodInputsFromPlacements`, slug omitted → backend\n// `custom_<id>`) merge-appended via `configure`. Stays plugin-side because it\n// touches the graphql sdk method types.\n// ---------------------------------------------------------------------------\n\nexport default function GraphqlAccountsPanel(props: {\n readonly sourceId: string;\n readonly integrationName: string;\n readonly accountHandoff?: IntegrationAccountHandoff | null;\n}) {\n const { sourceId, integrationName, accountHandoff } = props;\n const slug = IntegrationSlug.make(sourceId);\n const configResult = useAtomValue(graphqlConfigAtom(slug));\n const doConfigure = useAtomSet(graphqlConfigure, { mode: \"promiseExit\" });\n\n const existingTemplate = useMemo<readonly GraphqlAuthMethod[]>(() => {\n if (!AsyncResult.isSuccess(configResult) || configResult.value == null) return [];\n return configResult.value.authenticationTemplate ?? [];\n }, [configResult]);\n\n const methods = useMemo<readonly AuthMethod[]>(\n () => authMethodsFromConfig(existingTemplate),\n [existingTemplate],\n );\n\n // Custom-method create/remove: the shared skeleton (merge-append → diff out\n // the created method; filter → replace) parameterized by the GraphQL codec.\n // Stays plugin-side only where it touches the graphql method types.\n const configure = useCallback<ConfigureAuthMethods<GraphqlAuthMethod>>(\n async (input) => {\n const exit = await doConfigure({\n params: { slug: String(slug) },\n payload: {\n authenticationTemplate: input.authenticationTemplate.map(graphqlWireAuthInput),\n ...(input.mode ? { mode: input.mode } : {}),\n },\n reactivityKeys: integrationWriteKeys,\n });\n return Exit.map(exit, (result) => result.authenticationTemplate);\n },\n [doConfigure, slug],\n );\n\n const codec = useMemo<AuthMethodsCodec<GraphqlAuthMethod>>(\n () => ({\n toAuthMethods: authMethodsFromConfig,\n // Inputs omit slugs — the backend merge backfills `custom_<id>`.\n templatesFromPlacements: (placements: readonly Placement[]) =>\n graphqlAuthMethodInputsFromPlacements(placements) as readonly GraphqlAuthMethod[],\n slugOf: (template: GraphqlAuthMethod) => template.slug,\n }),\n [],\n );\n\n const { createCustomMethod, removeCustomMethod } = useCustomMethodActions({\n existing: existingTemplate,\n codec,\n configure,\n });\n\n return (\n <div className=\"mx-auto max-w-3xl space-y-8 px-6 py-8\">\n <AccountsSection\n integration={slug}\n integrationName={integrationName}\n methods={methods}\n accountHandoff={accountHandoff}\n createCustomMethod={createCustomMethod}\n removeCustomMethod={removeCustomMethod}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,aAAa,eAAe;AACrC,SAAS,cAAc,kBAAkB;AACzC,YAAY,UAAU;AACtB,YAAY,iBAAiB;AAC7B,SAAS,uBAAuB;AAGhC,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AAErC;AAAA,EACE;AAAA,OAGK;AAgFD;AAzDS,SAAR,qBAAsC,OAI1C;AACD,QAAM,EAAE,UAAU,iBAAiB,eAAe,IAAI;AACtD,QAAM,OAAO,gBAAgB,KAAK,QAAQ;AAC1C,QAAM,eAAe,aAAa,kBAAkB,IAAI,CAAC;AACzD,QAAM,cAAc,WAAW,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAExE,QAAM,mBAAmB,QAAsC,MAAM;AACnE,QAAI,CAAa,sBAAU,YAAY,KAAK,aAAa,SAAS,KAAM,QAAO,CAAC;AAChF,WAAO,aAAa,MAAM,0BAA0B,CAAC;AAAA,EACvD,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,UAAU;AAAA,IACd,MAAM,sBAAsB,gBAAgB;AAAA,IAC5C,CAAC,gBAAgB;AAAA,EACnB;AAKA,QAAM,YAAY;AAAA,IAChB,OAAO,UAAU;AACf,YAAM,OAAO,MAAM,YAAY;AAAA,QAC7B,QAAQ,EAAE,MAAM,OAAO,IAAI,EAAE;AAAA,QAC7B,SAAS;AAAA,UACP,wBAAwB,MAAM,uBAAuB,IAAI,oBAAoB;AAAA,UAC7E,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,QAC3C;AAAA,QACA,gBAAgB;AAAA,MAClB,CAAC;AACD,aAAY,SAAI,MAAM,CAAC,WAAW,OAAO,sBAAsB;AAAA,IACjE;AAAA,IACA,CAAC,aAAa,IAAI;AAAA,EACpB;AAEA,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL,eAAe;AAAA;AAAA,MAEf,yBAAyB,CAAC,eACxB,sCAAsC,UAAU;AAAA,MAClD,QAAQ,CAAC,aAAgC,SAAS;AAAA,IACpD;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,EAAE,oBAAoB,mBAAmB,IAAI,uBAAuB;AAAA,IACxE,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EACF,CAAC;AAED,SACE,oBAAC,SAAI,WAAU,yCACb;AAAA,IAAC;AAAA;AAAA,MACC,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}