### Install Vitest Examples Plugin Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Install the plugin as a development dependency using pnpm. ```bash pnpm add -D @jasonkuhrt/vitest-plugin-examples ``` -------------------------------- ### Setup Pokemon GraphQL Schema Source: https://github.com/graffle-js/graffle/blob/main/website/content/examples/index.md Starts a local Pokemon GraphQL schema server. This is a prerequisite for many of the provided examples. ```sh pnpm graphql-try pokemon ``` -------------------------------- ### Examples Plugin Usage Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Demonstrates how to add the examples plugin to your Vitest configuration. ```typescript import { examplesPlugin } from 'vite-plugin-examples' export default defineConfig({ plugins: [ examplesPlugin({ // ... plugin configuration }), ], }) ``` -------------------------------- ### Manual Test Setup with runExamples Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md For more control, use the lower-level `runExamples` API to execute examples and manually perform assertions. This allows for custom snapshot matching or other assertion logic. ```typescript import { runExamples } from '@jasonkuhrt/vitest-plugin-examples' import { expect, test } from 'vitest' test('examples', async () => { const results = await runExamples({ pattern: './*/*.ts', outputDir: './__outputs__', }) for (const result of results) { expect(result.encoded).toMatchSnapshot( `${result.file.group}/${result.file.name}`, ) } }, { timeout: 300000 }) ``` -------------------------------- ### Run Graffle Example Locally Source: https://github.com/graffle-js/graffle/blob/main/website/content/examples/index.md Installs and runs a Graffle example locally. This command scaffolds a new NodeJS project and executes the example immediately. ```sh npx graffle try ``` -------------------------------- ### Run All Examples Directly Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Executes all discovered examples and returns an array of their results. ```typescript import { runExamples } from 'vite-plugin-examples/test' const results = await runExamples({ // ... plugin configuration }) ``` -------------------------------- ### Run All Examples Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Creates a function that, when called, runs all discovered examples with the specified configuration and returns their results. ```typescript import { testExamples } from 'vite-plugin-examples/test' const runAllExamples = testExamples({ // ... plugin configuration }) // Later, to run them: // const results = await runAllExamples() ``` -------------------------------- ### Quick Start GraphQL Query Source: https://github.com/graffle-js/graffle/blob/main/website/content/index.md Demonstrates how to create a Graffle client, configure a transport, and send a GraphQL query. Ensure you have `graffle` and `graphql` installed, and use the `@next` tag for pre-release versions. ```typescript import { Graffle } from 'graffle' const graffle = Graffle .create() .transport({ url: 'https://countries.trevorblades.com/graphql' }) const data = await graffle.gql` query { countries(filter: { name: { in: ["Canada", "Germany", "Japan"] } }) { name capital emoji } } `.send() console.log(data) // ^? ``` -------------------------------- ### Run Single Example Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Executes a single example file specified by its relative path and returns its result. ```typescript import { runExample } from 'vite-plugin-examples/test' const result = await runExample('./path/to/example.ts', { // ... plugin configuration }) ``` -------------------------------- ### Discover Example Files Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Discovers all example files matching the configured patterns without executing them. ```typescript import { discoverExamples } from 'vite-plugin-examples/test' const exampleFiles = await discoverExamples({ // ... plugin configuration }) ``` -------------------------------- ### Setup and Usage of OpenTelemetry Extension Source: https://github.com/graffle-js/graffle/blob/main/website/content/examples/60_extension/opentelemetry.md Initialize the OpenTelemetry provider and register it. Then, create a Graffle instance and apply the OpenTelemetry extension to enable tracing for subsequent GraphQL requests. This example logs the traced spans to the console. ```ts // Our website uses Vitepress+Twoslash. Twoslash does not discover the generated Graffle modules. // Perhaps we can configure Twoslash to include them. Until we figure that out, we have to // explicitly import them like this. import './graffle/modules/global.js' import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base' import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node' import { OpenTelemetry } from 'graffle/extensions/opentelemetry' import { Graffle } from './graffle/_.js' // Setup Opentelemetry // 1. Initialize the OpenTelemetry provider // 2. Register the provider to make the OpenTelemetry API use it const exporter = new ConsoleSpanExporter() const processor = new SimpleSpanProcessor(exporter) const provider = new NodeTracerProvider({ spanProcessors: [processor], }) provider.register() const graffle = Graffle.create().use(OpenTelemetry()) const data = await graffle.gql('query { pokemons { name } }').$send() console.log(data) ``` -------------------------------- ### Expected Outputs Source: https://github.com/graffle-js/graffle/blob/main/website/content/examples/65_preset/minimal.md These are the expected console outputs when running the minimal preset example. ```txt Is the default preset true The current transport is http ``` -------------------------------- ### Install GraphQLSP Source: https://github.com/graffle-js/graffle/blob/main/website/content/guides/21_documents/50_lsp-setup.md Install the GraphQLSP package as a development dependency using npm. ```sh npm add -D @0no-co/graphqlsp ``` -------------------------------- ### Configure Vitest with Examples Plugin Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Configure Vitest to use the `examplesPlugin` by specifying the glob pattern for example files and the output directory for generated types and outputs. ```typescript import { examplesPlugin } from '@jasonkuhrt/vitest-plugin-examples' import { defineConfig } from 'vitest/config' export default defineConfig({ plugins: [ examplesPlugin({ pattern: './*/*.ts', outputDir: './__outputs__', }), ], // ... rest of your config }) ``` -------------------------------- ### BattleWild Example Output Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/document-builder/union.md This is an example of the output format for a 'BattleWild' event, showing the date, trainer, pokemons involved, and the result. ```text BattleWild on 1/1/2020 trainer: Ash with Pikachu vs wild pokemons: Squirtle, Bulbasaur result: pokemonsCaptured ``` -------------------------------- ### Install Graffle CLI Source: https://github.com/graffle-js/graffle/blob/main/website/content/guides/30_advanced/23_generator.md Command to install the Graffle CLI tool. ```bash pnpm add graffle ``` -------------------------------- ### Static Mutation Example Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/document-builder/static.detail.md This example demonstrates how to create a static mutation to add a new Pokémon with specified attributes. ```APIDOC ## Static Mutation Example ### Description This example shows how to construct a static mutation to add a new Pokémon to the system. It includes all required fields for a new Pokémon entry. ### Method `gql().mutation()` ### Endpoint N/A (SDK method) ### Parameters #### Mutation Arguments - **name** (String!) - Required - The name of the Pokémon. - **type** (PokemonType!) - Required - The type of the Pokémon. - **hp** (Int) - Optional - The hit points of the Pokémon. - **attack** (Int) - Optional - The attack power of the Pokémon. - **defense** (Int) - Optional - The defense power of the Pokémon. ### Request Example ```javascript const newPokemon = await client.gql(mixedDoc).addNewPokemon({ name: 'Mew', type: 'electric', hp: 100, attack: 100, defense: 100, }); ``` ### Response #### Success Response (200) - **addPokemon** (object) - The result of the addPokemon mutation. - **name** (string) - The name of the newly added Pokémon. - **type** (string) - The type of the newly added Pokémon. #### Response Example ```json { "addPokemon": { "name": "Mew", "type": "electric" } } ``` ``` -------------------------------- ### GQL Query Response Example Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/gql/gql-document-node-typed.md This is an example of the expected JSON response structure for the 'pokemonByName' query. ```txt [ { name: 'Pikachu', hp: 35, attack: 55, defense: 40, trainer: { name: 'Ash' } } ] ``` -------------------------------- ### Use Convenience Test Function for Examples Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Use the `createExamplesTest` function to automatically run discovered examples, generate snapshots, and handle assertions. Configure timeouts, patterns, output directories, ignored files, and custom encoders. ```typescript import type { ExamplePath } from '@generated/test-examples' import { createExamplesTest } from '@jasonkuhrt/vitest-plugin-examples' import { test } from 'vitest' // Type-safe encoder configuration with autocomplete const encoders = { './examples/dynamic-timestamp.ts': (value: string) => { return value.replace(/timestamp: \d+/g, 'timestamp: MASKED') }, } satisfies Partial> createExamplesTest(test, { timeout: 300000, config: { pattern: './*/*.ts', outputDir: './__outputs__', ignore: ['./$', './__outputs__', './__tests__'], encoders, beforeEach: async () => { // Reset database before each example await db.reset() }, }, }) ``` -------------------------------- ### Static Query Example Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/document-builder/static.detail.md This example shows how to create a static query to fetch Pokémon data, including custom scalars like 'birthday'. ```APIDOC ## Static Query with Custom Scalar ### Description This example demonstrates fetching Pokémon data, including a custom date scalar, using a static query. This requires an SDDM-enabled client for proper encoding and decoding of the custom scalar. ### Method `gql().query()` ### Endpoint N/A (SDK method) ### Parameters #### Query Parameters - **name** (boolean) - Required - Selects the 'name' field. - **birthday** (boolean) - Required - Selects the 'birthday' field (custom Date scalar). ### Request Example ```javascript const doc = Graffle.query.pokemons({ name: true, birthday: true, // Custom Date scalar - requires SDDM for encoding/decoding }); ``` ### Response #### Success Response (200) - **pokemons** (array) - An array of Pokémon objects. - **name** (string) - The name of the Pokémon. - **birthday** (Date) - The birthday of the Pokémon (custom scalar). #### Response Example ```json { "pokemons": [ { "name": "Pikachu", "birthday": "YYYY-MM-DD" }, { "name": "Charizard", "birthday": "YYYY-MM-DD" } ] } ``` ``` -------------------------------- ### BattleRoyale Example Output Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/document-builder/union.md This is an example of the output format for a 'BattleRoyale' event, showing the date and the combatants and winner. ```text BattleRoyale on 1/13/1987 combatants: Ash, Misty winner: Ash ``` -------------------------------- ### Graffle Anyware Example Source: https://github.com/graffle-js/graffle/blob/main/website/content/guides/22_transport/20_request-anyware.md This example shows how to create a Graffle instance and apply an anyware to the request pipeline. It demonstrates intercepting hooks like encode, pack, and exchange, and how to modify input, use custom implementations for slots, and short-circuit the pipeline. ```ts import { Graffle } from 'graffle' // ---cut--- Graffle .create() .anyware(async ({ encode }) => { const { pack } = await encode() // [1] const { exchange } = await pack({ input: { ...pack.input /* ... */ }, // [2] }) const { unpack } = await exchange({ using: { fetch: async () => new Response() }, // [3] }) return unpack() // [4] // const { decode } = await unpack() // const result = await decode() // return result }) ``` -------------------------------- ### Install Graffle and graphql Source: https://github.com/graffle-js/graffle/blob/main/website/content/guides/20_getting-started.md Install the Graffle package using the 'next' distribution tag and its peer dependency 'graphql'. ```sh pnpm add graffle@next graphql ``` -------------------------------- ### Example GraphQL Response Source: https://github.com/graffle-js/graffle/blob/main/website/content/guides/20_getting-started.md This is the expected JSON output for the GraphQL query sent in the previous example. ```json { "countries": [ { "name": "Canada", "continent": { "name": "North America" } }, { "name": "Germany", "continent": { "name": "Europe" } }, { "name": "Japan", "continent": { "name": "Asia" } } ] } ``` -------------------------------- ### Example Output for Query Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/document-builder/interface.detail.md This shows the expected output when running the query with the provided data. ```text Sally ``` ```text 1080000 ``` ```text Dylan ``` ```text 3530000 ``` ```text Ash ``` ```text youth ``` ```text Misty ``` ```text teamRocketGrunt ``` ```text Brock ``` ```text youth ``` ```text Gary ``` ```text youth ``` ```text Pikachu ``` ```text electric ``` ```text Charizard ``` ```text fire ``` ```text Squirtle ``` ```text water ``` ```text Bulbasaur ``` ```text grass ``` ```text Caterpie ``` ```text bug ``` ```text Weedle ``` ```text bug ``` -------------------------------- ### BattleTrainer Example Output Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/document-builder/union.md This is an example of the output format for a 'BattleTrainer' event, showing the date and the trainers involved in the battle. ```text BattleTrainer on 1/1/2003 Ash vs Misty winner: Misty ``` -------------------------------- ### Capture Single Example Output Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Executes a single example file and captures its standard output, standard error, and exit code. ```typescript import { captureExample } from 'vite-plugin-examples/test' const result = await captureExample('./path/to/example.ts', { // ... plugin configuration }) ``` -------------------------------- ### Create Examples Test Case Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md A convenience function to create a complete test case for all discovered examples using Vitest. ```typescript import { createExamplesTest } from 'vite-plugin-examples/vitest' // Vitest configuration createExamplesTest(test, { config: { // ... plugin configuration }, timeout: 300000, testName: 'examples', }) ``` -------------------------------- ### Implementing a Typical Anyware-Based Graffle.js Extension Source: https://context7.com/graffle-js/graffle/llms.txt An example of a typical anyware-based extension pattern, demonstrating how to add middleware-like functionality to the request pipeline. This example logs request duration. ```typescript // Typical anyware-based extension pattern export const RequestLogger = Extension.create({ name: 'RequestLogger', }) const client = Graffle.create() .use(RequestLogger) .use(RetryExtension({ retries: 3 })) .use(MyLogger) // ordering matters — first added, first executed .anyware(async ({ encode }) => { const start = Date.now() const result = await encode() console.log(`Request took ${Date.now() - start}ms`) return result }) .transport({ url: 'https://api.example.com/graphql' }) ``` -------------------------------- ### Example tsconfig.json for Bundler Mode Source: https://github.com/graffle-js/graffle/blob/main/website/content/guides/30_advanced/23_generator.md This tsconfig.json example demonstrates the 'bundler' moduleResolution option, which influences how generated code imports are formatted. ```json // tsconfig.json { "compilerOptions": { "moduleResolution": "bundler" } } ``` -------------------------------- ### Query Reuse Example Source: https://github.com/graffle-js/graffle/blob/main/src/extensions/DocumentBuilder/documentation.md Demonstrates how to build a query once and execute it multiple times with different variables. ```APIDOC ## Query Reuse ### Description Build a query once, execute it multiple times: ### Method `run` (on a pre-defined query object) ### Endpoint N/A (SDK method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **variables** (object) - Required - An object containing the variables for the operation. ### Request Example ```ts const getPokemon = graffle.query.pokemonByName({ $: { name: $.String$NonNull }, name: true, hp: true, attack: true, defense: true, }) // Reuse across your application const pikachu = await getPokemon.run({ name: 'Pikachu' }) const charizard = await getPokemon.run({ name: 'Charizard' }) const mewtwo = await getPokemon.run({ name: 'Mewtwo' }) ``` ### Response #### Success Response (object) - **Result** (object) - The shape of the result is determined by the query definition. #### Response Example (Example depends on the specific query) ``` -------------------------------- ### Single File Type Check Example Source: https://github.com/graffle-js/graffle/blob/main/docs/guides/typescript-type-diagnostics.md An example of how to use the single file type check script for debugging. ```bash ./scripts/check-file-types.sh src/client/methods/transport.ts ``` -------------------------------- ### Example Output with Envelope Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/output/envelope.md This is an example of the JSON output when the envelope is enabled. It includes a `data` field containing the query results and a `response` field with metadata about the HTTP response. ```txt { data: { pokemons: [ { name: 'Pikachu' }, { name: 'Charizard' }, { name: 'Squirtle' }, { name: 'Bulbasaur' }, { name: 'Caterpie' }, { name: 'Weedle' } ] }, response: Response { status: 200, statusText: 'OK', headers: Headers { 'content-type': 'application/graphql-response+json; charset=utf-8', 'content-length': '142', date: 'Mon, 03 Nov 2025 02:29:54 GMT', connection: 'keep-alive', 'keep-alive': 'timeout=5' }, body: ReadableStream { locked: true, state: 'closed', supportsBYOB: true }, bodyUsed: true, ok: true, redirected: false, type: 'basic', url: 'http://localhost:3000/graphql' } } ``` -------------------------------- ### Install Opentelemetry API Dependency Source: https://github.com/graffle-js/graffle/blob/main/src/extensions/Opentelemetry/documentation.md Install the `@opentelemetry/api` package as a peer dependency for the Opentelemetry extension. This is a prerequisite for using the extension. ```sh pnpm add @opentelemetry/api ``` -------------------------------- ### Example JSON Output Source: https://github.com/graffle-js/graffle/blob/main/website/content/examples/55_document-builder/root-field.md This is the expected JSON output when querying the 'pokemons' root field for their names. ```json [ { "name": "Pikachu" }, { "name": "Charizard" }, { "name": "Squirtle" }, { "name": "Bulbasaur" }, { "name": "Caterpie" }, { "name": "Weedle" } ] ``` -------------------------------- ### Batch Operations Example Source: https://github.com/graffle-js/graffle/blob/main/src/extensions/DocumentBuilder/documentation.md Shows how to use `$batch` to query multiple fields with variables in a single operation. ```APIDOC ## Batch Operations ### Description Use `$batch` to query multiple fields with variables: ### Method `run` (on a batched query object) ### Endpoint N/A (SDK method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **variables** (object) - Required - An object containing the variables for the batched operation. ### Request Example ```ts const runner = graffle.query.$batch({ pokemonByName: { $: { name: $.String$NonNull }, name: true, type: true, }, trainers: { name: true, class: true, }, }) const result = await runner.run({ name: 'Pikachu' }) // { // pokemonByName: { name: 'Pikachu', type: 'ELECTRIC' }, // trainers: [...] // } ``` ### Response #### Success Response (object) - **Result** (object) - An object containing the results for each batched query. #### Response Example ```json { "pokemonByName": { "name": "Pikachu", "type": "ELECTRIC" }, "trainers": [ // ... trainer data ] } ``` ``` -------------------------------- ### Jump Start Graffle with Anyware Source: https://github.com/graffle-js/graffle/blob/main/website/content/examples/50_anyware/jump-start.md Use the `anyware` function to start Graffle operations from a specific hook, like `exchange`, skipping initial hooks such as `encode` and `pack`. This is useful for custom request modifications. ```ts // Our website uses Vitepress+Twoslash. Twoslash does not discover the generated Graffle modules. // Perhaps we can configure Twoslash to include them. Until we figure that out, we have to // explicitly import them like this. import './graffle/modules/global.js' import { Graffle } from 'graffle' Graffle .create() .transport({ url: `http://localhost:3000/graphql` }) // Notice how we **start** with the `exchange` hook, skipping the `encode` and `pack` hooks. .anyware(async ({ exchange }) => { // ^^^^^^^^ if (exchange.input.transportType !== `http`) return exchange() const mergedHeaders = new Headers(exchange.input.request.headers) mergedHeaders.set(`X-Custom-Header`, `123`) const { unpack } = await exchange({ input: { ...exchange.input, request: { ...exchange.input.request, headers: mergedHeaders, }, }, }) const { decode } = await unpack() const result = await decode() return result }) ``` -------------------------------- ### ExampleResult Interface Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Represents the result of executing a single example, including captured output and failure status. ```typescript interface ExampleResult { /** The example file that was executed */ file: ExampleFile /** Captured stdout output */ stdout: string /** Captured stderr output */ stderr: string /** Whether the example failed */ failed: boolean /** Exit code from the process */ exitCode: number | null /** Encoded output (after applying encoders and masking) */ encoded: string } ``` -------------------------------- ### Customize Error Type Identification (Gentime) Source: https://github.com/graffle-js/graffle/blob/main/src/extensions/SchemaErrors/documentation.md Customize the logic for identifying error types during generation. By default, objects starting with 'Error' are considered error types. This example shows how to match types starting with 'Foo'. ```typescript import { SchemaErrors } from 'graffle/extensions/schema-errors/gentime' import { Generator } from 'graffle/generator' export default Generator .configure() .use(SchemaErrors({ isErrorType: (type) => type.name.match(/^Foo/), })) ``` -------------------------------- ### Get Path to Node Source: https://github.com/graffle-js/graffle/blob/main/bundle-sizes/basic/bundle-visualization.html Returns an array of nodes representing the path from the root to a specified node, including the start and end nodes. ```javascript function node_path(end) { var start = this, ancestor = leastCommonAncestor(start, end), nodes = [start]; while (start !== ancestor) { start = start.parent; nodes.push(start); } var k = nodes.length; while (end !== ancestor) { nodes.splice(k, 0, end); end = end.parent; } return nodes; } ``` -------------------------------- ### Main Component for Bundle Visualization Setup Source: https://github.com/graffle-js/graffle/blob/main/bundle-sizes/minimal/bundle-visualization.html Sets up the main application logic for bundle visualization. It fetches data, manages state for size property and selected node, and computes node size multipliers based on selection. ```javascript const Main = () => { const { availableSizeProperties, rawHierarchy, getModuleSize, layout, data, } = q(StaticContext); const [sizeProperty, setSizeProperty] = h(availableSizeProperties[0]); const [selectedNode, setSelectedNode] = h(undefined); const { getModuleFilterMultiplier, setExcludeFilter, setIncludeFilter, } = useFilter(); console.time("getNodeSizeMultiplier"); const getNodeSizeMultiplier = F(() => { const selectedMultiplier = 1; // selectedSize < rootSize * increaseFactor ? (rootSize * increaseFactor) / selectedSize : rootSize / selectedSize; const nonSelectedMultiplier = 0; // 1 / selectedMultiplier if (selectedNode === undefined) { return () => 1; } else if (isModuleTree(selectedNode.data)) { const leaves = new Set(selectedNode.leaves().map((d) => d.data)); return (node) => { if (leaves.has(node)) { return selectedMultiplier; } return nonSelectedMultiplier; }; } else { return (node) => { if (node === selectedNode.data) { return selectedMultiplier; } return nonSelectedMultiplier; }; } }, [getModuleSize, rawHierarchy.data, selectedNode, sizeProperty]); console.timeEnd("getNodeSizeMultiplier"); console.time("root hierarchy compute"); // root here always be the same as rawHierarchy even after layouting const root = F(() => { const rootWithSizesAndSorted = rawHierarchy .sum((node) => { var _a; if (isModuleTree(node)) return 0; const meta = data.nodeMetas[data.nodeParts[node.uid].metaUid]; const bundleId = (_a = Object.entries(meta.moduleParts).find( ([bundleId, uid]) => uid == node.uid, )) ? _a[0] : undefined; const ownSize = getModuleSize(node, sizeProperty); const zoomMultiplier = getNodeSizeMultiplier(node); const filterMultiplier = getModuleFilterMultiplier( bundleId, meta, ); return ownSize * zoomMultiplier * filterMultiplier; }) .sort((a, b) => getModuleSize(a); return rootWithSizesAndSorted; }, [rawHierarchy, getNodeSizeMultiplier, getModuleFilterMultiplier, sizeProperty]); console.timeEnd("root hierarchy compute"); return u$1(g$1, { children: [ u$1("div", { className: "controls", children: availableSizeProperties.map((sizeProp) => u$1("button", { children: LABELS[sizeProp], onClick: () => { setSizeProperty(sizeProp); setSelectedNode(undefined); }, className: sizeProp === sizeProperty ? "selected" : "", }), ), }), u$1(Chart, { root: root, sizeProperty: sizeProperty, selectedNode: selectedNode, setSelectedNode: setSelectedNode, }), ], }); }; ``` -------------------------------- ### Mixed Query and Mutation Document Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/document-builder/static.detail.md Combine different types of operations, such as queries and mutations, within a single GraphQL document. This example shows a query for 'getPokemon' and the start of a 'addPokemon' mutation. ```typescript const mixedDoc = Graffle.gql({ query: { getPokemon: { pokemonByName: { $: { name: $('name').required() }, name: true, hp: true, attack: true, }, }, }, mutation: { ``` -------------------------------- ### Type-Safe Encoder Configuration Example Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Define type-safe encoders for masking dynamic values in example outputs. The generated `ExamplePath` type ensures that only valid example file paths can be used as keys. ```typescript import type { EncoderFunction, ExamplePath } from '@generated/test-examples' const encoders = { './examples/dynamic-values.ts': (output: string) => { return output.replace(/'x-timestamp', '\d+'/gi, `'x-timestamp', 'MASKED'`) }, // ✅ TypeScript autocomplete works here! // ✅ Typos are caught at compile time! } satisfies Partial> ``` -------------------------------- ### HTTP GET Request Details (Query) Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/transport-http/method-get.md When `methodMode` is set to `getReads`, queries are sent via HTTP GET, with the query parameters appended to the URL. This log shows the structure of such a GET request. ```text { methodMode: 'getReads', headers: Headers { accept: 'application/graphql-response+json; charset=utf-8, application/json; charset=utf-8', tenant: 'nano' }, method: 'get', url: { _tag: 'url', value: URL { href: 'http://localhost:3000/graphql?query=query+%7B+pokemonByName%28name%3A+%22Nano%22%29+%7B+hp+%7D+%7D', origin: 'http://localhost:3000', protocol: 'http:', username: '', password: '', host: 'localhost:3000', hostname: 'localhost', port: '3000', pathname: '/graphql', search: '?query=query+%7B+pokemonByName%28name%3A+%22Nano%22%29+%7B+hp+%7D+%7D', searchParams: URLSearchParams { 'query' => 'query { pokemonByName(name: "Nano") { hp } }' }, hash: '' } } } ``` -------------------------------- ### Initialize a new Node.js project Source: https://github.com/graffle-js/graffle/blob/main/website/content/guides/20_getting-started.md Use this command to create a new Node.js project if you don't have one already. ```sh pnpm init ``` -------------------------------- ### Example JSON Data Source: https://github.com/graffle-js/graffle/blob/main/examples/__outputs__/55_document-builder/document-builder_arguments.output.txt This is an example of the JSON data structure used with the Document Builder. ```json [ { "name": "Pikachu", "trainer": { "name": "Ash" } }, { "name": "Charizard", "trainer": { "name": "Ash" } } ] ``` -------------------------------- ### ExamplesPluginConfig Interface Source: https://github.com/graffle-js/graffle/blob/main/tools/vitest-plugin-examples/README.md Defines the configuration options for the examples plugin, including glob patterns, output directories, hooks, and executor settings. ```typescript interface ExamplesPluginConfig { /** * Glob pattern(s) to discover example files. * @default './examples/*\/*.ts' */ pattern?: string | string[] /** * Directory where output files will be written. * @default './examples/__outputs__' */ outputDir?: string /** * Patterns to ignore when discovering examples. * @default ['./examples/$', './examples/__outputs__', './examples/__tests__'] */ ignore?: string[] /** * Custom encoder functions for masking dynamic values in outputs. * Keys are example file paths (relative to project root). */ encoders?: Record /** * Hook called before each example is executed. */ beforeEach?: () => Promise | void /** * Hook called after each example is executed. */ afterEach?: () => Promise | void /** * Whether to apply dynamic value masking for test determinism. * @default true */ maskDynamicValues?: boolean /** * Execution configuration for running examples. */ executor?: { /** * Command to execute examples. * @default ['tsx'] */ command?: string[] /** * Working directory for command execution. * @default process.cwd() */ cwd?: string /** * Environment variables to pass to the command. * @default process.env */ env?: Record } /** * Type generation configuration. */ typeGeneration?: { /** * Whether to enable type generation. * @default true */ enabled?: boolean /** * Output directory for generated types. * @default 'node_modules/@generated/test-examples' */ outputDir?: string /** * Package name for generated types. * @default '@generated/test-examples' */ packageName?: string } } ``` -------------------------------- ### Example of Available and Unavailable Domain Methods Source: https://github.com/graffle-js/graffle/blob/main/website/content/guides/21_documents/45_domains.md Demonstrates which methods are available after configuring only domain-based access. Methods not defined as domains will not be accessible through the domain namespace. ```typescript // ✅ Available await graffle.pokemon.findByName({ name: 'Pikachu' }) // ❌ Not available await graffle.query.pokemonByName({ name: 'Pikachu' }) ``` -------------------------------- ### Create tsconfig.json and main.ts Source: https://github.com/graffle-js/graffle/blob/main/website/content/guides/20_getting-started.md Create the TypeScript configuration file and the main application file. ```sh touch tsconfig.json main.ts ``` -------------------------------- ### Displaying Slot Body Content Source: https://github.com/graffle-js/graffle/blob/main/examples/__outputs__/50_anyware/anyware_slot_slot-body__slot-body.output.txt This example shows how to display the content of a slot body. It assumes a 'trainers' array is available in the scope. ```html

No trainers found.

``` -------------------------------- ### Check Entire Project Types Source: https://github.com/graffle-js/graffle/blob/main/docs/guides/typescript-type-diagnostics.md Run this command to get quick statistics on type checking for the entire project. ```bash pnpm ts:check:stats ``` -------------------------------- ### Install tsx for Graffle Source: https://github.com/graffle-js/graffle/blob/main/website/content/guides/30_advanced/23_generator.md Command to install tsx as a development dependency, required for running Graffle with TypeScript configuration files on older Node.js versions or when preferred. ```bash pnpm add -D tsx ``` -------------------------------- ### Send your first GraphQL document with Graffle Source: https://github.com/graffle-js/graffle/blob/main/website/content/guides/20_getting-started.md This example demonstrates how to create a Graffle instance, configure a transport, send a query with variables, and log the response. Ensure your project is configured for ESM and has the correct TypeScript settings. ```ts // @filename: main.ts import { Graffle } from 'graffle' const graffle = Graffle .create() .transport({ url: 'https://countries.trevorblades.com/graphql', }) const data = await graffle.gql(` query myQuery ($filter: [String!]) { countries (filter: { name: { in: $filter } }) { name continent { name } } } `) .send({ filter: [`Canada`, `Germany`, `Japan`] }) console.log(data) // ^? ``` -------------------------------- ### Graffle Throws Extension Setup Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/extension/throws.detail.md Configure a Graffle instance with the Throws extension and trigger an error in the pipeline. This setup is useful for testing error handling mechanisms. ```typescript // Our website uses Vitepress+Twoslash. Twoslash does not discover the generated Graffle modules. // Perhaps we can configure Twoslash to include them. Until we figure that out, we have to // explicitly import them like this. import './graffle/modules/global.js' // ---cut--- import { Throws } from 'graffle/extensions/throws' import { Graffle } from './graffle/_.js' const pokemon = Graffle .create({ output: { defaults: { errorChannel: `return` } } }) .use(Throws) .anyware(({ encode: _ }) => { throw new Error(`Something went wrong.`) }) const result1 = await pokemon.query.pokemons({ name: true }) console.log(result1) await pokemon.throws().query.pokemons({ name: true }) // ^^^^^^ console.log(`This line will never be reached because of thrown error.`) ``` -------------------------------- ### Install Graffle and graphql peer dependency Source: https://context7.com/graffle-js/graffle/llms.txt Install Graffle and its graphql peer dependency using npm. Ensure your tsconfig.json uses Node16 or Bundler module resolution and your project is ESM. ```sh npm install graffle@next graphql ``` -------------------------------- ### Configure Graffle for HTTP GET Reads Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/transport-http/method-get.md Set `methodMode: 'getReads'` to enable HTTP GET for queries. Mutations will still use POST. This configuration is useful for optimizing read operations. ```typescript // Our website uses Vitepress+Twoslash. Twoslash does not discover the generated Graffle modules. // Perhaps we can configure Twoslash to include them. Until we figure that out, we have to // explicitly import them like this. import './graffle/modules/global.js' // ---cut--- import { Graffle } from 'graffle' const graffle = Graffle .create() .transport({ url: `http://localhost:3000/graphql`, methodMode: `getReads`, // [!code highlight] headers: { tenant: `nano` }, }) .anyware(async ({ exchange }) => { console.log(exchange.input.request) return await exchange() }) // The following request will use an HTTP POST method because it is // using a ``` -------------------------------- ### Configure HTTP Transport to Use GET for Reads Source: https://github.com/graffle-js/graffle/blob/main/src/extensions/TransportHttp/documentation.md Set `methodMode` to `getReads` to configure the HTTP transport to send read queries over HTTP GET requests instead of the default POST. ```typescript import { Graffle } from 'graffle' // --- Graffle .create() .transport({ methodMode: 'getReads', // ^^^^^^^^^^^^ }) ``` -------------------------------- ### Graffle Envelope Error Output Example Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/output/envelope-error.md This is an example of the structured error output generated by Graffle when envelope error reporting is enabled and an exception occurs. It includes contextual information about the error's origin. ```txt { errors: [ ContextualError: There was an error in the interceptor "anonymous" (use named functions to improve this error message) while running hook "encode". at runPipeline (/some/path/to/runPipeline.ts:XX:XX) at async (/some/path/to/runner.ts:XX:XX) at async Module.run (/some/path/to/run.ts:XX:XX) at async sendRequest (/some/path/to/send.ts:XX:XX) at async executeRootField (/some/path/to/requestMethods.ts:XX:XX) at async (/some/path/to/output_envelope_envelope-error__envelope-error.ts:XX:XX) { context: { hookName: 'encode', source: 'extension', interceptorName: 'anonymous' }, cause: Error: Something went wrong. at (/some/path/to/output_envelope_envelope-error__envelope-error.ts:XX:XX) at applyBody (/some/path/to/runner.ts:XX:XX) } ] } ``` -------------------------------- ### Querying Pokemons with Arguments Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/type-level/selection-sets.md Constructs a query to fetch pokemons, filtering by type and selecting specific fields like 'hp' and 'name'. This example demonstrates how to use argument types and execute a query. ```typescript const graffle = Graffle.create() const getPokemonsLike = (filter: Graffle.SelectionSets.Query.pokemons.$Arguments['filter']) => graffle.query.pokemons({ $: { filter }, hp: true, name: true, }) const pokemons = await getPokemonsLike({ $type: `water` }) // We don't lose any type safety. :) console.log(pokemons) ``` ```json [ { "hp": 44, "name": "Squirtle" } ] ``` -------------------------------- ### Example Output for Discriminated Union Query Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/document-builder/interface.md These text outputs represent the console logs generated by the TypeScript example when run with specific data. They illustrate the expected values for names, money, classes, and types. ```text Sally ``` ```text 1080000 ``` ```text Dylan ``` ```text 3530000 ``` ```text Ash ``` ```text youth ``` ```text Misty ``` ```text teamRocketGrunt ``` ```text Brock ``` ```text youth ``` ```text Gary ``` ```text youth ``` ```text Pikachu ``` ```text electric ``` ```text Charizard ``` ```text fire ``` ```text Squirtle ``` ```text water ``` ```text Bulbasaur ``` ```text grass ``` ```text Caterpie ``` ```text bug ``` ```text Weedle ``` ```text bug ``` -------------------------------- ### Inspecting Request Headers Source: https://github.com/graffle-js/graffle/blob/main/website/content/_snippets/examples/transport-http/headers.md Log the request headers to the console to verify they have been set correctly. This example shows the final headers sent with the HTTP request. ```text Headers { accept: 'application/graphql-response+json; charset=utf-8, application/json; charset=utf-8', 'content-type': 'application/json', 'x-from-raw': 'true', authorization: 'Bearer MY_TOKEN' } ```