{"_id":"@common-grants/cg-grants-gov","_rev":"5-e0ed2d971019db52dc07b5afaf709786","name":"@common-grants/cg-grants-gov","dist-tags":{"latest":"0.3.1"},"versions":{"0.1.0":{"name":"@common-grants/cg-grants-gov","version":"0.1.0","keywords":["common-grants","grants-gov","plugin","typescript","grants","opportunities"],"license":"CC0-1.0","_id":"@common-grants/cg-grants-gov@0.1.0","maintainers":[{"name":"jcrichlake","email":"jeff.crichlake@intuitial.com"},{"name":"billy.daly","email":"billy.daly@agile6.com"}],"homepage":"https://github.com/common-grants/ts-cg-grants-gov#readme","bugs":{"url":"https://github.com/common-grants/ts-cg-grants-gov/issues"},"dist":{"shasum":"a7e7633c3f1273257e113b0ddae982b724a9ae4e","tarball":"https://registry.npmjs.org/@common-grants/cg-grants-gov/-/cg-grants-gov-0.1.0.tgz","fileCount":6,"integrity":"sha512-K58zRzlRZHEEJHodUKPbJVeyA6WwOTOjezL0W3o78DPL1P7jSQIKWOhe16urh9Za9zQ4jvsPKHK+aj24QGOOWA==","signatures":[{"sig":"MEYCIQDlTmy9g2I1eQkrL8Heq/vAflX6LeTiY1r+vLkMEpYlMwIhAIY28iaWVZTx6XmlgmbrwMyS63PH2z4IX3CtUEpuyIcO","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@common-grants%2fcg-grants-gov@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":28131},"main":"./dist/index.js","_from":"file:common-grants-cg-grants-gov-0.1.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"ci":"pnpm run checks && pnpm run build && pnpm run test && pnpm audit","lint":"eslint . --fix","test":"vitest run","build":"tsc","checks":"pnpm run check:lint && pnpm run check:format && pnpm run check:types","format":"prettier --write .","check:lint":"eslint .","check:types":"tsc --noEmit","check:format":"prettier --check .","example:parse":"pnpm dlx tsx examples/parse-opportunity.ts","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"billy.daly","email":"billy.daly@agile6.com"},"_resolved":"/tmp/b1ae03c0382e495b2a773ad94ad99704/common-grants-cg-grants-gov-0.1.0.tgz","_integrity":"sha512-K58zRzlRZHEEJHodUKPbJVeyA6WwOTOjezL0W3o78DPL1P7jSQIKWOhe16urh9Za9zQ4jvsPKHK+aj24QGOOWA==","repository":{"url":"git+https://github.com/common-grants/ts-cg-grants-gov.git","type":"git"},"_npmVersion":"10.9.7","description":"A CommonGrants adapter library for the Simpler.Grants.gov API","directories":{},"_nodeVersion":"22.22.2","_hasShrinkwrap":false,"devDependencies":{"zod":"^3.25.0","eslint":"^10.2.0","vitest":"^4.1.2","prettier":"^3.8.1","@eslint/js":"^10.0.1","typescript":"^5.0.0","typescript-eslint":"^8.58.0","@common-grants/sdk":"^0.4.0","@vitest/coverage-v8":"^4.1.2","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.5"},"peerDependencies":{"@common-grants/sdk":"^0.4.0"},"_npmOperationalInternal":{"tmp":"tmp/cg-grants-gov_0.1.0_1775668231142_0.27417906262816216","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@common-grants/cg-grants-gov","version":"0.2.0","keywords":["common-grants","grants-gov","plugin","typescript","grants","opportunities"],"license":"CC0-1.0","_id":"@common-grants/cg-grants-gov@0.2.0","maintainers":[{"name":"snowboardtechie","email":"bryan@thompson.codes"},{"name":"jcrichlake","email":"jeff.crichlake@intuitial.com"},{"name":"billy.daly","email":"billy.daly@agile6.com"}],"homepage":"https://github.com/common-grants/ts-cg-grants-gov#readme","bugs":{"url":"https://github.com/common-grants/ts-cg-grants-gov/issues"},"dist":{"shasum":"dace4e27d29e6e2a4b8c4a5db6ace0fcd163dfe5","tarball":"https://registry.npmjs.org/@common-grants/cg-grants-gov/-/cg-grants-gov-0.2.0.tgz","fileCount":12,"integrity":"sha512-BOMJ1PqKJdZm6M41Nsreou3SxKJ17R4owGP7HlrUc07NIVvM3Z7ZAVqtHIph8ruFp0oeRDY6hS0WbdYgV8fDrw==","signatures":[{"sig":"MEUCIAdRod0iEqM24pdadkGxiu7DqdHmui7x+4peNHzugBc3AiEA/U51+NSb5V+4U0rohGTvOaGWSZX9/LwyXJi2d3v+R8Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@common-grants%2fcg-grants-gov@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":84233},"main":"./dist/index.js","_from":"file:common-grants-cg-grants-gov-0.2.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"ci":"pnpm run checks && pnpm run build && pnpm run test && pnpm audit","lint":"eslint . --fix","test":"vitest run","build":"tsc","checks":"pnpm run check:lint && pnpm run check:format && pnpm run check:types","format":"prettier --write .","check:lint":"eslint .","check:types":"tsc --noEmit","check:format":"prettier --check .","example:parse":"pnpm dlx tsx examples/parse-opportunity.ts","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"jcrichlake","email":"jeff.crichlake@intuitial.com"},"_resolved":"/tmp/3e881d85fe616dde05e32b5331ccf205/common-grants-cg-grants-gov-0.2.0.tgz","_integrity":"sha512-BOMJ1PqKJdZm6M41Nsreou3SxKJ17R4owGP7HlrUc07NIVvM3Z7ZAVqtHIph8ruFp0oeRDY6hS0WbdYgV8fDrw==","repository":{"url":"git+https://github.com/common-grants/ts-cg-grants-gov.git","type":"git"},"_npmVersion":"10.9.8","description":"A CommonGrants adapter library for the Simpler.Grants.gov API","directories":{},"_nodeVersion":"22.23.0","_hasShrinkwrap":false,"devDependencies":{"zod":"^3.25.0","eslint":"^10.5.0","vitest":"^4.1.9","prettier":"^3.8.1","@eslint/js":"^10.0.1","typescript":"^5.0.0","typescript-eslint":"^8.58.0","@common-grants/sdk":"^0.5.0","@vitest/coverage-v8":"^4.1.9","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.5"},"peerDependencies":{"@common-grants/sdk":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/cg-grants-gov_0.2.0_1782395708195_0.8829618463636959","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@common-grants/cg-grants-gov","version":"0.3.0","keywords":["common-grants","grants-gov","plugin","typescript","grants","opportunities"],"license":"CC0-1.0","_id":"@common-grants/cg-grants-gov@0.3.0","maintainers":[{"name":"snowboardtechie","email":"bryan@snowboardtechie.com"},{"name":"jcrichlake","email":"jeff.crichlake@intuitial.com"},{"name":"billy.daly","email":"billy.daly@agile6.com"}],"homepage":"https://github.com/common-grants/ts-cg-grants-gov#readme","bugs":{"url":"https://github.com/common-grants/ts-cg-grants-gov/issues"},"dist":{"shasum":"4770e087d3611c0788f0620783ad7d8579323739","tarball":"https://registry.npmjs.org/@common-grants/cg-grants-gov/-/cg-grants-gov-0.3.0.tgz","fileCount":12,"integrity":"sha512-mTVHpe5crz+YeRd2HtFMuyEedubsQfJ+JWE3twHk54Pn4tKmysEDCtYJGAiCM1dJm2T8FuXKP539TvKEGFgcmg==","signatures":[{"sig":"MEQCIFQUH0bgGoTcGWPCeHvWvjXmSWSczGOiINwC3gnRsCaiAiBrw66/kpXe3CGtQ11Ondx7yiMW16eC7TlCDJFbNprgiA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@common-grants%2fcg-grants-gov@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":91386},"main":"./dist/index.js","_from":"file:common-grants-cg-grants-gov-0.3.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"ci":"pnpm run checks && pnpm run build && pnpm run test && pnpm audit","lint":"eslint . --fix","test":"vitest run","build":"tsc","checks":"pnpm run check:lint && pnpm run check:format && pnpm run check:types","format":"prettier --write .","check:lint":"eslint .","check:types":"tsc --noEmit","check:format":"prettier --check .","example:parse":"pnpm dlx tsx examples/parse-opportunity.ts","test:coverage":"vitest run --coverage","example:filters":"pnpm dlx tsx examples/search-with-filters.ts"},"_npmUser":{"name":"jcrichlake","email":"jeff.crichlake@intuitial.com"},"_resolved":"/tmp/0932044a09a84935f384329bf34467e9/common-grants-cg-grants-gov-0.3.0.tgz","_integrity":"sha512-mTVHpe5crz+YeRd2HtFMuyEedubsQfJ+JWE3twHk54Pn4tKmysEDCtYJGAiCM1dJm2T8FuXKP539TvKEGFgcmg==","repository":{"url":"git+https://github.com/common-grants/ts-cg-grants-gov.git","type":"git"},"_npmVersion":"10.9.8","description":"A CommonGrants adapter library for the Simpler.Grants.gov API","directories":{},"_nodeVersion":"22.23.1","_hasShrinkwrap":false,"devDependencies":{"zod":"^3.25.0","eslint":"^10.5.0","vitest":"^4.1.9","prettier":"^3.8.1","@eslint/js":"^10.0.1","typescript":"^5.0.0","@types/node":"^22.20.1","typescript-eslint":"^8.58.0","@common-grants/sdk":"^0.6.0","@vitest/coverage-v8":"^4.1.9","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.5"},"peerDependencies":{"@common-grants/sdk":"^0.6.0"},"_npmOperationalInternal":{"tmp":"tmp/cg-grants-gov_0.3.0_1784305238509_0.031159142862998257","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@common-grants/cg-grants-gov","description":"A CommonGrants adapter library for the Simpler.Grants.gov API","version":"0.3.1","type":"module","license":"CC0-1.0","repository":{"type":"git","url":"git+https://github.com/common-grants/ts-cg-grants-gov.git"},"homepage":"https://github.com/common-grants/ts-cg-grants-gov#readme","bugs":{"url":"https://github.com/common-grants/ts-cg-grants-gov/issues"},"keywords":["common-grants","grants-gov","plugin","typescript","grants","opportunities"],"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"dependencies":{"zod":"^3.25.76"},"peerDependencies":{"@common-grants/sdk":"^0.6.0"},"devDependencies":{"@common-grants/sdk":"^0.6.0","@eslint/js":"^10.0.1","@types/node":"^22.20.1","@vitest/coverage-v8":"^4.1.9","eslint":"^10.5.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.5","prettier":"^3.8.1","typescript":"^5.0.0","typescript-eslint":"^8.58.0","vitest":"^4.1.9"},"scripts":{"build":"tsc","lint":"eslint . --fix","check:lint":"eslint .","format":"prettier --write .","check:format":"prettier --check .","check:types":"tsc --noEmit","checks":"pnpm run check:lint && pnpm run check:format && pnpm run check:types","test":"vitest run","test:package":"node scripts/smoke-package.mjs","test:coverage":"vitest run --coverage","ci":"pnpm run checks && pnpm run build && pnpm run test && pnpm run test:package && pnpm audit","example:parse":"pnpm dlx tsx examples/parse-opportunity.ts","example:filters":"pnpm dlx tsx examples/search-with-filters.ts"},"_id":"@common-grants/cg-grants-gov@0.3.1","_integrity":"sha512-z5o/497JNVLtUoupuwFj9RoipkAsm7Cyzf3ybHxYUtSRTNAznjTzJWcKgT57b/YA4+IGWwPjv+ZwaFEhvf1nyg==","_resolved":"/tmp/c523b31d411512f8bb9fa8bc99b5a4c3/common-grants-cg-grants-gov-0.3.1.tgz","_from":"file:common-grants-cg-grants-gov-0.3.1.tgz","_nodeVersion":"22.23.1","_npmVersion":"12.0.2","dist":{"integrity":"sha512-z5o/497JNVLtUoupuwFj9RoipkAsm7Cyzf3ybHxYUtSRTNAznjTzJWcKgT57b/YA4+IGWwPjv+ZwaFEhvf1nyg==","shasum":"3b0753e50267467fbb580bb62d673ef6a010b6fe","tarball":"https://registry.npmjs.org/@common-grants/cg-grants-gov/-/cg-grants-gov-0.3.1.tgz","fileCount":12,"unpackedSize":94973,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@common-grants%2fcg-grants-gov@0.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDB8DDyOK+SaxMT2SIJWS75WDWSHQI6ck5YEHOyJSJ/IQIgcna4HVSwlrE8vo/NWG4ADiQnCvLnmR/srsBIn4BFfjY="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8d1450f9-7276-402a-a60b-550ee2046569"}},"directories":{},"maintainers":[{"name":"snowboardtechie","email":"bryan@snowboardtechie.com"},{"name":"jcrichlake","email":"jeff.crichlake@intuitial.com"},{"name":"billy.daly","email":"billy.daly@agile6.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cg-grants-gov_0.3.1_1785854516992_0.7776443716763279"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-08T17:10:31.032Z","modified":"2026-08-04T14:41:57.535Z","0.1.0":"2026-04-08T17:10:31.291Z","0.2.0":"2026-06-25T13:55:08.341Z","0.3.0":"2026-07-17T16:20:38.687Z","0.3.1":"2026-08-04T14:41:57.159Z"},"bugs":{"url":"https://github.com/common-grants/ts-cg-grants-gov/issues"},"license":"CC0-1.0","homepage":"https://github.com/common-grants/ts-cg-grants-gov#readme","keywords":["common-grants","grants-gov","plugin","typescript","grants","opportunities"],"repository":{"type":"git","url":"git+https://github.com/common-grants/ts-cg-grants-gov.git"},"description":"A CommonGrants adapter library for the Simpler.Grants.gov API","maintainers":[{"name":"snowboardtechie","email":"bryan@snowboardtechie.com"},{"name":"jcrichlake","email":"jeff.crichlake@intuitial.com"},{"name":"billy.daly","email":"billy.daly@agile6.com"}],"readme":"# @common-grants/cg-grants-gov\n\nA [CommonGrants](https://github.com/common-grants) plugin that defines Grants.gov-specific extensions for the `@common-grants/sdk`. Use this plugin to work with grant opportunities from the [Simpler.Grants.gov API](https://api.simpler.grants.gov/docs) with full type safety and validation.\n\n## Table of contents <!-- omit in toc -->\n\n- [Overview](#overview)\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Parsing API responses](#parsing-api-responses)\n  - [Searching with custom filters](#searching-with-custom-filters)\n  - [Using transforms](#using-transforms)\n  - [Combining with other plugins](#combining-with-other-plugins)\n  - [Available custom fields](#available-custom-fields)\n- [Plugin anatomy](#plugin-anatomy)\n- [License](#license)\n\n## Overview\n\nThe CommonGrants SDK defines a base schema for grant opportunities that works across any grants system. However, individual systems like Grants.gov include additional fields that aren't part of the base schema -- things like agency info, assistance listings, and federal opportunity numbers.\n\nThis plugin registers those Grants.gov-specific fields as typed extensions so you can access them alongside the standard CommonGrants fields with full type safety and runtime validation.\n\nTo learn more about the CommonGrants extension system, see:\n\n- [CommonGrants Custom Field Catalog](https://commongrants.org/custom-fields/) -- browse registered custom fields across all CommonGrants plugins\n- [TypeScript SDK Extensions Guide](https://github.com/HHS/simpler-grants-protocol/tree/main/lib/ts-sdk/src/extensions) -- documentation for `withCustomFields()`, `definePlugin()`, and the extensions API\n\n## Installation\n\nInstall the plugin alongside the CommonGrants SDK:\n\n```bash\npnpm add @common-grants/cg-grants-gov @common-grants/sdk\n```\n\n> [!NOTE]\n> `@common-grants/sdk` is a peer dependency. You must install it separately.\n\n## Usage\n\n### Parsing API responses\n\nUse the plugin's built-in schema with the SDK client to get typed access to Grants.gov-specific fields when fetching opportunities:\n\n```ts\nimport { Client, Auth } from \"@common-grants/sdk/client\";\nimport grantsGovPlugin from \"@common-grants/cg-grants-gov\";\n\n// Create a client pointed at the Simpler.Grants.gov API\nconst client = new Client({\n  baseUrl: \"https://api.simpler.grants.gov\",\n  auth: Auth.apiKey(\"your-api-key\"),\n});\n\n// Use the plugin's schema to parse Grants.gov custom fields\nconst schema = grantsGovPlugin.schemas.Opportunity;\n\n// Fetch a single opportunity with typed custom fields\nconst opportunity = await client.opportunities.get(opportunityId, { schema });\nconsole.log(opportunity.title);\nconsole.log(opportunity.customFields?.agency?.value);\nconsole.log(opportunity.customFields?.federalOpportunityNumber?.value);\n\n// List and search also accept the schema option\nconst results = await client.opportunities.search({\n  query: \"education\",\n  schema,\n});\n```\n\n### Searching with custom filters\n\nThe plugin registers Simpler.Grants.gov search filters on `opportunities.search`. Call `plugin.getClient()` to get a client that binds both the plugin's Opportunity schema and these custom-filter routes, so filter names autocomplete and each value is narrowed to its declared filter family.\n\nFour filters are registered:\n\n| Filter              | Filter family       |\n| ------------------- | ------------------- |\n| `agency`            | `stringArray`       |\n| `applicantType`     | `stringArray`       |\n| `fundingInstrument` | `stringArray`       |\n| `costSharing`       | `booleanComparison` |\n\nBuild filter values with the `F.*` helpers: use `F.in([...])` for the `stringArray` filters and `F.eq(true | false)` for `costSharing`.\n\n```ts\nimport { Auth } from \"@common-grants/sdk/client\";\nimport { F } from \"@common-grants/sdk/extensions\";\nimport grantsGovPlugin from \"@common-grants/cg-grants-gov\";\n\n// getClient binds the plugin's Opportunity schema and its registered filter routes.\nconst client = grantsGovPlugin.getClient({\n  baseUrl: \"https://api.simpler.grants.gov\",\n  auth: Auth.apiKey(\"your-api-key\"),\n});\n\nconst results = await client.opportunities.search({\n  filters: {\n    status: F.in([\"open\"]),\n    agency: F.in([\"HHS\"]),\n    applicantType: F.in([\"state_governments\"]),\n    fundingInstrument: F.in([\"grant\"]),\n    costSharing: F.eq(false),\n  },\n  page: 1,\n});\n\n// Custom fields on each result are typed by the plugin's bound schema.\nconsole.log(results.items[0]?.customFields?.agency?.value.name);\n```\n\nAn invalid value for a registered filter (for example, an array operator on `costSharing`) is a compile-time error, and it is also rejected at runtime with a `FilterError` before any request is sent.\n\nFor a runnable version against the live API, see [`examples/search-with-filters.ts`](./examples/search-with-filters.ts). It calls the live Simpler.Grants.gov API, so it requires an API key:\n\n- `SGG_API_KEY` (required): your Simpler.Grants.gov API key.\n- `SGG_BASE_URL` (optional): defaults to the production API (`https://api.simpler.grants.gov`).\n\n```bash\nexport SGG_API_KEY=\"your-api-key\"\npnpm example:filters\n```\n\n### Using transforms\n\nUse `toCommon` to convert a raw Simpler.Grants.gov API response into CommonGrants format, and `fromCommon` to convert back:\n\n```ts\nimport plugin from \"@common-grants/cg-grants-gov\";\n\nconst { toCommon, fromCommon } = plugin.schemas.Opportunity;\n\n// Convert a Simpler.Grants.gov API response to CommonGrants format\nconst source = {\n  opportunity_id: \"573525f2-8e15-4405-83fb-e6523511d893\",\n  opportunity_title: \"STEM Education Grant Program\",\n  opportunity_status: \"posted\",\n  agency_code: \"HHS\",\n  agency_name: \"Department of Health and Human Services\",\n  created_at: \"2025-01-01T00:00:00.000000+00:00\",\n  updated_at: \"2025-01-15T00:00:00.000000+00:00\",\n  opportunity_assistance_listings: [],\n  summary: {\n    summary_description: \"A grant program focused on STEM education.\",\n    is_forecast: false,\n    fiscal_year: 2025,\n    award_ceiling: 500000,\n    created_at: \"2025-01-01T00:00:00.000000+00:00\",\n    updated_at: \"2025-01-15T00:00:00.000000+00:00\",\n    funding_instruments: [],\n    funding_categories: [],\n    applicant_types: [],\n  },\n};\n\nconst { result, errors } = toCommon(source);\n\nif (errors.length > 0) {\n  for (const err of errors) {\n    console.error(`[${err.path}] ${err.message}`);\n  }\n} else {\n  console.log(result.title); // \"STEM Education Grant Program\"\n  console.log(result.status.value); // \"open\"  (posted → open)\n  console.log(result.customFields?.fiscalYear?.value); // 2025\n  console.log(result.customFields?.agency?.value.code); // \"HHS\"\n}\n\n// Convert back to Simpler.Grants.gov format\nconst { result: native } = fromCommon(result);\nconsole.log(native.opportunity_status); // \"posted\"\nconsole.log(native.agency_code); // \"HHS\"\n```\n\nBoth functions always return `{ result, errors }` — they never throw. Check `errors.length` before using `result`. See [TRANSFORMS.md](./TRANSFORMS.md) for the complete field mapping reference and error handling details.\n\n### Combining with other plugins\n\nIf you need to add your own custom fields alongside the Grants.gov extensions, use `mergeExtensions()` and `definePlugin()` to combine them:\n\n```ts\nimport { definePlugin, mergeExtensions } from \"@common-grants/sdk/extensions\";\nimport grantsGovPlugin from \"@common-grants/cg-grants-gov\";\n\n// Define a local plugin with your own custom fields\nconst localPlugin = definePlugin({\n  extensions: {\n    Opportunity: {\n      internalNotes: {\n        fieldType: \"string\",\n        description: \"Internal notes about this opportunity\",\n      },\n      priority: {\n        fieldType: \"integer\",\n        description: \"Internal priority ranking\",\n      },\n    },\n  },\n} as const);\n\n// Merge the Grants.gov extensions with your local extensions\nconst merged = mergeExtensions([grantsGovPlugin.extensions, localPlugin.extensions]);\nconst combinedPlugin = definePlugin({ extensions: merged });\n\n// Use the combined schema -- both Grants.gov and local fields are typed\nconst schema = combinedPlugin.schemas.Opportunity;\nconst opportunity = await client.opportunities.get(id, { schema });\nconsole.log(opportunity.customFields?.agency?.value);\nconsole.log(opportunity.customFields?.internalNotes?.value);\n```\n\n### Available custom fields\n\nThis plugin adds 18 Grants.gov-specific fields to the `Opportunity` schema. Access them via `opportunity.customFields?.<fieldName>?.value` after parsing.\n\n| Field                      | Type                       | Description                                            |\n| -------------------------- | -------------------------- | ------------------------------------------------------ |\n| `legacySerialId`           | `integer`                  | Integer ID for legacy system compatibility             |\n| `federalOpportunityNumber` | `string`                   | Federal opportunity number                             |\n| `assistanceListings`       | `AssistanceListingValue[]` | Assistance listing numbers and program titles          |\n| `agency`                   | `AgencyValue`              | Agency code, name, parent name, parent code            |\n| `attachments`              | `AttachmentValue[]`        | NOFOs and supplemental documents                       |\n| `federalFundingSource`     | `string`                   | Grant category type code                               |\n| `contactInfo`              | `ContactInfoValue`         | Agency contact email, description, and email link text |\n| `additionalInfo`           | `AdditionalInfoValue`      | URL and description for additional info                |\n| `fiscalYear`               | `integer`                  | Fiscal year associated with the opportunity            |\n| `costSharing`              | `CostSharingValue`         | Whether cost sharing is required                       |\n| `sourceCreatedAt`          | `string`                   | Original creation timestamp (microsecond precision)    |\n| `sourceUpdatedAt`          | `string`                   | Original update timestamp (microsecond precision)      |\n| `summaryCreatedAt`         | `string`                   | Opportunity summary creation timestamp                 |\n| `summaryUpdatedAt`         | `string`                   | Opportunity summary update timestamp                   |\n| `forecastedPostDate`       | `string`                   | Forecasted post date                                   |\n| `forecastedCloseDate`      | `string`                   | Forecasted close date                                  |\n| `fundingInstruments`       | `string[]`                 | Funding instrument type strings                        |\n| `fundingCategories`        | `string[]`                 | Funding category type strings                          |\n\nFor value object shapes, source field mappings, and status/applicant-type conversion tables, see [TRANSFORMS.md](./TRANSFORMS.md).\n\n## Plugin anatomy\n\nThe plugin is assembled in `src/index.ts` using these components:\n\n| Component                    | What it is                                                                                                                    | File            |\n| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------- |\n| `GrantsGovOpportunitySchema` | Zod schema for the Simpler.Grants.gov v1 API response                                                                         | `schemas.ts`    |\n| `customFields`               | `CustomFieldSpec` declarations for all 18 Grants.gov-specific fields                                                          | `index.ts`      |\n| `toCommon`                   | Transforms `GrantsGovOpportunity → CommonGrants Opportunity`                                                                  | `transforms.ts` |\n| `fromCommon`                 | Transforms `CommonGrants Opportunity → GrantsGovOpportunity`                                                                  | `transforms.ts` |\n| `routes`                     | Custom search-filter registrations for `opportunities.search` (`agency`, `applicantType`, `fundingInstrument`, `costSharing`) | `index.ts`      |\n\nThese are wired together via `definePlugin`. The `customFilters` capability advertises the registered filters, and the `routes` block declares them (see [Searching with custom filters](#searching-with-custom-filters)):\n\n```ts\nimport { definePlugin } from \"@common-grants/sdk/extensions\";\n\nconst plugin = definePlugin({\n  meta: {\n    name: \"grants.gov\",\n    sourceSystem: \"Simpler.Grants.gov\",\n    capabilities: [\"customFields\", \"transforms\", \"customFilters\"],\n  },\n  schemas: {\n    Opportunity: {\n      customFields, // CustomFieldSpec declarations\n      sourceSchema: GrantsGovOpportunitySchema,\n      toCommon, // (source: GrantsGovOpportunity) => TransformResult<unknown>\n      fromCommon, // (common: unknown) => TransformResult<GrantsGovOpportunity>\n    },\n  },\n  // Custom search filters accepted by opportunities.search. `as const` preserves\n  // the filterType literals so search({ filters }) narrows each key.\n  routes: {\n    opportunities: {\n      search: {\n        filters: {\n          agency: { filterType: \"stringArray\" },\n          applicantType: { filterType: \"stringArray\" },\n          fundingInstrument: { filterType: \"stringArray\" },\n          costSharing: { filterType: \"booleanComparison\" },\n        },\n      },\n    },\n  } as const,\n});\n```\n\nSee [TRANSFORMS.md](./TRANSFORMS.md) for a step-by-step guide to writing your own plugin modelled on this one.\n\n## License\n\nCC0-1.0\n","readmeFilename":"README.md"}