{"_id":"@kattebak/graphql-sdk-emitter","_rev":"3-eeeeeacd6b6c099dc9bce3227402dda6","name":"@kattebak/graphql-sdk-emitter","dist-tags":{"latest":"1.2.0"},"versions":{"1.0.0":{"name":"@kattebak/graphql-sdk-emitter","version":"1.0.0","keywords":["graphql","sdk","codegen","typescript","appsync","sigv4","cognito"],"license":"MIT","_id":"@kattebak/graphql-sdk-emitter@1.0.0","maintainers":[{"name":"mvhenten","email":"matthijs@ischen.nl"}],"homepage":"https://github.com/kattebak/graphql-sdk-emitter#readme","bugs":{"url":"https://github.com/kattebak/graphql-sdk-emitter/issues"},"bin":{"graphql-sdk-emitter":"bin/graphql-sdk-emitter.js"},"dist":{"shasum":"b12368b8f9d71f134d56c910ee916604a47cfcfd","tarball":"https://registry.npmjs.org/@kattebak/graphql-sdk-emitter/-/graphql-sdk-emitter-1.0.0.tgz","fileCount":52,"integrity":"sha512-BevdKvN+lPAU3p9IMzrtbo8DHcGZ7D2KmqO9EYm7k1sGYyivpl/GZFyX5ZTnUPjnHvuN95otxmXoMj1QL+N5ag==","signatures":[{"sig":"MEUCIQCQSj9FfKathtubH8ouB+lgNp0QAaeT2zptPPhPvPrzgAIgcn7+NEH8WlBeYa4I/bKEn8z90wOwB6RGpSATSqQWbFU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56317},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./auth":{"types":"./dist/auth/index.d.ts","default":"./dist/auth/index.js"},"./runtime":{"types":"./dist/runtime/index.d.ts","default":"./dist/runtime/index.js"}},"gitHead":"c22615a6cd6cd8f36ef5d76570189521c194abe2","scripts":{"fix":"biome check --write","lint":"biome check","test":"npm run build && npm run lint && npm run test:unit","build":"tsc -p tsconfig.build.json","watch":"tsc -p tsconfig.build.json --watch","test:unit":"node --test --import=tsx 'src/**/*.test.ts'","prepublishOnly":"npm run build"},"_npmUser":{"name":"mvhenten","email":"matthijs@ischen.nl"},"repository":{"url":"git+https://github.com/kattebak/graphql-sdk-emitter.git","type":"git"},"_npmVersion":"10.9.8","description":"Generate a typed TypeScript SDK from a GraphQL SDL with pluggable auth (SigV4, Cognito bearer, API key)","directories":{},"_nodeVersion":"24.14.1","dependencies":{"graphql":"^16.9.0","aws4fetch":"^1.0.20","graphql-request":"^7.1.2","@graphql-codegen/cli":"^5.0.3","@graphql-codegen/typescript":"^4.1.2","@graphql-codegen/typescript-operations":"^4.4.0","@graphql-codegen/typescript-graphql-request":"^6.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","typescript":"^5.9.3","@types/node":"^22.18.11","@biomejs/biome":"^2.3.7","semantic-release":"^24.2.0"},"peerDependencies":{"graphql":"^16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/graphql-sdk-emitter_1.0.0_1777934844735_0.5698686883137611","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@kattebak/graphql-sdk-emitter","version":"1.1.0","keywords":["graphql","sdk","codegen","typescript","appsync","sigv4","cognito"],"license":"MIT","_id":"@kattebak/graphql-sdk-emitter@1.1.0","maintainers":[{"name":"mvhenten","email":"matthijs@ischen.nl"}],"homepage":"https://github.com/kattebak/graphql-sdk-emitter#readme","bugs":{"url":"https://github.com/kattebak/graphql-sdk-emitter/issues"},"bin":{"graphql-sdk-emitter":"bin/graphql-sdk-emitter.js"},"dist":{"shasum":"c199a45bff0236f4c5e4e2927731d30cb40e77ca","tarball":"https://registry.npmjs.org/@kattebak/graphql-sdk-emitter/-/graphql-sdk-emitter-1.1.0.tgz","fileCount":52,"integrity":"sha512-fyvEqfUfzDg2u0FVSsHGJ2GA6A19BX25ly+tEZkRHz3xJpbhyZqfj13QhzO7Pa1Bw6Dis80BVCfrEwqzCCtQCQ==","signatures":[{"sig":"MEQCIEQsyP4EFHHD0zFMSLK5oDHcDZzsP6f/Zv5ivxpoi18GAiBnmnD5U8j4qboyny9QlUd8DwH91e3Vi4Sy78JbpbHWLA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61094},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./auth":{"types":"./dist/auth/index.d.ts","default":"./dist/auth/index.js"},"./runtime":{"types":"./dist/runtime/index.d.ts","default":"./dist/runtime/index.js"}},"gitHead":"0de70fd1cee3e95b0fb8bbaf0a78814cca4fcbc2","scripts":{"fix":"biome check --write","lint":"biome check","test":"npm run build && npm run lint && npm run test:unit","build":"tsc -p tsconfig.build.json","watch":"tsc -p tsconfig.build.json --watch","test:unit":"node --test --import=tsx 'src/**/*.test.ts'","prepublishOnly":"npm run build"},"_npmUser":{"name":"mvhenten","email":"matthijs@ischen.nl"},"repository":{"url":"git+https://github.com/kattebak/graphql-sdk-emitter.git","type":"git"},"_npmVersion":"10.9.8","description":"Generate a typed TypeScript SDK from a GraphQL SDL with pluggable auth (SigV4, Cognito bearer, API key)","directories":{},"_nodeVersion":"24.14.1","dependencies":{"graphql":"^16.9.0","aws4fetch":"^1.0.20","graphql-request":"^7.1.2","@graphql-codegen/cli":"^5.0.3","@graphql-codegen/typescript":"^4.1.2","@graphql-codegen/import-types-preset":"^3.0.0","@graphql-codegen/typescript-operations":"^4.4.0","@graphql-codegen/typescript-graphql-request":"^6.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","typescript":"^5.9.3","@types/node":"^22.18.11","@biomejs/biome":"^2.3.7","semantic-release":"^24.2.0"},"peerDependencies":{"graphql":"^16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/graphql-sdk-emitter_1.1.0_1777961068412_0.694792337663191","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@kattebak/graphql-sdk-emitter","version":"1.2.0","description":"Generate a typed TypeScript SDK from a GraphQL SDL with pluggable auth (SigV4, Cognito bearer, API key)","keywords":["graphql","sdk","codegen","typescript","appsync","sigv4","cognito"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/kattebak/graphql-sdk-emitter.git"},"bugs":{"url":"https://github.com/kattebak/graphql-sdk-emitter/issues"},"homepage":"https://github.com/kattebak/graphql-sdk-emitter#readme","type":"module","main":"dist/index.js","types":"dist/index.d.ts","bin":{"graphql-sdk-emitter":"bin/graphql-sdk-emitter.js"},"publishConfig":{"access":"public"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./runtime":{"types":"./dist/runtime/index.d.ts","default":"./dist/runtime/index.js"},"./auth":{"types":"./dist/auth/index.d.ts","default":"./dist/auth/index.js"}},"scripts":{"fix":"biome check --write","lint":"biome check","build":"tsc -p tsconfig.build.json","watch":"tsc -p tsconfig.build.json --watch","test":"npm run build && npm run lint && npm run test:unit","test:unit":"node --test --import=tsx 'src/**/*.test.ts'","prepublishOnly":"npm run build"},"dependencies":{"@graphql-codegen/cli":"^5.0.3","@graphql-codegen/import-types-preset":"^3.0.0","@graphql-codegen/typescript":"^4.1.2","@graphql-codegen/typescript-graphql-request":"^6.2.0","@graphql-codegen/typescript-operations":"^4.4.0","aws4fetch":"^1.0.20","graphql":"^16.9.0","graphql-request":"^7.1.2"},"peerDependencies":{"graphql":"^16.0.0"},"devDependencies":{"@biomejs/biome":"^2.3.7","@types/node":"^22.18.11","semantic-release":"^24.2.0","tsx":"^4.20.5","typescript":"^5.9.3"},"_id":"@kattebak/graphql-sdk-emitter@1.2.0","gitHead":"1084d111592e8388c41ce007d77854589531a6fa","_nodeVersion":"24.14.1","_npmVersion":"10.9.8","dist":{"integrity":"sha512-0YVx+SpxT+ADBk17fwixkNzvPRv0Hm9+z6zHSraOWrp8Lz0K1xwbZsPclDv5JvbA128taaD0igLZzlDzirOr4g==","shasum":"b0c3aba18a69716c26f2563ea0512d77702ad8af","tarball":"https://registry.npmjs.org/@kattebak/graphql-sdk-emitter/-/graphql-sdk-emitter-1.2.0.tgz","fileCount":52,"unpackedSize":68300,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD7v0yN/hAbZIHrqRYNZVCaBkt2PcmLjj/P6o5UKfjJcgIga5Z7H6uk6qrI7bBYVHB8ZdeK+HuoNDKRYDMru03EDK0="}]},"_npmUser":{"name":"mvhenten","email":"matthijs@ischen.nl"},"directories":{},"maintainers":[{"name":"mvhenten","email":"matthijs@ischen.nl"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/graphql-sdk-emitter_1.2.0_1778309615486_0.8495096242321933"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-04T22:47:24.613Z","modified":"2026-05-09T06:53:35.788Z","1.0.0":"2026-05-04T22:47:24.912Z","1.1.0":"2026-05-05T06:04:28.572Z","1.2.0":"2026-05-09T06:53:35.639Z"},"bugs":{"url":"https://github.com/kattebak/graphql-sdk-emitter/issues"},"license":"MIT","homepage":"https://github.com/kattebak/graphql-sdk-emitter#readme","keywords":["graphql","sdk","codegen","typescript","appsync","sigv4","cognito"],"repository":{"type":"git","url":"git+https://github.com/kattebak/graphql-sdk-emitter.git"},"description":"Generate a typed TypeScript SDK from a GraphQL SDL with pluggable auth (SigV4, Cognito bearer, API key)","maintainers":[{"name":"mvhenten","email":"matthijs@ischen.nl"}],"readme":"# @kattebak/graphql-sdk-emitter\n\nGenerate a typed TypeScript SDK from a GraphQL SDL.\n\n- One typed function per operation. No query strings in your application code.\n- Pluggable auth providers: SigV4 (AppSync IAM), Cognito bearer, API key. Bring your own.\n- Cursor-pagination helpers as async iterators.\n- LLM-friendly `manifest.json` describing every operation.\n- Optional smart filter-object builder for nested input types.\n- Framework-agnostic. No React. No global singletons.\n\nBuilt on top of `graphql-codegen` (`typescript`, `typescript-operations`, `typescript-graphql-request`) and `graphql-request`.\n\n## Install\n\n```bash\nnpm install --save-dev @kattebak/graphql-sdk-emitter\nnpm install graphql graphql-request\n```\n\n`graphql` is a peer dependency. `aws4fetch` ships in this package and is only loaded when you import `SigV4Auth`.\n\n## Quick start\n\nGiven a `schema.graphql` and a folder of `.graphql` operations:\n\n```bash\nnpx graphql-sdk-emitter \\\n\t--schema ./schema.graphql \\\n\t--output ./src/generated \\\n\t--operations 'src/operations/*.graphql'\n```\n\nThis writes:\n\n```\nsrc/generated/\n\ttypes.ts        # GraphQL types as TypeScript\n\tsdk.ts          # getSdk(client) with one method per operation\n\tfilters.ts      # buildXxxFilter helpers (optional, on by default)\n\tmanifest.json   # machine-readable operation index\n\tindex.ts        # re-exports everything\n```\n\nIn your application:\n\n```typescript\nimport { GraphQLClient } from \"graphql-request\";\nimport { ApiKeyAuth } from \"@kattebak/graphql-sdk-emitter\";\nimport { getSdk } from \"./generated\";\n\nconst auth = new ApiKeyAuth({ apiKey: process.env.API_KEY! });\nconst client = new GraphQLClient(url, { fetch: auth.wrap(fetch) });\nconst sdk = getSdk(client);\n\nconst r = await sdk.SearchBooks({ query: \"tolkien\", first: 20 });\n```\n\n## Programmatic codegen\n\n```typescript\nimport { generateSdk } from \"@kattebak/graphql-sdk-emitter\";\n\nawait generateSdk({\n\tschema: \"./schema.graphql\",\n\toutput: \"./src/generated\",\n\toperations: \"./src/operations/*.graphql\", // optional\n\temitFilterBuilder: true,                  // default true\n\temitManifest: true,                       // default true\n});\n```\n\nIf you skip `operations`, the emitter still produces `types.ts` and `manifest.json` so you have typed shapes and a discoverable operation index, but no `getSdk()` runtime.\n\n## Auth providers\n\nAll three providers implement the same `AuthProvider` interface:\n\n```typescript\ninterface AuthProvider {\n\twrap(fetch: FetchFn): FetchFn;\n}\n```\n\nYou hand the wrapped fetch to `GraphQLClient`. Implement your own provider by writing one method.\n\n### SigV4 (AppSync with IAM)\n\n```typescript\nimport { SigV4Auth } from \"@kattebak/graphql-sdk-emitter\";\n\nconst auth = new SigV4Auth({\n\tcredentials: { accessKeyId, secretAccessKey, sessionToken },\n\tregion: \"us-east-1\",\n\tservice: \"appsync\", // default\n});\nconst client = new GraphQLClient(url, { fetch: auth.wrap(fetch) });\n```\n\n`credentials` accepts a `() => Credentials | Promise<Credentials>` provider for refresh.\n\n### Cognito bearer\n\n```typescript\nimport { CognitoBearerAuth } from \"@kattebak/graphql-sdk-emitter\";\n\nconst auth = new CognitoBearerAuth({\n\ttoken: async () => session.getIdToken().getJwtToken(),\n});\n```\n\n### API key\n\n```typescript\nimport { ApiKeyAuth } from \"@kattebak/graphql-sdk-emitter\";\n\nconst auth = new ApiKeyAuth({ apiKey: process.env.API_KEY! });\n// header defaults to x-api-key; override with headerName.\n```\n\n### Custom\n\n```typescript\nimport type { AuthProvider, FetchFn } from \"@kattebak/graphql-sdk-emitter\";\n\nclass MyAuth implements AuthProvider {\n\twrap(fetch: FetchFn): FetchFn {\n\t\treturn async (input, init) => {\n\t\t\tconst headers = new Headers(init?.headers);\n\t\t\theaders.set(\"x-tenant\", \"acme\");\n\t\t\treturn fetch(input, { ...init, headers });\n\t\t};\n\t}\n}\n```\n\n## Pagination\n\nTwo helpers walk Relay-style cursored connections. Pick by what you need per page.\n\n**`paginatePages`** — yields the full operation result per page. Types infer from the operation; no generics required.\n\n```typescript\nimport { paginatePages } from \"@kattebak/graphql-sdk-emitter\";\n\nfor await (const page of paginatePages(sdk.SearchBooks, { query: \"tolkien\" }, { pageSize: 50 })) {\n\tconsole.log(page.searchBooks.totalCount);\n\tfor (const edge of page.searchBooks.edges) {\n\t\tconsole.log(edge.node.bookId, edge.node.title);\n\t}\n}\n```\n\n**`paginate` / `collect`** — yield a flat array of nodes per page, useful when you only need the nodes. Requires explicit `TNode` to type the result.\n\n```typescript\nimport { paginate, collect } from \"@kattebak/graphql-sdk-emitter\";\n\ntype Book = { bookId: string; title: string };\n\nfor await (const nodes of paginate<{ query: string }, unknown, Book>(\n\tsdk.SearchBooks,\n\t{ query: \"tolkien\" },\n)) {\n\tfor (const node of nodes) console.log(node.title);\n}\n\nconst all = await collect<{ query: string }, unknown, Book>(sdk.SearchBooks, { query: \"tolkien\" });\n```\n\nAll three auto-detect the connection inside the response (first object with a `pageInfo` field). For deeply nested or ambiguous responses pass `connectionPath: [\"data\", \"wrapper\", \"results\"]`. They stop when `hasNextPage` is false, when `endCursor` does not advance, or when `maxPages` is reached.\n\n## Manifest\n\nThe emitter writes a `manifest.json` next to your generated code:\n\n```json\n{\n\t\"version\": 1,\n\t\"generatedAt\": \"2026-01-01T00:00:00.000Z\",\n\t\"operations\": [\n\t\t{\n\t\t\t\"name\": \"searchBooks\",\n\t\t\t\"kind\": \"query\",\n\t\t\t\"description\": \"Search the catalogue by free-text query.\",\n\t\t\t\"parameters\": [\n\t\t\t\t{ \"name\": \"query\", \"type\": \"String\", \"required\": false },\n\t\t\t\t{ \"name\": \"filter\", \"type\": \"BookFilter\", \"required\": false, \"description\": \"Structured filter.\" }\n\t\t\t],\n\t\t\t\"returns\": \"BookConnection!\"\n\t\t}\n\t]\n}\n```\n\nDescriptions come from SDL `\"\"\"...\"\"\"` doc comments. Use this as an LLM-friendly entry point or to drive ad-hoc tooling.\n\n## Filter builder\n\nFor input types whose name matches `Filter`, `Where`, or `Condition` (or that contain `and`/`or`/`not` combinators), the emitter writes a typed identity helper in `filters.ts`:\n\n```typescript\nimport { buildBookFilter } from \"./generated/filters\";\n\nconst filter = buildBookFilter({\n\tor: [\n\t\t{ title: { contains: \"tolkien\" } },\n\t\t{ author: { contains: \"le guin\" } },\n\t],\n});\n```\n\nThe helper exists to give you autocomplete and type-checking on nested filter shapes without hand-typing the input type.\n\n## React + react-query\n\nThis package is framework-agnostic. To pair with `@tanstack/react-query`, write your own thin wrapper:\n\n```typescript\nimport { useQuery } from \"@tanstack/react-query\";\n\nexport function useSearchBooks(args: SearchBooksQueryVariables) {\n\treturn useQuery({\n\t\tqueryKey: [\"searchBooks\", args],\n\t\tqueryFn: () => sdk.SearchBooks(args),\n\t});\n}\n```\n\n## CLI\n\n```\ngraphql-sdk-emitter --schema <path> --output <dir> [options]\n\n  -s, --schema       Path to GraphQL SDL file (required)\n  -o, --output       Output directory (required)\n  -d, --operations   Path or glob to .graphql operation documents\n      --no-filters   Skip filter builder emission\n      --no-manifest  Skip operations manifest emission\n  -h, --help         Show help\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}