@apollo/client-ai-apps 0.5.3 → 0.5.4
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/CHANGELOG.md +8 -0
- package/dist/vite/apolloClientAiApps.d.ts.map +1 -1
- package/dist/vite/apolloClientAiApps.js +35 -31
- package/dist/vite/apolloClientAiApps.js.map +1 -1
- package/package.json +1 -1
- package/src/vite/__tests__/apolloClientAiApps.test.ts +183 -2
- package/src/vite/apolloClientAiApps.ts +46 -40
package/CHANGELOG.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apolloClientAiApps.d.ts","sourceRoot":"","sources":["../../src/vite/apolloClientAiApps.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,MAAM,EAEZ,MAAM,MAAM,CAAC;AAId,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAoB7E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"apolloClientAiApps.d.ts","sourceRoot":"","sources":["../../src/vite/apolloClientAiApps.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,MAAM,EAEZ,MAAM,MAAM,CAAC;AAId,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAoB7E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAKnE,MAAM,CAAC,OAAO,WAAW,kBAAkB,CAAC;IAC1C,KAAY,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC;IAExD,UAAiB,OAAO;QACtB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KAChC;CACF;AAgBD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,gCAOnD;AAQD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,kBAAkB,CAAC,OAAO,GAClC,MAAM,CAkRR;AA8ED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CA2CzE"}
|
|
@@ -9,12 +9,13 @@ import { glob } from "glob";
|
|
|
9
9
|
import { print } from "@apollo/client/utilities";
|
|
10
10
|
import { removeDirectivesFromDocument } from "@apollo/client/utilities/internal";
|
|
11
11
|
import { of } from "rxjs";
|
|
12
|
-
import { Kind, parse } from "graphql";
|
|
12
|
+
import { Kind, OperationTypeNode, parse } from "graphql";
|
|
13
13
|
import { getArgumentValue, getDirectiveArgument, getTypeName, maybeGetArgumentValue, } from "./utilities/graphql.js";
|
|
14
14
|
import { invariant } from "../utilities/invariant.js";
|
|
15
15
|
import { explorer } from "./utilities/config.js";
|
|
16
16
|
import { ApolloClientAiAppsConfigSchema } from "../config/schema.js";
|
|
17
17
|
import { z } from "zod";
|
|
18
|
+
import { createFragmentRegistry } from "@apollo/client/cache";
|
|
18
19
|
const root = process.cwd();
|
|
19
20
|
const VALID_TARGETS = ["openai", "mcp"];
|
|
20
21
|
function isValidTarget(target) {
|
|
@@ -33,10 +34,11 @@ export function apolloClientAiApps(options) {
|
|
|
33
34
|
const cache = new Map();
|
|
34
35
|
let packageJson;
|
|
35
36
|
let config;
|
|
37
|
+
const fragments = createFragmentRegistry();
|
|
36
38
|
invariant(Array.isArray(targets) && targets.length > 0, "The `targets` option must be a non-empty array");
|
|
37
39
|
invariant(targets.every(isValidTarget), `All targets must be one of: ${VALID_TARGETS.join(", ")}`);
|
|
38
40
|
const client = new ApolloClient({
|
|
39
|
-
cache: new InMemoryCache(),
|
|
41
|
+
cache: new InMemoryCache({ fragments }),
|
|
40
42
|
link: processQueryLink,
|
|
41
43
|
});
|
|
42
44
|
async function processFile(file) {
|
|
@@ -51,41 +53,43 @@ export function apolloClientAiApps(options) {
|
|
|
51
53
|
{ name: "graphql-tag", identifier: "gql" },
|
|
52
54
|
{ name: "@apollo/client", identifier: "gql" },
|
|
53
55
|
],
|
|
54
|
-
}).map((source) => (
|
|
55
|
-
|
|
56
|
-
file,
|
|
57
|
-
location: source.locationOffset,
|
|
58
|
-
}));
|
|
59
|
-
const operations = [];
|
|
60
|
-
for (const source of sources) {
|
|
61
|
-
const type = source.node.definitions.find((d) => d.kind === "OperationDefinition").operation;
|
|
62
|
-
let result;
|
|
63
|
-
if (type === "query") {
|
|
64
|
-
result = await client.query({
|
|
65
|
-
query: source.node,
|
|
66
|
-
fetchPolicy: "no-cache",
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
else if (type === "mutation") {
|
|
70
|
-
result = await client.mutate({
|
|
71
|
-
mutation: source.node,
|
|
72
|
-
fetchPolicy: "no-cache",
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
throw new Error("Found an unsupported operation type. Only Query and Mutation are supported.");
|
|
77
|
-
}
|
|
78
|
-
operations.push(result.data);
|
|
79
|
-
}
|
|
56
|
+
}).map((source) => parse(source.body));
|
|
57
|
+
fragments.register(...sources);
|
|
80
58
|
cache.set(file, {
|
|
81
59
|
file: file,
|
|
82
60
|
hash: fileHash,
|
|
83
|
-
|
|
61
|
+
sources,
|
|
84
62
|
});
|
|
85
63
|
}
|
|
86
64
|
async function generateManifest(environment) {
|
|
87
65
|
const appsConfig = await getAppsConfig();
|
|
88
|
-
const
|
|
66
|
+
const sources = Array.from(cache.values()).flatMap((entry) => entry.sources);
|
|
67
|
+
const operations = [];
|
|
68
|
+
for (const source of sources) {
|
|
69
|
+
const operationDef = source.definitions.find((d) => d.kind === Kind.OPERATION_DEFINITION);
|
|
70
|
+
if (!operationDef)
|
|
71
|
+
continue;
|
|
72
|
+
switch (operationDef.operation) {
|
|
73
|
+
case OperationTypeNode.QUERY: {
|
|
74
|
+
const result = await client.query({
|
|
75
|
+
query: source,
|
|
76
|
+
fetchPolicy: "no-cache",
|
|
77
|
+
});
|
|
78
|
+
operations.push(result.data);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
case OperationTypeNode.MUTATION: {
|
|
82
|
+
const result = await client.mutate({
|
|
83
|
+
mutation: source,
|
|
84
|
+
fetchPolicy: "no-cache",
|
|
85
|
+
});
|
|
86
|
+
operations.push(result.data);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
default:
|
|
90
|
+
throw new Error(`Found unsupported operation type '${operationDef.operation}'. Only queries and mutations are supported.`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
89
93
|
invariant(operations.filter((o) => o.prefetch).length <= 1, "Found multiple operations marked as `@prefetch`. You can only mark 1 operation with `@prefetch`.");
|
|
90
94
|
function getBuildResourceForTarget(target) {
|
|
91
95
|
const entryPoint = getResourceFromConfig(appsConfig, config.mode, target);
|
|
@@ -114,7 +118,7 @@ export function apolloClientAiApps(options) {
|
|
|
114
118
|
name: appsConfig.name ?? packageJson.name,
|
|
115
119
|
description: appsConfig.description ?? packageJson.description,
|
|
116
120
|
hash: createHash("sha256").update(Date.now().toString()).digest("hex"),
|
|
117
|
-
operations
|
|
121
|
+
operations,
|
|
118
122
|
resource,
|
|
119
123
|
csp: {
|
|
120
124
|
connectDomains: appsConfig.csp?.connectDomains ?? [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apolloClientAiApps.js","sourceRoot":"","sources":["../../src/vite/apolloClientAiApps.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n defaultClientConditions,\n type Environment,\n type Plugin,\n type ResolvedConfig,\n} from \"vite\";\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { ApolloClient, ApolloLink, type DocumentNode } from \"@apollo/client\";\nimport { InMemoryCache } from \"@apollo/client\";\nimport { gqlPluckFromCodeStringSync } from \"@graphql-tools/graphql-tag-pluck\";\nimport { glob } from \"glob\";\nimport { print } from \"@apollo/client/utilities\";\nimport { removeDirectivesFromDocument } from \"@apollo/client/utilities/internal\";\nimport { of } from \"rxjs\";\nimport { Kind, parse, type OperationDefinitionNode } from \"graphql\";\nimport {\n getArgumentValue,\n getDirectiveArgument,\n getTypeName,\n maybeGetArgumentValue,\n} from \"./utilities/graphql.js\";\nimport type {\n ApplicationManifest,\n ManifestOperation,\n} from \"../types/application-manifest\";\nimport { invariant } from \"../utilities/invariant.js\";\nimport { explorer } from \"./utilities/config.js\";\nimport type { ApolloClientAiAppsConfig } from \"../config/index.js\";\nimport { ApolloClientAiAppsConfigSchema } from \"../config/schema.js\";\nimport { z } from \"zod\";\n\nexport declare namespace apolloClientAiApps {\n export type Target = ApolloClientAiAppsConfig.AppTarget;\n\n export interface Options {\n targets: Target[];\n devTarget?: Target | undefined;\n }\n}\n\nconst root = process.cwd();\n\nconst VALID_TARGETS: apolloClientAiApps.Target[] = [\"openai\", \"mcp\"];\n\nfunction isValidTarget(target: unknown): target is apolloClientAiApps.Target {\n return VALID_TARGETS.includes(target as apolloClientAiApps.Target);\n}\n\nfunction buildExtensions(target: apolloClientAiApps.Target) {\n return [\".mjs\", \".js\", \".mts\", \".ts\", \".jsx\", \".tsx\", \".json\"].flatMap(\n (ext) => [`.${target}${ext}`, ext]\n );\n}\n\nexport function devTarget(target: string | undefined) {\n invariant(\n target === undefined || isValidTarget(target),\n `devTarget '${target}' is not a valid dev target. Must be one of ${VALID_TARGETS.join(\", \")}.`\n );\n\n return target;\n}\n\ninterface FileCache {\n file: string;\n hash: string;\n operations: ManifestOperation[];\n}\n\nexport function apolloClientAiApps(\n options: apolloClientAiApps.Options\n): Plugin {\n const targets = Array.from(new Set(options.targets));\n const { devTarget = targets.length === 1 ? targets[0] : undefined } = options;\n const cache = new Map<string, FileCache>();\n\n let packageJson!: Record<string, any>;\n let config!: ResolvedConfig;\n\n invariant(\n Array.isArray(targets) && targets.length > 0,\n \"The `targets` option must be a non-empty array\"\n );\n\n invariant(\n targets.every(isValidTarget),\n `All targets must be one of: ${VALID_TARGETS.join(\", \")}`\n );\n\n const client = new ApolloClient({\n cache: new InMemoryCache(),\n link: processQueryLink,\n });\n\n async function processFile(file: string) {\n const code = fs.readFileSync(file, \"utf-8\");\n\n if (!code.includes(\"gql\")) return;\n\n const fileHash = createHash(\"md5\").update(code).digest(\"hex\");\n if (cache.get(file)?.hash === fileHash) return;\n const sources = gqlPluckFromCodeStringSync(file, code, {\n modules: [\n { name: \"graphql-tag\", identifier: \"gql\" },\n { name: \"@apollo/client\", identifier: \"gql\" },\n ],\n }).map((source) => ({\n node: parse(source.body),\n file,\n location: source.locationOffset,\n }));\n\n const operations: ManifestOperation[] = [];\n for (const source of sources) {\n const type = (\n source.node.definitions.find(\n (d) => d.kind === \"OperationDefinition\"\n ) as OperationDefinitionNode\n ).operation;\n\n let result;\n if (type === \"query\") {\n result = await client.query({\n query: source.node,\n fetchPolicy: \"no-cache\",\n });\n } else if (type === \"mutation\") {\n result = await client.mutate({\n mutation: source.node,\n fetchPolicy: \"no-cache\",\n });\n } else {\n throw new Error(\n \"Found an unsupported operation type. Only Query and Mutation are supported.\"\n );\n }\n operations.push(result.data as ManifestOperation);\n }\n\n cache.set(file, {\n file: file,\n hash: fileHash,\n operations,\n });\n }\n\n async function generateManifest(environment?: Environment) {\n const appsConfig = await getAppsConfig();\n const operations = Array.from(cache.values()).flatMap(\n (entry) => entry.operations\n );\n\n invariant(\n operations.filter((o) => o.prefetch).length <= 1,\n \"Found multiple operations marked as `@prefetch`. You can only mark 1 operation with `@prefetch`.\"\n );\n\n function getBuildResourceForTarget(target: apolloClientAiApps.Target) {\n const entryPoint = getResourceFromConfig(appsConfig, config.mode, target);\n\n if (entryPoint) {\n return entryPoint;\n }\n\n if (config.mode === \"production\") {\n return `${target}/index.html`;\n }\n\n throw new Error(\n `No entry point found for mode \"${config.mode}\". Entry points other than \"development\" and \"production\" must be defined in package.json file.`\n );\n }\n\n let resource: ApplicationManifest[\"resource\"];\n if (config.command === \"serve\") {\n // Dev mode: resource is a string (dev server URL)\n resource =\n getResourceFromConfig(appsConfig, config.mode, devTarget!) ??\n `http${config.server.https ? \"s\" : \"\"}://${config.server.host ?? \"localhost\"}:${config.server.port}`;\n } else {\n resource = Object.fromEntries(\n targets.map((target) => [target, getBuildResourceForTarget(target)])\n ) as { mcp?: string; openai?: string };\n }\n\n const manifest: ApplicationManifest = {\n format: \"apollo-ai-app-manifest\",\n version: \"1\",\n appVersion: appsConfig.version ?? packageJson.version,\n name: appsConfig.name ?? packageJson.name,\n description: appsConfig.description ?? packageJson.description,\n hash: createHash(\"sha256\").update(Date.now().toString()).digest(\"hex\"),\n operations: Array.from(cache.values()).flatMap(\n (entry) => entry.operations\n ),\n resource,\n csp: {\n connectDomains: appsConfig.csp?.connectDomains ?? [],\n frameDomains: appsConfig.csp?.frameDomains ?? [],\n redirectDomains: appsConfig.csp?.redirectDomains ?? [],\n resourceDomains: appsConfig.csp?.resourceDomains ?? [],\n },\n };\n\n if (isNonEmptyObject(appsConfig.widgetSettings)) {\n manifest.widgetSettings = appsConfig.widgetSettings;\n }\n\n if (isNonEmptyObject(appsConfig.labels)) {\n manifest.labels = appsConfig.labels;\n }\n\n // We create mcp and openai environments in order to write to\n // subdirectories, but we want the manifest to be in the root outDir. If we\n // are running in a different environment, we'll put it in the configured\n // outDir directly instead.\n const outDir =\n environment?.name === \"mcp\" || environment?.name === \"openai\" ?\n path.resolve(config.build.outDir, \"../\")\n : config.build.outDir;\n\n // Always write to build directory so the MCP server picks it up\n const dest = path.resolve(root, outDir, \".application-manifest.json\");\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.writeFileSync(dest, JSON.stringify(manifest));\n\n // Always write to the dev location so that the app can bundle the manifest content\n fs.writeFileSync(\".application-manifest.json\", JSON.stringify(manifest));\n }\n\n return {\n name: \"@apollo/client-ai-apps/vite\",\n async buildStart() {\n // Read package.json on start\n packageJson = JSON.parse(fs.readFileSync(\"package.json\", \"utf-8\"));\n\n // Scan all files on startup\n const files = await glob(\"./src/**/*.{ts,tsx,js,jsx}\", { fs });\n\n for (const file of files) {\n const fullPath = path.resolve(root, file);\n await processFile(fullPath);\n }\n\n // We don't want to do this here on builds cause it just gets overwritten anyways. We'll call it on writeBundle instead.\n if (config.command === \"serve\") {\n await generateManifest(this.environment);\n }\n },\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n configEnvironment(name, { build }) {\n if (!targets.includes(name as any)) return;\n\n return {\n build: {\n outDir: path.join(build?.outDir ?? \"dist\", name),\n },\n };\n },\n configureServer(server) {\n server.watcher.on(\"change\", async (file) => {\n if (file.endsWith(\"package.json\")) {\n packageJson = JSON.parse(fs.readFileSync(\"package.json\", \"utf-8\"));\n await generateManifest();\n } else if (file.match(/\\.?apollo-client-ai-apps\\.config\\.\\w+$/)) {\n explorer.clearCaches();\n await generateManifest();\n } else if (file.match(/\\.(jsx?|tsx?)$/)) {\n await processFile(file);\n await generateManifest();\n }\n });\n },\n\n config(_, { command }) {\n if (command === \"serve\") {\n invariant(\n isValidTarget(devTarget) || targets.length === 1,\n \"`devTarget` must be set for development when using multiple targets.\"\n );\n\n const target = devTarget ?? targets[0];\n\n return {\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n };\n }\n\n return {\n environments: Object.fromEntries(\n targets.map((target) => [\n target,\n {\n consumer: \"client\",\n webCompatible: true,\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n },\n ])\n ),\n builder: {\n buildApp: async (builder) => {\n await Promise.all(\n targets.map((target) =>\n builder.build(builder.environments[target])\n )\n );\n },\n },\n };\n },\n transformIndexHtml(html, ctx) {\n if (!ctx.server) return html;\n\n let baseUrl = (\n ctx.server.config?.server?.origin ??\n ctx.server.resolvedUrls?.local[0] ??\n \"\"\n ).replace(/\\/$/, \"\");\n baseUrl = baseUrl.replace(/\\/$/, \"\");\n\n return (\n html\n // import \"/@vite/...\" or \"/@react-refresh\"\n .replace(/(from\\s+[\"'])\\/([^\"']+)/g, `$1${baseUrl}/$2`)\n // src=\"/src/...\"\n .replace(/(src=[\"'])\\/([^\"']+)/gi, `$1${baseUrl}/$2`)\n );\n },\n async writeBundle() {\n await generateManifest(this.environment);\n },\n } satisfies Plugin;\n}\n\nconst processQueryLink = new ApolloLink((operation) => {\n const body = print(\n removeManifestDirectives(sortTopLevelDefinitions(operation.query))\n );\n const name = operation.operationName;\n const definition = operation.query.definitions.find(\n (d) => d.kind === \"OperationDefinition\"\n );\n\n // Use `operation.query` so that the error reflects the end-user defined\n // document, not our sorted one\n invariant(\n definition,\n `Document does not contain an operation:\\n${print(operation.query)}`\n );\n\n const { directives, operation: type } = definition;\n\n const variables = definition.variableDefinitions?.reduce(\n (obj, varDef) => ({\n ...obj,\n [varDef.variable.name.value]: getTypeName(varDef.type),\n }),\n {}\n );\n\n const prefetch = directives?.some((d) => d.name.value === \"prefetch\");\n const id = createHash(\"sha256\").update(body).digest(\"hex\");\n // TODO: For now, you can only have 1 operation marked as prefetch. In the future, we'll likely support more than 1, and the \"prefetchId\" will be defined on the `@prefetch` itself as an argument\n const prefetchID = prefetch ? \"__anonymous\" : undefined;\n\n const tools = directives\n ?.filter((d) => d.name.value === \"tool\")\n .map((directive) => {\n const result = ToolDirectiveSchema.safeParse({\n name: getArgumentValue(\n getDirectiveArgument(\"name\", directive, { required: true }),\n Kind.STRING\n ),\n description: getArgumentValue(\n getDirectiveArgument(\"description\", directive, { required: true }),\n Kind.STRING\n ),\n extraInputs: maybeGetArgumentValue(\n getDirectiveArgument(\"extraInputs\", directive),\n Kind.LIST\n ),\n labels: maybeGetArgumentValue(\n getDirectiveArgument(\"labels\", directive),\n Kind.OBJECT\n ),\n });\n\n if (result.error) {\n throw z.prettifyError(result.error);\n }\n\n return result.data;\n });\n\n // TODO: Make this object satisfy the `ManifestOperation` type. Currently\n // it errors because we need more validation on a few of these fields\n return of({\n data: { id, name, type, body, variables, prefetch, prefetchID, tools },\n });\n});\n\nfunction removeManifestDirectives(doc: DocumentNode) {\n return removeDirectivesFromDocument(\n [{ name: \"prefetch\" }, { name: \"tool\" }],\n doc\n )!;\n}\n\n// Sort the definitions in this document so that operations come before fragments,\n// and so that each kind of definition is sorted by name.\nexport function sortTopLevelDefinitions(query: DocumentNode): DocumentNode {\n const definitions = [...query.definitions];\n // We want to avoid unnecessary dependencies, so write out a comparison\n // function instead of using _.orderBy.\n definitions.sort((a, b) => {\n // This is a reverse sort by kind, so that OperationDefinition precedes FragmentDefinition.\n if (a.kind > b.kind) {\n return -1;\n }\n if (a.kind < b.kind) {\n return 1;\n }\n\n // Extract the name from each definition. Jump through some hoops because\n // non-executable definitions don't have to have names (even though any\n // DocumentNode actually passed here should only have executable\n // definitions).\n const aName =\n a.kind === \"OperationDefinition\" || a.kind === \"FragmentDefinition\" ?\n (a.name?.value ?? \"\")\n : \"\";\n const bName =\n b.kind === \"OperationDefinition\" || b.kind === \"FragmentDefinition\" ?\n (b.name?.value ?? \"\")\n : \"\";\n\n // Sort by name ascending.\n if (aName < bName) {\n return -1;\n }\n if (aName > bName) {\n return 1;\n }\n\n // Assuming that the document is \"valid\", no operation or fragment name can appear\n // more than once, so we don't need to differentiate further to have a deterministic\n // sort.\n return 0;\n });\n return {\n ...query,\n definitions,\n };\n}\n\nfunction isNonEmptyObject<T extends object>(\n obj: T | null | undefined\n): obj is T {\n return !!obj && Object.keys(obj).length > 0;\n}\n\nasync function getAppsConfig() {\n const result = await explorer.search();\n const config = (result?.config ??\n {}) as Partial<ApolloClientAiAppsConfig.Config>;\n\n const parsed = ApolloClientAiAppsConfigSchema.safeParse(config);\n\n if (parsed.error) {\n throw z.prettifyError(parsed.error);\n }\n\n return parsed.data;\n}\n\nfunction getResourceFromConfig(\n appsConfig: z.infer<typeof ApolloClientAiAppsConfigSchema>,\n mode: string,\n target: apolloClientAiApps.Target\n) {\n if (!appsConfig.entry || !appsConfig.entry[mode]) {\n return;\n }\n\n const config = appsConfig.entry[mode];\n\n return typeof config === \"string\" ? config : config[target];\n}\n\nconst ToolDirectiveSchema = z.strictObject({\n name: z.stringFormat(\"toolName\", (value) => value.indexOf(\" \") === -1, {\n error: (iss) => `Tool with name \"${iss.input}\" must not contain spaces`,\n }),\n description: z.string(),\n extraInputs: z.optional(\n z.array(\n z.strictObject({\n name: z.string(),\n description: z.string(),\n type: z.literal([\"string\", \"boolean\", \"number\"]),\n })\n )\n ),\n labels: ApolloClientAiAppsConfigSchema.shape.labels.optional(),\n});\n"]}
|
|
1
|
+
{"version":3,"file":"apolloClientAiApps.js","sourceRoot":"","sources":["../../src/vite/apolloClientAiApps.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n defaultClientConditions,\n type Environment,\n type Plugin,\n type ResolvedConfig,\n} from \"vite\";\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { ApolloClient, ApolloLink, type DocumentNode } from \"@apollo/client\";\nimport { InMemoryCache } from \"@apollo/client\";\nimport { gqlPluckFromCodeStringSync } from \"@graphql-tools/graphql-tag-pluck\";\nimport { glob } from \"glob\";\nimport { print } from \"@apollo/client/utilities\";\nimport { removeDirectivesFromDocument } from \"@apollo/client/utilities/internal\";\nimport { of } from \"rxjs\";\nimport { Kind, OperationTypeNode, parse } from \"graphql\";\nimport {\n getArgumentValue,\n getDirectiveArgument,\n getTypeName,\n maybeGetArgumentValue,\n} from \"./utilities/graphql.js\";\nimport type {\n ApplicationManifest,\n ManifestOperation,\n} from \"../types/application-manifest\";\nimport { invariant } from \"../utilities/invariant.js\";\nimport { explorer } from \"./utilities/config.js\";\nimport type { ApolloClientAiAppsConfig } from \"../config/index.js\";\nimport { ApolloClientAiAppsConfigSchema } from \"../config/schema.js\";\nimport { z } from \"zod\";\nimport { createFragmentRegistry } from \"@apollo/client/cache\";\n\nexport declare namespace apolloClientAiApps {\n export type Target = ApolloClientAiAppsConfig.AppTarget;\n\n export interface Options {\n targets: Target[];\n devTarget?: Target | undefined;\n }\n}\n\nconst root = process.cwd();\n\nconst VALID_TARGETS: apolloClientAiApps.Target[] = [\"openai\", \"mcp\"];\n\nfunction isValidTarget(target: unknown): target is apolloClientAiApps.Target {\n return VALID_TARGETS.includes(target as apolloClientAiApps.Target);\n}\n\nfunction buildExtensions(target: apolloClientAiApps.Target) {\n return [\".mjs\", \".js\", \".mts\", \".ts\", \".jsx\", \".tsx\", \".json\"].flatMap(\n (ext) => [`.${target}${ext}`, ext]\n );\n}\n\nexport function devTarget(target: string | undefined) {\n invariant(\n target === undefined || isValidTarget(target),\n `devTarget '${target}' is not a valid dev target. Must be one of ${VALID_TARGETS.join(\", \")}.`\n );\n\n return target;\n}\n\ninterface FileCache {\n file: string;\n hash: string;\n sources: DocumentNode[];\n}\n\nexport function apolloClientAiApps(\n options: apolloClientAiApps.Options\n): Plugin {\n const targets = Array.from(new Set(options.targets));\n const { devTarget = targets.length === 1 ? targets[0] : undefined } = options;\n const cache = new Map<string, FileCache>();\n\n let packageJson!: Record<string, any>;\n let config!: ResolvedConfig;\n\n const fragments = createFragmentRegistry();\n\n invariant(\n Array.isArray(targets) && targets.length > 0,\n \"The `targets` option must be a non-empty array\"\n );\n\n invariant(\n targets.every(isValidTarget),\n `All targets must be one of: ${VALID_TARGETS.join(\", \")}`\n );\n\n const client = new ApolloClient({\n cache: new InMemoryCache({ fragments }),\n link: processQueryLink,\n });\n\n async function processFile(file: string) {\n const code = fs.readFileSync(file, \"utf-8\");\n\n if (!code.includes(\"gql\")) return;\n\n const fileHash = createHash(\"md5\").update(code).digest(\"hex\");\n if (cache.get(file)?.hash === fileHash) return;\n const sources = gqlPluckFromCodeStringSync(file, code, {\n modules: [\n { name: \"graphql-tag\", identifier: \"gql\" },\n { name: \"@apollo/client\", identifier: \"gql\" },\n ],\n }).map((source) => parse(source.body));\n\n fragments.register(...sources);\n\n cache.set(file, {\n file: file,\n hash: fileHash,\n sources,\n });\n }\n\n async function generateManifest(environment?: Environment) {\n const appsConfig = await getAppsConfig();\n const sources = Array.from(cache.values()).flatMap(\n (entry) => entry.sources\n );\n\n const operations: ManifestOperation[] = [];\n for (const source of sources) {\n const operationDef = source.definitions.find(\n (d) => d.kind === Kind.OPERATION_DEFINITION\n );\n\n if (!operationDef) continue;\n\n switch (operationDef.operation) {\n case OperationTypeNode.QUERY: {\n const result = await client.query<ManifestOperation>({\n query: source,\n fetchPolicy: \"no-cache\",\n });\n\n operations.push(result.data!);\n break;\n }\n case OperationTypeNode.MUTATION: {\n const result = await client.mutate<ManifestOperation>({\n mutation: source,\n fetchPolicy: \"no-cache\",\n });\n\n operations.push(result.data!);\n break;\n }\n default:\n throw new Error(\n `Found unsupported operation type '${operationDef.operation}'. Only queries and mutations are supported.`\n );\n }\n }\n\n invariant(\n operations.filter((o) => o.prefetch).length <= 1,\n \"Found multiple operations marked as `@prefetch`. You can only mark 1 operation with `@prefetch`.\"\n );\n\n function getBuildResourceForTarget(target: apolloClientAiApps.Target) {\n const entryPoint = getResourceFromConfig(appsConfig, config.mode, target);\n\n if (entryPoint) {\n return entryPoint;\n }\n\n if (config.mode === \"production\") {\n return `${target}/index.html`;\n }\n\n throw new Error(\n `No entry point found for mode \"${config.mode}\". Entry points other than \"development\" and \"production\" must be defined in package.json file.`\n );\n }\n\n let resource: ApplicationManifest[\"resource\"];\n if (config.command === \"serve\") {\n // Dev mode: resource is a string (dev server URL)\n resource =\n getResourceFromConfig(appsConfig, config.mode, devTarget!) ??\n `http${config.server.https ? \"s\" : \"\"}://${config.server.host ?? \"localhost\"}:${config.server.port}`;\n } else {\n resource = Object.fromEntries(\n targets.map((target) => [target, getBuildResourceForTarget(target)])\n ) as { mcp?: string; openai?: string };\n }\n\n const manifest: ApplicationManifest = {\n format: \"apollo-ai-app-manifest\",\n version: \"1\",\n appVersion: appsConfig.version ?? packageJson.version,\n name: appsConfig.name ?? packageJson.name,\n description: appsConfig.description ?? packageJson.description,\n hash: createHash(\"sha256\").update(Date.now().toString()).digest(\"hex\"),\n operations,\n resource,\n csp: {\n connectDomains: appsConfig.csp?.connectDomains ?? [],\n frameDomains: appsConfig.csp?.frameDomains ?? [],\n redirectDomains: appsConfig.csp?.redirectDomains ?? [],\n resourceDomains: appsConfig.csp?.resourceDomains ?? [],\n },\n };\n\n if (isNonEmptyObject(appsConfig.widgetSettings)) {\n manifest.widgetSettings = appsConfig.widgetSettings;\n }\n\n if (isNonEmptyObject(appsConfig.labels)) {\n manifest.labels = appsConfig.labels;\n }\n\n // We create mcp and openai environments in order to write to\n // subdirectories, but we want the manifest to be in the root outDir. If we\n // are running in a different environment, we'll put it in the configured\n // outDir directly instead.\n const outDir =\n environment?.name === \"mcp\" || environment?.name === \"openai\" ?\n path.resolve(config.build.outDir, \"../\")\n : config.build.outDir;\n\n // Always write to build directory so the MCP server picks it up\n const dest = path.resolve(root, outDir, \".application-manifest.json\");\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.writeFileSync(dest, JSON.stringify(manifest));\n\n // Always write to the dev location so that the app can bundle the manifest content\n fs.writeFileSync(\".application-manifest.json\", JSON.stringify(manifest));\n }\n\n return {\n name: \"@apollo/client-ai-apps/vite\",\n async buildStart() {\n // Read package.json on start\n packageJson = JSON.parse(fs.readFileSync(\"package.json\", \"utf-8\"));\n\n // Scan all files on startup\n const files = await glob(\"./src/**/*.{ts,tsx,js,jsx}\", { fs });\n\n for (const file of files) {\n const fullPath = path.resolve(root, file);\n await processFile(fullPath);\n }\n\n // We don't want to do this here on builds cause it just gets overwritten anyways. We'll call it on writeBundle instead.\n if (config.command === \"serve\") {\n await generateManifest(this.environment);\n }\n },\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n configEnvironment(name, { build }) {\n if (!targets.includes(name as any)) return;\n\n return {\n build: {\n outDir: path.join(build?.outDir ?? \"dist\", name),\n },\n };\n },\n configureServer(server) {\n server.watcher.on(\"change\", async (file) => {\n if (file.endsWith(\"package.json\")) {\n packageJson = JSON.parse(fs.readFileSync(\"package.json\", \"utf-8\"));\n await generateManifest();\n } else if (file.match(/\\.?apollo-client-ai-apps\\.config\\.\\w+$/)) {\n explorer.clearCaches();\n await generateManifest();\n } else if (file.match(/\\.(jsx?|tsx?)$/)) {\n await processFile(file);\n await generateManifest();\n }\n });\n },\n\n config(_, { command }) {\n if (command === \"serve\") {\n invariant(\n isValidTarget(devTarget) || targets.length === 1,\n \"`devTarget` must be set for development when using multiple targets.\"\n );\n\n const target = devTarget ?? targets[0];\n\n return {\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n };\n }\n\n return {\n environments: Object.fromEntries(\n targets.map((target) => [\n target,\n {\n consumer: \"client\",\n webCompatible: true,\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n },\n ])\n ),\n builder: {\n buildApp: async (builder) => {\n await Promise.all(\n targets.map((target) =>\n builder.build(builder.environments[target])\n )\n );\n },\n },\n };\n },\n transformIndexHtml(html, ctx) {\n if (!ctx.server) return html;\n\n let baseUrl = (\n ctx.server.config?.server?.origin ??\n ctx.server.resolvedUrls?.local[0] ??\n \"\"\n ).replace(/\\/$/, \"\");\n baseUrl = baseUrl.replace(/\\/$/, \"\");\n\n return (\n html\n // import \"/@vite/...\" or \"/@react-refresh\"\n .replace(/(from\\s+[\"'])\\/([^\"']+)/g, `$1${baseUrl}/$2`)\n // src=\"/src/...\"\n .replace(/(src=[\"'])\\/([^\"']+)/gi, `$1${baseUrl}/$2`)\n );\n },\n async writeBundle() {\n await generateManifest(this.environment);\n },\n } satisfies Plugin;\n}\n\nconst processQueryLink = new ApolloLink((operation) => {\n const body = print(\n removeManifestDirectives(sortTopLevelDefinitions(operation.query))\n );\n const name = operation.operationName;\n const definition = operation.query.definitions.find(\n (d) => d.kind === \"OperationDefinition\"\n );\n\n // Use `operation.query` so that the error reflects the end-user defined\n // document, not our sorted one\n invariant(\n definition,\n `Document does not contain an operation:\\n${print(operation.query)}`\n );\n\n const { directives, operation: type } = definition;\n\n const variables = definition.variableDefinitions?.reduce(\n (obj, varDef) => ({\n ...obj,\n [varDef.variable.name.value]: getTypeName(varDef.type),\n }),\n {}\n );\n\n const prefetch = directives?.some((d) => d.name.value === \"prefetch\");\n const id = createHash(\"sha256\").update(body).digest(\"hex\");\n // TODO: For now, you can only have 1 operation marked as prefetch. In the future, we'll likely support more than 1, and the \"prefetchId\" will be defined on the `@prefetch` itself as an argument\n const prefetchID = prefetch ? \"__anonymous\" : undefined;\n\n const tools = directives\n ?.filter((d) => d.name.value === \"tool\")\n .map((directive) => {\n const result = ToolDirectiveSchema.safeParse({\n name: getArgumentValue(\n getDirectiveArgument(\"name\", directive, { required: true }),\n Kind.STRING\n ),\n description: getArgumentValue(\n getDirectiveArgument(\"description\", directive, { required: true }),\n Kind.STRING\n ),\n extraInputs: maybeGetArgumentValue(\n getDirectiveArgument(\"extraInputs\", directive),\n Kind.LIST\n ),\n labels: maybeGetArgumentValue(\n getDirectiveArgument(\"labels\", directive),\n Kind.OBJECT\n ),\n });\n\n if (result.error) {\n throw z.prettifyError(result.error);\n }\n\n return result.data;\n });\n\n // TODO: Make this object satisfy the `ManifestOperation` type. Currently\n // it errors because we need more validation on a few of these fields\n return of({\n data: { id, name, type, body, variables, prefetch, prefetchID, tools },\n });\n});\n\nfunction removeManifestDirectives(doc: DocumentNode) {\n return removeDirectivesFromDocument(\n [{ name: \"prefetch\" }, { name: \"tool\" }],\n doc\n )!;\n}\n\n// Sort the definitions in this document so that operations come before fragments,\n// and so that each kind of definition is sorted by name.\nexport function sortTopLevelDefinitions(query: DocumentNode): DocumentNode {\n const definitions = [...query.definitions];\n // We want to avoid unnecessary dependencies, so write out a comparison\n // function instead of using _.orderBy.\n definitions.sort((a, b) => {\n // This is a reverse sort by kind, so that OperationDefinition precedes FragmentDefinition.\n if (a.kind > b.kind) {\n return -1;\n }\n if (a.kind < b.kind) {\n return 1;\n }\n\n // Extract the name from each definition. Jump through some hoops because\n // non-executable definitions don't have to have names (even though any\n // DocumentNode actually passed here should only have executable\n // definitions).\n const aName =\n a.kind === \"OperationDefinition\" || a.kind === \"FragmentDefinition\" ?\n (a.name?.value ?? \"\")\n : \"\";\n const bName =\n b.kind === \"OperationDefinition\" || b.kind === \"FragmentDefinition\" ?\n (b.name?.value ?? \"\")\n : \"\";\n\n // Sort by name ascending.\n if (aName < bName) {\n return -1;\n }\n if (aName > bName) {\n return 1;\n }\n\n // Assuming that the document is \"valid\", no operation or fragment name can appear\n // more than once, so we don't need to differentiate further to have a deterministic\n // sort.\n return 0;\n });\n return {\n ...query,\n definitions,\n };\n}\n\nfunction isNonEmptyObject<T extends object>(\n obj: T | null | undefined\n): obj is T {\n return !!obj && Object.keys(obj).length > 0;\n}\n\nasync function getAppsConfig() {\n const result = await explorer.search();\n const config = (result?.config ??\n {}) as Partial<ApolloClientAiAppsConfig.Config>;\n\n const parsed = ApolloClientAiAppsConfigSchema.safeParse(config);\n\n if (parsed.error) {\n throw z.prettifyError(parsed.error);\n }\n\n return parsed.data;\n}\n\nfunction getResourceFromConfig(\n appsConfig: z.infer<typeof ApolloClientAiAppsConfigSchema>,\n mode: string,\n target: apolloClientAiApps.Target\n) {\n if (!appsConfig.entry || !appsConfig.entry[mode]) {\n return;\n }\n\n const config = appsConfig.entry[mode];\n\n return typeof config === \"string\" ? config : config[target];\n}\n\nconst ToolDirectiveSchema = z.strictObject({\n name: z.stringFormat(\"toolName\", (value) => value.indexOf(\" \") === -1, {\n error: (iss) => `Tool with name \"${iss.input}\" must not contain spaces`,\n }),\n description: z.string(),\n extraInputs: z.optional(\n z.array(\n z.strictObject({\n name: z.string(),\n description: z.string(),\n type: z.literal([\"string\", \"boolean\", \"number\"]),\n })\n )\n ),\n labels: ApolloClientAiAppsConfigSchema.shape.labels.optional(),\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import { gql, type DocumentNode } from "@apollo/client";
|
|
4
|
-
import { print } from "@apollo/client/utilities";
|
|
4
|
+
import { getMainDefinition, print } from "@apollo/client/utilities";
|
|
5
5
|
import { getOperationName } from "@apollo/client/utilities/internal";
|
|
6
6
|
import { vol } from "memfs";
|
|
7
7
|
import { apolloClientAiApps } from "../apolloClientAiApps.js";
|
|
@@ -11,6 +11,8 @@ import type {
|
|
|
11
11
|
ManifestWidgetSettings,
|
|
12
12
|
} from "../../types/application-manifest.js";
|
|
13
13
|
import { explorer } from "../utilities/config.js";
|
|
14
|
+
import { invariant } from "@apollo/client/utilities/invariant";
|
|
15
|
+
import { Kind } from "graphql";
|
|
14
16
|
|
|
15
17
|
beforeEach(() => {
|
|
16
18
|
explorer.clearCaches();
|
|
@@ -121,6 +123,173 @@ describe("operations", () => {
|
|
|
121
123
|
`);
|
|
122
124
|
});
|
|
123
125
|
|
|
126
|
+
test("handles operations with fragments in the same file", async () => {
|
|
127
|
+
vol.fromJSON({
|
|
128
|
+
"package.json": mockPackageJson(),
|
|
129
|
+
"src/my-component.tsx": declareOperation(gql`
|
|
130
|
+
query HelloWorldQuery($name: string!)
|
|
131
|
+
@tool(name: "hello-world", description: "This is an awesome tool!") {
|
|
132
|
+
greeting {
|
|
133
|
+
message
|
|
134
|
+
recipient {
|
|
135
|
+
...RecipientFragment
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
fragment RecipientFragment on Recipient {
|
|
141
|
+
id
|
|
142
|
+
name
|
|
143
|
+
}
|
|
144
|
+
`),
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
await using server = await setupServer({
|
|
148
|
+
plugins: [apolloClientAiApps({ targets: ["mcp"] })],
|
|
149
|
+
});
|
|
150
|
+
await server.listen();
|
|
151
|
+
|
|
152
|
+
const manifest = readManifestFile();
|
|
153
|
+
expect(manifest).toMatchInlineSnapshot(`
|
|
154
|
+
{
|
|
155
|
+
"appVersion": "1.0.0",
|
|
156
|
+
"csp": {
|
|
157
|
+
"connectDomains": [],
|
|
158
|
+
"frameDomains": [],
|
|
159
|
+
"redirectDomains": [],
|
|
160
|
+
"resourceDomains": [],
|
|
161
|
+
},
|
|
162
|
+
"format": "apollo-ai-app-manifest",
|
|
163
|
+
"hash": "abc",
|
|
164
|
+
"operations": [
|
|
165
|
+
{
|
|
166
|
+
"body": "query HelloWorldQuery {
|
|
167
|
+
greeting {
|
|
168
|
+
message
|
|
169
|
+
recipient {
|
|
170
|
+
...RecipientFragment
|
|
171
|
+
__typename
|
|
172
|
+
}
|
|
173
|
+
__typename
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
fragment RecipientFragment on Recipient {
|
|
178
|
+
id
|
|
179
|
+
name
|
|
180
|
+
__typename
|
|
181
|
+
}",
|
|
182
|
+
"id": "1646a86ae2ff5ad75457161be5cff80f3ba5172da573a0fc796b268870119020",
|
|
183
|
+
"name": "HelloWorldQuery",
|
|
184
|
+
"prefetch": false,
|
|
185
|
+
"tools": [
|
|
186
|
+
{
|
|
187
|
+
"description": "This is an awesome tool!",
|
|
188
|
+
"name": "hello-world",
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
"type": "query",
|
|
192
|
+
"variables": {
|
|
193
|
+
"name": "string",
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
"resource": "http://localhost:3333",
|
|
198
|
+
"version": "1",
|
|
199
|
+
}
|
|
200
|
+
`);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test("handles operations with fragments in other files", async () => {
|
|
204
|
+
vol.fromJSON({
|
|
205
|
+
"package.json": mockPackageJson(),
|
|
206
|
+
"src/first-recipient.tsx": declareFragment(gql`
|
|
207
|
+
fragment OtherRecipientFragment on Recipient {
|
|
208
|
+
name
|
|
209
|
+
}
|
|
210
|
+
`),
|
|
211
|
+
"src/my-component.tsx": declareOperation(gql`
|
|
212
|
+
query HelloWorldQuery($name: string!)
|
|
213
|
+
@tool(name: "hello-world", description: "This is an awesome tool!") {
|
|
214
|
+
greeting {
|
|
215
|
+
message
|
|
216
|
+
recipient {
|
|
217
|
+
...RecipientFragment
|
|
218
|
+
...OtherRecipientFragment
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
`),
|
|
223
|
+
"src/my-fragment.tsx": declareFragment(gql`
|
|
224
|
+
fragment RecipientFragment on Recipient {
|
|
225
|
+
id
|
|
226
|
+
name
|
|
227
|
+
}
|
|
228
|
+
`),
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
await using server = await setupServer({
|
|
232
|
+
plugins: [apolloClientAiApps({ targets: ["mcp"] })],
|
|
233
|
+
});
|
|
234
|
+
await server.listen();
|
|
235
|
+
|
|
236
|
+
const manifest = readManifestFile();
|
|
237
|
+
expect(manifest).toMatchInlineSnapshot(`
|
|
238
|
+
{
|
|
239
|
+
"appVersion": "1.0.0",
|
|
240
|
+
"csp": {
|
|
241
|
+
"connectDomains": [],
|
|
242
|
+
"frameDomains": [],
|
|
243
|
+
"redirectDomains": [],
|
|
244
|
+
"resourceDomains": [],
|
|
245
|
+
},
|
|
246
|
+
"format": "apollo-ai-app-manifest",
|
|
247
|
+
"hash": "abc",
|
|
248
|
+
"operations": [
|
|
249
|
+
{
|
|
250
|
+
"body": "query HelloWorldQuery {
|
|
251
|
+
greeting {
|
|
252
|
+
message
|
|
253
|
+
recipient {
|
|
254
|
+
...RecipientFragment
|
|
255
|
+
...OtherRecipientFragment
|
|
256
|
+
__typename
|
|
257
|
+
}
|
|
258
|
+
__typename
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
fragment OtherRecipientFragment on Recipient {
|
|
263
|
+
name
|
|
264
|
+
__typename
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
fragment RecipientFragment on Recipient {
|
|
268
|
+
id
|
|
269
|
+
name
|
|
270
|
+
__typename
|
|
271
|
+
}",
|
|
272
|
+
"id": "c65cb5ec2dc76bbfa992cd2a98c05ab3f909349f3f1478e608a7f16ae29bdd4a",
|
|
273
|
+
"name": "HelloWorldQuery",
|
|
274
|
+
"prefetch": false,
|
|
275
|
+
"tools": [
|
|
276
|
+
{
|
|
277
|
+
"description": "This is an awesome tool!",
|
|
278
|
+
"name": "hello-world",
|
|
279
|
+
},
|
|
280
|
+
],
|
|
281
|
+
"type": "query",
|
|
282
|
+
"variables": {
|
|
283
|
+
"name": "string",
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
"resource": "http://localhost:3333",
|
|
288
|
+
"version": "1",
|
|
289
|
+
}
|
|
290
|
+
`);
|
|
291
|
+
});
|
|
292
|
+
|
|
124
293
|
test("does not write to dev application manifest file when using a build command", async () => {
|
|
125
294
|
vol.fromJSON({
|
|
126
295
|
"package.json": mockPackageJson(),
|
|
@@ -289,7 +458,7 @@ describe("operations", () => {
|
|
|
289
458
|
});
|
|
290
459
|
await server.listen();
|
|
291
460
|
}).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
292
|
-
`[Error: Found
|
|
461
|
+
`[Error: Found unsupported operation type 'subscription'. Only queries and mutations are supported.]`
|
|
293
462
|
);
|
|
294
463
|
});
|
|
295
464
|
|
|
@@ -1461,6 +1630,18 @@ function declareOperation(operation: DocumentNode) {
|
|
|
1461
1630
|
return `const ${varName} = gql\`\n${print(operation)}\n\``;
|
|
1462
1631
|
}
|
|
1463
1632
|
|
|
1633
|
+
function declareFragment(fragment: DocumentNode) {
|
|
1634
|
+
const definition = getMainDefinition(fragment);
|
|
1635
|
+
invariant(
|
|
1636
|
+
definition.kind === Kind.FRAGMENT_DEFINITION,
|
|
1637
|
+
"declareFragment must receive a fragment definition"
|
|
1638
|
+
);
|
|
1639
|
+
|
|
1640
|
+
const name = definition.name.value;
|
|
1641
|
+
const varName = name.replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase();
|
|
1642
|
+
return `const ${varName} = gql\`\n${print(fragment)}\n\``;
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1464
1645
|
function mockPackageJson(config?: Record<string, unknown>) {
|
|
1465
1646
|
return JSON.stringify({ version: "1.0.0", ...config });
|
|
1466
1647
|
}
|
|
@@ -14,7 +14,7 @@ import { glob } from "glob";
|
|
|
14
14
|
import { print } from "@apollo/client/utilities";
|
|
15
15
|
import { removeDirectivesFromDocument } from "@apollo/client/utilities/internal";
|
|
16
16
|
import { of } from "rxjs";
|
|
17
|
-
import { Kind,
|
|
17
|
+
import { Kind, OperationTypeNode, parse } from "graphql";
|
|
18
18
|
import {
|
|
19
19
|
getArgumentValue,
|
|
20
20
|
getDirectiveArgument,
|
|
@@ -30,6 +30,7 @@ import { explorer } from "./utilities/config.js";
|
|
|
30
30
|
import type { ApolloClientAiAppsConfig } from "../config/index.js";
|
|
31
31
|
import { ApolloClientAiAppsConfigSchema } from "../config/schema.js";
|
|
32
32
|
import { z } from "zod";
|
|
33
|
+
import { createFragmentRegistry } from "@apollo/client/cache";
|
|
33
34
|
|
|
34
35
|
export declare namespace apolloClientAiApps {
|
|
35
36
|
export type Target = ApolloClientAiAppsConfig.AppTarget;
|
|
@@ -66,7 +67,7 @@ export function devTarget(target: string | undefined) {
|
|
|
66
67
|
interface FileCache {
|
|
67
68
|
file: string;
|
|
68
69
|
hash: string;
|
|
69
|
-
|
|
70
|
+
sources: DocumentNode[];
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
export function apolloClientAiApps(
|
|
@@ -79,6 +80,8 @@ export function apolloClientAiApps(
|
|
|
79
80
|
let packageJson!: Record<string, any>;
|
|
80
81
|
let config!: ResolvedConfig;
|
|
81
82
|
|
|
83
|
+
const fragments = createFragmentRegistry();
|
|
84
|
+
|
|
82
85
|
invariant(
|
|
83
86
|
Array.isArray(targets) && targets.length > 0,
|
|
84
87
|
"The `targets` option must be a non-empty array"
|
|
@@ -90,7 +93,7 @@ export function apolloClientAiApps(
|
|
|
90
93
|
);
|
|
91
94
|
|
|
92
95
|
const client = new ApolloClient({
|
|
93
|
-
cache: new InMemoryCache(),
|
|
96
|
+
cache: new InMemoryCache({ fragments }),
|
|
94
97
|
link: processQueryLink,
|
|
95
98
|
});
|
|
96
99
|
|
|
@@ -106,52 +109,57 @@ export function apolloClientAiApps(
|
|
|
106
109
|
{ name: "graphql-tag", identifier: "gql" },
|
|
107
110
|
{ name: "@apollo/client", identifier: "gql" },
|
|
108
111
|
],
|
|
109
|
-
}).map((source) => (
|
|
110
|
-
node: parse(source.body),
|
|
111
|
-
file,
|
|
112
|
-
location: source.locationOffset,
|
|
113
|
-
}));
|
|
112
|
+
}).map((source) => parse(source.body));
|
|
114
113
|
|
|
115
|
-
|
|
116
|
-
for (const source of sources) {
|
|
117
|
-
const type = (
|
|
118
|
-
source.node.definitions.find(
|
|
119
|
-
(d) => d.kind === "OperationDefinition"
|
|
120
|
-
) as OperationDefinitionNode
|
|
121
|
-
).operation;
|
|
122
|
-
|
|
123
|
-
let result;
|
|
124
|
-
if (type === "query") {
|
|
125
|
-
result = await client.query({
|
|
126
|
-
query: source.node,
|
|
127
|
-
fetchPolicy: "no-cache",
|
|
128
|
-
});
|
|
129
|
-
} else if (type === "mutation") {
|
|
130
|
-
result = await client.mutate({
|
|
131
|
-
mutation: source.node,
|
|
132
|
-
fetchPolicy: "no-cache",
|
|
133
|
-
});
|
|
134
|
-
} else {
|
|
135
|
-
throw new Error(
|
|
136
|
-
"Found an unsupported operation type. Only Query and Mutation are supported."
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
operations.push(result.data as ManifestOperation);
|
|
140
|
-
}
|
|
114
|
+
fragments.register(...sources);
|
|
141
115
|
|
|
142
116
|
cache.set(file, {
|
|
143
117
|
file: file,
|
|
144
118
|
hash: fileHash,
|
|
145
|
-
|
|
119
|
+
sources,
|
|
146
120
|
});
|
|
147
121
|
}
|
|
148
122
|
|
|
149
123
|
async function generateManifest(environment?: Environment) {
|
|
150
124
|
const appsConfig = await getAppsConfig();
|
|
151
|
-
const
|
|
152
|
-
(entry) => entry.
|
|
125
|
+
const sources = Array.from(cache.values()).flatMap(
|
|
126
|
+
(entry) => entry.sources
|
|
153
127
|
);
|
|
154
128
|
|
|
129
|
+
const operations: ManifestOperation[] = [];
|
|
130
|
+
for (const source of sources) {
|
|
131
|
+
const operationDef = source.definitions.find(
|
|
132
|
+
(d) => d.kind === Kind.OPERATION_DEFINITION
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
if (!operationDef) continue;
|
|
136
|
+
|
|
137
|
+
switch (operationDef.operation) {
|
|
138
|
+
case OperationTypeNode.QUERY: {
|
|
139
|
+
const result = await client.query<ManifestOperation>({
|
|
140
|
+
query: source,
|
|
141
|
+
fetchPolicy: "no-cache",
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
operations.push(result.data!);
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case OperationTypeNode.MUTATION: {
|
|
148
|
+
const result = await client.mutate<ManifestOperation>({
|
|
149
|
+
mutation: source,
|
|
150
|
+
fetchPolicy: "no-cache",
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
operations.push(result.data!);
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
default:
|
|
157
|
+
throw new Error(
|
|
158
|
+
`Found unsupported operation type '${operationDef.operation}'. Only queries and mutations are supported.`
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
155
163
|
invariant(
|
|
156
164
|
operations.filter((o) => o.prefetch).length <= 1,
|
|
157
165
|
"Found multiple operations marked as `@prefetch`. You can only mark 1 operation with `@prefetch`."
|
|
@@ -192,9 +200,7 @@ export function apolloClientAiApps(
|
|
|
192
200
|
name: appsConfig.name ?? packageJson.name,
|
|
193
201
|
description: appsConfig.description ?? packageJson.description,
|
|
194
202
|
hash: createHash("sha256").update(Date.now().toString()).digest("hex"),
|
|
195
|
-
operations
|
|
196
|
-
(entry) => entry.operations
|
|
197
|
-
),
|
|
203
|
+
operations,
|
|
198
204
|
resource,
|
|
199
205
|
csp: {
|
|
200
206
|
connectDomains: appsConfig.csp?.connectDomains ?? [],
|